diff --git a/src/lib/proxy-auth-contract.test.ts b/src/lib/proxy-auth-contract.test.ts new file mode 100644 index 00000000..af07b1a7 --- /dev/null +++ b/src/lib/proxy-auth-contract.test.ts @@ -0,0 +1,13 @@ +import { readFileSync } from "node:fs"; +import { describe, expect, it } from "vitest"; + +describe("proxy authentication boundary", () => { + it("uses a database-free Auth.js decoder", () => { + const proxy = readFileSync("src/proxy.ts", "utf8"); + const proxyAuth = readFileSync("src/lib/proxy-auth.ts", "utf8"); + + expect(proxy).toContain('from "@/lib/proxy-auth"'); + expect(proxy).not.toContain('from "@/lib/auth"'); + expect(proxyAuth).not.toMatch(/from\s+["'][^"']*(prisma|site-settings|credentials)[^"']*["']/i); + }); +}); diff --git a/src/lib/proxy-auth.ts b/src/lib/proxy-auth.ts new file mode 100644 index 00000000..1801f78f --- /dev/null +++ b/src/lib/proxy-auth.ts @@ -0,0 +1,10 @@ +import NextAuth from "next-auth"; + +// Proxy authentication must only decode the Auth.js session. Importing the +// full CMS auth configuration here would also run Prisma/settings callbacks. +export const { auth: proxyAuth } = NextAuth({ + trustHost: true, + secret: process.env.AUTH_SECRET, + session: { strategy: "jwt" }, + providers: [], +}); diff --git a/src/proxy.ts b/src/proxy.ts index 092c0477..f6dd2823 100644 --- a/src/proxy.ts +++ b/src/proxy.ts @@ -1,12 +1,12 @@ import { NextResponse } from "next/server"; -import { auth } from "@/lib/auth"; +import { proxyAuth } from "@/lib/proxy-auth"; import { shouldRedirectAdminRequest } from "@/lib/proxy-access"; // Edge proxy (formerly "middleware"): Prisma can't run here, so we only forward // the request path (so server components / the access guard can read it via // headers()) and normalize the real client IP. The DB-backed banned/maintenance // checks happen in src/lib/access-guard.ts (Node runtime) from the root layout. -export const proxy = auth((req) => { +export const proxy = proxyAuth((req) => { if (shouldRedirectAdminRequest(req.nextUrl.pathname, req.auth?.user ?? null)) { return NextResponse.redirect(new URL("/login", req.url)); }