Fix saml config + org form permissions handling

Signed-off-by: Émile Ré <nemile.re@gmail.com>
This commit is contained in:
Émile Ré
2025-12-31 15:44:29 +01:00
committed by Bryan Frimin
parent b24ef0c3aa
commit 7e22893fd2
10 changed files with 199 additions and 65 deletions

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<7b9dd98afd5bdc994e7d2e422dec2cf2>> * @generated SignedSource<<125407dec78c8db89ee91aa12a097cf0>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -16,6 +16,7 @@ export type GeneralSettingsPageQuery$variables = {
export type GeneralSettingsPageQuery$data = { export type GeneralSettingsPageQuery$data = {
readonly organization: { readonly organization: {
readonly __typename: "Organization"; readonly __typename: "Organization";
readonly canDelete: boolean;
readonly id: string; readonly id: string;
readonly name: string; readonly name: string;
readonly " $fragmentSpreads": FragmentRefs<"OrganizationFormFragment">; readonly " $fragmentSpreads": FragmentRefs<"OrganizationFormFragment">;
@@ -65,6 +66,19 @@ v4 = {
"kind": "ScalarField", "kind": "ScalarField",
"name": "name", "name": "name",
"storageKey": null "storageKey": null
},
v5 = {
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "iam:organization:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"iam:organization:delete\")"
}; };
return { return {
"fragment": { "fragment": {
@@ -93,6 +107,7 @@ return {
"field": (v4/*: any*/), "field": (v4/*: any*/),
"action": "THROW" "action": "THROW"
}, },
(v5/*: any*/),
{ {
"args": null, "args": null,
"kind": "FragmentSpread", "kind": "FragmentSpread",
@@ -131,6 +146,7 @@ return {
"kind": "InlineFragment", "kind": "InlineFragment",
"selections": [ "selections": [
(v4/*: any*/), (v4/*: any*/),
(v5/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -172,6 +188,19 @@ return {
"kind": "ScalarField", "kind": "ScalarField",
"name": "headquarterAddress", "name": "headquarterAddress",
"storageKey": null "storageKey": null
},
{
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "iam:organization:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"iam:organization:update\")"
} }
], ],
"type": "Organization", "type": "Organization",
@@ -183,16 +212,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "11f654f40301ba539b6d78ead3029308", "cacheID": "0d8f14524ef2e72d138e5bb5a42a8f8d",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "GeneralSettingsPageQuery", "name": "GeneralSettingsPageQuery",
"operationKind": "query", "operationKind": "query",
"text": "query GeneralSettingsPageQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n id\n name\n ...OrganizationFormFragment\n }\n id\n }\n}\n\nfragment OrganizationFormFragment on Organization {\n id\n name\n logoUrl\n horizontalLogoUrl\n description\n websiteUrl\n email\n headquarterAddress\n}\n" "text": "query GeneralSettingsPageQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n id\n name\n canDelete: permission(action: \"iam:organization:delete\")\n ...OrganizationFormFragment\n }\n id\n }\n}\n\nfragment OrganizationFormFragment on Organization {\n id\n name\n logoUrl\n horizontalLogoUrl\n description\n websiteUrl\n email\n headquarterAddress\n canUpdate: permission(action: \"iam:organization:update\")\n}\n"
} }
}; };
})(); })();
(node as any).hash = "a83e24379e0772bbaf19bad92d60c6d4"; (node as any).hash = "307473752dd5dc91caaa7536b7b3e69a";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<84f3f3da89ad2bdfecd79b479bf74814>> * @generated SignedSource<<4516a7a0c95bb6634bbe7d1b097cc5de>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -26,6 +26,7 @@ export type InviteUserDialogMutation$data = {
readonly invitationEdge: { readonly invitationEdge: {
readonly node: { readonly node: {
readonly acceptedAt: any | null | undefined; readonly acceptedAt: any | null | undefined;
readonly canDelete: boolean;
readonly createdAt: any; readonly createdAt: any;
readonly email: any; readonly email: any;
readonly expiresAt: any; readonly expiresAt: any;
@@ -123,6 +124,19 @@ v3 = {
"kind": "ScalarField", "kind": "ScalarField",
"name": "createdAt", "name": "createdAt",
"storageKey": null "storageKey": null
},
{
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "iam:invitation:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"iam:invitation:delete\")"
} }
], ],
"storageKey": null "storageKey": null
@@ -196,16 +210,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "43ea730d742b7d259b50b50d3684147c", "cacheID": "8d9e447c08739bef2460474225fb77bf",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "InviteUserDialogMutation", "name": "InviteUserDialogMutation",
"operationKind": "mutation", "operationKind": "mutation",
"text": "mutation InviteUserDialogMutation(\n $input: InviteMemberInput!\n) {\n inviteMember(input: $input) {\n invitationEdge {\n node {\n id\n email\n fullName\n role\n expiresAt\n acceptedAt\n createdAt\n }\n }\n }\n}\n" "text": "mutation InviteUserDialogMutation(\n $input: InviteMemberInput!\n) {\n inviteMember(input: $input) {\n invitationEdge {\n node {\n id\n email\n fullName\n role\n expiresAt\n acceptedAt\n createdAt\n canDelete: permission(action: \"iam:invitation:delete\")\n }\n }\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "b45737075b750b79b3a90748cb2565f3"; (node as any).hash = "dc2446f51b33dbab3a348e1250a25049";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<8deb33fbc8305caa3d3de954cf555c79>> * @generated SignedSource<<a51e172adf9985b58d315d510a665377>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -11,6 +11,7 @@
import { ReaderFragment } from 'relay-runtime'; import { ReaderFragment } from 'relay-runtime';
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type OrganizationFormFragment$data = { export type OrganizationFormFragment$data = {
readonly canUpdate: boolean;
readonly description: string | null | undefined; readonly description: string | null | undefined;
readonly email: string | null | undefined; readonly email: string | null | undefined;
readonly headquarterAddress: string | null | undefined; readonly headquarterAddress: string | null | undefined;
@@ -91,12 +92,25 @@ const node: ReaderFragment = {
"kind": "ScalarField", "kind": "ScalarField",
"name": "headquarterAddress", "name": "headquarterAddress",
"storageKey": null "storageKey": null
},
{
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "iam:organization:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"iam:organization:update\")"
} }
], ],
"type": "Organization", "type": "Organization",
"abstractKey": null "abstractKey": null
}; };
(node as any).hash = "0894093a550e5ba033a33b255b1bf2c7"; (node as any).hash = "d1a518b08167fdd53901c4b842fa2e9c";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<12fade1fd1f7f3ae53595970b6c2c47e>> * @generated SignedSource<<6b22aeaed6a8da4374bb98a36e236cd2>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -15,6 +15,8 @@ export type SAMLConfigurationListFragment$data = {
readonly samlConfigurations: { readonly samlConfigurations: {
readonly edges: ReadonlyArray<{ readonly edges: ReadonlyArray<{
readonly node: { readonly node: {
readonly canDelete: boolean;
readonly canUpdate: boolean;
readonly domainVerificationToken: string | null | undefined; readonly domainVerificationToken: string | null | undefined;
readonly domainVerifiedAt: any | null | undefined; readonly domainVerifiedAt: any | null | undefined;
readonly emailDomain: string; readonly emailDomain: string;
@@ -118,6 +120,32 @@ const node: ReaderFragment = {
"name": "testLoginUrl", "name": "testLoginUrl",
"storageKey": null "storageKey": null
}, },
{
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "iam:saml-configuration:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"iam:saml-configuration:update\")"
},
{
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "iam:saml-configuration:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"iam:saml-configuration:delete\")"
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -175,6 +203,6 @@ const node: ReaderFragment = {
"abstractKey": null "abstractKey": null
}; };
(node as any).hash = "79203ccae6f8e3a1967b463f0f3f3c76"; (node as any).hash = "3adfb13b2a908c93602b219ef1d0cf50";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<57eb2489b4c62cb4b1df1a61bc135313>> * @generated SignedSource<<b786c501cc6f8f4da479b138e36888d2>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -15,7 +15,13 @@ export type SAMLSettingsPageQuery$variables = {
}; };
export type SAMLSettingsPageQuery$data = { export type SAMLSettingsPageQuery$data = {
readonly organization: { readonly organization: {
readonly __typename: "Organization";
readonly canCreateSAMLConfiguration: boolean;
readonly " $fragmentSpreads": FragmentRefs<"SAMLConfigurationListFragment">; readonly " $fragmentSpreads": FragmentRefs<"SAMLConfigurationListFragment">;
} | {
// This will never be '%other', but we need some
// value in case none of the concrete values match.
readonly __typename: "%other";
}; };
}; };
export type SAMLSettingsPageQuery = { export type SAMLSettingsPageQuery = {
@@ -45,14 +51,27 @@ v2 = {
"name": "__typename", "name": "__typename",
"storageKey": null "storageKey": null
}, },
v3 = [ v3 = {
"alias": "canCreateSAMLConfiguration",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "iam:saml-configuration:create"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"iam:saml-configuration:create\")"
},
v4 = [
{ {
"kind": "Literal", "kind": "Literal",
"name": "first", "name": "first",
"value": 1000 "value": 1000
} }
], ],
v4 = { v5 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
@@ -76,10 +95,19 @@ return {
"name": "node", "name": "node",
"plural": false, "plural": false,
"selections": [ "selections": [
(v2/*: any*/),
{ {
"args": null, "kind": "InlineFragment",
"kind": "FragmentSpread", "selections": [
"name": "SAMLConfigurationListFragment" (v3/*: any*/),
{
"args": null,
"kind": "FragmentSpread",
"name": "SAMLConfigurationListFragment"
}
],
"type": "Organization",
"abstractKey": null
} }
], ],
"storageKey": null "storageKey": null
@@ -108,9 +136,10 @@ return {
{ {
"kind": "InlineFragment", "kind": "InlineFragment",
"selections": [ "selections": [
(v3/*: any*/),
{ {
"alias": null, "alias": null,
"args": (v3/*: any*/), "args": (v4/*: any*/),
"concreteType": "SAMLConfigurationConnection", "concreteType": "SAMLConfigurationConnection",
"kind": "LinkedField", "kind": "LinkedField",
"name": "samlConfigurations", "name": "samlConfigurations",
@@ -132,7 +161,7 @@ return {
"name": "node", "name": "node",
"plural": false, "plural": false,
"selections": [ "selections": [
(v4/*: any*/), (v5/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -168,6 +197,32 @@ return {
"name": "testLoginUrl", "name": "testLoginUrl",
"storageKey": null "storageKey": null
}, },
{
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "iam:saml-configuration:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"iam:saml-configuration:update\")"
},
{
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "iam:saml-configuration:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"iam:saml-configuration:delete\")"
},
(v2/*: any*/) (v2/*: any*/)
], ],
"storageKey": null "storageKey": null
@@ -212,7 +267,7 @@ return {
}, },
{ {
"alias": null, "alias": null,
"args": (v3/*: any*/), "args": (v4/*: any*/),
"filters": null, "filters": null,
"handle": "connection", "handle": "connection",
"key": "SAMLConfigurationListFragment_samlConfigurations", "key": "SAMLConfigurationListFragment_samlConfigurations",
@@ -223,23 +278,23 @@ return {
"type": "Organization", "type": "Organization",
"abstractKey": null "abstractKey": null
}, },
(v4/*: any*/) (v5/*: any*/)
], ],
"storageKey": null "storageKey": null
} }
] ]
}, },
"params": { "params": {
"cacheID": "45740d8e7e6fba1ec2576fd62487e41e", "cacheID": "1a2bfe52dd42459b83e7f99e9b790218",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "SAMLSettingsPageQuery", "name": "SAMLSettingsPageQuery",
"operationKind": "query", "operationKind": "query",
"text": "query SAMLSettingsPageQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ...SAMLConfigurationListFragment\n id\n }\n}\n\nfragment SAMLConfigurationListFragment on Organization {\n samlConfigurations(first: 1000) {\n edges {\n node {\n id\n emailDomain\n enforcementPolicy\n domainVerificationToken\n domainVerifiedAt\n testLoginUrl\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n" "text": "query SAMLSettingsPageQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n canCreateSAMLConfiguration: permission(action: \"iam:saml-configuration:create\")\n ...SAMLConfigurationListFragment\n }\n id\n }\n}\n\nfragment SAMLConfigurationListFragment on Organization {\n samlConfigurations(first: 1000) {\n edges {\n node {\n id\n emailDomain\n enforcementPolicy\n domainVerificationToken\n domainVerifiedAt\n testLoginUrl\n canUpdate: permission(action: \"iam:saml-configuration:update\")\n canDelete: permission(action: \"iam:saml-configuration:delete\")\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "d2d6ef2a90f81a75df7ab0dd83ef52cf"; (node as any).hash = "d0fd8fe9afb6ff650cce48c89eb83c46";
export default node; export default node;

View File

@@ -1,7 +1,5 @@
import { useTranslate } from "@probo/i18n"; import { useTranslate } from "@probo/i18n";
import { Button, Card, IconTrashCan } from "@probo/ui"; import { Button, Card, IconTrashCan } from "@probo/ui";
import { use } from "react";
import { PermissionsContext } from "/providers/PermissionsContext";
import { useNavigate } from "react-router"; import { useNavigate } from "react-router";
import { useMutationWithToasts } from "/hooks/useMutationWithToasts"; import { useMutationWithToasts } from "/hooks/useMutationWithToasts";
import { graphql } from "relay-runtime"; import { graphql } from "relay-runtime";
@@ -18,6 +16,7 @@ export const generalSettingsPageQuery = graphql`
... on Organization { ... on Organization {
id id
name @required(action: THROW) name @required(action: THROW)
canDelete: permission(action: "iam:organization:delete")
...OrganizationFormFragment ...OrganizationFormFragment
} }
} }
@@ -42,9 +41,6 @@ export function GeneralSettingsPage(props: {
const { __ } = useTranslate(); const { __ } = useTranslate();
const navigate = useNavigate(); const navigate = useNavigate();
const { isAuthorized } = use(PermissionsContext);
const canDelete = isAuthorized("Organization", "deleteOrganization");
const { organization } = usePreloadedQuery<GeneralSettingsPageQuery>( const { organization } = usePreloadedQuery<GeneralSettingsPageQuery>(
generalSettingsPageQuery, generalSettingsPageQuery,
queryRef, queryRef,
@@ -80,7 +76,7 @@ export function GeneralSettingsPage(props: {
<div className="space-y-6"> <div className="space-y-6">
<OrganizationForm fKey={organization} /> <OrganizationForm fKey={organization} />
{canDelete && ( {organization.canDelete && (
<div className="space-y-4 mt-12"> <div className="space-y-4 mt-12">
<h2 className="text-base font-medium text-red-600"> <h2 className="text-base font-medium text-red-600">
{__("Danger Zone")} {__("Danger Zone")}

View File

@@ -5,8 +5,7 @@ import {
type PreloadedQuery, type PreloadedQuery,
} from "react-relay"; } from "react-relay";
import type { SAMLSettingsPageQuery } from "/__generated__/iam/SAMLSettingsPageQuery.graphql"; import type { SAMLSettingsPageQuery } from "/__generated__/iam/SAMLSettingsPageQuery.graphql";
import { Suspense, use, useState } from "react"; import { Suspense, useState } from "react";
import { PermissionsContext } from "/providers/PermissionsContext";
import { Breadcrumb, Button, Dialog, useDialogRef } from "@probo/ui"; import { Breadcrumb, Button, Dialog, useDialogRef } from "@probo/ui";
import { useTranslate } from "@probo/i18n"; import { useTranslate } from "@probo/i18n";
import { SAMLConfigurationList } from "./_components/SAMLConfigurationList"; import { SAMLConfigurationList } from "./_components/SAMLConfigurationList";
@@ -21,7 +20,13 @@ import { SAMLDomainVerifyDialog } from "./_components/SAMLDomainVerifyDialog";
export const samlSettingsPageQuery = graphql` export const samlSettingsPageQuery = graphql`
query SAMLSettingsPageQuery($organizationId: ID!) { query SAMLSettingsPageQuery($organizationId: ID!) {
organization: node(id: $organizationId) @required(action: THROW) { organization: node(id: $organizationId) @required(action: THROW) {
...SAMLConfigurationListFragment __typename
... on Organization {
canCreateSAMLConfiguration: permission(
action: "iam:saml-configuration:create"
)
...SAMLConfigurationListFragment
}
} }
} }
`; `;
@@ -38,9 +43,11 @@ export function SAMLSettingsPage(props: {
useState<string>(); useState<string>();
const { __ } = useTranslate(); const { __ } = useTranslate();
const { isAuthorized } = use(PermissionsContext);
const { organization } = usePreloadedQuery(samlSettingsPageQuery, queryRef); const { organization } = usePreloadedQuery(samlSettingsPageQuery, queryRef);
if (organization.__typename !== "Organization") {
throw new Error("invalid node type");
}
const [formQueryRef, loadFormQuery] = const [formQueryRef, loadFormQuery] =
useQueryLoader<EditSAMLConfigurationFormQuery>(samlConfigurationFormQuery); useQueryLoader<EditSAMLConfigurationFormQuery>(samlConfigurationFormQuery);
@@ -70,7 +77,7 @@ export function SAMLSettingsPage(props: {
<div className="space-y-4"> <div className="space-y-4">
<div className="flex justify-between items-center"> <div className="flex justify-between items-center">
<h2 className="text-base font-medium">{__("SAML Single Sign-On")}</h2> <h2 className="text-base font-medium">{__("SAML Single Sign-On")}</h2>
{isAuthorized("Organization", "createSAMLConfiguration") && ( {organization.canCreateSAMLConfiguration && (
<Button onClick={() => handleOpenFormDialog()}> <Button onClick={() => handleOpenFormDialog()}>
{__("Add Configuration")} {__("Add Configuration")}
</Button> </Button>

View File

@@ -44,6 +44,7 @@ const inviteMutation = graphql`
expiresAt expiresAt
acceptedAt acceptedAt
createdAt createdAt
canDelete: permission(action: "iam:invitation:delete")
} }
} }
} }

View File

@@ -13,8 +13,7 @@ import {
Textarea, Textarea,
useDialogRef, useDialogRef,
} from "@probo/ui"; } from "@probo/ui";
import { use, useState, type ChangeEventHandler } from "react"; import { useState, type ChangeEventHandler } from "react";
import { PermissionsContext } from "/providers/PermissionsContext";
import { useFormWithSchema } from "/hooks/useFormWithSchema"; import { useFormWithSchema } from "/hooks/useFormWithSchema";
import { useMutationWithToasts } from "/hooks/useMutationWithToasts"; import { useMutationWithToasts } from "/hooks/useMutationWithToasts";
import { graphql } from "relay-runtime"; import { graphql } from "relay-runtime";
@@ -33,6 +32,7 @@ const fragment = graphql`
websiteUrl websiteUrl
email email
headquarterAddress headquarterAddress
canUpdate: permission(action: "iam:organization:update")
} }
`; `;
@@ -83,18 +83,13 @@ export function OrganizationForm(props: {
const { __ } = useTranslate(); const { __ } = useTranslate();
const deleteDialogRef = useDialogRef(); const deleteDialogRef = useDialogRef();
const { isAuthorized } = use(PermissionsContext);
const canUpdate = isAuthorized("Organization", "updateOrganization");
const [logoPreview, setLogoPreview] = useState<string | null>(null); const [logoPreview, setLogoPreview] = useState<string | null>(null);
const [horizontalLogoPreview, setHorizontalLogoPreview] = useState< const [horizontalLogoPreview, setHorizontalLogoPreview] = useState<
string | null string | null
>(null); >(null);
const organization = useFragment<OrganizationFormFragment$key>( const { canUpdate, ...organization } =
fragment, useFragment<OrganizationFormFragment$key>(fragment, fKey);
fKey,
);
const [updateOrganization, isUpdatingOrganization] = useMutationWithToasts( const [updateOrganization, isUpdatingOrganization] = useMutationWithToasts(
updateOrganizationMutation, updateOrganizationMutation,

View File

@@ -1,6 +1,4 @@
import { useTranslate } from "@probo/i18n"; import { useTranslate } from "@probo/i18n";
import { use } from "react";
import { PermissionsContext } from "/providers/PermissionsContext";
import { import {
Button, Button,
Card, Card,
@@ -37,6 +35,8 @@ const fragment = graphql`
domainVerificationToken domainVerificationToken
domainVerifiedAt domainVerifiedAt
testLoginUrl testLoginUrl
canUpdate: permission(action: "iam:saml-configuration:update")
canDelete: permission(action: "iam:saml-configuration:delete")
} }
} }
} }
@@ -63,7 +63,6 @@ export function SAMLConfigurationList(props: {
const organizationId = useOrganizationId(); const organizationId = useOrganizationId();
const { __ } = useTranslate(); const { __ } = useTranslate();
const { isAuthorized } = use(PermissionsContext);
const confirm = useConfirm(); const confirm = useConfirm();
const [isCopied, copy] = useCopy(); const [isCopied, copy] = useCopy();
@@ -197,10 +196,7 @@ export function SAMLConfigurationList(props: {
<div className="flex gap-2 justify-end"> <div className="flex gap-2 justify-end">
{config.domainVerifiedAt ? ( {config.domainVerifiedAt ? (
<> <>
{isAuthorized( {config.canUpdate && (
"SAMLConfiguration",
"updateSAMLConfiguration",
) && (
<Button <Button
variant="secondary" variant="secondary"
onClick={() => onEdit(config.id)} onClick={() => onEdit(config.id)}
@@ -208,7 +204,7 @@ export function SAMLConfigurationList(props: {
{__("Edit")} {__("Edit")}
</Button> </Button>
)} )}
{isAuthorized("Organization", "deleteOrganization") && ( {config.canDelete && (
<Button <Button
variant="danger" variant="danger"
onClick={() => handleDelete(config)} onClick={() => handleDelete(config)}
@@ -219,18 +215,17 @@ export function SAMLConfigurationList(props: {
</> </>
) : ( ) : (
<> <>
{isAuthorized("Organization", "verifyDomain") && {config.canUpdate && !!config.domainVerificationToken && (
!!config.domainVerificationToken && ( <Button
<Button variant="primary"
variant="primary" onClick={() =>
onClick={() => onVerifyDomain(config.domainVerificationToken!)
onVerifyDomain(config.domainVerificationToken!) }
} >
> {__("Verify Domain")}
{__("Verify Domain")} </Button>
</Button> )}
)} {config.canDelete && (
{isAuthorized("Organization", "deleteOrganization") && (
<Button <Button
variant="danger" variant="danger"
onClick={() => handleDelete(config)} onClick={() => handleDelete(config)}