presentercoach / apps /web /middleware.ts
nathycodes's picture
Deploy Tech Presenter Coach
ec17af3
Raw History Blame Contribute Delete
1.7 kB
import { NextResponse, type NextRequest } from "next/server";
const isProduction = process.env.NODE_ENV === "production" && process.env.ALLOW_FRAME_EMBEDDING !== "true";
const configuredApiUrl = process.env.NEXT_PUBLIC_API_URL || "";
const externalApiOrigin = configuredApiUrl.startsWith("http")
? configuredApiUrl.replace(/\/+$/, "")
: "";
export function middleware(_request: NextRequest) {
const response = NextResponse.next();
const scriptSrc = isProduction
? "script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval'"
: "script-src 'self' 'unsafe-inline' 'unsafe-eval' 'wasm-unsafe-eval'";
const connectSources = ["'self'", "ws:", "wss:", "blob:", "data:"];
if (externalApiOrigin) {
connectSources.push(externalApiOrigin);
}
const directives = [
"default-src 'self'",
scriptSrc,
"style-src 'self' 'unsafe-inline'",
"img-src 'self' blob: data: https:",
"media-src 'self' blob: data:",
"font-src 'self' data:",
`connect-src ${connectSources.join(" ")}`,
"worker-src 'self' blob:",
isProduction ? "frame-ancestors 'none'" : "frame-ancestors *",
];
response.headers.set("Content-Security-Policy", directives.join("; "));
response.headers.set("X-Content-Type-Options", "nosniff");
response.headers.set("Referrer-Policy", "strict-origin-when-cross-origin");
response.headers.set(
"Permissions-Policy",
isProduction ? "camera=(self), microphone=(self), geolocation=()" : "camera=*, microphone=*, geolocation=()"
);
if (isProduction) {
response.headers.set("X-Frame-Options", "DENY");
}
return response;
}
export const config = {
matcher: ["/((?!api/backend|_next/static|_next/image|favicon.ico).*)"],
};