import { getToken } from "next-auth/jwt"; import { NextResponse, type NextRequest } from "next/server"; import { getAuthMode, getRequiredAuthSecret, isAuthRoute, isProtectedPath } from "@/lib/auth-config"; export async function proxy(request: NextRequest) { const { pathname } = request.nextUrl; if (!isProtectedPath(pathname)) return NextResponse.next(); const authMode = getAuthMode(); if (!authMode.enabled && !authMode.error) return NextResponse.next(); if (authMode.error) { return authConfigErrorResponse(request, authMode.error); } const token = await getToken({ req: request, secret: getRequiredAuthSecret(), }); if (token) return NextResponse.next(); if (pathname.startsWith("/api/")) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } const signInUrl = new URL("/api/auth/signin/oidc", request.url); signInUrl.searchParams.set("callbackUrl", request.nextUrl.href); return NextResponse.redirect(signInUrl); } export const config = { matcher: ["/((?!_next/static|_next/image|favicon.ico|icon.svg).*)"], }; function authConfigErrorResponse(request: NextRequest, error: string) { if (request.nextUrl.pathname.startsWith("/api/") && !isAuthRoute(request.nextUrl.pathname)) { return NextResponse.json({ error }, { status: 500 }); } return new NextResponse(authErrorHtml(error), { status: 500, headers: { "content-type": "text/html; charset=utf-8", }, }); } function authErrorHtml(error: string): string { return ` Authentication Configuration Error

OIDC 配置不完整

${escapeHtml(error)}

请补全 OIDC 配置,或移除全部 OIDC 相关变量以保持开放访问。

`; } function escapeHtml(value: string): string { return value .replaceAll("&", "&") .replaceAll("<", "<") .replaceAll(">", ">") .replaceAll('"', """) .replaceAll("'", "'"); }