mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-15 19:16:22 +00:00
misc: added audit log and overwrite feature
This commit is contained in:
@@ -383,22 +383,34 @@ export const useMoveSecrets = ({
|
||||
} = {}) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<{}, {}, TMoveSecretsDTO>({
|
||||
return useMutation<
|
||||
{
|
||||
isSourceUpdated: boolean;
|
||||
isDestinationUpdated: boolean;
|
||||
},
|
||||
{},
|
||||
TMoveSecretsDTO
|
||||
>({
|
||||
mutationFn: async ({
|
||||
sourceEnvironment,
|
||||
sourceSecretPath,
|
||||
projectSlug,
|
||||
destinationEnvironment,
|
||||
destinationSecretPath,
|
||||
secretIds
|
||||
secretIds,
|
||||
shouldOverwrite
|
||||
}) => {
|
||||
const { data } = await apiRequest.post("/api/v3/secrets/move", {
|
||||
const { data } = await apiRequest.post<{
|
||||
isSourceUpdated: boolean;
|
||||
isDestinationUpdated: boolean;
|
||||
}>("/api/v3/secrets/move", {
|
||||
sourceEnvironment,
|
||||
sourceSecretPath,
|
||||
projectSlug,
|
||||
destinationEnvironment,
|
||||
destinationSecretPath,
|
||||
secretIds
|
||||
secretIds,
|
||||
shouldOverwrite
|
||||
});
|
||||
|
||||
return data;
|
||||
|
||||
@@ -185,6 +185,7 @@ export type TMoveSecretsDTO = {
|
||||
destinationEnvironment: string;
|
||||
destinationSecretPath: string;
|
||||
secretIds: string[];
|
||||
shouldOverwrite: boolean;
|
||||
};
|
||||
|
||||
export type CreateSecretDTO = {
|
||||
|
||||
@@ -239,15 +239,18 @@ export const ActionBar = ({
|
||||
|
||||
const handleSecretsMove = async ({
|
||||
destinationEnvironment,
|
||||
destinationSecretPath
|
||||
destinationSecretPath,
|
||||
shouldOverwrite
|
||||
}: {
|
||||
destinationEnvironment: string;
|
||||
destinationSecretPath: string;
|
||||
shouldOverwrite: boolean;
|
||||
}) => {
|
||||
try {
|
||||
const secretsToMove = secrets.filter(({ id }) => Boolean(selectedSecrets?.[id]));
|
||||
await moveSecrets({
|
||||
const { isDestinationUpdated, isSourceUpdated } = await moveSecrets({
|
||||
projectSlug,
|
||||
shouldOverwrite,
|
||||
sourceEnvironment: environment,
|
||||
sourceSecretPath: secretPath,
|
||||
destinationEnvironment,
|
||||
@@ -256,10 +259,25 @@ export const ActionBar = ({
|
||||
secretIds: secretsToMove.map((sec) => sec.id)
|
||||
});
|
||||
|
||||
let successMessage = "";
|
||||
if (isDestinationUpdated && isSourceUpdated) {
|
||||
successMessage = "Successfully moved selected secrets";
|
||||
} else if (isDestinationUpdated) {
|
||||
successMessage =
|
||||
"Successfully created secrets in destination. A secret approval request has been generated for the source.";
|
||||
} else if (isSourceUpdated) {
|
||||
successMessage = "A secret approval request has been generated in the destination";
|
||||
} else {
|
||||
successMessage =
|
||||
"A secret approval request has been generated in both the source and the destination.";
|
||||
}
|
||||
|
||||
createNotification({
|
||||
type: "success",
|
||||
text: "Successfully moved selected secrets"
|
||||
text: successMessage
|
||||
});
|
||||
|
||||
resetSelectedSecret();
|
||||
} catch (error) {
|
||||
createNotification({
|
||||
type: "error",
|
||||
|
||||
@@ -2,7 +2,15 @@ import { Controller, useForm } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { z } from "zod";
|
||||
|
||||
import { Button, FormControl, Modal, ModalContent, Select, SelectItem } from "@app/components/v2";
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
FormControl,
|
||||
Modal,
|
||||
ModalContent,
|
||||
Select,
|
||||
SelectItem
|
||||
} from "@app/components/v2";
|
||||
import { SecretPathInput } from "@app/components/v2/SecretPathInput";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
@@ -13,6 +21,7 @@ type Props = {
|
||||
onMoveApproved: (moveParams: {
|
||||
destinationEnvironment: string;
|
||||
destinationSecretPath: string;
|
||||
shouldOverwrite: boolean;
|
||||
}) => void;
|
||||
};
|
||||
|
||||
@@ -23,7 +32,8 @@ const formSchema = z.object({
|
||||
.trim()
|
||||
.transform((val) =>
|
||||
typeof val === "string" && val.at(-1) === "/" && val.length > 1 ? val.slice(0, -1) : val
|
||||
)
|
||||
),
|
||||
shouldOverwrite: z.boolean().default(false)
|
||||
});
|
||||
|
||||
type TFormSchema = z.infer<typeof formSchema>;
|
||||
@@ -44,7 +54,8 @@ export const MoveSecretsModal = ({ popUp, handlePopUpToggle, onMoveApproved }: P
|
||||
const handleFormSubmit = (data: TFormSchema) => {
|
||||
onMoveApproved({
|
||||
destinationEnvironment: data.environment,
|
||||
destinationSecretPath: data.secretPath
|
||||
destinationSecretPath: data.secretPath,
|
||||
shouldOverwrite: data.shouldOverwrite
|
||||
});
|
||||
|
||||
handlePopUpToggle("moveSecrets", false);
|
||||
@@ -60,7 +71,7 @@ export const MoveSecretsModal = ({ popUp, handlePopUpToggle, onMoveApproved }: P
|
||||
>
|
||||
<ModalContent
|
||||
title="Move Secrets"
|
||||
subTitle="Move selected secrets from current path to selected destination"
|
||||
subTitle="Move secrets from the current path to the selected destination"
|
||||
>
|
||||
<form onSubmit={handleSubmit(handleFormSubmit)}>
|
||||
<Controller
|
||||
@@ -94,6 +105,22 @@ export const MoveSecretsModal = ({ popUp, handlePopUpToggle, onMoveApproved }: P
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
control={control}
|
||||
name="shouldOverwrite"
|
||||
defaultValue={false}
|
||||
render={({ field: { onBlur, value, onChange } }) => (
|
||||
<Checkbox
|
||||
id="overwrite-checkbox"
|
||||
className="ml-2"
|
||||
isChecked={value}
|
||||
onCheckedChange={onChange}
|
||||
onBlur={onBlur}
|
||||
>
|
||||
Overwrite existing secrets
|
||||
</Checkbox>
|
||||
)}
|
||||
/>
|
||||
<div className="mt-7 flex items-center">
|
||||
<Button
|
||||
isDisabled={isSubmitting}
|
||||
|
||||
Reference in New Issue
Block a user