From 62298eaf3836d51410b11f1b37435123baff3dc2 Mon Sep 17 00:00:00 2001 From: "2569718930@qq.com" <2569718930@qq.com> Date: Wed, 15 Apr 2026 22:40:01 +0800 Subject: [PATCH] Harden auth profile fallback for slow backend responses --- frontend/app/api/auth/me/route.ts | 52 ++++++++++++++++++++++++++++--- frontend/lib/backend-auth.ts | 10 ++++-- 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/frontend/app/api/auth/me/route.ts b/frontend/app/api/auth/me/route.ts index a0b9d449..c67e7f03 100644 --- a/frontend/app/api/auth/me/route.ts +++ b/frontend/app/api/auth/me/route.ts @@ -16,10 +16,18 @@ export async function GET(req: NextRequest) { try { const auth = await buildBackendRequestHeaders(req); - const res = await fetch(`${API_BASE}/api/auth/me`, { - headers: auth.headers, - cache: "no-store", - }); + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), 6000); + let res: Response; + try { + res = await fetch(`${API_BASE}/api/auth/me`, { + headers: auth.headers, + cache: "no-store", + signal: controller.signal, + }); + } finally { + clearTimeout(timeoutId); + } if (res.status === 401 || res.status === 403) { const response = NextResponse.json({ authenticated: false, @@ -30,6 +38,23 @@ export async function GET(req: NextRequest) { } if (!res.ok) { const raw = await res.text(); + if (auth.authUserId) { + const response = NextResponse.json({ + authenticated: true, + user_id: auth.authUserId, + email: auth.authEmail || null, + subscription_active: null, + subscription_plan_code: null, + subscription_expires_at: null, + subscription_total_expires_at: null, + subscription_queued_days: 0, + subscription_queued_count: 0, + points: 0, + degraded_auth_profile: true, + degraded_reason: `backend_${res.status}`, + }); + return applyAuthResponseCookies(response, auth.response); + } const response = NextResponse.json( { error: `Backend returned ${res.status}`, detail: raw.slice(0, 300) }, { status: res.status }, @@ -40,9 +65,28 @@ export async function GET(req: NextRequest) { const response = NextResponse.json(data); return applyAuthResponseCookies(response, auth.response); } catch (error) { + const auth = await buildBackendRequestHeaders(req); + if (auth.authUserId) { + const response = NextResponse.json({ + authenticated: true, + user_id: auth.authUserId, + email: auth.authEmail || null, + subscription_active: null, + subscription_plan_code: null, + subscription_expires_at: null, + subscription_total_expires_at: null, + subscription_queued_days: 0, + subscription_queued_count: 0, + points: 0, + degraded_auth_profile: true, + degraded_reason: String(error), + }); + return applyAuthResponseCookies(response, auth.response); + } return NextResponse.json( { error: "Failed to fetch auth profile", detail: String(error) }, { status: 500 }, ); } } + diff --git a/frontend/lib/backend-auth.ts b/frontend/lib/backend-auth.ts index 8289d381..5436f19f 100644 --- a/frontend/lib/backend-auth.ts +++ b/frontend/lib/backend-auth.ts @@ -9,6 +9,8 @@ export const FORWARDED_SUPABASE_EMAIL_HEADER = "x-polyweather-auth-email"; type HeaderBuildResult = { headers: HeadersInit; response: NextResponse | null; + authUserId?: string | null; + authEmail?: string | null; }; type HeaderBuildOptions = { @@ -59,20 +61,20 @@ export async function buildBackendRequestHeaders( if (incomingAuth) { headers.set("Authorization", `Bearer ${incomingAuth}`); - return { headers, response: passthroughResponse }; + return { headers, response: passthroughResponse, authUserId: forwardedUserId || null, authEmail: forwardedEmail || null }; } const accessToken = session?.access_token || ""; if (accessToken) { // Fallback to cookie-backed session when request does not carry bearer. headers.set("Authorization", `Bearer ${accessToken}`); } - return { headers, response: passthroughResponse }; + return { headers, response: passthroughResponse, authUserId: forwardedUserId || null, authEmail: forwardedEmail || null }; } if (incomingAuth) { headers.set("Authorization", `Bearer ${incomingAuth}`); } - return { headers, response: null }; + return { headers, response: null, authUserId: null, authEmail: null }; } export function applyAuthResponseCookies( @@ -87,3 +89,5 @@ export function applyAuthResponseCookies( } return target; } + +