feat(captcha): implement MAT-140 CAPTCHA pipeline
Summary
- add a persistent CAPTCHA challenge model, SQLite log, queue coordination, startup recovery, and safe timeout handling
- propagate hoster CAPTCHA requirements through the engine, CQRS commands and queries, Tauri events, and five IPC commands
- add the manual solver UI, queue/history view, timeout settings, and EN/FR translations
- keep answers transient, redact terminal challenge payloads, bound raster inputs, and cover rollback and concurrency failure paths
Verification
- cargo test --manifest-path src-tauri/Cargo.toml --workspace
- npx vitest run
- cargo clippy --manifest-path src-tauri/Cargo.toml --workspace -- -D warnings
- npm run build
- npx oxlint .
- targeted oxfmt check for every touched frontend file
- full pre-push gate: knip, cargo-deny, TypeScript typecheck/tests, Rust tests
Result: 734 frontend tests passed; 1,728 Rust unit tests and 4 Rust integration tests passed. Five OS/format-dependent unit tests and two doctests remain ignored.
Scope note
reCAPTCHA/hCaptcha solving and a plugin ABI for submitting a manual answer remain out of scope for MAT-140. The current official 1fichier flow surfaces these challenge types as unsupported so the user can skip or retry; image/text challenges are handled by the manual solver.
Linear: MAT-140
Summary by cubic
Implements the end-to-end manual CAPTCHA pipeline with a separate queue, CQRS/Tauri events, UI, timeout with automatic download resumption, compact base64 image transport, and persistent SQLite captcha_log (with migration). Also hardens recovery and removal flows. Satisfies Linear MAT-140 acceptance.
-
New Features
- Separate CAPTCHA queue that doesn’t block download slots; solving resumes, skipping fails with a clear reason. Emits
download-queuedwhen re-queued. - Commands:
captcha_solve,captcha_skip,captcha_retry; Queries:captcha_list,captcha_get_pending; Tauri events:captcha-pending,captcha-solved,captcha-skipped,captcha-timed-out. - Hoster plugin contract surfaces CAPTCHA (
requires_captcha, type, optional image); engine emits typed internalCaptchaRequired. - React UI: solver panel, queue/history, countdown, solver settings, EN/FR translations; compact base64 image + MIME type; redacted history and bounded plugin payloads.
- Config:
captcha_timeout_secondswith safe defaults and bounds; clean scheduling on CAPTCHA and startup recovery.
- Separate CAPTCHA queue that doesn’t block download slots; solving resumes, skipping fails with a clear reason. Emits
-
Bug Fixes
- Startup recovery re-arms pending CAPTCHA timeouts; cancel/remove now atomically coordinate engine cancellation with challenge cleanup.
- Event forwarding filters internal
captcha-requiredto avoid frontend races; download logging includesdownload-queuedand CAPTCHA lifecycle entries.
Summary by CodeRabbit
- New Features
- Added a persistent CAPTCHA queue for protected downloads with solve/skip/retry actions, automatic timeout handling, and capped history.
- Introduced SQLite-backed CAPTCHA persistence, new CAPTCHA Tauri commands/queries, and React UI for the queue, challenge panel, and solver settings.
- Added configurable CAPTCHA timeout with settings/UI support, input safety limits, and updated English/French translations.
- Exposed new lifecycle events, including
download-queued, plus CAPTCHA pending/solved/skipped/timed-out.
- Bug Fixes
- Improved CAPTCHA-aware recovery and cancellation for downloads waiting on challenges, plus safer event forwarding and enhanced CAPTCHA lifecycle logging.