diff --git a/src/front/Api/Entities/rule.ts b/src/front/Api/Entities/rule.ts new file mode 100644 index 00000000..72716a8e --- /dev/null +++ b/src/front/Api/Entities/rule.ts @@ -0,0 +1,16 @@ +export interface IAppRule { + name: AppRuleNames; + action: AppRuleActions; +} + +export enum AppRuleActions { + read = "GET", + create = "POST", + update = "PUT", + delete = "DELETE", +} + +export enum AppRuleNames { + users = "users", + officeFolders = "folders", +} diff --git a/src/front/Components/DesignSystem/FolderListContainer/index.tsx b/src/front/Components/DesignSystem/FolderListContainer/index.tsx index 11753672..7c730e6e 100644 --- a/src/front/Components/DesignSystem/FolderListContainer/index.tsx +++ b/src/front/Components/DesignSystem/FolderListContainer/index.tsx @@ -9,6 +9,8 @@ import BlockList, { IBlock } from "../BlockList"; import Button from "../Button"; import SearchBar from "../SearchBar"; import classes from "./classes.module.scss"; +import Rules, { RulesMode } from "@Front/Components/Elements/Rules"; +import { AppRuleActions, AppRuleNames } from "@Front/Api/Entities/rule"; type IProps = { folders: OfficeFolder[]; @@ -53,9 +55,18 @@ class FolderListContainerClass extends React.Component { {!this.props.isArchived && (
- - - + + + + +
)} diff --git a/src/front/Components/Elements/Rules/index.tsx b/src/front/Components/Elements/Rules/index.tsx new file mode 100644 index 00000000..889adf89 --- /dev/null +++ b/src/front/Components/Elements/Rules/index.tsx @@ -0,0 +1,45 @@ +import React, { useCallback, useEffect } from "react"; +import { useRouter } from "next/router"; +import Module from "@Front/Config/Module"; +import JwtService from "@Front/Services/JwtService/JwtService"; +import { IAppRule } from "@Front/Api/Entities/rule"; + +export enum RulesMode { + OPTIONAL = "optional", + NECESSARY = "necessary", +} + +type IProps = { + isPage?: boolean; + mode: RulesMode; + rules: IAppRule[]; + no?: boolean; + children: JSX.Element; +}; + +export default function Rules(props: IProps) { + const router = useRouter(); + + const getShowValue = useCallback(() => { + if (props.mode === RulesMode.NECESSARY) { + return props.rules.every((rule) => JwtService.getInstance().hasRule(rule.name, rule.action)); + } + return !!props.rules.find((rule) => JwtService.getInstance().hasRule(rule.name, rule.action)); + }, [props.mode, props.rules]); + + const show = getShowValue(); + const [isShowing, setIsShowing] = React.useState(props.no ? !show : show); + + useEffect(() => { + setIsShowing(props.no ? !show : show); + }, [props.no, show]); + + if (!isShowing && props.isPage) { + router.push(Module.getInstance().get().modules.pages.Home.props.path); + } + + if (!JwtService.getInstance().decodeJwt() || !isShowing) { + return null; + } + return props.children; +} diff --git a/src/front/Services/JwtService/JwtService.ts b/src/front/Services/JwtService/JwtService.ts index 3d1d5ac4..86380536 100644 --- a/src/front/Services/JwtService/JwtService.ts +++ b/src/front/Services/JwtService/JwtService.ts @@ -66,4 +66,12 @@ export default class JwtService { } } } + + public hasRule(name: string, action: string) { + const accessToken = CookieService.getInstance().getCookie("leCoffreAccessToken"); + if (!accessToken) return false; + const decodedToken = this.decodeJwt(); + if (!decodedToken) return false; + return decodedToken?.rules?.some((rule: string) => rule === `${action} ${name}`); + } }