Files
accounted/app/(auth)/auth/callback/route.ts
T
2026-02-21 16:08:01 +01:00

75 lines
2.3 KiB
TypeScript

import { createServerClient } from '@supabase/ssr'
import { type NextRequest, NextResponse } from 'next/server'
export async function GET(request: NextRequest) {
const { searchParams, origin } = new URL(request.url)
const code = searchParams.get('code')
const token_hash = searchParams.get('token_hash')
const type = searchParams.get('type')
const next = searchParams.get('next') ?? '/'
// Collect cookies that Supabase sets during auth so we can
// explicitly forward them on the redirect response.
const pendingCookies: { name: string; value: string; options: Record<string, unknown> }[] = []
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return request.cookies.getAll()
},
setAll(cookiesToSet) {
pendingCookies.length = 0
cookiesToSet.forEach((cookie) => pendingCookies.push(cookie))
},
},
}
)
let authenticated = false
// Handle PKCE flow (code exchange)
if (code) {
const { error } = await supabase.auth.exchangeCodeForSession(code)
authenticated = !error
}
// Handle token hash flow (email verification / magic link)
else if (token_hash && type) {
const { error } = await supabase.auth.verifyOtp({
token_hash,
type: type as 'signup' | 'invite' | 'magiclink' | 'recovery' | 'email_change' | 'email',
})
authenticated = !error
}
if (authenticated) {
let redirectPath = next
// Check if user has completed onboarding
const { data: { user } } = await supabase.auth.getUser()
if (user) {
const { data: settings } = await supabase
.from('company_settings')
.select('onboarding_complete')
.eq('user_id', user.id)
.single()
if (!settings?.onboarding_complete) {
redirectPath = '/onboarding'
}
}
// Create redirect and explicitly set auth cookies on the response
const response = NextResponse.redirect(new URL(redirectPath, origin))
for (const { name, value, options } of pendingCookies) {
response.cookies.set({ name, value, ...options })
}
return response
}
// Authentication failed — redirect to login with error
return NextResponse.redirect(new URL('/login?error=auth_error', origin))
}