diff --git a/apps/console/src/__generated__/core/TrustCenterFilesCardFragment.graphql.ts b/apps/console/src/__generated__/core/TrustCenterFilesCardFragment.graphql.ts index a75576aa9..83e02861d 100644 --- a/apps/console/src/__generated__/core/TrustCenterFilesCardFragment.graphql.ts +++ b/apps/console/src/__generated__/core/TrustCenterFilesCardFragment.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<0defaaf1ce3544420e8fbd9c9f3af139>> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -12,6 +12,8 @@ import { ReaderFragment } from 'relay-runtime'; export type TrustCenterVisibility = "NONE" | "PRIVATE" | "PUBLIC"; import { FragmentRefs } from "relay-runtime"; export type TrustCenterFilesCardFragment$data = { + readonly canDelete: boolean; + readonly canUpdate: boolean; readonly category: string; readonly createdAt: any; readonly fileUrl: string; @@ -80,12 +82,38 @@ const node: ReaderFragment = { "kind": "ScalarField", "name": "updatedAt", "storageKey": null + }, + { + "alias": "canUpdate", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:trust-center-file:update" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:trust-center-file:update\")" + }, + { + "alias": "canDelete", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:trust-center-file:delete" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:trust-center-file:delete\")" } ], "type": "TrustCenterFile", "abstractKey": null }; -(node as any).hash = "33cb01782ca37fc776cd8e5dfde20f76"; +(node as any).hash = "7b9e482868fc5d815923fbefdbafc8bb"; export default node; diff --git a/apps/console/src/__generated__/core/TrustCenterGraphQuery.graphql.ts b/apps/console/src/__generated__/core/TrustCenterGraphQuery.graphql.ts index b03d29bd0..cc49ca3f5 100644 --- a/apps/console/src/__generated__/core/TrustCenterGraphQuery.graphql.ts +++ b/apps/console/src/__generated__/core/TrustCenterGraphQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -23,6 +23,7 @@ export type TrustCenterGraphQuery$data = { }; }>; }; + readonly canCreateTrustCenterFile?: boolean; readonly customDomain?: { readonly domain: string; readonly id: string; @@ -50,7 +51,10 @@ export type TrustCenterGraphQuery$data = { }; readonly trustCenter?: { readonly active: boolean; + readonly canDeleteNDA: boolean; + readonly canGetNDA: boolean; readonly canUpdate: boolean; + readonly canUploadNDA: boolean; readonly createdAt: any; readonly id: string; readonly ndaFileName: string | null | undefined; @@ -124,6 +128,19 @@ v3 = { "storageKey": null }, v4 = { + "alias": "canCreateTrustCenterFile", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:trust-center-file:create" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:trust-center-file:create\")" +}, +v5 = { "alias": null, "args": null, "concreteType": "CustomDomain", @@ -142,33 +159,33 @@ v4 = { ], "storageKey": null }, -v5 = { +v6 = { "alias": null, "args": null, "kind": "ScalarField", "name": "createdAt", "storageKey": null }, -v6 = { +v7 = { "alias": null, "args": null, "kind": "ScalarField", "name": "updatedAt", "storageKey": null }, -v7 = { +v8 = { "kind": "Literal", "name": "first", "value": 100 }, -v8 = { +v9 = { "alias": null, "args": null, "kind": "ScalarField", "name": "description", "storageKey": null }, -v9 = { +v10 = { "alias": null, "args": null, "concreteType": "TrustCenter", @@ -198,8 +215,8 @@ v9 = { "name": "ndaFileUrl", "storageKey": null }, - (v5/*: any*/), (v6/*: any*/), + (v7/*: any*/), { "alias": "canUpdate", "args": [ @@ -213,10 +230,49 @@ v9 = { "name": "permission", "storageKey": "permission(action:\"core:trust-center:update\")" }, + { + "alias": "canGetNDA", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:trust-center:get-nda" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:trust-center:get-nda\")" + }, + { + "alias": "canUploadNDA", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:trust-center:upload-nda" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:trust-center:upload-nda\")" + }, + { + "alias": "canDeleteNDA", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:trust-center:delete-nda" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:trust-center:delete-nda\")" + }, { "alias": null, "args": [ - (v7/*: any*/), + (v8/*: any*/), { "kind": "Literal", "name": "orderBy", @@ -249,7 +305,7 @@ v9 = { "selections": [ (v2/*: any*/), (v3/*: any*/), - (v8/*: any*/), + (v9/*: any*/), { "alias": null, "args": null, @@ -264,8 +320,8 @@ v9 = { "name": "logoUrl", "storageKey": null }, - (v5/*: any*/), - (v6/*: any*/) + (v6/*: any*/), + (v7/*: any*/) ], "storageKey": null } @@ -278,24 +334,24 @@ v9 = { ], "storageKey": null }, -v10 = [ - (v7/*: any*/) +v11 = [ + (v8/*: any*/) ], -v11 = { +v12 = { "alias": null, "args": null, "kind": "ScalarField", "name": "__typename", "storageKey": null }, -v12 = { +v13 = { "alias": null, "args": null, "kind": "ScalarField", "name": "cursor", "storageKey": null }, -v13 = { +v14 = { "alias": null, "args": null, "concreteType": "PageInfo", @@ -320,7 +376,7 @@ v13 = { ], "storageKey": null }, -v14 = { +v15 = { "kind": "ClientExtension", "selections": [ { @@ -332,9 +388,9 @@ v14 = { } ] }, -v15 = { +v16 = { "alias": null, - "args": (v10/*: any*/), + "args": (v11/*: any*/), "concreteType": "SlackConnectionConnection", "kind": "LinkedField", "name": "slackConnections", @@ -371,8 +427,8 @@ v15 = { "name": "channelId", "storageKey": null }, - (v5/*: any*/), - (v6/*: any*/) + (v6/*: any*/), + (v7/*: any*/) ], "storageKey": null } @@ -382,14 +438,14 @@ v15 = { ], "storageKey": "slackConnections(first:100)" }, -v16 = { +v17 = { "alias": null, "args": null, "kind": "ScalarField", "name": "trustCenterVisibility", "storageKey": null }, -v17 = { +v18 = { "alias": null, "args": null, "kind": "ScalarField", @@ -417,10 +473,11 @@ return { (v2/*: any*/), (v3/*: any*/), (v4/*: any*/), - (v9/*: any*/), + (v5/*: any*/), + (v10/*: any*/), { "alias": null, - "args": (v10/*: any*/), + "args": (v11/*: any*/), "concreteType": "DocumentConnection", "kind": "LinkedField", "name": "documents", @@ -459,7 +516,7 @@ return { }, { "alias": null, - "args": (v10/*: any*/), + "args": (v11/*: any*/), "concreteType": "AuditConnection", "kind": "LinkedField", "name": "audits", @@ -498,7 +555,7 @@ return { }, { "alias": null, - "args": (v10/*: any*/), + "args": (v11/*: any*/), "concreteType": "VendorConnection", "kind": "LinkedField", "name": "vendors", @@ -565,20 +622,20 @@ return { "kind": "FragmentSpread", "name": "TrustCenterFilesCardFragment" }, - (v11/*: any*/) + (v12/*: any*/) ], "storageKey": null }, - (v12/*: any*/) + (v13/*: any*/) ], "storageKey": null }, - (v13/*: any*/), - (v14/*: any*/) + (v14/*: any*/), + (v15/*: any*/) ], "storageKey": null }, - (v15/*: any*/) + (v16/*: any*/) ], "type": "Organization", "abstractKey": null @@ -604,17 +661,18 @@ return { "name": "node", "plural": false, "selections": [ - (v11/*: any*/), + (v12/*: any*/), (v2/*: any*/), { "kind": "InlineFragment", "selections": [ (v3/*: any*/), (v4/*: any*/), - (v9/*: any*/), + (v5/*: any*/), + (v10/*: any*/), { "alias": null, - "args": (v10/*: any*/), + "args": (v11/*: any*/), "concreteType": "DocumentConnection", "kind": "LinkedField", "name": "documents", @@ -644,7 +702,7 @@ return { "name": "title", "storageKey": null }, - (v5/*: any*/), + (v6/*: any*/), { "alias": null, "args": null, @@ -652,7 +710,7 @@ return { "name": "documentType", "storageKey": null }, - (v16/*: any*/), + (v17/*: any*/), { "alias": null, "args": [ @@ -711,7 +769,7 @@ return { }, { "alias": null, - "args": (v10/*: any*/), + "args": (v11/*: any*/), "concreteType": "AuditConnection", "kind": "LinkedField", "name": "audits", @@ -769,8 +827,8 @@ return { "name": "state", "storageKey": null }, - (v16/*: any*/), - (v5/*: any*/) + (v17/*: any*/), + (v6/*: any*/) ], "storageKey": null } @@ -782,7 +840,7 @@ return { }, { "alias": null, - "args": (v10/*: any*/), + "args": (v11/*: any*/), "concreteType": "VendorConnection", "kind": "LinkedField", "name": "vendors", @@ -806,8 +864,8 @@ return { "selections": [ (v2/*: any*/), (v3/*: any*/), - (v17/*: any*/), - (v8/*: any*/), + (v18/*: any*/), + (v9/*: any*/), { "alias": null, "args": null, @@ -815,7 +873,7 @@ return { "name": "showOnTrustCenter", "storageKey": null }, - (v5/*: any*/) + (v6/*: any*/) ], "storageKey": null } @@ -827,7 +885,7 @@ return { }, { "alias": null, - "args": (v10/*: any*/), + "args": (v11/*: any*/), "concreteType": "TrustCenterFileConnection", "kind": "LinkedField", "name": "trustCenterFiles", @@ -851,7 +909,7 @@ return { "selections": [ (v2/*: any*/), (v3/*: any*/), - (v17/*: any*/), + (v18/*: any*/), { "alias": null, "args": null, @@ -859,32 +917,58 @@ return { "name": "fileUrl", "storageKey": null }, - (v16/*: any*/), - (v5/*: any*/), + (v17/*: any*/), (v6/*: any*/), - (v11/*: any*/) + (v7/*: any*/), + { + "alias": "canUpdate", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:trust-center-file:update" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:trust-center-file:update\")" + }, + { + "alias": "canDelete", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:trust-center-file:delete" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:trust-center-file:delete\")" + }, + (v12/*: any*/) ], "storageKey": null }, - (v12/*: any*/) + (v13/*: any*/) ], "storageKey": null }, - (v13/*: any*/), - (v14/*: any*/) + (v14/*: any*/), + (v15/*: any*/) ], "storageKey": "trustCenterFiles(first:100)" }, { "alias": null, - "args": (v10/*: any*/), + "args": (v11/*: any*/), "filters": null, "handle": "connection", "key": "TrustCenterPage_trustCenterFiles", "kind": "LinkedHandle", "name": "trustCenterFiles" }, - (v15/*: any*/) + (v16/*: any*/) ], "type": "Organization", "abstractKey": null @@ -895,7 +979,7 @@ return { ] }, "params": { - "cacheID": "77cfcb8a51459702b07cd2295688ad07", + "cacheID": "0fbd1275d4051e236a6f9711cf21c23b", "id": null, "metadata": { "connection": [ @@ -912,11 +996,11 @@ return { }, "name": "TrustCenterGraphQuery", "operationKind": "query", - "text": "query TrustCenterGraphQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n id\n name\n customDomain {\n id\n domain\n }\n trustCenter {\n id\n active\n ndaFileName\n ndaFileUrl\n createdAt\n updatedAt\n canUpdate: permission(action: \"core:trust-center:update\")\n references(first: 100, orderBy: {field: CREATED_AT, direction: DESC}) {\n edges {\n node {\n id\n name\n description\n websiteUrl\n logoUrl\n createdAt\n updatedAt\n }\n }\n }\n }\n documents(first: 100) {\n edges {\n node {\n id\n ...TrustCenterDocumentsCardFragment\n }\n }\n }\n audits(first: 100) {\n edges {\n node {\n id\n ...TrustCenterAuditsCardFragment\n }\n }\n }\n vendors(first: 100) {\n edges {\n node {\n id\n ...TrustCenterVendorsCardFragment\n }\n }\n }\n trustCenterFiles(first: 100) {\n edges {\n node {\n id\n ...TrustCenterFilesCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n slackConnections(first: 100) {\n edges {\n node {\n id\n channel\n channelId\n createdAt\n updatedAt\n }\n }\n }\n }\n id\n }\n}\n\nfragment TrustCenterAuditsCardFragment on Audit {\n id\n name\n framework {\n name\n id\n }\n validFrom\n validUntil\n state\n trustCenterVisibility\n createdAt\n}\n\nfragment TrustCenterDocumentsCardFragment on Document {\n id\n title\n createdAt\n documentType\n trustCenterVisibility\n versions(first: 1) {\n edges {\n node {\n id\n status\n }\n }\n }\n}\n\nfragment TrustCenterFilesCardFragment on TrustCenterFile {\n id\n name\n category\n fileUrl\n trustCenterVisibility\n createdAt\n updatedAt\n}\n\nfragment TrustCenterVendorsCardFragment on Vendor {\n id\n name\n category\n description\n showOnTrustCenter\n createdAt\n}\n" + "text": "query TrustCenterGraphQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n id\n name\n canCreateTrustCenterFile: permission(action: \"core:trust-center-file:create\")\n customDomain {\n id\n domain\n }\n trustCenter {\n id\n active\n ndaFileName\n ndaFileUrl\n createdAt\n updatedAt\n canUpdate: permission(action: \"core:trust-center:update\")\n canGetNDA: permission(action: \"core:trust-center:get-nda\")\n canUploadNDA: permission(action: \"core:trust-center:upload-nda\")\n canDeleteNDA: permission(action: \"core:trust-center:delete-nda\")\n references(first: 100, orderBy: {field: CREATED_AT, direction: DESC}) {\n edges {\n node {\n id\n name\n description\n websiteUrl\n logoUrl\n createdAt\n updatedAt\n }\n }\n }\n }\n documents(first: 100) {\n edges {\n node {\n id\n ...TrustCenterDocumentsCardFragment\n }\n }\n }\n audits(first: 100) {\n edges {\n node {\n id\n ...TrustCenterAuditsCardFragment\n }\n }\n }\n vendors(first: 100) {\n edges {\n node {\n id\n ...TrustCenterVendorsCardFragment\n }\n }\n }\n trustCenterFiles(first: 100) {\n edges {\n node {\n id\n ...TrustCenterFilesCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n slackConnections(first: 100) {\n edges {\n node {\n id\n channel\n channelId\n createdAt\n updatedAt\n }\n }\n }\n }\n id\n }\n}\n\nfragment TrustCenterAuditsCardFragment on Audit {\n id\n name\n framework {\n name\n id\n }\n validFrom\n validUntil\n state\n trustCenterVisibility\n createdAt\n}\n\nfragment TrustCenterDocumentsCardFragment on Document {\n id\n title\n createdAt\n documentType\n trustCenterVisibility\n versions(first: 1) {\n edges {\n node {\n id\n status\n }\n }\n }\n}\n\nfragment TrustCenterFilesCardFragment on TrustCenterFile {\n id\n name\n category\n fileUrl\n trustCenterVisibility\n createdAt\n updatedAt\n canUpdate: permission(action: \"core:trust-center-file:update\")\n canDelete: permission(action: \"core:trust-center-file:delete\")\n}\n\nfragment TrustCenterVendorsCardFragment on Vendor {\n id\n name\n category\n description\n showOnTrustCenter\n createdAt\n}\n" } }; })(); -(node as any).hash = "8c59eb08a0ec74662a01a3b8bb8ab56f"; +(node as any).hash = "2c169dd5176d4dedd98ff82210335a86"; export default node; diff --git a/apps/console/src/components/trustCenter/TrustCenterAuditsCard.tsx b/apps/console/src/components/trustCenter/TrustCenterAuditsCard.tsx index d626c38b4..f9b418d0b 100644 --- a/apps/console/src/components/trustCenter/TrustCenterAuditsCard.tsx +++ b/apps/console/src/components/trustCenter/TrustCenterAuditsCard.tsx @@ -14,7 +14,7 @@ import { } from "@probo/ui"; import { useTranslate } from "@probo/i18n"; import { useFragment } from "react-relay"; -import { useMemo, useState, useCallback, useEffect, use } from "react"; +import { useMemo, useState, useCallback, useEffect } from "react"; import { sprintf, getAuditStateVariant, @@ -24,7 +24,6 @@ import { } from "@probo/helpers"; import { useOrganizationId } from "/hooks/useOrganizationId"; import type { TrustCenterAuditsCardFragment$key } from "/__generated__/core/TrustCenterAuditsCardFragment.graphql"; -import { PermissionsContext } from "/providers/PermissionsContext"; const trustCenterAuditFragment = graphql` fragment TrustCenterAuditsCardFragment on Audit { @@ -55,6 +54,7 @@ type Props = { params: Params; disabled?: boolean; onChangeVisibility: Mutation; + canUpdate: boolean; }; export function TrustCenterAuditsCard(props: Props) { @@ -104,6 +104,7 @@ export function TrustCenterAuditsCard(props: Props) { @@ -131,16 +132,13 @@ function AuditRow(props: { trustCenterVisibility: "NONE" | "PRIVATE" | "PUBLIC", ) => void; disabled?: boolean; + canUpdate: boolean; }) { - const { auditFragmentRef, onChangeVisibility, disabled } = props; + const { auditFragmentRef, onChangeVisibility, disabled, canUpdate } = props; const audit = useFragment(trustCenterAuditFragment, auditFragmentRef); const organizationId = useOrganizationId(); const { __ } = useTranslate(); const [optimisticValue, setOptimisticValue] = useState(null); - const { isAuthorized } = use(PermissionsContext); - const canUpdate = organizationId - ? isAuthorized("TrustCenter", "updateTrustCenter") - : false; const handleValueChange = useCallback( (value: string) => { diff --git a/apps/console/src/components/trustCenter/TrustCenterDocumentsCard.tsx b/apps/console/src/components/trustCenter/TrustCenterDocumentsCard.tsx index 8f21e0e33..e29c38617 100644 --- a/apps/console/src/components/trustCenter/TrustCenterDocumentsCard.tsx +++ b/apps/console/src/components/trustCenter/TrustCenterDocumentsCard.tsx @@ -17,10 +17,9 @@ import { import { useTranslate } from "@probo/i18n"; import type { TrustCenterDocumentsCardFragment$key } from "/__generated__/core/TrustCenterDocumentsCardFragment.graphql"; import { useFragment } from "react-relay"; -import { useMemo, useState, useCallback, useEffect, use } from "react"; +import { useMemo, useState, useCallback, useEffect } from "react"; import { sprintf, getTrustCenterVisibilityOptions } from "@probo/helpers"; import { useOrganizationId } from "/hooks/useOrganizationId"; -import { PermissionsContext } from "/providers/PermissionsContext"; const trustCenterDocumentFragment = graphql` fragment TrustCenterDocumentsCardFragment on Document { @@ -54,6 +53,7 @@ type Props = { params: Params; disabled?: boolean; onChangeVisibility: Mutation; + canUpdate: boolean; }; export function TrustCenterDocumentsCard(props: Props) { @@ -104,6 +104,7 @@ export function TrustCenterDocumentsCard(props: Props) { documentFragmentRef={document} onChangeVisibility={onChangeVisibility} disabled={props.disabled} + canUpdate={props.canUpdate} /> ))} @@ -129,8 +130,10 @@ function DocumentRow(props: { trustCenterVisibility: "NONE" | "PRIVATE" | "PUBLIC", ) => void; disabled?: boolean; + canUpdate: boolean; }) { - const { documentFragmentRef, onChangeVisibility, disabled } = props; + const { documentFragmentRef, onChangeVisibility, disabled, canUpdate } = + props; const document = useFragment( trustCenterDocumentFragment, documentFragmentRef, @@ -138,8 +141,6 @@ function DocumentRow(props: { const organizationId = useOrganizationId(); const { __ } = useTranslate(); const [optimisticValue, setOptimisticValue] = useState(null); - const { isAuthorized } = use(PermissionsContext); - const canUpdate = isAuthorized("TrustCenter", "updateTrustCenter"); const handleValueChange = useCallback( (value: string) => { diff --git a/apps/console/src/components/trustCenter/TrustCenterFilesCard.tsx b/apps/console/src/components/trustCenter/TrustCenterFilesCard.tsx index 75bad7426..51679cee6 100644 --- a/apps/console/src/components/trustCenter/TrustCenterFilesCard.tsx +++ b/apps/console/src/components/trustCenter/TrustCenterFilesCard.tsx @@ -21,10 +21,9 @@ import type { TrustCenterFilesCardFragment$data, } from "/__generated__/core/TrustCenterFilesCardFragment.graphql"; import { useFragment } from "react-relay"; -import { useMemo, useState, useCallback, useEffect, use } from "react"; +import { useMemo, useState, useCallback, useEffect } from "react"; import { sprintf, getTrustCenterVisibilityOptions } from "@probo/helpers"; import { formatDate } from "@probo/helpers"; -import { PermissionsContext } from "/providers/PermissionsContext"; const trustCenterFileFragment = graphql` fragment TrustCenterFilesCardFragment on TrustCenterFile { @@ -35,6 +34,8 @@ const trustCenterFileFragment = graphql` trustCenterVisibility createdAt updatedAt + canUpdate: permission(action: "core:trust-center-file:update") + canDelete: permission(action: "core:trust-center-file:delete") } `; @@ -54,6 +55,7 @@ type Props = { onChangeVisibility: Mutation; onEdit: (file: { id: string; name: string; category: string }) => void; onDelete: (id: string) => void; + canUpdate: boolean; }; export function TrustCenterFilesCard(props: Props) { @@ -107,6 +109,7 @@ export function TrustCenterFilesCard(props: Props) { onEdit={props.onEdit} onDelete={props.onDelete} disabled={props.disabled} + canUpdate={props.canUpdate} /> ))} @@ -134,6 +137,7 @@ function FileRowWrapper(props: { onEdit: (file: { id: string; name: string; category: string }) => void; onDelete: (id: string) => void; disabled?: boolean; + canUpdate: boolean; }) { const file = useFragment(trustCenterFileFragment, props.fileFragmentRef); return ( @@ -143,6 +147,7 @@ function FileRowWrapper(props: { onEdit={props.onEdit} onDelete={props.onDelete} disabled={props.disabled} + canUpdate={props.canUpdate} /> ); } @@ -156,12 +161,12 @@ function FileRow(props: { onEdit: (file: { id: string; name: string; category: string }) => void; onDelete: (id: string) => void; disabled?: boolean; + canUpdate: boolean; }) { - const { file, onChangeVisibility, onEdit, onDelete, disabled } = props; + const { file, onChangeVisibility, onEdit, onDelete, disabled, canUpdate } = + props; const { __ } = useTranslate(); const [optimisticValue, setOptimisticValue] = useState(null); - const { isAuthorized } = use(PermissionsContext); - const canUpdate = isAuthorized("TrustCenter", "updateTrustCenter"); const handleValueChange = useCallback( (value: string) => { @@ -217,7 +222,7 @@ function FileRow(props: { } title={__("Download")} /> - {isAuthorized("TrustCenterFile", "updateTrustCenterFile") && ( + {file.canUpdate && ( - {canUpdateTrustCenter && ( +
+ {organization.trustCenter?.canDeleteNDA && ( +
- - ) : ( - <> - {canUpdateTrustCenter ? ( - - ) : ( -

- {__("No NDA file uploaded")} -

- )} - - )} - - - + ) : ( + <> + {canUpdateTrustCenter ? ( + + ) : ( +

+ {__("No NDA file uploaded")} +

+ )} + + )} + + + + )}

{__("Integrations")}

diff --git a/pkg/server/api/connect/v1/v1_resolver.go b/pkg/server/api/connect/v1/v1_resolver.go index fa03aa1e8..d9ccf865f 100644 --- a/pkg/server/api/connect/v1/v1_resolver.go +++ b/pkg/server/api/connect/v1/v1_resolver.go @@ -1409,15 +1409,3 @@ type sAMLConfigurationResolver struct{ *Resolver } type sAMLConfigurationConnectionResolver struct{ *Resolver } type sessionResolver struct{ *Resolver } type sessionConnectionResolver struct{ *Resolver } - -// !!! WARNING !!! -// The code below was going to be deleted when updating resolvers. It has been copied here so you have -// one last chance to move it out of harms way if you want. There are two reasons this happens: -// - When renaming or deleting a resolver the old code will be put in here. You can safely delete -// it when you're done. -// - You have helper methods in this file. Move them out to keep these resolver files clean. -/* - func (r *membershipResolver) Permissions(ctx context.Context, obj *types.Membership) ([]*types.Permission, error) { - panic("not implemented") -} -*/ diff --git a/pkg/server/api/console/v1/schema.graphql b/pkg/server/api/console/v1/schema.graphql index 5670e033f..4ccd5a799 100644 --- a/pkg/server/api/console/v1/schema.graphql +++ b/pkg/server/api/console/v1/schema.graphql @@ -2543,7 +2543,7 @@ type TrustCenterReferenceEdge { node: TrustCenterReference! } -type TrustCenterFile { +type TrustCenterFile implements Node { id: ID! name: String! category: String! @@ -2552,6 +2552,8 @@ type TrustCenterFile { createdAt: Datetime! updatedAt: Datetime! organization: Organization! @goField(forceResolver: true) + + permission(action: String!): Boolean! @goField(forceResolver: true) } type TrustCenterFileConnection diff --git a/pkg/server/api/console/v1/schema/schema.go b/pkg/server/api/console/v1/schema/schema.go index 4820a91ad..4ae2e3743 100644 --- a/pkg/server/api/console/v1/schema/schema.go +++ b/pkg/server/api/console/v1/schema/schema.go @@ -1590,6 +1590,7 @@ type ComplexityRoot struct { ID func(childComplexity int) int Name func(childComplexity int) int Organization func(childComplexity int) int + Permission func(childComplexity int, action string) int TrustCenterVisibility func(childComplexity int) int UpdatedAt func(childComplexity int) int } @@ -2394,6 +2395,7 @@ type TrustCenterFileResolver interface { FileURL(ctx context.Context, obj *types.TrustCenterFile) (string, error) Organization(ctx context.Context, obj *types.TrustCenterFile) (*types.Organization, error) + Permission(ctx context.Context, obj *types.TrustCenterFile, action string) (bool, error) } type TrustCenterFileConnectionResolver interface { TotalCount(ctx context.Context, obj *types.TrustCenterFileConnection) (int, error) @@ -8896,6 +8898,17 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin } return e.complexity.TrustCenterFile.Organization(childComplexity), true + case "TrustCenterFile.permission": + if e.complexity.TrustCenterFile.Permission == nil { + break + } + + args, err := ec.field_TrustCenterFile_permission_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.TrustCenterFile.Permission(childComplexity, args["action"].(string)), true case "TrustCenterFile.trustCenterVisibility": if e.complexity.TrustCenterFile.TrustCenterVisibility == nil { break @@ -12872,7 +12885,7 @@ type TrustCenterReferenceEdge { node: TrustCenterReference! } -type TrustCenterFile { +type TrustCenterFile implements Node { id: ID! name: String! category: String! @@ -12881,6 +12894,8 @@ type TrustCenterFile { createdAt: Datetime! updatedAt: Datetime! organization: Organization! @goField(forceResolver: true) + + permission(action: String!): Boolean! @goField(forceResolver: true) } type TrustCenterFileConnection @@ -19036,6 +19051,17 @@ func (ec *executionContext) field_TrustCenterAccess_permission_args(ctx context. return args, nil } +func (ec *executionContext) field_TrustCenterFile_permission_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "action", ec.unmarshalNString2string) + if err != nil { + return nil, err + } + args["action"] = arg0 + return args, nil +} + func (ec *executionContext) field_TrustCenterReference_permission_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -31802,6 +31828,8 @@ func (ec *executionContext) fieldContext_GetTrustCenterFilePayload_trustCenterFi return ec.fieldContext_TrustCenterFile_updatedAt(ctx, field) case "organization": return ec.fieldContext_TrustCenterFile_organization(ctx, field) + case "permission": + return ec.fieldContext_TrustCenterFile_permission(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type TrustCenterFile", field.Name) }, @@ -51785,6 +51813,8 @@ func (ec *executionContext) fieldContext_TrustCenterDocumentAccess_trustCenterFi return ec.fieldContext_TrustCenterFile_updatedAt(ctx, field) case "organization": return ec.fieldContext_TrustCenterFile_organization(ctx, field) + case "permission": + return ec.fieldContext_TrustCenterFile_permission(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type TrustCenterFile", field.Name) }, @@ -52353,6 +52383,47 @@ func (ec *executionContext) fieldContext_TrustCenterFile_organization(_ context. return fc, nil } +func (ec *executionContext) _TrustCenterFile_permission(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenterFile) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_TrustCenterFile_permission, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.resolvers.TrustCenterFile().Permission(ctx, obj, fc.Args["action"].(string)) + }, + nil, + ec.marshalNBoolean2bool, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_TrustCenterFile_permission(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TrustCenterFile", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_TrustCenterFile_permission_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _TrustCenterFileConnection_totalCount(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenterFileConnection) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -52525,6 +52596,8 @@ func (ec *executionContext) fieldContext_TrustCenterFileEdge_node(_ context.Cont return ec.fieldContext_TrustCenterFile_updatedAt(ctx, field) case "organization": return ec.fieldContext_TrustCenterFile_organization(ctx, field) + case "permission": + return ec.fieldContext_TrustCenterFile_permission(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type TrustCenterFile", field.Name) }, @@ -54290,6 +54363,8 @@ func (ec *executionContext) fieldContext_UpdateTrustCenterFilePayload_trustCente return ec.fieldContext_TrustCenterFile_updatedAt(ctx, field) case "organization": return ec.fieldContext_TrustCenterFile_organization(ctx, field) + case "permission": + return ec.fieldContext_TrustCenterFile_permission(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type TrustCenterFile", field.Name) }, @@ -69052,6 +69127,13 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj return graphql.Null } return ec._TrustCenterReference(ctx, sel, obj) + case types.TrustCenterFile: + return ec._TrustCenterFile(ctx, sel, &obj) + case *types.TrustCenterFile: + if obj == nil { + return graphql.Null + } + return ec._TrustCenterFile(ctx, sel, obj) case types.TrustCenterAccess: return ec._TrustCenterAccess(ctx, sel, &obj) case *types.TrustCenterAccess: @@ -85535,7 +85617,7 @@ func (ec *executionContext) _TrustCenterEdge(ctx context.Context, sel ast.Select return out } -var trustCenterFileImplementors = []string{"TrustCenterFile"} +var trustCenterFileImplementors = []string{"TrustCenterFile", "Node"} func (ec *executionContext) _TrustCenterFile(ctx context.Context, sel ast.SelectionSet, obj *types.TrustCenterFile) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, trustCenterFileImplementors) @@ -85647,6 +85729,42 @@ func (ec *executionContext) _TrustCenterFile(ctx context.Context, sel ast.Select continue } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "permission": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._TrustCenterFile_permission(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) default: panic("unknown field " + strconv.Quote(field.Name)) diff --git a/pkg/server/api/console/v1/types/types.go b/pkg/server/api/console/v1/types/types.go index 2b918746d..ca753f4f7 100644 --- a/pkg/server/api/console/v1/types/types.go +++ b/pkg/server/api/console/v1/types/types.go @@ -1952,8 +1952,12 @@ type TrustCenterFile struct { CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` Organization *Organization `json:"organization"` + Permission bool `json:"permission"` } +func (TrustCenterFile) IsNode() {} +func (this TrustCenterFile) GetID() gid.GID { return this.ID } + type TrustCenterFileEdge struct { Cursor page.CursorKey `json:"cursor"` Node *TrustCenterFile `json:"node"` diff --git a/pkg/server/api/console/v1/v1_resolver.go b/pkg/server/api/console/v1/v1_resolver.go index e81dd9b75..2245afa07 100644 --- a/pkg/server/api/console/v1/v1_resolver.go +++ b/pkg/server/api/console/v1/v1_resolver.go @@ -6917,7 +6917,18 @@ func (r *transferImpactAssessmentConnectionResolver) TotalCount(ctx context.Cont // NdaFileURL is the resolver for the ndaFileUrl field. func (r *trustCenterResolver) NdaFileURL(ctx context.Context, obj *types.TrustCenter) (*string, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionTrustCenterGetNda) + if err := r.iam.Authorizer.Authorize(ctx, iam.AuthorizeParams{ + Principal: connect_v1.IdentityFromContext(ctx).ID, + Resource: obj.ID, + Action: "core:trust-center:get-nda-file-url", + }); err != nil { + var errInsufficientPermissions *iam.ErrInsufficientPermissions + if errors.As(err, &errInsufficientPermissions) { + return nil, nil + } + + panic(fmt.Errorf("cannot authorize: %w", err)) + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -7179,6 +7190,11 @@ func (r *trustCenterFileResolver) Organization(ctx context.Context, obj *types.T return types.NewOrganization(organization), nil } +// Permission is the resolver for the permission field. +func (r *trustCenterFileResolver) Permission(ctx context.Context, obj *types.TrustCenterFile, action string) (bool, error) { + return r.Resolver.Permission(ctx, obj, action) +} + // TotalCount is the resolver for the totalCount field. func (r *trustCenterFileConnectionResolver) TotalCount(ctx context.Context, obj *types.TrustCenterFileConnection) (int, error) { r.MustAuthorize(ctx, obj.ParentID, probo.ActionTrustCenterFileList)