From 79becc971bf2369723428b981ecd576c7e3fc7c2 Mon Sep 17 00:00:00 2001 From: Till JS Date: Sun, 22 Mar 2026 17:49:07 +0100 Subject: [PATCH] fix(calendar): add auth gate to prevent 401 errors and fix CSP for analytics Child components' onMount callbacks fire before the parent layout's auth check in Svelte, causing API calls (todo, contacts, calendar) to fire without a valid token on initial page load. Added appReady gate so children only render after auth is confirmed. Also added stats.mana.how to CSP script-src to allow Umami analytics. Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/calendar/apps/web/src/hooks.server.ts | 2 +- .../apps/web/src/routes/(app)/+layout.svelte | 220 +++++++++--------- 2 files changed, 117 insertions(+), 105 deletions(-) diff --git a/apps/calendar/apps/web/src/hooks.server.ts b/apps/calendar/apps/web/src/hooks.server.ts index 5db8003a5..598e9b52c 100644 --- a/apps/calendar/apps/web/src/hooks.server.ts +++ b/apps/calendar/apps/web/src/hooks.server.ts @@ -48,7 +48,7 @@ window.__PUBLIC_CONTACTS_API_URL__ = "${PUBLIC_CONTACTS_API_URL}"; 'Content-Security-Policy', [ "default-src 'self'", - "script-src 'self' 'unsafe-inline'", + "script-src 'self' 'unsafe-inline' https://stats.mana.how", "style-src 'self' 'unsafe-inline'", "img-src 'self' data: https:", `connect-src 'self' ${PUBLIC_MANA_CORE_AUTH_URL_CLIENT} ${PUBLIC_BACKEND_URL_CLIENT} ${PUBLIC_STT_URL} ${PUBLIC_TODO_BACKEND_URL} ${PUBLIC_CONTACTS_API_URL}`, diff --git a/apps/calendar/apps/web/src/routes/(app)/+layout.svelte b/apps/calendar/apps/web/src/routes/(app)/+layout.svelte index d63d4051d..206415781 100644 --- a/apps/calendar/apps/web/src/routes/(app)/+layout.svelte +++ b/apps/calendar/apps/web/src/routes/(app)/+layout.svelte @@ -62,6 +62,9 @@ let { children } = $props(); + // Auth gate - prevent children from mounting before auth is confirmed + let appReady = $state(false); + // InputBar search - search events async function handleSearch(query: string): Promise { if (!query.trim()) return []; @@ -378,6 +381,9 @@ return; } + // Auth confirmed - allow children to render + appReady = true; + // Initialize split-panel from URL/localStorage splitPanel.initialize(); @@ -408,114 +414,120 @@ - -
- - Zum Inhalt springen - - - - {#if !settingsStore.immersiveModeEnabled} - - {/if} - - - - - - - - - settingsStore.toggleImmersiveMode()} - visible={showCalendarToolbar} - /> - -
-
- {@render children()} -
-
+{#if !appReady} +
+
- +{:else} + +
+ + Zum Inhalt springen + - - + + {#if !settingsStore.immersiveModeEnabled} + + {/if} - - (showSettingsModal = false)} /> + + - -{#if calendarOnboarding.shouldShow} - + + + + + settingsStore.toggleImmersiveMode()} + visible={showCalendarToolbar} + /> + +
+
+ {@render children()} +
+
+
+
+ + + + + + (showSettingsModal = false)} /> + + + {#if calendarOnboarding.shouldShow} + + {/if} {/if}