fix(news): absolutize meshmonitor.org links in the news feed - #4377
Conversation
|
Claude finished @Yeraze's task —— View job PR Review
Overall this is a clean, well-scoped fix. The two-layer approach (generator + renderer) is the right design choice. A few observations:
|
|
Claude finished @Yeraze's task —— View job PR Review
Overall this is a clean, well-scoped fix. The two-layer approach (generator + renderer) is the right design choice. A few observations:
|
Blog posts link with site-root-relative paths ("/features/atak") because
that is what VitePress wants. The news feed copies post bodies verbatim,
and the News popup renders them inside a MeshMonitor instance, where a
root-relative path resolves against that instance's own base URL and
404s. The 4.13.2 post surfaced it, but 13 of 45 feed items were affected,
including every inline image.
Fix at the generator, so blog markdown stays portable: blog-to-news.mjs
now rewrites root-relative markdown links, images, reference definitions,
and raw href/src attributes to https://meshmonitor.org. Protocol-relative,
absolute, anchor, and mailto targets are left alone.
The News popup also rewrites root-relative href/src on render, so items
already published to the live feed work without waiting for a docs
rebuild.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9NzRtqE8eSMS8tvAeodUB
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9NzRtqE8eSMS8tvAeodUB
CodeQL flagged `out.match(/https:\/\/meshmonitor\.org/g)` as an unanchored URL-host regex (js/incomplete-url-substring-sanitization). It was never a sanitization check — it counted rewrites in generator output — but an exact-output assertion is a stronger test and drops the pattern entirely. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9NzRtqE8eSMS8tvAeodUB
5288b9a to
7da0d1c
Compare
|
Claude finished @Yeraze's task —— View job PR Review
Overall this is a clean, well-scoped fix. The two-layer approach (generator rewrite + render-time fallback) is the right design. Previous automated reviews have already covered most angles; this review adds a few additional observations.
|
Summary
Blog posts link with site-root-relative paths (
/features/atak) because that is what VitePress wants.scripts/blog-to-news.mjscopies post bodies verbatim intonews.json, and the News popup renders that markdown inside a MeshMonitor instance — where/features/atakresolves against the instance's own base URL and 404s instead of opening meshmonitor.org.The 4.13.2 release post surfaced it, but this was never a one-post problem: 13 of 45 feed items carried 64 root-relative targets, including every inline image in the offline-emergency-kit post.
Fixed at the generator so blog markdown stays portable for the docs site, plus a render-time rewrite in the popup so items already published to the live feed work without waiting for a docs rebuild.
Changes
scripts/blog-to-news.mjs— newabsolutizeLinks()rewrites root-relative markdown links, images, reference-style definitions, and rawhref/srcattributes tohttps://meshmonitor.orgas posts flow intonews.json. Protocol-relative (//cdn…), absolute, anchor, andmailto:targets are left alone. The helper is exported and the top-level run is guarded by the usualprocess.argv[1] === fileURLToPath(import.meta.url)check (same pattern aslint-ratchet.mjs) so it is unit-testable; VitePress still invokes it viaspawnSync, unchanged.src/components/NewsPopup/NewsPopup.tsx— theaandimgReactMarkdown renderers absolutize root-relative URLs. This covers feed items already published relative, and is the only part that helps instances reading the live feed before the docs redeploy.scripts/blog-to-news.test.mjs— 7 tests over the absolutizer (links, images, fragments, raw HTML, reference definitions, the leave-alone cases, multi-link documents).src/components/NewsPopup/NewsPopup.test.tsx— 4 tests rendering the popup against a mocked feed, asserting the resolvedhref/src.CHANGELOG.md— entry under[Unreleased].Blog post sources are deliberately not edited — relative links are correct on meshmonitor.org and keep VitePress client-side routing working.
docs/public/news.jsonis gitignored and regenerated by the docs build, so the site rebuild picks this up on its own.Issues Resolved
None filed — reported directly against the 4.13.2 news item.
Documentation Updates
CHANGELOG.md—[Unreleased] / Fixedentry.absolutizeLinks(), which is where an author would look.Testing
success: true(679 pending are the PostgreSQL/MySQL suites skipping with no local containers; no schema is touched here)npx tsc -p tsconfig.server.json --noEmitcleannpm run lint:ciclean (no in-repoFAILlines)news.jsonand verified: 0 root-relative targets remain, 64 absolutized, and the diff contains no non-link changesnpm run docs:news, then confirm the 4.13.2 item's ATAK and receive-only links readhttps://meshmonitor.org/features/…, and that the GitHub changelog link is untouchedBASE_URL(e.g./meshmonitor) and confirm links open meshmonitor.org rather than the local instance🤖 Generated with Claude Code