diff --git a/site/src/pages/ResetPasswordPage/ChangePasswordPage.stories.tsx b/site/src/pages/ResetPasswordPage/ChangePasswordPage.stories.tsx index d59ead3a59579..2768323ead15b 100644 --- a/site/src/pages/ResetPasswordPage/ChangePasswordPage.stories.tsx +++ b/site/src/pages/ResetPasswordPage/ChangePasswordPage.stories.tsx @@ -51,7 +51,7 @@ export const WrongConfirmationPassword: Story = { }, }; -export const ServerError: Story = { +export const GeneralServerError: Story = { play: async ({ canvasElement }) => { const serverError = "New password should be different from the old password"; @@ -71,3 +71,29 @@ export const ServerError: Story = { await canvas.findByText(serverError); }, }; + +export const ValidationServerError: Story = { + play: async ({ canvasElement }) => { + const validationDetail = + "insecure password, try including more special characters, using uppercase letters, using numbers or using a longer password"; + const error = mockApiError({ + message: "Invalid password.", + validations: [ + { + field: "password", + detail: validationDetail, + }, + ], + }); + spyOn(API, "changePasswordWithOTP").mockRejectedValueOnce(error); + const canvas = within(canvasElement); + const user = userEvent.setup(); + const newPasswordInput = await canvas.findByLabelText("Password *"); + await user.type(newPasswordInput, "password"); + const confirmPasswordInput = + await canvas.findByLabelText("Confirm password *"); + await user.type(confirmPasswordInput, "password"); + await user.click(canvas.getByRole("button", { name: /reset password/i })); + await canvas.findByText(validationDetail); + }, +}; diff --git a/site/src/pages/ResetPasswordPage/ChangePasswordPage.tsx b/site/src/pages/ResetPasswordPage/ChangePasswordPage.tsx index 077bc39da82d4..2a633232c99b5 100644 --- a/site/src/pages/ResetPasswordPage/ChangePasswordPage.tsx +++ b/site/src/pages/ResetPasswordPage/ChangePasswordPage.tsx @@ -2,6 +2,7 @@ import type { Interpolation, Theme } from "@emotion/react"; import LoadingButton from "@mui/lab/LoadingButton"; import Button from "@mui/material/Button"; import TextField from "@mui/material/TextField"; +import { isApiError, isApiValidationError } from "api/errors"; import { changePasswordWithOTP } from "api/queries/users"; import { ErrorAlert } from "components/Alert/ErrorAlert"; import { CustomLogo } from "components/CustomLogo/CustomLogo"; @@ -64,7 +65,7 @@ const ChangePasswordPage: FC = ({ redirect }) => { } }, }); - const getFieldHelpers = getFormHelpers(form); + const getFieldHelpers = getFormHelpers(form, changePasswordMutation.error); return ( <> @@ -86,7 +87,8 @@ const ChangePasswordPage: FC = ({ redirect }) => { > Choose a new password - {changePasswordMutation.error ? ( + {changePasswordMutation.error && + !isApiValidationError(changePasswordMutation.error) ? (