import { NextResponse } from "next/server" import type { NextRequest } from "next/server" import { auth } from "@/lib/auth" /** Cookies, unter denen Auth.js die Sitzung ablegt (http und https). */ const SESSION_COOKIES = [ "authjs.session-token", "__Secure-authjs.session-token", ] /** * Ermittelt die vom Client tatsächlich verwendete Basis-URL. * * `req.nextUrl.origin` zeigt hinter einem Reverse-Proxy oder im Container auf * den internen Port (3000) – Weiterleitungen landeten dadurch auf einer für den * Benutzer nicht erreichbaren Adresse. Die Forwarded-Header haben Vorrang. */ function externalBaseUrl(req: NextRequest) { const forwardedHost = req.headers.get("x-forwarded-host")?.split(",")[0]?.trim() const host = forwardedHost || req.headers.get("host")?.trim() if (!host) return req.nextUrl.origin const forwardedProto = req.headers.get("x-forwarded-proto")?.split(",")[0]?.trim() const protocol = forwardedProto || req.nextUrl.protocol.replace(":", "") || "http" return `${protocol}://${host}` } /** * Leitet zur Anmeldung um und entfernt dabei ein eventuell vorhandenes * Sitzungs-Cookie. Ohne das bleibt ein mit einem anderen NEXTAUTH_SECRET * verschlüsseltes Cookie im Browser liegen und erzeugt bei jedem Aufruf einen * JWTSessionError ("no matching decryption secret"), bis es von Hand * gelöscht wird. */ function redirectToSignIn(req: NextRequest) { const target = new URL("/auth/signin", externalBaseUrl(req)) const response = NextResponse.redirect(target) for (const name of SESSION_COOKIES) { if (req.cookies.has(name)) { response.cookies.set(name, "", { path: "/", maxAge: 0 }) } } return response } export default auth((req) => { const { pathname } = req.nextUrl // Öffentlich erreichbare Bereiche if ( pathname === "/" || pathname.startsWith("/auth/") || pathname.startsWith("/api/auth/") || pathname.startsWith("/api/privacy-policies") ) { return } if (pathname.startsWith("/admin") || pathname.startsWith("/api/users")) { if (!req.auth) { return redirectToSignIn(req) } const userRole = req.auth.user?.role if (userRole !== "ADMIN" && userRole !== "SUPER_ADMIN") { return redirectToSignIn(req) } } }) export const config = { matcher: [ /* * Alle Pfade außer statischen Next.js-Dateien und dem Favicon. */ "/((?!_next/static|_next/image|favicon.ico).*)", ], }