From 99c9b644df0d0ea75411ec82ba679237c102f69a Mon Sep 17 00:00:00 2001 From: Scott Wilson Date: Fri, 24 Jan 2025 12:55:56 -0800 Subject: [PATCH] improvements: address feedback --- .../src/hooks/api/identities/mutations.tsx | 4 +- .../IdentityAuthMethodModal.tsx | 2 +- .../IdentityAuthMethodModalContent.tsx | 16 +- .../IdentitySection/IdentityAwsAuthForm.tsx | 383 ++++----- .../IdentitySection/IdentityAzureAuthForm.tsx | 383 ++++----- .../IdentitySection/IdentityGcpAuthForm.tsx | 427 +++++----- .../IdentitySection/IdentityJwtAuthForm.tsx | 737 +++++++++--------- .../IdentityKubernetesAuthForm.tsx | 494 ++++++------ .../IdentitySection/IdentityOidcAuthForm.tsx | 629 ++++++++------- .../IdentitySection/IdentityTokenAuthForm.tsx | 326 ++++---- .../IdentityUniversalAuthForm.tsx | 432 +++++----- .../components/IdentitySection/types/index.ts | 4 + .../IdentityDetailsByIDPage.tsx | 8 - .../IdentityAuthFieldDisplay.tsx | 6 +- .../IdentityTokenAuthTokensTable.tsx | 4 +- ...dentityUniversalAuthClientSecretsTable.tsx | 4 +- .../ViewIdentityAuthModal.tsx | 24 +- .../ViewIdentityAwsAuthContent.tsx | 47 +- .../ViewIdentityAzureAuthContent.tsx | 47 +- .../ViewIdentityContentWrapper.tsx | 49 +- .../ViewIdentityGcpAuthContent.tsx | 47 +- .../ViewIdentityJwtAuthContent.tsx | 90 ++- .../ViewIdentityKubernetesAuthContent.tsx | 73 +- .../ViewIdentityOidcAuthContent.tsx | 73 +- .../ViewIdentityTokenAuthContent.tsx | 23 +- .../ViewIdentityUniversalAuthContent.tsx | 27 +- .../ViewIdentityAuthModal/types/index.ts | 9 +- 27 files changed, 2374 insertions(+), 1994 deletions(-) create mode 100644 frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/types/index.ts diff --git a/frontend/src/hooks/api/identities/mutations.tsx b/frontend/src/hooks/api/identities/mutations.tsx index 42de92e71..3e38d9067 100644 --- a/frontend/src/hooks/api/identities/mutations.tsx +++ b/frontend/src/hooks/api/identities/mutations.tsx @@ -923,7 +923,7 @@ export const useAddIdentityTokenAuth = () => { }); queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) }); queryClient.invalidateQueries({ - queryKey: identitiesKeys.getIdentityUniversalAuth(identityId) + queryKey: identitiesKeys.getIdentityTokenAuth(identityId) }); } }); @@ -959,7 +959,7 @@ export const useUpdateIdentityTokenAuth = () => { }); queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) }); queryClient.invalidateQueries({ - queryKey: identitiesKeys.getIdentityUniversalAuth(identityId) + queryKey: identitiesKeys.getIdentityTokenAuth(identityId) }); } }); diff --git a/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityAuthMethodModal.tsx b/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityAuthMethodModal.tsx index 27d2f727a..a5f2357dd 100644 --- a/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityAuthMethodModal.tsx +++ b/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityAuthMethodModal.tsx @@ -34,7 +34,7 @@ export const IdentityAuthMethodModal = ({ popUp, handlePopUpOpen, handlePopUpTog title={ isSelectedAuthAlreadyConfigured ? `Edit ${identityAuthToNameMap[selectedAuthMethod!] ?? ""}` - : `Create new ${identityAuthToNameMap[selectedAuthMethod!] ?? ""}` + : `Add ${identityAuthToNameMap[selectedAuthMethod!] ?? ""}` } > ( @@ -121,7 +121,7 @@ export const IdentityAuthMethodModalContent = ({ [IdentityAuthMethod.OIDC_AUTH]: { render: () => ( @@ -131,7 +131,7 @@ export const IdentityAuthMethodModalContent = ({ [IdentityAuthMethod.TOKEN_AUTH]: { render: () => ( @@ -141,7 +141,7 @@ export const IdentityAuthMethodModalContent = ({ [IdentityAuthMethod.AZURE_AUTH]: { render: () => ( @@ -151,7 +151,7 @@ export const IdentityAuthMethodModalContent = ({ [IdentityAuthMethod.GCP_AUTH]: { render: () => ( @@ -161,7 +161,7 @@ export const IdentityAuthMethodModalContent = ({ [IdentityAuthMethod.KUBERNETES_AUTH]: { render: () => ( @@ -171,7 +171,7 @@ export const IdentityAuthMethodModalContent = ({ [IdentityAuthMethod.AWS_AUTH]: { render: () => ( @@ -181,7 +181,7 @@ export const IdentityAuthMethodModalContent = ({ [IdentityAuthMethod.JWT_AUTH]: { render: () => ( diff --git a/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityAwsAuthForm.tsx b/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityAwsAuthForm.tsx index 9c73f50b4..7f609305d 100644 --- a/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityAwsAuthForm.tsx +++ b/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityAwsAuthForm.tsx @@ -1,4 +1,4 @@ -import { useEffect } from "react"; +import { useEffect, useState } from "react"; import { Controller, useFieldArray, useForm } from "react-hook-form"; import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; @@ -6,17 +6,27 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; import { createNotification } from "@app/components/notifications"; -import { Button, FormControl, IconButton, Input } from "@app/components/v2"; +import { + Button, + FormControl, + IconButton, + Input, + Tab, + TabList, + TabPanel, + Tabs +} from "@app/components/v2"; import { useOrganization, useSubscription } from "@app/context"; import { useAddIdentityAwsAuth, useGetIdentityAwsAuth, useUpdateIdentityAwsAuth } from "@app/hooks/api"; -import { IdentityAuthMethod } from "@app/hooks/api/identities"; import { IdentityTrustedIp } from "@app/hooks/api/identities/types"; import { UsePopUpState } from "@app/hooks/usePopUp"; +import { IdentityFormTab } from "./types"; + const schema = z .object({ stsEndpoint: z.string(), @@ -52,18 +62,15 @@ type Props = { popUpName: keyof UsePopUpState<["identityAuthMethod"]>, state?: boolean ) => void; - identityAuthMethodData: { - identityId: string; - name: string; - configuredAuthMethods?: IdentityAuthMethod[]; - authMethod?: IdentityAuthMethod; - }; + identityId?: string; + isUpdate?: boolean; }; export const IdentityAwsAuthForm = ({ handlePopUpOpen, handlePopUpToggle, - identityAuthMethodData + identityId, + isUpdate }: Props) => { const { currentOrg } = useOrganization(); const orgId = currentOrg?.id || ""; @@ -71,11 +78,9 @@ export const IdentityAwsAuthForm = ({ const { mutateAsync: addMutateAsync } = useAddIdentityAwsAuth(); const { mutateAsync: updateMutateAsync } = useUpdateIdentityAwsAuth(); + const [tabValue, setTabValue] = useState(IdentityFormTab.Configuration); - const isUpdate = identityAuthMethodData?.configuredAuthMethods?.includes( - identityAuthMethodData.authMethod! || "" - ); - const { data } = useGetIdentityAwsAuth(identityAuthMethodData?.identityId ?? "", { + const { data } = useGetIdentityAwsAuth(identityId ?? "", { enabled: isUpdate }); @@ -143,7 +148,7 @@ export const IdentityAwsAuthForm = ({ accessTokenTrustedIps }: FormData) => { try { - if (!identityAuthMethodData) return; + if (!identityId) return; if (data) { await updateMutateAsync({ @@ -151,7 +156,7 @@ export const IdentityAwsAuthForm = ({ stsEndpoint, allowedPrincipalArns, allowedAccountIds, - identityId: identityAuthMethodData.identityId, + identityId, accessTokenTTL: Number(accessTokenTTL), accessTokenMaxTTL: Number(accessTokenMaxTTL), accessTokenNumUsesLimit: Number(accessTokenNumUsesLimit), @@ -160,7 +165,7 @@ export const IdentityAwsAuthForm = ({ } else { await addMutateAsync({ organizationId: orgId, - identityId: identityAuthMethodData.identityId, + identityId, stsEndpoint: stsEndpoint || "", allowedPrincipalArns: allowedPrincipalArns || "", allowedAccountIds: allowedAccountIds || "", @@ -188,178 +193,194 @@ export const IdentityAwsAuthForm = ({ }; return ( -
- ( - - - - )} - /> - ( - - - - )} - /> - ( - - - - )} - /> - ( - - - - )} - /> - ( - - - - )} - /> - ( - - - - )} - /> - {accessTokenTrustedIpsFields.map(({ id }, index) => ( -
+ { + setTabValue( + ["accessTokenTrustedIps"].includes(Object.keys(fields)[0]) + ? IdentityFormTab.Advanced + : IdentityFormTab.Configuration + ); + })} + > + setTabValue(value as IdentityFormTab)}> + + Configuration + Advanced + + { - return ( - - { - if (subscription?.ipAllowlisting) { - field.onChange(e); - return; - } - - handlePopUpOpen("upgradePlan"); - }} - placeholder="123.456.789.0" - /> - - ); - }} + defaultValue="2592000" + name="allowedPrincipalArns" + render={({ field, fieldState: { error } }) => ( + + + + )} /> - { - if (subscription?.ipAllowlisting) { - removeAccessTokenTrustedIp(index); - return; - } + ( + + + + )} + /> + ( + + + + )} + /> + ( + + + + )} + /> + ( + + + + )} + /> + ( + + + + )} + /> + + + {accessTokenTrustedIpsFields.map(({ id }, index) => ( +
+ { + return ( + + { + if (subscription?.ipAllowlisting) { + field.onChange(e); + return; + } - handlePopUpOpen("upgradePlan"); - }} - size="lg" - colorSchema="danger" - variant="plain" - ariaLabel="update" - className="p-3" - > - - -
- ))} -
+ handlePopUpOpen("upgradePlan"); + }} + placeholder="123.456.789.0" + /> + + ); + }} + /> + { + if (subscription?.ipAllowlisting) { + removeAccessTokenTrustedIp(index); + return; + } + + handlePopUpOpen("upgradePlan"); + }} + size="lg" + colorSchema="danger" + variant="plain" + ariaLabel="update" + className="p-3" + > + + +
+ ))} +
+ +
+
+
+
-
-
-
- - -
+
); diff --git a/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityAzureAuthForm.tsx b/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityAzureAuthForm.tsx index e2491c261..1bfdf2757 100644 --- a/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityAzureAuthForm.tsx +++ b/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityAzureAuthForm.tsx @@ -1,4 +1,4 @@ -import { useEffect } from "react"; +import { useEffect, useState } from "react"; import { Controller, useFieldArray, useForm } from "react-hook-form"; import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; @@ -6,17 +6,27 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; import { createNotification } from "@app/components/notifications"; -import { Button, FormControl, IconButton, Input } from "@app/components/v2"; +import { + Button, + FormControl, + IconButton, + Input, + Tab, + TabList, + TabPanel, + Tabs +} from "@app/components/v2"; import { useOrganization, useSubscription } from "@app/context"; import { useAddIdentityAzureAuth, useGetIdentityAzureAuth, useUpdateIdentityAzureAuth } from "@app/hooks/api"; -import { IdentityAuthMethod } from "@app/hooks/api/identities"; import { IdentityTrustedIp } from "@app/hooks/api/identities/types"; import { UsePopUpState } from "@app/hooks/usePopUp"; +import { IdentityFormTab } from "./types"; + const schema = z .object({ tenantId: z.string().min(1), @@ -47,18 +57,15 @@ type Props = { popUpName: keyof UsePopUpState<["identityAuthMethod"]>, state?: boolean ) => void; - identityAuthMethodData: { - identityId: string; - name: string; - configuredAuthMethods?: IdentityAuthMethod[]; - authMethod?: IdentityAuthMethod; - }; + identityId?: string; + isUpdate?: boolean; }; export const IdentityAzureAuthForm = ({ handlePopUpOpen, handlePopUpToggle, - identityAuthMethodData + identityId, + isUpdate }: Props) => { const { currentOrg } = useOrganization(); const orgId = currentOrg?.id || ""; @@ -66,11 +73,9 @@ export const IdentityAzureAuthForm = ({ const { mutateAsync: addMutateAsync } = useAddIdentityAzureAuth(); const { mutateAsync: updateMutateAsync } = useUpdateIdentityAzureAuth(); + const [tabValue, setTabValue] = useState(IdentityFormTab.Configuration); - const isUpdate = identityAuthMethodData?.configuredAuthMethods?.includes( - identityAuthMethodData.authMethod! || "" - ); - const { data } = useGetIdentityAzureAuth(identityAuthMethodData?.identityId ?? "", { + const { data } = useGetIdentityAzureAuth(identityId ?? "", { enabled: isUpdate }); @@ -139,12 +144,12 @@ export const IdentityAzureAuthForm = ({ accessTokenTrustedIps }: FormData) => { try { - if (!identityAuthMethodData) return; + if (!identityId) return; if (data) { await updateMutateAsync({ organizationId: orgId, - identityId: identityAuthMethodData.identityId, + identityId, tenantId, resource, allowedServicePrincipalIds, @@ -156,7 +161,7 @@ export const IdentityAzureAuthForm = ({ } else { await addMutateAsync({ organizationId: orgId, - identityId: identityAuthMethodData.identityId, + identityId, tenantId: tenantId || "", resource: resource || "", allowedServicePrincipalIds: allowedServicePrincipalIds || "", @@ -184,178 +189,194 @@ export const IdentityAzureAuthForm = ({ }; return ( -
- ( - - - - )} - /> - ( - - - - )} - /> - ( - - - - )} - /> - ( - - - - )} - /> - ( - - - - )} - /> - ( - - - - )} - /> - {accessTokenTrustedIpsFields.map(({ id }, index) => ( -
+ { + setTabValue( + ["accessTokenTrustedIps"].includes(Object.keys(fields)[0]) + ? IdentityFormTab.Advanced + : IdentityFormTab.Configuration + ); + })} + > + setTabValue(value as IdentityFormTab)}> + + Configuration + Advanced + + { - return ( - - { - if (subscription?.ipAllowlisting) { - field.onChange(e); - return; - } - - handlePopUpOpen("upgradePlan"); - }} - placeholder="123.456.789.0" - /> - - ); - }} + defaultValue="2592000" + name="tenantId" + render={({ field, fieldState: { error } }) => ( + + + + )} /> - { - if (subscription?.ipAllowlisting) { - removeAccessTokenTrustedIp(index); - return; - } + ( + + + + )} + /> + ( + + + + )} + /> + ( + + + + )} + /> + ( + + + + )} + /> + ( + + + + )} + /> + + + {accessTokenTrustedIpsFields.map(({ id }, index) => ( +
+ { + return ( + + { + if (subscription?.ipAllowlisting) { + field.onChange(e); + return; + } - handlePopUpOpen("upgradePlan"); - }} - size="lg" - colorSchema="danger" - variant="plain" - ariaLabel="update" - className="p-3" - > - - -
- ))} -
+ handlePopUpOpen("upgradePlan"); + }} + placeholder="123.456.789.0" + /> + + ); + }} + /> + { + if (subscription?.ipAllowlisting) { + removeAccessTokenTrustedIp(index); + return; + } + + handlePopUpOpen("upgradePlan"); + }} + size="lg" + colorSchema="danger" + variant="plain" + ariaLabel="update" + className="p-3" + > + + +
+ ))} +
+ +
+
+
+
-
-
-
- - -
+
); diff --git a/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityGcpAuthForm.tsx b/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityGcpAuthForm.tsx index 71a171eac..2a3fc526d 100644 --- a/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityGcpAuthForm.tsx +++ b/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityGcpAuthForm.tsx @@ -1,4 +1,4 @@ -import { useEffect } from "react"; +import { useEffect, useState } from "react"; import { Controller, useFieldArray, useForm } from "react-hook-form"; import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; @@ -6,17 +6,29 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; import { createNotification } from "@app/components/notifications"; -import { Button, FormControl, IconButton, Input, Select, SelectItem } from "@app/components/v2"; +import { + Button, + FormControl, + IconButton, + Input, + Select, + SelectItem, + Tab, + TabList, + TabPanel, + Tabs +} from "@app/components/v2"; import { useOrganization, useSubscription } from "@app/context"; import { useAddIdentityGcpAuth, useGetIdentityGcpAuth, useUpdateIdentityGcpAuth } from "@app/hooks/api"; -import { IdentityAuthMethod } from "@app/hooks/api/identities"; import { IdentityTrustedIp } from "@app/hooks/api/identities/types"; import { UsePopUpState } from "@app/hooks/usePopUp"; +import { IdentityFormTab } from "./types"; + const schema = z .object({ type: z.enum(["iam", "gce"]), @@ -48,18 +60,15 @@ type Props = { popUpName: keyof UsePopUpState<["identityAuthMethod"]>, state?: boolean ) => void; - identityAuthMethodData: { - identityId: string; - name: string; - configuredAuthMethods?: IdentityAuthMethod[]; - authMethod?: IdentityAuthMethod; - }; + identityId?: string; + isUpdate?: boolean; }; export const IdentityGcpAuthForm = ({ handlePopUpOpen, handlePopUpToggle, - identityAuthMethodData + identityId, + isUpdate }: Props) => { const { currentOrg } = useOrganization(); const orgId = currentOrg?.id || ""; @@ -67,11 +76,9 @@ export const IdentityGcpAuthForm = ({ const { mutateAsync: addMutateAsync } = useAddIdentityGcpAuth(); const { mutateAsync: updateMutateAsync } = useUpdateIdentityGcpAuth(); + const [tabValue, setTabValue] = useState(IdentityFormTab.Configuration); - const isUpdate = identityAuthMethodData?.configuredAuthMethods?.includes( - identityAuthMethodData.authMethod! || "" - ); - const { data } = useGetIdentityGcpAuth(identityAuthMethodData?.identityId ?? "", { + const { data } = useGetIdentityGcpAuth(identityId ?? "", { enabled: isUpdate }); @@ -146,11 +153,11 @@ export const IdentityGcpAuthForm = ({ accessTokenTrustedIps }: FormData) => { try { - if (!identityAuthMethodData) return; + if (!identityId) return; if (data) { await updateMutateAsync({ - identityId: identityAuthMethodData.identityId, + identityId, organizationId: orgId, type, allowedServiceAccounts, @@ -163,7 +170,7 @@ export const IdentityGcpAuthForm = ({ }); } else { await addMutateAsync({ - identityId: identityAuthMethodData.identityId, + identityId, organizationId: orgId, type, allowedServiceAccounts: allowedServiceAccounts || "", @@ -193,202 +200,222 @@ export const IdentityGcpAuthForm = ({ }; return ( -
- ( - - - - )} - /> - ( - - - - )} - /> - {watchedType === "gce" && ( - ( - - - - )} - /> - )} - {watchedType === "gce" && ( - ( - - - - )} - /> - )} - ( - - - - )} - /> - ( - - - - )} - /> - ( - - - - )} - /> - {accessTokenTrustedIpsFields.map(({ id }, index) => ( -
+ { + setTabValue( + ["accessTokenTrustedIps"].includes(Object.keys(fields)[0]) + ? IdentityFormTab.Advanced + : IdentityFormTab.Configuration + ); + })} + > + setTabValue(value as IdentityFormTab)}> + + Configuration + Advanced + + { - return ( + name="type" + render={({ field: { onChange, ...field }, fieldState: { error } }) => ( + + + + )} + /> + ( + + + + )} + /> + {watchedType === "gce" && ( + ( - { - if (subscription?.ipAllowlisting) { - field.onChange(e); - return; - } - - handlePopUpOpen("upgradePlan"); - }} - placeholder="123.456.789.0" - /> + - ); - }} + )} + /> + )} + {watchedType === "gce" && ( + ( + + + + )} + /> + )} + ( + + + + )} /> - { - if (subscription?.ipAllowlisting) { - removeAccessTokenTrustedIp(index); - return; - } + ( + + + + )} + /> + ( + + + + )} + /> + + + {accessTokenTrustedIpsFields.map(({ id }, index) => ( +
+ { + return ( + + { + if (subscription?.ipAllowlisting) { + field.onChange(e); + return; + } - handlePopUpOpen("upgradePlan"); - }} - size="lg" - colorSchema="danger" - variant="plain" - ariaLabel="update" - className="p-3" - > - - -
- ))} -
+ handlePopUpOpen("upgradePlan"); + }} + placeholder="123.456.789.0" + /> + + ); + }} + /> + { + if (subscription?.ipAllowlisting) { + removeAccessTokenTrustedIp(index); + return; + } + + handlePopUpOpen("upgradePlan"); + }} + size="lg" + colorSchema="danger" + variant="plain" + ariaLabel="update" + className="p-3" + > + + +
+ ))} +
+ +
+
+
+
-
-
-
- - -
+
); diff --git a/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityJwtAuthForm.tsx b/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityJwtAuthForm.tsx index d1cdfe6a7..9b2f56d15 100644 --- a/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityJwtAuthForm.tsx +++ b/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityJwtAuthForm.tsx @@ -1,4 +1,4 @@ -import { useEffect } from "react"; +import { useEffect, useState } from "react"; import { Controller, useFieldArray, useForm } from "react-hook-form"; import { faQuestionCircle } from "@fortawesome/free-regular-svg-icons"; import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons"; @@ -14,17 +14,22 @@ import { Input, Select, SelectItem, + Tab, + TabList, + TabPanel, + Tabs, TextArea, Tooltip } from "@app/components/v2"; import { useOrganization, useSubscription } from "@app/context"; import { useAddIdentityJwtAuth, useUpdateIdentityJwtAuth } from "@app/hooks/api"; -import { IdentityAuthMethod } from "@app/hooks/api/identities"; import { IdentityJwtConfigurationType } from "@app/hooks/api/identities/enums"; import { useGetIdentityJwtAuth } from "@app/hooks/api/identities/queries"; import { IdentityTrustedIp } from "@app/hooks/api/identities/types"; import { UsePopUpState } from "@app/hooks/usePopUp"; +import { IdentityFormTab } from "./types"; + const commonSchema = z.object({ accessTokenTrustedIps: z .array( @@ -88,18 +93,15 @@ type Props = { popUpName: keyof UsePopUpState<["identityAuthMethod"]>, state?: boolean ) => void; - identityAuthMethodData: { - identityId: string; - name: string; - configuredAuthMethods?: IdentityAuthMethod[]; - authMethod?: IdentityAuthMethod; - }; + identityId?: string; + isUpdate?: boolean; }; export const IdentityJwtAuthForm = ({ handlePopUpOpen, handlePopUpToggle, - identityAuthMethodData + identityId, + isUpdate }: Props) => { const { currentOrg } = useOrganization(); const orgId = currentOrg?.id || ""; @@ -107,11 +109,9 @@ export const IdentityJwtAuthForm = ({ const { mutateAsync: addMutateAsync } = useAddIdentityJwtAuth(); const { mutateAsync: updateMutateAsync } = useUpdateIdentityJwtAuth(); + const [tabValue, setTabValue] = useState(IdentityFormTab.Configuration); - const isUpdate = identityAuthMethodData?.configuredAuthMethods?.includes( - identityAuthMethodData.authMethod! || "" - ); - const { data } = useGetIdentityJwtAuth(identityAuthMethodData?.identityId ?? "", { + const { data } = useGetIdentityJwtAuth(identityId ?? "", { enabled: isUpdate }); @@ -218,13 +218,13 @@ export const IdentityJwtAuthForm = ({ boundSubject }: FormData) => { try { - if (!identityAuthMethodData) { + if (!identityId) { return; } if (data) { await updateMutateAsync({ - identityId: identityAuthMethodData.identityId, + identityId, organizationId: orgId, configurationType, jwksUrl, @@ -241,7 +241,7 @@ export const IdentityJwtAuthForm = ({ }); } else { await addMutateAsync({ - identityId: identityAuthMethodData.identityId, + identityId, configurationType, jwksUrl, jwksCaCert, @@ -275,56 +275,230 @@ export const IdentityJwtAuthForm = ({ }; return ( -
- ( - - - - )} - /> - {selectedConfigurationType === IdentityJwtConfigurationType.JWKS && ( - <> + { + setTabValue( + [ + "accessTokenTrustedIps", + "boundIssuer", + "boundAudiences", + "boundSubject", + "boundClaims" + ].includes(Object.keys(fields)[0]) + ? IdentityFormTab.Advanced + : IdentityFormTab.Configuration + ); + })} + > + setTabValue(value as IdentityFormTab)}> + + Configuration + Advanced + + ( + name="configurationType" + render={({ field: { onChange, ...field }, fieldState: { error } }) => ( + + + )} + /> + {selectedConfigurationType === IdentityJwtConfigurationType.JWKS && ( + <> + ( + + + + )} + /> + ( + +