fix: Preserve original host in OAuth callback redirects

Fixed OAuth callback to preserve the original host (localhost vs 127.0.0.1)
by using request headers instead of request.url as the base URL for redirects.

This ensures that if a user accesses the app via 127.0.0.1, they will be
redirected back to 127.0.0.1 after OAuth, and vice versa for localhost.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-09 04:50:47 +00:00
parent 43f9009b31
commit bada693e76

View File

@@ -24,13 +24,18 @@ import Surreal from 'surrealdb';
export async function GET(request: NextRequest) { export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url); const { searchParams } = new URL(request.url);
// Get base URL from request headers to preserve the original host
const protocol = request.headers.get('x-forwarded-proto') || 'http';
const host = request.headers.get('host') || 'localhost:3000';
const baseUrl = `${protocol}://${host}`;
// Check for error from OAuth provider // Check for error from OAuth provider
const error = searchParams.get('error'); const error = searchParams.get('error');
if (error) { if (error) {
const errorDescription = searchParams.get('error_description') || 'Unknown error'; const errorDescription = searchParams.get('error_description') || 'Unknown error';
console.error('[OAuth Callback] Error from provider:', error, errorDescription); console.error('[OAuth Callback] Error from provider:', error, errorDescription);
return NextResponse.redirect( return NextResponse.redirect(
new URL(`/login?error=${encodeURIComponent(errorDescription)}`, request.url) new URL(`/login?error=${encodeURIComponent(errorDescription)}`, baseUrl)
); );
} }
@@ -105,7 +110,7 @@ export async function GET(request: NextRequest) {
} }
// Create redirect response // Create redirect response
const response = NextResponse.redirect(new URL(returnTo, request.url)); const response = NextResponse.redirect(new URL(returnTo, baseUrl));
// Set SurrealDB JWT cookie (for our app's authorization) // Set SurrealDB JWT cookie (for our app's authorization)
response.cookies.set('ponderants-auth', surrealJwt, { response.cookies.set('ponderants-auth', surrealJwt, {
@@ -130,20 +135,20 @@ export async function GET(request: NextRequest) {
if (error instanceof Error) { if (error instanceof Error) {
if (error.message.includes('Invalid state')) { if (error.message.includes('Invalid state')) {
return NextResponse.redirect( return NextResponse.redirect(
new URL('/login?error=Invalid or expired session', request.url) new URL('/login?error=Invalid or expired session', baseUrl)
); );
} }
if (error.message.includes('DPoP')) { if (error.message.includes('DPoP')) {
console.error('[OAuth Callback] DPoP error - this should not happen with the library!', error); console.error('[OAuth Callback] DPoP error - this should not happen with the library!', error);
return NextResponse.redirect( return NextResponse.redirect(
new URL('/login?error=Authentication protocol error', request.url) new URL('/login?error=Authentication protocol error', baseUrl)
); );
} }
} }
return NextResponse.redirect( return NextResponse.redirect(
new URL('/login?error=Authentication failed', request.url) new URL('/login?error=Authentication failed', baseUrl)
); );
} }
} }