Files
butcem/next.config.ts
T

91 lines
2.9 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { NextConfig } from "next";
const isDev = process.env.NODE_ENV === "development";
/**
* Content-Security-Policy (nonce'suz): Cache Components'in statik kabuğu ile uyumlu.
* 'unsafe-inline' script: Next.js'in satır içi hydration verisi ve next-themes'in tema betiği için.
* Grafikler (Recharts, SVG) ve carousel (Embla) ek kaynak gerektirmez; ek dosyalar
* kendi origin'imizden (/api/files/...) ve blob: önizlemelerle servis edilir.
*/
const csp = [
"default-src 'self'",
`script-src 'self' 'unsafe-inline'${isDev ? " 'unsafe-eval'" : ""}`,
"style-src 'self' 'unsafe-inline'",
"img-src 'self' blob: data:",
"font-src 'self'",
"connect-src 'self'",
"media-src 'self' blob:",
"worker-src 'self' blob:",
"manifest-src 'self'",
"object-src 'none'",
"base-uri 'self'",
"form-action 'self'",
"frame-ancestors 'none'",
...(isDev ? [] : ["upgrade-insecure-requests"]),
].join("; ");
const securityHeaders = [
{ key: "Content-Security-Policy", value: csp },
{ key: "X-Content-Type-Options", value: "nosniff" },
{ key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
{ key: "X-Frame-Options", value: "DENY" },
{ key: "Cross-Origin-Opener-Policy", value: "same-origin" },
// Kamera: Faz 6'da fiş fotoğrafı için yalnızca kendi origin'imiz.
{
key: "Permissions-Policy",
value: "camera=(self), microphone=(), geolocation=(), payment=(), usb=()",
},
...(isDev
? []
: // includeSubDomains/preload bilinçli olarak yok: ta1sph.website'in diğer alt alanlarını bağlamasın.
[{ key: "Strict-Transport-Security", value: "max-age=31536000" }]),
];
/**
* /api/files: kullanıcı dosyaları (WebP görsel, PDF). Sayfa CSP'si yerine daha sıkı bir politika:
* betik yok; PDF'in tarayıcı görüntüleyicisinde açılabilmesi için object-src 'self'.
*/
const fileCsp = [
"default-src 'none'",
"img-src 'self'",
"style-src 'unsafe-inline'",
"object-src 'self'",
"frame-ancestors 'self'",
].join("; ");
const nextConfig: NextConfig = {
// Docker imajı için yalnızca gerekli dosyaları .next/standalone altına kopyala.
output: "standalone",
poweredByHeader: false,
// HEIC çözücü (libheif WASM) bundle'a girmesin; Node require ile yüklensin.
serverExternalPackages: ["heic-decode", "libheif-js"],
experimental: {
agentFeedback: true,
},
cacheComponents: true,
partialPrefetching: true,
turbopack: {
rules: {
"*.css": {
loaders: ["@tailwindcss/turbopack"],
as: "*.css",
},
},
},
async headers() {
return [
{ source: "/:path((?!api/files/).*)", headers: securityHeaders },
{
source: "/api/files/:path*",
headers: [
...securityHeaders.filter((h) => h.key !== "Content-Security-Policy"),
{ key: "Content-Security-Policy", value: fileCsp },
],
},
];
},
};
export default nextConfig;