feat: CDN citation-key resolution, WSL2 auth fix, content_word_match method#386
feat: CDN citation-key resolution, WSL2 auth fix, content_word_match method#386bensonwong merged 9 commits intomainfrom
Conversation
The /verify workflow now emits data-citation-key directly (instead of data-cite). Extend resolveKeyMap() to also replace human-readable data-citation-key values with their hashed counterparts from the key map. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Windows browsers cannot reach 127.0.0.1 inside WSL2. Binding to 0.0.0.0 makes the callback server reachable. The 64-char random nonce prevents unauthorized callers from exploiting the broader bind address. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The second loop (data-citation-key resolution) used to re-process elements that the first loop had already set data-citation-key on. Use :not([data-cite]) selector to exclude them. Adds a regression test for the overlap case. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The comment incorrectly stated the callback server only runs on 127.0.0.1. Updated to reflect the WSL2 binding change and nonce-based security model. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New SearchMethod variant for content-word matching. Adds the type discriminant, narrative mapping, and translations for all locales. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Both attribute-resolution loops shared identical logic differing only in selector and source attribute. Extracted into a private helper and dropped the redundant Object.hasOwn guard (missing keys yield undefined which already fails the typeof check). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 4 Skipped Deployments
|
Code ReviewOverall this is a well-structured PR with clear separation of concerns. A few things worth discussing:
|
| Area | Verdict |
|---|---|
| CDN keymap refactor | ✅ Approve with nit (restore Object.hasOwn) |
| Auth WSL2 fix | |
content_word_match |
✅ Approve |
| Tests | ✅ Approve, suggested one additional case |
The WSL2 change is the only item I'd want resolved before merge. Everything else is low-risk.
✅ Playwright Test ReportStatus: Tests passed 📊 Download Report & Snapshots (see Artifacts section) What's in the Visual SnapshotsThe gallery includes visual snapshots for:
Run ID: 23702718837 |
- Restore Object.hasOwn guard in resolveEls for explicit own-property intent - WSL2-conditional binding: only use 0.0.0.0 when WSL_DISTRO_NAME is set, keep 127.0.0.1 loopback-only elsewhere for defense-in-depth - Update CORS comment to reflect conditional binding logic - Add symmetric test: current-path elements resolve even when value looks like a hash (documents the asymmetry with legacy double-processing guard) - Fix French translation: "mots de contenu" (content words) not "mots-clés" (keywords) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Spanish: "palabras clave" (keywords) → "palabras de contenido" (content words) to match en/fr/vi translations - Test: element with both data-cite and pre-existing data-citation-key verifies legacy path overwrites and current path skips via :not([data-cite]) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Code ReviewOverall this is a clean, well-scoped PR. A few things worth flagging before merge: CDN keymap refactor ✅The One minor nit: the PR description says "4 new tests" but the diff adds 6 WSL2 auth fix — security surface worth notingconst host = process.env.WSL_DISTRO_NAME ? "0.0.0.0" : "127.0.0.1";Two observations: 1. 2. Binding if (req.method === "GET" && req.url === "/health") {
sendJson(res, 200, { ok: true }, origin);
return;
}On a shared or corporate network, this lets anyone on the LAN confirm the server is listening on the ephemeral port (though they can't complete auth without the nonce). Reasonable to accept this tradeoff for a developer tool, but it should be documented. Suggesting either:
|
| Area | Status |
|---|---|
| CDN keymap refactor | ✅ Approve |
| Double-processing guard + tests | ✅ Approve |
content_word_match + i18n |
✅ Approve |
WSL2 auth: WSL_DISTRO_NAME matches WSL1 too |
Minor / worth noting in comments |
WSL2 auth: /health exposed on 0.0.0.0 |
Minor / acceptable risk, but worth a comment |
Happy to approve once the WSL1 vs WSL2 comment is clarified (or acknowledged as intentional).
Address code review feedback: WSL_DISTRO_NAME is set in both WSL1 and WSL2, not just WSL2. Also document that binding 0.0.0.0 exposes the /health endpoint on LAN during the login window (acceptable tradeoff since auth completion still requires the 64-char nonce). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
resolveKeyMap()to resolve human-readabledata-citation-keyattributes (current/verifyworkflow) in addition to legacydata-citeattributes. Extracted shared loop logic into aresolveElshelper and fixed a double-processing bug where legacy elements would be re-resolved by the second pass.0.0.0.0instead of127.0.0.1so Windows browsers can reach it under WSL.WSL_DISTRO_NAMEis set in both WSL1 and WSL2; binding is unnecessary but harmless in WSL1. The 64-char random nonce prevents unauthorized callers. Updated a stale CORS comment that still referenced the old127.0.0.1binding.content_word_matchto theSearchMethodtype union with i18n support across all locales (en, es, fr, vi).Test plan
bun test src/__tests__/cdnPopover.test.tsx— 6 new tests fordata-citation-keyresolution (happy path, unknown value pass-through, mixed elements, double-processing guard, legacy overwrite edge case, hash-like value edge case)bun test src/__tests__/i18nLocales.test.ts— verify locale parity for newcontentWordMatchkeybun test— full suite passesdeepcitation loginfrom WSL2 and confirm the browser callback completes🤖 Generated with Claude Code