mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 23:27:35 +00:00
fix: address changes
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery, UseQueryOptions } from "@tanstack/react-query";
|
||||||
|
|
||||||
import { apiRequest } from "@app/config/request";
|
import { apiRequest } from "@app/config/request";
|
||||||
|
|
||||||
@@ -13,7 +13,8 @@ import {
|
|||||||
IdentityMembershipOrg,
|
IdentityMembershipOrg,
|
||||||
IdentityOidcAuth,
|
IdentityOidcAuth,
|
||||||
IdentityTokenAuth,
|
IdentityTokenAuth,
|
||||||
IdentityUniversalAuth} from "./types";
|
IdentityUniversalAuth
|
||||||
|
} from "./types";
|
||||||
|
|
||||||
export const identitiesKeys = {
|
export const identitiesKeys = {
|
||||||
getIdentityById: (identityId: string) => [{ identityId }, "identity"] as const,
|
getIdentityById: (identityId: string) => [{ identityId }, "identity"] as const,
|
||||||
@@ -64,9 +65,16 @@ export const useGetIdentityProjectMemberships = (identityId: string) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetIdentityUniversalAuth = (identityId: string) => {
|
export const useGetIdentityUniversalAuth = (
|
||||||
|
identityId: string,
|
||||||
|
options?: UseQueryOptions<
|
||||||
|
IdentityUniversalAuth,
|
||||||
|
unknown,
|
||||||
|
IdentityUniversalAuth,
|
||||||
|
ReturnType<typeof identitiesKeys.getIdentityUniversalAuth>
|
||||||
|
>
|
||||||
|
) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
enabled: Boolean(identityId),
|
|
||||||
queryKey: identitiesKeys.getIdentityUniversalAuth(identityId),
|
queryKey: identitiesKeys.getIdentityUniversalAuth(identityId),
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const {
|
const {
|
||||||
@@ -76,8 +84,10 @@ export const useGetIdentityUniversalAuth = (identityId: string) => {
|
|||||||
);
|
);
|
||||||
return identityUniversalAuth;
|
return identityUniversalAuth;
|
||||||
},
|
},
|
||||||
|
cacheTime: 0,
|
||||||
staleTime: 0,
|
staleTime: 0,
|
||||||
cacheTime: 0
|
...options,
|
||||||
|
enabled: Boolean(identityId) && (options?.enabled ?? true)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -96,9 +106,16 @@ export const useGetIdentityUniversalAuthClientSecrets = (identityId: string) =>
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetIdentityGcpAuth = (identityId: string) => {
|
export const useGetIdentityGcpAuth = (
|
||||||
|
identityId: string,
|
||||||
|
options?: UseQueryOptions<
|
||||||
|
IdentityGcpAuth,
|
||||||
|
unknown,
|
||||||
|
IdentityGcpAuth,
|
||||||
|
ReturnType<typeof identitiesKeys.getIdentityGcpAuth>
|
||||||
|
>
|
||||||
|
) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
enabled: Boolean(identityId),
|
|
||||||
queryKey: identitiesKeys.getIdentityGcpAuth(identityId),
|
queryKey: identitiesKeys.getIdentityGcpAuth(identityId),
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const {
|
const {
|
||||||
@@ -109,13 +126,22 @@ export const useGetIdentityGcpAuth = (identityId: string) => {
|
|||||||
return identityGcpAuth;
|
return identityGcpAuth;
|
||||||
},
|
},
|
||||||
staleTime: 0,
|
staleTime: 0,
|
||||||
cacheTime: 0
|
cacheTime: 0,
|
||||||
|
...options,
|
||||||
|
enabled: Boolean(identityId) && (options?.enabled ?? true)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetIdentityAwsAuth = (identityId: string) => {
|
export const useGetIdentityAwsAuth = (
|
||||||
|
identityId: string,
|
||||||
|
options?: UseQueryOptions<
|
||||||
|
IdentityAwsAuth,
|
||||||
|
unknown,
|
||||||
|
IdentityAwsAuth,
|
||||||
|
ReturnType<typeof identitiesKeys.getIdentityAwsAuth>
|
||||||
|
>
|
||||||
|
) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
enabled: Boolean(identityId),
|
|
||||||
queryKey: identitiesKeys.getIdentityAwsAuth(identityId),
|
queryKey: identitiesKeys.getIdentityAwsAuth(identityId),
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const {
|
const {
|
||||||
@@ -126,13 +152,22 @@ export const useGetIdentityAwsAuth = (identityId: string) => {
|
|||||||
return identityAwsAuth;
|
return identityAwsAuth;
|
||||||
},
|
},
|
||||||
staleTime: 0,
|
staleTime: 0,
|
||||||
cacheTime: 0
|
cacheTime: 0,
|
||||||
|
...options,
|
||||||
|
enabled: Boolean(identityId) && (options?.enabled ?? true)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetIdentityAzureAuth = (identityId: string) => {
|
export const useGetIdentityAzureAuth = (
|
||||||
|
identityId: string,
|
||||||
|
options?: UseQueryOptions<
|
||||||
|
IdentityAzureAuth,
|
||||||
|
unknown,
|
||||||
|
IdentityAzureAuth,
|
||||||
|
ReturnType<typeof identitiesKeys.getIdentityAzureAuth>
|
||||||
|
>
|
||||||
|
) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
enabled: Boolean(identityId),
|
|
||||||
queryKey: identitiesKeys.getIdentityAzureAuth(identityId),
|
queryKey: identitiesKeys.getIdentityAzureAuth(identityId),
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const {
|
const {
|
||||||
@@ -143,13 +178,22 @@ export const useGetIdentityAzureAuth = (identityId: string) => {
|
|||||||
return identityAzureAuth;
|
return identityAzureAuth;
|
||||||
},
|
},
|
||||||
staleTime: 0,
|
staleTime: 0,
|
||||||
cacheTime: 0
|
cacheTime: 0,
|
||||||
|
...options,
|
||||||
|
enabled: Boolean(identityId) && (options?.enabled ?? true)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetIdentityKubernetesAuth = (identityId: string) => {
|
export const useGetIdentityKubernetesAuth = (
|
||||||
|
identityId: string,
|
||||||
|
options?: UseQueryOptions<
|
||||||
|
IdentityKubernetesAuth,
|
||||||
|
unknown,
|
||||||
|
IdentityKubernetesAuth,
|
||||||
|
ReturnType<typeof identitiesKeys.getIdentityKubernetesAuth>
|
||||||
|
>
|
||||||
|
) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
enabled: Boolean(identityId),
|
|
||||||
queryKey: identitiesKeys.getIdentityKubernetesAuth(identityId),
|
queryKey: identitiesKeys.getIdentityKubernetesAuth(identityId),
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const {
|
const {
|
||||||
@@ -160,13 +204,22 @@ export const useGetIdentityKubernetesAuth = (identityId: string) => {
|
|||||||
return identityKubernetesAuth;
|
return identityKubernetesAuth;
|
||||||
},
|
},
|
||||||
staleTime: 0,
|
staleTime: 0,
|
||||||
cacheTime: 0
|
cacheTime: 0,
|
||||||
|
...options,
|
||||||
|
enabled: Boolean(identityId) && (options?.enabled ?? true)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetIdentityTokenAuth = (identityId: string) => {
|
export const useGetIdentityTokenAuth = (
|
||||||
|
identityId: string,
|
||||||
|
options?: UseQueryOptions<
|
||||||
|
IdentityTokenAuth,
|
||||||
|
unknown,
|
||||||
|
IdentityTokenAuth,
|
||||||
|
ReturnType<typeof identitiesKeys.getIdentityTokenAuth>
|
||||||
|
>
|
||||||
|
) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
enabled: Boolean(identityId),
|
|
||||||
queryKey: identitiesKeys.getIdentityTokenAuth(identityId),
|
queryKey: identitiesKeys.getIdentityTokenAuth(identityId),
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const {
|
const {
|
||||||
@@ -177,7 +230,9 @@ export const useGetIdentityTokenAuth = (identityId: string) => {
|
|||||||
return identityTokenAuth;
|
return identityTokenAuth;
|
||||||
},
|
},
|
||||||
staleTime: 0,
|
staleTime: 0,
|
||||||
cacheTime: 0
|
cacheTime: 0,
|
||||||
|
...options,
|
||||||
|
enabled: Boolean(identityId) && (options?.enabled ?? true)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -196,9 +251,16 @@ export const useGetIdentityTokensTokenAuth = (identityId: string) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetIdentityOidcAuth = (identityId: string) => {
|
export const useGetIdentityOidcAuth = (
|
||||||
|
identityId: string,
|
||||||
|
options?: UseQueryOptions<
|
||||||
|
IdentityOidcAuth,
|
||||||
|
unknown,
|
||||||
|
IdentityOidcAuth,
|
||||||
|
ReturnType<typeof identitiesKeys.getIdentityOidcAuth>
|
||||||
|
>
|
||||||
|
) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
enabled: Boolean(identityId),
|
|
||||||
queryKey: identitiesKeys.getIdentityOidcAuth(identityId),
|
queryKey: identitiesKeys.getIdentityOidcAuth(identityId),
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const {
|
const {
|
||||||
@@ -209,6 +271,8 @@ export const useGetIdentityOidcAuth = (identityId: string) => {
|
|||||||
return identityOidcAuth;
|
return identityOidcAuth;
|
||||||
},
|
},
|
||||||
staleTime: 0,
|
staleTime: 0,
|
||||||
cacheTime: 0
|
cacheTime: 0,
|
||||||
|
...options,
|
||||||
|
enabled: Boolean(identityId) && (options?.enabled ?? true)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
+39
-29
@@ -21,7 +21,8 @@ import {
|
|||||||
useDeleteIdentityKubernetesAuth,
|
useDeleteIdentityKubernetesAuth,
|
||||||
useDeleteIdentityOidcAuth,
|
useDeleteIdentityOidcAuth,
|
||||||
useDeleteIdentityTokenAuth,
|
useDeleteIdentityTokenAuth,
|
||||||
useDeleteIdentityUniversalAuth} from "@app/hooks/api";
|
useDeleteIdentityUniversalAuth
|
||||||
|
} from "@app/hooks/api";
|
||||||
import { IdentityAuthMethod, identityAuthToNameMap } from "@app/hooks/api/identities";
|
import { IdentityAuthMethod, identityAuthToNameMap } from "@app/hooks/api/identities";
|
||||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||||
|
|
||||||
@@ -54,7 +55,10 @@ const identityAuthMethods = [
|
|||||||
|
|
||||||
const schema = yup
|
const schema = yup
|
||||||
.object({
|
.object({
|
||||||
authMethod: yup.mixed<IdentityAuthMethod>().oneOf(Object.values(IdentityAuthMethod)).required("Auth method is required")
|
authMethod: yup
|
||||||
|
.mixed<IdentityAuthMethod>()
|
||||||
|
.oneOf(Object.values(IdentityAuthMethod))
|
||||||
|
.required("Auth method is required")
|
||||||
})
|
})
|
||||||
.required();
|
.required();
|
||||||
|
|
||||||
@@ -71,27 +75,33 @@ export const IdentityAuthMethodModal = ({ popUp, handlePopUpOpen, handlePopUpTog
|
|||||||
const { mutateAsync: revokeAwsAuth } = useDeleteIdentityAwsAuth();
|
const { mutateAsync: revokeAwsAuth } = useDeleteIdentityAwsAuth();
|
||||||
const { mutateAsync: revokeAzureAuth } = useDeleteIdentityAzureAuth();
|
const { mutateAsync: revokeAzureAuth } = useDeleteIdentityAzureAuth();
|
||||||
const { mutateAsync: revokeOidcAuth } = useDeleteIdentityOidcAuth();
|
const { mutateAsync: revokeOidcAuth } = useDeleteIdentityOidcAuth();
|
||||||
|
|
||||||
const initialAuthMethod = popUp?.identityAuthMethod?.data?.authMethod;
|
const initialAuthMethod = popUp?.identityAuthMethod?.data?.authMethod;
|
||||||
|
|
||||||
const { control, watch, setValue } = useForm<FormData>({
|
const { control, watch, setValue, reset } = useForm<FormData>({
|
||||||
resolver: yupResolver(schema),
|
resolver: yupResolver(schema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
authMethod: initialAuthMethod
|
authMethod: initialAuthMethod
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const identityAuthMethodData = {
|
useEffect(() => {
|
||||||
identityId: popUp?.identityAuthMethod.data?.identityId,
|
// reset form on open
|
||||||
name: popUp?.identityAuthMethod?.data?.name,
|
if (popUp.identityAuthMethod.isOpen)
|
||||||
authMethod: watch("authMethod")
|
reset({ authMethod: popUp?.identityAuthMethod?.data?.authMethod });
|
||||||
} as {
|
}, [popUp.identityAuthMethod.isOpen]);
|
||||||
identityId: string;
|
|
||||||
name: string;
|
const identityAuthMethodData = {
|
||||||
authMethod?: IdentityAuthMethod;
|
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) {
|
if (identityAuthMethodData?.authMethod) {
|
||||||
setValue("authMethod", identityAuthMethodData.authMethod);
|
setValue("authMethod", identityAuthMethodData.authMethod);
|
||||||
return;
|
return;
|
||||||
@@ -103,7 +113,6 @@ export const IdentityAuthMethodModal = ({ popUp, handlePopUpOpen, handlePopUpTog
|
|||||||
const onRevokeAuthMethodSubmit = async (authMethod: IdentityAuthMethod) => {
|
const onRevokeAuthMethodSubmit = async (authMethod: IdentityAuthMethod) => {
|
||||||
if (!orgId || !authMethod) return;
|
if (!orgId || !authMethod) return;
|
||||||
try {
|
try {
|
||||||
console.log("onRevokeAuthMethodSubmit identityId: ", identityAuthMethodData);
|
|
||||||
switch (authMethod) {
|
switch (authMethod) {
|
||||||
case IdentityAuthMethod.UNIVERSAL_AUTH: {
|
case IdentityAuthMethod.UNIVERSAL_AUTH: {
|
||||||
await revokeUniversalAuth({
|
await revokeUniversalAuth({
|
||||||
@@ -159,9 +168,7 @@ export const IdentityAuthMethodModal = ({ popUp, handlePopUpOpen, handlePopUpTog
|
|||||||
}
|
}
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
text: `Successfully removed ${
|
text: `Successfully removed ${identityAuthToNameMap[authMethod]} on ${identityAuthMethodData.name}`,
|
||||||
identityAuthToNameMap[authMethod]
|
|
||||||
} on ${identityAuthMethodData.name}`,
|
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -170,9 +177,7 @@ export const IdentityAuthMethodModal = ({ popUp, handlePopUpOpen, handlePopUpTog
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
createNotification({
|
createNotification({
|
||||||
text: `Failed to remove ${identityAuthToNameMap[authMethod]} on ${
|
text: `Failed to remove ${identityAuthToNameMap[authMethod]} on ${identityAuthMethodData.name}`,
|
||||||
identityAuthMethodData.name
|
|
||||||
}`,
|
|
||||||
type: "error"
|
type: "error"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -272,7 +277,9 @@ export const IdentityAuthMethodModal = ({ popUp, handlePopUpOpen, handlePopUpTog
|
|||||||
<ModalContent
|
<ModalContent
|
||||||
title={`${
|
title={`${
|
||||||
identityAuthMethodData.authMethod === initialAuthMethod ? "Update" : "Configure"
|
identityAuthMethodData.authMethod === initialAuthMethod ? "Update" : "Configure"
|
||||||
} Identity Auth Method for ${identityAuthToNameMap[identityAuthMethodData.authMethod!] ?? ""}`}
|
} Identity Auth Method for ${
|
||||||
|
identityAuthToNameMap[identityAuthMethodData.authMethod!] ?? ""
|
||||||
|
}`}
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
@@ -283,7 +290,9 @@ export const IdentityAuthMethodModal = ({ popUp, handlePopUpOpen, handlePopUpTog
|
|||||||
<Select
|
<Select
|
||||||
defaultValue={field.value}
|
defaultValue={field.value}
|
||||||
{...field}
|
{...field}
|
||||||
onValueChange={(e) => {onChange(e)}}
|
onValueChange={(e) => {
|
||||||
|
onChange(e);
|
||||||
|
}}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
>
|
>
|
||||||
{identityAuthMethods.map(({ label, value }) => (
|
{identityAuthMethods.map(({ label, value }) => (
|
||||||
@@ -310,6 +319,7 @@ export const IdentityAuthMethodModal = ({ popUp, handlePopUpOpen, handlePopUpTog
|
|||||||
} on ${identityAuthMethodData?.name ?? ""}?`}
|
} on ${identityAuthMethodData?.name ?? ""}?`}
|
||||||
onChange={(isOpen) => handlePopUpToggle("revokeAuthMethod", isOpen)}
|
onChange={(isOpen) => handlePopUpToggle("revokeAuthMethod", isOpen)}
|
||||||
deleteKey="confirm"
|
deleteKey="confirm"
|
||||||
|
buttonText="Remove"
|
||||||
onDeleteApproved={() => onRevokeAuthMethodSubmit(identityAuthMethodData.authMethod!)}
|
onDeleteApproved={() => onRevokeAuthMethodSubmit(identityAuthMethodData.authMethod!)}
|
||||||
/>
|
/>
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
|
|||||||
+199
-190
@@ -82,11 +82,12 @@ export const IdentityAwsAuthForm = ({
|
|||||||
const { mutateAsync: addMutateAsync } = useAddIdentityAwsAuth();
|
const { mutateAsync: addMutateAsync } = useAddIdentityAwsAuth();
|
||||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityAwsAuth();
|
const { mutateAsync: updateMutateAsync } = useUpdateIdentityAwsAuth();
|
||||||
|
|
||||||
const { data } = useGetIdentityAwsAuth(identityAuthMethodData?.identityId ?? "");
|
const isCurrentAuthMethod = identityAuthMethodData?.authMethod === initialAuthMethod;
|
||||||
|
const { data } = useGetIdentityAwsAuth(identityAuthMethodData?.identityId ?? "", {
|
||||||
|
enabled: isCurrentAuthMethod
|
||||||
|
});
|
||||||
|
|
||||||
const popup = usePopUp([
|
const internalPopUpState = usePopUp(["overwriteAuthMethod"] as const);
|
||||||
"overwriteAuthMethod",
|
|
||||||
] as const);
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
@@ -183,8 +184,7 @@ export const IdentityAwsAuthForm = ({
|
|||||||
handlePopUpToggle("identityAuthMethod", false);
|
handlePopUpToggle("identityAuthMethod", false);
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
text: `Successfully ${identityAuthMethodData?.authMethod === initialAuthMethod ? "updated" : "configured"
|
text: `Successfully ${isCurrentAuthMethod ? "updated" : "configured"} auth method`,
|
||||||
} auth method`,
|
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -198,207 +198,216 @@ export const IdentityAwsAuthForm = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit(onFormSubmit)}>
|
<>
|
||||||
<Controller
|
<form onSubmit={handleSubmit(onFormSubmit)}>
|
||||||
control={control}
|
<Controller
|
||||||
defaultValue="2592000"
|
control={control}
|
||||||
name="allowedPrincipalArns"
|
defaultValue="2592000"
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="allowedPrincipalArns"
|
||||||
<FormControl
|
render={({ field, fieldState: { error } }) => (
|
||||||
label="Allowed Principal ARNs"
|
<FormControl
|
||||||
isError={Boolean(error)}
|
label="Allowed Principal ARNs"
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
>
|
errorText={error?.message}
|
||||||
<Input
|
>
|
||||||
{...field}
|
<Input
|
||||||
placeholder="arn:aws:iam::123456789012:role/MyRoleName, arn:aws:iam::123456789012:user/MyUserName..."
|
{...field}
|
||||||
type="text"
|
placeholder="arn:aws:iam::123456789012:role/MyRoleName, arn:aws:iam::123456789012:user/MyUserName..."
|
||||||
/>
|
type="text"
|
||||||
</FormControl>
|
/>
|
||||||
)}
|
</FormControl>
|
||||||
/>
|
)}
|
||||||
<Controller
|
/>
|
||||||
control={control}
|
<Controller
|
||||||
name="allowedAccountIds"
|
control={control}
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="allowedAccountIds"
|
||||||
<FormControl
|
render={({ field, fieldState: { error } }) => (
|
||||||
label="Allowed Account IDs"
|
<FormControl
|
||||||
isError={Boolean(error)}
|
label="Allowed Account IDs"
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
>
|
errorText={error?.message}
|
||||||
<Input {...field} placeholder="123456789012, ..." />
|
>
|
||||||
</FormControl>
|
<Input {...field} placeholder="123456789012, ..." />
|
||||||
)}
|
</FormControl>
|
||||||
/>
|
)}
|
||||||
<Controller
|
/>
|
||||||
control={control}
|
<Controller
|
||||||
defaultValue="https://sts.amazonaws.com/"
|
control={control}
|
||||||
name="stsEndpoint"
|
defaultValue="https://sts.amazonaws.com/"
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="stsEndpoint"
|
||||||
<FormControl label="STS Endpoint" isError={Boolean(error)} errorText={error?.message}>
|
render={({ field, fieldState: { error } }) => (
|
||||||
<Input {...field} placeholder="https://sts.amazonaws.com/" type="text" />
|
<FormControl label="STS Endpoint" isError={Boolean(error)} errorText={error?.message}>
|
||||||
</FormControl>
|
<Input {...field} placeholder="https://sts.amazonaws.com/" type="text" />
|
||||||
)}
|
</FormControl>
|
||||||
/>
|
)}
|
||||||
<Controller
|
/>
|
||||||
control={control}
|
<Controller
|
||||||
defaultValue="2592000"
|
control={control}
|
||||||
name="accessTokenTTL"
|
defaultValue="2592000"
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="accessTokenTTL"
|
||||||
<FormControl
|
render={({ field, fieldState: { error } }) => (
|
||||||
label="Access Token TTL (seconds)"
|
<FormControl
|
||||||
isError={Boolean(error)}
|
label="Access Token TTL (seconds)"
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
>
|
errorText={error?.message}
|
||||||
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
>
|
||||||
</FormControl>
|
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
||||||
)}
|
</FormControl>
|
||||||
/>
|
)}
|
||||||
<Controller
|
/>
|
||||||
control={control}
|
<Controller
|
||||||
defaultValue="2592000"
|
control={control}
|
||||||
name="accessTokenMaxTTL"
|
defaultValue="2592000"
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="accessTokenMaxTTL"
|
||||||
<FormControl
|
render={({ field, fieldState: { error } }) => (
|
||||||
label="Access Token Max TTL (seconds)"
|
<FormControl
|
||||||
isError={Boolean(error)}
|
label="Access Token Max TTL (seconds)"
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
>
|
errorText={error?.message}
|
||||||
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
>
|
||||||
</FormControl>
|
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
||||||
)}
|
</FormControl>
|
||||||
/>
|
)}
|
||||||
<Controller
|
/>
|
||||||
control={control}
|
<Controller
|
||||||
defaultValue="0"
|
control={control}
|
||||||
name="accessTokenNumUsesLimit"
|
defaultValue="0"
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="accessTokenNumUsesLimit"
|
||||||
<FormControl
|
render={({ field, fieldState: { error } }) => (
|
||||||
label="Access Token Max Number of Uses"
|
<FormControl
|
||||||
isError={Boolean(error)}
|
label="Access Token Max Number of Uses"
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
>
|
errorText={error?.message}
|
||||||
<Input {...field} placeholder="0" type="number" min="0" step="1" />
|
>
|
||||||
</FormControl>
|
<Input {...field} placeholder="0" type="number" min="0" step="1" />
|
||||||
)}
|
</FormControl>
|
||||||
/>
|
)}
|
||||||
{accessTokenTrustedIpsFields.map(({ id }, index) => (
|
/>
|
||||||
<div className="mb-3 flex items-end space-x-2" key={id}>
|
{accessTokenTrustedIpsFields.map(({ id }, index) => (
|
||||||
<Controller
|
<div className="mb-3 flex items-end space-x-2" key={id}>
|
||||||
control={control}
|
<Controller
|
||||||
name={`accessTokenTrustedIps.${index}.ipAddress`}
|
control={control}
|
||||||
defaultValue="0.0.0.0/0"
|
name={`accessTokenTrustedIps.${index}.ipAddress`}
|
||||||
render={({ field, fieldState: { error } }) => {
|
defaultValue="0.0.0.0/0"
|
||||||
return (
|
render={({ field, fieldState: { error } }) => {
|
||||||
<FormControl
|
return (
|
||||||
className="mb-0 flex-grow"
|
<FormControl
|
||||||
label={index === 0 ? "Access Token Trusted IPs" : undefined}
|
className="mb-0 flex-grow"
|
||||||
isError={Boolean(error)}
|
label={index === 0 ? "Access Token Trusted IPs" : undefined}
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
>
|
errorText={error?.message}
|
||||||
<Input
|
>
|
||||||
value={field.value}
|
<Input
|
||||||
onChange={(e) => {
|
value={field.value}
|
||||||
if (subscription?.ipAllowlisting) {
|
onChange={(e) => {
|
||||||
field.onChange(e);
|
if (subscription?.ipAllowlisting) {
|
||||||
return;
|
field.onChange(e);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
handlePopUpOpen("upgradePlan");
|
handlePopUpOpen("upgradePlan");
|
||||||
}}
|
}}
|
||||||
placeholder="123.456.789.0"
|
placeholder="123.456.789.0"
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
onClick={() => {
|
||||||
|
if (subscription?.ipAllowlisting) {
|
||||||
|
removeAccessTokenTrustedIp(index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePopUpOpen("upgradePlan");
|
||||||
|
}}
|
||||||
|
size="lg"
|
||||||
|
colorSchema="danger"
|
||||||
|
variant="plain"
|
||||||
|
ariaLabel="update"
|
||||||
|
className="p-3"
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faXmark} />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
<div className="my-4 ml-1">
|
||||||
|
<Button
|
||||||
|
variant="outline_bg"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (subscription?.ipAllowlisting) {
|
if (subscription?.ipAllowlisting) {
|
||||||
removeAccessTokenTrustedIp(index);
|
appendAccessTokenTrustedIp({
|
||||||
|
ipAddress: "0.0.0.0/0"
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePopUpOpen("upgradePlan");
|
handlePopUpOpen("upgradePlan");
|
||||||
}}
|
}}
|
||||||
size="lg"
|
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
||||||
colorSchema="danger"
|
size="xs"
|
||||||
variant="plain"
|
|
||||||
ariaLabel="update"
|
|
||||||
className="p-3"
|
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faXmark} />
|
Add IP Address
|
||||||
</IconButton>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
))}
|
<div className="flex justify-between">
|
||||||
<div className="my-4 ml-1">
|
<div className="flex items-center">
|
||||||
<Button
|
{initialAuthMethod && identityAuthMethodData?.authMethod !== initialAuthMethod ? (
|
||||||
variant="outline_bg"
|
<Button
|
||||||
onClick={() => {
|
className="mr-4"
|
||||||
if (subscription?.ipAllowlisting) {
|
size="sm"
|
||||||
appendAccessTokenTrustedIp({
|
isLoading={isSubmitting}
|
||||||
ipAddress: "0.0.0.0/0"
|
isDisabled={isSubmitting}
|
||||||
});
|
onClick={() => internalPopUpState.handlePopUpToggle("overwriteAuthMethod", true)}
|
||||||
return;
|
>
|
||||||
}
|
Overwrite
|
||||||
|
</Button>
|
||||||
handlePopUpOpen("upgradePlan");
|
) : (
|
||||||
}}
|
<Button
|
||||||
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
className="mr-4"
|
||||||
size="xs"
|
size="sm"
|
||||||
>
|
type="submit"
|
||||||
Add IP Address
|
isLoading={isSubmitting}
|
||||||
</Button>
|
isDisabled={isSubmitting}
|
||||||
</div>
|
>
|
||||||
<div className="flex justify-between">
|
Submit
|
||||||
<div className="flex items-center">
|
</Button>
|
||||||
{(initialAuthMethod && identityAuthMethodData?.authMethod !== initialAuthMethod) ?
|
)}
|
||||||
<Button
|
<Button
|
||||||
className="mr-4"
|
colorSchema="secondary"
|
||||||
size="sm"
|
variant="plain"
|
||||||
isLoading={isSubmitting}
|
onClick={() => handlePopUpToggle("identityAuthMethod", false)}
|
||||||
isDisabled={isSubmitting}
|
|
||||||
onClick={() => popup.handlePopUpToggle("overwriteAuthMethod", true)}
|
|
||||||
>
|
>
|
||||||
Overwrite
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
: <Button
|
</div>
|
||||||
className="mr-4"
|
{isCurrentAuthMethod && (
|
||||||
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
type="submit"
|
colorSchema="danger"
|
||||||
isLoading={isSubmitting}
|
isLoading={isSubmitting}
|
||||||
isDisabled={isSubmitting}
|
isDisabled={isSubmitting}
|
||||||
>Submit</Button>
|
onClick={() => handlePopUpToggle("revokeAuthMethod", true)}
|
||||||
}
|
>
|
||||||
<Button
|
Remove Auth Method
|
||||||
colorSchema="secondary"
|
</Button>
|
||||||
variant="plain"
|
)}
|
||||||
onClick={() => handlePopUpToggle("identityAuthMethod", false)}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
{identityAuthMethodData?.authMethod === initialAuthMethod && (
|
</form>
|
||||||
<Button
|
|
||||||
size="sm"
|
|
||||||
colorSchema="danger"
|
|
||||||
isLoading={isSubmitting}
|
|
||||||
isDisabled={isSubmitting}
|
|
||||||
onClick={() => handlePopUpToggle("revokeAuthMethod", true)}
|
|
||||||
>
|
|
||||||
Remove Auth Method
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<DeleteActionModal
|
<DeleteActionModal
|
||||||
isOpen={popup.popUp.overwriteAuthMethod?.isOpen}
|
isOpen={internalPopUpState.popUp.overwriteAuthMethod?.isOpen}
|
||||||
title={`Are you sure want to overwrite ${
|
title={`Are you sure want to overwrite ${initialAuthMethod || "the auth method"} on ${
|
||||||
initialAuthMethod || "the auth method"
|
identityAuthMethodData?.name ?? ""
|
||||||
} on ${identityAuthMethodData?.name ?? ""}?`}
|
}?`}
|
||||||
onChange={(isOpen) => popup.handlePopUpToggle("overwriteAuthMethod", isOpen)}
|
onChange={(isOpen) => internalPopUpState.handlePopUpToggle("overwriteAuthMethod", isOpen)}
|
||||||
deleteKey="confirm"
|
deleteKey="confirm"
|
||||||
onDeleteApproved={async () => { await revokeAuth(initialAuthMethod); handleSubmit(onFormSubmit)(); }}
|
buttonText="Overwrite"
|
||||||
/>
|
onDeleteApproved={async () => {
|
||||||
</form>
|
await revokeAuth(initialAuthMethod);
|
||||||
|
handleSubmit(onFormSubmit)();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
+209
-203
@@ -70,11 +70,12 @@ export const IdentityAzureAuthForm = ({
|
|||||||
const { mutateAsync: addMutateAsync } = useAddIdentityAzureAuth();
|
const { mutateAsync: addMutateAsync } = useAddIdentityAzureAuth();
|
||||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityAzureAuth();
|
const { mutateAsync: updateMutateAsync } = useUpdateIdentityAzureAuth();
|
||||||
|
|
||||||
const { data } = useGetIdentityAzureAuth(identityAuthMethodData?.identityId ?? "");
|
const isCurrentAuthMethod = identityAuthMethodData?.authMethod === initialAuthMethod;
|
||||||
|
const { data } = useGetIdentityAzureAuth(identityAuthMethodData?.identityId ?? "", {
|
||||||
|
enabled: isCurrentAuthMethod
|
||||||
|
});
|
||||||
|
|
||||||
const popup = usePopUp([
|
const internalPopUpState = usePopUp(["overwriteAuthMethod"] as const);
|
||||||
"overwriteAuthMethod",
|
|
||||||
] as const);
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
@@ -172,8 +173,7 @@ export const IdentityAzureAuthForm = ({
|
|||||||
handlePopUpToggle("identityAuthMethod", false);
|
handlePopUpToggle("identityAuthMethod", false);
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
text: `Successfully ${identityAuthMethodData?.authMethod === initialAuthMethod ? "updated" : "configured"
|
text: `Successfully ${isCurrentAuthMethod ? "updated" : "configured"} auth method`,
|
||||||
} auth method`,
|
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -187,219 +187,225 @@ export const IdentityAzureAuthForm = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit(onFormSubmit)}>
|
<>
|
||||||
<Controller
|
<form onSubmit={handleSubmit(onFormSubmit)}>
|
||||||
control={control}
|
<Controller
|
||||||
defaultValue="2592000"
|
control={control}
|
||||||
name="tenantId"
|
defaultValue="2592000"
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="tenantId"
|
||||||
<FormControl
|
render={({ field, fieldState: { error } }) => (
|
||||||
label="Tenant ID"
|
<FormControl
|
||||||
isError={Boolean(error)}
|
label="Tenant ID"
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
isRequired
|
errorText={error?.message}
|
||||||
>
|
isRequired
|
||||||
<Input {...field} placeholder="00000000-0000-0000-0000-000000000000" type="text" />
|
>
|
||||||
</FormControl>
|
<Input {...field} placeholder="00000000-0000-0000-0000-000000000000" type="text" />
|
||||||
)}
|
</FormControl>
|
||||||
/>
|
)}
|
||||||
<Controller
|
/>
|
||||||
control={control}
|
<Controller
|
||||||
name="resource"
|
control={control}
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="resource"
|
||||||
<FormControl
|
render={({ field, fieldState: { error } }) => (
|
||||||
label="Resource / Audience"
|
<FormControl
|
||||||
isError={Boolean(error)}
|
label="Resource / Audience"
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
>
|
errorText={error?.message}
|
||||||
<Input {...field} placeholder="https://management.azure.com/" />
|
>
|
||||||
</FormControl>
|
<Input {...field} placeholder="https://management.azure.com/" />
|
||||||
)}
|
</FormControl>
|
||||||
/>
|
)}
|
||||||
<Controller
|
/>
|
||||||
control={control}
|
<Controller
|
||||||
name="allowedServicePrincipalIds"
|
control={control}
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="allowedServicePrincipalIds"
|
||||||
<FormControl
|
render={({ field, fieldState: { error } }) => (
|
||||||
label="Allowed Service Principal IDs"
|
<FormControl
|
||||||
isError={Boolean(error)}
|
label="Allowed Service Principal IDs"
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
>
|
errorText={error?.message}
|
||||||
<Input {...field} placeholder="00000000-0000-0000-0000-000000000000, ..." />
|
>
|
||||||
</FormControl>
|
<Input {...field} placeholder="00000000-0000-0000-0000-000000000000, ..." />
|
||||||
)}
|
</FormControl>
|
||||||
/>
|
)}
|
||||||
<Controller
|
/>
|
||||||
control={control}
|
<Controller
|
||||||
defaultValue="2592000"
|
control={control}
|
||||||
name="accessTokenTTL"
|
defaultValue="2592000"
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="accessTokenTTL"
|
||||||
<FormControl
|
render={({ field, fieldState: { error } }) => (
|
||||||
label="Access Token TTL (seconds)"
|
<FormControl
|
||||||
isError={Boolean(error)}
|
label="Access Token TTL (seconds)"
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
>
|
errorText={error?.message}
|
||||||
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
>
|
||||||
</FormControl>
|
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
||||||
)}
|
</FormControl>
|
||||||
/>
|
)}
|
||||||
<Controller
|
/>
|
||||||
control={control}
|
<Controller
|
||||||
defaultValue="2592000"
|
control={control}
|
||||||
name="accessTokenMaxTTL"
|
defaultValue="2592000"
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="accessTokenMaxTTL"
|
||||||
<FormControl
|
render={({ field, fieldState: { error } }) => (
|
||||||
label="Access Token Max TTL (seconds)"
|
<FormControl
|
||||||
isError={Boolean(error)}
|
label="Access Token Max TTL (seconds)"
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
>
|
errorText={error?.message}
|
||||||
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
>
|
||||||
</FormControl>
|
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
||||||
)}
|
</FormControl>
|
||||||
/>
|
)}
|
||||||
<Controller
|
/>
|
||||||
control={control}
|
<Controller
|
||||||
defaultValue="0"
|
control={control}
|
||||||
name="accessTokenNumUsesLimit"
|
defaultValue="0"
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="accessTokenNumUsesLimit"
|
||||||
<FormControl
|
render={({ field, fieldState: { error } }) => (
|
||||||
label="Access Token Max Number of Uses"
|
<FormControl
|
||||||
isError={Boolean(error)}
|
label="Access Token Max Number of Uses"
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
>
|
errorText={error?.message}
|
||||||
<Input {...field} placeholder="0" type="number" min="0" step="1" />
|
>
|
||||||
</FormControl>
|
<Input {...field} placeholder="0" type="number" min="0" step="1" />
|
||||||
)}
|
</FormControl>
|
||||||
/>
|
)}
|
||||||
{accessTokenTrustedIpsFields.map(({ id }, index) => (
|
/>
|
||||||
<div className="mb-3 flex items-end space-x-2" key={id}>
|
{accessTokenTrustedIpsFields.map(({ id }, index) => (
|
||||||
<Controller
|
<div className="mb-3 flex items-end space-x-2" key={id}>
|
||||||
control={control}
|
<Controller
|
||||||
name={`accessTokenTrustedIps.${index}.ipAddress`}
|
control={control}
|
||||||
defaultValue="0.0.0.0/0"
|
name={`accessTokenTrustedIps.${index}.ipAddress`}
|
||||||
render={({ field, fieldState: { error } }) => {
|
defaultValue="0.0.0.0/0"
|
||||||
return (
|
render={({ field, fieldState: { error } }) => {
|
||||||
<FormControl
|
return (
|
||||||
className="mb-0 flex-grow"
|
<FormControl
|
||||||
label={index === 0 ? "Access Token Trusted IPs" : undefined}
|
className="mb-0 flex-grow"
|
||||||
isError={Boolean(error)}
|
label={index === 0 ? "Access Token Trusted IPs" : undefined}
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
>
|
errorText={error?.message}
|
||||||
<Input
|
>
|
||||||
value={field.value}
|
<Input
|
||||||
onChange={(e) => {
|
value={field.value}
|
||||||
if (subscription?.ipAllowlisting) {
|
onChange={(e) => {
|
||||||
field.onChange(e);
|
if (subscription?.ipAllowlisting) {
|
||||||
return;
|
field.onChange(e);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
handlePopUpOpen("upgradePlan");
|
handlePopUpOpen("upgradePlan");
|
||||||
}}
|
}}
|
||||||
placeholder="123.456.789.0"
|
placeholder="123.456.789.0"
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
onClick={() => {
|
||||||
|
if (subscription?.ipAllowlisting) {
|
||||||
|
removeAccessTokenTrustedIp(index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePopUpOpen("upgradePlan");
|
||||||
|
}}
|
||||||
|
size="lg"
|
||||||
|
colorSchema="danger"
|
||||||
|
variant="plain"
|
||||||
|
ariaLabel="update"
|
||||||
|
className="p-3"
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faXmark} />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
<div className="my-4 ml-1">
|
||||||
|
<Button
|
||||||
|
variant="outline_bg"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (subscription?.ipAllowlisting) {
|
if (subscription?.ipAllowlisting) {
|
||||||
removeAccessTokenTrustedIp(index);
|
appendAccessTokenTrustedIp({
|
||||||
|
ipAddress: "0.0.0.0/0"
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePopUpOpen("upgradePlan");
|
handlePopUpOpen("upgradePlan");
|
||||||
}}
|
}}
|
||||||
size="lg"
|
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
||||||
colorSchema="danger"
|
size="xs"
|
||||||
variant="plain"
|
|
||||||
ariaLabel="update"
|
|
||||||
className="p-3"
|
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faXmark} />
|
Add IP Address
|
||||||
</IconButton>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
))}
|
<div className="flex justify-between">
|
||||||
<div className="my-4 ml-1">
|
<div className="flex items-center">
|
||||||
<Button
|
{initialAuthMethod && identityAuthMethodData?.authMethod !== initialAuthMethod ? (
|
||||||
variant="outline_bg"
|
<Button
|
||||||
onClick={() => {
|
className="mr-4"
|
||||||
if (subscription?.ipAllowlisting) {
|
size="sm"
|
||||||
appendAccessTokenTrustedIp({
|
isLoading={isSubmitting}
|
||||||
ipAddress: "0.0.0.0/0"
|
isDisabled={isSubmitting}
|
||||||
});
|
onClick={() => internalPopUpState.handlePopUpToggle("overwriteAuthMethod", true)}
|
||||||
return;
|
>
|
||||||
}
|
Overwrite
|
||||||
|
</Button>
|
||||||
handlePopUpOpen("upgradePlan");
|
) : (
|
||||||
}}
|
<Button
|
||||||
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
className="mr-4"
|
||||||
size="xs"
|
size="sm"
|
||||||
>
|
type="submit"
|
||||||
Add IP Address
|
isLoading={isSubmitting}
|
||||||
</Button>
|
isDisabled={isSubmitting}
|
||||||
</div>
|
>
|
||||||
<div className="flex justify-between">
|
Submit
|
||||||
<div className="flex items-center">
|
</Button>
|
||||||
{(initialAuthMethod && identityAuthMethodData?.authMethod !== initialAuthMethod) ?
|
)}
|
||||||
<Button
|
<Button
|
||||||
className="mr-4"
|
colorSchema="secondary"
|
||||||
size="sm"
|
variant="plain"
|
||||||
isLoading={isSubmitting}
|
onClick={() => handlePopUpToggle("identityAuthMethod", false)}
|
||||||
isDisabled={isSubmitting}
|
>
|
||||||
onClick={() => popup.handlePopUpToggle("overwriteAuthMethod", true)}>
|
Cancel
|
||||||
Overwrite
|
|
||||||
</Button>
|
</Button>
|
||||||
: <Button
|
</div>
|
||||||
className="mr-4"
|
{isCurrentAuthMethod && (
|
||||||
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
type="submit"
|
colorSchema="danger"
|
||||||
isLoading={isSubmitting}
|
isLoading={isSubmitting}
|
||||||
isDisabled={isSubmitting}
|
isDisabled={isSubmitting}
|
||||||
>Submit</Button>
|
onClick={() => handlePopUpToggle("revokeAuthMethod", true)}
|
||||||
}
|
>
|
||||||
<Button
|
Remove Auth Method
|
||||||
colorSchema="secondary"
|
</Button>
|
||||||
variant="plain"
|
)}
|
||||||
onClick={() => handlePopUpToggle("identityAuthMethod", false)}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
{identityAuthMethodData?.authMethod === initialAuthMethod && (
|
</form>
|
||||||
<Button
|
|
||||||
size="sm"
|
|
||||||
colorSchema="danger"
|
|
||||||
isLoading={isSubmitting}
|
|
||||||
isDisabled={isSubmitting}
|
|
||||||
onClick={() => handlePopUpToggle("revokeAuthMethod", true)}
|
|
||||||
>
|
|
||||||
Remove Auth Method
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<DeleteActionModal
|
<DeleteActionModal
|
||||||
isOpen={popup.popUp.overwriteAuthMethod?.isOpen}
|
isOpen={internalPopUpState.popUp.overwriteAuthMethod?.isOpen}
|
||||||
title={`Are you sure want to overwrite ${
|
title={`Are you sure want to overwrite ${initialAuthMethod || "the auth method"} on ${
|
||||||
initialAuthMethod || "the auth method"
|
identityAuthMethodData?.name ?? ""
|
||||||
} on ${identityAuthMethodData?.name ?? ""}?`}
|
}?`}
|
||||||
onChange={(isOpen) => popup.handlePopUpToggle("overwriteAuthMethod", isOpen)}
|
onChange={(isOpen) => internalPopUpState.handlePopUpToggle("overwriteAuthMethod", isOpen)}
|
||||||
deleteKey="confirm"
|
deleteKey="confirm"
|
||||||
onDeleteApproved={async () => {
|
buttonText="Overwrite"
|
||||||
const result = await trigger();
|
onDeleteApproved={async () => {
|
||||||
if(result){
|
const result = await trigger();
|
||||||
await revokeAuth(initialAuthMethod);
|
if (result) {
|
||||||
handleSubmit(onFormSubmit)();
|
await revokeAuth(initialAuthMethod);
|
||||||
}else{
|
handleSubmit(onFormSubmit)();
|
||||||
createNotification({
|
} else {
|
||||||
text: "Please fill in all required fields",
|
createNotification({
|
||||||
type: "error"
|
text: "Please fill in all required fields",
|
||||||
});
|
type: "error"
|
||||||
popup.handlePopUpToggle("overwriteAuthMethod", false);
|
});
|
||||||
}
|
internalPopUpState.handlePopUpToggle("overwriteAuthMethod", false);
|
||||||
}}
|
}
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
</form>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
+225
-205
@@ -6,7 +6,15 @@ import { zodResolver } from "@hookform/resolvers/zod";
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
import { Button, DeleteActionModal, 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 { useOrganization, useSubscription } from "@app/context";
|
||||||
import {
|
import {
|
||||||
useAddIdentityGcpAuth,
|
useAddIdentityGcpAuth,
|
||||||
@@ -71,17 +79,18 @@ export const IdentityGcpAuthForm = ({
|
|||||||
const { mutateAsync: addMutateAsync } = useAddIdentityGcpAuth();
|
const { mutateAsync: addMutateAsync } = useAddIdentityGcpAuth();
|
||||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityGcpAuth();
|
const { mutateAsync: updateMutateAsync } = useUpdateIdentityGcpAuth();
|
||||||
|
|
||||||
const { data } = useGetIdentityGcpAuth(identityAuthMethodData?.identityId ?? "");
|
const isCurrentAuthMethod = identityAuthMethodData?.authMethod === initialAuthMethod;
|
||||||
const popup = usePopUp([
|
const { data } = useGetIdentityGcpAuth(identityAuthMethodData?.identityId ?? "", {
|
||||||
"overwriteAuthMethod",
|
enabled: isCurrentAuthMethod
|
||||||
] as const);
|
});
|
||||||
|
const internalPopUpState = usePopUp(["overwriteAuthMethod"] as const);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
reset,
|
reset,
|
||||||
formState: { isSubmitting },
|
formState: { isSubmitting },
|
||||||
watch,
|
watch
|
||||||
} = useForm<FormData>({
|
} = useForm<FormData>({
|
||||||
resolver: zodResolver(schema),
|
resolver: zodResolver(schema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
@@ -180,12 +189,10 @@ export const IdentityGcpAuthForm = ({
|
|||||||
handlePopUpToggle("identityAuthMethod", false);
|
handlePopUpToggle("identityAuthMethod", false);
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
text: `Successfully ${identityAuthMethodData?.authMethod === initialAuthMethod ? "updated" : "configured"
|
text: `Successfully ${isCurrentAuthMethod ? "updated" : "configured"} auth method`,
|
||||||
} auth method`,
|
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
createNotification({
|
createNotification({
|
||||||
@@ -196,231 +203,244 @@ export const IdentityGcpAuthForm = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit(onFormSubmit)}>
|
<>
|
||||||
<Controller
|
<form onSubmit={handleSubmit(onFormSubmit)}>
|
||||||
control={control}
|
|
||||||
name="type"
|
|
||||||
render={({ field: { onChange, ...field }, fieldState: { error } }) => (
|
|
||||||
<FormControl label="Type" isError={Boolean(error)} errorText={error?.message}>
|
|
||||||
<Select
|
|
||||||
defaultValue={field.value}
|
|
||||||
{...field}
|
|
||||||
onValueChange={(e) => onChange(e)}
|
|
||||||
className="w-full"
|
|
||||||
>
|
|
||||||
<SelectItem value="gce" key="gce">
|
|
||||||
GCP ID Token Auth (Recommended)
|
|
||||||
</SelectItem>
|
|
||||||
<SelectItem value="iam" key="iam">
|
|
||||||
GCP IAM Auth
|
|
||||||
</SelectItem>
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
defaultValue="2592000"
|
|
||||||
name="allowedServiceAccounts"
|
|
||||||
render={({ field, fieldState: { error } }) => (
|
|
||||||
<FormControl
|
|
||||||
label="Allowed Service Account Emails"
|
|
||||||
isError={Boolean(error)}
|
|
||||||
errorText={error?.message}
|
|
||||||
>
|
|
||||||
<Input
|
|
||||||
{...field}
|
|
||||||
placeholder="[email protected], [email protected]"
|
|
||||||
type="text"
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
{watchedType === "gce" && (
|
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="allowedProjects"
|
name="type"
|
||||||
|
render={({ field: { onChange, ...field }, fieldState: { error } }) => (
|
||||||
|
<FormControl label="Type" isError={Boolean(error)} errorText={error?.message}>
|
||||||
|
<Select
|
||||||
|
defaultValue={field.value}
|
||||||
|
{...field}
|
||||||
|
onValueChange={(e) => onChange(e)}
|
||||||
|
className="w-full"
|
||||||
|
>
|
||||||
|
<SelectItem value="gce" key="gce">
|
||||||
|
GCP ID Token Auth (Recommended)
|
||||||
|
</SelectItem>
|
||||||
|
<SelectItem value="iam" key="iam">
|
||||||
|
GCP IAM Auth
|
||||||
|
</SelectItem>
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
defaultValue="2592000"
|
||||||
|
name="allowedServiceAccounts"
|
||||||
render={({ field, fieldState: { error } }) => (
|
render={({ field, fieldState: { error } }) => (
|
||||||
<FormControl
|
<FormControl
|
||||||
label="Allowed Projects"
|
label="Allowed Service Account Emails"
|
||||||
isError={Boolean(error)}
|
isError={Boolean(error)}
|
||||||
errorText={error?.message}
|
errorText={error?.message}
|
||||||
>
|
>
|
||||||
<Input {...field} placeholder="my-gcp-project, ..." />
|
<Input
|
||||||
|
{...field}
|
||||||
|
placeholder="[email protected], [email protected]"
|
||||||
|
type="text"
|
||||||
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
)}
|
{watchedType === "gce" && (
|
||||||
{watchedType === "gce" && (
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
name="allowedZones"
|
|
||||||
render={({ field, fieldState: { error } }) => (
|
|
||||||
<FormControl label="Allowed Zones" isError={Boolean(error)} errorText={error?.message}>
|
|
||||||
<Input {...field} placeholder="us-west2-a, us-central1-a, ..." />
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
defaultValue="2592000"
|
|
||||||
name="accessTokenTTL"
|
|
||||||
render={({ field, fieldState: { error } }) => (
|
|
||||||
<FormControl
|
|
||||||
label="Access Token TTL (seconds)"
|
|
||||||
isError={Boolean(error)}
|
|
||||||
errorText={error?.message}
|
|
||||||
>
|
|
||||||
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
defaultValue="2592000"
|
|
||||||
name="accessTokenMaxTTL"
|
|
||||||
render={({ field, fieldState: { error } }) => (
|
|
||||||
<FormControl
|
|
||||||
label="Access Token Max TTL (seconds)"
|
|
||||||
isError={Boolean(error)}
|
|
||||||
errorText={error?.message}
|
|
||||||
>
|
|
||||||
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
defaultValue="0"
|
|
||||||
name="accessTokenNumUsesLimit"
|
|
||||||
render={({ field, fieldState: { error } }) => (
|
|
||||||
<FormControl
|
|
||||||
label="Access Token Max Number of Uses"
|
|
||||||
isError={Boolean(error)}
|
|
||||||
errorText={error?.message}
|
|
||||||
>
|
|
||||||
<Input {...field} placeholder="0" type="number" min="0" step="1" />
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
{accessTokenTrustedIpsFields.map(({ id }, index) => (
|
|
||||||
<div className="mb-3 flex items-end space-x-2" key={id}>
|
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name={`accessTokenTrustedIps.${index}.ipAddress`}
|
name="allowedProjects"
|
||||||
defaultValue="0.0.0.0/0"
|
render={({ field, fieldState: { error } }) => (
|
||||||
render={({ field, fieldState: { error } }) => {
|
<FormControl
|
||||||
return (
|
label="Allowed Projects"
|
||||||
<FormControl
|
isError={Boolean(error)}
|
||||||
className="mb-0 flex-grow"
|
errorText={error?.message}
|
||||||
label={index === 0 ? "Access Token Trusted IPs" : undefined}
|
>
|
||||||
isError={Boolean(error)}
|
<Input {...field} placeholder="my-gcp-project, ..." />
|
||||||
errorText={error?.message}
|
</FormControl>
|
||||||
>
|
)}
|
||||||
<Input
|
|
||||||
value={field.value}
|
|
||||||
onChange={(e) => {
|
|
||||||
if (subscription?.ipAllowlisting) {
|
|
||||||
field.onChange(e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
handlePopUpOpen("upgradePlan");
|
|
||||||
}}
|
|
||||||
placeholder="123.456.789.0"
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
<IconButton
|
)}
|
||||||
|
{watchedType === "gce" && (
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="allowedZones"
|
||||||
|
render={({ field, fieldState: { error } }) => (
|
||||||
|
<FormControl
|
||||||
|
label="Allowed Zones"
|
||||||
|
isError={Boolean(error)}
|
||||||
|
errorText={error?.message}
|
||||||
|
>
|
||||||
|
<Input {...field} placeholder="us-west2-a, us-central1-a, ..." />
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
defaultValue="2592000"
|
||||||
|
name="accessTokenTTL"
|
||||||
|
render={({ field, fieldState: { error } }) => (
|
||||||
|
<FormControl
|
||||||
|
label="Access Token TTL (seconds)"
|
||||||
|
isError={Boolean(error)}
|
||||||
|
errorText={error?.message}
|
||||||
|
>
|
||||||
|
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
defaultValue="2592000"
|
||||||
|
name="accessTokenMaxTTL"
|
||||||
|
render={({ field, fieldState: { error } }) => (
|
||||||
|
<FormControl
|
||||||
|
label="Access Token Max TTL (seconds)"
|
||||||
|
isError={Boolean(error)}
|
||||||
|
errorText={error?.message}
|
||||||
|
>
|
||||||
|
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
defaultValue="0"
|
||||||
|
name="accessTokenNumUsesLimit"
|
||||||
|
render={({ field, fieldState: { error } }) => (
|
||||||
|
<FormControl
|
||||||
|
label="Access Token Max Number of Uses"
|
||||||
|
isError={Boolean(error)}
|
||||||
|
errorText={error?.message}
|
||||||
|
>
|
||||||
|
<Input {...field} placeholder="0" type="number" min="0" step="1" />
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{accessTokenTrustedIpsFields.map(({ id }, index) => (
|
||||||
|
<div className="mb-3 flex items-end space-x-2" key={id}>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name={`accessTokenTrustedIps.${index}.ipAddress`}
|
||||||
|
defaultValue="0.0.0.0/0"
|
||||||
|
render={({ field, fieldState: { error } }) => {
|
||||||
|
return (
|
||||||
|
<FormControl
|
||||||
|
className="mb-0 flex-grow"
|
||||||
|
label={index === 0 ? "Access Token Trusted IPs" : undefined}
|
||||||
|
isError={Boolean(error)}
|
||||||
|
errorText={error?.message}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
value={field.value}
|
||||||
|
onChange={(e) => {
|
||||||
|
if (subscription?.ipAllowlisting) {
|
||||||
|
field.onChange(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePopUpOpen("upgradePlan");
|
||||||
|
}}
|
||||||
|
placeholder="123.456.789.0"
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<IconButton
|
||||||
|
onClick={() => {
|
||||||
|
if (subscription?.ipAllowlisting) {
|
||||||
|
removeAccessTokenTrustedIp(index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePopUpOpen("upgradePlan");
|
||||||
|
}}
|
||||||
|
size="lg"
|
||||||
|
colorSchema="danger"
|
||||||
|
variant="plain"
|
||||||
|
ariaLabel="update"
|
||||||
|
className="p-3"
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faXmark} />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
<div className="my-4 ml-1">
|
||||||
|
<Button
|
||||||
|
variant="outline_bg"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (subscription?.ipAllowlisting) {
|
if (subscription?.ipAllowlisting) {
|
||||||
removeAccessTokenTrustedIp(index);
|
appendAccessTokenTrustedIp({
|
||||||
|
ipAddress: "0.0.0.0/0"
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePopUpOpen("upgradePlan");
|
handlePopUpOpen("upgradePlan");
|
||||||
}}
|
}}
|
||||||
size="lg"
|
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
||||||
colorSchema="danger"
|
size="xs"
|
||||||
variant="plain"
|
|
||||||
ariaLabel="update"
|
|
||||||
className="p-3"
|
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faXmark} />
|
Add IP Address
|
||||||
</IconButton>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
))}
|
<div className="flex justify-between">
|
||||||
<div className="my-4 ml-1">
|
<div className="flex items-center">
|
||||||
<Button
|
{initialAuthMethod && identityAuthMethodData?.authMethod !== initialAuthMethod ? (
|
||||||
variant="outline_bg"
|
<Button
|
||||||
onClick={() => {
|
className="mr-4"
|
||||||
if (subscription?.ipAllowlisting) {
|
size="sm"
|
||||||
appendAccessTokenTrustedIp({
|
isLoading={isSubmitting}
|
||||||
ipAddress: "0.0.0.0/0"
|
isDisabled={isSubmitting}
|
||||||
});
|
onClick={() => internalPopUpState.handlePopUpToggle("overwriteAuthMethod", true)}
|
||||||
return;
|
>
|
||||||
}
|
Overwrite
|
||||||
|
</Button>
|
||||||
handlePopUpOpen("upgradePlan");
|
) : (
|
||||||
}}
|
<Button
|
||||||
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
className="mr-4"
|
||||||
size="xs"
|
size="sm"
|
||||||
>
|
type="submit"
|
||||||
Add IP Address
|
isLoading={isSubmitting}
|
||||||
</Button>
|
isDisabled={isSubmitting}
|
||||||
</div>
|
>
|
||||||
<div className="flex justify-between">
|
Submit
|
||||||
<div className="flex items-center">
|
</Button>
|
||||||
{(initialAuthMethod && identityAuthMethodData?.authMethod !== initialAuthMethod) ?
|
)}
|
||||||
<Button
|
<Button
|
||||||
className="mr-4"
|
colorSchema="secondary"
|
||||||
size="sm"
|
variant="plain"
|
||||||
isLoading={isSubmitting}
|
onClick={() => handlePopUpToggle("identityAuthMethod", false)}
|
||||||
isDisabled={isSubmitting}
|
|
||||||
onClick={() => popup.handlePopUpToggle("overwriteAuthMethod", true)}
|
|
||||||
>
|
>
|
||||||
Overwrite
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
: <Button
|
</div>
|
||||||
className="mr-4"
|
{isCurrentAuthMethod && (
|
||||||
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
type="submit"
|
colorSchema="danger"
|
||||||
isLoading={isSubmitting}
|
isLoading={isSubmitting}
|
||||||
isDisabled={isSubmitting}
|
isDisabled={isSubmitting}
|
||||||
>Submit</Button>
|
onClick={() => handlePopUpToggle("revokeAuthMethod", true)}
|
||||||
}
|
>
|
||||||
<Button
|
Remove Auth Method
|
||||||
colorSchema="secondary"
|
</Button>
|
||||||
variant="plain"
|
)}
|
||||||
onClick={() => handlePopUpToggle("identityAuthMethod", false)}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
{identityAuthMethodData?.authMethod === initialAuthMethod && (
|
</form>
|
||||||
<Button
|
|
||||||
size="sm"
|
|
||||||
colorSchema="danger"
|
|
||||||
isLoading={isSubmitting}
|
|
||||||
isDisabled={isSubmitting}
|
|
||||||
onClick={() => handlePopUpToggle("revokeAuthMethod", true)}
|
|
||||||
>
|
|
||||||
Remove Auth Method
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<DeleteActionModal
|
<DeleteActionModal
|
||||||
isOpen={popup.popUp.overwriteAuthMethod?.isOpen}
|
isOpen={internalPopUpState.popUp.overwriteAuthMethod?.isOpen}
|
||||||
title={`Are you sure want to overwrite ${
|
title={`Are you sure want to overwrite ${initialAuthMethod || "the auth method"} on ${
|
||||||
initialAuthMethod || "the auth method"
|
identityAuthMethodData?.name ?? ""
|
||||||
} on ${identityAuthMethodData?.name ?? ""}?`}
|
}?`}
|
||||||
onChange={(isOpen) => popup.handlePopUpToggle("overwriteAuthMethod", isOpen)}
|
buttonText="Overwrite"
|
||||||
deleteKey="confirm"
|
onChange={(isOpen) => internalPopUpState.handlePopUpToggle("overwriteAuthMethod", isOpen)}
|
||||||
onDeleteApproved={async () => { await revokeAuth(initialAuthMethod); handleSubmit(onFormSubmit)(); }}
|
deleteKey="confirm"
|
||||||
/>
|
onDeleteApproved={async () => {
|
||||||
</form>
|
await revokeAuth(initialAuthMethod);
|
||||||
|
handleSubmit(onFormSubmit)();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
+268
-253
@@ -6,7 +6,14 @@ import { zodResolver } from "@hookform/resolvers/zod";
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
import { Button, DeleteActionModal, 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 { useOrganization, useSubscription } from "@app/context";
|
||||||
import {
|
import {
|
||||||
useAddIdentityKubernetesAuth,
|
useAddIdentityKubernetesAuth,
|
||||||
@@ -73,17 +80,18 @@ export const IdentityKubernetesAuthForm = ({
|
|||||||
const { mutateAsync: addMutateAsync } = useAddIdentityKubernetesAuth();
|
const { mutateAsync: addMutateAsync } = useAddIdentityKubernetesAuth();
|
||||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityKubernetesAuth();
|
const { mutateAsync: updateMutateAsync } = useUpdateIdentityKubernetesAuth();
|
||||||
|
|
||||||
const { data } = useGetIdentityKubernetesAuth(identityAuthMethodData?.identityId ?? "");
|
const isCurrentAuthMethod = identityAuthMethodData?.authMethod === initialAuthMethod;
|
||||||
const popup = usePopUp([
|
const { data } = useGetIdentityKubernetesAuth(identityAuthMethodData?.identityId ?? "", {
|
||||||
"overwriteAuthMethod",
|
enabled: isCurrentAuthMethod
|
||||||
] as const);
|
});
|
||||||
|
const internalPopUpState = usePopUp(["overwriteAuthMethod"] as const);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
reset,
|
reset,
|
||||||
trigger,
|
trigger,
|
||||||
formState: { isSubmitting },
|
formState: { isSubmitting }
|
||||||
} = useForm<FormData>({
|
} = useForm<FormData>({
|
||||||
resolver: zodResolver(schema),
|
resolver: zodResolver(schema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
@@ -192,8 +200,7 @@ export const IdentityKubernetesAuthForm = ({
|
|||||||
handlePopUpToggle("identityAuthMethod", false);
|
handlePopUpToggle("identityAuthMethod", false);
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
text: `Successfully ${identityAuthMethodData?.authMethod === initialAuthMethod ? "updated" : "configured"
|
text: `Successfully ${isCurrentAuthMethod ? "updated" : "configured"} auth method`,
|
||||||
} auth method`,
|
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -207,269 +214,277 @@ export const IdentityKubernetesAuthForm = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit(onFormSubmit)}>
|
<>
|
||||||
<Controller
|
<form onSubmit={handleSubmit(onFormSubmit)}>
|
||||||
control={control}
|
<Controller
|
||||||
defaultValue="2592000"
|
control={control}
|
||||||
name="kubernetesHost"
|
defaultValue="2592000"
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="kubernetesHost"
|
||||||
<FormControl
|
render={({ field, fieldState: { error } }) => (
|
||||||
label="Kubernetes Host / Base Kubernetes API URL "
|
<FormControl
|
||||||
isError={Boolean(error)}
|
label="Kubernetes Host / Base Kubernetes API URL "
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
tooltipText="The host string, host:port pair, or URL to the base of the Kubernetes API server. This can usually be obtained by running 'kubectl cluster-info'"
|
errorText={error?.message}
|
||||||
isRequired
|
tooltipText="The host string, host:port pair, or URL to the base of the Kubernetes API server. This can usually be obtained by running 'kubectl cluster-info'"
|
||||||
>
|
isRequired
|
||||||
<Input {...field} placeholder="https://my-example-k8s-api-host.com" type="text" />
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
name="tokenReviewerJwt"
|
|
||||||
render={({ field, fieldState: { error } }) => (
|
|
||||||
<FormControl
|
|
||||||
label="Token Reviewer JWT"
|
|
||||||
isError={Boolean(error)}
|
|
||||||
errorText={error?.message}
|
|
||||||
tooltipText="A long-lived service account JWT token for Infisical to access the TokenReview API to validate other service account JWT tokens submitted by applications/pods."
|
|
||||||
isRequired
|
|
||||||
>
|
|
||||||
<Input {...field} placeholder="" type="password" />
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
name="allowedNames"
|
|
||||||
render={({ field, fieldState: { error } }) => (
|
|
||||||
<FormControl
|
|
||||||
label="Allowed Service Account Names"
|
|
||||||
isError={Boolean(error)}
|
|
||||||
tooltipText="An optional comma-separated list of trusted service account names that are allowed to authenticate with Infisical. Leave empty to allow any service account."
|
|
||||||
errorText={error?.message}
|
|
||||||
>
|
|
||||||
<Input {...field} placeholder="service-account-1-name, service-account-1-name" />
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
defaultValue=""
|
|
||||||
name="allowedNamespaces"
|
|
||||||
render={({ field, fieldState: { error } }) => (
|
|
||||||
<FormControl
|
|
||||||
label="Allowed Namespaces"
|
|
||||||
isError={Boolean(error)}
|
|
||||||
errorText={error?.message}
|
|
||||||
tooltipText="An optional comma-separated list of trusted service account names that are allowed to authenticate with Infisical. Leave empty to allow any namespaces."
|
|
||||||
>
|
|
||||||
<Input {...field} placeholder="namespaceA, namespaceB" type="text" />
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
defaultValue=""
|
|
||||||
name="allowedAudience"
|
|
||||||
render={({ field, fieldState: { error } }) => (
|
|
||||||
<FormControl
|
|
||||||
label="Allowed Audience"
|
|
||||||
isError={Boolean(error)} errorText={error?.message}
|
|
||||||
tooltipText="An optional audience claim that the service account JWT token must have to authenticate with Infisical. Leave empty to allow any audience claim."
|
|
||||||
>
|
>
|
||||||
<Input {...field} placeholder="" type="text" />
|
<Input {...field} placeholder="https://my-example-k8s-api-host.com" type="text" />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="caCert"
|
name="tokenReviewerJwt"
|
||||||
render={({ field, fieldState: { error } }) => (
|
render={({ field, fieldState: { error } }) => (
|
||||||
<FormControl
|
<FormControl
|
||||||
label="CA Certificate"
|
label="Token Reviewer JWT"
|
||||||
errorText={error?.message} isError={Boolean(error)}
|
isError={Boolean(error)}
|
||||||
tooltipText="An optional PEM-encoded CA cert for the Kubernetes API server. This is used by the TLS client for secure communication with the Kubernetes API server."
|
errorText={error?.message}
|
||||||
>
|
tooltipText="A long-lived service account JWT token for Infisical to access the TokenReview API to validate other service account JWT tokens submitted by applications/pods."
|
||||||
<TextArea {...field} placeholder="-----BEGIN CERTIFICATE----- ..." />
|
isRequired
|
||||||
</FormControl>
|
>
|
||||||
)}
|
<Input {...field} placeholder="" type="password" />
|
||||||
/>
|
</FormControl>
|
||||||
<Controller
|
)}
|
||||||
control={control}
|
/>
|
||||||
defaultValue="2592000"
|
<Controller
|
||||||
name="accessTokenTTL"
|
control={control}
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="allowedNames"
|
||||||
<FormControl
|
render={({ field, fieldState: { error } }) => (
|
||||||
label="Access Token TTL (seconds)"
|
<FormControl
|
||||||
tooltipText="The lifetime for an acccess token in seconds. This value will be referenced at renewal time."
|
label="Allowed Service Account Names"
|
||||||
isError={Boolean(error)}
|
isError={Boolean(error)}
|
||||||
errorText={error?.message}
|
tooltipText="An optional comma-separated list of trusted service account names that are allowed to authenticate with Infisical. Leave empty to allow any service account."
|
||||||
>
|
errorText={error?.message}
|
||||||
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
>
|
||||||
</FormControl>
|
<Input {...field} placeholder="service-account-1-name, service-account-1-name" />
|
||||||
)}
|
</FormControl>
|
||||||
/>
|
)}
|
||||||
<Controller
|
/>
|
||||||
control={control}
|
<Controller
|
||||||
defaultValue="2592000"
|
control={control}
|
||||||
name="accessTokenMaxTTL"
|
defaultValue=""
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="allowedNamespaces"
|
||||||
<FormControl
|
render={({ field, fieldState: { error } }) => (
|
||||||
label="Access Token Max TTL (seconds)"
|
<FormControl
|
||||||
isError={Boolean(error)}
|
label="Allowed Namespaces"
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
tooltipText="The maximum lifetime for an access token in seconds. This value will be referenced at renewal time."
|
errorText={error?.message}
|
||||||
>
|
tooltipText="An optional comma-separated list of trusted service account names that are allowed to authenticate with Infisical. Leave empty to allow any namespaces."
|
||||||
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
>
|
||||||
</FormControl>
|
<Input {...field} placeholder="namespaceA, namespaceB" type="text" />
|
||||||
)}
|
</FormControl>
|
||||||
/>
|
)}
|
||||||
<Controller
|
/>
|
||||||
control={control}
|
<Controller
|
||||||
defaultValue="0"
|
control={control}
|
||||||
name="accessTokenNumUsesLimit"
|
defaultValue=""
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="allowedAudience"
|
||||||
<FormControl
|
render={({ field, fieldState: { error } }) => (
|
||||||
label="Access Token Max Number of Uses"
|
<FormControl
|
||||||
isError={Boolean(error)}
|
label="Allowed Audience"
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
tooltipText="The maximum number of times that an access token can be used; a value of 0 implies infinite number of uses."
|
errorText={error?.message}
|
||||||
>
|
tooltipText="An optional audience claim that the service account JWT token must have to authenticate with Infisical. Leave empty to allow any audience claim."
|
||||||
<Input {...field} placeholder="0" type="number" min="0" step="1" />
|
>
|
||||||
</FormControl>
|
<Input {...field} placeholder="" type="text" />
|
||||||
)}
|
</FormControl>
|
||||||
/>
|
)}
|
||||||
{accessTokenTrustedIpsFields.map(({ id }, index) => (
|
/>
|
||||||
<div className="mb-3 flex items-end space-x-2" key={id}>
|
<Controller
|
||||||
<Controller
|
control={control}
|
||||||
control={control}
|
name="caCert"
|
||||||
name={`accessTokenTrustedIps.${index}.ipAddress`}
|
render={({ field, fieldState: { error } }) => (
|
||||||
defaultValue="0.0.0.0/0"
|
<FormControl
|
||||||
render={({ field, fieldState: { error } }) => {
|
label="CA Certificate"
|
||||||
return (
|
errorText={error?.message}
|
||||||
<FormControl
|
isError={Boolean(error)}
|
||||||
className="mb-0 flex-grow"
|
tooltipText="An optional PEM-encoded CA cert for the Kubernetes API server. This is used by the TLS client for secure communication with the Kubernetes API server."
|
||||||
label={index === 0 ? "Access Token Trusted IPs" : undefined}
|
>
|
||||||
isError={Boolean(error)}
|
<TextArea {...field} placeholder="-----BEGIN CERTIFICATE----- ..." />
|
||||||
errorText={error?.message}
|
</FormControl>
|
||||||
tooltipText="The IPs or CIDR ranges that access tokens can be used from. By default, each token is given the 0.0.0.0/0, allowing usage from any network address."
|
)}
|
||||||
>
|
/>
|
||||||
<Input
|
<Controller
|
||||||
value={field.value}
|
control={control}
|
||||||
onChange={(e) => {
|
defaultValue="2592000"
|
||||||
if (subscription?.ipAllowlisting) {
|
name="accessTokenTTL"
|
||||||
field.onChange(e);
|
render={({ field, fieldState: { error } }) => (
|
||||||
return;
|
<FormControl
|
||||||
}
|
label="Access Token TTL (seconds)"
|
||||||
|
tooltipText="The lifetime for an acccess token in seconds. This value will be referenced at renewal time."
|
||||||
|
isError={Boolean(error)}
|
||||||
|
errorText={error?.message}
|
||||||
|
>
|
||||||
|
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
defaultValue="2592000"
|
||||||
|
name="accessTokenMaxTTL"
|
||||||
|
render={({ field, fieldState: { error } }) => (
|
||||||
|
<FormControl
|
||||||
|
label="Access Token Max TTL (seconds)"
|
||||||
|
isError={Boolean(error)}
|
||||||
|
errorText={error?.message}
|
||||||
|
tooltipText="The maximum lifetime for an access token in seconds. This value will be referenced at renewal time."
|
||||||
|
>
|
||||||
|
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
defaultValue="0"
|
||||||
|
name="accessTokenNumUsesLimit"
|
||||||
|
render={({ field, fieldState: { error } }) => (
|
||||||
|
<FormControl
|
||||||
|
label="Access Token Max Number of Uses"
|
||||||
|
isError={Boolean(error)}
|
||||||
|
errorText={error?.message}
|
||||||
|
tooltipText="The maximum number of times that an access token can be used; a value of 0 implies infinite number of uses."
|
||||||
|
>
|
||||||
|
<Input {...field} placeholder="0" type="number" min="0" step="1" />
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{accessTokenTrustedIpsFields.map(({ id }, index) => (
|
||||||
|
<div className="mb-3 flex items-end space-x-2" key={id}>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name={`accessTokenTrustedIps.${index}.ipAddress`}
|
||||||
|
defaultValue="0.0.0.0/0"
|
||||||
|
render={({ field, fieldState: { error } }) => {
|
||||||
|
return (
|
||||||
|
<FormControl
|
||||||
|
className="mb-0 flex-grow"
|
||||||
|
label={index === 0 ? "Access Token Trusted IPs" : undefined}
|
||||||
|
isError={Boolean(error)}
|
||||||
|
errorText={error?.message}
|
||||||
|
tooltipText="The IPs or CIDR ranges that access tokens can be used from. By default, each token is given the 0.0.0.0/0, allowing usage from any network address."
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
value={field.value}
|
||||||
|
onChange={(e) => {
|
||||||
|
if (subscription?.ipAllowlisting) {
|
||||||
|
field.onChange(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
handlePopUpOpen("upgradePlan");
|
handlePopUpOpen("upgradePlan");
|
||||||
}}
|
}}
|
||||||
placeholder="123.456.789.0"
|
placeholder="123.456.789.0"
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
onClick={() => {
|
||||||
|
if (subscription?.ipAllowlisting) {
|
||||||
|
removeAccessTokenTrustedIp(index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePopUpOpen("upgradePlan");
|
||||||
|
}}
|
||||||
|
size="lg"
|
||||||
|
colorSchema="danger"
|
||||||
|
variant="plain"
|
||||||
|
ariaLabel="update"
|
||||||
|
className="p-3"
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faXmark} />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
<div className="my-4 ml-1">
|
||||||
|
<Button
|
||||||
|
variant="outline_bg"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (subscription?.ipAllowlisting) {
|
if (subscription?.ipAllowlisting) {
|
||||||
removeAccessTokenTrustedIp(index);
|
appendAccessTokenTrustedIp({
|
||||||
|
ipAddress: "0.0.0.0/0"
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePopUpOpen("upgradePlan");
|
handlePopUpOpen("upgradePlan");
|
||||||
}}
|
}}
|
||||||
size="lg"
|
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
||||||
colorSchema="danger"
|
size="xs"
|
||||||
variant="plain"
|
|
||||||
ariaLabel="update"
|
|
||||||
className="p-3"
|
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faXmark} />
|
Add IP Address
|
||||||
</IconButton>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
))}
|
<div className="flex justify-between">
|
||||||
<div className="my-4 ml-1">
|
<div className="flex items-center">
|
||||||
<Button
|
{initialAuthMethod && identityAuthMethodData?.authMethod !== initialAuthMethod ? (
|
||||||
variant="outline_bg"
|
<Button
|
||||||
onClick={() => {
|
className="mr-4"
|
||||||
if (subscription?.ipAllowlisting) {
|
size="sm"
|
||||||
appendAccessTokenTrustedIp({
|
isLoading={isSubmitting}
|
||||||
ipAddress: "0.0.0.0/0"
|
isDisabled={isSubmitting}
|
||||||
});
|
onClick={() => internalPopUpState.handlePopUpToggle("overwriteAuthMethod", true)}
|
||||||
return;
|
>
|
||||||
}
|
Overwrite
|
||||||
|
</Button>
|
||||||
handlePopUpOpen("upgradePlan");
|
) : (
|
||||||
}}
|
<Button
|
||||||
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
className="mr-4"
|
||||||
size="xs"
|
size="sm"
|
||||||
>
|
type="submit"
|
||||||
Add IP Address
|
isLoading={isSubmitting}
|
||||||
</Button>
|
isDisabled={isSubmitting}
|
||||||
</div>
|
>
|
||||||
<div className="flex justify-between">
|
Submit
|
||||||
<div className="flex items-center">
|
</Button>
|
||||||
{(initialAuthMethod && identityAuthMethodData?.authMethod !== initialAuthMethod) ?
|
)}
|
||||||
<Button
|
<Button
|
||||||
className="mr-4"
|
colorSchema="secondary"
|
||||||
size="sm"
|
variant="plain"
|
||||||
isLoading={isSubmitting}
|
onClick={() => handlePopUpToggle("identityAuthMethod", false)}
|
||||||
isDisabled={isSubmitting}
|
|
||||||
onClick={() => popup.handlePopUpToggle("overwriteAuthMethod", true)}
|
|
||||||
>
|
>
|
||||||
Overwrite
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
: <Button
|
</div>
|
||||||
className="mr-4"
|
{isCurrentAuthMethod && (
|
||||||
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
type="submit"
|
colorSchema="danger"
|
||||||
isLoading={isSubmitting}
|
isLoading={isSubmitting}
|
||||||
isDisabled={isSubmitting}
|
isDisabled={isSubmitting}
|
||||||
>Submit</Button>
|
onClick={() => handlePopUpToggle("revokeAuthMethod", true)}
|
||||||
}
|
>
|
||||||
<Button
|
Remove Auth Method
|
||||||
colorSchema="secondary"
|
</Button>
|
||||||
variant="plain"
|
)}
|
||||||
onClick={() => handlePopUpToggle("identityAuthMethod", false)}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
{identityAuthMethodData?.authMethod === initialAuthMethod && (
|
</form>
|
||||||
<Button
|
|
||||||
size="sm"
|
|
||||||
colorSchema="danger"
|
|
||||||
isLoading={isSubmitting}
|
|
||||||
isDisabled={isSubmitting}
|
|
||||||
onClick={() => handlePopUpToggle("revokeAuthMethod", true)}
|
|
||||||
>
|
|
||||||
Remove Auth Method
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<DeleteActionModal
|
<DeleteActionModal
|
||||||
isOpen={popup.popUp.overwriteAuthMethod?.isOpen}
|
isOpen={internalPopUpState.popUp.overwriteAuthMethod?.isOpen}
|
||||||
title={`Are you sure want to overwrite ${
|
title={`Are you sure want to overwrite ${initialAuthMethod || "the auth method"} on ${
|
||||||
initialAuthMethod || "the auth method"
|
identityAuthMethodData?.name ?? ""
|
||||||
} on ${identityAuthMethodData?.name ?? ""}?`}
|
}?`}
|
||||||
onChange={(isOpen) => popup.handlePopUpToggle("overwriteAuthMethod", isOpen)}
|
onChange={(isOpen) => internalPopUpState.handlePopUpToggle("overwriteAuthMethod", isOpen)}
|
||||||
deleteKey="confirm"
|
deleteKey="confirm"
|
||||||
onDeleteApproved={async () => {
|
buttonText="Overwrite"
|
||||||
const result = await trigger();
|
onDeleteApproved={async () => {
|
||||||
if(result){
|
const result = await trigger();
|
||||||
await revokeAuth(initialAuthMethod);
|
if (result) {
|
||||||
handleSubmit(onFormSubmit)();
|
await revokeAuth(initialAuthMethod);
|
||||||
}else{
|
handleSubmit(onFormSubmit)();
|
||||||
createNotification({
|
} else {
|
||||||
text: "Please fill in all required fields",
|
createNotification({
|
||||||
type: "error"
|
text: "Please fill in all required fields",
|
||||||
});
|
type: "error"
|
||||||
popup.handlePopUpToggle("overwriteAuthMethod", false);
|
});
|
||||||
}
|
internalPopUpState.handlePopUpToggle("overwriteAuthMethod", false);
|
||||||
}}
|
}
|
||||||
/>
|
}}
|
||||||
</form>
|
/>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
+337
-323
@@ -7,7 +7,15 @@ import { zodResolver } from "@hookform/resolvers/zod";
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
import { Button, DeleteActionModal,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 { useOrganization, useSubscription } from "@app/context";
|
||||||
import { useAddIdentityOidcAuth, useUpdateIdentityOidcAuth } from "@app/hooks/api";
|
import { useAddIdentityOidcAuth, useUpdateIdentityOidcAuth } from "@app/hooks/api";
|
||||||
import { IdentityAuthMethod } from "@app/hooks/api/identities";
|
import { IdentityAuthMethod } from "@app/hooks/api/identities";
|
||||||
@@ -74,10 +82,11 @@ export const IdentityOidcAuthForm = ({
|
|||||||
const { mutateAsync: addMutateAsync } = useAddIdentityOidcAuth();
|
const { mutateAsync: addMutateAsync } = useAddIdentityOidcAuth();
|
||||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityOidcAuth();
|
const { mutateAsync: updateMutateAsync } = useUpdateIdentityOidcAuth();
|
||||||
|
|
||||||
const { data } = useGetIdentityOidcAuth(identityAuthMethodData?.identityId ?? "");
|
const isCurrentAuthMethod = identityAuthMethodData?.authMethod === initialAuthMethod;
|
||||||
const popup = usePopUp([
|
const { data } = useGetIdentityOidcAuth(identityAuthMethodData?.identityId ?? "", {
|
||||||
"overwriteAuthMethod",
|
enabled: isCurrentAuthMethod
|
||||||
] as const);
|
});
|
||||||
|
const internalPopUpState = usePopUp(["overwriteAuthMethod"] as const);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
@@ -201,8 +210,7 @@ export const IdentityOidcAuthForm = ({
|
|||||||
handlePopUpToggle("identityAuthMethod", false);
|
handlePopUpToggle("identityAuthMethod", false);
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
text: `Successfully ${identityAuthMethodData?.authMethod === initialAuthMethod ? "updated" : "configured"
|
text: `Successfully ${isCurrentAuthMethod ? "updated" : "configured"} auth method`,
|
||||||
} auth method`,
|
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -216,344 +224,350 @@ export const IdentityOidcAuthForm = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit(onFormSubmit)}>
|
<>
|
||||||
<Controller
|
<form onSubmit={handleSubmit(onFormSubmit)}>
|
||||||
control={control}
|
<Controller
|
||||||
name="oidcDiscoveryUrl"
|
control={control}
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="oidcDiscoveryUrl"
|
||||||
<FormControl
|
render={({ field, fieldState: { error } }) => (
|
||||||
isRequired
|
<FormControl
|
||||||
label="OIDC Discovery URL"
|
isRequired
|
||||||
isError={Boolean(error)}
|
label="OIDC Discovery URL"
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
>
|
errorText={error?.message}
|
||||||
<Input
|
>
|
||||||
{...field}
|
<Input
|
||||||
placeholder="https://token.actions.githubusercontent.com"
|
{...field}
|
||||||
type="text"
|
placeholder="https://token.actions.githubusercontent.com"
|
||||||
/>
|
type="text"
|
||||||
</FormControl>
|
/>
|
||||||
)}
|
</FormControl>
|
||||||
/>
|
)}
|
||||||
<Controller
|
/>
|
||||||
control={control}
|
<Controller
|
||||||
name="boundIssuer"
|
control={control}
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="boundIssuer"
|
||||||
<FormControl
|
render={({ field, fieldState: { error } }) => (
|
||||||
isRequired
|
<FormControl
|
||||||
label="Issuer"
|
isRequired
|
||||||
isError={Boolean(error)}
|
label="Issuer"
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
>
|
errorText={error?.message}
|
||||||
<Input
|
>
|
||||||
{...field}
|
<Input
|
||||||
type="text"
|
{...field}
|
||||||
placeholder="https://token.actions.githubusercontent.com"
|
type="text"
|
||||||
/>
|
placeholder="https://token.actions.githubusercontent.com"
|
||||||
</FormControl>
|
/>
|
||||||
)}
|
</FormControl>
|
||||||
/>
|
)}
|
||||||
<Controller
|
/>
|
||||||
control={control}
|
<Controller
|
||||||
name="caCert"
|
control={control}
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="caCert"
|
||||||
<FormControl label="CA Certificate" errorText={error?.message} isError={Boolean(error)}>
|
render={({ field, fieldState: { error } }) => (
|
||||||
<TextArea {...field} placeholder="-----BEGIN CERTIFICATE----- ..." />
|
<FormControl label="CA Certificate" errorText={error?.message} isError={Boolean(error)}>
|
||||||
</FormControl>
|
<TextArea {...field} placeholder="-----BEGIN CERTIFICATE----- ..." />
|
||||||
)}
|
</FormControl>
|
||||||
/>
|
)}
|
||||||
<Controller
|
/>
|
||||||
control={control}
|
<Controller
|
||||||
name="boundSubject"
|
control={control}
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="boundSubject"
|
||||||
<FormControl
|
render={({ field, fieldState: { error } }) => (
|
||||||
label="Subject"
|
<FormControl
|
||||||
isError={Boolean(error)}
|
label="Subject"
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
icon={
|
errorText={error?.message}
|
||||||
<Tooltip
|
icon={
|
||||||
className="text-center"
|
<Tooltip
|
||||||
content={<span>This field supports glob patterns</span>}
|
className="text-center"
|
||||||
>
|
content={<span>This field supports glob patterns</span>}
|
||||||
<FontAwesomeIcon icon={faQuestionCircle} size="sm" />
|
|
||||||
</Tooltip>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Input {...field} type="text" />
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
name="boundAudiences"
|
|
||||||
render={({ field, fieldState: { error } }) => (
|
|
||||||
<FormControl
|
|
||||||
label="Audiences"
|
|
||||||
isError={Boolean(error)}
|
|
||||||
errorText={error?.message}
|
|
||||||
icon={
|
|
||||||
<Tooltip
|
|
||||||
className="text-center"
|
|
||||||
content={<span>This field supports glob patterns</span>}
|
|
||||||
>
|
|
||||||
<FontAwesomeIcon icon={faQuestionCircle} size="sm" />
|
|
||||||
</Tooltip>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Input {...field} type="text" placeholder="service1, service2" />
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
{boundClaimsFields.map(({ id }, index) => (
|
|
||||||
<div className="mb-3 flex items-end space-x-2" key={id}>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
name={`boundClaims.${index}.key`}
|
|
||||||
render={({ field, fieldState: { error } }) => {
|
|
||||||
return (
|
|
||||||
<FormControl
|
|
||||||
className="mb-0 flex-grow"
|
|
||||||
label={index === 0 ? "Claims" : undefined}
|
|
||||||
icon={
|
|
||||||
index === 0 ? (
|
|
||||||
<Tooltip
|
|
||||||
className="text-center"
|
|
||||||
content={<span>This field supports glob patterns</span>}
|
|
||||||
>
|
|
||||||
<FontAwesomeIcon icon={faQuestionCircle} size="sm" />
|
|
||||||
</Tooltip>
|
|
||||||
) : undefined
|
|
||||||
}
|
|
||||||
isError={Boolean(error)}
|
|
||||||
errorText={error?.message}
|
|
||||||
>
|
>
|
||||||
<Input
|
<FontAwesomeIcon icon={faQuestionCircle} size="sm" />
|
||||||
value={field.value}
|
</Tooltip>
|
||||||
onChange={(e) => field.onChange(e)}
|
}
|
||||||
placeholder="property"
|
>
|
||||||
/>
|
<Input {...field} type="text" />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
);
|
)}
|
||||||
}}
|
/>
|
||||||
/>
|
<Controller
|
||||||
<Controller
|
control={control}
|
||||||
control={control}
|
name="boundAudiences"
|
||||||
name={`boundClaims.${index}.value`}
|
render={({ field, fieldState: { error } }) => (
|
||||||
render={({ field, fieldState: { error } }) => {
|
<FormControl
|
||||||
return (
|
label="Audiences"
|
||||||
<FormControl
|
isError={Boolean(error)}
|
||||||
className="mb-0 flex-grow"
|
errorText={error?.message}
|
||||||
isError={Boolean(error)}
|
icon={
|
||||||
errorText={error?.message}
|
<Tooltip
|
||||||
|
className="text-center"
|
||||||
|
content={<span>This field supports glob patterns</span>}
|
||||||
>
|
>
|
||||||
<Input
|
<FontAwesomeIcon icon={faQuestionCircle} size="sm" />
|
||||||
value={field.value}
|
</Tooltip>
|
||||||
onChange={(e) => field.onChange(e)}
|
}
|
||||||
placeholder="value1, value2"
|
>
|
||||||
/>
|
<Input {...field} type="text" placeholder="service1, service2" />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
);
|
)}
|
||||||
}}
|
/>
|
||||||
/>
|
{boundClaimsFields.map(({ id }, index) => (
|
||||||
|
<div className="mb-3 flex items-end space-x-2" key={id}>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name={`boundClaims.${index}.key`}
|
||||||
|
render={({ field, fieldState: { error } }) => {
|
||||||
|
return (
|
||||||
|
<FormControl
|
||||||
|
className="mb-0 flex-grow"
|
||||||
|
label={index === 0 ? "Claims" : undefined}
|
||||||
|
icon={
|
||||||
|
index === 0 ? (
|
||||||
|
<Tooltip
|
||||||
|
className="text-center"
|
||||||
|
content={<span>This field supports glob patterns</span>}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faQuestionCircle} size="sm" />
|
||||||
|
</Tooltip>
|
||||||
|
) : undefined
|
||||||
|
}
|
||||||
|
isError={Boolean(error)}
|
||||||
|
errorText={error?.message}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
value={field.value}
|
||||||
|
onChange={(e) => field.onChange(e)}
|
||||||
|
placeholder="property"
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name={`boundClaims.${index}.value`}
|
||||||
|
render={({ field, fieldState: { error } }) => {
|
||||||
|
return (
|
||||||
|
<FormControl
|
||||||
|
className="mb-0 flex-grow"
|
||||||
|
isError={Boolean(error)}
|
||||||
|
errorText={error?.message}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
value={field.value}
|
||||||
|
onChange={(e) => field.onChange(e)}
|
||||||
|
placeholder="value1, value2"
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
<IconButton
|
<IconButton
|
||||||
onClick={() => removeBoundClaimField(index)}
|
onClick={() => removeBoundClaimField(index)}
|
||||||
size="lg"
|
size="lg"
|
||||||
colorSchema="danger"
|
colorSchema="danger"
|
||||||
variant="plain"
|
variant="plain"
|
||||||
ariaLabel="update"
|
ariaLabel="update"
|
||||||
className="p-3"
|
className="p-3"
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faXmark} />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
<div className="my-4 ml-1">
|
||||||
|
<Button
|
||||||
|
variant="outline_bg"
|
||||||
|
onClick={() =>
|
||||||
|
appendBoundClaimField({
|
||||||
|
key: "",
|
||||||
|
value: ""
|
||||||
|
})
|
||||||
|
}
|
||||||
|
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
||||||
|
size="xs"
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faXmark} />
|
Add Claims
|
||||||
</IconButton>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
))}
|
<Controller
|
||||||
<div className="my-4 ml-1">
|
control={control}
|
||||||
<Button
|
defaultValue="2592000"
|
||||||
variant="outline_bg"
|
name="accessTokenTTL"
|
||||||
onClick={() =>
|
render={({ field, fieldState: { error } }) => (
|
||||||
appendBoundClaimField({
|
<FormControl
|
||||||
key: "",
|
label="Access Token TTL (seconds)"
|
||||||
value: ""
|
isError={Boolean(error)}
|
||||||
})
|
errorText={error?.message}
|
||||||
}
|
>
|
||||||
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
||||||
size="xs"
|
</FormControl>
|
||||||
>
|
)}
|
||||||
Add Claims
|
/>
|
||||||
</Button>
|
<Controller
|
||||||
</div>
|
control={control}
|
||||||
<Controller
|
defaultValue="2592000"
|
||||||
control={control}
|
name="accessTokenMaxTTL"
|
||||||
defaultValue="2592000"
|
render={({ field, fieldState: { error } }) => (
|
||||||
name="accessTokenTTL"
|
<FormControl
|
||||||
render={({ field, fieldState: { error } }) => (
|
label="Access Token Max TTL (seconds)"
|
||||||
<FormControl
|
isError={Boolean(error)}
|
||||||
label="Access Token TTL (seconds)"
|
errorText={error?.message}
|
||||||
isError={Boolean(error)}
|
>
|
||||||
errorText={error?.message}
|
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
||||||
>
|
</FormControl>
|
||||||
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
)}
|
||||||
</FormControl>
|
/>
|
||||||
)}
|
<Controller
|
||||||
/>
|
control={control}
|
||||||
<Controller
|
defaultValue="0"
|
||||||
control={control}
|
name="accessTokenNumUsesLimit"
|
||||||
defaultValue="2592000"
|
render={({ field, fieldState: { error } }) => (
|
||||||
name="accessTokenMaxTTL"
|
<FormControl
|
||||||
render={({ field, fieldState: { error } }) => (
|
label="Access Token Max Number of Uses"
|
||||||
<FormControl
|
isError={Boolean(error)}
|
||||||
label="Access Token Max TTL (seconds)"
|
errorText={error?.message}
|
||||||
isError={Boolean(error)}
|
>
|
||||||
errorText={error?.message}
|
<Input {...field} placeholder="0" type="number" min="0" step="1" />
|
||||||
>
|
</FormControl>
|
||||||
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
)}
|
||||||
</FormControl>
|
/>
|
||||||
)}
|
{accessTokenTrustedIpsFields.map(({ id }, index) => (
|
||||||
/>
|
<div className="mb-3 flex items-end space-x-2" key={id}>
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
defaultValue="0"
|
name={`accessTokenTrustedIps.${index}.ipAddress`}
|
||||||
name="accessTokenNumUsesLimit"
|
defaultValue="0.0.0.0/0"
|
||||||
render={({ field, fieldState: { error } }) => (
|
render={({ field, fieldState: { error } }) => {
|
||||||
<FormControl
|
return (
|
||||||
label="Access Token Max Number of Uses"
|
<FormControl
|
||||||
isError={Boolean(error)}
|
className="mb-0 flex-grow"
|
||||||
errorText={error?.message}
|
label={index === 0 ? "Access Token Trusted IPs" : undefined}
|
||||||
>
|
isError={Boolean(error)}
|
||||||
<Input {...field} placeholder="0" type="number" min="0" step="1" />
|
errorText={error?.message}
|
||||||
</FormControl>
|
>
|
||||||
)}
|
<Input
|
||||||
/>
|
value={field.value}
|
||||||
{accessTokenTrustedIpsFields.map(({ id }, index) => (
|
onChange={(e) => {
|
||||||
<div className="mb-3 flex items-end space-x-2" key={id}>
|
if (subscription?.ipAllowlisting) {
|
||||||
<Controller
|
field.onChange(e);
|
||||||
control={control}
|
return;
|
||||||
name={`accessTokenTrustedIps.${index}.ipAddress`}
|
}
|
||||||
defaultValue="0.0.0.0/0"
|
|
||||||
render={({ field, fieldState: { error } }) => {
|
|
||||||
return (
|
|
||||||
<FormControl
|
|
||||||
className="mb-0 flex-grow"
|
|
||||||
label={index === 0 ? "Access Token Trusted IPs" : undefined}
|
|
||||||
isError={Boolean(error)}
|
|
||||||
errorText={error?.message}
|
|
||||||
>
|
|
||||||
<Input
|
|
||||||
value={field.value}
|
|
||||||
onChange={(e) => {
|
|
||||||
if (subscription?.ipAllowlisting) {
|
|
||||||
field.onChange(e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
handlePopUpOpen("upgradePlan");
|
handlePopUpOpen("upgradePlan");
|
||||||
}}
|
}}
|
||||||
placeholder="123.456.789.0"
|
placeholder="123.456.789.0"
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
onClick={() => {
|
||||||
|
if (subscription?.ipAllowlisting) {
|
||||||
|
removeAccessTokenTrustedIp(index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePopUpOpen("upgradePlan");
|
||||||
|
}}
|
||||||
|
size="lg"
|
||||||
|
colorSchema="danger"
|
||||||
|
variant="plain"
|
||||||
|
ariaLabel="update"
|
||||||
|
className="p-3"
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faXmark} />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
<div className="my-4 ml-1">
|
||||||
|
<Button
|
||||||
|
variant="outline_bg"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (subscription?.ipAllowlisting) {
|
if (subscription?.ipAllowlisting) {
|
||||||
removeAccessTokenTrustedIp(index);
|
appendAccessTokenTrustedIp({
|
||||||
|
ipAddress: "0.0.0.0/0"
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePopUpOpen("upgradePlan");
|
handlePopUpOpen("upgradePlan");
|
||||||
}}
|
}}
|
||||||
size="lg"
|
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
||||||
colorSchema="danger"
|
size="xs"
|
||||||
variant="plain"
|
|
||||||
ariaLabel="update"
|
|
||||||
className="p-3"
|
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faXmark} />
|
Add IP Address
|
||||||
</IconButton>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
))}
|
<div className="flex justify-between">
|
||||||
<div className="my-4 ml-1">
|
<div className="flex items-center">
|
||||||
<Button
|
{initialAuthMethod && identityAuthMethodData?.authMethod !== initialAuthMethod ? (
|
||||||
variant="outline_bg"
|
<Button
|
||||||
onClick={() => {
|
className="mr-4"
|
||||||
if (subscription?.ipAllowlisting) {
|
size="sm"
|
||||||
appendAccessTokenTrustedIp({
|
isLoading={isSubmitting}
|
||||||
ipAddress: "0.0.0.0/0"
|
isDisabled={isSubmitting}
|
||||||
});
|
onClick={() => internalPopUpState.handlePopUpToggle("overwriteAuthMethod", true)}
|
||||||
return;
|
>
|
||||||
}
|
Overwrite
|
||||||
|
</Button>
|
||||||
handlePopUpOpen("upgradePlan");
|
) : (
|
||||||
}}
|
<Button
|
||||||
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
className="mr-4"
|
||||||
size="xs"
|
size="sm"
|
||||||
>
|
type="submit"
|
||||||
Add IP Address
|
isLoading={isSubmitting}
|
||||||
</Button>
|
isDisabled={isSubmitting}
|
||||||
</div>
|
>
|
||||||
<div className="flex justify-between">
|
Submit
|
||||||
<div className="flex items-center">
|
</Button>
|
||||||
{(initialAuthMethod && identityAuthMethodData?.authMethod !== initialAuthMethod) ?
|
)}
|
||||||
<Button
|
<Button
|
||||||
className="mr-4"
|
colorSchema="secondary"
|
||||||
size="sm"
|
variant="plain"
|
||||||
isLoading={isSubmitting}
|
onClick={() => handlePopUpToggle("identityAuthMethod", false)}
|
||||||
isDisabled={isSubmitting}
|
|
||||||
onClick={() => popup.handlePopUpToggle("overwriteAuthMethod", true)}
|
|
||||||
>
|
>
|
||||||
Overwrite
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
: <Button
|
</div>
|
||||||
className="mr-4"
|
{isCurrentAuthMethod && (
|
||||||
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
type="submit"
|
colorSchema="danger"
|
||||||
isLoading={isSubmitting}
|
isLoading={isSubmitting}
|
||||||
isDisabled={isSubmitting}
|
isDisabled={isSubmitting}
|
||||||
>Submit</Button>
|
onClick={() => handlePopUpToggle("revokeAuthMethod", true)}
|
||||||
}
|
>
|
||||||
<Button
|
Remove Auth Method
|
||||||
colorSchema="secondary"
|
</Button>
|
||||||
variant="plain"
|
)}
|
||||||
onClick={() => handlePopUpToggle("identityAuthMethod", false)}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
{identityAuthMethodData?.authMethod === initialAuthMethod && (
|
</form>
|
||||||
<Button
|
|
||||||
size="sm"
|
|
||||||
colorSchema="danger"
|
|
||||||
isLoading={isSubmitting}
|
|
||||||
isDisabled={isSubmitting}
|
|
||||||
onClick={() => handlePopUpToggle("revokeAuthMethod", true)}
|
|
||||||
>
|
|
||||||
Remove Auth Method
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<DeleteActionModal
|
<DeleteActionModal
|
||||||
isOpen={popup.popUp.overwriteAuthMethod?.isOpen}
|
isOpen={internalPopUpState.popUp.overwriteAuthMethod?.isOpen}
|
||||||
title={`Are you sure want to overwrite ${
|
title={`Are you sure want to overwrite ${initialAuthMethod || "the auth method"} on ${
|
||||||
initialAuthMethod || "the auth method"
|
identityAuthMethodData?.name ?? ""
|
||||||
} on ${identityAuthMethodData?.name ?? ""}?`}
|
}?`}
|
||||||
onChange={(isOpen) => popup.handlePopUpToggle("overwriteAuthMethod", isOpen)}
|
onChange={(isOpen) => internalPopUpState.handlePopUpToggle("overwriteAuthMethod", isOpen)}
|
||||||
deleteKey="confirm"
|
deleteKey="confirm"
|
||||||
onDeleteApproved={async () => {
|
buttonText="Overwrite"
|
||||||
const result = await trigger();
|
onDeleteApproved={async () => {
|
||||||
if(result){
|
const result = await trigger();
|
||||||
await revokeAuth(initialAuthMethod);
|
if (result) {
|
||||||
handleSubmit(onFormSubmit)();
|
await revokeAuth(initialAuthMethod);
|
||||||
}else{
|
handleSubmit(onFormSubmit)();
|
||||||
createNotification({
|
} else {
|
||||||
text: "Please fill in all required fields",
|
createNotification({
|
||||||
type: "error"
|
text: "Please fill in all required fields",
|
||||||
});
|
type: "error"
|
||||||
popup.handlePopUpToggle("overwriteAuthMethod", false);
|
});
|
||||||
}
|
internalPopUpState.handlePopUpToggle("overwriteAuthMethod", false);
|
||||||
}}
|
}
|
||||||
/>
|
}}
|
||||||
</form>
|
/>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
+160
-150
@@ -65,10 +65,11 @@ export const IdentityTokenAuthForm = ({
|
|||||||
const { mutateAsync: addMutateAsync } = useAddIdentityTokenAuth();
|
const { mutateAsync: addMutateAsync } = useAddIdentityTokenAuth();
|
||||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityTokenAuth();
|
const { mutateAsync: updateMutateAsync } = useUpdateIdentityTokenAuth();
|
||||||
|
|
||||||
const { data } = useGetIdentityTokenAuth(identityAuthMethodData?.identityId ?? "");
|
const isCurrentAuthMethod = identityAuthMethodData?.authMethod === initialAuthMethod;
|
||||||
const popup = usePopUp([
|
const { data } = useGetIdentityTokenAuth(identityAuthMethodData?.identityId ?? "", {
|
||||||
"overwriteAuthMethod",
|
enabled: isCurrentAuthMethod
|
||||||
] as const);
|
});
|
||||||
|
const internalPopUpState = usePopUp(["overwriteAuthMethod"] as const);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
@@ -123,180 +124,189 @@ export const IdentityTokenAuthForm = ({
|
|||||||
handlePopUpToggle("identityAuthMethod", false);
|
handlePopUpToggle("identityAuthMethod", false);
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
text: `Successfully ${identityAuthMethodData?.authMethod === initialAuthMethod ? "updated" : "configured"
|
text: `Successfully ${isCurrentAuthMethod ? "updated" : "configured"} auth method`,
|
||||||
} auth method`,
|
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
createNotification({
|
createNotification({
|
||||||
text: `Failed to ${identityAuthMethodData?.authMethod === initialAuthMethod ? "update" : "configure"} identity`,
|
text: `Failed to ${isCurrentAuthMethod ? "update" : "configure"} identity`,
|
||||||
type: "error"
|
type: "error"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit(onFormSubmit)}>
|
<>
|
||||||
<Controller
|
<form onSubmit={handleSubmit(onFormSubmit)}>
|
||||||
control={control}
|
<Controller
|
||||||
defaultValue="2592000"
|
control={control}
|
||||||
name="accessTokenTTL"
|
defaultValue="2592000"
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="accessTokenTTL"
|
||||||
<FormControl
|
render={({ field, fieldState: { error } }) => (
|
||||||
label="Access Token TTL (seconds)"
|
<FormControl
|
||||||
isError={Boolean(error)}
|
label="Access Token TTL (seconds)"
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
>
|
errorText={error?.message}
|
||||||
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
>
|
||||||
</FormControl>
|
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
||||||
)}
|
</FormControl>
|
||||||
/>
|
)}
|
||||||
<Controller
|
/>
|
||||||
control={control}
|
<Controller
|
||||||
defaultValue="2592000"
|
control={control}
|
||||||
name="accessTokenMaxTTL"
|
defaultValue="2592000"
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="accessTokenMaxTTL"
|
||||||
<FormControl
|
render={({ field, fieldState: { error } }) => (
|
||||||
label="Access Token Max TTL (seconds)"
|
<FormControl
|
||||||
isError={Boolean(error)}
|
label="Access Token Max TTL (seconds)"
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
>
|
errorText={error?.message}
|
||||||
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
>
|
||||||
</FormControl>
|
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
||||||
)}
|
</FormControl>
|
||||||
/>
|
)}
|
||||||
<Controller
|
/>
|
||||||
control={control}
|
<Controller
|
||||||
defaultValue="0"
|
control={control}
|
||||||
name="accessTokenNumUsesLimit"
|
defaultValue="0"
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="accessTokenNumUsesLimit"
|
||||||
<FormControl
|
render={({ field, fieldState: { error } }) => (
|
||||||
label="Access Token Max Number of Uses"
|
<FormControl
|
||||||
isError={Boolean(error)}
|
label="Access Token Max Number of Uses"
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
>
|
errorText={error?.message}
|
||||||
<Input {...field} placeholder="0" type="number" min="0" step="1" />
|
>
|
||||||
</FormControl>
|
<Input {...field} placeholder="0" type="number" min="0" step="1" />
|
||||||
)}
|
</FormControl>
|
||||||
/>
|
)}
|
||||||
{accessTokenTrustedIpsFields.map(({ id }, index) => (
|
/>
|
||||||
<div className="mb-3 flex items-end space-x-2" key={id}>
|
{accessTokenTrustedIpsFields.map(({ id }, index) => (
|
||||||
<Controller
|
<div className="mb-3 flex items-end space-x-2" key={id}>
|
||||||
control={control}
|
<Controller
|
||||||
name={`accessTokenTrustedIps.${index}.ipAddress`}
|
control={control}
|
||||||
defaultValue="0.0.0.0/0"
|
name={`accessTokenTrustedIps.${index}.ipAddress`}
|
||||||
render={({ field, fieldState: { error } }) => {
|
defaultValue="0.0.0.0/0"
|
||||||
return (
|
render={({ field, fieldState: { error } }) => {
|
||||||
<FormControl
|
return (
|
||||||
className="mb-0 flex-grow"
|
<FormControl
|
||||||
label={index === 0 ? "Access Token Trusted IPs" : undefined}
|
className="mb-0 flex-grow"
|
||||||
isError={Boolean(error)}
|
label={index === 0 ? "Access Token Trusted IPs" : undefined}
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
>
|
errorText={error?.message}
|
||||||
<Input
|
>
|
||||||
value={field.value}
|
<Input
|
||||||
onChange={(e) => {
|
value={field.value}
|
||||||
if (subscription?.ipAllowlisting) {
|
onChange={(e) => {
|
||||||
field.onChange(e);
|
if (subscription?.ipAllowlisting) {
|
||||||
return;
|
field.onChange(e);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
handlePopUpOpen("upgradePlan");
|
handlePopUpOpen("upgradePlan");
|
||||||
}}
|
}}
|
||||||
placeholder="123.456.789.0"
|
placeholder="123.456.789.0"
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
onClick={() => {
|
||||||
|
if (subscription?.ipAllowlisting) {
|
||||||
|
removeAccessTokenTrustedIp(index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePopUpOpen("upgradePlan");
|
||||||
|
}}
|
||||||
|
size="lg"
|
||||||
|
colorSchema="danger"
|
||||||
|
variant="plain"
|
||||||
|
ariaLabel="update"
|
||||||
|
className="p-3"
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faXmark} />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
<div className="my-4 ml-1">
|
||||||
|
<Button
|
||||||
|
variant="outline_bg"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (subscription?.ipAllowlisting) {
|
if (subscription?.ipAllowlisting) {
|
||||||
removeAccessTokenTrustedIp(index);
|
appendAccessTokenTrustedIp({
|
||||||
|
ipAddress: "0.0.0.0/0"
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePopUpOpen("upgradePlan");
|
handlePopUpOpen("upgradePlan");
|
||||||
}}
|
}}
|
||||||
size="lg"
|
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
||||||
colorSchema="danger"
|
size="xs"
|
||||||
variant="plain"
|
|
||||||
ariaLabel="update"
|
|
||||||
className="p-3"
|
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faXmark} />
|
Add IP Address
|
||||||
</IconButton>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
))}
|
<div className="flex justify-between">
|
||||||
<div className="my-4 ml-1">
|
<div className="flex items-center">
|
||||||
<Button
|
{initialAuthMethod && identityAuthMethodData?.authMethod !== initialAuthMethod ? (
|
||||||
variant="outline_bg"
|
<Button
|
||||||
onClick={() => {
|
className="mr-4"
|
||||||
if (subscription?.ipAllowlisting) {
|
size="sm"
|
||||||
appendAccessTokenTrustedIp({
|
isLoading={isSubmitting}
|
||||||
ipAddress: "0.0.0.0/0"
|
isDisabled={isSubmitting}
|
||||||
});
|
onClick={() => internalPopUpState.handlePopUpToggle("overwriteAuthMethod", true)}
|
||||||
return;
|
>
|
||||||
}
|
Overwrite
|
||||||
|
</Button>
|
||||||
handlePopUpOpen("upgradePlan");
|
) : (
|
||||||
}}
|
<Button
|
||||||
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
className="mr-4"
|
||||||
size="xs"
|
size="sm"
|
||||||
>
|
type="submit"
|
||||||
Add IP Address
|
isLoading={isSubmitting}
|
||||||
</Button>
|
isDisabled={isSubmitting}
|
||||||
</div>
|
>
|
||||||
<div className="flex justify-between">
|
Submit
|
||||||
<div className="flex items-center">
|
</Button>
|
||||||
{(initialAuthMethod && identityAuthMethodData?.authMethod !== initialAuthMethod) ?
|
)}
|
||||||
<Button
|
<Button
|
||||||
className="mr-4"
|
colorSchema="secondary"
|
||||||
size="sm"
|
variant="plain"
|
||||||
isLoading={isSubmitting}
|
onClick={() => handlePopUpToggle("identityAuthMethod", false)}
|
||||||
isDisabled={isSubmitting}
|
>
|
||||||
onClick={() => popup.handlePopUpToggle("overwriteAuthMethod", true)}>
|
Cancel
|
||||||
Overwrite
|
|
||||||
</Button>
|
</Button>
|
||||||
: <Button
|
</div>
|
||||||
className="mr-4"
|
{isCurrentAuthMethod && (
|
||||||
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
type="submit"
|
colorSchema="danger"
|
||||||
isLoading={isSubmitting}
|
isLoading={isSubmitting}
|
||||||
isDisabled={isSubmitting}
|
isDisabled={isSubmitting}
|
||||||
>Submit</Button>
|
onClick={() => handlePopUpToggle("revokeAuthMethod", true)}
|
||||||
}
|
>
|
||||||
<Button
|
Remove Auth Method
|
||||||
colorSchema="secondary"
|
</Button>
|
||||||
variant="plain"
|
)}
|
||||||
onClick={() => handlePopUpToggle("identityAuthMethod", false)}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
{identityAuthMethodData?.authMethod === initialAuthMethod && (
|
</form>
|
||||||
<Button
|
|
||||||
size="sm"
|
|
||||||
colorSchema="danger"
|
|
||||||
isLoading={isSubmitting}
|
|
||||||
isDisabled={isSubmitting}
|
|
||||||
onClick={() => handlePopUpToggle("revokeAuthMethod", true)}
|
|
||||||
>
|
|
||||||
Remove Auth Method
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<DeleteActionModal
|
<DeleteActionModal
|
||||||
isOpen={popup.popUp.overwriteAuthMethod?.isOpen}
|
isOpen={internalPopUpState.popUp.overwriteAuthMethod?.isOpen}
|
||||||
title={`Are you sure want to overwrite ${
|
title={`Are you sure want to overwrite ${initialAuthMethod || "the auth method"} on ${
|
||||||
initialAuthMethod || "the auth method"
|
identityAuthMethodData?.name ?? ""
|
||||||
} on ${identityAuthMethodData?.name ?? ""}?`}
|
}?`}
|
||||||
onChange={(isOpen) => popup.handlePopUpToggle("overwriteAuthMethod", isOpen)}
|
onChange={(isOpen) => internalPopUpState.handlePopUpToggle("overwriteAuthMethod", isOpen)}
|
||||||
deleteKey="confirm"
|
deleteKey="confirm"
|
||||||
onDeleteApproved={async () => { await revokeAuth(initialAuthMethod); handleSubmit(onFormSubmit)(); }}
|
buttonText="Overwrite"
|
||||||
/>
|
onDeleteApproved={async () => {
|
||||||
</form>
|
await revokeAuth(initialAuthMethod);
|
||||||
|
handleSubmit(onFormSubmit)();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
+236
-226
@@ -86,10 +86,12 @@ export const IdentityUniversalAuthForm = ({
|
|||||||
const { subscription } = useSubscription();
|
const { subscription } = useSubscription();
|
||||||
const { mutateAsync: addMutateAsync } = useAddIdentityUniversalAuth();
|
const { mutateAsync: addMutateAsync } = useAddIdentityUniversalAuth();
|
||||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityUniversalAuth();
|
const { mutateAsync: updateMutateAsync } = useUpdateIdentityUniversalAuth();
|
||||||
const { data } = useGetIdentityUniversalAuth(identityAuthMethodData?.identityId ?? "");
|
|
||||||
const popup = usePopUp([
|
const isCurrentAuthMethod = identityAuthMethodData?.authMethod === initialAuthMethod;
|
||||||
"overwriteAuthMethod",
|
const { data } = useGetIdentityUniversalAuth(identityAuthMethodData?.identityId ?? "", {
|
||||||
] as const);
|
enabled: isCurrentAuthMethod
|
||||||
|
});
|
||||||
|
const internalPopUpState = usePopUp(["overwriteAuthMethod"] as const);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
@@ -188,8 +190,7 @@ export const IdentityUniversalAuthForm = ({
|
|||||||
handlePopUpToggle("identityAuthMethod", false);
|
handlePopUpToggle("identityAuthMethod", false);
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
text: `Successfully ${identityAuthMethodData?.authMethod === initialAuthMethod ? "updated" : "configured"
|
text: `Successfully ${isCurrentAuthMethod ? "updated" : "configured"} auth method`,
|
||||||
} auth method`,
|
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -209,234 +210,243 @@ export const IdentityUniversalAuthForm = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit(onFormSubmit)}>
|
<>
|
||||||
<Controller
|
<form onSubmit={handleSubmit(onFormSubmit)}>
|
||||||
control={control}
|
<Controller
|
||||||
defaultValue="2592000"
|
control={control}
|
||||||
name="accessTokenTTL"
|
defaultValue="2592000"
|
||||||
render={({ field, fieldState: { error } }) => (
|
name="accessTokenTTL"
|
||||||
<FormControl
|
render={({ field, fieldState: { error } }) => (
|
||||||
label="Access Token TTL (seconds)"
|
<FormControl
|
||||||
isError={Boolean(error)}
|
label="Access Token TTL (seconds)"
|
||||||
errorText={error?.message}
|
isError={Boolean(error)}
|
||||||
>
|
errorText={error?.message}
|
||||||
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
defaultValue="2592000"
|
|
||||||
name="accessTokenMaxTTL"
|
|
||||||
render={({ field, fieldState: { error } }) => (
|
|
||||||
<FormControl
|
|
||||||
label="Access Token Max TTL (seconds)"
|
|
||||||
isError={Boolean(error)}
|
|
||||||
errorText={error?.message}
|
|
||||||
>
|
|
||||||
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
defaultValue="0"
|
|
||||||
name="accessTokenNumUsesLimit"
|
|
||||||
render={({ field, fieldState: { error } }) => (
|
|
||||||
<FormControl
|
|
||||||
label="Access Token Max Number of Uses"
|
|
||||||
isError={Boolean(error)}
|
|
||||||
errorText={error?.message}
|
|
||||||
>
|
|
||||||
<Input {...field} placeholder="0" type="number" min="0" step="1" />
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
{clientSecretTrustedIpsFields.map(({ id }, index) => (
|
|
||||||
<div className="mb-3 flex items-end space-x-2" key={id}>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
name={`clientSecretTrustedIps.${index}.ipAddress`}
|
|
||||||
defaultValue="0.0.0.0/0"
|
|
||||||
render={({ field, fieldState: { error } }) => {
|
|
||||||
return (
|
|
||||||
<FormControl
|
|
||||||
className="mb-0 flex-grow"
|
|
||||||
label={index === 0 ? "Client Secret Trusted IPs" : undefined}
|
|
||||||
isError={Boolean(error)}
|
|
||||||
errorText={error?.message}
|
|
||||||
>
|
|
||||||
<Input
|
|
||||||
value={field.value}
|
|
||||||
onChange={(e) => {
|
|
||||||
if (subscription?.ipAllowlisting) {
|
|
||||||
field.onChange(e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
handlePopUpOpen("upgradePlan");
|
|
||||||
}}
|
|
||||||
placeholder="123.456.789.0"
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<IconButton
|
|
||||||
onClick={() => {
|
|
||||||
if (subscription?.ipAllowlisting) {
|
|
||||||
removeClientSecretTrustedIp(index);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
handlePopUpOpen("upgradePlan");
|
|
||||||
}}
|
|
||||||
size="lg"
|
|
||||||
colorSchema="danger"
|
|
||||||
variant="plain"
|
|
||||||
ariaLabel="update"
|
|
||||||
className="p-3"
|
|
||||||
>
|
|
||||||
<FontAwesomeIcon icon={faXmark} />
|
|
||||||
</IconButton>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
<div className="my-4 ml-1">
|
|
||||||
<Button
|
|
||||||
variant="outline_bg"
|
|
||||||
onClick={() => {
|
|
||||||
if (subscription?.ipAllowlisting) {
|
|
||||||
appendClientSecretTrustedIp({
|
|
||||||
ipAddress: "0.0.0.0/0"
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
handlePopUpOpen("upgradePlan");
|
|
||||||
}}
|
|
||||||
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
Add IP Address
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
{accessTokenTrustedIpsFields.map(({ id }, index) => (
|
|
||||||
<div className="mb-3 flex items-end space-x-2" key={id}>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
name={`accessTokenTrustedIps.${index}.ipAddress`}
|
|
||||||
defaultValue="0.0.0.0/0"
|
|
||||||
render={({ field, fieldState: { error } }) => {
|
|
||||||
return (
|
|
||||||
<FormControl
|
|
||||||
className="mb-0 flex-grow"
|
|
||||||
label={index === 0 ? "Access Token Trusted IPs" : undefined}
|
|
||||||
isError={Boolean(error)}
|
|
||||||
errorText={error?.message}
|
|
||||||
>
|
|
||||||
<Input
|
|
||||||
value={field.value}
|
|
||||||
onChange={(e) => {
|
|
||||||
if (subscription?.ipAllowlisting) {
|
|
||||||
field.onChange(e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
handlePopUpOpen("upgradePlan");
|
|
||||||
}}
|
|
||||||
placeholder="123.456.789.0"
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<IconButton
|
|
||||||
onClick={() => {
|
|
||||||
if (subscription?.ipAllowlisting) {
|
|
||||||
removeAccessTokenTrustedIp(index);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
handlePopUpOpen("upgradePlan");
|
|
||||||
}}
|
|
||||||
size="lg"
|
|
||||||
colorSchema="danger"
|
|
||||||
variant="plain"
|
|
||||||
ariaLabel="update"
|
|
||||||
className="p-3"
|
|
||||||
>
|
|
||||||
<FontAwesomeIcon icon={faXmark} />
|
|
||||||
</IconButton>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
<div className="my-4 ml-1">
|
|
||||||
<Button
|
|
||||||
variant="outline_bg"
|
|
||||||
onClick={() => {
|
|
||||||
if (subscription?.ipAllowlisting) {
|
|
||||||
appendAccessTokenTrustedIp({
|
|
||||||
ipAddress: "0.0.0.0/0"
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
handlePopUpOpen("upgradePlan");
|
|
||||||
}}
|
|
||||||
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
Add IP Address
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<div className="flex justify-between">
|
|
||||||
<div className="flex items-center">
|
|
||||||
{(initialAuthMethod && identityAuthMethodData?.authMethod !== initialAuthMethod) ?
|
|
||||||
<Button
|
|
||||||
className="mr-4"
|
|
||||||
size="sm"
|
|
||||||
isLoading={isSubmitting}
|
|
||||||
isDisabled={isSubmitting}
|
|
||||||
onClick={() => popup.handlePopUpToggle("overwriteAuthMethod", true)}
|
|
||||||
>
|
>
|
||||||
Overwrite
|
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
||||||
</Button>
|
</FormControl>
|
||||||
: <Button
|
)}
|
||||||
className="mr-4"
|
/>
|
||||||
size="sm"
|
<Controller
|
||||||
type="submit"
|
control={control}
|
||||||
isLoading={isSubmitting}
|
defaultValue="2592000"
|
||||||
isDisabled={isSubmitting}
|
name="accessTokenMaxTTL"
|
||||||
>Submit</Button>
|
render={({ field, fieldState: { error } }) => (
|
||||||
}
|
<FormControl
|
||||||
|
label="Access Token Max TTL (seconds)"
|
||||||
|
isError={Boolean(error)}
|
||||||
|
errorText={error?.message}
|
||||||
|
>
|
||||||
|
<Input {...field} placeholder="2592000" type="number" min="1" step="1" />
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
defaultValue="0"
|
||||||
|
name="accessTokenNumUsesLimit"
|
||||||
|
render={({ field, fieldState: { error } }) => (
|
||||||
|
<FormControl
|
||||||
|
label="Access Token Max Number of Uses"
|
||||||
|
isError={Boolean(error)}
|
||||||
|
errorText={error?.message}
|
||||||
|
>
|
||||||
|
<Input {...field} placeholder="0" type="number" min="0" step="1" />
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{clientSecretTrustedIpsFields.map(({ id }, index) => (
|
||||||
|
<div className="mb-3 flex items-end space-x-2" key={id}>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name={`clientSecretTrustedIps.${index}.ipAddress`}
|
||||||
|
defaultValue="0.0.0.0/0"
|
||||||
|
render={({ field, fieldState: { error } }) => {
|
||||||
|
return (
|
||||||
|
<FormControl
|
||||||
|
className="mb-0 flex-grow"
|
||||||
|
label={index === 0 ? "Client Secret Trusted IPs" : undefined}
|
||||||
|
isError={Boolean(error)}
|
||||||
|
errorText={error?.message}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
value={field.value}
|
||||||
|
onChange={(e) => {
|
||||||
|
if (subscription?.ipAllowlisting) {
|
||||||
|
field.onChange(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePopUpOpen("upgradePlan");
|
||||||
|
}}
|
||||||
|
placeholder="123.456.789.0"
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<IconButton
|
||||||
|
onClick={() => {
|
||||||
|
if (subscription?.ipAllowlisting) {
|
||||||
|
removeClientSecretTrustedIp(index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePopUpOpen("upgradePlan");
|
||||||
|
}}
|
||||||
|
size="lg"
|
||||||
|
colorSchema="danger"
|
||||||
|
variant="plain"
|
||||||
|
ariaLabel="update"
|
||||||
|
className="p-3"
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faXmark} />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
<div className="my-4 ml-1">
|
||||||
<Button
|
<Button
|
||||||
colorSchema="secondary"
|
variant="outline_bg"
|
||||||
variant="plain"
|
onClick={() => {
|
||||||
onClick={() => handlePopUpToggle("identityAuthMethod", false)}
|
if (subscription?.ipAllowlisting) {
|
||||||
|
appendClientSecretTrustedIp({
|
||||||
|
ipAddress: "0.0.0.0/0"
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePopUpOpen("upgradePlan");
|
||||||
|
}}
|
||||||
|
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
||||||
|
size="xs"
|
||||||
>
|
>
|
||||||
Cancel
|
Add IP Address
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
{identityAuthMethodData?.authMethod === initialAuthMethod && (
|
{accessTokenTrustedIpsFields.map(({ id }, index) => (
|
||||||
|
<div className="mb-3 flex items-end space-x-2" key={id}>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name={`accessTokenTrustedIps.${index}.ipAddress`}
|
||||||
|
defaultValue="0.0.0.0/0"
|
||||||
|
render={({ field, fieldState: { error } }) => {
|
||||||
|
return (
|
||||||
|
<FormControl
|
||||||
|
className="mb-0 flex-grow"
|
||||||
|
label={index === 0 ? "Access Token Trusted IPs" : undefined}
|
||||||
|
isError={Boolean(error)}
|
||||||
|
errorText={error?.message}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
value={field.value}
|
||||||
|
onChange={(e) => {
|
||||||
|
if (subscription?.ipAllowlisting) {
|
||||||
|
field.onChange(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePopUpOpen("upgradePlan");
|
||||||
|
}}
|
||||||
|
placeholder="123.456.789.0"
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<IconButton
|
||||||
|
onClick={() => {
|
||||||
|
if (subscription?.ipAllowlisting) {
|
||||||
|
removeAccessTokenTrustedIp(index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePopUpOpen("upgradePlan");
|
||||||
|
}}
|
||||||
|
size="lg"
|
||||||
|
colorSchema="danger"
|
||||||
|
variant="plain"
|
||||||
|
ariaLabel="update"
|
||||||
|
className="p-3"
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faXmark} />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
<div className="my-4 ml-1">
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
variant="outline_bg"
|
||||||
colorSchema="danger"
|
onClick={() => {
|
||||||
isLoading={isSubmitting}
|
if (subscription?.ipAllowlisting) {
|
||||||
isDisabled={isSubmitting}
|
appendAccessTokenTrustedIp({
|
||||||
onClick={() => handlePopUpToggle("revokeAuthMethod", true)}
|
ipAddress: "0.0.0.0/0"
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePopUpOpen("upgradePlan");
|
||||||
|
}}
|
||||||
|
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
||||||
|
size="xs"
|
||||||
>
|
>
|
||||||
Remove Auth Method
|
Add IP Address
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
</div>
|
||||||
</div>
|
<div className="flex justify-between">
|
||||||
|
<div className="flex items-center">
|
||||||
|
{initialAuthMethod && identityAuthMethodData?.authMethod !== initialAuthMethod ? (
|
||||||
|
<Button
|
||||||
|
className="mr-4"
|
||||||
|
size="sm"
|
||||||
|
isLoading={isSubmitting}
|
||||||
|
isDisabled={isSubmitting}
|
||||||
|
onClick={() => internalPopUpState.handlePopUpToggle("overwriteAuthMethod", true)}
|
||||||
|
>
|
||||||
|
Overwrite
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<Button
|
||||||
|
className="mr-4"
|
||||||
|
size="sm"
|
||||||
|
type="submit"
|
||||||
|
isLoading={isSubmitting}
|
||||||
|
isDisabled={isSubmitting}
|
||||||
|
>
|
||||||
|
Submit
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
<Button
|
||||||
|
colorSchema="secondary"
|
||||||
|
variant="plain"
|
||||||
|
onClick={() => handlePopUpToggle("identityAuthMethod", false)}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
{isCurrentAuthMethod && (
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
colorSchema="danger"
|
||||||
|
isLoading={isSubmitting}
|
||||||
|
isDisabled={isSubmitting}
|
||||||
|
onClick={() => handlePopUpToggle("revokeAuthMethod", true)}
|
||||||
|
>
|
||||||
|
Remove Auth Method
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
<DeleteActionModal
|
<DeleteActionModal
|
||||||
isOpen={popup.popUp.overwriteAuthMethod?.isOpen}
|
isOpen={internalPopUpState.popUp.overwriteAuthMethod?.isOpen}
|
||||||
title={`Are you sure want to overwrite ${
|
title={`Are you sure want to overwrite ${initialAuthMethod || "the auth method"} on ${
|
||||||
initialAuthMethod || "the auth method"
|
identityAuthMethodData?.name ?? ""
|
||||||
} on ${identityAuthMethodData?.name ?? ""}?`}
|
}?`}
|
||||||
onChange={(isOpen) => popup.handlePopUpToggle("overwriteAuthMethod", isOpen)}
|
onChange={(isOpen) => internalPopUpState.handlePopUpToggle("overwriteAuthMethod", isOpen)}
|
||||||
deleteKey="confirm"
|
deleteKey="confirm"
|
||||||
onDeleteApproved={async () => { await revokeAuth(initialAuthMethod); handleSubmit(onFormSubmit)(); }}
|
buttonText="Overwrite"
|
||||||
/>
|
onDeleteApproved={async () => {
|
||||||
</form>
|
await revokeAuth(initialAuthMethod);
|
||||||
|
handleSubmit(onFormSubmit)();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user