/** @type {import('next').NextConfig} */ // MultiToolApp-Plattform (module-plan.md): // HUB_URL – Basis-URL des Hubs (JWKS-Abruf für Token-Validierung) // HUB_BASE_PATH – Pfad, unter dem der Hub diese App routet (z. B. /apps/kalender). // Setzt Next.js basePath → alle Routen hängen darunter. // Ohne HUB_BASE_PATH läuft die App standalone (basePath: ''). const hubUrl = (process.env.HUB_URL ?? '').replace(/\/$/, ''); const hubBasePath = (process.env.HUB_BASE_PATH ?? '').replace(/\/$/, ''); const nextConfig = { // Standalone-Ausgabe für einen schlanken Docker-Container output: 'standalone', reactStrictMode: true, // Proxy-Modus: App läuft unter /apps/ innerhalb der Hub-Domain. // basePath '' (falsy) = Standalone-Betrieb ohne Pfad-Präfix. ...(hubBasePath ? { basePath: hubBasePath } : {}), // Manifest-Route: /.well-known/app-manifest → /api/manifest // (Next.js App Router routed keine Dot-Ordner; mit beforeFiles-Phase // fangen wir den Pfad ab, bevor basePath zuschlägt.) async rewrites() { return { beforeFiles: [ { source: '/.well-known/app-manifest', destination: '/api/manifest', }, ], }; }, // Security-Header (Next.js setzt keine davon by default): // - X-Content-Type-Options: verhindert MIME-Sniffing // - Referrer-Policy: keine URLs/Token an Dritte leaken // - Permissions-Policy: Browser-Features, die die App nicht nutzt // - CSP: Skripte nur 'self' + Inline (Next.js Hydration-Snippet); // style-src 'unsafe-inline' ist fuer Tailwind noetig. // - frame-ancestors: nur der Hub darf einbetten (statt X-Frame-Options, // das Subdomain-Embedding blockieren wuerde – platform-plan.md §4). async headers() { return [ { source: '/:path*', headers: [ { key: 'X-Content-Type-Options', value: 'nosniff' }, { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' }, { key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()', }, { key: 'Content-Security-Policy', value: [ "default-src 'self'", "script-src 'self' 'unsafe-inline'", "style-src 'self' 'unsafe-inline'", "img-src 'self' data:", "font-src 'self'", // JWKS-Abruf vom Hub (Token-Validierung in /auth/hub) hubUrl ? `connect-src 'self' ${hubUrl}` : "connect-src 'self'", // Proxy-Modus: kein Framing mehr nötig – aber der Hub darf // weiterhin einbetten (Rückwärtskompatibilität). hubUrl ? `frame-ancestors ${hubUrl}` : "frame-ancestors 'none'", "base-uri 'self'", "form-action 'self'", ].join('; '), }, ], }, ]; }, }; export default nextConfig;