mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-08 12:28:54 +00:00
Merge pull request #1517 from rhythmbhiwani/fix-rename-bug
Stop ability to rename a secret to empty name from frontend
This commit is contained in:
@@ -375,6 +375,10 @@ export const secretServiceFactory = ({
|
|||||||
|
|
||||||
await projectDAL.checkProjectUpgradeStatus(projectId);
|
await projectDAL.checkProjectUpgradeStatus(projectId);
|
||||||
|
|
||||||
|
if (inputSecret.newSecretName === "") {
|
||||||
|
throw new BadRequestError({ message: "New secret name cannot be empty" });
|
||||||
|
}
|
||||||
|
|
||||||
const folder = await folderDAL.findBySecretPath(projectId, environment, path);
|
const folder = await folderDAL.findBySecretPath(projectId, environment, path);
|
||||||
if (!folder) throw new BadRequestError({ message: "Folder not found", name: "Create secret" });
|
if (!folder) throw new BadRequestError({ message: "Folder not found", name: "Create secret" });
|
||||||
const folderId = folder.id;
|
const folderId = folder.id;
|
||||||
|
|||||||
@@ -1,24 +1,4 @@
|
|||||||
/* eslint-disable simple-import-sort/imports */
|
/* eslint-disable simple-import-sort/imports */
|
||||||
import { memo, useEffect } from "react";
|
|
||||||
import { Controller, useFieldArray, useForm } from "react-hook-form";
|
|
||||||
import { subject } from "@casl/ability";
|
|
||||||
import { faCheckCircle } from "@fortawesome/free-regular-svg-icons";
|
|
||||||
import {
|
|
||||||
faCheck,
|
|
||||||
faClock,
|
|
||||||
faClose,
|
|
||||||
faCodeBranch,
|
|
||||||
faComment,
|
|
||||||
faCopy,
|
|
||||||
faEllipsis,
|
|
||||||
faKey,
|
|
||||||
faTag,
|
|
||||||
faTags
|
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import { AnimatePresence, motion } from "framer-motion";
|
|
||||||
import { twMerge } from "tailwind-merge";
|
|
||||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
@@ -48,9 +28,29 @@ import {
|
|||||||
import { useToggle } from "@app/hooks";
|
import { useToggle } from "@app/hooks";
|
||||||
import { DecryptedSecret } from "@app/hooks/api/secrets/types";
|
import { DecryptedSecret } from "@app/hooks/api/secrets/types";
|
||||||
import { WsTag } from "@app/hooks/api/types";
|
import { WsTag } from "@app/hooks/api/types";
|
||||||
|
import { subject } from "@casl/ability";
|
||||||
|
import { faCheckCircle } from "@fortawesome/free-regular-svg-icons";
|
||||||
|
import {
|
||||||
|
faCheck,
|
||||||
|
faClock,
|
||||||
|
faClose,
|
||||||
|
faCodeBranch,
|
||||||
|
faComment,
|
||||||
|
faCopy,
|
||||||
|
faEllipsis,
|
||||||
|
faKey,
|
||||||
|
faTag,
|
||||||
|
faTags
|
||||||
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { AnimatePresence, motion } from "framer-motion";
|
||||||
|
import { memo, useEffect } from "react";
|
||||||
|
import { Controller, useFieldArray, useForm } from "react-hook-form";
|
||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
import { formSchema, SecretActionType, TFormSchema } from "./SecretListView.utils";
|
|
||||||
import { CreateReminderForm } from "./CreateReminderForm";
|
import { CreateReminderForm } from "./CreateReminderForm";
|
||||||
|
import { formSchema, SecretActionType, TFormSchema } from "./SecretListView.utils";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
secret: DecryptedSecret;
|
secret: DecryptedSecret;
|
||||||
@@ -104,7 +104,8 @@ export const SecretItem = memo(
|
|||||||
setValue,
|
setValue,
|
||||||
reset,
|
reset,
|
||||||
getValues,
|
getValues,
|
||||||
formState: { isDirty, isSubmitting }
|
trigger,
|
||||||
|
formState: { isDirty, isSubmitting, errors }
|
||||||
} = useForm<TFormSchema>({
|
} = useForm<TFormSchema>({
|
||||||
defaultValues: secret,
|
defaultValues: secret,
|
||||||
values: secret,
|
values: secret,
|
||||||
@@ -235,15 +236,18 @@ export const SecretItem = memo(
|
|||||||
<Controller
|
<Controller
|
||||||
name="key"
|
name="key"
|
||||||
control={control}
|
control={control}
|
||||||
render={({ field }) => (
|
render={({ field, fieldState: { error } }) => (
|
||||||
<Input
|
<Input
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
isReadOnly={isReadOnly}
|
isReadOnly={isReadOnly}
|
||||||
autoCapitalization={currentWorkspace?.autoCapitalization}
|
autoCapitalization={currentWorkspace?.autoCapitalization}
|
||||||
variant="plain"
|
variant="plain"
|
||||||
isDisabled={isOverriden}
|
isDisabled={isOverriden}
|
||||||
|
placeholder={error?.message}
|
||||||
|
isError={Boolean(error)}
|
||||||
|
onKeyUp={() => trigger("key")}
|
||||||
{...field}
|
{...field}
|
||||||
className="w-full px-0 focus:text-bunker-100 focus:ring-transparent"
|
className="w-full px-0 placeholder:text-red-500 focus:text-bunker-100 focus:ring-transparent"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
@@ -497,7 +501,7 @@ export const SecretItem = memo(
|
|||||||
animate={{ x: 0, opacity: 1 }}
|
animate={{ x: 0, opacity: 1 }}
|
||||||
exit={{ x: -10, opacity: 0 }}
|
exit={{ x: -10, opacity: 0 }}
|
||||||
>
|
>
|
||||||
<Tooltip content="Save">
|
<Tooltip content={errors.key ? errors.key?.message : "Save"}>
|
||||||
<IconButton
|
<IconButton
|
||||||
ariaLabel="more"
|
ariaLabel="more"
|
||||||
variant="plain"
|
variant="plain"
|
||||||
@@ -507,12 +511,16 @@ export const SecretItem = memo(
|
|||||||
"p-0 text-primary opacity-0 group-hover:opacity-100",
|
"p-0 text-primary opacity-0 group-hover:opacity-100",
|
||||||
isDirty && "opacity-100"
|
isDirty && "opacity-100"
|
||||||
)}
|
)}
|
||||||
isDisabled={isSubmitting}
|
isDisabled={isSubmitting || Boolean(errors.key)}
|
||||||
>
|
>
|
||||||
{isSubmitting ? (
|
{isSubmitting ? (
|
||||||
<Spinner className="m-0 h-4 w-4 p-0" />
|
<Spinner className="m-0 h-4 w-4 p-0" />
|
||||||
) : (
|
) : (
|
||||||
<FontAwesomeIcon icon={faCheck} size="lg" className="text-primary" />
|
<FontAwesomeIcon
|
||||||
|
icon={faCheck}
|
||||||
|
size="lg"
|
||||||
|
className={twMerge("text-primary", errors.key && "text-mineshaft-300")}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ export const SecretListView = ({
|
|||||||
reminderRepeatDays,
|
reminderRepeatDays,
|
||||||
reminderNote
|
reminderNote
|
||||||
} = modSecret;
|
} = modSecret;
|
||||||
const hasKeyChanged = oldKey !== key;
|
const hasKeyChanged = oldKey !== key && key;
|
||||||
|
|
||||||
const tagIds = tags?.map(({ id }) => id);
|
const tagIds = tags?.map(({ id }) => id);
|
||||||
const oldTagIds = (orgSecret?.tags || []).map(({ id }) => id);
|
const oldTagIds = (orgSecret?.tags || []).map(({ id }) => id);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export enum SecretActionType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const formSchema = z.object({
|
export const formSchema = z.object({
|
||||||
key: z.string().trim(),
|
key: z.string().trim().min(1, { message: "Secret key is required" }),
|
||||||
value: z.string().transform((val) => (val.at(-1) === "\n" ? `${val.trim()}\n` : val.trim())),
|
value: z.string().transform((val) => (val.at(-1) === "\n" ? `${val.trim()}\n` : val.trim())),
|
||||||
idOverride: z.string().trim().optional(),
|
idOverride: z.string().trim().optional(),
|
||||||
valueOverride: z
|
valueOverride: z
|
||||||
|
|||||||
Reference in New Issue
Block a user