Skip to content

feat(passkeys): show max-limit banner and disable Create button when passkey limit reached#20355

Merged
vpomerleau merged 1 commit intomainfrom
FXA-13369
Apr 10, 2026
Merged

feat(passkeys): show max-limit banner and disable Create button when passkey limit reached#20355
vpomerleau merged 1 commit intomainfrom
FXA-13369

Conversation

@vpomerleau
Copy link
Copy Markdown
Contributor

@vpomerleau vpomerleau commented Apr 10, 2026

Because

  • Users need clear feedback when they've reached the passkey limit and should not be able to attempt creating another one.

This pull request

  • Threads passkeys.maxPerUser config from content-server to fxa-settings using the same PASSKEYS__MAX_PASSKEYS_PER_USER env var as auth-server
  • Renders a warning Banner in the passkeys row when the limit is reached
  • Passes disabled/disabledReason to UnitRow to gray out the Create button

Additional tweaks to align with latest UX designs:

  • Renames canSync → prfEnabled on the Passkey type (no phase-1 UI; needed for the phase-2 passwordless-sync upgrade flow)
  • Removes the sign-in-only SubRow badge (not shown in phase 1)
  • Updates link copy to "Learn more"
  • Tightens SubRow padding and UnitRow action-button top margin
  • Adds className prop to Banner to allow margin overrides

Issue that this pull request solves

Closes: FXA-13369

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)

Compare with UX designs on Figma
Check out the storybook for passkey unit row

Screenshots (Optional)

image

Other information (Optional)

Any other information that is important to this pull request.

@vpomerleau vpomerleau requested a review from a team as a code owner April 10, 2026 01:18
Copilot AI review requested due to automatic review settings April 10, 2026 01:18
@vpomerleau vpomerleau requested a review from a team as a code owner April 10, 2026 01:18
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds passkey-limit UX to the Settings UI (warning banner + disabled Create action) and introduces a new passkeys.maxPerUser config value intended to be threaded from server config into fxa-settings.

Changes:

  • Add passkeys.maxPerUser to the settings config and use it to show a max-limit warning banner + disable the “Create” action when at/over the limit.
  • Rename the passkey field canSyncprfEnabled and remove the phase-1 “sign-in-only” sub-row badge.
  • Minor UX copy/styling tweaks (link text, paddings/margins) and add className support to Banner.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/fxa-settings/src/lib/config.ts Adds passkeys.maxPerUser to the typed config + defaults.
packages/fxa-settings/src/components/Settings/UnitRowSecondaryEmail/index.tsx Updates a fallback string (apostrophe/copy tweak).
packages/fxa-settings/src/components/Settings/UnitRowPasskey/index.tsx Uses config max to render warning banner and disable Create action; updates link copy/id; renames passkey field.
packages/fxa-settings/src/components/Settings/UnitRowPasskey/index.test.tsx Updates mock passkey shape; adds tests for banner/disabled state at max.
packages/fxa-settings/src/components/Settings/UnitRowPasskey/index.stories.tsx Updates mock passkey shape; adds “AtMaxPasskeys” story.
packages/fxa-settings/src/components/Settings/UnitRowPasskey/en.ftl Updates link string/id; adds banner + disabled-reason strings.
packages/fxa-settings/src/components/Settings/UnitRow/index.tsx Adjusts action area top margin per updated UX spacing.
packages/fxa-settings/src/components/Settings/SubRow/index.tsx Tightens sub-row spacing; updates passkey type and removes sign-in-only badge logic.
packages/fxa-settings/src/components/Settings/SubRow/index.test.tsx Updates mock passkey shape; removes tests for the removed badge.
packages/fxa-settings/src/components/Settings/SubRow/index.stories.tsx Updates mock passkey shape for stories.
packages/fxa-settings/src/components/Settings/SubRow/en.ftl Removes unused passkey “sign-in-only” string.
packages/fxa-settings/src/components/Banner/interfaces.ts Adds className?: string to BannerProps.
packages/fxa-settings/src/components/Banner/index.tsx Applies className to banner wrapper for spacing overrides.
packages/fxa-content-server/server/lib/routes/react-app/route-definition-index.js Exposes passkeys.maxPerUser to the root react-app config payload.
packages/fxa-content-server/server/lib/configuration.js Adds convict schema/env wiring for passkeys.maxPerUser.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/fxa-settings/src/components/Banner/interfaces.ts
Comment thread packages/fxa-settings/src/lib/config.ts
Comment thread packages/fxa-settings/src/components/Settings/SubRow/index.test.tsx
Comment thread packages/fxa-settings/src/components/Settings/SubRow/index.tsx Outdated
Copy link
Copy Markdown
Contributor

@vbudhram vbudhram left a comment

Choose a reason for hiding this comment

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

@vpomerleau 👍🏽

# Shown as a warning banner when the user has registered the maximum number of passkeys.
# Variables:
# $count (Number) - the maximum number of passkeys allowed (defaults to 10 allowed)
passkey-row-max-limit-banner = You’ve used all { $count } passkeys. Delete a passkey to create a new one.
Copy link
Copy Markdown
Contributor

@bcolsson bcolsson Apr 10, 2026

Choose a reason for hiding this comment

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

Suggested change
passkey-row-max-limit-banner = You’ve used all { $count } passkeys. Delete a passkey to create a new one.
passkey-row-max-limit-banner =
{ $count ->
*[other] You've used all { $count } passkeys. Delete a passkey to create a new one.
}

Actually, we should make this have a plural selector to trigger the plurals UI for localizers. If there's a chance for the max to be 1, then we should add a [one] variant as well.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I don't anticipate ever having of max 1 passkey, so plural only should be sufficient here.

…sskey limit

Because:

* Users need clear feedback when they've reached the passkey limit and should not be able to attempt creating another one.

This commit:

* Threads passkeys.maxPerUser config from content-server to fxa-settings using the same PASSKEYS__MAX_PASSKEYS_PER_USER env var as auth-server
* Renders a warning Banner in the passkeys row when the limit is reached
* Passes disabled/disabledReason to UnitRow to gray out the Create button
Additional tweaks to align with latest UX designs:
* Renames canSync → prfEnabled on the Passkey type (no phase-1 UI; needed for the phase-2 passwordless-sync upgrade flow)
* Removes the sign-in-only SubRow badge (not shown in phase 1)
* Updates link copy to "Learn more" with FTL id passkey-row-info-link-2
* Tightens SubRow padding and UnitRow action-button top margin
* Adds className prop to Banner to allow margin overrides

Closes #FXA-13369
@vpomerleau vpomerleau merged commit 4e21b04 into main Apr 10, 2026
22 checks passed
@vpomerleau vpomerleau deleted the FXA-13369 branch April 10, 2026 23:24
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.

4 participants