From 1c305c7d1ed3fc419c046ab6c0c90ca26d78c6ec Mon Sep 17 00:00:00 2001 From: colinislit Date: Wed, 19 Nov 2025 12:02:22 +0100 Subject: [PATCH] fix: password reset email now redirects to update-password page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Problem:** Password reset emails redirected users to homepage with ?code= parameter, leaving users stuck without ability to set new password. **Root Cause:** Auth callback route didn't detect password recovery flow. When Supabase sent users back with type=recovery parameter, the callback defaulted to /epd/clients redirect instead of /update-password. **Solution:** - Detect `type=recovery` parameter in auth callback route - Always redirect password recovery flows to /update-password - Preserves existing flows (signup, magic link) unchanged **Flow now:** 1. User clicks reset link in email 2. Supabase verifies token → redirect to homepage with ?code=&type=recovery 3. Middleware redirects to /auth/callback?code=&type=recovery 4. Callback detects type=recovery → redirect to /update-password ✅ 5. User can set new password This fix ensures password reset works regardless of Supabase redirect_to configuration, making the flow more resilient. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- app/auth/callback/route.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/auth/callback/route.ts b/app/auth/callback/route.ts index 9030cf6..4a0af49 100644 --- a/app/auth/callback/route.ts +++ b/app/auth/callback/route.ts @@ -12,6 +12,7 @@ import type { NextRequest } from 'next/server' export async function GET(request: NextRequest) { const requestUrl = new URL(request.url) const code = requestUrl.searchParams.get('code') + const type = requestUrl.searchParams.get('type') // recovery, signup, etc const next = requestUrl.searchParams.get('next') ?? '/epd/clients' if (code) { @@ -21,6 +22,11 @@ export async function GET(request: NextRequest) { const { data, error } = await supabase.auth.exchangeCodeForSession(code) if (!error && data.user) { + // Password recovery flow - always go to update-password + if (type === 'recovery') { + return NextResponse.redirect(new URL('/update-password', request.url)) + } + // Check if new user (first login) const isNewUser = new Date(data.user.created_at).getTime() === new Date(data.user.last_sign_in_at || '').getTime()