import { createClient } from '@supabase/supabase-js'
import { NextRequest, NextResponse } from 'next/server'
export async function GET(request: NextRequest) {
const { searchParams, origin, hash } = new URL(request.url)
const code = searchParams.get('code')
const error = searchParams.get('error')
const error_description = searchParams.get('error_description')
const next = searchParams.get('next') ?? '/'
console.log('Auth callback received:', {
code: code ? 'present' : 'missing',
error,
error_description,
origin,
next,
hash: hash || 'none',
fullUrl: request.url
})
// Check for OAuth errors first
if (error) {
console.error('OAuth error received:', { error, error_description })
return NextResponse.redirect(`${origin}/auth/auth-code-error?error=${error}&description=${encodeURIComponent(error_description || '')}`)
}
// Handle Authorization Code Flow
if (code) {
try {
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)
console.log('Attempting to exchange code for session...')
const { data, error: exchangeError } = await supabase.auth.exchangeCodeForSession(code)
if (exchangeError) {
console.error('Code exchange failed:', {
error: exchangeError.message,
status: exchangeError.status,
details: exchangeError
})
return NextResponse.redirect(`${origin}/auth/auth-code-error?error=exchange_failed&description=${encodeURIComponent(exchangeError.message)}`)
}
if (data?.session) {
console.log('Session created successfully for user:', data.user?.email)
return NextResponse.redirect(`${origin}${next}`)
} else {
console.error('No session created despite successful exchange')
return NextResponse.redirect(`${origin}/auth/auth-code-error?error=no_session`)
}
} catch (err) {
console.error('Unexpected error in auth callback:', err)
return NextResponse.redirect(`${origin}/auth/auth-code-error?error=unexpected&description=${encodeURIComponent(String(err))}`)
}
}
// Handle Implicit Flow (hash-based tokens) - Lightweight version
console.log('No code found, checking for implicit flow tokens...')
// Create a minimal response that will handle hash-based tokens on the client side
const html = `
<!DOCTYPE html>
<html>
<head>
<title>Completing Sign-In...</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: #111827;
color: white;
}
.container {
text-align: center;
padding: 2rem;
background: rgba(30, 41, 59, 0.8);
border-radius: 1rem;
border: 1px solid rgba(20, 184, 166, 0.3);
}
.spinner {
width: 24px;
height: 24px;
border: 2px solid rgba(20, 184, 166, 0.3);
border-top: 2px solid #14b8a6;
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 0 auto 1rem;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
h1 {
font-size: 1.25rem;
margin-bottom: 0.5rem;
color: #f3f4f6;
}
p {
color: #d1d5db;
font-size: 0.875rem;
}
</style>
</head>
<body>
<div class="container">
<div class="spinner"></div>
<h1>Completing Sign-In</h1>
<p>Setting up your session...</p>
</div>
<script>
// Handle hash-based tokens (implicit flow)
const hash = window.location.hash;
if (hash && hash.includes('access_token')) {
console.log('Implicit flow tokens found in hash');
// Parse hash parameters
const params = new URLSearchParams(hash.substring(1));
const accessToken = params.get('access_token');
const refreshToken = params.get('refresh_token');
const expiresIn = params.get('expires_in');
if (accessToken && refreshToken) {
// Store tokens in sessionStorage temporarily
sessionStorage.setItem('supabase_auth_tokens', JSON.stringify({
access_token: accessToken,
refresh_token: refreshToken,
expires_in: expiresIn
}));
// Redirect to dashboard - AuthProvider will handle session setup
window.location.href = '${origin}/dashboard';
} else {
console.error('Missing required tokens in hash');
window.location.href = '${origin}/auth/auth-code-error?error=missing_tokens';
}
} else {
console.error('No authentication data found');
window.location.href = '${origin}/auth/auth-code-error?error=no_auth_data';
}
</script>
</body>
</html>
`;
return new Response(html, {
headers: { 'Content-Type': 'text/html' },
});
}