Newer
Older
import React, { ComponentType, FC, useContext } from 'react';
import { BlurCircular } from '@material-ui/icons';
import { NonAuthRoutes } from 'api/routes';
import { Redirect } from 'react-router-dom';
import { Unauthorized } from 'components/Unauthorized/Unauthorized';
import { AuthContext } from 'components/Auth/AuthContext';
const HandleIsAuth: FC<{ isAuth: boolean }> = ({ isAuth }) =>
isAuth ? (
<Unauthorized />
) : (
<Redirect
to={{ pathname: `${NonAuthRoutes.auth}${NonAuthRoutes.signIn}` }}
/>
);
interface WithAuthProps {
allowedRoles: string[];
}
children: React.ReactNode;
}
/* eslint-disable react/jsx-props-no-spreading */
/**
*
* @param WrappedComponent component to be wrapped by the authentication control.
* This creates a "personal area" in the working implementation.
* @returns {FC<T>} wrapped component.
*/
export const withAuthorization = <T extends WithAuthProps = WithAuthProps>(
WrappedComponent: React.ComponentType<T>,
): FC<T> => {
// Creating the inner component. The calculated Props type here is the where the magic happens.
const ComponentWithAuthorization: FC<T> = (
props: Omit<T, keyof WithAuthProps>,
) => {
const { allowedRoles } = props as T;
const { role, isAuth } = useContext(AuthContext);
console.log(`ROLE ${role} AUTH ${isAuth}`);
/* eslint-disable no-nested-ternary */
return typeof isAuth === null || role === null ? (
<BlurCircular />
) : // props comes afterwards so the can override the default ones.
allowedRoles.includes(role) && isAuth ? (
<HandleIsAuth isAuth={!!isAuth} />