import { NextResponse } from 'next/server'; import { cookies, headers } from 'next/headers'; import { getRequestOrigin } from '@/core/lib/site-url'; const BACKEND_URL = (process.env.BRAINERCE_API_URL || 'https://api.brainerce.com').replace( /\/$/, '' ); const CONNECTION_ID = process.env.NEXT_PUBLIC_BRAINERCE_SALES_CHANNEL_ID || process.env.NEXT_PUBLIC_BRAINERCE_CONNECTION_ID || ''; const TOKEN_COOKIE = 'brainerce_customer_token'; const LOGGED_IN_COOKIE = 'brainerce_logged_in'; /** * Auth status check endpoint. * Reads the httpOnly cookie, validates against backend, returns auth state. */ export async function GET() { const cookieStore = await cookies(); const tokenCookie = cookieStore.get(TOKEN_COOKIE); if (!tokenCookie?.value) { return NextResponse.json({ isLoggedIn: false }); } // The backend compares this against the sales channel's configured domain, so // it must be the storefront's real public origin. This route used to build it // by hand and got three things wrong at once: it read `host` but not // `x-forwarded-host` (an internal container host behind a proxy), it defaulted // the protocol to `http` (never matching an `https://` configured domain), and // it preferred the CLIENT-SUPPLIED `Origin` header — the same value the BFF // proxy deliberately refuses to forward, because trusting it lets a caller // pick which storefront the backend thinks it is talking to. The localhost // fallback then made a Live channel reject every logged-in session check. const origin = await getRequestOrigin(await headers()); try { // Validate token by calling backend profile endpoint const response = await fetch(`${BACKEND_URL}/api/vc/${CONNECTION_ID}/customers/me`, { headers: { Authorization: `Bearer ${tokenCookie.value}`, 'Content-Type': 'application/json', Origin: origin, }, }); if (!response.ok) { // Token is invalid or expired — clear cookies const res = NextResponse.json({ isLoggedIn: false }); res.cookies.delete(TOKEN_COOKIE); res.cookies.delete(LOGGED_IN_COOKIE); return res; } const customer = await response.json(); return NextResponse.json({ isLoggedIn: true, customer }); } catch { // Backend unreachable — don't clear cookies, might be temporary return NextResponse.json({ isLoggedIn: false, error: 'Service unavailable' }, { status: 503 }); } }