v0.1.1 — Security + hardening
Security & code-quality release
Security
- Path traversal in
mirror_browseanddelete_mirror— resolved paths are now confined to the mirror/output directory (returns 403/404) - XSS in clone log — switched from Alpine
x-htmltox-textso mirrored page titles can't inject HTML - Extension credentials moved from
chrome.storage.sync→chrome.storage.local(no longer synced to Google's servers) - Constant-time credential comparison (
hmac.compare_digest) in Basic Auth and login routes
Bugs
- Missing
MBunit label in size formatting - Page count pluralization (
1 pagevs2 pages) mirror_browsehardcodedtext/htmlmimetype — now guesses from file extension (CSS/JS/images serve correctly in the iframe browser)/api/jobsendpoints no longer leak subprocess stdoutlines- Missing kage binary raises
KageNotFoundErrorwith install instructions instead of crashing the reader thread
Code quality
get_mirroris O(1) (direct path check, no full directory scan)- Thread-safe job dictionary access (
_job_lockon all mutations/reads) get_job_rawadded for WebSocket streaming; API-facingget_jobreturns clean snapshots
Tests
24 → 49 tests. New coverage: parse_clone_output (8 cases), path traversal regression, mimetype, lines exclusion, constant-time auth, _build_mirror.
Docs
- README screenshots (dashboard + mirror detail) added in v0.1.0 follow-up