From f1cdf58a5cff5ed59edc47c45a88857a3156b377 Mon Sep 17 00:00:00 2001 From: Nichita Pasecinic Date: Thu, 12 May 2022 20:47:45 +0300 Subject: [PATCH 1/2] fix: flickering for invalid role check --- example/src/App.tsx | 2 +- src/hooks/use-role.hook.ts | 85 +++++++++++--------- src/route/common.tsx | 2 +- src/route/private.tsx | 2 +- src/route/public.tsx | 2 +- src/shared/invalid-user-default-fallback.tsx | 2 +- 6 files changed, 50 insertions(+), 45 deletions(-) diff --git a/example/src/App.tsx b/example/src/App.tsx index 41b3e87..9d2687b 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -82,7 +82,7 @@ const App = () => { -
+
pages wrapper
diff --git a/src/hooks/use-role.hook.ts b/src/hooks/use-role.hook.ts index 87d4f2d..a4b4bef 100644 --- a/src/hooks/use-role.hook.ts +++ b/src/hooks/use-role.hook.ts @@ -1,5 +1,5 @@ -import {useContext, useEffect, useState} from 'react'; -import {RouterContext} from "../context/context"; +import { useContext, useEffect, useState } from 'react'; +import { RouterContext } from '../context/context'; /** * Custom hook that returns a boolean value if the user can access the specified route path, @@ -17,50 +17,55 @@ export const useRole = ( ) => { const ctx = useContext(RouterContext); if (!ctx) { - throw new Error( - `useRole hook must be used inside AppRouter provider!`, - ); + throw new Error(`useRole hook must be used inside AppRouter provider!`); } - const [userHasRequiredRole, setUserHasRequiredRole] = useState(false); const { userRole } = ctx; + const [userHasRequiredRole, setUserHasRequiredRole] = useState(() => + checkRole(path, routeRoles, userRole, allRolesRequired), + ); + useEffect(() => { - /** the route has some roles */ - if (routeRoles && routeRoles.length) { - if (!userRole) { - /** but user has no role */ - const errorMsg = `The path ${path} has some required roles: ${JSON.stringify( - routeRoles, - )}, but current user does not have a role!`; - console.error(errorMsg); - // throw new Error(errorMsg); - } else { - /** check against user role/s */ + const canAccess = checkRole(path, routeRoles, userRole, allRolesRequired); + if (canAccess !== userHasRequiredRole) setUserHasRequiredRole(canAccess); + }, [userRole, routeRoles]); + + return [userHasRequiredRole]; +}; - if (Array.isArray(userRole)) { - /** user has multiple roles */ - if (allRolesRequired) { - /** and all roles must be required */ - const hasAllRoles = routeRoles.every((r) => userRole.includes(r)); - setUserHasRequiredRole(hasAllRoles); - } else { - /** user must have at least one role */ - const hasAtLeastOneRole = userRole.some((r) => - routeRoles.includes(r), - ); - setUserHasRequiredRole(hasAtLeastOneRole); - } - } else { - /** user has a single role */ - const roleIsIncluded = routeRoles.includes(userRole); - setUserHasRequiredRole(roleIsIncluded); +const checkRole = ( + path: string, + routeRoles?: string[], + userRole?: string[] | string, + allRolesRequired?: boolean, +): boolean => { + /** the route has some roles */ + if (routeRoles && routeRoles.length) { + if (!userRole) { + /** but user has no role */ + const errorMsg = `The path ${path} has some required roles: ${JSON.stringify( + routeRoles, + )}, but current user does not have a role!`; + console.error(errorMsg); + // throw new Error(errorMsg); + } else { + /** check against user role/s */ + if (Array.isArray(userRole)) { + /** user has multiple roles */ + if (allRolesRequired) { + /** and all roles must be required */ + const hasAllRoles = routeRoles.every((r) => userRole.includes(r)); + return hasAllRoles; } + /** user must have at least one role */ + const hasAtLeastOneRole = userRole.some((r) => routeRoles.includes(r)); + return hasAtLeastOneRole; } - } else { - /** the route has no roles */ - setUserHasRequiredRole(true); + /** user has a single role */ + const roleIsIncluded = routeRoles.includes(userRole); + return roleIsIncluded; } - }, [userRole, routeRoles]); - - return [userHasRequiredRole]; + } + /** the route has no roles */ + return true; }; \ No newline at end of file diff --git a/src/route/common.tsx b/src/route/common.tsx index 474359a..d0da68b 100644 --- a/src/route/common.tsx +++ b/src/route/common.tsx @@ -19,7 +19,7 @@ export const Common: FC = (props): ReactElement => { ? defaultFallback : null; - if (userHasRequiredRole === false) { + if (!userHasRequiredRole) { return InvalidUserRoleFallback ? ( = (props): ReactElement => { } /** user must have the required role that matches a route role */ - if (userHasRequiredRole === false) { + if (!userHasRequiredRole) { return InvalidUserRoleFallback ? ( = (props): ReactElement => { } /** user must have the required role that matches a route role */ - if (userHasRequiredRole === false) { + if (!userHasRequiredRole) { return InvalidUserRoleFallback ? ( = ({


- Route required roles:{' '} + Route required roles:  {JSON.stringify(routeRequiredRoles)}

From eb81ee91e146cef4683138e2cc21dd10ac7688fd Mon Sep 17 00:00:00 2001 From: Nichita Pasecinic Date: Thu, 12 May 2022 20:48:09 +0300 Subject: [PATCH 2/2] update `package.json` version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c50dba8..dc321ef 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "0.4.1", + "version": "0.4.2", "license": "MIT", "main": "dist/index.js", "typings": "dist/index.d.ts",