Replug SAML configurations
Signed-off-by: Émile Ré <nemile.re@gmail.com>
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
import {
|
||||
graphql,
|
||||
usePreloadedQuery,
|
||||
useQueryLoader,
|
||||
type PreloadedQuery,
|
||||
} from "react-relay";
|
||||
import type { SAMLSettingsPageQuery } from "./__generated__/SAMLSettingsPageQuery.graphql";
|
||||
import { Suspense, use, useState } from "react";
|
||||
import { PermissionsContext } from "/providers/PermissionsContext";
|
||||
import { Breadcrumb, Button, Dialog, useDialogRef } from "@probo/ui";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { SAMLConfigurationList } from "./_components/SAMLConfigurationList";
|
||||
import { NewSAMLConfigurationForm } from "./_components/NewSAMLConfigurationForm";
|
||||
import {
|
||||
EditSAMLConfigurationForm,
|
||||
samlConfigurationFormQuery,
|
||||
} from "./_components/EditSAMLConfigurationForm";
|
||||
import type { EditSAMLConfigurationFormQuery } from "./_components/__generated__/EditSAMLConfigurationFormQuery.graphql";
|
||||
import { SAMLDomainVerifyDialog } from "./_components/SAMLDomainVerifyDialog";
|
||||
|
||||
export const samlSettingsPageQuery = graphql`
|
||||
query SAMLSettingsPageQuery($organizationId: ID!) {
|
||||
organization: node(id: $organizationId) @required(action: THROW) {
|
||||
...SAMLConfigurationListFragment
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export function SAMLSettingsPage(props: {
|
||||
queryRef: PreloadedQuery<SAMLSettingsPageQuery>;
|
||||
}) {
|
||||
const { queryRef } = props;
|
||||
|
||||
const formDialogRef = useDialogRef();
|
||||
const domainDialogRef = useDialogRef();
|
||||
const [isEditing, setIsEditing] = useState<boolean>();
|
||||
const [domainVerificationToken, setDomainVerificationToken] =
|
||||
useState<string>();
|
||||
|
||||
const { __ } = useTranslate();
|
||||
const { isAuthorized } = use(PermissionsContext);
|
||||
|
||||
const { organization } = usePreloadedQuery(samlSettingsPageQuery, queryRef);
|
||||
const [formQueryRef, loadFormQuery] =
|
||||
useQueryLoader<EditSAMLConfigurationFormQuery>(samlConfigurationFormQuery);
|
||||
|
||||
const handleOpenFormDialog = (samlConfigurationId?: string) => {
|
||||
setIsEditing(!!samlConfigurationId);
|
||||
if (samlConfigurationId) {
|
||||
loadFormQuery({ samlConfigurationId }, { fetchPolicy: "network-only" });
|
||||
}
|
||||
formDialogRef.current?.open();
|
||||
};
|
||||
const handleCloseFormDialog = () => {
|
||||
setIsEditing(false);
|
||||
formDialogRef.current?.close();
|
||||
};
|
||||
|
||||
const handleOpenVerifyDomainDialog = (domainVerificationToken: string) => {
|
||||
setDomainVerificationToken(domainVerificationToken);
|
||||
domainDialogRef.current?.open();
|
||||
};
|
||||
const handleCloseVerifyDomainDialog = () => {
|
||||
setDomainVerificationToken("");
|
||||
formDialogRef.current?.close();
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between items-center">
|
||||
<h2 className="text-base font-medium">{__("SAML Single Sign-On")}</h2>
|
||||
{isAuthorized("Organization", "createSAMLConfiguration") && (
|
||||
<Button onClick={() => handleOpenFormDialog()}>
|
||||
{__("Add Configuration")}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<SAMLConfigurationList
|
||||
fKey={organization}
|
||||
onNew={handleOpenFormDialog}
|
||||
onEdit={(id: string) => handleOpenFormDialog(id)}
|
||||
onVerifyDomain={handleOpenVerifyDomainDialog}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Dialog
|
||||
ref={formDialogRef}
|
||||
onClose={handleCloseFormDialog}
|
||||
title={<Breadcrumb items={[__("SAML Settings"), __("Configure")]} />}
|
||||
>
|
||||
{isEditing ? (
|
||||
<Suspense>
|
||||
{formQueryRef && (
|
||||
<EditSAMLConfigurationForm
|
||||
queryRef={formQueryRef}
|
||||
onUpdate={handleCloseFormDialog}
|
||||
/>
|
||||
)}
|
||||
</Suspense>
|
||||
) : (
|
||||
<NewSAMLConfigurationForm onCreate={handleCloseFormDialog} />
|
||||
)}
|
||||
</Dialog>
|
||||
|
||||
<Dialog
|
||||
ref={domainDialogRef}
|
||||
onClose={handleCloseVerifyDomainDialog}
|
||||
title={
|
||||
<Breadcrumb items={[__("SAML Settings"), __("Verify Domain")]} />
|
||||
}
|
||||
>
|
||||
{domainVerificationToken && (
|
||||
<SAMLDomainVerifyDialog
|
||||
key={domainVerificationToken}
|
||||
domainVerificationToken={domainVerificationToken}
|
||||
/>
|
||||
)}
|
||||
</Dialog>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { useQueryLoader } from "react-relay";
|
||||
import { SAMLSettingsPage, samlSettingsPageQuery } from "./SAMLSettingsPage";
|
||||
import { useOrganizationId } from "/hooks/useOrganizationId";
|
||||
import { IAMRelayProvider } from "/providers/IAMRelayProvider";
|
||||
import { useEffect } from "react";
|
||||
import type { SAMLSettingsPageQuery } from "./__generated__/SAMLSettingsPageQuery.graphql";
|
||||
|
||||
function SAMLSettingsPageLoader() {
|
||||
const organizationId = useOrganizationId();
|
||||
const [queryRef, loadQuery] = useQueryLoader<SAMLSettingsPageQuery>(
|
||||
samlSettingsPageQuery,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
loadQuery({
|
||||
organizationId,
|
||||
});
|
||||
}, [loadQuery, organizationId]);
|
||||
|
||||
if (!queryRef) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <SAMLSettingsPage queryRef={queryRef} />;
|
||||
}
|
||||
|
||||
export default function () {
|
||||
return (
|
||||
<IAMRelayProvider>
|
||||
<SAMLSettingsPageLoader />
|
||||
</IAMRelayProvider>
|
||||
);
|
||||
}
|
||||
245
apps/console/src/pages/iam/organizations/settings/__generated__/SAMLSettingsPageQuery.graphql.ts
generated
Normal file
245
apps/console/src/pages/iam/organizations/settings/__generated__/SAMLSettingsPageQuery.graphql.ts
generated
Normal file
@@ -0,0 +1,245 @@
|
||||
/**
|
||||
* @generated SignedSource<<57eb2489b4c62cb4b1df1a61bc135313>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type SAMLSettingsPageQuery$variables = {
|
||||
organizationId: string;
|
||||
};
|
||||
export type SAMLSettingsPageQuery$data = {
|
||||
readonly organization: {
|
||||
readonly " $fragmentSpreads": FragmentRefs<"SAMLConfigurationListFragment">;
|
||||
};
|
||||
};
|
||||
export type SAMLSettingsPageQuery = {
|
||||
response: SAMLSettingsPageQuery$data;
|
||||
variables: SAMLSettingsPageQuery$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "organizationId"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "id",
|
||||
"variableName": "organizationId"
|
||||
}
|
||||
],
|
||||
v2 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
},
|
||||
v3 = [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 1000
|
||||
}
|
||||
],
|
||||
v4 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "SAMLSettingsPageQuery",
|
||||
"selections": [
|
||||
{
|
||||
"kind": "RequiredField",
|
||||
"field": {
|
||||
"alias": "organization",
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "SAMLConfigurationListFragment"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
"action": "THROW"
|
||||
}
|
||||
],
|
||||
"type": "Query",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "SAMLSettingsPageQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "organization",
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v3/*: any*/),
|
||||
"concreteType": "SAMLConfigurationConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "samlConfigurations",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "SAMLConfigurationEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "SAMLConfiguration",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v4/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "emailDomain",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "enforcementPolicy",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "domainVerificationToken",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "domainVerifiedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "testLoginUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
(v2/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
"kind": "LinkedField",
|
||||
"name": "pageInfo",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "endCursor",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "hasNextPage",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": "samlConfigurations(first:1000)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v3/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "SAMLConfigurationListFragment_samlConfigurations",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "samlConfigurations"
|
||||
}
|
||||
],
|
||||
"type": "Organization",
|
||||
"abstractKey": null
|
||||
},
|
||||
(v4/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "45740d8e7e6fba1ec2576fd62487e41e",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "SAMLSettingsPageQuery",
|
||||
"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"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "d2d6ef2a90f81a75df7ab0dd83ef52cf";
|
||||
|
||||
export default node;
|
||||
@@ -0,0 +1,111 @@
|
||||
import { usePreloadedQuery, type PreloadedQuery } from "react-relay";
|
||||
import { graphql } from "relay-runtime";
|
||||
import type { EditSAMLConfigurationForm_updateMutation } from "./__generated__/EditSAMLConfigurationForm_updateMutation.graphql";
|
||||
import { useCallback } from "react";
|
||||
import type { EditSAMLConfigurationFormQuery } from "./__generated__/EditSAMLConfigurationFormQuery.graphql";
|
||||
import { useOrganizationId } from "/hooks/useOrganizationId";
|
||||
import {
|
||||
SAMLConfigurationForm,
|
||||
type SAMLConfigurationFormData,
|
||||
} from "./SAMLConfigurationForm";
|
||||
import { useMutationWithToasts } from "/hooks/useMutationWithToasts";
|
||||
|
||||
export const samlConfigurationFormQuery = graphql`
|
||||
query EditSAMLConfigurationFormQuery($samlConfigurationId: ID!) {
|
||||
samlConfiguration: node(id: $samlConfigurationId) @required(action: THROW) {
|
||||
__typename
|
||||
... on SAMLConfiguration {
|
||||
id
|
||||
emailDomain
|
||||
enforcementPolicy
|
||||
domainVerificationToken
|
||||
domainVerifiedAt
|
||||
testLoginUrl
|
||||
idpEntityId
|
||||
idpSsoUrl
|
||||
idpCertificate
|
||||
attributeMappings {
|
||||
email
|
||||
firstName
|
||||
lastName
|
||||
role
|
||||
}
|
||||
autoSignupEnabled
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const updateSAMLConfigurationMutation = graphql`
|
||||
mutation EditSAMLConfigurationForm_updateMutation(
|
||||
$input: UpdateSAMLConfigurationInput!
|
||||
) {
|
||||
updateSAMLConfiguration(input: $input) {
|
||||
samlConfiguration {
|
||||
id
|
||||
emailDomain
|
||||
enforcementPolicy
|
||||
domainVerificationToken
|
||||
domainVerifiedAt
|
||||
testLoginUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export function EditSAMLConfigurationForm(props: {
|
||||
onUpdate: () => void;
|
||||
queryRef: PreloadedQuery<EditSAMLConfigurationFormQuery>;
|
||||
}) {
|
||||
const { onUpdate, queryRef } = props;
|
||||
|
||||
const organizationId = useOrganizationId();
|
||||
|
||||
const { samlConfiguration } =
|
||||
usePreloadedQuery<EditSAMLConfigurationFormQuery>(
|
||||
samlConfigurationFormQuery,
|
||||
queryRef,
|
||||
);
|
||||
if (samlConfiguration.__typename !== "SAMLConfiguration") {
|
||||
throw new Error("node is not a SAML configuration");
|
||||
}
|
||||
|
||||
const [update, isUpdating] =
|
||||
useMutationWithToasts<EditSAMLConfigurationForm_updateMutation>(
|
||||
updateSAMLConfigurationMutation,
|
||||
{
|
||||
successMessage: "SAML configuration updated successfully.",
|
||||
errorMessage: "Failed to update SAML configuration. Please try again.",
|
||||
},
|
||||
);
|
||||
|
||||
const handleUpdate = useCallback(
|
||||
(data: SAMLConfigurationFormData) => {
|
||||
update({
|
||||
variables: {
|
||||
input: {
|
||||
samlConfigurationId: samlConfiguration.id,
|
||||
organizationId,
|
||||
idpEntityId: data.idpEntityId,
|
||||
idpSsoUrl: data.idpSsoUrl,
|
||||
idpCertificate: data.idpCertificate,
|
||||
autoSignupEnabled: data.autoSignupEnabled,
|
||||
enforcementPolicy: data.enforcementPolicy,
|
||||
attributeMappings: data.attributeMappings,
|
||||
},
|
||||
},
|
||||
onCompleted: onUpdate,
|
||||
});
|
||||
},
|
||||
[onUpdate, organizationId, samlConfiguration.id, update],
|
||||
);
|
||||
|
||||
return (
|
||||
<SAMLConfigurationForm
|
||||
disabled={isUpdating}
|
||||
initialValues={samlConfiguration}
|
||||
isEditing
|
||||
onSubmit={handleUpdate}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import { ConnectionHandler, graphql } from "react-relay";
|
||||
import type { NewSAMLConfigurationForm_createMutation } from "./__generated__/NewSAMLConfigurationForm_createMutation.graphql";
|
||||
import {
|
||||
SAMLConfigurationForm,
|
||||
type SAMLConfigurationFormData,
|
||||
} from "./SAMLConfigurationForm";
|
||||
import { useOrganizationId } from "/hooks/useOrganizationId";
|
||||
import { useCallback } from "react";
|
||||
import { useMutationWithToasts } from "/hooks/useMutationWithToasts";
|
||||
|
||||
const createSAMLConfigurationMutation = graphql`
|
||||
mutation NewSAMLConfigurationForm_createMutation(
|
||||
$input: CreateSAMLConfigurationInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
createSAMLConfiguration(input: $input) {
|
||||
samlConfigurationEdge @prependEdge(connections: $connections) {
|
||||
node {
|
||||
id
|
||||
emailDomain
|
||||
enforcementPolicy
|
||||
domainVerificationToken
|
||||
domainVerifiedAt
|
||||
testLoginUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export function NewSAMLConfigurationForm(props: { onCreate: () => void }) {
|
||||
const { onCreate } = props;
|
||||
const organizationId = useOrganizationId();
|
||||
|
||||
const [create, isCreating] =
|
||||
useMutationWithToasts<NewSAMLConfigurationForm_createMutation>(
|
||||
createSAMLConfigurationMutation,
|
||||
{
|
||||
successMessage: "SAML configuration created successfully.",
|
||||
errorMessage: "Failed to create SAML configuration",
|
||||
},
|
||||
);
|
||||
|
||||
const handleCreate = useCallback(
|
||||
(data: SAMLConfigurationFormData) => {
|
||||
const connectionID = ConnectionHandler.getConnectionID(
|
||||
organizationId,
|
||||
"SAMLConfigurationListFragment_samlConfigurations",
|
||||
);
|
||||
|
||||
create({
|
||||
variables: {
|
||||
input: {
|
||||
organizationId,
|
||||
emailDomain: data.emailDomain,
|
||||
idpEntityId: data.idpEntityId,
|
||||
idpSsoUrl: data.idpSsoUrl,
|
||||
idpCertificate: data.idpCertificate,
|
||||
autoSignupEnabled: data.autoSignupEnabled,
|
||||
attributeMappings: data.attributeMappings,
|
||||
},
|
||||
connections: [connectionID],
|
||||
},
|
||||
onCompleted: onCreate,
|
||||
});
|
||||
},
|
||||
[organizationId, create, onCreate],
|
||||
);
|
||||
|
||||
return (
|
||||
<SAMLConfigurationForm onSubmit={handleCreate} disabled={isCreating} />
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
DialogContent,
|
||||
DialogFooter,
|
||||
Field,
|
||||
Label,
|
||||
Option,
|
||||
Select,
|
||||
Textarea,
|
||||
} from "@probo/ui";
|
||||
import { Controller } from "react-hook-form";
|
||||
import z from "zod";
|
||||
import { useFormWithSchema } from "/hooks/useFormWithSchema";
|
||||
|
||||
const defaultValues: SAMLConfigurationFormData = {
|
||||
emailDomain: "",
|
||||
enforcementPolicy: "OPTIONAL" as const,
|
||||
idpEntityId: "",
|
||||
idpSsoUrl: "",
|
||||
idpCertificate: "",
|
||||
attributeMappings: {
|
||||
email: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
|
||||
firstName:
|
||||
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname",
|
||||
lastName: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname",
|
||||
role: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role",
|
||||
},
|
||||
autoSignupEnabled: false,
|
||||
};
|
||||
|
||||
const getEnforcementPolicyLabel = (
|
||||
policy: string,
|
||||
__: (key: string) => string,
|
||||
) => {
|
||||
switch (policy) {
|
||||
case "OFF":
|
||||
return __(
|
||||
"Your team members can't use single sign-on and must use their password",
|
||||
);
|
||||
case "REQUIRED":
|
||||
return __("Your team members must use single sign-on to log in");
|
||||
case "OPTIONAL":
|
||||
default:
|
||||
return __(
|
||||
"Your team members may use either single sign-on or their password to log in",
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const samlConfigSchema = z.object({
|
||||
emailDomain: z
|
||||
.string()
|
||||
.min(1, "Email domain is required")
|
||||
.regex(
|
||||
/^[a-z0-9.-]+\.[a-z]{2,}$/i,
|
||||
"Must be a valid domain (e.g., example.com)",
|
||||
),
|
||||
enforcementPolicy: z.enum(["OFF", "OPTIONAL", "REQUIRED"]),
|
||||
spCertificate: z.string().optional(),
|
||||
spPrivateKey: z.string().optional(),
|
||||
idpEntityId: z.string().min(1, "IdP Entity ID is required"),
|
||||
idpSsoUrl: z.string().url("IdP SSO URL must be a valid URL"),
|
||||
idpCertificate: z.string().min(1, "IdP Certificate is required"),
|
||||
attributeMappings: z.object({
|
||||
email: z.string().optional(),
|
||||
firstName: z.string().optional(),
|
||||
lastName: z.string().optional(),
|
||||
role: z.string().optional(),
|
||||
}),
|
||||
autoSignupEnabled: z.boolean().default(false),
|
||||
});
|
||||
|
||||
export type SAMLConfigurationFormData = z.infer<typeof samlConfigSchema>;
|
||||
|
||||
export function SAMLConfigurationForm(props: {
|
||||
isEditing?: boolean;
|
||||
disabled: boolean;
|
||||
initialValues?: SAMLConfigurationFormData;
|
||||
onSubmit: (data: SAMLConfigurationFormData) => void;
|
||||
}) {
|
||||
const {
|
||||
disabled,
|
||||
initialValues = defaultValues,
|
||||
isEditing,
|
||||
onSubmit,
|
||||
} = props;
|
||||
const { __ } = useTranslate();
|
||||
|
||||
const form = useFormWithSchema(samlConfigSchema, {
|
||||
defaultValues: initialValues,
|
||||
});
|
||||
|
||||
return (
|
||||
<form
|
||||
onSubmit={async (e) => {
|
||||
e.preventDefault();
|
||||
await form.handleSubmit(onSubmit)();
|
||||
form.reset(form.getValues());
|
||||
}}
|
||||
>
|
||||
<DialogContent padded className="space-y-6">
|
||||
<div>
|
||||
<h3 className="text-base font-medium mb-4">
|
||||
{__("Basic Configuration")}
|
||||
</h3>
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<Field
|
||||
{...form.register("emailDomain")}
|
||||
label={__("Email Domain") + " *"}
|
||||
placeholder="example.com"
|
||||
disabled={isEditing}
|
||||
error={form.formState.errors.emailDomain?.message}
|
||||
/>
|
||||
<p className="text-xs text-gray-600 mt-1">
|
||||
{isEditing
|
||||
? __("Email domain cannot be changed after creation")
|
||||
: __(
|
||||
"The email domain this SAML configuration applies to (e.g., example.com)",
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
{isEditing && (
|
||||
<div>
|
||||
<Label htmlFor="enforcementPolicy">
|
||||
{__("Enforcement Policy") + " *"}
|
||||
</Label>
|
||||
<Controller
|
||||
control={form.control}
|
||||
name="enforcementPolicy"
|
||||
render={({ field }) => (
|
||||
<div className="mt-2">
|
||||
<Select
|
||||
value={field.value}
|
||||
onValueChange={field.onChange}
|
||||
>
|
||||
<Option value="OPTIONAL">{__("Optional")}</Option>
|
||||
<Option value="REQUIRED">{__("Required")}</Option>
|
||||
<Option value="OFF">{__("Off")}</Option>
|
||||
</Select>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
{form.watch("enforcementPolicy") && (
|
||||
<p className="text-xs text-gray-600 mt-2">
|
||||
{getEnforcementPolicyLabel(
|
||||
form.watch("enforcementPolicy"),
|
||||
__,
|
||||
)}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-base font-medium mb-4">
|
||||
{__("Identity Provider Configuration")}
|
||||
</h3>
|
||||
<div className="space-y-4">
|
||||
<Field
|
||||
{...form.register("idpEntityId")}
|
||||
label={__("IdP Entity ID") + " *"}
|
||||
placeholder="https://idp.example.com/metadata"
|
||||
error={form.formState.errors.idpEntityId?.message}
|
||||
/>
|
||||
<Field
|
||||
{...form.register("idpSsoUrl")}
|
||||
label={__("IdP SSO URL") + " *"}
|
||||
placeholder="https://idp.example.com/sso"
|
||||
error={form.formState.errors.idpSsoUrl?.message}
|
||||
/>
|
||||
<div>
|
||||
<Label htmlFor="idpCertificate">
|
||||
{__("IdP X.509 Certificate") + " *"}
|
||||
</Label>
|
||||
<Textarea
|
||||
{...form.register("idpCertificate")}
|
||||
id="idpCertificate"
|
||||
rows={6}
|
||||
placeholder="-----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----"
|
||||
className="font-mono text-sm"
|
||||
/>
|
||||
{form.formState.errors.idpCertificate && (
|
||||
<p className="text-sm text-red-600 mt-1">
|
||||
{form.formState.errors.idpCertificate.message}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-base font-medium mb-4">
|
||||
{__("Attribute Mapping")}
|
||||
</h3>
|
||||
<div className="space-y-4">
|
||||
<Field
|
||||
{...form.register("attributeMappings.email")}
|
||||
label={__("Email Attribute")}
|
||||
placeholder={defaultValues.attributeMappings.email}
|
||||
error={form.formState.errors.attributeMappings?.email?.message}
|
||||
/>
|
||||
<Field
|
||||
{...form.register("attributeMappings.firstName")}
|
||||
label={__("First Name Attribute")}
|
||||
placeholder={defaultValues.attributeMappings.firstName}
|
||||
error={
|
||||
form.formState.errors.attributeMappings?.firstName?.message
|
||||
}
|
||||
/>
|
||||
<Field
|
||||
{...form.register("attributeMappings.lastName")}
|
||||
label={__("Last Name Attribute")}
|
||||
placeholder={defaultValues.attributeMappings.lastName}
|
||||
error={form.formState.errors.attributeMappings?.lastName?.message}
|
||||
/>
|
||||
<Field
|
||||
{...form.register("attributeMappings.role")}
|
||||
label={__("Role Attribute")}
|
||||
placeholder={defaultValues.attributeMappings.role}
|
||||
error={form.formState.errors.attributeMappings?.role?.message}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Controller
|
||||
control={form.control}
|
||||
name="autoSignupEnabled"
|
||||
render={({ field }) => (
|
||||
<div className="flex items-center gap-2">
|
||||
<Checkbox
|
||||
checked={field.value ?? false}
|
||||
onChange={field.onChange}
|
||||
/>
|
||||
<Label htmlFor="autoSignupEnabled" className="cursor-pointer">
|
||||
{__("Enable automatic user signup via SAML")}
|
||||
</Label>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</DialogContent>
|
||||
<DialogFooter>
|
||||
<Button type="submit" disabled={disabled}>
|
||||
{isEditing ? __("Update Configuration") : __("Create Configuration")}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { use } from "react";
|
||||
import { PermissionsContext } from "/providers/PermissionsContext";
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
Table,
|
||||
Tbody,
|
||||
Td,
|
||||
Th,
|
||||
Thead,
|
||||
Tr,
|
||||
useConfirm,
|
||||
} from "@probo/ui";
|
||||
import { graphql } from "relay-runtime";
|
||||
import { useFragment } from "react-relay";
|
||||
import type {
|
||||
SAMLConfigurationListFragment$data,
|
||||
SAMLConfigurationListFragment$key,
|
||||
} from "./__generated__/SAMLConfigurationListFragment.graphql";
|
||||
import { useMutationWithToasts } from "/hooks/useMutationWithToasts";
|
||||
import type { SAMLConfigurationList_deleteMutation } from "./__generated__/SAMLConfigurationList_deleteMutation.graphql";
|
||||
import { useOrganizationId } from "/hooks/useOrganizationId";
|
||||
import type { NodeOf } from "/types";
|
||||
import { useCopy } from "@probo/hooks";
|
||||
|
||||
const fragment = graphql`
|
||||
fragment SAMLConfigurationListFragment on Organization {
|
||||
samlConfigurations(first: 1000)
|
||||
@required(action: THROW)
|
||||
@connection(key: "SAMLConfigurationListFragment_samlConfigurations") {
|
||||
edges @required(action: THROW) {
|
||||
node {
|
||||
id
|
||||
emailDomain
|
||||
enforcementPolicy
|
||||
domainVerificationToken
|
||||
domainVerifiedAt
|
||||
testLoginUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const deleteMutation = graphql`
|
||||
mutation SAMLConfigurationList_deleteMutation(
|
||||
$input: DeleteSAMLConfigurationInput!
|
||||
) {
|
||||
deleteSAMLConfiguration(input: $input) {
|
||||
deletedSamlConfigurationId
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export function SAMLConfigurationList(props: {
|
||||
fKey: SAMLConfigurationListFragment$key;
|
||||
onNew: () => void;
|
||||
onEdit: (id: string) => void;
|
||||
onVerifyDomain: (dnsVerificationToken: string) => void;
|
||||
}) {
|
||||
const { fKey, onNew, onEdit, onVerifyDomain } = props;
|
||||
|
||||
const organizationId = useOrganizationId();
|
||||
const { __ } = useTranslate();
|
||||
const { isAuthorized } = use(PermissionsContext);
|
||||
|
||||
const confirm = useConfirm();
|
||||
const [isCopied, copy] = useCopy();
|
||||
|
||||
const {
|
||||
samlConfigurations: { edges: samlConfigurations },
|
||||
} = useFragment<SAMLConfigurationListFragment$key>(fragment, fKey);
|
||||
|
||||
const [deleteSAMLConfiguration] =
|
||||
useMutationWithToasts<SAMLConfigurationList_deleteMutation>(
|
||||
deleteMutation,
|
||||
{
|
||||
successMessage: "SAML configuration deleted successfully.",
|
||||
errorMessage: "Failed to delete SAML configuration. Please try again.",
|
||||
},
|
||||
);
|
||||
|
||||
const handleDelete = (
|
||||
config: NodeOf<SAMLConfigurationListFragment$data["samlConfigurations"]>,
|
||||
) => {
|
||||
confirm(
|
||||
async () => {
|
||||
deleteSAMLConfiguration({
|
||||
variables: {
|
||||
input: {
|
||||
organizationId,
|
||||
samlConfigurationId: config.id,
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
{
|
||||
title: __("Delete SAML Configuration"),
|
||||
message: __(
|
||||
"Are you sure you want to delete the SAML configuration for " +
|
||||
config.emailDomain +
|
||||
"? This action cannot be undone.",
|
||||
),
|
||||
label: __("Delete"),
|
||||
variant: "danger",
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
if (samlConfigurations.length === 0) {
|
||||
return (
|
||||
<Card padded>
|
||||
<div className="text-center py-12">
|
||||
<h3 className="text-lg font-medium text-gray-900 mb-2">
|
||||
{__("No SAML Configurations")}
|
||||
</h3>
|
||||
<p className="text-gray-600 mb-6">
|
||||
{__(
|
||||
"Set up SAML 2.0 single sign-on for your organization by adding a configuration for each email domain.",
|
||||
)}
|
||||
</p>
|
||||
{isAuthorized("Organization", "createSAMLConfiguration") && (
|
||||
<Button onClick={onNew}>
|
||||
{__("Add Your First Configuration")}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Table>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>{__("Email Domain")}</Th>
|
||||
<Th>{__("Domain Status")}</Th>
|
||||
<Th>{__("SAML Status")}</Th>
|
||||
<Th>{__("Enforcement")}</Th>
|
||||
<Th>{__("SSO URL")}</Th>
|
||||
<Th></Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{samlConfigurations.map(({ node: config }) => (
|
||||
<Tr key={config.id}>
|
||||
<Td>
|
||||
<button
|
||||
onClick={() => onEdit(config.id)}
|
||||
className="font-semibold text-blue-600 hover:text-blue-800"
|
||||
>
|
||||
{config.emailDomain}
|
||||
</button>
|
||||
</Td>
|
||||
<Td>
|
||||
<span
|
||||
className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${
|
||||
config.domainVerifiedAt
|
||||
? "bg-green-100 text-green-800"
|
||||
: "bg-yellow-100 text-yellow-800"
|
||||
}`}
|
||||
>
|
||||
{config.domainVerifiedAt
|
||||
? __("Verified")
|
||||
: __("Pending Verification")}
|
||||
</span>
|
||||
</Td>
|
||||
<Td>
|
||||
<span
|
||||
className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${
|
||||
config.enforcementPolicy !== "OFF"
|
||||
? "bg-green-100 text-green-800"
|
||||
: "bg-gray-100 text-gray-800"
|
||||
}`}
|
||||
>
|
||||
{config.enforcementPolicy !== "OFF"
|
||||
? __("Enabled")
|
||||
: __("Disabled")}
|
||||
</span>
|
||||
</Td>
|
||||
<Td>{config.enforcementPolicy}</Td>
|
||||
<Td>
|
||||
{config.domainVerifiedAt && config.enforcementPolicy !== "OFF" ? (
|
||||
<button
|
||||
onClick={() => copy(config.testLoginUrl)}
|
||||
className="text-blue-600 hover:text-blue-800"
|
||||
>
|
||||
{isCopied ? __("Copied!") : __("Copy URL")}
|
||||
</button>
|
||||
) : (
|
||||
<span className="text-gray-400">—</span>
|
||||
)}
|
||||
</Td>
|
||||
<Td width={180} className="text-end">
|
||||
<div className="flex gap-2 justify-end">
|
||||
{config.domainVerifiedAt ? (
|
||||
<>
|
||||
{isAuthorized(
|
||||
"SAMLConfiguration",
|
||||
"updateSAMLConfiguration",
|
||||
) && (
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => onEdit(config.id)}
|
||||
>
|
||||
{__("Edit")}
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{isAuthorized("Organization", "verifyDomain") &&
|
||||
!!config.domainVerificationToken && (
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={() =>
|
||||
onVerifyDomain(config.domainVerificationToken!)
|
||||
}
|
||||
>
|
||||
{__("Verify Domain")}
|
||||
</Button>
|
||||
)}
|
||||
{isAuthorized("Organization", "deleteOrganization") && (
|
||||
<Button
|
||||
variant="danger"
|
||||
onClick={() => handleDelete(config)}
|
||||
>
|
||||
{__("Delete")}
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</Td>
|
||||
</Tr>
|
||||
))}
|
||||
</Tbody>
|
||||
</Table>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import { useCopy } from "@probo/hooks";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { DialogContent, Button } from "@probo/ui";
|
||||
|
||||
export function SAMLDomainVerifyDialog(props: {
|
||||
domainVerificationToken: string;
|
||||
}) {
|
||||
const { domainVerificationToken } = props;
|
||||
|
||||
const { __ } = useTranslate();
|
||||
|
||||
const dnsRecord = `probo-verification=${domainVerificationToken}`;
|
||||
const [isCopied, copy] = useCopy();
|
||||
|
||||
return (
|
||||
<>
|
||||
<DialogContent padded className="space-y-6">
|
||||
<div>
|
||||
<h3 className="text-base font-medium mb-4">
|
||||
{__("Verify Domain Ownership")}
|
||||
</h3>
|
||||
<p className="text-sm text-gray-600 mb-4">
|
||||
{__(
|
||||
"Add the following TXT record to your domain's DNS configuration to verify ownership:",
|
||||
)}
|
||||
</p>
|
||||
<div className="bg-gray-50 rounded-lg p-4 mb-4">
|
||||
<div className="space-y-2">
|
||||
<div>
|
||||
<span className="font-semibold text-sm">
|
||||
{__("Host/Name:")}
|
||||
</span>
|
||||
<code className="ml-2 bg-white px-2 py-1 rounded text-sm">
|
||||
@
|
||||
</code>
|
||||
<span className="ml-2 text-xs text-gray-600">
|
||||
{__("or use your domain name")}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className="font-semibold text-sm">{__("Type:")}</span>
|
||||
<code className="ml-2 bg-white px-2 py-1 rounded text-sm">
|
||||
TXT
|
||||
</code>
|
||||
</div>
|
||||
<div>
|
||||
<span className="font-semibold text-sm">{__("Value:")}</span>
|
||||
<div className="mt-1 flex items-center gap-2">
|
||||
<code className="flex-1 bg-white px-2 py-1 rounded text-sm break-all font-mono">
|
||||
{dnsRecord}
|
||||
</code>
|
||||
<Button
|
||||
type="button"
|
||||
variant="secondary"
|
||||
onClick={() => copy(dnsRecord)}
|
||||
>
|
||||
{isCopied ? __("Copied!") : __("Copy")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-blue-50 border border-blue-200 rounded-lg p-4">
|
||||
<p className="text-sm text-blue-800">
|
||||
<strong>{__("Note:")}</strong>{" "}
|
||||
{__(
|
||||
"DNS changes may take up to 48 hours to propagate, but typically complete within a few minutes.",
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
/**
|
||||
* @generated SignedSource<<3da2840acb86d86a80715539be18fba0>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type SAMLEnforcementPolicy = "OFF" | "OPTIONAL" | "REQUIRED";
|
||||
export type EditSAMLConfigurationFormQuery$variables = {
|
||||
samlConfigurationId: string;
|
||||
};
|
||||
export type EditSAMLConfigurationFormQuery$data = {
|
||||
readonly samlConfiguration: {
|
||||
readonly __typename: "SAMLConfiguration";
|
||||
readonly attributeMappings: {
|
||||
readonly email: string;
|
||||
readonly firstName: string;
|
||||
readonly lastName: string;
|
||||
readonly role: string;
|
||||
};
|
||||
readonly autoSignupEnabled: boolean;
|
||||
readonly domainVerificationToken: string | null | undefined;
|
||||
readonly domainVerifiedAt: any | null | undefined;
|
||||
readonly emailDomain: string;
|
||||
readonly enforcementPolicy: SAMLEnforcementPolicy;
|
||||
readonly id: string;
|
||||
readonly idpCertificate: string;
|
||||
readonly idpEntityId: string;
|
||||
readonly idpSsoUrl: string;
|
||||
readonly testLoginUrl: string;
|
||||
} | {
|
||||
// This will never be '%other', but we need some
|
||||
// value in case none of the concrete values match.
|
||||
readonly __typename: "%other";
|
||||
};
|
||||
};
|
||||
export type EditSAMLConfigurationFormQuery = {
|
||||
response: EditSAMLConfigurationFormQuery$data;
|
||||
variables: EditSAMLConfigurationFormQuery$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "samlConfigurationId"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "id",
|
||||
"variableName": "samlConfigurationId"
|
||||
}
|
||||
],
|
||||
v2 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
},
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v4 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "emailDomain",
|
||||
"storageKey": null
|
||||
},
|
||||
v5 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "enforcementPolicy",
|
||||
"storageKey": null
|
||||
},
|
||||
v6 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "domainVerificationToken",
|
||||
"storageKey": null
|
||||
},
|
||||
v7 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "domainVerifiedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
v8 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "testLoginUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
v9 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "idpEntityId",
|
||||
"storageKey": null
|
||||
},
|
||||
v10 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "idpSsoUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
v11 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "idpCertificate",
|
||||
"storageKey": null
|
||||
},
|
||||
v12 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "SAMLAttributeMappings",
|
||||
"kind": "LinkedField",
|
||||
"name": "attributeMappings",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "email",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "firstName",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "lastName",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "role",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
v13 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "autoSignupEnabled",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "EditSAMLConfigurationFormQuery",
|
||||
"selections": [
|
||||
{
|
||||
"kind": "RequiredField",
|
||||
"field": {
|
||||
"alias": "samlConfiguration",
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
(v4/*: any*/),
|
||||
(v5/*: any*/),
|
||||
(v6/*: any*/),
|
||||
(v7/*: any*/),
|
||||
(v8/*: any*/),
|
||||
(v9/*: any*/),
|
||||
(v10/*: any*/),
|
||||
(v11/*: any*/),
|
||||
(v12/*: any*/),
|
||||
(v13/*: any*/)
|
||||
],
|
||||
"type": "SAMLConfiguration",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
"action": "THROW"
|
||||
}
|
||||
],
|
||||
"type": "Query",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "EditSAMLConfigurationFormQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "samlConfiguration",
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
(v4/*: any*/),
|
||||
(v5/*: any*/),
|
||||
(v6/*: any*/),
|
||||
(v7/*: any*/),
|
||||
(v8/*: any*/),
|
||||
(v9/*: any*/),
|
||||
(v10/*: any*/),
|
||||
(v11/*: any*/),
|
||||
(v12/*: any*/),
|
||||
(v13/*: any*/)
|
||||
],
|
||||
"type": "SAMLConfiguration",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "47c1ce92e8ba0395fa803b343d093879",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "EditSAMLConfigurationFormQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query EditSAMLConfigurationFormQuery(\n $samlConfigurationId: ID!\n) {\n samlConfiguration: node(id: $samlConfigurationId) {\n __typename\n ... on SAMLConfiguration {\n id\n emailDomain\n enforcementPolicy\n domainVerificationToken\n domainVerifiedAt\n testLoginUrl\n idpEntityId\n idpSsoUrl\n idpCertificate\n attributeMappings {\n email\n firstName\n lastName\n role\n }\n autoSignupEnabled\n }\n id\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "d31326e3e4423e62d8acde5735d9b578";
|
||||
|
||||
export default node;
|
||||
@@ -0,0 +1,159 @@
|
||||
/**
|
||||
* @generated SignedSource<<33cdb4d30c06225b656ba2b3f27830eb>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type SAMLEnforcementPolicy = "OFF" | "OPTIONAL" | "REQUIRED";
|
||||
export type UpdateSAMLConfigurationInput = {
|
||||
attributeMappings?: SAMLAttributeMappingsInput | null | undefined;
|
||||
autoSignupEnabled?: boolean | null | undefined;
|
||||
enforcementPolicy: SAMLEnforcementPolicy;
|
||||
idpCertificate?: string | null | undefined;
|
||||
idpEntityId?: string | null | undefined;
|
||||
idpSsoUrl?: string | null | undefined;
|
||||
organizationId: string;
|
||||
samlConfigurationId: string;
|
||||
};
|
||||
export type SAMLAttributeMappingsInput = {
|
||||
email?: string | null | undefined;
|
||||
firstName?: string | null | undefined;
|
||||
lastName?: string | null | undefined;
|
||||
role?: string | null | undefined;
|
||||
};
|
||||
export type EditSAMLConfigurationForm_updateMutation$variables = {
|
||||
input: UpdateSAMLConfigurationInput;
|
||||
};
|
||||
export type EditSAMLConfigurationForm_updateMutation$data = {
|
||||
readonly updateSAMLConfiguration: {
|
||||
readonly samlConfiguration: {
|
||||
readonly domainVerificationToken: string | null | undefined;
|
||||
readonly domainVerifiedAt: any | null | undefined;
|
||||
readonly emailDomain: string;
|
||||
readonly enforcementPolicy: SAMLEnforcementPolicy;
|
||||
readonly id: string;
|
||||
readonly testLoginUrl: string;
|
||||
} | null | undefined;
|
||||
} | null | undefined;
|
||||
};
|
||||
export type EditSAMLConfigurationForm_updateMutation = {
|
||||
response: EditSAMLConfigurationForm_updateMutation$data;
|
||||
variables: EditSAMLConfigurationForm_updateMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
{
|
||||
"alias": null,
|
||||
"args": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
],
|
||||
"concreteType": "UpdateSAMLConfigurationPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "updateSAMLConfiguration",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "SAMLConfiguration",
|
||||
"kind": "LinkedField",
|
||||
"name": "samlConfiguration",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "emailDomain",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "enforcementPolicy",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "domainVerificationToken",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "domainVerifiedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "testLoginUrl",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "EditSAMLConfigurationForm_updateMutation",
|
||||
"selections": (v1/*: any*/),
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "EditSAMLConfigurationForm_updateMutation",
|
||||
"selections": (v1/*: any*/)
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "56d29623294c243a01bfbc2ab4310d28",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "EditSAMLConfigurationForm_updateMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation EditSAMLConfigurationForm_updateMutation(\n $input: UpdateSAMLConfigurationInput!\n) {\n updateSAMLConfiguration(input: $input) {\n samlConfiguration {\n id\n emailDomain\n enforcementPolicy\n domainVerificationToken\n domainVerifiedAt\n testLoginUrl\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "b98e701514c179bba0f0ce63aae0c0b8";
|
||||
|
||||
export default node;
|
||||
@@ -0,0 +1,211 @@
|
||||
/**
|
||||
* @generated SignedSource<<0d0fdbf079f1a72545fa363ce60cd2f7>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type SAMLEnforcementPolicy = "OFF" | "OPTIONAL" | "REQUIRED";
|
||||
export type CreateSAMLConfigurationInput = {
|
||||
attributeMappings?: SAMLAttributeMappingsInput | null | undefined;
|
||||
autoSignupEnabled: boolean;
|
||||
emailDomain: string;
|
||||
idpCertificate: string;
|
||||
idpEntityId: string;
|
||||
idpSsoUrl: string;
|
||||
organizationId: string;
|
||||
};
|
||||
export type SAMLAttributeMappingsInput = {
|
||||
email?: string | null | undefined;
|
||||
firstName?: string | null | undefined;
|
||||
lastName?: string | null | undefined;
|
||||
role?: string | null | undefined;
|
||||
};
|
||||
export type NewSAMLConfigurationForm_createMutation$variables = {
|
||||
connections: ReadonlyArray<string>;
|
||||
input: CreateSAMLConfigurationInput;
|
||||
};
|
||||
export type NewSAMLConfigurationForm_createMutation$data = {
|
||||
readonly createSAMLConfiguration: {
|
||||
readonly samlConfigurationEdge: {
|
||||
readonly node: {
|
||||
readonly domainVerificationToken: string | null | undefined;
|
||||
readonly domainVerifiedAt: any | null | undefined;
|
||||
readonly emailDomain: string;
|
||||
readonly enforcementPolicy: SAMLEnforcementPolicy;
|
||||
readonly id: string;
|
||||
readonly testLoginUrl: string;
|
||||
};
|
||||
};
|
||||
} | null | undefined;
|
||||
};
|
||||
export type NewSAMLConfigurationForm_createMutation = {
|
||||
response: NewSAMLConfigurationForm_createMutation$data;
|
||||
variables: NewSAMLConfigurationForm_createMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "connections"
|
||||
},
|
||||
v1 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
},
|
||||
v2 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
],
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "SAMLConfigurationEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "samlConfigurationEdge",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "SAMLConfiguration",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "emailDomain",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "enforcementPolicy",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "domainVerificationToken",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "domainVerifiedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "testLoginUrl",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "NewSAMLConfigurationForm_createMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "CreateSAMLConfigurationPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "createSAMLConfiguration",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": [
|
||||
(v1/*: any*/),
|
||||
(v0/*: any*/)
|
||||
],
|
||||
"kind": "Operation",
|
||||
"name": "NewSAMLConfigurationForm_createMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "CreateSAMLConfigurationPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "createSAMLConfiguration",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"filters": null,
|
||||
"handle": "prependEdge",
|
||||
"key": "",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "samlConfigurationEdge",
|
||||
"handleArgs": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "connections",
|
||||
"variableName": "connections"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "969d5fb34995f5cce359c792cbe1ff49",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "NewSAMLConfigurationForm_createMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation NewSAMLConfigurationForm_createMutation(\n $input: CreateSAMLConfigurationInput!\n) {\n createSAMLConfiguration(input: $input) {\n samlConfigurationEdge {\n node {\n id\n emailDomain\n enforcementPolicy\n domainVerificationToken\n domainVerifiedAt\n testLoginUrl\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "5a3b2e5d219b40ca096eece75d7b63b3";
|
||||
|
||||
export default node;
|
||||
@@ -0,0 +1,180 @@
|
||||
/**
|
||||
* @generated SignedSource<<12fade1fd1f7f3ae53595970b6c2c47e>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment } from 'relay-runtime';
|
||||
export type SAMLEnforcementPolicy = "OFF" | "OPTIONAL" | "REQUIRED";
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type SAMLConfigurationListFragment$data = {
|
||||
readonly samlConfigurations: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly domainVerificationToken: string | null | undefined;
|
||||
readonly domainVerifiedAt: any | null | undefined;
|
||||
readonly emailDomain: string;
|
||||
readonly enforcementPolicy: SAMLEnforcementPolicy;
|
||||
readonly id: string;
|
||||
readonly testLoginUrl: string;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly " $fragmentType": "SAMLConfigurationListFragment";
|
||||
};
|
||||
export type SAMLConfigurationListFragment$key = {
|
||||
readonly " $data"?: SAMLConfigurationListFragment$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"SAMLConfigurationListFragment">;
|
||||
};
|
||||
|
||||
const node: ReaderFragment = {
|
||||
"argumentDefinitions": [],
|
||||
"kind": "Fragment",
|
||||
"metadata": {
|
||||
"connection": [
|
||||
{
|
||||
"count": null,
|
||||
"cursor": null,
|
||||
"direction": "forward",
|
||||
"path": [
|
||||
"samlConfigurations"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "SAMLConfigurationListFragment",
|
||||
"selections": [
|
||||
{
|
||||
"kind": "RequiredField",
|
||||
"field": {
|
||||
"alias": "samlConfigurations",
|
||||
"args": null,
|
||||
"concreteType": "SAMLConfigurationConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "__SAMLConfigurationListFragment_samlConfigurations_connection",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"kind": "RequiredField",
|
||||
"field": {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "SAMLConfigurationEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "SAMLConfiguration",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "emailDomain",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "enforcementPolicy",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "domainVerificationToken",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "domainVerifiedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "testLoginUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
"action": "THROW"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
"kind": "LinkedField",
|
||||
"name": "pageInfo",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "endCursor",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "hasNextPage",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
"action": "THROW"
|
||||
}
|
||||
],
|
||||
"type": "Organization",
|
||||
"abstractKey": null
|
||||
};
|
||||
|
||||
(node as any).hash = "79203ccae6f8e3a1967b463f0f3f3c76";
|
||||
|
||||
export default node;
|
||||
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* @generated SignedSource<<4ce15b49974b7e512f334f47765caaa4>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type DeleteSAMLConfigurationInput = {
|
||||
organizationId: string;
|
||||
samlConfigurationId: string;
|
||||
};
|
||||
export type SAMLConfigurationList_deleteMutation$variables = {
|
||||
input: DeleteSAMLConfigurationInput;
|
||||
};
|
||||
export type SAMLConfigurationList_deleteMutation$data = {
|
||||
readonly deleteSAMLConfiguration: {
|
||||
readonly deletedSamlConfigurationId: string;
|
||||
} | null | undefined;
|
||||
};
|
||||
export type SAMLConfigurationList_deleteMutation = {
|
||||
response: SAMLConfigurationList_deleteMutation$data;
|
||||
variables: SAMLConfigurationList_deleteMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
{
|
||||
"alias": null,
|
||||
"args": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
],
|
||||
"concreteType": "DeleteSAMLConfigurationPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "deleteSAMLConfiguration",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "deletedSamlConfigurationId",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "SAMLConfigurationList_deleteMutation",
|
||||
"selections": (v1/*: any*/),
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "SAMLConfigurationList_deleteMutation",
|
||||
"selections": (v1/*: any*/)
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "cb46bb31e5d10f0ddad38795a72b1ab1",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "SAMLConfigurationList_deleteMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation SAMLConfigurationList_deleteMutation(\n $input: DeleteSAMLConfigurationInput!\n) {\n deleteSAMLConfiguration(input: $input) {\n deletedSamlConfigurationId\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "2ebbe76aae843f00570f7ae1848ee995";
|
||||
|
||||
export default node;
|
||||
@@ -220,12 +220,13 @@ const routes = [
|
||||
() => import("./pages/organizations/settings/DomainSettingsTab"),
|
||||
),
|
||||
},
|
||||
// {
|
||||
// path: "saml-sso",
|
||||
// Component: lazy(
|
||||
// () => import("./pages/organizations/settings/SAMLSettingsTab")
|
||||
// ),
|
||||
// },
|
||||
{
|
||||
path: "saml-sso",
|
||||
Component: lazy(
|
||||
() =>
|
||||
import("./pages/iam/organizations/settings/SAMLSettingsPageLoader"),
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
...riskRoutes,
|
||||
|
||||
Reference in New Issue
Block a user