diff --git a/src/routes/reset-password/+page.server.ts b/src/routes/reset-password/+page.server.ts index efe4d56..75aa803 100644 --- a/src/routes/reset-password/+page.server.ts +++ b/src/routes/reset-password/+page.server.ts @@ -10,9 +10,11 @@ export const load: PageServerLoad = async ({ url }) => { throw redirect(302, '/'); } + // Better Auth stores reset tokens as identifier `reset-password:` + // with the user id in `value`. const verification = await prisma.verification.findFirst({ where: { - value: token, + identifier: `reset-password:${token}`, expiresAt: { gt: new Date() } } }); @@ -20,6 +22,8 @@ export const load: PageServerLoad = async ({ url }) => { if (!verification) { throw redirect(302, '/'); } + + return { invite: url.searchParams.get('invite') === '1' }; }; export const actions: Actions = { diff --git a/src/routes/reset-password/+page.svelte b/src/routes/reset-password/+page.svelte index 7d1c957..34b4ff3 100644 --- a/src/routes/reset-password/+page.svelte +++ b/src/routes/reset-password/+page.svelte @@ -2,7 +2,7 @@ import type { PageProps } from './$types'; import Window from '$lib/components/containers/Window.svelte'; - let { form }: PageProps = $props(); + let { data, form }: PageProps = $props(); @@ -13,7 +13,14 @@ {/if}
-

Reset Password

+

+ {data.invite ? 'Set Your Password' : 'Reset Password'} +

+ {#if data.invite} +

+ Welcome! Choose a password to finish setting up your account. +

+ {/if}
diff --git a/src/routes/reset-password/page.server.spec.ts b/src/routes/reset-password/page.server.spec.ts index d2c91a6..389c59b 100644 --- a/src/routes/reset-password/page.server.spec.ts +++ b/src/routes/reset-password/page.server.spec.ts @@ -56,19 +56,28 @@ describe('reset-password page server load', () => { } expect(findFirst).toHaveBeenCalledWith({ where: { - value: 'invalid-token', + identifier: 'reset-password:invalid-token', expiresAt: { gt: expect.any(Date) } } }); }); - it('returns undefined when token is valid (verification found)', async () => { - findFirst.mockResolvedValue({ id: 'v-1', value: 'valid-token' }); + it('returns invite=false when token is valid', async () => { + findFirst.mockResolvedValue({ id: 'v-1', identifier: 'reset-password:valid-token' }); const url = createUrl('/reset-password', { token: 'valid-token' }); const result = await load({ url } as any); - expect(result).toBeUndefined(); + expect(result).toEqual({ invite: false }); + }); + + it('returns invite=true for registration links', async () => { + findFirst.mockResolvedValue({ id: 'v-1', identifier: 'reset-password:valid-token' }); + + const url = createUrl('/reset-password', { token: 'valid-token', invite: '1' }); + + const result = await load({ url } as any); + expect(result).toEqual({ invite: true }); }); it('redirects to / when verification is expired', async () => {