From d82b65059cb9c580b4c95ca9e9cfd953dfa1b39f Mon Sep 17 00:00:00 2001 From: screentinker Date: Fri, 24 Jul 2026 16:41:18 -0500 Subject: [PATCH] fix(dashboard): make the "Reload now" update toast actually clickable (#229) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "Dashboard updated. Reload now" toast (fired when /api/version's hash changes after a deploy) used `href="javascript:location.reload()"`. The dashboard CSP is `script-src 'self'` with no 'unsafe-inline', which blocks `javascript:` URIs — so the link was dead: clicking it did nothing but log a CSP violation. Users had to hard-refresh manually. Build the link and attach a real click listener (first-party script, CSP-clean) instead of the inline javascript: href. No behaviour change beyond the link now working; text unchanged. Co-authored-by: Claude Opus 4.8 (1M context) --- frontend/js/app.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/frontend/js/app.js b/frontend/js/app.js index 8365353..4593fc7 100644 --- a/frontend/js/app.js +++ b/frontend/js/app.js @@ -619,7 +619,19 @@ async function checkVersion() { if (toast) { const notice = document.createElement('div'); notice.className = 'toast info'; - notice.innerHTML = 'Dashboard updated. Reload now'; + const span = document.createElement('span'); + span.textContent = 'Dashboard updated. '; + const link = document.createElement('a'); + link.textContent = 'Reload now'; + link.href = '#'; + link.style.cssText = 'color:var(--accent);text-decoration:underline;font-weight:600'; + // The dashboard CSP is `script-src 'self'` (no 'unsafe-inline'), which blocks + // `javascript:` URIs — so the old `href="javascript:location.reload()"` link was dead + // (click did nothing, only a CSP console warning). Use a real click listener, which + // runs as first-party script and is CSP-clean. + link.addEventListener('click', (e) => { e.preventDefault(); location.reload(); }); + span.appendChild(link); + notice.appendChild(span); toast.appendChild(notice); } }