add: auto-open Proton's verification page in the gui's browser #154

Merged
mysticalsoap merged 1 commit from captcha-auto-open into trunk 2026-08-24 16:24:01 -04:00
Owner

Problem

Proton gates every aqomui login behind a CAPTCHA (#150). After #146 the token rides the retry automatically — and that full solve→retry→import cycle is already verified live — but the human still has to fish the verification URL out of the log tab and retype their credentials afterwards.

Fix

Option 1 from the issue, plus the retry: a dedicated signal chain for the URL. The provider emits verification_needed(url) on the import thread, the service forwards it as a new human_verification_needed D-Bus signal, and the gui opens the page with QDesktopServices.openUrl — the user's real browser, in their session.

The failed payload gained an optional 4th field naming the kind of failure. A verification failure presents as an Information dialog (it's an expected step, not an error): "A verification page just opened in your browser / Solve it, then continue" with Close / Continue buttons. Continue re-fires the stored import, so the solved token rides a fresh attempt with no retyping — except a 2FA code, which has usually expired by the time the page is solved, so Continue prompts for a fresh one (cancelling the prompt abandons the retry). Clicking Continue before solving is harmless — the retry draws a fresh demand and the same dialog again. A provider guard keeps a scheduled auto-update's demand from re-firing an unrelated stored import.

The stored payload holds the account password, so the gui drops it the moment the import flow ends any way but a pending verification (success, hard failure, Close, cancelled 2FA prompt). 3-field payloads behave exactly as before; the cli already tolerates extra fields.

Verification

  • pytest: 351 passed; CAPTCHA test asserts the emitted URL + 4-field payload; new gui tests cover Continue/Close/unrelated-import/2FA-reprompt/cancelled-prompt and credential dropping.
  • CI lint gate (ruff, compileall) clean locally.
  • An earlier revision (auto-open + log link, no Continue button) was verified against a live 9001; the dialog/retry revision needs one more build-branch-and-install.sh round before merge.

Why not the QtWebEngine view (option 3)

Checked the claims rather than hand-waving: qt5-webengine is a 163 MiB installed optdepend, and Qt5's WebEngine is frozen on a Chromium 87-era engine (2020) — a stale engine with a fresh, cookie-less profile is exactly what anti-bot checks score against, so the embedded view is both the heaviest option and the one most likely to fail the CAPTCHA it exists to solve. The real browser wins on every axis. (Revisit only after #155.)

🤖 Generated with Claude Code

## Problem Proton gates every aqomui login behind a CAPTCHA (#150). After #146 the token rides the retry automatically — and that full solve→retry→import cycle is already verified live — but the human still has to fish the verification URL out of the log tab and retype their credentials afterwards. ## Fix Option 1 from the issue, plus the retry: a dedicated signal chain for the URL. The provider emits `verification_needed(url)` on the import thread, the service forwards it as a new `human_verification_needed` D-Bus signal, and the gui opens the page with `QDesktopServices.openUrl` — the user's real browser, in their session. The failed payload gained an optional 4th field naming the kind of failure. A `verification` failure presents as an Information dialog (it's an expected step, not an error): *"A verification page just opened in your browser / Solve it, then continue"* with **Close / Continue** buttons. Continue re-fires the stored import, so the solved token rides a fresh attempt with no retyping — except a 2FA code, which has usually expired by the time the page is solved, so Continue prompts for a fresh one (cancelling the prompt abandons the retry). Clicking Continue before solving is harmless — the retry draws a fresh demand and the same dialog again. A provider guard keeps a scheduled auto-update's demand from re-firing an unrelated stored import. The stored payload holds the account password, so the gui drops it the moment the import flow ends any way but a pending verification (success, hard failure, Close, cancelled 2FA prompt). 3-field payloads behave exactly as before; the cli already tolerates extra fields. ## Verification - `pytest`: 351 passed; CAPTCHA test asserts the emitted URL + 4-field payload; new gui tests cover Continue/Close/unrelated-import/2FA-reprompt/cancelled-prompt and credential dropping. - CI lint gate (`ruff`, `compileall`) clean locally. - An earlier revision (auto-open + log link, no Continue button) was verified against a live 9001; the dialog/retry revision needs one more `build-branch-and-install.sh` round before merge. ## Why not the QtWebEngine view (option 3) Checked the claims rather than hand-waving: `qt5-webengine` is a 163 MiB installed optdepend, and Qt5's WebEngine is frozen on a Chromium 87-era engine (2020) — a stale engine with a fresh, cookie-less profile is exactly what anti-bot checks score against, so the embedded view is both the heaviest option and the one most likely to fail the CAPTCHA it exists to solve. The real browser wins on every axis. (Revisit only after #155.) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
add: auto-open Proton's verification page in the gui's browser
Some checks failed
ci / test (pull_request) Has been cancelled
0401af9b9e
The CAPTCHA demand surfaces inside the root service, which cannot open
a browser, and the failed payload cannot carry the URL (& is its field
separator) - so the URL rides a dedicated signal chain instead:
provider thread -> service -> human_verification_needed D-Bus signal ->
gui, which opens it with QDesktopServices and lets the existing failed
modal explain the flow.

The user's real browser is deliberate, not just cheap: an embedded
QtWebEngine view (old qomui's AirVPN approach) would pin a Chromium
87-era engine with a fresh cookie-less profile against an anti-bot
check - likelier to fail it - and cost a 163 MiB optdepend.

Closes #150

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
mysticalsoap force-pushed captcha-auto-open from 0401af9b9e
Some checks failed
ci / test (pull_request) Has been cancelled
to 20c6bbc1e1
All checks were successful
ci / test (pull_request) Successful in 30s
2026-08-24 15:38:19 -04:00
Compare
mysticalsoap force-pushed captcha-auto-open from 20c6bbc1e1
All checks were successful
ci / test (pull_request) Successful in 30s
to 9a0512fe56
All checks were successful
ci / test (pull_request) Successful in 27s
2026-08-24 15:51:40 -04:00
Compare
mysticalsoap force-pushed captcha-auto-open from 9a0512fe56
All checks were successful
ci / test (pull_request) Successful in 27s
to 23ff1adda4
All checks were successful
ci / test (pull_request) Successful in 30s
2026-08-24 15:58:44 -04:00
Compare
mysticalsoap force-pushed captcha-auto-open from 23ff1adda4
All checks were successful
ci / test (pull_request) Successful in 30s
to 4cd43739c5
All checks were successful
ci / test (pull_request) Successful in 28s
2026-08-24 16:08:21 -04:00
Compare
mysticalsoap force-pushed captcha-auto-open from 4cd43739c5
All checks were successful
ci / test (pull_request) Successful in 28s
to add140e3f7
All checks were successful
ci / test (pull_request) Successful in 29s
ci / test (push) Successful in 30s
2026-08-24 16:20:40 -04:00
Compare
mysticalsoap deleted branch captcha-auto-open 2026-08-24 16:24:01 -04:00
Sign in to join this conversation.
No description provided.