Skip to content

feat(passkey): expose wrap state on the password reset flow - #21155

Draft
vpomerleau wants to merge 1 commit into
mainfrom
FXA-14220
Draft

feat(passkey): expose wrap state on the password reset flow#21155
vpomerleau wants to merge 1 commit into
mainfrom
FXA-14220

Conversation

@vpomerleau

Copy link
Copy Markdown
Contributor

Because

  • A Sync account whose passkey can recover its encryption keys should get the
    passkey wording on the reset footer; it was suppressed for every Sync sign-in
    while wraps did not exist.
  • Wrap state describes account state, so it belongs on the email-verified step of
    the reset flow and on no unauthenticated route.

This pull request

  • Adds hasPasskeyWraps to PasskeyService, backed by a per-uid wrap count.
  • Returns hasPasskeyWraps from /password/forgot/verify_otp and adds it to the
    auth-client return type.
  • Threads the passkey signals through the reset flow as one grouped object.
  • Gates the passkey reset footer on a stored wrap plus passkeyPasswordlessSyncEnabled
    for Sync, failing closed when either is unknown.
  • Asserts the flag is absent from /account/status and never looked up there.

Issue that this pull request solves

Closes: FXA-14220

Checklist

Put an x in the boxes that apply

  • My commit is GPG signed.
  • If applicable, I have modified or added tests which pass locally.
  • I have added necessary documentation (if appropriate).
  • I have verified that my changes render correctly in RTL (if appropriate).
  • I have manually reviewed all AI generated code.

How to review (Optional)

  • Key files/areas to focus on: lib/routes/password.ts for the new lookup and its
    gating, and lib/passkeys/should-show-passkey-reset-option.ts for the footer decision.
  • Suggested review order: passkey.wrap.repository.tspasskey.service.ts
    routes/password.tsshould-show-passkey-reset-option.ts → the reset-flow containers.
  • Risky or complex parts: the exposure boundary. hasPasskeyWraps must stay off
    /account/status; account.spec.ts asserts both the handler omission and the
    Joi schema rejection.

Screenshots (Optional)

Please attach the screenshots of the changes made in case of change in user interface.

Other information (Optional)

  • The PasskeyService method this ticket assumed had not landed, so the
    repository → manager → service chain is added here. Another in-flight wrap change
    needs a per-credential lookup in the same files and will collide textually.
  • The Sync branch also requires passkeyPasswordlessSyncEnabled, beyond the ticket's
    acceptance criteria. Wrap storage can ship ahead of wrap consumption, and without
    the gate the footer would send a user mid-reset to a passkey sign-in that asks for
    the password they just declared forgotten.

Because:
- A Sync account whose passkey can recover its encryption keys should get
  the passkey wording on the reset footer, which was suppressed for every
  Sync sign-in while wraps did not exist.
- Wrap state describes account state, so it belongs on the email-verified
  step of the reset flow and on no unauthenticated route.
- Wraps can be stored before sign-in can unwrap them, so the footer needs
  the same kill switch the wrap routes use.

This commit:
- Adds hasPasskeyWraps to PasskeyService, backed by a per-uid wrap count.
- Returns hasPasskeyWraps from /password/forgot/verify_otp and adds it to
  the auth-client return type.
- Threads the signals through the reset flow as one grouped object.
- Gates the passkey reset footer on a wrap plus passkeyPasswordlessSyncEnabled
  for Sync, failing closed when either is unknown.
- Asserts the flag is absent from /account/status and never looked up there.

Closes #FXA-14220
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.

1 participant