Release · v3.14.10
Stop the URL sanitizer killing every publication…
fix(v3): stop the URL sanitizer killing every publication link
Details
Every link in the v3 Selected Publications section was a dead `href="#"`, so clicking one (e.g. arXiv under the TPP paper) only scrolled the page to the top. 27 links across all 9 publications were affected — arXiv, ACM, IEEE, OpenReview, Code, Video, Poster, Presentation, Research Gate, Proceedings, News Article. Cause: `v3RenderPubLinks` routed each URL through `dbSafeExternalUrl`, whose scheme allow-list is http/https/mailto. But the renderer runs BEFORE `applyDbLinks`, so its URLs are still unresolved `db://<key>` placeholders — the unknown `db:` scheme collapsed to '#'. That both killed the link and hid it from the resolver, which selects on `[href^="db://"]` and so could never repair it. Fix: add `dbSafeLinkHref`, the placeholder-aware variant, for renderers that emit markup before resolution. It passes a `db://` placeholder through untouched and scheme-checks everything else exactly as before. Resolution itself is unchanged and still sanitizes the URL it writes into the DOM, so the security property is preserved: no unsanitized URL ever becomes a navigable href. `db://` is now a named constant shared by the helper and the resolver's selector so they can't drift. Tests: `v3RenderPubLinks` must emit placeholders intact (fails on the old code with exactly the shipped `href="#"`), plus `dbSafeLinkHref` unit coverage including the look-alikes `db:` and `DB://`, which stay rejected. Verified against live Supabase data with the fixed bundle injected into the production page: 27/27 links resolve — 21 external (all target=_blank, arXiv click opens arxiv.org, no scroll) and 6 masked to the in-tab /view.html viewer (click renders the PDF). Clean across dark/light x desktop/mobile x weather on/off x all four seasons. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012ZejPEHvD8ombiu37aHbGY
Files changed (4)
| frontend/client/tests/db-assets-core.test.mjs | +27 | −2 |
| frontend/client/tests/publication-list.test.mjs | +18 | −0 |
| frontend/client/ts/components/publication-list.ts | +7 | −3 |
| frontend/client/ts/core/db_assets.ts | +20 | −2 |