@djangocfg/nextjs 2.1.471 → 2.1.472
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/index.d.mts +36 -0
- package/dist/config/index.mjs +49 -30
- package/dist/config/index.mjs.map +1 -1
- package/dist/i18n/routing.d.mts +2 -2
- package/dist/index.mjs +49 -30
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -9
- package/src/config/createNextConfig.ts +101 -36
package/dist/config/index.d.mts
CHANGED
|
@@ -70,6 +70,42 @@ interface BaseNextConfigOptions {
|
|
|
70
70
|
* dashboard), so every other app keeps the tighter default. Default: false.
|
|
71
71
|
*/
|
|
72
72
|
stripe?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Content-Security-Policy control.
|
|
75
|
+
*
|
|
76
|
+
* - `false` — do not emit the `Content-Security-Policy` header at all.
|
|
77
|
+
* Use this on apps with no user auth/payment surface and unpredictable
|
|
78
|
+
* third-party embeds (a pitch deck, a marketing microsite) where
|
|
79
|
+
* naming every future embed's origin is not worth the maintenance —
|
|
80
|
+
* `X-Content-Type-Options`/`Referrer-Policy`/`X-Frame-Options` below
|
|
81
|
+
* still apply.
|
|
82
|
+
* - object — keep the baseline CSP but additively loosen specific
|
|
83
|
+
* directives for named trusted origins (the pattern `stripe` above is
|
|
84
|
+
* a hardcoded special case of). Every array is additive; omit a key to
|
|
85
|
+
* leave that directive untouched.
|
|
86
|
+
* - omitted — tightest default (`frame-src 'self'`, etc.), same as today.
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* // No CSP at all — simplest option for a low-risk app with ad hoc embeds
|
|
91
|
+
* createBaseNextConfig({ csp: false })
|
|
92
|
+
*
|
|
93
|
+
* // Keep CSP, just allow one trusted iframe origin
|
|
94
|
+
* createBaseNextConfig({ csp: { frameSrc: ['https://www.youtube-nocookie.com'] } })
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
csp?: false | {
|
|
98
|
+
/** Extra `frame-src` origins (iframes this app embeds). */
|
|
99
|
+
frameSrc?: string[];
|
|
100
|
+
/** Extra `script-src` origins (third-party SDK scripts). */
|
|
101
|
+
scriptSrc?: string[];
|
|
102
|
+
/** Extra `connect-src` origins (XHR/fetch/WebSocket to a third party). */
|
|
103
|
+
connectSrc?: string[];
|
|
104
|
+
/** Extra `img-src` origins (hotlinked third-party images). */
|
|
105
|
+
imgSrc?: string[];
|
|
106
|
+
/** Extra `font-src` origins (third-party web fonts). */
|
|
107
|
+
fontSrc?: string[];
|
|
108
|
+
};
|
|
73
109
|
/**
|
|
74
110
|
* PWA configuration options
|
|
75
111
|
* Set to false to disable PWA, or provide custom options
|
package/dist/config/index.mjs
CHANGED
|
@@ -14,7 +14,7 @@ var require_package = __commonJS({
|
|
|
14
14
|
"package.json"(exports, module) {
|
|
15
15
|
module.exports = {
|
|
16
16
|
name: "@djangocfg/nextjs",
|
|
17
|
-
version: "2.1.
|
|
17
|
+
version: "2.1.472",
|
|
18
18
|
description: "Next.js server utilities: sitemap, health, OG images, contact forms, navigation, config",
|
|
19
19
|
keywords: [
|
|
20
20
|
"nextjs",
|
|
@@ -1396,38 +1396,57 @@ function createBaseNextConfig(options = {}) {
|
|
|
1396
1396
|
];
|
|
1397
1397
|
const hasIframeAllowlist = !!options.allowIframeFrom && options.allowIframeFrom.length > 0;
|
|
1398
1398
|
const frameAncestors = hasIframeAllowlist ? options.allowIframeFrom.includes("*") ? "*" : `'self' ${options.allowIframeFrom.join(" ")}` : "'none'";
|
|
1399
|
+
const cspDisabled = options.csp === false;
|
|
1400
|
+
const cspExtra = typeof options.csp === "object" ? options.csp : void 0;
|
|
1399
1401
|
const stripeScript = options.stripe ? " https://js.stripe.com" : "";
|
|
1400
1402
|
const stripeConnect = options.stripe ? " https://api.stripe.com" : "";
|
|
1401
1403
|
const stripeFrame = options.stripe ? " https://js.stripe.com https://checkout.stripe.com" : "";
|
|
1402
|
-
const
|
|
1403
|
-
const
|
|
1404
|
-
const
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1404
|
+
const extraScript = cspExtra?.scriptSrc?.length ? " " + cspExtra.scriptSrc.join(" ") : "";
|
|
1405
|
+
const extraConnect = cspExtra?.connectSrc?.length ? " " + cspExtra.connectSrc.join(" ") : "";
|
|
1406
|
+
const extraFrame = cspExtra?.frameSrc?.length ? " " + cspExtra.frameSrc.join(" ") : "";
|
|
1407
|
+
const extraImg = cspExtra?.imgSrc?.length ? " " + cspExtra.imgSrc.join(" ") : "";
|
|
1408
|
+
const extraFont = cspExtra?.fontSrc?.length ? " " + cspExtra.fontSrc.join(" ") : "";
|
|
1409
|
+
const connectSrc = isDev ? `connect-src 'self' http: https: ws: wss:${stripeConnect}${extraConnect}` : `connect-src 'self' https: wss:${stripeConnect}${extraConnect}`;
|
|
1410
|
+
const imgSrc = isDev ? `img-src 'self' data: blob: http: https:${extraImg}` : `img-src 'self' data: blob: https:${extraImg}`;
|
|
1411
|
+
if (!cspDisabled) {
|
|
1412
|
+
const cspDirectives = [
|
|
1413
|
+
"default-src 'self'",
|
|
1414
|
+
// Next.js requires inline + eval for its runtime/HMR. Tighten to nonces later.
|
|
1415
|
+
`script-src 'self' 'unsafe-inline' 'unsafe-eval'${stripeScript}${extraScript}`,
|
|
1416
|
+
"style-src 'self' 'unsafe-inline'",
|
|
1417
|
+
imgSrc,
|
|
1418
|
+
`font-src 'self' data:${extraFont}`,
|
|
1419
|
+
// API/websocket calls go cross-origin to Django/Centrifugo.
|
|
1420
|
+
connectSrc,
|
|
1421
|
+
// Stripe Elements/Checkout and any app-declared trusted origins
|
|
1422
|
+
// (options.csp.frameSrc) mount iframes; add their hosts when enabled.
|
|
1423
|
+
`frame-src 'self'${stripeFrame}${extraFrame}`,
|
|
1424
|
+
"object-src 'none'",
|
|
1425
|
+
"base-uri 'self'",
|
|
1426
|
+
"form-action 'self'",
|
|
1427
|
+
`frame-ancestors ${frameAncestors}`
|
|
1428
|
+
];
|
|
1429
|
+
headers.push({
|
|
1430
|
+
source: "/:path*",
|
|
1431
|
+
headers: [
|
|
1432
|
+
{ key: "X-Content-Type-Options", value: "nosniff" },
|
|
1433
|
+
{ key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
|
|
1434
|
+
{ key: "Content-Security-Policy", value: cspDirectives.join("; ") },
|
|
1435
|
+
// X-Frame-Options for older browsers. Omitted when a wildcard iframe
|
|
1436
|
+
// allowlist is set (browsers then rely on CSP frame-ancestors).
|
|
1437
|
+
...hasIframeAllowlist && options.allowIframeFrom.includes("*") ? [] : [{ key: "X-Frame-Options", value: hasIframeAllowlist ? "SAMEORIGIN" : "DENY" }]
|
|
1438
|
+
]
|
|
1439
|
+
});
|
|
1440
|
+
} else {
|
|
1441
|
+
headers.push({
|
|
1442
|
+
source: "/:path*",
|
|
1443
|
+
headers: [
|
|
1444
|
+
{ key: "X-Content-Type-Options", value: "nosniff" },
|
|
1445
|
+
{ key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
|
|
1446
|
+
...hasIframeAllowlist && options.allowIframeFrom.includes("*") ? [] : [{ key: "X-Frame-Options", value: hasIframeAllowlist ? "SAMEORIGIN" : "DENY" }]
|
|
1447
|
+
]
|
|
1448
|
+
});
|
|
1449
|
+
}
|
|
1431
1450
|
const userHeaders = options.headers ? await options.headers() : [];
|
|
1432
1451
|
return [...headers, ...userHeaders];
|
|
1433
1452
|
},
|