diff --git a/src/ui/components/userDetail/userDetailForm.tsx b/src/ui/components/userDetail/userDetailForm.tsx index 61d1e664..d4ecabc3 100644 --- a/src/ui/components/userDetail/userDetailForm.tsx +++ b/src/ui/components/userDetail/userDetailForm.tsx @@ -18,6 +18,7 @@ import { Tenant } from "../../../api/tenants/list"; import { useUserService } from "../../../api/user"; import usePasswordResetService from "../../../api/user/password/reset"; import { getImageUrl } from "../../../utils"; +import { ForbiddenError } from "../../../utils/customErrors"; import { getTenantsObjectsForIds } from "../../../utils/user"; import { PopupContentContext } from "../../contexts/PopupContentContext"; import { useTenantsListContext } from "../../contexts/TenantsListContext"; @@ -289,20 +290,26 @@ export const UserDetailChangeEmailForm: FC = ( return; } - const response = await updateUserInformation({ - userId, - email, - recipeId, - tenantId, - }); - - if (response.status === "INVALID_EMAIL_ERROR") { - setApiError(response.error); - } else if (response.status === "EMAIL_ALREADY_EXISTS_ERROR") { - setApiError("A user with this email already exists"); - } else { - showToast(getUpdateEmailToast(true)); - await onEmailChange(true); + try { + const response = await updateUserInformation({ + userId, + email, + recipeId, + tenantId, + }); + + if (response.status === "INVALID_EMAIL_ERROR") { + setApiError(response.error); + } else if (response.status === "EMAIL_ALREADY_EXISTS_ERROR") { + setApiError("A user with this email already exists"); + } else if (response.status === "OK") { + showToast(getUpdateEmailToast(true)); + await onEmailChange(true); + } + } catch (error) { + if (ForbiddenError.isThisError(error)) { + void onCancel(); + } } }; @@ -383,17 +390,23 @@ export const UserDetailChangePasswordForm: FC return; } - const response = await updatePassword( - userId, - password, - matchingTenantIds.length > 0 ? matchingTenantIds[0].tenantId : undefined - ); + try { + const response = await updatePassword( + userId, + password, + matchingTenantIds.length > 0 ? matchingTenantIds[0].tenantId : undefined + ); - if (response.status === "INVALID_PASSWORD_ERROR") { - setApiError(response.error); - } else { - showToast(getUpdatePasswordToast(true)); - await onPasswordChange(); + if (response?.status === "INVALID_PASSWORD_ERROR") { + setApiError(response.error); + } else if (response?.status === "OK") { + showToast(getUpdatePasswordToast(true)); + await onPasswordChange(); + } + } catch (error) { + if (ForbiddenError.isThisError(error)) { + void onCancel(); + } } }; diff --git a/src/utils/customErrors.ts b/src/utils/customErrors.ts new file mode 100644 index 00000000..f41ed17a --- /dev/null +++ b/src/utils/customErrors.ts @@ -0,0 +1,11 @@ +export class ForbiddenError extends Error { + statusCode = 403; + status = "FORBIDDEN_REQUEST"; + constructor(message: string) { + super(message); + } + + static isThisError(err: any): boolean { + return err.status === "FORBIDDEN_REQUEST"; + } +} diff --git a/src/utils/index.ts b/src/utils/index.ts index 4520f9bd..14be0994 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -20,6 +20,7 @@ import NetworkManager from "../services/network"; import { localStorageHandler } from "../services/storage"; import { HttpMethod } from "../types"; import { UserRecipeType } from "../ui/pages/usersList/types"; +import { ForbiddenError } from "./customErrors"; export function getStaticBasePath(): string { return (window as any).staticBasePath; @@ -124,11 +125,17 @@ export const useFetchData = () => { } if (response.status === HTTPStatusCodes.FORBIDDEN) { - const message = (await response.clone().json())?.message; + let message = (await response.clone().json())?.message; + if (message === undefined) { + message = "You do not have access to this page"; + } + window.dispatchEvent(getAccessDeniedEvent(message)); + + /* throwing this error just to make sure that this case is handled in some places in the application. + global search for ForbiddenError.isThisError to see those places + */ - window.dispatchEvent( - getAccessDeniedEvent(message === undefined ? "You do not have access to this page" : message) - ); + throw new ForbiddenError(message); } const logoutAndRedirect = shouldRedirectOnUnauthorised && HTTPStatusCodes.UNAUTHORIZED === response.status;