Skip to content

Eversource: support interactive MFA (text/email code) with remember-me - #241

Merged
tronikos merged 1 commit into
tronikos:mainfrom
djbombay:eversource-mfa
Nov 4, 2026
Merged

tronikos merged 1 commit into
tronikos:mainfrom
djbombay:eversource-mfa

Conversation

@djbombay

@djbombay djbombay commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Eversource accounts with 2-step verification turned on fail with InvalidAuth("MFA required - not yet supported"), which Home Assistant shows as "Invalid authentication". This adds interactive MFA using the existing MfaChallenge / MfaHandlerBase framework, the same way PG&E and Exelon do it.

Flow (mirrors eversource.com's login page)

  1. MSLogin returns status: MFA_REQUIRED together with token (encrypted user id) and the enrolled factors.
  2. async_login raises MfaChallenge with an EversourceMfaHandler.
  3. async_get_mfa_options lists the ACTIVE sms / email factors (masked).
  4. async_select_mfa_option → POST /security/api/OktaMFA/IssueMFAFactor {userId, factorId} (expects factorResult: CHALLENGE).
  5. async_submit_mfa_code → POST /security/api/OktaMFA/VerifyMFAFactor {userId, factorId, passCode, mfaRememberMe: true} (expects factorResult: SUCCESS) and returns {"mfa_remember_me_data": ...} as login data.
  6. The next MSLogin sends it as MfaRememberMeData. A reply with ValidMfaRememberMeData: true continues with the existing Okta/PKCE steps, so MFA isn't asked again until Eversource expires it.

Endpoints and fields come from Eversource's own login bundle (ms-login main.bundle.js: IssueChallenge, ValidateChallengeCode, and the ValidMfaRememberMeData branch in the login handler).

Testing

  • 6 new unit tests in tests/opower/utilities/test_eversource.py (challenge + masked options, missing user id, code sent and remember-me returned with the expected request bodies, wrong code, code not sent, valid remember-me skips MFA). Full suite passes; ruff and mypy are clean.
  • Live test against a real Eversource (NH) account with SMS 2-step via python -m opower --utility eversource --login_data_file ...: the first run asked for the texted code and downloaded usage; a second run with the saved login data skipped MFA and downloaded usage.

Not covered: accounts whose only factor is email were not tested live (same endpoints, different factorType).

🤖 Generated with Claude Code

MSLogin returns MFA_REQUIRED for accounts with 2-step verification, which was
raised as InvalidAuth. Raise MfaChallenge with an EversourceMfaHandler instead:
list the active sms/email factors, send the code via IssueMFAFactor, verify it
via VerifyMFAFactor with mfaRememberMe, and return the remember-me data as
login data. The next MSLogin sends it as MfaRememberMeData; a reply with
ValidMfaRememberMeData skips MFA, as on eversource.com.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tronikos
tronikos merged commit a2f90c3 into tronikos:main Nov 4, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants