From dd46bd3ad64f36734816a2569980dd56a6292918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=B6glund?= Date: Thu, 9 Apr 2026 16:02:47 +0200 Subject: [PATCH 1/3] Hide back button on sign-in password compromised/pwned screen This would take you back to re-enter the password, which never works so it was leading to a confusing dead end. --- packages/ui/src/components/SignIn/SignInFactorOne.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/ui/src/components/SignIn/SignInFactorOne.tsx b/packages/ui/src/components/SignIn/SignInFactorOne.tsx index c493c19dfd9..7403ec02f1c 100644 --- a/packages/ui/src/components/SignIn/SignInFactorOne.tsx +++ b/packages/ui/src/components/SignIn/SignInFactorOne.tsx @@ -155,7 +155,8 @@ function SignInFactorOneInternal(): JSX.Element { } if (showAllStrategies || showForgotPasswordStrategies) { - const canGoBack = factorHasLocalStrategy(currentFactor); + // Password errors are not recoverable by re-entering the password, so we hide the back button + const canGoBack = factorHasLocalStrategy(currentFactor) && !passwordErrorCode; const toggle = showAllStrategies ? toggleAllStrategies : toggleForgotPasswordStrategies; const backHandler = () => { From 3a2b08bfdcee76a84868e6f1cef93ec00e5c9b63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=B6glund?= Date: Thu, 9 Apr 2026 16:07:20 +0200 Subject: [PATCH 2/3] Add changeset --- .changeset/pink-taxes-do.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/pink-taxes-do.md diff --git a/.changeset/pink-taxes-do.md b/.changeset/pink-taxes-do.md new file mode 100644 index 00000000000..a2f6452c5fd --- /dev/null +++ b/.changeset/pink-taxes-do.md @@ -0,0 +1,7 @@ +--- +'@clerk/ui': patch +--- + +Remove back button on the sign-in password compromised/pwned error screen. + +These errors are not recoverable by re-entering the password, so the back button led to a confusing dead end that would always take you back to the same error. From 18269d6e6b74be351679be26163930f762f00b20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=B6glund?= Date: Thu, 9 Apr 2026 16:19:42 +0200 Subject: [PATCH 3/3] Remove no longer useful test --- .../SignIn/__tests__/SignInFactorOne.test.tsx | 51 ------------------- 1 file changed, 51 deletions(-) diff --git a/packages/ui/src/components/SignIn/__tests__/SignInFactorOne.test.tsx b/packages/ui/src/components/SignIn/__tests__/SignInFactorOne.test.tsx index 2a43a6632f0..bc8bc8da99b 100644 --- a/packages/ui/src/components/SignIn/__tests__/SignInFactorOne.test.tsx +++ b/packages/ui/src/components/SignIn/__tests__/SignInFactorOne.test.tsx @@ -303,57 +303,6 @@ describe('SignInFactorOne', () => { await screen.findByText('First, enter the code sent to your phone'); }); - it('entering a pwned password, then going back and clicking forgot password should result in the correct title', async () => { - const { wrapper, fixtures } = await createFixtures(f => { - f.withEmailAddress(); - f.withPassword(); - f.withPreferredSignInStrategy({ strategy: 'password' }); - f.startSignInWithEmailAddress({ - supportPassword: true, - supportEmailCode: true, - supportResetPassword: true, - }); - }); - fixtures.signIn.prepareFirstFactor.mockReturnValueOnce(Promise.resolve({} as SignInResource)); - - const errJSON = { - code: 'form_password_pwned', - long_message: - 'Password has been found in an online data breach. For account safety, please reset your password.', - message: 'Password has been found in an online data breach. For account safety, please reset your password.', - meta: { param_name: 'password' }, - }; - - fixtures.signIn.attemptFirstFactor.mockRejectedValueOnce( - new ClerkAPIResponseError('Error', { - data: [errJSON], - status: 422, - }), - ); - - const { userEvent } = render(, { wrapper }); - await userEvent.type(screen.getByLabelText('Password'), '123456'); - await userEvent.click(screen.getByText('Continue')); - - await screen.findByText('Password compromised'); - await screen.findByText( - 'This password has been found as part of a breach and can not be used, please reset your password.', - ); - await screen.findByText('Or, sign in with another method'); - - // Go back - await userEvent.click(screen.getByText('Back')); - - // Choose to reset password via "Forgot password" instead - await userEvent.click(screen.getByText(/Forgot password/i)); - await screen.findByText('Forgot Password?'); - expect( - screen.queryByText( - 'This password has been found as part of a breach and can not be used, please reset your password.', - ), - ).not.toBeInTheDocument(); - }); - it('using an compromised password should show the compromised password screen', async () => { const { wrapper, fixtures } = await createFixtures(f => { f.withEmailAddress();