Changeset 5421ce1 in Klonkt
- Timestamp:
- 06/27/2026 09:30:42 AM (2 months ago)
- Branches:
- main
- Children:
- 07de464
- Parents:
- ca0ad44
- File:
-
- 1 edited
-
src/middleware/render.js (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/middleware/render.js
rca0ad44 r5421ce1 53 53 }; 54 54 55 // Cross-site Klonkt audio embeds (a followed/boosted site's /embed player) need their 56 // origins in the DOCUMENT CSP frame-src — the per-/news injection is ignored once you 57 // navigate there via htmx (the document's CSP governs, not the partial's). Collect the 58 // distinct origins from the site's timeline (followed + boosted). Cached 60s. 59 const _embedOriginsCache = new Map(); // slug -> { origins, exp } 60 function embedOriginsFor(slug) { 61 const now = Date.now(); 62 const c = _embedOriginsCache.get(slug); 63 if (c && c.exp > now) return c.origins; 64 let origins = []; 65 try { 66 const rows = db.prepare('SELECT DISTINCT url FROM ap_timeline WHERE slug = ? AND url IS NOT NULL').all(slug); 67 const set = new Set(); 68 for (const r of rows) { try { set.add(new URL(r.url).origin); } catch { /* skip bad url */ } } 69 origins = [...set]; 70 } catch { origins = []; } 71 _embedOriginsCache.set(slug, { origins, exp: now + 60000 }); 72 return origins; 73 } 74 55 75 export async function renderPage(req, res, viewName, data = {}) { 56 76 // Decide: partial (HTMX) or full? … … 93 113 // to hide/disable write buttons (post, save, delete). 94 114 const _isViewer = isViewer(_u); 115 116 // Per-domain CSP: let a logged-in site manager frame the Klonkt players of the sites in 117 // their timeline (followed + boosted) on the DOCUMENT, so cross-site embeds also work 118 // after an htmx/PWA navigation. NEVER on authorize_interaction — that page shows 119 // untrusted remote content next to the interact buttons, so no embeds / no frame-src 120 // loosening there (clickjacking risk). 121 try { 122 if (_site && _site.slug && viewName !== 'pages/authorize-interaction' && _u && PermissionsService.canAdminSite(_u, _site)) { 123 const origins = embedOriginsFor(_site.slug); 124 if (origins.length) { 125 const csp = res.getHeader('Content-Security-Policy'); 126 if (csp) res.setHeader('Content-Security-Policy', String(csp).replace(/frame-src ([^;]*)/i, (m, g) => `frame-src ${g} ${origins.join(' ')}`)); 127 } 128 } 129 } catch { /* CSP extension is best-effort */ } 95 130 96 131 // Who sees the "Admin" link? god/admin, a site owner (artist self-manage),
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)