Fix viewer API routing under Content-Security-Policy.

Pass the viewer id via a body data attribute instead of a blocked inline script so personal links still load saved data after restart.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-19 16:33:59 +02:00
parent fdeaf04280
commit e79fe34643
2 changed files with 9 additions and 6 deletions
+8 -4
View File
@@ -38,13 +38,17 @@ const CATEGORY_I18N_KEYS = {
document.addEventListener("DOMContentLoaded", init); document.addEventListener("DOMContentLoaded", init);
function getViewerId() {
return document.body?.dataset?.viewerId || "";
}
function apiBase() { function apiBase() {
const vid = window.VIEWER_ID; const vid = getViewerId();
return vid ? `/v/${vid}/api` : "/api"; return vid ? `/v/${vid}/api` : "/api";
} }
function viewerPageUrl() { function viewerPageUrl() {
const vid = window.VIEWER_ID; const vid = getViewerId();
if (!vid) return window.location.href; if (!vid) return window.location.href;
return `${window.location.origin}/v/${vid}/`; return `${window.location.origin}/v/${vid}/`;
} }
@@ -60,7 +64,7 @@ async function init() {
} }
function setupViewerBanner() { function setupViewerBanner() {
const vid = window.VIEWER_ID; const vid = getViewerId();
if (!vid || vid === "local") return; if (!vid || vid === "local") return;
const banner = document.getElementById("viewer-link-banner"); const banner = document.getElementById("viewer-link-banner");
@@ -223,7 +227,7 @@ async function loadData() {
try { try {
const res = await fetch(`${apiBase()}/snapshot/latest`); const res = await fetch(`${apiBase()}/snapshot/latest`);
if (!res.ok) { if (!res.ok) {
showEmpty(window.VIEWER_ID ? t("empty.noSaveWeb") : t("empty.noSave")); showEmpty(getViewerId() ? t("empty.noSaveWeb") : t("empty.noSave"));
return; return;
} }
state.data = await res.json(); state.data = await res.json();
+1 -2
View File
@@ -7,10 +7,9 @@
<link rel="stylesheet" href="/static/style.css"> <link rel="stylesheet" href="/static/style.css">
<script src="/static/vendor/chart.umd.min.js" defer></script> <script src="/static/vendor/chart.umd.min.js" defer></script>
<script src="/static/i18n.js" defer></script> <script src="/static/i18n.js" defer></script>
<script>window.VIEWER_ID = {{ viewer_id|tojson }};</script>
<script src="/static/app.js" defer></script> <script src="/static/app.js" defer></script>
</head> </head>
<body> <body data-viewer-id="{{ viewer_id }}">
<div class="layout"> <div class="layout">
<aside class="sidebar"> <aside class="sidebar">
<div class="brand"> <div class="brand">