Repository navigation
feat(js,ui,localizations): limit password confirmation attempts per session #9913
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
296905f
ffee697
89a2ca7
6b465aa
5188de5
dda5b3d
bbf2b01
df88382
4ed044c
868ce3d
b2e558d
6786473
bb40537
72f3f83
dcf6031
63cea57
d7c54fc
a12f970
3960aee
4f58354
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| --- | ||
| '@clerk/clerk-js': minor | ||
| '@clerk/localizations': minor | ||
| '@clerk/shared': minor | ||
| '@clerk/ui': minor | ||
| --- | ||
|
|
||
| Show how many password attempts remain when a user enters the wrong current password while changing their password or during reverification, and explain that the session has ended once the attempts run out. | ||
|
|
||
| - `ClerkAPIError.meta.remainingAttempts` holds the attempts left in the current session. `0` means the session has ended, and Clerk signs the user out of the current tab and notifies other tabs. | ||
| - Customize the messages with the `unstable__errors.password_confirmation_attempt_remaining`, `unstable__errors.password_confirmation_attempts_remaining` (receives `{{remainingAttempts}}`), and `unstable__errors.password_confirmation_session_ended` localization keys. | ||
| - After the attempt limit signs a user out, the next prebuilt sign-in form explains why their session ended, including after a page reload. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| import { isValidBrowserOnline } from '@clerk/shared/browser'; | ||
| import { ClerkAPIResponseError, ClerkRuntimeError } from '@clerk/shared/error'; | ||
| import { isPasswordConfirmationError } from '@clerk/shared/internal/clerk-js/passwordConfirmation'; | ||
| import { isProductionFromPublishableKey } from '@clerk/shared/keys'; | ||
| import type { | ||
| ClerkAPIErrorJSON, | ||
|
|
@@ -128,15 +129,20 @@ export abstract class BaseResource { | |
| } | ||
|
|
||
| const { payload, status, statusText, headers } = fapiResponse; | ||
|
|
||
| const errors = payload?.errors ?? []; | ||
| if (headers) { | ||
| const country = headers.get('x-country'); | ||
|
|
||
| this.clerk.__internal_setCountry(country ? country.toLowerCase() : null); | ||
| } | ||
|
|
||
| // TODO: Link to Client payload piggybacking design document | ||
| if ((requestInit.method !== 'GET' || opts.forceUpdateClient) && !opts.skipUpdateClient) { | ||
| const shouldUpdateClient = (requestInit.method !== 'GET' || opts.forceUpdateClient) && !opts.skipUpdateClient; | ||
| if (status === 422 && isPasswordConfirmationError(errors[0]) && errors[0]?.meta?.remaining_attempts === 0) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Update: not a blocker. I read clerk_go#22414 at
The client check itself still isn't scoped: a mocked 422 |
||
| await BaseResource.clerk.__internal_handleSessionEnded( | ||
| shouldUpdateClient ? getClientResourceFromPayload(payload) : undefined, | ||
| ); | ||
| } else if (shouldUpdateClient) { | ||
| this._updateClient<J>(payload); | ||
| } | ||
|
|
||
|
|
@@ -145,9 +151,8 @@ export abstract class BaseResource { | |
| } | ||
|
|
||
| if (status >= 400) { | ||
| const errors = payload?.errors as ClerkAPIErrorJSON[]; | ||
| const message = errors?.[0]?.long_message; | ||
| const code = errors?.[0]?.code; | ||
| const message = errors[0]?.long_message; | ||
| const code = errors[0]?.code; | ||
|
|
||
| // Handle 401 errors based on the specific error code: | ||
| // - dev_browser_unauthenticated: reset the dev browser token | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.