Repository navigation
Eversource: support interactive MFA (text/email code) with remember-me - #241
Merged
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 existingMfaChallenge/MfaHandlerBaseframework, the same way PG&E and Exelon do it.Flow (mirrors eversource.com's login page)
MSLoginreturnsstatus: MFA_REQUIREDtogether withtoken(encrypted user id) and the enrolledfactors.async_loginraisesMfaChallengewith anEversourceMfaHandler.async_get_mfa_optionslists the ACTIVEsms/emailfactors (masked).async_select_mfa_option→POST /security/api/OktaMFA/IssueMFAFactor {userId, factorId}(expectsfactorResult: CHALLENGE).async_submit_mfa_code→POST /security/api/OktaMFA/VerifyMFAFactor {userId, factorId, passCode, mfaRememberMe: true}(expectsfactorResult: SUCCESS) and returns{"mfa_remember_me_data": ...}as login data.MSLoginsends it asMfaRememberMeData. A reply withValidMfaRememberMeData: truecontinues 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-loginmain.bundle.js:IssueChallenge,ValidateChallengeCode, and theValidMfaRememberMeDatabranch in the login handler).Testing
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.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