import type { NextConfig } from "next"; // Static, request-independent security headers — applied to every // response via next.config's own headers() so they can't be missed on a // route that forgets to set them itself. Content-Security-Policy is NOT // set here: it needs a per-request nonce (for Next's own inline // hydration scripts), which only a request-scoped place like proxy.ts // can generate — see that file. const SECURITY_HEADERS = [ // This app is never meant to be framed by another origin. { key: "X-Frame-Options", value: "DENY" }, // Stops the browser from MIME-sniffing a response into something more // dangerous than its declared Content-Type. { key: "X-Content-Type-Options", value: "nosniff" }, // Full referrer to same-origin navigations (useful for our own // analytics-free logs), origin-only to other origins, nothing on downgrade. { key: "Referrer-Policy", value: "strict-origin-when-cross-origin" }, // No page here needs the camera, microphone, geolocation, etc. { key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=(), interest-cohort=()" }, // Only meaningful over HTTPS (which every real deployment of this app // uses) — harmless to send in local HTTP dev too, since browsers only // honor it on secure origins. { key: "Strict-Transport-Security", value: "max-age=63072000; includeSubDomains; preload" }, ]; const nextConfig: NextConfig = { reactStrictMode: true, experimental: { // Next's Server Action default (1MB) is too small for the PWA // icon/splash-screen ZIP import (see updateAppIconSettingsAction's // sibling importAppIconZipAction) — a full iOS splash-screen bundle // from a generator like progressier.com is ~10-15MB. Also lifts the // ceiling for regular media uploads (MediaPicker), which were // previously constrained below their own MEDIA_MAX_UPLOAD_BYTES. serverActions: { bodySizeLimit: "20mb" }, }, images: { remotePatterns: [ { protocol: "https", hostname: "storage.googleapis.com", pathname: "/uxpilot-auth.appspot.com/**", }, // Google OAuth profile photos (session.user.image when signed in via // "Continue with Google" — see src/auth.ts's Google provider). { protocol: "https", hostname: "lh3.googleusercontent.com" }, ], }, async headers() { return [{ source: "/(.*)", headers: SECURITY_HEADERS }]; }, }; export default nextConfig;