fix: address final review blockers
- Add /api/onboarding and /status to PUBLIC_PATHS in hooks.server.ts so onboarding wizard and status page work for unauthenticated users - Add isOnboardingNeeded() guard to POST /api/onboarding to reject calls after onboarding is complete (security hardening) - Add data-app-widget attribute to all AppWidget card variants to enable j/k keyboard navigation
This commit is contained in:
+1
-1
@@ -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));
|
||||
|
||||
@@ -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 @@
|
||||
<!-- Large: icon + name + description + sparkline + tags + links -->
|
||||
<div
|
||||
class="card-hover group rounded-xl {cardStyleClass} p-5 transition-colors hover:border-primary/50"
|
||||
data-app-widget
|
||||
data-app-url={app.url}
|
||||
oncontextmenu={handleContextMenu}
|
||||
>
|
||||
<a
|
||||
@@ -283,6 +287,8 @@
|
||||
<!-- Medium (default): icon + name + status + sparkline on hover + links -->
|
||||
<div
|
||||
class="card-hover group rounded-xl {cardStyleClass} p-4 transition-colors hover:border-primary/50"
|
||||
data-app-widget
|
||||
data-app-url={app.url}
|
||||
oncontextmenu={handleContextMenu}
|
||||
>
|
||||
<a
|
||||
|
||||
@@ -48,6 +48,12 @@ export const POST: RequestHandler = async ({ request }) => {
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user