mirror of
https://github.com/jjbrunton/Sauci.git
synced 2026-10-31 10:19:43 +00:00
merge: redact invite analytics URLs
This commit is contained in:
commit
077f5433e1
3 files changed
+50
-11
No files matched your search
@@ -0,0 +1,24 @@
|
|||||||
|
import { readFile } from 'node:fs/promises'
|
||||||
|
import { describe, expect, it } from 'vitest'
|
||||||
|
|
||||||
|
const pageViewPath = new URL('./PostHogPageView.tsx', import.meta.url)
|
||||||
|
const providerPath = new URL('./providers.tsx', import.meta.url)
|
||||||
|
|
||||||
|
describe('PostHog invite privacy boundary', () => {
|
||||||
|
it('does not send a global page view for invite routes', async () => {
|
||||||
|
const source = await readFile(pageViewPath, 'utf8')
|
||||||
|
|
||||||
|
expect(source).toContain("pathname?.startsWith('/join/')")
|
||||||
|
expect(source.indexOf("pathname?.startsWith('/join/')")).toBeLessThan(source.indexOf("posthog.capture('$pageview'"))
|
||||||
|
})
|
||||||
|
|
||||||
|
it('disables automatic page-leave capture and redacts join URLs', async () => {
|
||||||
|
const source = await readFile(providerPath, 'utf8')
|
||||||
|
|
||||||
|
expect(source).toContain('capture_pageview: false')
|
||||||
|
expect(source).toContain('capture_pageleave: false')
|
||||||
|
expect(source).toContain('get_current_url: redactInviteUrl')
|
||||||
|
expect(source).toContain("url.pathname.startsWith('/join/')")
|
||||||
|
expect(source).toContain('/join/[invite]')
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -7,10 +7,14 @@ import { usePostHog } from 'posthog-js/react'
|
|||||||
function PostHogPageViewInner() {
|
function PostHogPageViewInner() {
|
||||||
const pathname = usePathname()
|
const pathname = usePathname()
|
||||||
const searchParams = useSearchParams()
|
const searchParams = useSearchParams()
|
||||||
const posthog = usePostHog()
|
const posthog = usePostHog()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (pathname && posthog) {
|
// Invite codes are bearer-like tokens. The join route emits its own
|
||||||
|
// aggregate-only event, so it must never produce a URL-bearing page view.
|
||||||
|
if (pathname?.startsWith('/join/')) return
|
||||||
|
|
||||||
|
if (pathname && posthog) {
|
||||||
let url = window.origin + pathname
|
let url = window.origin + pathname
|
||||||
if (searchParams.toString()) {
|
if (searchParams.toString()) {
|
||||||
url = url + '?' + searchParams.toString()
|
url = url + '?' + searchParams.toString()
|
||||||
|
|||||||
@@ -2,16 +2,27 @@
|
|||||||
|
|
||||||
import posthog from 'posthog-js'
|
import posthog from 'posthog-js'
|
||||||
import { PostHogProvider as PHProvider } from 'posthog-js/react'
|
import { PostHogProvider as PHProvider } from 'posthog-js/react'
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
|
|
||||||
export function PostHogProvider({ children }: { children: React.ReactNode }) {
|
function redactInviteUrl(defaultUrl: string): string {
|
||||||
|
const url = new URL(defaultUrl)
|
||||||
|
|
||||||
|
if (url.pathname.startsWith('/join/')) {
|
||||||
|
return `${url.origin}/join/[invite]`
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
export function PostHogProvider({ children }: { children: React.ReactNode }) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (typeof window !== 'undefined' && process.env.NEXT_PUBLIC_POSTHOG_KEY) {
|
if (typeof window !== 'undefined' && process.env.NEXT_PUBLIC_POSTHOG_KEY) {
|
||||||
posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, {
|
posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, {
|
||||||
api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST || 'https://eu.i.posthog.com',
|
api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST || 'https://eu.i.posthog.com',
|
||||||
person_profiles: 'identified_only',
|
person_profiles: 'identified_only',
|
||||||
capture_pageview: false, // We'll capture pageviews manually for better control
|
capture_pageview: false,
|
||||||
capture_pageleave: true,
|
capture_pageleave: false,
|
||||||
|
get_current_url: redactInviteUrl,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|||||||
Reference in new issue
Block a user