mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-15 15:02:04 +00:00
fix(auth): move onboarding redirect from AuthShell useEffect to proxy
The post-hydration redirect for users with `onboardingCompletedAt === null` caused a brief dashboard flash before the client-side effect could fire. The redirect now lives in `src/proxy.ts` so it lands on the first server response. The proxy runs in the Edge runtime and can't reach Prisma, so the auth routes (login / passkey-verify / register / password / /api/auth/me) mirror the DB `onboardingCompletedAt` column into a non-httpOnly `hl_onboarding` cookie. The cookie is a UX hint, not a security signal — a user editing it locally only skips the dashboard flash; they still can't bypass any server check. `/api/onboarding/complete` clears the cookie so the next navigation drops the redirect immediately, and `destroySession` + expired-session purge wipe it alongside the session cookie. The e2e onboarding-flicker spec can return to testing the actual incomplete-onboarding case: the proxy reads the cookie (absent for the fully-onboarded storage-state user), not the mocked `/api/auth/me` response, so the test now sets `onboardingCompletedAt: null` honestly instead of pinning it to a non-null value as a workaround. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
b281c0655b
commit
15796c148b
14 files changed
+208
-32
No files matched your search
@@ -137,6 +137,21 @@ export function proxy(request: NextRequest) {
|
||||
if (!hasSession) {
|
||||
return NextResponse.redirect(new URL("/auth/login", request.url));
|
||||
}
|
||||
|
||||
// v1.4.22 C4 — server-side onboarding redirect. Previously the
|
||||
// `<AuthShell>` ran this in a post-hydration `useEffect`, so a user
|
||||
// with `onboardingCompletedAt === null` briefly saw the dashboard
|
||||
// flash before the redirect fired. The auth flows (login, passkey,
|
||||
// register, /api/auth/me) keep an `hl_onboarding` cookie in sync
|
||||
// with the DB state; the proxy reads it without a DB roundtrip so
|
||||
// the redirect lands on the first server response. The /onboarding
|
||||
// page itself is in PUBLIC_PATHS above, so this branch only runs
|
||||
// for the surfaces that need to redirect away.
|
||||
const onboardingPending =
|
||||
request.cookies.get("hl_onboarding")?.value === "pending";
|
||||
if (onboardingPending && !pathname.startsWith("/onboarding")) {
|
||||
return NextResponse.redirect(new URL("/onboarding", request.url));
|
||||
}
|
||||
}
|
||||
|
||||
// Generate or propagate x-request-id for request correlation
|
||||
|
||||
Reference in new issue
Block a user