diff --git a/frontend/src/layout/navigation-3000/sidepanel/panels/activation/activationLogic.ts b/frontend/src/layout/navigation-3000/sidepanel/panels/activation/activationLogic.ts index e8afd00aea1ed..b0be99d68f438 100644 --- a/frontend/src/layout/navigation-3000/sidepanel/panels/activation/activationLogic.ts +++ b/frontend/src/layout/navigation-3000/sidepanel/panels/activation/activationLogic.ts @@ -2,6 +2,7 @@ import { actions, connect, events, kea, listeners, path, reducers, selectors } f import { loaders } from 'kea-loaders' import { router } from 'kea-router' import api from 'lib/api' +import { reverseProxyCheckerLogic } from 'lib/components/ReverseProxyChecker/reverseProxyCheckerLogic' import { permanentlyMount } from 'lib/utils/kea-logic-builders' import posthog from 'posthog-js' import { membersLogic } from 'scenes/organization/membersLogic' @@ -58,6 +59,8 @@ export const activationLogic = kea([ ['insights'], dashboardsModel, ['rawDashboards'], + reverseProxyCheckerLogic, + ['hasReverseProxy'], ], actions: [ inviteLogic, @@ -193,6 +196,7 @@ export const activationLogic = kea([ s.customEventsCount, s.installedPlugins, s.currentTeamSkippedTasks, + s.hasReverseProxy, ], ( currentTeam, @@ -202,7 +206,8 @@ export const activationLogic = kea([ dashboards, customEventsCount, installedPlugins, - skippedTasks + skippedTasks, + hasReverseProxy ) => { const tasks: ActivationTaskType[] = [] for (const task of Object.values(ActivationTasks)) { @@ -286,7 +291,7 @@ export const activationLogic = kea([ id: ActivationTasks.SetUpReverseProxy, name: 'Set up a reverse proxy', description: 'Send your events from your own domain to avoid tracking blockers', - completed: false, + completed: hasReverseProxy || false, canSkip: true, skipped: skippedTasks.includes(ActivationTasks.SetUpReverseProxy), url: 'https://posthog.com/docs/advanced/proxy', diff --git a/frontend/src/lib/components/ReverseProxyChecker/reverseProxyCheckerLogic.test.ts b/frontend/src/lib/components/ReverseProxyChecker/reverseProxyCheckerLogic.test.ts new file mode 100644 index 0000000000000..5ea635b7e4f90 --- /dev/null +++ b/frontend/src/lib/components/ReverseProxyChecker/reverseProxyCheckerLogic.test.ts @@ -0,0 +1,63 @@ +import { expectLogic } from 'kea-test-utils' + +import { useMocks } from '~/mocks/jest' +import { initKeaTests } from '~/test/init' + +import { reverseProxyCheckerLogic } from './reverseProxyCheckerLogic' + +const hasReverseProxyValues = [['https://proxy.example.com'], [null]] +const doesNotHaveReverseProxyValues = [[null], [null]] + +const useMockedValues = (results: (string | null)[][]): void => { + useMocks({ + post: { + '/api/projects/:team/query': () => [ + 200, + { + results, + }, + ], + }, + }) +} + +describe('reverseProxyCheckerLogic', () => { + let logic: ReturnType + + beforeEach(() => { + initKeaTests() + localStorage.clear() + logic = reverseProxyCheckerLogic() + }) + + afterEach(() => { + logic.unmount() + }) + + it('should not have a reverse proxy set - when no data', async () => { + useMockedValues([]) + + logic.mount() + await expectLogic(logic).toFinishAllListeners().toMatchValues({ + hasReverseProxy: false, + }) + }) + + it('should not have a reverse proxy set - when data with no lib_custom_api_host values', async () => { + useMockedValues(doesNotHaveReverseProxyValues) + + logic.mount() + await expectLogic(logic).toFinishAllListeners().toMatchValues({ + hasReverseProxy: false, + }) + }) + + it('should have a reverse proxy set', async () => { + useMockedValues(hasReverseProxyValues) + + logic.mount() + await expectLogic(logic).toFinishAllListeners().toMatchValues({ + hasReverseProxy: true, + }) + }) +}) diff --git a/frontend/src/lib/components/ReverseProxyChecker/reverseProxyCheckerLogic.ts b/frontend/src/lib/components/ReverseProxyChecker/reverseProxyCheckerLogic.ts new file mode 100644 index 0000000000000..6b945e5c94c48 --- /dev/null +++ b/frontend/src/lib/components/ReverseProxyChecker/reverseProxyCheckerLogic.ts @@ -0,0 +1,49 @@ +import { afterMount, kea, path, reducers } from 'kea' +import { loaders } from 'kea-loaders' +import api from 'lib/api' + +import { HogQLQuery, NodeKind } from '~/queries/schema' +import { hogql } from '~/queries/utils' + +import type { reverseProxyCheckerLogicType } from './reverseProxyCheckerLogicType' + +const CHECK_INTERVAL_MS = 1000 * 60 * 60 // 1 hour + +export const reverseProxyCheckerLogic = kea([ + path(['components', 'ReverseProxyChecker', 'reverseProxyCheckerLogic']), + loaders({ + hasReverseProxy: [ + false as boolean | null, + { + loadHasReverseProxy: async () => { + const query: HogQLQuery = { + kind: NodeKind.HogQLQuery, + query: hogql`SELECT properties.$lib_custom_api_host AS lib_custom_api_host + FROM events + WHERE timestamp >= now() - INTERVAL 1 DAY + AND timestamp <= now() + ORDER BY timestamp DESC + limit 10`, + } + + const res = await api.query(query) + return !!res.results?.find((x) => !!x[0]) + }, + }, + ], + }), + reducers({ + lastCheckedTimestamp: [ + 0, + { persist: true }, + { + loadHasReverseProxySuccess: () => Date.now(), + }, + ], + }), + afterMount(({ actions, values }) => { + if (values.lastCheckedTimestamp < Date.now() - CHECK_INTERVAL_MS) { + actions.loadHasReverseProxy() + } + }), +]) diff --git a/frontend/src/lib/components/VersionChecker/versionCheckerLogic.ts b/frontend/src/lib/components/VersionChecker/versionCheckerLogic.ts index cc26d0eff45fc..ce53ba46d5db8 100644 --- a/frontend/src/lib/components/VersionChecker/versionCheckerLogic.ts +++ b/frontend/src/lib/components/VersionChecker/versionCheckerLogic.ts @@ -7,7 +7,7 @@ import { hogql } from '~/queries/utils' import type { versionCheckerLogicType } from './versionCheckerLogicType' -const CHECK_INTERVAL_MS = 1000 * 60 * 60 // 6 hour +const CHECK_INTERVAL_MS = 1000 * 60 * 60 * 6 // 6 hour export type SDKVersion = { version: string