From fc2790f6fa7e75a7faa2a702d2802189f1532c31 Mon Sep 17 00:00:00 2001 From: NeilClack Date: Tue, 7 Jul 2026 09:05:29 -0500 Subject: [PATCH] fix: handle duplicate email sign-up and null user in protected layout - Register action now returns success instead of redirecting to /account/setup so users without a session (duplicate email with requireEmailVerification) see a 'check your email' message instead of crashing - Protected layout guards against null/undefined locals.user before querying Prisma (was passing id: undefined) - Updated register page to show success banner with verification instructions - Updated test to match new action response --- src/routes/(protected)/+layout.server.ts | 6 +++++- src/routes/register/+page.server.ts | 9 +++------ src/routes/register/+page.svelte | 12 +++++++++++- src/routes/register/page.server.spec.ts | 7 +++---- 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/routes/(protected)/+layout.server.ts b/src/routes/(protected)/+layout.server.ts index 8a0b4b4..373710c 100644 --- a/src/routes/(protected)/+layout.server.ts +++ b/src/routes/(protected)/+layout.server.ts @@ -3,8 +3,12 @@ import { error, redirect } from '@sveltejs/kit'; import { prisma } from '$lib/db'; export const load: LayoutServerLoad = async ({ locals }) => { + if (!locals.user?.id) { + throw error(403, 'not authorized'); + } + const user = await prisma.user.findUnique({ - where: { id: locals.user?.id }, + where: { id: locals.user.id }, select: { id: true, roleId: true, profile: { select: { id: true } } } }); if (!user) { diff --git a/src/routes/register/+page.server.ts b/src/routes/register/+page.server.ts index 4e91d9b..3b9e8b5 100644 --- a/src/routes/register/+page.server.ts +++ b/src/routes/register/+page.server.ts @@ -1,6 +1,6 @@ import type { Actions } from './$types'; import { auth } from '$lib/auth'; -import { fail, isRedirect, redirect } from '@sveltejs/kit'; +import { fail } from '@sveltejs/kit'; export const actions: Actions = { default: async ({ request }) => { @@ -17,7 +17,7 @@ export const actions: Actions = { } try { - const response = await auth.api.signUpEmail({ + await auth.api.signUpEmail({ body: { name: `${firstName} ${lastName}`, email: email, @@ -25,11 +25,8 @@ export const actions: Actions = { } }); - if (response.user) { - throw redirect(303, '/account/setup'); - } + return { success: true }; } catch (err) { - if (isRedirect(err)) throw err; const message = err instanceof Error ? err.message : 'An unexpected error occurred'; return fail(400, { error: message }); } diff --git a/src/routes/register/+page.svelte b/src/routes/register/+page.svelte index 4b34826..a18a904 100644 --- a/src/routes/register/+page.svelte +++ b/src/routes/register/+page.svelte @@ -8,7 +8,17 @@
- {#if form?.error} + {#if form?.success} +
+

Account created!

+

+ We've sent a verification email. Check your inbox and click the link to verify your + email address, then log in. +

+
+ {:else if form?.error}
{form.error}
diff --git a/src/routes/register/page.server.spec.ts b/src/routes/register/page.server.spec.ts index b7b1c1b..8699c53 100644 --- a/src/routes/register/page.server.spec.ts +++ b/src/routes/register/page.server.spec.ts @@ -41,7 +41,7 @@ describe('register page server action', () => { expect(signUpEmail).not.toHaveBeenCalled(); }); - it('redirects to /account/setup on successful signup', async () => { + it('returns success on successful signup', async () => { signUpEmail.mockResolvedValue({ user: { id: 'user-1' } }); const request = createFormRequest({ @@ -52,9 +52,8 @@ describe('register page server action', () => { password2: 'secret123' }); - await expect(actions.default({ request } as any)).rejects.toMatchObject({ - status: 303 - }); + const result = await invokeDefault(request); + expect(result).toEqual({ success: true }); }); it('returns fail(400) when signUpEmail throws', async () => {