From d484cf33b9d6582caa814ba06ef22ea12cb31488 Mon Sep 17 00:00:00 2001 From: Remy van der Wereld Date: Tue, 13 Aug 2024 14:46:21 +0200 Subject: [PATCH] 121703 Added permission checks --- package-lock.json | 92 ++++++++++--------- package.json | 2 +- .../ChangeableItem/ChangeableItem.tsx | 26 +++--- .../case/CaseDetails/EditableTag/CaseTags.tsx | 26 +++--- .../components/case/CaseStatus/CaseStatus.tsx | 15 ++- .../components/SelectTaskWorkflow.tsx | 7 +- .../tasks/ChangeDueDate/ChangebleDueDate.tsx | 7 +- .../TableTasks/SelectTask/SelectTask.tsx | 8 +- src/app/pages/cases/routes.tsx | 27 ++++-- .../custom/usePermissions/useHasPermission.ts | 1 + 10 files changed, 123 insertions(+), 88 deletions(-) diff --git a/package-lock.json b/package-lock.json index e5cf6da3b..aa139c962 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,6 @@ "@types/lodash.debounce": "^4.0.7", "@types/lodash.isempty": "^4.4.7", "@types/lodash.merge": "^4.6.7", - "@types/node": "^20.14.2", "@types/qs": "^6.9.15", "@types/react": "^17.0.43", "@types/react-dom": "^18.0.3", @@ -55,7 +54,7 @@ }, "devDependencies": { "@babel/preset-env": "^7.24.7", - "@babel/preset-react": "^7.23.3", + "@babel/preset-react": "^7.24.7", "@babel/preset-typescript": "^7.24.7", "@types/dotenv-flow": "^3.2.0", "@types/jest": "^29.5.3", @@ -445,9 +444,10 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", - "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -520,9 +520,10 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", - "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -1627,11 +1628,12 @@ } }, "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz", - "integrity": "sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.7.tgz", + "integrity": "sha512-H/Snz9PFxKsS1JLI4dJLtnJgCJRoo0AUm3chP6NYr+9En1JMKloheEiLIhlp5MDVznWo+H3AAC1Mc8lmUEpsgg==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1641,15 +1643,16 @@ } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz", - "integrity": "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.2.tgz", + "integrity": "sha512-KQsqEAVBpU82NM/B/N9j9WOdphom1SZH3R+2V7INrQUH+V9EBFwZsEJl8eBIVeQE62FxJCc70jzEZwqU7RcVqA==", + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.23.3", - "@babel/types": "^7.23.4" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/plugin-syntax-jsx": "^7.24.7", + "@babel/types": "^7.25.2" }, "engines": { "node": ">=6.9.0" @@ -1659,11 +1662,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", - "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.24.7.tgz", + "integrity": "sha512-QG9EnzoGn+Qar7rxuW+ZOsbWOt56FvvI93xInqsZDC5fsekx1AlIO4KIJ5M+D0p0SqSH156EpmZyXq630B8OlQ==", + "license": "MIT", "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.22.5" + "@babel/plugin-transform-react-jsx": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1701,12 +1705,13 @@ } }, "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz", - "integrity": "sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.7.tgz", + "integrity": "sha512-PLgBVk3fzbmEjBJ/u8kFzOqS9tUeDjiaWud/rRym/yjCo/M9cASPlnrd2ZmmZpQT40fOOrvR8jh+n8jikrOhNA==", + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -2056,16 +2061,17 @@ } }, "node_modules/@babel/preset-react": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.23.3.tgz", - "integrity": "sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.24.7.tgz", + "integrity": "sha512-AAH4lEkpmzFWrGVlHaxJB7RLH21uPQ9+He+eFLWHmF9IuFQVugz8eAsamaW0DXRrTfco5zj1wWtpdcXJUOfsag==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.15", - "@babel/plugin-transform-react-display-name": "^7.23.3", - "@babel/plugin-transform-react-jsx": "^7.22.15", - "@babel/plugin-transform-react-jsx-development": "^7.22.5", - "@babel/plugin-transform-react-pure-annotations": "^7.23.3" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-transform-react-display-name": "^7.24.7", + "@babel/plugin-transform-react-jsx": "^7.24.7", + "@babel/plugin-transform-react-jsx-development": "^7.24.7", + "@babel/plugin-transform-react-pure-annotations": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -2142,11 +2148,12 @@ } }, "node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz", + "integrity": "sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==", + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-string-parser": "^7.24.8", "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, @@ -14486,6 +14493,7 @@ "version": "5.1.6", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index 1fd092ba4..334227da3 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ }, "devDependencies": { "@babel/preset-env": "^7.24.7", - "@babel/preset-react": "^7.23.3", + "@babel/preset-react": "^7.24.7", "@babel/preset-typescript": "^7.24.7", "@types/dotenv-flow": "^3.2.0", "@types/jest": "^29.5.3", diff --git a/src/app/components/case/CaseDetails/ChangeableItem/ChangeableItem.tsx b/src/app/components/case/CaseDetails/ChangeableItem/ChangeableItem.tsx index 54713909a..7a5102d5c 100644 --- a/src/app/components/case/CaseDetails/ChangeableItem/ChangeableItem.tsx +++ b/src/app/components/case/CaseDetails/ChangeableItem/ChangeableItem.tsx @@ -1,6 +1,7 @@ import styled from "styled-components" import { Icon, themeSpacing } from "@amsterdam/asc-ui" import { Edit } from "app/components/shared/Icons" +import useHasPermission, { CAN_PERFORM_TASK } from "app/state/rest/custom/usePermissions/useHasPermission" type Props = { name?: string @@ -27,16 +28,19 @@ const StyledIcon = styled(Icon)` margin-left: ${ themeSpacing(1) }; ` -const ChangeableItem = ({ name = "-", titleAccess = "", onClick }: Props) => ( - - { name } - - - - -) +const ChangeableItem = ({ name = "-", titleAccess = "", onClick }: Props) => { + const [hasPermission] = useHasPermission([CAN_PERFORM_TASK]) + return hasPermission ? ( + + { name } + + + + + ) : <>{ name } +} export default ChangeableItem diff --git a/src/app/components/case/CaseDetails/EditableTag/CaseTags.tsx b/src/app/components/case/CaseDetails/EditableTag/CaseTags.tsx index d34b8c48e..ca4b4aa02 100644 --- a/src/app/components/case/CaseDetails/EditableTag/CaseTags.tsx +++ b/src/app/components/case/CaseDetails/EditableTag/CaseTags.tsx @@ -2,6 +2,7 @@ import styled, { keyframes } from "styled-components" import { Icon, themeSpacing } from "@amsterdam/asc-ui" import { Edit } from "app/components/shared/Icons" +import useHasPermission, { CAN_PERFORM_TASK } from "app/state/rest/custom/usePermissions/useHasPermission" type Props = { @@ -43,16 +44,19 @@ const StyledIcon = styled(Icon)` cursor: pointer; ` -const CaseTags: React.FC = ({ tags = [], titleAccess = "Wijzig tag", onClick }) => ( - - { tags.map(tag => { tag.name })} - - - - -) +const CaseTags: React.FC = ({ tags = [], titleAccess = "Wijzig tag", onClick }) => { + const [hasPermission] = useHasPermission([CAN_PERFORM_TASK]) + return hasPermission ? ( + + { tags.map(tag => { tag.name })} + + + + + ) : <>{ tags.length > 0 ? tags.map(tag => { tag.name }) : "-"} +} export default CaseTags diff --git a/src/app/components/case/CaseStatus/CaseStatus.tsx b/src/app/components/case/CaseStatus/CaseStatus.tsx index 97c005a39..dbd63dd81 100644 --- a/src/app/components/case/CaseStatus/CaseStatus.tsx +++ b/src/app/components/case/CaseStatus/CaseStatus.tsx @@ -1,11 +1,12 @@ import styled from "styled-components" -import { Button, Divider, Heading, themeSpacing } from "@amsterdam/asc-ui" +import { Divider, Heading, themeSpacing } from "@amsterdam/asc-ui" import Workflow from "../Workflow/Workflow" import { Row, Column, RowWithColumn } from "app/components/layouts/Grid" -import ButtonLink from "app/components/shared/ButtonLink/ButtonLink" import to from "app/routing/utils/to" +import IsAuthorizedButtonLink from "app/components/shared/ButtonLink/IsAuthorizedButtonLink" +import { CAN_PERFORM_TASK } from "app/state/rest/custom/usePermissions/useHasPermission" type Props = { id: Components.Schemas.CaseDetail["id"] @@ -29,9 +30,13 @@ const CaseStatus: React.FC = ({ id }) => ( - - - + diff --git a/src/app/components/case/Workflow/components/SelectTaskWorkflow.tsx b/src/app/components/case/Workflow/components/SelectTaskWorkflow.tsx index 292b71b6a..72eb65cf0 100644 --- a/src/app/components/case/Workflow/components/SelectTaskWorkflow.tsx +++ b/src/app/components/case/Workflow/components/SelectTaskWorkflow.tsx @@ -7,6 +7,7 @@ import { createNameAbbreviation } from "app/components/shared/Helpers/helpers" import CustomTooltip from "app/components/help/HelpContent/CustomTooltip" import { makeApiUrl } from "app/state/rest/hooks/utils/apiUrl" import UserIcon from "./UserInitials" +import useHasPermission, { CAN_PERFORM_TASK } from "app/state/rest/custom/usePermissions/useHasPermission" type Props = { @@ -33,8 +34,8 @@ const SelectTaskWorkflow: React.FC = ({ task }) => { const [me, { isBusy }] = useUsersMe() const [, { execPatch }] = useTask(taskId) const apiUrl = makeApiUrl("cases", caseId, "workflows") - const { getContextItem, updateContextItem } = useContextCache("cases", apiUrl) + const [hasPermission] = useHasPermission([CAN_PERFORM_TASK]) useEffect(() => { // Check if userId is matching with the taskOwner. @@ -88,13 +89,13 @@ const SelectTaskWorkflow: React.FC = ({ task }) => { if (taskOwner && taskOwner !== me?.id ) { return } - return ( + return hasPermission ? ( - ) + ) : <>- } export default SelectTaskWorkflow diff --git a/src/app/components/case/tasks/ChangeDueDate/ChangebleDueDate.tsx b/src/app/components/case/tasks/ChangeDueDate/ChangebleDueDate.tsx index ad7394e72..90fac55c7 100644 --- a/src/app/components/case/tasks/ChangeDueDate/ChangebleDueDate.tsx +++ b/src/app/components/case/tasks/ChangeDueDate/ChangebleDueDate.tsx @@ -6,6 +6,7 @@ import { appendTimeToDate } from "app/components/shared/Helpers/helpers" import DueDate from "app/components/shared/DueDate/DueDate" import ChangeDueDateModal from "./ChangeDueDateModal" import { useTaskUpdate } from "app/state/rest" +import useHasPermission, { CAN_PERFORM_TASK } from "app/state/rest/custom/usePermissions/useHasPermission" type Props = { caseId: Components.Schemas.CaseDetail["id"] @@ -30,9 +31,9 @@ const StyledIcon = styled(Icon)` ` const ChangeableDueDate: React.FC = ({ dueDate, caseId, caseUserTaskId }) => { - const { isModalOpen, openModal, closeModal } = useModal() const [, { execPatch }] = useTaskUpdate(caseUserTaskId) + const [hasPermission] = useHasPermission([CAN_PERFORM_TASK]) const onSubmit = (data: { date: string, id: string }) => { appendTimeToDate(data.date) !== dueDate @@ -40,7 +41,7 @@ const ChangeableDueDate: React.FC = ({ dueDate, caseId, caseUserTaskId }) : closeModal() } - return ( + return hasPermission ? ( <> = ({ dueDate, caseId, caseUserTaskId }) taskId={ caseUserTaskId } /> - ) + ) : } export default ChangeableDueDate diff --git a/src/app/components/tasks/TableTasks/SelectTask/SelectTask.tsx b/src/app/components/tasks/TableTasks/SelectTask/SelectTask.tsx index 4aaf59a3a..260abbd72 100644 --- a/src/app/components/tasks/TableTasks/SelectTask/SelectTask.tsx +++ b/src/app/components/tasks/TableTasks/SelectTask/SelectTask.tsx @@ -6,7 +6,7 @@ import UserIcon from "./UserIcon" import useContextCache from "app/state/rest/provider/useContextCache" import { createNameAbbreviation } from "app/components/shared/Helpers/helpers" import CustomTooltip from "app/components/help/HelpContent/CustomTooltip" -import useHasPermission, { SENSITIVE_CASE_PERMISSION } from "app/state/rest/custom/usePermissions/useHasPermission" +import useHasPermission, { CAN_PERFORM_TASK, SENSITIVE_CASE_PERMISSION } from "app/state/rest/custom/usePermissions/useHasPermission" import { ContextValues } from "app/state/context/ValueProvider" import { getQueryUrl } from "app/state/rest/tasks" @@ -37,6 +37,7 @@ const SelectTask: React.FC = ({ taskId, taskOwner, isEnforcement }) => { tags, taskNames, reason, districtNames, housingCorporations } = useContext(ContextValues)["tasks"] const [hasPermission] = useHasPermission([SENSITIVE_CASE_PERMISSION]) + const [hasPerformTaskPermission] = useHasPermission([CAN_PERFORM_TASK]) const [isChecked, setIsChecked] = useState(false) const [loading, setLoading] = useState(false) const [data, { isBusy }] = useUsersMe() @@ -93,13 +94,14 @@ const SelectTask: React.FC = ({ taskId, taskOwner, isEnforcement }) => { if (taskOwner && taskOwner !== data?.id ) { return } - return ( + + return hasPerformTaskPermission ? ( - ) + ) : <>- } export default SelectTask diff --git a/src/app/pages/cases/routes.tsx b/src/app/pages/cases/routes.tsx index 16c5b06e6..5a62d9987 100644 --- a/src/app/pages/cases/routes.tsx +++ b/src/app/pages/cases/routes.tsx @@ -25,47 +25,56 @@ export default { "afronding/:caseUserTaskId": { Page: CompleteCasePage, title: "Zaak afronden", - icon: "Edit" + icon: "Edit", + permissionNames: ["perform_task"] }, "taak": { Page: TaskCreatePage, title: "Taak opvoeren", - icon: "Edit" + icon: "Edit", + permissionNames: ["perform_task"] }, "debriefing/:caseUserTaskId": { Page: DebriefCreatePage, title: "Debrief terugkoppeling geven", - icon: "Edit" + icon: "Edit", + permissionNames: ["perform_task"] }, "besluit/:caseUserTaskId": { Page: DecisionCreatePage, title: "Resultaat besluit", - icon: "Edit" + icon: "Edit", + permissionNames: ["perform_task"] }, "snel-besluit/:caseUserTaskId": { Page: QuickDecisionCreatePage, title: "Resultaat besluit", - icon: "Edit" + icon: "Edit", + permissionNames: ["perform_task"] }, "aanschrijving/:caseUserTaskId": { Page: SummonCreatePage, title: "Resultaat aanschrijving", - icon: "Edit" + icon: "Edit", + permissionNames: ["perform_task"] }, "inplanning/:caseUserTaskId": { Page: ScheduleCreatePage, title: "Bezoek inplannen", - icon: "Edit" + icon: "Edit", + permissionNames: ["perform_task"] }, "huisbezoek/:caseUserTaskId": { Page: VisitCreatePage, title: "Resultaat bezoek", - icon: "Edit" + icon: "Edit", + permissionNames: ["perform_task"] }, "melding/:caseUserTaskId": { Page: CitizenReportPage, title: "Melding verwerken", - icon: "Edit" + icon: "Edit", + permissionNames: ["perform_task"] } } } diff --git a/src/app/state/rest/custom/usePermissions/useHasPermission.ts b/src/app/state/rest/custom/usePermissions/useHasPermission.ts index aa57318b7..a656d4ad3 100644 --- a/src/app/state/rest/custom/usePermissions/useHasPermission.ts +++ b/src/app/state/rest/custom/usePermissions/useHasPermission.ts @@ -26,3 +26,4 @@ export default (permissionsToCheck?: Components.Schemas.PermissionsEnum[]) => { } export const SENSITIVE_CASE_PERMISSION = "access_sensitive_dossiers" +export const CAN_PERFORM_TASK = "perform_task"