Conversation
There was a problem hiding this comment.
Pull request overview
This PR expands Playwright functional coverage for passkey sign-in flows (including Sync OAuth edge-cases) and adds an AMO-like “profile AAL2” enforcement mode to the 123done test relier to validate the FxA-side divert behavior for passkey-only accounts.
Changes:
- Add new functional tests for passkey sign-in across email-first, Sync OAuth fallback/set-password flows, and AAL2 + profile-AAL2 scenarios.
- Extend the passkey polyfill with a “corrupt assertion” mode to exercise invalid-signature server handling.
- Update 123done to support “Require Profile AAL2” (post-grant profile check + one-bounce behavior) and surface account-level AAL2 state in UI + test page object helpers.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/functional-tests/tests/passkeyAuth/passkeySetPassword.spec.ts | Adds Sync OAuth coverage for passwordless+passkey routing through /post_verify/passkey/set_password (with/without TOTP). |
| packages/functional-tests/tests/passkeyAuth/passkeyPasswordFallback.spec.ts | Reworks Sync passkey fallback test to be UI-driven and adds TOTP-enrolled “no re-prompt” coverage. |
| packages/functional-tests/tests/passkeyAuth/passkey-signin.spec.ts | Adds broad passkey sign-in functional coverage, including AAL2 and AMO-style profile-AAL2 scenarios. |
| packages/functional-tests/pages/relier.ts | Adds relier actions and badge checks for the new profile-AAL2 toggle and account/session AAL2 markers. |
| packages/functional-tests/lib/passkeyPolyfill.ts | Adds a “corrupt” mode that tampers with the assertion signature for negative-path testing. |
| packages/123done/static/js/123done.js | Displays account-level AAL2 marker and wires up the new “Require Profile AAL2” button. |
| packages/123done/static/index.html | Adds the “Sign In (Require Profile AAL2)” button. |
| packages/123done/server.js | Exposes account_aal2 via /api/auth_status for UI/tests. |
| packages/123done/oauth.js | Adds /api/profile_aal2 flow and profile-based post-grant bounce logic to mirror AMO-style enforcement. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| await clearSession(page); | ||
| await page.goto(target.contentServerUrl); | ||
|
|
| await clearSession(page); | ||
| await page.goto(target.contentServerUrl); | ||
|
|
vpomerleau
left a comment
There was a problem hiding this comment.
Tests cases look good and thorough on first pass 💎 I'll have a closer look and do some manual testing after the weekly meeting, mainly for the 123done flows
| @@ -42,6 +42,12 @@ | |||
| > | |||
| Sign In (Require 2FA) | |||
There was a problem hiding this comment.
I see the difference as Require AAL2 session vs Require 2FA-enabled account, but not sure if this would be clear for others? Either option feels like it needs more explanation 😅
There was a problem hiding this comment.
It looks like the labels might be reversed? This one here requires an AAL2 session and the one below require 2FA-enabled account
| return account; | ||
| } | ||
|
|
||
| function findPasswordlessPassword( |
There was a problem hiding this comment.
findPasswordlessPassword - just from the name that's a tad odd. Looks like the test account tracker artificially creates a password before the account actually has one set? Feels like that would be worth a follow-up cleanup to more closely align with real user flows.
There was a problem hiding this comment.
Ok, I see this is now returned by the testAccountTracker now. Still odd, but out of scope here.
| }); | ||
| }); | ||
|
|
||
| test('shows the passkey button on /signin even when the account has no passkeys (no hasPasskeys leak)', async ({ |
There was a problem hiding this comment.
Is this necessary? We're guarding against state that isn't passed in /account/status?
Adds Playwright coverage for the passkey signin flow introduced in FXA-13101, including: - Passkey-only sign-in into a non-AAL2 RP and into an RP that requires AAL2 (account with TOTP enrolled and without). - The AMO-style profile-AAL2 divert: a passkey-only user hitting an RP that enforces profile-level AAL2 is sent to /inline_totp_setup before the OAuth grant completes, preventing AMO's bounce-loop. - Passkey + password fallback for Sync, and the passwordless set-password flow. Extends 123done with a Sign In (Require AAL2 Session) toggle that mirrors AMO's post-grant profile.twoFactorAuthentication check and bounces back to FxA once if the account lacks TOTP. The two AMO tests are gated to the local target (the toggle is local-only).
| ); | ||
| }); | ||
|
|
||
| test('passwordless+passkey signin into Sync routes through /post_verify/passkey/set_password', async ({ |
There was a problem hiding this comment.
Github isn't flagging a merge conflict (or test failure?), but this route was standardized to post_verify/set_password for all sign in methods
Because
This pull request
passkey-signin.spec.ts: email-first sign-in, /signin after submitting an email, error banners, non-AAL2 RPs, AAL2 RPs (with and without TOTP), and thepasskeySetPassword.spec.tspasswordless flow/inline_totp_setupbefore the OAuth grant, and a passkey+TOTP user completes straight to the RPSign In (Require Profile AAL2)toggle that mirrors AMO: checksprofile.twoFactorAuthenticationafter the grant and bounces back to FxA once if the account lacks TOTP. Surfaces both session-AAL2 (🔒) and account-AAL2 (🛡) on the post-auth pageIssue that this pull request solves
Closes: https://mozilla-hub.atlassian.net/browse/FXA-13103
Checklist
Other information
Depends on: FXA-13101 (PR #20635). The AMO profile-AAL2 tests rely on the FxA-side divert in
packages/fxa-settings/src/pages/Signin/utils.ts. This PR should land after that one.How to test locally: