Security: per-username login throttling, constant-time unknown-user check, Sec-Fetch-Site CSRF guard for writes, session rotation on login and password change, absolute session lifetime, sessions ended on reset and deactivation, last-admin protection, input length caps, ASCII usernames, clickjacking headers. Covered by tests/authentication.test.ts. Filter panel: toggle, fields and count share one row to save space. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
45 lines
1.1 KiB
JavaScript
45 lines
1.1 KiB
JavaScript
/** @type {import('next').NextConfig} */
|
|
const apiInternalUrl = (process.env.API_INTERNAL_URL || "http://localhost:3000").replace(/\/$/, "");
|
|
|
|
const nextConfig = {
|
|
allowedDevOrigins: [
|
|
"192.168.3.13",
|
|
"docker01.int.jappel.io",
|
|
"lb.jappel.io"
|
|
],
|
|
|
|
typescript: {
|
|
tsconfigPath: "./tsconfig.next.json",
|
|
},
|
|
poweredByHeader: false,
|
|
// Clickjacking: the Config pages hold admin actions, so no foreign page
|
|
// may frame the app. Same-origin framing stays allowed.
|
|
async headers() {
|
|
return [
|
|
{
|
|
source: "/:path*",
|
|
headers: [
|
|
{ key: "X-Frame-Options", value: "SAMEORIGIN" },
|
|
{ key: "Content-Security-Policy", value: "frame-ancestors 'self'" },
|
|
{ key: "X-Content-Type-Options", value: "nosniff" },
|
|
{ key: "Referrer-Policy", value: "same-origin" },
|
|
],
|
|
},
|
|
];
|
|
},
|
|
async rewrites() {
|
|
return [
|
|
{
|
|
source: "/api/:path*",
|
|
destination: `${apiInternalUrl}/api/:path*`,
|
|
},
|
|
{
|
|
source: "/health",
|
|
destination: `${apiInternalUrl}/health`,
|
|
},
|
|
];
|
|
},
|
|
};
|
|
|
|
export default nextConfig;
|
|
|