Skip to content

Commit 5c17f82

Browse files
authored
Merge pull request #8 from nichitaa/dev
fix flickering for first check/validation of user role
2 parents a984572 + eb81ee9 commit 5c17f82

File tree

7 files changed

+51
-46
lines changed

7 files changed

+51
-46
lines changed

example/src/App.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ const App = () => {
8282
</Link>
8383
</li>
8484
</ul>
85-
<fieldset>
85+
<fieldset style={{minHeight: 100}}>
8686
<legend>pages wrapper</legend>
8787
<Routes />
8888
</fieldset>

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "0.4.1",
2+
"version": "0.4.2",
33
"license": "MIT",
44
"main": "dist/index.js",
55
"typings": "dist/index.d.ts",

src/hooks/use-role.hook.ts

+45-40
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import {useContext, useEffect, useState} from 'react';
2-
import {RouterContext} from "../context/context";
1+
import { useContext, useEffect, useState } from 'react';
2+
import { RouterContext } from '../context/context';
33

44
/**
55
* Custom hook that returns a boolean value if the user can access the specified route path,
@@ -17,50 +17,55 @@ export const useRole = (
1717
) => {
1818
const ctx = useContext(RouterContext);
1919
if (!ctx) {
20-
throw new Error(
21-
`useRole hook must be used inside AppRouter provider!`,
22-
);
20+
throw new Error(`useRole hook must be used inside AppRouter provider!`);
2321
}
24-
const [userHasRequiredRole, setUserHasRequiredRole] = useState(false);
2522
const { userRole } = ctx;
2623

24+
const [userHasRequiredRole, setUserHasRequiredRole] = useState(() =>
25+
checkRole(path, routeRoles, userRole, allRolesRequired),
26+
);
27+
2728
useEffect(() => {
28-
/** the route has some roles */
29-
if (routeRoles && routeRoles.length) {
30-
if (!userRole) {
31-
/** but user has no role */
32-
const errorMsg = `The path ${path} has some required roles: ${JSON.stringify(
33-
routeRoles,
34-
)}, but current user does not have a role!`;
35-
console.error(errorMsg);
36-
// throw new Error(errorMsg);
37-
} else {
38-
/** check against user role/s */
29+
const canAccess = checkRole(path, routeRoles, userRole, allRolesRequired);
30+
if (canAccess !== userHasRequiredRole) setUserHasRequiredRole(canAccess);
31+
}, [userRole, routeRoles]);
32+
33+
return [userHasRequiredRole];
34+
};
3935

40-
if (Array.isArray(userRole)) {
41-
/** user has multiple roles */
42-
if (allRolesRequired) {
43-
/** and all roles must be required */
44-
const hasAllRoles = routeRoles.every((r) => userRole.includes(r));
45-
setUserHasRequiredRole(hasAllRoles);
46-
} else {
47-
/** user must have at least one role */
48-
const hasAtLeastOneRole = userRole.some((r) =>
49-
routeRoles.includes(r),
50-
);
51-
setUserHasRequiredRole(hasAtLeastOneRole);
52-
}
53-
} else {
54-
/** user has a single role */
55-
const roleIsIncluded = routeRoles.includes(userRole);
56-
setUserHasRequiredRole(roleIsIncluded);
36+
const checkRole = (
37+
path: string,
38+
routeRoles?: string[],
39+
userRole?: string[] | string,
40+
allRolesRequired?: boolean,
41+
): boolean => {
42+
/** the route has some roles */
43+
if (routeRoles && routeRoles.length) {
44+
if (!userRole) {
45+
/** but user has no role */
46+
const errorMsg = `The path ${path} has some required roles: ${JSON.stringify(
47+
routeRoles,
48+
)}, but current user does not have a role!`;
49+
console.error(errorMsg);
50+
// throw new Error(errorMsg);
51+
} else {
52+
/** check against user role/s */
53+
if (Array.isArray(userRole)) {
54+
/** user has multiple roles */
55+
if (allRolesRequired) {
56+
/** and all roles must be required */
57+
const hasAllRoles = routeRoles.every((r) => userRole.includes(r));
58+
return hasAllRoles;
5759
}
60+
/** user must have at least one role */
61+
const hasAtLeastOneRole = userRole.some((r) => routeRoles.includes(r));
62+
return hasAtLeastOneRole;
5863
}
59-
} else {
60-
/** the route has no roles */
61-
setUserHasRequiredRole(true);
64+
/** user has a single role */
65+
const roleIsIncluded = routeRoles.includes(userRole);
66+
return roleIsIncluded;
6267
}
63-
}, [userRole, routeRoles]);
64-
65-
return [userHasRequiredRole];
68+
}
69+
/** the route has no roles */
70+
return true;
6671
};

src/route/common.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export const Common: FC<IRoute> = (props): ReactElement => {
1919
? defaultFallback
2020
: null;
2121

22-
if (userHasRequiredRole === false) {
22+
if (!userHasRequiredRole) {
2323
return InvalidUserRoleFallback ? (
2424
<InvalidUserRoleFallback
2525
currentUserRole={userRole}

src/route/private.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export const Private: FC<IRoute> = (props): ReactElement => {
2929
}
3030

3131
/** user must have the required role that matches a route role */
32-
if (userHasRequiredRole === false) {
32+
if (!userHasRequiredRole) {
3333
return InvalidUserRoleFallback ? (
3434
<InvalidUserRoleFallback
3535
currentUserRole={userRole}

src/route/public.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export const Public: FC<IRoute> = (props): ReactElement => {
2828
}
2929

3030
/** user must have the required role that matches a route role */
31-
if (userHasRequiredRole === false) {
31+
if (!userHasRequiredRole) {
3232
return InvalidUserRoleFallback ? (
3333
<InvalidUserRoleFallback
3434
currentUserRole={userRole}

src/shared/invalid-user-default-fallback.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const InvalidUserDefaultFallback: FC<MainProps> = ({
1616
</p>
1717
<br />
1818
<p>
19-
Route required roles:{' '}
19+
Route required roles:&nbsp;
2020
<strong>{JSON.stringify(routeRequiredRoles)}</strong>
2121
</p>
2222
</>

0 commit comments

Comments
 (0)