fix: handle more auth API errors (#3241)

This commit is contained in:
Abhineet Jain
2022-07-28 17:14:05 -04:00
committed by GitHub
parent 6b82fdd0c0
commit 74c87664c1
9 changed files with 203 additions and 70 deletions
@@ -1,5 +1,6 @@
import { Story } from "@storybook/react"
import { SignInForm, SignInFormProps } from "./SignInForm"
import { makeMockApiError } from "testHelpers/entities"
import { LoginErrors, SignInForm, SignInFormProps } from "./SignInForm"
export default {
title: "components/SignInForm",
@@ -15,7 +16,7 @@ const Template: Story<SignInFormProps> = (args: SignInFormProps) => <SignInForm
export const SignedOut = Template.bind({})
SignedOut.args = {
isLoading: false,
authError: undefined,
loginErrors: {},
onSubmit: () => {
return Promise.resolve()
},
@@ -34,29 +35,39 @@ Loading.args = {
export const WithLoginError = Template.bind({})
WithLoginError.args = {
...SignedOut.args,
authError: {
response: {
data: {
message: "Email or password was invalid",
validations: [
{
field: "password",
detail: "Password is invalid.",
},
],
},
},
isAxiosError: true,
loginErrors: {
[LoginErrors.AUTH_ERROR]: makeMockApiError({
message: "Email or password was invalid",
validations: [
{
field: "password",
detail: "Password is invalid.",
},
],
}),
},
initialTouched: {
password: true,
},
}
export const WithCheckPermissionsError = Template.bind({})
WithCheckPermissionsError.args = {
...SignedOut.args,
loginErrors: {
[LoginErrors.CHECK_PERMISSIONS_ERROR]: makeMockApiError({
message: "Unable to fetch user permissions",
detail: "Resource not found or you do not have access to this resource.",
}),
},
}
export const WithAuthMethodsError = Template.bind({})
WithAuthMethodsError.args = {
...SignedOut.args,
methodsError: new Error("Failed to fetch auth methods"),
loginErrors: {
[LoginErrors.GET_METHODS_ERROR]: new Error("Failed to fetch auth methods"),
},
}
export const WithGithub = Template.bind({})
+25 -12
View File
@@ -23,13 +23,22 @@ interface BuiltInAuthFormValues {
password: string
}
export enum LoginErrors {
AUTH_ERROR = "authError",
CHECK_PERMISSIONS_ERROR = "checkPermissionsError",
GET_METHODS_ERROR = "getMethodsError",
}
export const Language = {
emailLabel: "Email",
passwordLabel: "Password",
emailInvalid: "Please enter a valid email address.",
emailRequired: "Please enter an email address.",
authErrorMessage: "Incorrect email or password.",
methodsErrorMessage: "Unable to fetch auth methods.",
errorMessages: {
[LoginErrors.AUTH_ERROR]: "Incorrect email or password.",
[LoginErrors.CHECK_PERMISSIONS_ERROR]: "Unable to fetch user permissions.",
[LoginErrors.GET_METHODS_ERROR]: "Unable to fetch auth methods.",
},
passwordSignIn: "Sign In",
githubSignIn: "GitHub",
}
@@ -68,8 +77,7 @@ const useStyles = makeStyles((theme) => ({
export interface SignInFormProps {
isLoading: boolean
redirectTo: string
authError?: Error | unknown
methodsError?: Error | unknown
loginErrors: Partial<Record<LoginErrors, Error | unknown>>
authMethods?: AuthMethods
onSubmit: ({ email, password }: { email: string; password: string }) => Promise<void>
// initialTouched is only used for testing the error state of the form.
@@ -80,8 +88,7 @@ export const SignInForm: FC<SignInFormProps> = ({
authMethods,
redirectTo,
isLoading,
authError,
methodsError,
loginErrors,
onSubmit,
initialTouched,
}) => {
@@ -101,18 +108,24 @@ export const SignInForm: FC<SignInFormProps> = ({
onSubmit,
initialTouched,
})
const getFieldHelpers = getFormHelpersWithError<BuiltInAuthFormValues>(form, authError)
const getFieldHelpers = getFormHelpersWithError<BuiltInAuthFormValues>(
form,
loginErrors.authError,
)
return (
<>
<Welcome />
<form onSubmit={form.handleSubmit}>
<Stack>
{authError && (
<ErrorSummary error={authError} defaultMessage={Language.authErrorMessage} />
)}
{methodsError && (
<ErrorSummary error={methodsError} defaultMessage={Language.methodsErrorMessage} />
{Object.keys(loginErrors).map((errorKey: string) =>
loginErrors[errorKey as LoginErrors] ? (
<ErrorSummary
key={errorKey}
error={loginErrors[errorKey as LoginErrors]}
defaultMessage={Language.errorMessages[errorKey as LoginErrors]}
/>
) : null,
)}
<TextField
{...getFieldHelpers("email")}