Skip to content

[Bug]: v6/MegaTransition login: legacy CAPTCHA after v6 success blocks the connected signal and the (legacy-only) device list — regression 4.0.0 → 4.1.0 #953

Description

@tareko

Note: I used Opencode and Qwen 3.6 27b / GLM 5.2 to find this bug

Version

eufy-security-client 4.1.0 (also reproducible on 4.1.1 / master). Via bropat/eufy-security-ws 3.1.0.

Regression

4.0.0 → 4.1.0. 4.0.0 logs in legacy-first (HTTPApi.login + email 2FA + addTrustDevice) and works. 4.1.0 enables the new MegaTransition (v6-first) login, which breaks for a new/trusted device.

Environment

  • Standalone bropat/eufy-security-ws Docker (not the HA add-on); WS clients drive the API directly.
  • Region: CA. Fresh device (first login).

Reproduction

  1. Fresh data dir → connect() (no code).
  2. MegaTransition.loginMega requests email 2FA (v6 login: email 2FA required — call loginMega(code)), pendingChallenge = "mega".
  3. Submit the code via the WS driver.set_verify_codedriver.connect({ verifyCode })runConnect → PHASE 1 loginMega(code):
[http] [MegaHTTPApi.login] MegaApi login ok { auth_token, token_expires_at, token_id, trust_list, ... }
[main] [MegaTransition.loginMega] v6 login: success, mega session persisted
  1. PHASE 2 then runs the legacy login (best-effort), and the legacy backend returns LOGIN_NEED_CAPTCHA:
[http] [HTTPApi.login] ... endpoint: 'v2/passport/login_sec', verifyCode: undefined
[http] [HTTPApi.loginRequestCaptcha] Login - Captcha verification received
[http] [HTTPApi.loginRequestCaptcha] Please send requested captcha to proceed with authentication
  1. Result: pendingChallenge = "legacy", and runConnect returns early at the PHASE-2 guard — PHASE 3 (onAPIConnect) never runs despite megaLoggedIn === true. No push connect, no Connected to station, and start_listening returns 0 stations / 0 devices.

Why devices never load (the deeper issue)

Stations/devices are fetched only from the legacy backend — HTTPApi.getStationList() / getDeviceList() (src/http/api.ts). There is no v6/mega equivalent in megaHTTPApi.ts, and MegaTransition doesn't fetch them. So when legacy is captcha-blocked, the device list is unreachable even though v6 login succeeded.

Partial fix (verified) + why it's not enough

Adding && !this.megaLoggedIn to the PHASE-2 guard in runConnect:

// src/http/megaTransition.ts
if (this.pendingChallenge === "legacy" && !this.host.api.isConnected() && !this.megaLoggedIn) return;

I tested this against the bundled build/http/megaTransition.js: with it, the app reaches PHASE 3 and Push notification connection successfully established fires (FCM token registered on the eufy_mega backend). But start_listening still returns 0 stations / 0 devices, because those are legacy-only and legacy remains captcha-blocked.

Workaround

Pin eufy-security-client 4.0.0 (bropat/eufy-security-ws 3.0.1). Legacy-first login → email 2FA → trust → devices load normally.

Question / suggestion

  • Is the legacy captcha in the v6-first flow expected to be solved by the consumer via driver.set_captcha? If so, the connected/push signal still shouldn't be gated on it (the one-liner above).
  • Longer term, can stations/devices be fetched from the mega backend so the v6 flow is self-sufficient when legacy is unavailable? Currently a successful v6 login yields no devices.

Happy to turn the verified one-liner into a PR if it's useful on its own, or to test a v6 device-list path if one exists/is planned.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions