import { withAuth } from "next-auth/middleware"; import { NextResponse } from "next/server"; export default withAuth( function middleware(req) { const isDev = process.env.NODE_ENV === "development"; const nonce = Buffer.from(crypto.randomUUID()).toString("base64"); // Allow digiresilience.org for embedding documentation const frameSrcDirective = `frame-src 'self' https://digiresilience.org;`; const cspHeader = ` default-src 'self'; ${frameSrcDirective} connect-src 'self'; script-src 'self' 'nonce-${nonce}' 'strict-dynamic' ${isDev ? "'unsafe-eval'" : ""}; style-src 'self' 'unsafe-inline'; img-src 'self' blob: data:; font-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'self'; upgrade-insecure-requests; `; const contentSecurityPolicyHeaderValue = cspHeader .replace(/\s{2,}/g, " ") .trim(); const requestHeaders = new Headers(req.headers); requestHeaders.set("x-nonce", nonce); requestHeaders.set( "Content-Security-Policy", contentSecurityPolicyHeaderValue, ); const response = NextResponse.next({ request: { headers: requestHeaders, }, }); response.headers.set( "Content-Security-Policy", contentSecurityPolicyHeaderValue, ); // Additional security headers response.headers.set("X-Frame-Options", "SAMEORIGIN"); response.headers.set("X-Content-Type-Options", "nosniff"); response.headers.set("Referrer-Policy", "strict-origin-when-cross-origin"); response.headers.set("X-XSS-Protection", "1; mode=block"); response.headers.set( "Permissions-Policy", "camera=(), microphone=(), geolocation=()" ); return response; }, { pages: { signIn: `/login`, }, callbacks: { authorized: ({ token }) => { if (process.env.SETUP_MODE === "true") { return true; } if (token?.email) { return true; } return false; }, }, } ); export const config = { matcher: ["/((?!ws|wss|api|_next/static|_next/image|favicon.ico).*)"], };