@djangocfg/nextjs 2.1.478 → 2.1.480
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 +157 -8
- package/dist/config/index.mjs +124 -14
- package/dist/config/index.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +124 -14
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -9
- package/src/config/createNextConfig.ts +69 -28
- package/src/config/csp.ts +180 -0
- package/src/config/index.ts +9 -0
package/dist/config/index.d.mts
CHANGED
|
@@ -5,6 +5,129 @@ import { P as PWAPluginOptions } from '../plugin-DdmK3zAE.mjs';
|
|
|
5
5
|
export { A as AI_DOCS_HINT, M as MCP_API_URL, b as MCP_BASE_URL, c as MCP_SERVER_URL } from '../constants-BDS8GXHN.mjs';
|
|
6
6
|
import '@djangocfg/i18n';
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* CSP Vendor Presets
|
|
10
|
+
*
|
|
11
|
+
* The problem this solves: every third-party script a DjangoCFG app loads needs
|
|
12
|
+
* its origin named in the CSP, and until now each app had to hand-list those
|
|
13
|
+
* origins (`csp: { scriptSrc: [...] }`) in its own `next.config.ts`. That
|
|
14
|
+
* repeats the same Stripe/Cloudflare/Google origin strings across every app,
|
|
15
|
+
* and — worse — nobody remembers which directive a given vendor needs, so the
|
|
16
|
+
* usual outcome is a production-only console error and a scramble.
|
|
17
|
+
*
|
|
18
|
+
* Instead, apps declare WHAT THEY USE by name (`csp: { vendors: ['stripe'] }`)
|
|
19
|
+
* and this registry owns WHICH ORIGINS that implies. When a vendor changes a
|
|
20
|
+
* host, it is fixed once here and every app inherits the fix on its next build.
|
|
21
|
+
*
|
|
22
|
+
* Adding a vendor: add an entry below, keyed by a short stable name, listing
|
|
23
|
+
* only the directives it genuinely needs. Keep the origins exact — never widen
|
|
24
|
+
* a directive to a bare `https:` to make a vendor work.
|
|
25
|
+
*/
|
|
26
|
+
/** The CSP directives a vendor preset may contribute origins to. */
|
|
27
|
+
interface CspOrigins {
|
|
28
|
+
/** `script-src` — the vendor's SDK/tag `<script>` hosts. */
|
|
29
|
+
scriptSrc?: string[];
|
|
30
|
+
/** `frame-src` — hosts the vendor mounts iframes from. */
|
|
31
|
+
frameSrc?: string[];
|
|
32
|
+
/** `connect-src` — hosts the vendor makes XHR/fetch/WebSocket calls to. */
|
|
33
|
+
connectSrc?: string[];
|
|
34
|
+
/** `img-src` — hosts the vendor loads images/pixels from. */
|
|
35
|
+
imgSrc?: string[];
|
|
36
|
+
/** `font-src` — hosts the vendor loads web fonts from. */
|
|
37
|
+
fontSrc?: string[];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Known third-party vendors and the CSP origins each one requires.
|
|
41
|
+
*
|
|
42
|
+
* Every entry is OFF by default — an app opts in via `csp.vendors`, so an app
|
|
43
|
+
* that mounts nothing third-party keeps the tightest possible policy.
|
|
44
|
+
*/
|
|
45
|
+
declare const CSP_VENDOR_PRESETS: {
|
|
46
|
+
/**
|
|
47
|
+
* Stripe.js / Checkout / Elements.
|
|
48
|
+
*
|
|
49
|
+
* `js.stripe.com` serves the SDK and also hosts the Elements iframes;
|
|
50
|
+
* `checkout.stripe.com` is the hosted Checkout iframe; `api.stripe.com`
|
|
51
|
+
* takes the tokenization/confirm XHR. Without all three the payment form
|
|
52
|
+
* silently fails to render.
|
|
53
|
+
*/
|
|
54
|
+
readonly stripe: {
|
|
55
|
+
readonly scriptSrc: ["https://js.stripe.com"];
|
|
56
|
+
readonly frameSrc: ["https://js.stripe.com", "https://checkout.stripe.com"];
|
|
57
|
+
readonly connectSrc: ["https://api.stripe.com"];
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Cloudflare Web Analytics (the RUM beacon).
|
|
61
|
+
*
|
|
62
|
+
* IMPORTANT: this script is NOT in the app's own HTML — when Web Analytics
|
|
63
|
+
* is enabled on the zone, Cloudflare INJECTS `beacon.min.js` into the
|
|
64
|
+
* response at the edge, after Next.js has already emitted the CSP header.
|
|
65
|
+
* So any app served through a Cloudflare zone with that feature on will
|
|
66
|
+
* violate its own CSP unless this preset is enabled, no matter what the
|
|
67
|
+
* source tree contains. The beacon also POSTs its payload back to
|
|
68
|
+
* `cloudflareinsights.com`, hence the `connect-src` entry.
|
|
69
|
+
*/
|
|
70
|
+
readonly cloudflare: {
|
|
71
|
+
readonly scriptSrc: ["https://static.cloudflareinsights.com"];
|
|
72
|
+
readonly connectSrc: ["https://cloudflareinsights.com", "https://static.cloudflareinsights.com"];
|
|
73
|
+
};
|
|
74
|
+
/** Google Analytics 4 / gtag.js. */
|
|
75
|
+
readonly 'google-analytics': {
|
|
76
|
+
readonly scriptSrc: ["https://www.googletagmanager.com", "https://www.google-analytics.com"];
|
|
77
|
+
readonly connectSrc: ["https://www.google-analytics.com", "https://analytics.google.com", "https://region1.google-analytics.com"];
|
|
78
|
+
readonly imgSrc: ["https://www.google-analytics.com", "https://www.googletagmanager.com"];
|
|
79
|
+
};
|
|
80
|
+
/** Google Tag Manager (the container itself; tags it loads may need more). */
|
|
81
|
+
readonly 'google-tag-manager': {
|
|
82
|
+
readonly scriptSrc: ["https://www.googletagmanager.com"];
|
|
83
|
+
readonly connectSrc: ["https://www.googletagmanager.com"];
|
|
84
|
+
readonly imgSrc: ["https://www.googletagmanager.com"];
|
|
85
|
+
readonly frameSrc: ["https://www.googletagmanager.com"];
|
|
86
|
+
};
|
|
87
|
+
/** Google Fonts (stylesheet host + the font files themselves). */
|
|
88
|
+
readonly 'google-fonts': {
|
|
89
|
+
readonly fontSrc: ["https://fonts.gstatic.com"];
|
|
90
|
+
};
|
|
91
|
+
/** Sentry browser SDK — errors/traces are POSTed to the ingest host. */
|
|
92
|
+
readonly sentry: {
|
|
93
|
+
readonly connectSrc: ["https://*.ingest.sentry.io", "https://*.sentry.io"];
|
|
94
|
+
};
|
|
95
|
+
/** YouTube embeds (privacy-enhanced host included). */
|
|
96
|
+
readonly youtube: {
|
|
97
|
+
readonly frameSrc: ["https://www.youtube.com", "https://www.youtube-nocookie.com"];
|
|
98
|
+
readonly imgSrc: ["https://i.ytimg.com"];
|
|
99
|
+
};
|
|
100
|
+
/** Vimeo embeds. */
|
|
101
|
+
readonly vimeo: {
|
|
102
|
+
readonly frameSrc: ["https://player.vimeo.com"];
|
|
103
|
+
readonly imgSrc: ["https://i.vimeocdn.com"];
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
/** Name of a vendor preset in {@link CSP_VENDOR_PRESETS}. */
|
|
107
|
+
type CspVendor = keyof typeof CSP_VENDOR_PRESETS;
|
|
108
|
+
/**
|
|
109
|
+
* Vendors applied to every app unless explicitly disabled.
|
|
110
|
+
*
|
|
111
|
+
* Only for origins the DEPLOYMENT PLATFORM injects, which an app therefore
|
|
112
|
+
* cannot discover by reading its own source. Cloudflare's Web Analytics beacon
|
|
113
|
+
* is rewritten into the HTML at the edge, after Next.js has already sent the
|
|
114
|
+
* CSP header — so an opt-in flag here reliably produces a production-only
|
|
115
|
+
* console error that nobody notices until a user reports it. (Observed
|
|
116
|
+
* 2026-07-22: all six DjangoCFG-served hosts were violating their own CSP.)
|
|
117
|
+
*
|
|
118
|
+
* Do NOT add ordinary third parties here; those belong in `csp.vendors` on the
|
|
119
|
+
* app that actually uses them, so unrelated apps keep the tighter policy.
|
|
120
|
+
*/
|
|
121
|
+
declare const CSP_BASELINE_VENDORS: CspVendor[];
|
|
122
|
+
/**
|
|
123
|
+
* Merge the named vendor presets into a single set of extra origins.
|
|
124
|
+
*
|
|
125
|
+
* Unknown names are ignored rather than thrown on: a typo must not break the
|
|
126
|
+
* production build of an app whose only mistake was a misspelled analytics
|
|
127
|
+
* vendor. `warnUnknown` surfaces them on the build log instead.
|
|
128
|
+
*/
|
|
129
|
+
declare function resolveCspVendors(vendors: readonly string[] | undefined, warnUnknown?: boolean): CspOrigins;
|
|
130
|
+
|
|
8
131
|
/**
|
|
9
132
|
* Base Next.js Configuration Factory
|
|
10
133
|
*
|
|
@@ -79,22 +202,48 @@ interface BaseNextConfigOptions {
|
|
|
79
202
|
* naming every future embed's origin is not worth the maintenance —
|
|
80
203
|
* `X-Content-Type-Options`/`Referrer-Policy`/`X-Frame-Options` below
|
|
81
204
|
* still apply.
|
|
82
|
-
* - object — keep the baseline CSP but additively loosen
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* leave that directive untouched.
|
|
205
|
+
* - object — keep the baseline CSP but additively loosen it. Prefer
|
|
206
|
+
* `vendors` (declare WHAT you use by name; the package owns which origins
|
|
207
|
+
* that implies) over hand-listing origins per directive. Every array is
|
|
208
|
+
* additive; omit a key to leave that directive untouched.
|
|
86
209
|
* - omitted — tightest default (`frame-src 'self'`, etc.), same as today.
|
|
87
210
|
*
|
|
211
|
+
* **The deployment platform counts as a vendor.** Some origins are injected
|
|
212
|
+
* into the response by the EDGE, after Next.js has emitted this header —
|
|
213
|
+
* Cloudflare Web Analytics rewrites `beacon.min.js` into the HTML when the
|
|
214
|
+
* feature is on for the zone. Nothing in the source tree reveals that, so
|
|
215
|
+
* any app served through such a zone must name the platform in `vendors`
|
|
216
|
+
* (e.g. `'cloudflare'`) or it will violate its own CSP in production only.
|
|
217
|
+
*
|
|
88
218
|
* @example
|
|
89
219
|
* ```ts
|
|
90
|
-
* //
|
|
91
|
-
*
|
|
220
|
+
* // Declare the third parties this app actually uses — origins come from
|
|
221
|
+
* // the shared registry, so a vendor host change is fixed in one place.
|
|
222
|
+
* createBaseNextConfig({ csp: { vendors: ['stripe', 'cloudflare'] } })
|
|
92
223
|
*
|
|
93
|
-
* //
|
|
224
|
+
* // Escape hatch for something not in the registry yet
|
|
94
225
|
* createBaseNextConfig({ csp: { frameSrc: ['https://www.youtube-nocookie.com'] } })
|
|
226
|
+
*
|
|
227
|
+
* // No CSP at all — simplest option for a low-risk app with ad hoc embeds
|
|
228
|
+
* createBaseNextConfig({ csp: false })
|
|
95
229
|
* ```
|
|
96
230
|
*/
|
|
97
231
|
csp?: false | {
|
|
232
|
+
/**
|
|
233
|
+
* Named third-party vendors this app uses (`'stripe'`, `'cloudflare'`,
|
|
234
|
+
* `'google-analytics'`, …). Each expands to the exact origins that
|
|
235
|
+
* vendor needs across the relevant directives. See `CSP_VENDOR_PRESETS`
|
|
236
|
+
* for the full list. Unknown names warn at build time, never throw.
|
|
237
|
+
*/
|
|
238
|
+
vendors?: (CspVendor | (string & {}))[];
|
|
239
|
+
/**
|
|
240
|
+
* Cloudflare Web Analytics origins are in the baseline (see
|
|
241
|
+
* `CSP_BASELINE_VENDORS`) because DjangoCFG apps are Cloudflare-served
|
|
242
|
+
* and the beacon is injected at the edge, where no app can see it.
|
|
243
|
+
* Set `false` only for an app served off Cloudflare entirely.
|
|
244
|
+
* @default true
|
|
245
|
+
*/
|
|
246
|
+
cloudflare?: boolean;
|
|
98
247
|
/** Extra `frame-src` origins (iframes this app embeds). */
|
|
99
248
|
frameSrc?: string[];
|
|
100
249
|
/** Extra `script-src` origins (third-party SDK scripts). */
|
|
@@ -430,4 +579,4 @@ declare function addCompressionPlugins(config: Configuration, options?: Compress
|
|
|
430
579
|
*/
|
|
431
580
|
declare function isCompressionAvailable(): boolean;
|
|
432
581
|
|
|
433
|
-
export { type BaseNextConfigOptions, type CompressionPluginOptions, DEFAULT_OPTIMIZE_PACKAGES, DEFAULT_TRANSPILE_PACKAGES, DJANGOCFG_PACKAGES, DJANGO_CFG_BANNER, DevStartupPlugin, type DevStartupPluginOptions, type InstallOptions, type InstallProgress, type MissingPackage, OPTIONAL_PACKAGES, PACKAGE_NAME, PEER_DEPENDENCIES, type PackageDefinition, type PackageVersion, type UpdateOptions, addCompressionPlugins, buildInstallCommand, buildSingleInstallCommand, checkAndInstallPackages, checkAndUpdatePackages, checkForUpdate, checkForUpdates, checkPackages, createBaseNextConfig, deepMerge, detectPackageManager, fetchLatestVersion, getApiUrl, getBasePath, getCurrentVersion, getInstalledVersion, getMissingPackages, getOutdatedPackages, getPackagesForContext, getSiteUrl, getUpdateCommand, installPackages, installPackagesWithProgress, isCI, isCompressionAvailable, isDev, isPackageInstalled, isProduction, isStaticBuild, printVersionInfo, resetDevStartupState, resetInstallerPreferences, resetUpdaterPreferences, updatePackagesWithProgress };
|
|
582
|
+
export { type BaseNextConfigOptions, CSP_BASELINE_VENDORS, CSP_VENDOR_PRESETS, type CompressionPluginOptions, type CspOrigins, type CspVendor, DEFAULT_OPTIMIZE_PACKAGES, DEFAULT_TRANSPILE_PACKAGES, DJANGOCFG_PACKAGES, DJANGO_CFG_BANNER, DevStartupPlugin, type DevStartupPluginOptions, type InstallOptions, type InstallProgress, type MissingPackage, OPTIONAL_PACKAGES, PACKAGE_NAME, PEER_DEPENDENCIES, type PackageDefinition, type PackageVersion, type UpdateOptions, addCompressionPlugins, buildInstallCommand, buildSingleInstallCommand, checkAndInstallPackages, checkAndUpdatePackages, checkForUpdate, checkForUpdates, checkPackages, createBaseNextConfig, deepMerge, detectPackageManager, fetchLatestVersion, getApiUrl, getBasePath, getCurrentVersion, getInstalledVersion, getMissingPackages, getOutdatedPackages, getPackagesForContext, getSiteUrl, getUpdateCommand, installPackages, installPackagesWithProgress, isCI, isCompressionAvailable, isDev, isPackageInstalled, isProduction, isStaticBuild, printVersionInfo, resetDevStartupState, resetInstallerPreferences, resetUpdaterPreferences, resolveCspVendors, updatePackagesWithProgress };
|
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.480",
|
|
18
18
|
description: "Next.js server utilities: sitemap, health, OG images, contact forms, navigation, config",
|
|
19
19
|
keywords: [
|
|
20
20
|
"nextjs",
|
|
@@ -289,6 +289,106 @@ var DEFAULT_OPTIMIZE_PACKAGES = [
|
|
|
289
289
|
"recharts"
|
|
290
290
|
];
|
|
291
291
|
|
|
292
|
+
// src/config/csp.ts
|
|
293
|
+
var CSP_VENDOR_PRESETS = {
|
|
294
|
+
/**
|
|
295
|
+
* Stripe.js / Checkout / Elements.
|
|
296
|
+
*
|
|
297
|
+
* `js.stripe.com` serves the SDK and also hosts the Elements iframes;
|
|
298
|
+
* `checkout.stripe.com` is the hosted Checkout iframe; `api.stripe.com`
|
|
299
|
+
* takes the tokenization/confirm XHR. Without all three the payment form
|
|
300
|
+
* silently fails to render.
|
|
301
|
+
*/
|
|
302
|
+
stripe: {
|
|
303
|
+
scriptSrc: ["https://js.stripe.com"],
|
|
304
|
+
frameSrc: ["https://js.stripe.com", "https://checkout.stripe.com"],
|
|
305
|
+
connectSrc: ["https://api.stripe.com"]
|
|
306
|
+
},
|
|
307
|
+
/**
|
|
308
|
+
* Cloudflare Web Analytics (the RUM beacon).
|
|
309
|
+
*
|
|
310
|
+
* IMPORTANT: this script is NOT in the app's own HTML — when Web Analytics
|
|
311
|
+
* is enabled on the zone, Cloudflare INJECTS `beacon.min.js` into the
|
|
312
|
+
* response at the edge, after Next.js has already emitted the CSP header.
|
|
313
|
+
* So any app served through a Cloudflare zone with that feature on will
|
|
314
|
+
* violate its own CSP unless this preset is enabled, no matter what the
|
|
315
|
+
* source tree contains. The beacon also POSTs its payload back to
|
|
316
|
+
* `cloudflareinsights.com`, hence the `connect-src` entry.
|
|
317
|
+
*/
|
|
318
|
+
cloudflare: {
|
|
319
|
+
scriptSrc: ["https://static.cloudflareinsights.com"],
|
|
320
|
+
connectSrc: ["https://cloudflareinsights.com", "https://static.cloudflareinsights.com"]
|
|
321
|
+
},
|
|
322
|
+
/** Google Analytics 4 / gtag.js. */
|
|
323
|
+
"google-analytics": {
|
|
324
|
+
scriptSrc: ["https://www.googletagmanager.com", "https://www.google-analytics.com"],
|
|
325
|
+
connectSrc: [
|
|
326
|
+
"https://www.google-analytics.com",
|
|
327
|
+
"https://analytics.google.com",
|
|
328
|
+
"https://region1.google-analytics.com"
|
|
329
|
+
],
|
|
330
|
+
imgSrc: ["https://www.google-analytics.com", "https://www.googletagmanager.com"]
|
|
331
|
+
},
|
|
332
|
+
/** Google Tag Manager (the container itself; tags it loads may need more). */
|
|
333
|
+
"google-tag-manager": {
|
|
334
|
+
scriptSrc: ["https://www.googletagmanager.com"],
|
|
335
|
+
connectSrc: ["https://www.googletagmanager.com"],
|
|
336
|
+
imgSrc: ["https://www.googletagmanager.com"],
|
|
337
|
+
frameSrc: ["https://www.googletagmanager.com"]
|
|
338
|
+
},
|
|
339
|
+
/** Google Fonts (stylesheet host + the font files themselves). */
|
|
340
|
+
"google-fonts": {
|
|
341
|
+
fontSrc: ["https://fonts.gstatic.com"]
|
|
342
|
+
},
|
|
343
|
+
/** Sentry browser SDK — errors/traces are POSTed to the ingest host. */
|
|
344
|
+
sentry: {
|
|
345
|
+
connectSrc: ["https://*.ingest.sentry.io", "https://*.sentry.io"]
|
|
346
|
+
},
|
|
347
|
+
/** YouTube embeds (privacy-enhanced host included). */
|
|
348
|
+
youtube: {
|
|
349
|
+
frameSrc: ["https://www.youtube.com", "https://www.youtube-nocookie.com"],
|
|
350
|
+
imgSrc: ["https://i.ytimg.com"]
|
|
351
|
+
},
|
|
352
|
+
/** Vimeo embeds. */
|
|
353
|
+
vimeo: {
|
|
354
|
+
frameSrc: ["https://player.vimeo.com"],
|
|
355
|
+
imgSrc: ["https://i.vimeocdn.com"]
|
|
356
|
+
}
|
|
357
|
+
};
|
|
358
|
+
var CSP_BASELINE_VENDORS = ["cloudflare"];
|
|
359
|
+
function resolveCspVendors(vendors, warnUnknown = true) {
|
|
360
|
+
const merged = {
|
|
361
|
+
scriptSrc: [],
|
|
362
|
+
frameSrc: [],
|
|
363
|
+
connectSrc: [],
|
|
364
|
+
imgSrc: [],
|
|
365
|
+
fontSrc: []
|
|
366
|
+
};
|
|
367
|
+
if (!vendors?.length) return merged;
|
|
368
|
+
const unknown = [];
|
|
369
|
+
for (const name of vendors) {
|
|
370
|
+
const preset = CSP_VENDOR_PRESETS[name];
|
|
371
|
+
if (!preset) {
|
|
372
|
+
unknown.push(name);
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
375
|
+
for (const key of Object.keys(merged)) {
|
|
376
|
+
const origins = preset[key];
|
|
377
|
+
if (origins) merged[key].push(...origins);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
if (unknown.length && warnUnknown) {
|
|
381
|
+
const known = Object.keys(CSP_VENDOR_PRESETS).join(", ");
|
|
382
|
+
console.warn(
|
|
383
|
+
`[djangocfg] Unknown CSP vendor(s): ${unknown.join(", ")}. Known vendors: ${known}`
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
for (const key of Object.keys(merged)) {
|
|
387
|
+
merged[key] = [...new Set(merged[key])];
|
|
388
|
+
}
|
|
389
|
+
return merged;
|
|
390
|
+
}
|
|
391
|
+
|
|
292
392
|
// src/config/packages/checker.ts
|
|
293
393
|
import { createRequire } from "module";
|
|
294
394
|
import { join } from "path";
|
|
@@ -1399,29 +1499,36 @@ function createBaseNextConfig(options = {}) {
|
|
|
1399
1499
|
const frameAncestors = hasIframeAllowlist ? options.allowIframeFrom.includes("*") ? "*" : `'self' ${options.allowIframeFrom.join(" ")}` : "'none'";
|
|
1400
1500
|
const cspDisabled = options.csp === false;
|
|
1401
1501
|
const cspExtra = typeof options.csp === "object" ? options.csp : void 0;
|
|
1402
|
-
const
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
const
|
|
1408
|
-
const
|
|
1409
|
-
|
|
1410
|
-
|
|
1502
|
+
const vendorNames = [
|
|
1503
|
+
...cspExtra?.cloudflare === false ? [] : CSP_BASELINE_VENDORS,
|
|
1504
|
+
...options.stripe ? ["stripe"] : [],
|
|
1505
|
+
...cspExtra?.vendors ?? []
|
|
1506
|
+
];
|
|
1507
|
+
const vendor = resolveCspVendors(vendorNames);
|
|
1508
|
+
const join3 = (...groups) => {
|
|
1509
|
+
const all = [...new Set(groups.flatMap((g) => g ?? []))];
|
|
1510
|
+
return all.length ? " " + all.join(" ") : "";
|
|
1511
|
+
};
|
|
1512
|
+
const extraScript = join3(vendor.scriptSrc, cspExtra?.scriptSrc);
|
|
1513
|
+
const extraConnect = join3(vendor.connectSrc, cspExtra?.connectSrc);
|
|
1514
|
+
const extraFrame = join3(vendor.frameSrc, cspExtra?.frameSrc);
|
|
1515
|
+
const extraImg = join3(vendor.imgSrc, cspExtra?.imgSrc);
|
|
1516
|
+
const extraFont = join3(vendor.fontSrc, cspExtra?.fontSrc);
|
|
1517
|
+
const connectSrc = isDev ? `connect-src 'self' http: https: ws: wss:${extraConnect}` : `connect-src 'self' https: wss:${extraConnect}`;
|
|
1411
1518
|
const imgSrc = isDev ? `img-src 'self' data: blob: http: https:${extraImg}` : `img-src 'self' data: blob: https:${extraImg}`;
|
|
1412
1519
|
if (!cspDisabled) {
|
|
1413
1520
|
const cspDirectives = [
|
|
1414
1521
|
"default-src 'self'",
|
|
1415
1522
|
// Next.js requires inline + eval for its runtime/HMR. Tighten to nonces later.
|
|
1416
|
-
`script-src 'self' 'unsafe-inline' 'unsafe-eval'${
|
|
1523
|
+
`script-src 'self' 'unsafe-inline' 'unsafe-eval'${extraScript}`,
|
|
1417
1524
|
"style-src 'self' 'unsafe-inline'",
|
|
1418
1525
|
imgSrc,
|
|
1419
1526
|
`font-src 'self' data:${extraFont}`,
|
|
1420
1527
|
// API/websocket calls go cross-origin to Django/Centrifugo.
|
|
1421
1528
|
connectSrc,
|
|
1422
|
-
// Stripe Elements/Checkout and any
|
|
1423
|
-
//
|
|
1424
|
-
`frame-src 'self'${
|
|
1529
|
+
// Declared vendors (Stripe Elements/Checkout, video embeds…) and any
|
|
1530
|
+
// app-declared trusted origins mount iframes; add their hosts here.
|
|
1531
|
+
`frame-src 'self'${extraFrame}`,
|
|
1425
1532
|
"object-src 'none'",
|
|
1426
1533
|
"base-uri 'self'",
|
|
1427
1534
|
"form-action 'self'",
|
|
@@ -1566,6 +1673,8 @@ function createBaseNextConfig(options = {}) {
|
|
|
1566
1673
|
}
|
|
1567
1674
|
export {
|
|
1568
1675
|
AI_DOCS_HINT,
|
|
1676
|
+
CSP_BASELINE_VENDORS,
|
|
1677
|
+
CSP_VENDOR_PRESETS,
|
|
1569
1678
|
DEFAULT_OPTIMIZE_PACKAGES,
|
|
1570
1679
|
DEFAULT_TRANSPILE_PACKAGES,
|
|
1571
1680
|
DJANGOCFG_PACKAGES,
|
|
@@ -1610,6 +1719,7 @@ export {
|
|
|
1610
1719
|
resetDevStartupState,
|
|
1611
1720
|
resetInstallerPreferences,
|
|
1612
1721
|
resetUpdaterPreferences,
|
|
1722
|
+
resolveCspVendors,
|
|
1613
1723
|
updatePackagesWithProgress
|
|
1614
1724
|
};
|
|
1615
1725
|
//# sourceMappingURL=index.mjs.map
|