feat(passkeys): show max-limit banner and disable Create button when passkey limit reached#20355
feat(passkeys): show max-limit banner and disable Create button when passkey limit reached#20355vpomerleau wants to merge 1 commit intomainfrom
Conversation
There was a problem hiding this comment.
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.maxPerUserto 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
canSync→prfEnabledand remove the phase-1 “sign-in-only” sub-row badge. - Minor UX copy/styling tweaks (link text, paddings/margins) and add
classNamesupport toBanner.
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.
| passkeys: { | ||
| maxPerUser: PASSKEYS_MAX_PER_USER, | ||
| }, |
There was a problem hiding this comment.
This adds passkeys.maxPerUser to the config rendered for the root React app, but /settings gets its injected config from server/lib/beta-settings.js (settingsConfig). Unless settingsConfig is also extended to include this value, fxa-settings will always use its default (10) and won’t reflect PASSKEYS__MAX_PASSKEYS_PER_USER as described in the PR.
| link?: BannerLinkProps; | ||
| isFancy?: boolean; | ||
| bannerId?: string; | ||
| className?: string; | ||
| iconAlignClassName?: 'self-start' | 'self-center'; |
There was a problem hiding this comment.
The BannerProps JSDoc lists supported props, but the newly added className prop isn’t documented. Please update the doc comment so it’s clear callers can override spacing/margins via className.
| passkeys: { | ||
| maxPerUser: number; | ||
| }; |
There was a problem hiding this comment.
config.passkeys.maxPerUser is newly introduced here, but there isn’t a targeted test ensuring readConfigMeta can override this value from the fxa-config meta payload (see packages/fxa-settings/src/lib/config.test.ts). Adding a small test case for passkeys.maxPerUser would help catch nesting/type regressions when threading the env var through.
…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
Because
This pull request
passkeys.maxPerUserconfig from content-server to fxa-settings using the samePASSKEYS__MAX_PASSKEYS_PER_USERenv var as auth-serverUnitRowto gray out the Create buttonAdditional tweaks to align with latest UX designs:
Issue that this pull request solves
Closes: FXA-13369
Checklist
Put an
xin the boxes that applyHow to review (Optional)
Compare with UX designs on Figma
Check out the storybook for passkey unit row
Screenshots (Optional)
Other information (Optional)
Any other information that is important to this pull request.