From f63c6b725b576f9ae67f4e582c0df80160b18cdc Mon Sep 17 00:00:00 2001 From: Meet Date: Tue, 24 Sep 2024 21:07:43 +0530 Subject: [PATCH] feat: allow users to replace auth methods --- .../IdentityAuthMethodModal.tsx | 211 ++++++++++-------- .../IdentitySection/IdentityAwsAuthForm.tsx | 57 +++-- .../IdentitySection/IdentityAzureAuthForm.tsx | 72 ++++-- .../IdentitySection/IdentityGcpAuthForm.tsx | 67 ++++-- .../IdentityKubernetesAuthForm.tsx | 75 +++++-- .../IdentitySection/IdentityOidcAuthForm.tsx | 69 ++++-- .../IdentitySection/IdentityTokenAuthForm.tsx | 57 +++-- .../IdentityUniversalAuthForm.tsx | 56 +++-- 8 files changed, 444 insertions(+), 220 deletions(-) diff --git a/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityAuthMethodModal.tsx b/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityAuthMethodModal.tsx index b144c9cc8..cf5774c0f 100644 --- a/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityAuthMethodModal.tsx +++ b/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityAuthMethodModal.tsx @@ -54,7 +54,7 @@ const identityAuthMethods = [ const schema = yup .object({ - authMethod: yup.string().required("Auth method is required") + authMethod: yup.mixed().oneOf(Object.values(IdentityAuthMethod)).required("Auth method is required") }) .required(); @@ -71,21 +71,27 @@ export const IdentityAuthMethodModal = ({ popUp, handlePopUpOpen, handlePopUpTog const { mutateAsync: revokeAwsAuth } = useDeleteIdentityAwsAuth(); const { mutateAsync: revokeAzureAuth } = useDeleteIdentityAzureAuth(); const { mutateAsync: revokeOidcAuth } = useDeleteIdentityOidcAuth(); - - const { control, watch, setValue } = useForm({ - resolver: yupResolver(schema), - defaultValues: { - authMethod: IdentityAuthMethod.UNIVERSAL_AUTH - } - }); - - const identityAuthMethodData = popUp?.identityAuthMethod?.data as { - identityId: string; - name: string; - authMethod?: IdentityAuthMethod; + + const initialAuthMethod = popUp?.identityAuthMethod?.data?.authMethod; + + const { control, watch, setValue } = useForm({ + resolver: yupResolver(schema), + defaultValues: { + authMethod: initialAuthMethod + } + }); + + const identityAuthMethodData = { + identityId: popUp?.identityAuthMethod.data?.identityId, + name: popUp?.identityAuthMethod?.data?.name, + authMethod: watch("authMethod") + } as { + identityId: string; + name: string; + authMethod?: IdentityAuthMethod; }; - useEffect(() => { + useEffect(() => { if (identityAuthMethodData?.authMethod) { setValue("authMethod", identityAuthMethodData.authMethod); return; @@ -94,85 +100,11 @@ export const IdentityAuthMethodModal = ({ popUp, handlePopUpOpen, handlePopUpTog setValue("authMethod", IdentityAuthMethod.UNIVERSAL_AUTH); }, [identityAuthMethodData?.authMethod]); - const authMethod = watch("authMethod"); - - const renderIdentityAuthForm = () => { - switch (identityAuthMethodData?.authMethod ?? authMethod) { - case IdentityAuthMethod.AWS_AUTH: { - return ( - - ); - } - case IdentityAuthMethod.KUBERNETES_AUTH: { - return ( - - ); - } - case IdentityAuthMethod.GCP_AUTH: { - return ( - - ); - } - case IdentityAuthMethod.AZURE_AUTH: { - return ( - - ); - } - case IdentityAuthMethod.UNIVERSAL_AUTH: { - return ( - - ); - } - case IdentityAuthMethod.OIDC_AUTH: { - return ( - - ); - } - case IdentityAuthMethod.TOKEN_AUTH: { - return ( - - ); - } - default: { - return
; - } - } - }; - - const onRevokeAuthMethodSubmit = async () => { - if (!identityAuthMethodData.authMethod) return; - if (!orgId) return; + const onRevokeAuthMethodSubmit = async (authMethod: IdentityAuthMethod) => { + if (!orgId || !authMethod) return; try { console.log("onRevokeAuthMethodSubmit identityId: ", identityAuthMethodData); - switch (identityAuthMethodData.authMethod) { + switch (authMethod) { case IdentityAuthMethod.UNIVERSAL_AUTH: { await revokeUniversalAuth({ identityId: identityAuthMethodData.identityId, @@ -228,7 +160,7 @@ export const IdentityAuthMethodModal = ({ popUp, handlePopUpOpen, handlePopUpTog createNotification({ text: `Successfully removed ${ - identityAuthToNameMap[identityAuthMethodData.authMethod] + identityAuthToNameMap[authMethod] } on ${identityAuthMethodData.name}`, type: "success" }); @@ -238,13 +170,97 @@ export const IdentityAuthMethodModal = ({ popUp, handlePopUpOpen, handlePopUpTog } catch (err) { console.error(err); createNotification({ - text: `Failed to remove ${identityAuthToNameMap[identityAuthMethodData.authMethod]} on ${ + text: `Failed to remove ${identityAuthToNameMap[authMethod]} on ${ identityAuthMethodData.name }`, type: "error" }); } }; + const renderIdentityAuthForm = () => { + switch (identityAuthMethodData.authMethod) { + case IdentityAuthMethod.AWS_AUTH: { + return ( + + ); + } + case IdentityAuthMethod.KUBERNETES_AUTH: { + return ( + + ); + } + case IdentityAuthMethod.GCP_AUTH: { + return ( + + ); + } + case IdentityAuthMethod.AZURE_AUTH: { + return ( + + ); + } + case IdentityAuthMethod.UNIVERSAL_AUTH: { + return ( + + ); + } + case IdentityAuthMethod.OIDC_AUTH: { + return ( + + ); + } + case IdentityAuthMethod.TOKEN_AUTH: { + return ( + + ); + } + default: { + return
; + } + } + }; return ( onChange(e)} + onValueChange={(e) => {onChange(e)}} className="w-full" - isDisabled={!!identityAuthMethodData?.authMethod} > {identityAuthMethods.map(({ label, value }) => ( @@ -295,7 +310,7 @@ export const IdentityAuthMethodModal = ({ popUp, handlePopUpOpen, handlePopUpTog } on ${identityAuthMethodData?.name ?? ""}?`} onChange={(isOpen) => handlePopUpToggle("revokeAuthMethod", isOpen)} deleteKey="confirm" - onDeleteApproved={onRevokeAuthMethodSubmit} + onDeleteApproved={() => onRevokeAuthMethodSubmit(identityAuthMethodData.authMethod!)} /> diff --git a/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityAwsAuthForm.tsx b/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityAwsAuthForm.tsx index d56f4b738..54c148616 100644 --- a/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityAwsAuthForm.tsx +++ b/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityAwsAuthForm.tsx @@ -6,7 +6,7 @@ import { yupResolver } from "@hookform/resolvers/yup"; import * as yup from "yup"; import { createNotification } from "@app/components/notifications"; -import { Button, FormControl, IconButton, Input } from "@app/components/v2"; +import { Button, DeleteActionModal, FormControl, IconButton, Input } from "@app/components/v2"; import { useOrganization, useSubscription } from "@app/context"; import { useAddIdentityAwsAuth, @@ -15,7 +15,7 @@ import { } 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 { usePopUp, UsePopUpState } from "@app/hooks/usePopUp"; const schema = yup .object({ @@ -64,12 +64,16 @@ type Props = { name: string; authMethod?: IdentityAuthMethod; }; + initialAuthMethod: IdentityAuthMethod; + revokeAuth: (authMethod: IdentityAuthMethod) => Promise; }; export const IdentityAwsAuthForm = ({ handlePopUpOpen, handlePopUpToggle, - identityAuthMethodData + identityAuthMethodData, + initialAuthMethod, + revokeAuth }: Props) => { const { currentOrg } = useOrganization(); const orgId = currentOrg?.id || ""; @@ -80,6 +84,10 @@ export const IdentityAwsAuthForm = ({ const { data } = useGetIdentityAwsAuth(identityAuthMethodData?.identityId ?? ""); + const popup = usePopUp([ + "overwriteAuthMethod", + ] as const); + const { control, handleSubmit, @@ -175,9 +183,8 @@ export const IdentityAwsAuthForm = ({ handlePopUpToggle("identityAuthMethod", false); createNotification({ - text: `Successfully ${ - identityAuthMethodData?.authMethod ? "updated" : "configured" - } auth method`, + text: `Successfully ${identityAuthMethodData?.authMethod === initialAuthMethod ? "updated" : "configured" + } auth method`, type: "success" }); @@ -345,15 +352,24 @@ export const IdentityAwsAuthForm = ({
- + {(initialAuthMethod && identityAuthMethodData?.authMethod !== initialAuthMethod) ? + + : + }
- {identityAuthMethodData?.authMethod && ( + {identityAuthMethodData?.authMethod === initialAuthMethod && (
+ popup.handlePopUpToggle("overwriteAuthMethod", isOpen)} + deleteKey="confirm" + onDeleteApproved={async () => { await revokeAuth(initialAuthMethod); handleSubmit(onFormSubmit)(); }} + /> ); }; diff --git a/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityAzureAuthForm.tsx b/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityAzureAuthForm.tsx index a3902d120..ec15e556d 100644 --- a/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityAzureAuthForm.tsx +++ b/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityAzureAuthForm.tsx @@ -6,7 +6,7 @@ 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, DeleteActionModal, FormControl, IconButton, Input } from "@app/components/v2"; import { useOrganization, useSubscription } from "@app/context"; import { useAddIdentityAzureAuth, @@ -15,11 +15,11 @@ import { } 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 { usePopUp, UsePopUpState } from "@app/hooks/usePopUp"; const schema = z .object({ - tenantId: z.string(), + tenantId: z.string().min(1), resource: z.string(), allowedServicePrincipalIds: z.string(), accessTokenTTL: z.string().refine((val) => Number(val) <= 315360000, { @@ -52,12 +52,16 @@ type Props = { name: string; authMethod?: IdentityAuthMethod; }; + initialAuthMethod: IdentityAuthMethod; + revokeAuth: (authMethod: IdentityAuthMethod) => Promise; }; export const IdentityAzureAuthForm = ({ handlePopUpOpen, handlePopUpToggle, - identityAuthMethodData + identityAuthMethodData, + initialAuthMethod, + revokeAuth }: Props) => { const { currentOrg } = useOrganization(); const orgId = currentOrg?.id || ""; @@ -68,10 +72,15 @@ export const IdentityAzureAuthForm = ({ const { data } = useGetIdentityAzureAuth(identityAuthMethodData?.identityId ?? ""); + const popup = usePopUp([ + "overwriteAuthMethod", + ] as const); + const { control, handleSubmit, reset, + trigger, formState: { isSubmitting } } = useForm({ resolver: zodResolver(schema), @@ -163,9 +172,8 @@ export const IdentityAzureAuthForm = ({ handlePopUpToggle("identityAuthMethod", false); createNotification({ - text: `Successfully ${ - identityAuthMethodData?.authMethod ? "updated" : "configured" - } auth method`, + text: `Successfully ${identityAuthMethodData?.authMethod === initialAuthMethod ? "updated" : "configured" + } auth method`, type: "success" }); @@ -333,15 +341,23 @@ export const IdentityAzureAuthForm = ({
- + {(initialAuthMethod && identityAuthMethodData?.authMethod !== initialAuthMethod) ? + + : + }
- {identityAuthMethodData?.authMethod && ( + {identityAuthMethodData?.authMethod === initialAuthMethod && (
+ popup.handlePopUpToggle("overwriteAuthMethod", isOpen)} + deleteKey="confirm" + onDeleteApproved={async () => { + const result = await trigger(); + if(result){ + await revokeAuth(initialAuthMethod); + handleSubmit(onFormSubmit)(); + }else{ + createNotification({ + text: "Please fill in all required fields", + type: "error" + }); + popup.handlePopUpToggle("overwriteAuthMethod", false); + } + }} + /> + ); }; diff --git a/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityGcpAuthForm.tsx b/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityGcpAuthForm.tsx index a0834b3ae..4c59f46fa 100644 --- a/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityGcpAuthForm.tsx +++ b/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityGcpAuthForm.tsx @@ -6,7 +6,7 @@ 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, DeleteActionModal, FormControl, IconButton, Input, Select, SelectItem } from "@app/components/v2"; import { useOrganization, useSubscription } from "@app/context"; import { useAddIdentityGcpAuth, @@ -15,7 +15,7 @@ import { } 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 { usePopUp, UsePopUpState } from "@app/hooks/usePopUp"; const schema = z .object({ @@ -53,12 +53,16 @@ type Props = { name: string; authMethod?: IdentityAuthMethod; }; + initialAuthMethod: IdentityAuthMethod; + revokeAuth: (authMethod: IdentityAuthMethod) => Promise; }; export const IdentityGcpAuthForm = ({ handlePopUpOpen, handlePopUpToggle, - identityAuthMethodData + identityAuthMethodData, + revokeAuth, + initialAuthMethod }: Props) => { const { currentOrg } = useOrganization(); const orgId = currentOrg?.id || ""; @@ -68,13 +72,16 @@ export const IdentityGcpAuthForm = ({ const { mutateAsync: updateMutateAsync } = useUpdateIdentityGcpAuth(); const { data } = useGetIdentityGcpAuth(identityAuthMethodData?.identityId ?? ""); + const popup = usePopUp([ + "overwriteAuthMethod", + ] as const); const { control, handleSubmit, reset, formState: { isSubmitting }, - watch + watch, } = useForm({ resolver: zodResolver(schema), defaultValues: { @@ -100,7 +107,7 @@ export const IdentityGcpAuthForm = ({ useEffect(() => { if (data) { reset({ - type: data.type, + type: data.type || "gce", allowedServiceAccounts: data.allowedServiceAccounts, allowedProjects: data.allowedProjects, allowedZones: data.allowedZones, @@ -117,7 +124,7 @@ export const IdentityGcpAuthForm = ({ }); } else { reset({ - type: "iam", + type: "gce", allowedServiceAccounts: "", allowedProjects: "", allowedZones: "", @@ -173,12 +180,12 @@ export const IdentityGcpAuthForm = ({ handlePopUpToggle("identityAuthMethod", false); createNotification({ - text: `Successfully ${ - identityAuthMethodData?.authMethod ? "updated" : "configured" - } auth method`, + text: `Successfully ${identityAuthMethodData?.authMethod === initialAuthMethod ? "updated" : "configured" + } auth method`, type: "success" }); + reset(); } catch (err) { createNotification({ @@ -201,10 +208,10 @@ export const IdentityGcpAuthForm = ({ onValueChange={(e) => onChange(e)} className="w-full" > - + GCP ID Token Auth (Recommended) - + GCP IAM Auth @@ -367,15 +374,24 @@ export const IdentityGcpAuthForm = ({
- + {(initialAuthMethod && identityAuthMethodData?.authMethod !== initialAuthMethod) ? + + : + }
- {identityAuthMethodData?.authMethod && ( + {identityAuthMethodData?.authMethod === initialAuthMethod && (
+ popup.handlePopUpToggle("overwriteAuthMethod", isOpen)} + deleteKey="confirm" + onDeleteApproved={async () => { await revokeAuth(initialAuthMethod); handleSubmit(onFormSubmit)(); }} + /> ); }; diff --git a/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityKubernetesAuthForm.tsx b/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityKubernetesAuthForm.tsx index 44bb2d8c9..adcf93cbe 100644 --- a/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityKubernetesAuthForm.tsx +++ b/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityKubernetesAuthForm.tsx @@ -6,7 +6,7 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; import { createNotification } from "@app/components/notifications"; -import { Button, FormControl, IconButton, Input, TextArea } from "@app/components/v2"; +import { Button, DeleteActionModal, FormControl, IconButton, Input, TextArea } from "@app/components/v2"; import { useOrganization, useSubscription } from "@app/context"; import { useAddIdentityKubernetesAuth, @@ -15,12 +15,12 @@ import { } 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 { usePopUp, UsePopUpState } from "@app/hooks/usePopUp"; const schema = z .object({ - kubernetesHost: z.string(), - tokenReviewerJwt: z.string(), + kubernetesHost: z.string().min(1), + tokenReviewerJwt: z.string().min(1), allowedNames: z.string(), allowedNamespaces: z.string(), allowedAudience: z.string(), @@ -55,12 +55,16 @@ type Props = { name: string; authMethod?: IdentityAuthMethod; }; + initialAuthMethod: IdentityAuthMethod; + revokeAuth: (authMethod: IdentityAuthMethod) => Promise; }; export const IdentityKubernetesAuthForm = ({ handlePopUpOpen, handlePopUpToggle, - identityAuthMethodData + identityAuthMethodData, + initialAuthMethod, + revokeAuth }: Props) => { const { currentOrg } = useOrganization(); const orgId = currentOrg?.id || ""; @@ -70,12 +74,16 @@ export const IdentityKubernetesAuthForm = ({ const { mutateAsync: updateMutateAsync } = useUpdateIdentityKubernetesAuth(); const { data } = useGetIdentityKubernetesAuth(identityAuthMethodData?.identityId ?? ""); + const popup = usePopUp([ + "overwriteAuthMethod", + ] as const); const { control, handleSubmit, reset, - formState: { isSubmitting } + trigger, + formState: { isSubmitting }, } = useForm({ resolver: zodResolver(schema), defaultValues: { @@ -184,9 +192,8 @@ export const IdentityKubernetesAuthForm = ({ handlePopUpToggle("identityAuthMethod", false); createNotification({ - text: `Successfully ${ - identityAuthMethodData?.authMethod ? "updated" : "configured" - } auth method`, + text: `Successfully ${identityAuthMethodData?.authMethod === initialAuthMethod ? "updated" : "configured" + } auth method`, type: "success" }); @@ -404,15 +411,24 @@ export const IdentityKubernetesAuthForm = ({
- + {(initialAuthMethod && identityAuthMethodData?.authMethod !== initialAuthMethod) ? + + : + }
- {identityAuthMethodData?.authMethod && ( + {identityAuthMethodData?.authMethod === initialAuthMethod && (
+ popup.handlePopUpToggle("overwriteAuthMethod", isOpen)} + deleteKey="confirm" + onDeleteApproved={async () => { + const result = await trigger(); + if(result){ + await revokeAuth(initialAuthMethod); + handleSubmit(onFormSubmit)(); + }else{ + createNotification({ + text: "Please fill in all required fields", + type: "error" + }); + popup.handlePopUpToggle("overwriteAuthMethod", false); + } + }} + /> ); }; diff --git a/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityOidcAuthForm.tsx b/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityOidcAuthForm.tsx index fdfb17e0d..f35d1469b 100644 --- a/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityOidcAuthForm.tsx +++ b/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityOidcAuthForm.tsx @@ -7,13 +7,13 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; import { createNotification } from "@app/components/notifications"; -import { Button, FormControl, IconButton, Input, TextArea, Tooltip } from "@app/components/v2"; +import { Button, DeleteActionModal,FormControl, IconButton, Input, TextArea, Tooltip } from "@app/components/v2"; import { useOrganization, useSubscription } from "@app/context"; import { useAddIdentityOidcAuth, useUpdateIdentityOidcAuth } from "@app/hooks/api"; import { IdentityAuthMethod } from "@app/hooks/api/identities"; import { useGetIdentityOidcAuth } from "@app/hooks/api/identities/queries"; import { IdentityTrustedIp } from "@app/hooks/api/identities/types"; -import { UsePopUpState } from "@app/hooks/usePopUp"; +import { usePopUp, UsePopUpState } from "@app/hooks/usePopUp"; const schema = z.object({ accessTokenTrustedIps: z @@ -56,12 +56,16 @@ type Props = { name: string; authMethod?: IdentityAuthMethod; }; + initialAuthMethod: IdentityAuthMethod; + revokeAuth: (authMethod: IdentityAuthMethod) => Promise; }; export const IdentityOidcAuthForm = ({ handlePopUpOpen, handlePopUpToggle, - identityAuthMethodData + identityAuthMethodData, + initialAuthMethod, + revokeAuth }: Props) => { const { currentOrg } = useOrganization(); const orgId = currentOrg?.id || ""; @@ -71,11 +75,15 @@ export const IdentityOidcAuthForm = ({ const { mutateAsync: updateMutateAsync } = useUpdateIdentityOidcAuth(); const { data } = useGetIdentityOidcAuth(identityAuthMethodData?.identityId ?? ""); + const popup = usePopUp([ + "overwriteAuthMethod", + ] as const); const { control, handleSubmit, reset, + trigger, formState: { isSubmitting } } = useForm({ resolver: zodResolver(schema), @@ -193,9 +201,8 @@ export const IdentityOidcAuthForm = ({ handlePopUpToggle("identityAuthMethod", false); createNotification({ - text: `Successfully ${ - identityAuthMethodData?.authMethod ? "updated" : "configured" - } auth method`, + text: `Successfully ${identityAuthMethodData?.authMethod === initialAuthMethod ? "updated" : "configured" + } auth method`, type: "success" }); @@ -488,15 +495,24 @@ export const IdentityOidcAuthForm = ({
- + {(initialAuthMethod && identityAuthMethodData?.authMethod !== initialAuthMethod) ? + + : + }
- {identityAuthMethodData?.authMethod && ( + {identityAuthMethodData?.authMethod === initialAuthMethod && (
+ popup.handlePopUpToggle("overwriteAuthMethod", isOpen)} + deleteKey="confirm" + onDeleteApproved={async () => { + const result = await trigger(); + if(result){ + await revokeAuth(initialAuthMethod); + handleSubmit(onFormSubmit)(); + }else{ + createNotification({ + text: "Please fill in all required fields", + type: "error" + }); + popup.handlePopUpToggle("overwriteAuthMethod", false); + } + }} + /> ); }; diff --git a/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityTokenAuthForm.tsx b/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityTokenAuthForm.tsx index 4ce437fc1..4f3828a6e 100644 --- a/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityTokenAuthForm.tsx +++ b/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityTokenAuthForm.tsx @@ -5,7 +5,7 @@ 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, DeleteActionModal, FormControl, IconButton, Input } from "@app/components/v2"; import { useOrganization, useSubscription } from "@app/context"; import { useAddIdentityTokenAuth, @@ -13,7 +13,7 @@ import { useUpdateIdentityTokenAuth } from "@app/hooks/api"; import { IdentityAuthMethod } from "@app/hooks/api/identities"; -import { UsePopUpState } from "@app/hooks/usePopUp"; +import { usePopUp, UsePopUpState } from "@app/hooks/usePopUp"; const schema = z .object({ @@ -47,12 +47,16 @@ type Props = { name: string; authMethod?: IdentityAuthMethod; }; + initialAuthMethod: IdentityAuthMethod; + revokeAuth: (authMethod: IdentityAuthMethod) => Promise; }; export const IdentityTokenAuthForm = ({ handlePopUpOpen, handlePopUpToggle, - identityAuthMethodData + identityAuthMethodData, + initialAuthMethod, + revokeAuth }: Props) => { const { currentOrg } = useOrganization(); const orgId = currentOrg?.id || ""; @@ -62,6 +66,9 @@ export const IdentityTokenAuthForm = ({ const { mutateAsync: updateMutateAsync } = useUpdateIdentityTokenAuth(); const { data } = useGetIdentityTokenAuth(identityAuthMethodData?.identityId ?? ""); + const popup = usePopUp([ + "overwriteAuthMethod", + ] as const); const { control, @@ -116,16 +123,15 @@ export const IdentityTokenAuthForm = ({ handlePopUpToggle("identityAuthMethod", false); createNotification({ - text: `Successfully ${ - identityAuthMethodData?.authMethod ? "updated" : "configured" - } auth method`, + text: `Successfully ${identityAuthMethodData?.authMethod === initialAuthMethod ? "updated" : "configured" + } auth method`, type: "success" }); reset(); } catch (err) { createNotification({ - text: `Failed to ${identityAuthMethodData?.authMethod ? "update" : "configure"} identity`, + text: `Failed to ${identityAuthMethodData?.authMethod === initialAuthMethod ? "update" : "configure"} identity`, type: "error" }); } @@ -245,15 +251,23 @@ export const IdentityTokenAuthForm = ({
- + {(initialAuthMethod && identityAuthMethodData?.authMethod !== initialAuthMethod) ? + + : + }
- {identityAuthMethodData?.authMethod && ( + {identityAuthMethodData?.authMethod === initialAuthMethod && (
+ popup.handlePopUpToggle("overwriteAuthMethod", isOpen)} + deleteKey="confirm" + onDeleteApproved={async () => { await revokeAuth(initialAuthMethod); handleSubmit(onFormSubmit)(); }} + /> ); }; diff --git a/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityUniversalAuthForm.tsx b/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityUniversalAuthForm.tsx index cb8c3f580..e0cc6407e 100644 --- a/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityUniversalAuthForm.tsx +++ b/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityUniversalAuthForm.tsx @@ -6,7 +6,7 @@ import { yupResolver } from "@hookform/resolvers/yup"; import * as yup from "yup"; import { createNotification } from "@app/components/notifications"; -import { Button, FormControl, IconButton, Input } from "@app/components/v2"; +import { Button, DeleteActionModal, FormControl, IconButton, Input } from "@app/components/v2"; import { useOrganization, useSubscription } from "@app/context"; import { useAddIdentityUniversalAuth, @@ -15,7 +15,7 @@ import { } 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 { usePopUp, UsePopUpState } from "@app/hooks/usePopUp"; const schema = yup .object({ @@ -70,12 +70,16 @@ type Props = { name: string; authMethod?: IdentityAuthMethod; }; + initialAuthMethod: IdentityAuthMethod; + revokeAuth: (authMethod: IdentityAuthMethod) => Promise; }; export const IdentityUniversalAuthForm = ({ handlePopUpOpen, handlePopUpToggle, - identityAuthMethodData + identityAuthMethodData, + initialAuthMethod, + revokeAuth }: Props) => { const { currentOrg } = useOrganization(); const orgId = currentOrg?.id || ""; @@ -83,6 +87,9 @@ export const IdentityUniversalAuthForm = ({ const { mutateAsync: addMutateAsync } = useAddIdentityUniversalAuth(); const { mutateAsync: updateMutateAsync } = useUpdateIdentityUniversalAuth(); const { data } = useGetIdentityUniversalAuth(identityAuthMethodData?.identityId ?? ""); + const popup = usePopUp([ + "overwriteAuthMethod", + ] as const); const { control, @@ -181,9 +188,8 @@ export const IdentityUniversalAuthForm = ({ handlePopUpToggle("identityAuthMethod", false); createNotification({ - text: `Successfully ${ - identityAuthMethodData?.authMethod ? "updated" : "configured" - } auth method`, + text: `Successfully ${identityAuthMethodData?.authMethod === initialAuthMethod ? "updated" : "configured" + } auth method`, type: "success" }); @@ -384,15 +390,24 @@ export const IdentityUniversalAuthForm = ({
- + {(initialAuthMethod && identityAuthMethodData?.authMethod !== initialAuthMethod) ? + + : + }
- {identityAuthMethodData?.authMethod && ( + {identityAuthMethodData?.authMethod === initialAuthMethod && (
+ popup.handlePopUpToggle("overwriteAuthMethod", isOpen)} + deleteKey="confirm" + onDeleteApproved={async () => { await revokeAuth(initialAuthMethod); handleSubmit(onFormSubmit)(); }} + /> ); };