Changeset c6185fa in Klonkt


Ignore:
Timestamp:
07/24/2026 09:30:48 PM (7 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
c1f5c23
Parents:
fcd6964
git-author:
Robin <roboburr@…> (07/24/2026 09:30:36 PM)
git-committer:
Robin <roboburr@…> (07/24/2026 09:30:48 PM)
Message:

Guardian-PWA: CSP-nonce injecteren zodat de JS laadt

DIT was de echte oorzaak van "guardian-PWA doet niks / hangt / niks functioneel",
en waarom cache legen en incognito nooit hielpen: het is geen caching.

De guardian-PWA wordt direct met res.render gerenderd, NIET via renderPage. Alleen
renderPage draait injectCspNonce over de HTML. Onze CSP is strict-dynamic + per-
request nonce, dus een <script src="/guardian/app.js"> zonder nonce wordt door de
browser geweigerd (precies de fout die Robin zag op boiert.eu). Gevolg: guardian.js
laadde nooit, dus alle knoppen deden niks. Dit gold ook al voor de oude
/assets/js/guardian.js; de no-cache-verhuizing veranderde daar niks aan.

Fix: de guardian-render door injectCspNonce halen, net als de rest van de app.
injectCspNonce is nu exporteerbaar. Geverifieerd: na injectie heeft het app.js-
script de per-request nonce.

Changed files:
src/middleware/render.js

  • injectCspNonce geexporteerd

src/routes/guardian.js

  • guardian-PWA gerenderd naar string en nonce geinjecteerd (anders blokkeert strict-dynamic de JS)

remarks: embed-player zet een eigen CSP (unsafe-inline) en is niet geraakt. Tests 6/6.

-robo
Co-Authored-By: Claude Opus 4.8 <noreply@…>

Location:
src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/middleware/render.js

    rfcd6964 rc6185fa  
    2727// partials. HTML-escaped "&lt;script" in rendered content (e.g. sanitized post bodies) won't
    2828// match, so this only touches real tags.
    29 function injectCspNonce(html, nonce) {
     29export function injectCspNonce(html, nonce) {
    3030  if (!html || !nonce) return html;
    3131  return String(html).replace(/<script(?![^>]*\snonce=)/gi, () => `<script nonce="${nonce}"`);
  • src/routes/guardian.js

    rfcd6964 rc6185fa  
    1717import * as Guardianship from '../services/guardianship/index.js';
    1818import { t as i18nT, resolveLang } from '../services/i18n.js';
     19import { injectCspNonce } from '../middleware/render.js';
    1920
    2021const router = express.Router();
     
    6364  if (!site) return res.status(404).send('No site for this account.');
    6465  const sites = db.prepare('SELECT slug, title FROM sites WHERE owner_id = ? ORDER BY id').all(req.session.user.id);
     66  // This standalone PWA page is rendered directly (not through renderPage), so
     67  // the CSP nonce must be injected here — otherwise strict-dynamic blocks
     68  // guardian.js and the whole dashboard is dead (buttons do nothing).
    6569  res.render('pages/guardian', {
    6670    state: dashboardState(site, L),
     
    6973    t: (k, v) => i18nT(L, k, v),
    7074    cspNonce: res.locals.cspNonce,
     75  }, (err, html) => {
     76    if (err) { console.error('[guardian] render error', err); return res.status(500).send('Internal Server Error'); }
     77    res.send(injectCspNonce(html, res.locals.cspNonce));
    7178  });
    7279});
Note: See TracChangeset for help on using the changeset viewer.