diff --git a/pb_public/index.html b/pb_public/index.html index d4f4c3b..d6a4f3e 100644 --- a/pb_public/index.html +++ b/pb_public/index.html @@ -1201,22 +1201,45 @@ async function loadDownloads(){ li.style.cssText="padding:12px;border:1px solid var(--line);border-radius:10px;"+ "margin-bottom:8px;background:var(--sunk);font-size:14px;list-style:none"; if (m.ok && m.data && m.data.available){ - // `releases.file` is a protected file: the path alone 403s, it needs a - // short-lived file token. Minted per link, exactly as the landing page does. - var t=await api("POST","/api/files/token",null); - var href=(t.ok && t.data && t.data.token) - ? m.data.downloadPath+"?token="+encodeURIComponent(t.data.token) : null; + // **The token is minted when the button is pressed, not when this list is + // built.** `releases.file` is protected, so the path needs a file token, and a + // file token lives 180 seconds — measured, not assumed. Baking one into the + // href at render time meant every download button died three minutes after + // the page loaded, permanently, until someone thought to reload. PocketBase + // answers an expired token with 404 "The requested resource wasn't found.", + // which reads like the file is gone rather than like "press it again". + // + // That is not a hypothetical: a friend hit it on the Windows build. The setup + // flow makes it near-certain, because it walks somebody through buying + // subscriptions and fetching a TMDB key before it points them here, which is + // many minutes, and the download tab may have been rendered at sign-in. li.innerHTML='