Conversation
Because:
- The auth-server removed /password/forgot/{send_code,resend_code,status}
in January 2026 (mozilla/fxa 985f565dc9), so Client.send_reset_code and
the PasswordForgotToken flow have returned 404 since then.
- Only the opt-in stage live test exercised the flow, so it went unnoticed.
This commit:
- Point send_reset_code at /password/forgot/send_otp and add
Client.verify_reset_otp for /password/forgot/verify_otp.
- Make PasswordForgotToken.verify_code chain verify_otp then verify_code
and populate token, uid and email_to_hash_with on success.
- Drop resend_reset_code, get_reset_code_status and get_status, which have
no OTP equivalent; resend_code now re-sends the OTP.
- Update the live test and add mocked tests for the request shapes.
- Add a CHANGES entry.
Fixes FXA-14639
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The implementation matches the current auth-server contract and has focused coverage for the changed behavior.
Review effort: Balanced
Findings: None
What changed in this PR
Migrates password resets to the auth server’s supported OTP flow.
Changes:
- Adds OTP sending and verification APIs.
- Updates
PasswordForgotTokenand removes obsolete reset methods. - Adds mocked and live-flow coverage plus release notes.
| File | Description |
|---|---|
fxa/core.py |
Implements the OTP password-reset flow. |
fxa/tests/test_core.py |
Tests request shapes, authentication, and flow behavior. |
CHANGES.txt |
Documents API changes and removals. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
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.
Summary
The auth-server removed
POST /password/forgot/send_code,POST /password/forgot/resend_codeandGET /password/forgot/statusin January 2026 (mozilla/fxa985f565dc9). PyFxA still called all three, soClient.send_reset_codeand the wholePasswordForgotTokenflow have returned 404 since then. Only the opt-in stage live test exercised it, which is why nobody noticed.This moves the flow onto the OTP routes that replaced them:
/password/forgot/send_otpemails an 8-digit code,/password/forgot/verify_otpexchanges it for thepasswordForgotToken, and the still-live/password/forgot/verify_codeand/account/resetfinish the reset as before.Changes
Client.send_reset_code(email, service=None)posts tosend_otpand returns aPasswordForgotToken. Breaking: theredirectToandresumekwargs are gone (the OTP route does not take them), and the returned object has notokenuntil the code is verified.Client.verify_reset_otp(email, code)is new; it wrapsverify_otp.PasswordForgotToken.verify_code(code)chainsverify_otpthenverify_codeand still returns theaccountResetToken. On success it setstoken,uidandemail_to_hash_with.PasswordForgotToken.resend_code()re-sends the OTP. Breaking:get_status,Client.resend_reset_codeandClient.get_reset_code_statusare removed; the OTP flow has nottl/triesequivalent.test_forgot_password_flowrewritten around the OTP flow. The code arrives in thex-password-forgot-otpemail header.send_otp/verify_otpare unauthenticated, and thatverify_codestill sends thefxpf_prefixed Bearer token.CHANGES.txtentry under 0.9.0 (unreleased); no version bump here. Will conflict trivially with feat(totp): move TOTP management to the /mfa/totp/* routes #126, which adds the same header.Notes
reset_accountis unchanged. It still stretches with theemailthe caller passes;email_to_hash_withis exposed on the token for callers who started the reset from a secondary email, but wiring it through is a separate change.FXA_RUN_LIVE_TESTS=1, stage, and restmail). Mocked suite: 110 passed, 30 skipped.Related: FXA-14639, FXA-12699, FXA-12686.