Skip to content

fix(password): move password reset to the /password/forgot OTP routes - #127

Open
clouserw wants to merge 1 commit into
mainfrom
fxa-14639-forgot-password-otp
Open

clouserw wants to merge 1 commit into
mainfrom
fxa-14639-forgot-password-otp

Conversation

@clouserw

Copy link
Copy Markdown
Member

Summary

The auth-server removed POST /password/forgot/send_code, POST /password/forgot/resend_code and GET /password/forgot/status in January 2026 (mozilla/fxa 985f565dc9). PyFxA still called all three, so Client.send_reset_code and the whole PasswordForgotToken flow 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_otp emails an 8-digit code, /password/forgot/verify_otp exchanges it for the passwordForgotToken, and the still-live /password/forgot/verify_code and /account/reset finish the reset as before.

Changes

  • Client.send_reset_code(email, service=None) posts to send_otp and returns a PasswordForgotToken. Breaking: the redirectTo and resume kwargs are gone (the OTP route does not take them), and the returned object has no token until the code is verified.
  • Client.verify_reset_otp(email, code) is new; it wraps verify_otp.
  • PasswordForgotToken.verify_code(code) chains verify_otp then verify_code and still returns the accountResetToken. On success it sets token, uid and email_to_hash_with.
  • PasswordForgotToken.resend_code() re-sends the OTP. Breaking: get_status, Client.resend_reset_code and Client.get_reset_code_status are removed; the OTP flow has no ttl / tries equivalent.
  • Live test_forgot_password_flow rewritten around the OTP flow. The code arrives in the x-password-forgot-otp email header.
  • Mocked tests pin the request bodies, that send_otp / verify_otp are unauthenticated, and that verify_code still sends the fxpf_ prefixed Bearer token.
  • CHANGES.txt entry 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_account is unchanged. It still stretches with the email the caller passes; email_to_hash_with is exposed on the token for callers who started the reset from a secondary email, but wiring it through is a separate change.
  • Live test not run here (needs FXA_RUN_LIVE_TESTS=1, stage, and restmail). Mocked suite: 110 passed, 30 skipped.
  • Commit is unsigned; will be amended and force-pushed with a signature before merge.

Related: FXA-14639, FXA-12699, FXA-12686.

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
@clouserw
clouserw requested review from vbudhram and a balanced review from Copilot September 25, 2026 22:32

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 PasswordForgotToken and 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.

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