domma-cms 1.6.41 → 1.6.42

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domma-cms",
3
- "version": "1.6.41",
3
+ "version": "1.6.42",
4
4
  "description": "File-based CMS powered by Domma and Fastify. Run npx domma-cms my-site to create a new project.",
5
5
  "type": "module",
6
6
  "main": "server/server.js",
package/server/server.js CHANGED
@@ -32,7 +32,7 @@ import * as cache from './services/cache/index.js';
32
32
  import {parseTrustProxy} from './services/network.js';
33
33
  import {requestSerializer} from './services/request-log.js';
34
34
  import {rateLimitOptions} from './services/rate-limit.js';
35
- import {frameSources} from './services/embedCsp.js';
35
+ import {connectSources, frameSources} from './services/embedCsp.js';
36
36
 
37
37
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
38
38
  const ROOT = path.resolve(__dirname, '..');
@@ -126,7 +126,8 @@ await app.register(helmet, {
126
126
  styleSrc: ["'self'", "'unsafe-inline'", 'https://cdn.jsdelivr.net', 'https://fonts.googleapis.com'],
127
127
  imgSrc: ["'self'", 'data:', 'blob:'],
128
128
  fontSrc: ["'self'", 'data:', 'https://fonts.gstatic.com'],
129
- connectSrc: ["'self'", 'https://cdn.jsdelivr.net'],
129
+ // config/server.json csp.connectHosts: other sites a page may read from (services/embedCsp.js).
130
+ connectSrc: connectSources(serverConfig.csp?.connectHosts),
130
131
  // [embed] players and config/embeds.json hosts - without this, default-src blocked them all.
131
132
  frameSrc: frameSources((() => { try { return getConfig('embeds')?.allowedHosts; } catch { return []; } })()),
132
133
  upgradeInsecureRequests: null, // prevent browsers forcing HTTPS on HTTP deployments
@@ -31,3 +31,22 @@ export function frameSources(allowedHosts = []) {
31
31
  .map(h => `https://${h}`);
32
32
  return [...new Set(["'self'", ...ALWAYS_FRAMED, ...extra])];
33
33
  }
34
+
35
+ /** What a page may always fetch from: the site itself and the CDN Domma's own assets come from. */
36
+ export const ALWAYS_CONNECTED = ["'self'", 'https://cdn.jsdelivr.net'];
37
+
38
+ /**
39
+ * The connect-src: the site, the CDN, and every host in config/server.json `csp.connectHosts` - for a page
40
+ * that reads another site's public API (domma-cms.com's Pricing page reads the prices dcm sells at). Bare
41
+ * hostnames only, served over https; anything else is dropped. Read at boot, like frame-src.
42
+ *
43
+ * @param {string[]} connectHosts - config/server.json csp.connectHosts
44
+ * @returns {string[]} connect-src sources
45
+ */
46
+ export function connectSources(connectHosts = []) {
47
+ const extra = (Array.isArray(connectHosts) ? connectHosts : [])
48
+ .map(h => String(h).trim().toLowerCase())
49
+ .filter(h => HOST_RE.test(h))
50
+ .map(h => `https://${h}`);
51
+ return [...new Set([...ALWAYS_CONNECTED, ...extra])];
52
+ }