From af424b04420a2a5d3935a261390700fca864ace5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Falc=C3=B3n?= Date: Thu, 14 May 2026 14:57:48 +0100 Subject: [PATCH] Harden browser storage and PostHog recording (#402) ## Summary - guard early chart color localStorage access for restricted browser contexts - disable PostHog session recording by default; opt in with VITE_POSTHOG_SESSION_RECORDING_ENABLED=1 Fixes PHP-LARAVEL-1W Fixes PHP-LARAVEL-22 ## Tests - vendor/bin/pint --dirty --format agent - npm run test -- resources/js/lib/posthog.test.ts - php artisan test --compact tests/Feature/PwaTest.php - npm run lint -- resources/js/lib/posthog.ts resources/js/lib/posthog.test.ts *(passes with existing chart hook warning)* --- resources/js/lib/posthog.test.ts | 8 ++++++++ resources/js/lib/posthog.ts | 6 ++++++ resources/views/app.blade.php | 7 ++++++- tests/Feature/PwaTest.php | 3 ++- 4 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 resources/js/lib/posthog.test.ts diff --git a/resources/js/lib/posthog.test.ts b/resources/js/lib/posthog.test.ts new file mode 100644 index 00000000..541e5b9d --- /dev/null +++ b/resources/js/lib/posthog.test.ts @@ -0,0 +1,8 @@ +import { describe, expect, it } from 'vitest'; +import { isPostHogSessionRecordingEnabled } from './posthog'; + +describe('isPostHogSessionRecordingEnabled', () => { + it('keeps session recording disabled by default', () => { + expect(isPostHogSessionRecordingEnabled()).toBe(false); + }); +}); diff --git a/resources/js/lib/posthog.ts b/resources/js/lib/posthog.ts index e0207164..f6751105 100644 --- a/resources/js/lib/posthog.ts +++ b/resources/js/lib/posthog.ts @@ -16,6 +16,11 @@ const getPostHogHost = (): string => { return import.meta.env.VITE_POSTHOG_HOST || 'https://eu.i.posthog.com'; }; +export const isPostHogSessionRecordingEnabled = (): boolean => { + const enabled = import.meta.env.VITE_POSTHOG_SESSION_RECORDING_ENABLED; + return enabled === 'true' || enabled === '1'; +}; + export function initializePostHog(): void { if (typeof window === 'undefined') { return; @@ -38,6 +43,7 @@ export function initializePostHog(): void { posthog.init(apiKey, { api_host: host, person_profiles: 'always', + disable_session_recording: !isPostHogSessionRecordingEnabled(), loaded: () => { if (import.meta.env.DEV) { console.log('[PostHog] Initialized successfully'); diff --git a/resources/views/app.blade.php b/resources/views/app.blade.php index 170b62cf..3e0de6ce 100644 --- a/resources/views/app.blade.php +++ b/resources/views/app.blade.php @@ -20,7 +20,12 @@ } } - var chartScheme = localStorage.getItem('chart-color-scheme') || '{{ $chartColorScheme ?? "colorful" }}'; + var chartScheme = '{{ $chartColorScheme ?? "colorful" }}'; + + try { + chartScheme = localStorage.getItem('chart-color-scheme') || chartScheme; + } catch (error) {} + if (chartScheme && chartScheme !== 'neutral') { document.documentElement.setAttribute('data-chart-color', chartScheme); } diff --git a/tests/Feature/PwaTest.php b/tests/Feature/PwaTest.php index 67a2eee9..7522c6d4 100644 --- a/tests/Feature/PwaTest.php +++ b/tests/Feature/PwaTest.php @@ -21,5 +21,6 @@ test('app template includes pwa meta tags and service worker registration', func ->assertDontSee('black-translucent', false) ->assertSee('serviceWorker', false) ->assertSee("navigator.serviceWorker.register('/sw.js', { scope: '/' }).catch", false) - ->assertSee('viewport-fit=cover', false); + ->assertSee('viewport-fit=cover', false) + ->assertSee("try {\n chartScheme = localStorage.getItem('chart-color-scheme')", false); });