TODO#
Lexicon Publisher#
Remaining issues from code review (2025-12-23).
Important#
CSP unsafe-inline vulnerability#
lexicon-publisher.html:7-9
The CSP includes 'unsafe-inline' for both scripts and styles, which defeats much of the purpose of having a CSP. Requires major refactor to move inline scripts/styles to external files or use nonces.
Pin quickslice to specific version#
lexicon-publisher.html:777
Currently using @main branch which can change at any time. Pin to a specific commit or tag and add SRI integrity attribute.
Validate DNS lookup inputs#
lexicon-publisher.html:1802-1812
The resolveDNS() function directly uses user-controlled domain names without validation. Should validate domain names against RFC standards before DNS lookup.
Full re-render performance#
lexicon-publisher.html
renderAllSteps() rebuilds the entire UI on every state change, losing focus/scroll position. Consider targeted updates for specific UI sections.
Accessibility improvements#
lexicon-publisher.html
- Add
role="progressbar"orrole="tablist"for wizard - Add
aria-labelto buttons with only icons - Add
aria-liveregions for status messages - Add
aria-expandedfor collapsible sections - Make step headers keyboard navigable
- Add escape key handler for dialogs
Medium#
escapeAttr() missing single quote escape#
lexicon-publisher.html:940
Add .replace(/'/g, "'") to prevent attribute injection with single quotes.
Domain extraction edge cases#
lexicon-publisher.html:1672-1698
getUserDomain() assumes all domains are TLD + SLD (e.g., example.com). Fails for country-code TLDs like .co.uk. Consider using a public suffix list.
No file count limit in ZIP#
lexicon-publisher.html:2044-2051
While there's a check for zero files, there's no upper limit. A ZIP with thousands of files could freeze the browser. Add reasonable limit (e.g., 100 files).
Clipboard API fallback#
lexicon-publisher.html:1836-1840
No user feedback on success/failure and no fallback for older browsers. Add toast notification and document.execCommand('copy') fallback.
OAuth callback race condition#
lexicon-publisher.html:2130-2146
If handleRedirectCallback() fails, the URL still has ?code=... but history is only replaced on success. Move window.history.replaceState() to a finally block.
Low Priority#
Split into multiple files#
lexicon-publisher.html (2200+ lines)
Consider splitting into separate HTML, CSS, and JS files for maintainability. This would also help solve the CSP unsafe-inline issue.
Add lexicon preview#
Users can't see what a lexicon defines without reading JSON. Add human-readable schema preview.
Add export functionality#
Users can upload ZIPs but can't download their lexicons. Add "Export as ZIP" feature.
Add schema templates#
Provide multiple templates: record, query, procedure, subscription.
Real-time validation#
Add debounced validation as users type instead of only on "Continue to Publish".