import { NextResponse } from "next/server"; import { headers } from "next/headers"; import { getServerSession } from "next-auth"; import { authOptions } from "@/lib/auth"; function unauth() { return NextResponse.json({ error: { code: "UNAUTH", message: "unauthorized", retryable: false } }, { status: 401 }); } export async function middlewareAuth(): Promise<{ ok: boolean; res?: NextResponse }> { // Used by route handlers (edge middleware handles pages first; this is defense-in-depth) // Local e2e login-stub: secret-gated, dead code unless E2E_SECRET is set (never on HF). try { const h = headers(); const e2e = h.get("x-e2e-secret"); if (e2e && process.env.E2E_SECRET && e2e === process.env.E2E_SECRET) return { ok: true }; } catch {} try { const session = await getServerSession(authOptions); const allow = process.env.APP_ALLOW_EMAIL ?? ""; if (!session?.user?.email || (allow && session.user.email.toLowerCase() !== allow.toLowerCase())) { return { ok: false, res: unauth() }; } return { ok: true }; } catch { // No session infra in CI — allow when no auth configured? No: fail closed unless MOCK if (process.env.MOCK_SOURCES === "1") return { ok: true }; return { ok: false, res: unauth() }; } } export function err(code: string, message: string, status = 400, retryable = false, details?: unknown) { return NextResponse.json({ error: { code, message, retryable, details } }, { status }); }