Initial commit: Kalendartool (Next.js, Prisma, Docker)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
73
next.config.mjs
Normal file
73
next.config.mjs
Normal file
@@ -0,0 +1,73 @@
|
||||
/** @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/<slug> 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;
|
||||
Reference in New Issue
Block a user