diff --git a/src/hooks.server.ts b/src/hooks.server.ts index 604b396..ee31b47 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -7,7 +7,7 @@ import * as apiTokenService from '$lib/server/services/apiTokenService.js'; import { extractBearerToken } from '$lib/server/middleware/authenticate.js'; import { isBoardGuestAccessible } from '$lib/server/middleware/guestAccess.js'; -const PUBLIC_PATHS = ['/login', '/register', '/auth/', '/api/health']; +const PUBLIC_PATHS = ['/login', '/register', '/auth/', '/api/health', '/api/onboarding', '/status']; function isPublicPath(pathname: string): boolean { return PUBLIC_PATHS.some((path) => pathname === path || pathname.startsWith(path)); diff --git a/src/lib/components/widget/AppWidget.svelte b/src/lib/components/widget/AppWidget.svelte index dfb954d..149b5ee 100644 --- a/src/lib/components/widget/AppWidget.svelte +++ b/src/lib/components/widget/AppWidget.svelte @@ -134,6 +134,8 @@ target="_blank" rel="noopener noreferrer" class="card-hover group flex items-center gap-2 rounded-lg {cardStyleClass} px-3 py-2 text-left transition-colors hover:border-primary/50" + data-app-widget + data-app-url={app.url} oncontextmenu={handleContextMenu} onclick={recordClick} > @@ -190,6 +192,8 @@
{ const { step, data } = parsed.data; try { + // Guard: reject calls after onboarding is complete + const needed = await onboardingService.isOnboardingNeeded(); + if (!needed) { + return json(error('Onboarding is already complete'), { status: 403 }); + } + switch (step) { case 'admin': { // Create admin user