2023-09-15 10:08:21 +02:00
|
|
|
import * as React from 'react';
|
2021-05-24 14:46:22 +02:00
|
|
|
|
2023-08-07 10:44:05 +01:00
|
|
|
import { useNotification } from '../features/Notifications';
|
2023-10-18 11:22:34 +01:00
|
|
|
import { useRBACProvider, Permission } from '../features/RBAC';
|
2023-08-07 10:44:05 +01:00
|
|
|
import { hasPermissions } from '../utils/hasPermissions';
|
2020-06-10 14:37:43 +02:00
|
|
|
|
2020-06-11 09:38:34 +02:00
|
|
|
// NOTE: this component is very similar to the CheckPagePermissions
|
2020-06-10 14:37:43 +02:00
|
|
|
// except that it does not handle redirections nor loading state
|
|
|
|
|
|
2023-10-12 17:10:45 +01:00
|
|
|
export interface CheckPermissionsProps {
|
2023-09-15 10:08:21 +02:00
|
|
|
children: React.ReactNode;
|
|
|
|
|
permissions?: Permission[];
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-12 17:10:45 +01:00
|
|
|
const CheckPermissions = ({ permissions = [], children }: CheckPermissionsProps) => {
|
2021-05-24 14:46:22 +02:00
|
|
|
const { allPermissions } = useRBACProvider();
|
2021-05-17 15:55:46 +02:00
|
|
|
const toggleNotification = useNotification();
|
2023-09-15 10:08:21 +02:00
|
|
|
const [state, setState] = React.useState({ isLoading: true, canAccess: false });
|
|
|
|
|
const isMounted = React.useRef(true);
|
2020-06-19 17:33:47 +02:00
|
|
|
const abortController = new AbortController();
|
|
|
|
|
const { signal } = abortController;
|
2020-06-10 14:37:43 +02:00
|
|
|
|
2023-09-15 10:08:21 +02:00
|
|
|
React.useEffect(() => {
|
2020-06-10 14:37:43 +02:00
|
|
|
const checkPermission = async () => {
|
|
|
|
|
try {
|
2020-06-10 16:05:56 +02:00
|
|
|
setState({ isLoading: true, canAccess: false });
|
|
|
|
|
|
2023-09-15 10:08:21 +02:00
|
|
|
const canAccess = await hasPermissions(allPermissions || [], permissions, signal);
|
2020-06-10 14:37:43 +02:00
|
|
|
|
2020-06-10 15:52:10 +02:00
|
|
|
if (isMounted.current) {
|
|
|
|
|
setState({ isLoading: false, canAccess });
|
|
|
|
|
}
|
2020-06-10 14:37:43 +02:00
|
|
|
} catch (err) {
|
2020-06-10 15:52:10 +02:00
|
|
|
if (isMounted.current) {
|
|
|
|
|
console.error(err);
|
2023-09-15 10:08:21 +02:00
|
|
|
toggleNotification?.({
|
2020-10-02 18:58:15 +02:00
|
|
|
type: 'warning',
|
|
|
|
|
message: { id: 'notification.error' },
|
|
|
|
|
});
|
2020-06-10 14:37:43 +02:00
|
|
|
|
2023-09-15 10:08:21 +02:00
|
|
|
setState({ isLoading: false, canAccess: false });
|
2020-06-10 15:52:10 +02:00
|
|
|
}
|
2020-06-10 14:37:43 +02:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
checkPermission();
|
2020-06-19 17:33:47 +02:00
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
abortController.abort();
|
|
|
|
|
};
|
2020-06-10 14:37:43 +02:00
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
2020-06-10 16:05:56 +02:00
|
|
|
}, [permissions]);
|
2020-06-10 15:52:10 +02:00
|
|
|
|
2023-09-15 10:08:21 +02:00
|
|
|
React.useEffect(() => {
|
2020-06-10 15:52:10 +02:00
|
|
|
return () => {
|
|
|
|
|
isMounted.current = false;
|
|
|
|
|
};
|
2020-06-10 14:37:43 +02:00
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
if (state.isLoading) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!state.canAccess) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-12 17:10:45 +01:00
|
|
|
return <>{children}</>;
|
2020-06-10 14:37:43 +02:00
|
|
|
};
|
|
|
|
|
|
2023-08-07 10:44:05 +01:00
|
|
|
export { CheckPermissions };
|