fix: Login page breaking when handling not expected errors (#31804)

pull/31679/head
gabriellsh 2 years ago committed by GitHub
parent 8a59f10057
commit 8b10c6cf0f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 5
      .changeset/quick-cheetahs-help.md
  2. 36
      packages/web-ui-registration/src/LoginForm.tsx
  3. 4
      packages/web-ui-registration/src/LoginServices.tsx
  4. 8
      packages/web-ui-registration/src/LoginServicesButton.tsx

@ -0,0 +1,5 @@
---
"@rocket.chat/web-ui-registration": patch
---
fixed the login page crashing when receiving unexpected errors

@ -56,7 +56,9 @@ const LOGIN_SUBMIT_ERRORS = {
},
} as const;
export type LoginErrors = keyof typeof LOGIN_SUBMIT_ERRORS | 'totp-canceled';
export type LoginErrors = keyof typeof LOGIN_SUBMIT_ERRORS | 'totp-canceled' | string;
export type LoginErrorState = [error: LoginErrors, message?: string] | undefined;
export const LoginForm = ({ setLoginRoute }: { setLoginRoute: DispatchLoginRouter }): ReactElement => {
const {
@ -72,7 +74,7 @@ export const LoginForm = ({ setLoginRoute }: { setLoginRoute: DispatchLoginRoute
const { t } = useTranslation();
const formLabelId = useUniqueId();
const [errorOnSubmit, setErrorOnSubmit] = useState<LoginErrors | undefined>(undefined);
const [errorOnSubmit, setErrorOnSubmit] = useState<LoginErrorState>(undefined);
const isResetPasswordAllowed = useSetting('Accounts_PasswordReset');
const login = useLoginWithPassword();
const showFormLogin = useSetting('Accounts_ShowFormLogin');
@ -92,11 +94,11 @@ export const LoginForm = ({ setLoginRoute }: { setLoginRoute: DispatchLoginRoute
}
if ('error' in error && error.error !== 403) {
setErrorOnSubmit(error.error);
setErrorOnSubmit([error.error, error.reason]);
return;
}
setErrorOnSubmit('user-not-found');
setErrorOnSubmit(['user-not-found']);
},
});
@ -110,18 +112,28 @@ export const LoginForm = ({ setLoginRoute }: { setLoginRoute: DispatchLoginRoute
}
}, [errorOnSubmit]);
const renderErrorOnSubmit = (error: LoginErrors) => {
const renderErrorOnSubmit = ([error, message]: Exclude<LoginErrorState, undefined>) => {
if (error in LOGIN_SUBMIT_ERRORS) {
const { type, i18n } = LOGIN_SUBMIT_ERRORS[error as Exclude<LoginErrors, string>];
return (
<Callout id={`${usernameId}-error`} aria-live='assertive' type={type}>
{t(i18n)}
</Callout>
);
}
if (error === 'totp-canceled') {
return null;
}
const { type, i18n } = LOGIN_SUBMIT_ERRORS[error];
return (
<Callout id={`${usernameId}-error`} aria-live='assertive' type={type}>
{t(i18n)}
</Callout>
);
if (message) {
return (
<Callout id={`${usernameId}-error`} aria-live='assertive' type='danger'>
{message}
</Callout>
);
}
return null;
};
if (errors.usernameOrEmail?.type === 'invalid-email') {

@ -3,7 +3,7 @@ import { useLoginServices, useSetting } from '@rocket.chat/ui-contexts';
import type { Dispatch, ReactElement, SetStateAction } from 'react';
import { useTranslation } from 'react-i18next';
import type { LoginErrors } from './LoginForm';
import type { LoginErrorState } from './LoginForm';
import LoginServicesButton from './LoginServicesButton';
const LoginServices = ({
@ -11,7 +11,7 @@ const LoginServices = ({
setError,
}: {
disabled?: boolean;
setError: Dispatch<SetStateAction<LoginErrors | undefined>>;
setError: Dispatch<SetStateAction<LoginErrorState>>;
}): ReactElement | null => {
const { t } = useTranslation();
const services = useLoginServices();

@ -5,7 +5,7 @@ import { useLoginWithService, useTranslation } from '@rocket.chat/ui-contexts';
import type { ReactElement, SetStateAction, Dispatch } from 'react';
import { useCallback } from 'react';
import type { LoginErrors } from './LoginForm';
import type { LoginErrorState, LoginErrors } from './LoginForm';
const LoginServicesButton = <T extends LoginService>({
buttonLabelText,
@ -19,17 +19,17 @@ const LoginServicesButton = <T extends LoginService>({
}: T & {
className?: string;
disabled?: boolean;
setError?: Dispatch<SetStateAction<LoginErrors | undefined>>;
setError?: Dispatch<SetStateAction<LoginErrorState>>;
}): ReactElement => {
const t = useTranslation();
const handler = useLoginWithService({ service, buttonLabelText, ...props });
const handleOnClick = useCallback(() => {
handler().catch((e: { error?: LoginErrors }) => {
handler().catch((e: { error?: LoginErrors; reason?: string }) => {
if (!e.error || typeof e.error !== 'string') {
return;
}
setError?.(e.error);
setError?.([e.error, e.reason]);
});
}, [handler, setError]);

Loading…
Cancel
Save