From d12c4b7580d4f7832b8be0adf704b129f5e98d08 Mon Sep 17 00:00:00 2001 From: Rhythm Bhiwani Date: Sat, 2 Mar 2024 09:21:46 +0530 Subject: [PATCH 1/5] Stop ability to rename a secret to empty name from frontend --- .../SecretMainPage/components/SecretListView/SecretListView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/views/SecretMainPage/components/SecretListView/SecretListView.tsx b/frontend/src/views/SecretMainPage/components/SecretListView/SecretListView.tsx index 780e49448..db57cb144 100644 --- a/frontend/src/views/SecretMainPage/components/SecretListView/SecretListView.tsx +++ b/frontend/src/views/SecretMainPage/components/SecretListView/SecretListView.tsx @@ -206,7 +206,7 @@ export const SecretListView = ({ reminderRepeatDays, reminderNote } = modSecret; - const hasKeyChanged = oldKey !== key; + const hasKeyChanged = oldKey !== key && key; const tagIds = tags?.map(({ id }) => id); const oldTagIds = (orgSecret?.tags || []).map(({ id }) => id); From 4afb20ad0d896475a591ec76237b18943a78f5c0 Mon Sep 17 00:00:00 2001 From: Rhythm Bhiwani Date: Sat, 2 Mar 2024 19:44:20 +0530 Subject: [PATCH 2/5] Added proper error message when secret name is empty while renaming --- .../components/SecretListView/SecretItem.tsx | 58 +++++++++++-------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/frontend/src/views/SecretMainPage/components/SecretListView/SecretItem.tsx b/frontend/src/views/SecretMainPage/components/SecretListView/SecretItem.tsx index a72463c9a..33661dee7 100644 --- a/frontend/src/views/SecretMainPage/components/SecretListView/SecretItem.tsx +++ b/frontend/src/views/SecretMainPage/components/SecretListView/SecretItem.tsx @@ -1,24 +1,4 @@ /* 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 { Button, @@ -48,9 +28,30 @@ import { import { useToggle } from "@app/hooks"; import { DecryptedSecret } from "@app/hooks/api/secrets/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 { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider"; import { CreateReminderForm } from "./CreateReminderForm"; +import { formSchema, SecretActionType, TFormSchema } from "./SecretListView.utils"; type Props = { secret: DecryptedSecret; @@ -86,6 +87,7 @@ export const SecretItem = memo( }: Props) => { const { currentWorkspace } = useWorkspace(); const { permission } = useProjectPermission(); + const { createNotification } = useNotificationContext(); const isReadOnly = permission.can( ProjectPermissionActions.Read, @@ -235,15 +237,25 @@ export const SecretItem = memo( ( + render={({ field, fieldState: { error } }) => ( { + e.preventDefault(); + createNotification({ + text: "Secret name cannot be empty", + type: "error" + }); + }} {...field} - className="w-full px-0 focus:text-bunker-100 focus:ring-transparent" + className="w-full px-0 placeholder:text-red-600 focus:text-bunker-100 focus:ring-transparent" /> )} /> From e3e4a98cd6b97d8fda703ae4c765696131357346 Mon Sep 17 00:00:00 2001 From: Rhythm Bhiwani Date: Sat, 2 Mar 2024 19:46:04 +0530 Subject: [PATCH 3/5] changed share of red in error message --- .../SecretMainPage/components/SecretListView/SecretItem.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/views/SecretMainPage/components/SecretListView/SecretItem.tsx b/frontend/src/views/SecretMainPage/components/SecretListView/SecretItem.tsx index 33661dee7..3bc66d0a5 100644 --- a/frontend/src/views/SecretMainPage/components/SecretListView/SecretItem.tsx +++ b/frontend/src/views/SecretMainPage/components/SecretListView/SecretItem.tsx @@ -255,7 +255,7 @@ export const SecretItem = memo( }); }} {...field} - className="w-full px-0 placeholder:text-red-600 focus:text-bunker-100 focus:ring-transparent" + className="w-full px-0 placeholder:text-red-500 focus:text-bunker-100 focus:ring-transparent" /> )} /> From 68296c1b994ce2b7f6cb9cb47f236f077f7df3c0 Mon Sep 17 00:00:00 2001 From: Rhythm Bhiwani Date: Sun, 3 Mar 2024 01:37:49 +0530 Subject: [PATCH 4/5] Disabled submit button if secret name is empty --- .../components/SecretListView/SecretItem.tsx | 26 ++++++++----------- .../SecretListView/SecretListView.utils.ts | 2 +- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/frontend/src/views/SecretMainPage/components/SecretListView/SecretItem.tsx b/frontend/src/views/SecretMainPage/components/SecretListView/SecretItem.tsx index 3bc66d0a5..d165b4bd5 100644 --- a/frontend/src/views/SecretMainPage/components/SecretListView/SecretItem.tsx +++ b/frontend/src/views/SecretMainPage/components/SecretListView/SecretItem.tsx @@ -49,7 +49,6 @@ import { memo, useEffect } from "react"; import { Controller, useFieldArray, useForm } from "react-hook-form"; import { twMerge } from "tailwind-merge"; -import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider"; import { CreateReminderForm } from "./CreateReminderForm"; import { formSchema, SecretActionType, TFormSchema } from "./SecretListView.utils"; @@ -87,7 +86,6 @@ export const SecretItem = memo( }: Props) => { const { currentWorkspace } = useWorkspace(); const { permission } = useProjectPermission(); - const { createNotification } = useNotificationContext(); const isReadOnly = permission.can( ProjectPermissionActions.Read, @@ -106,7 +104,8 @@ export const SecretItem = memo( setValue, reset, getValues, - formState: { isDirty, isSubmitting } + trigger, + formState: { isDirty, isSubmitting, errors } } = useForm({ defaultValues: secret, values: secret, @@ -244,16 +243,9 @@ export const SecretItem = memo( autoCapitalization={currentWorkspace?.autoCapitalization} variant="plain" isDisabled={isOverriden} - placeholder="Secret name is required" - isRequired + placeholder={error?.message} isError={Boolean(error)} - onInvalid={(e) => { - e.preventDefault(); - createNotification({ - text: "Secret name cannot be empty", - type: "error" - }); - }} + onKeyUp={() => trigger("key")} {...field} className="w-full px-0 placeholder:text-red-500 focus:text-bunker-100 focus:ring-transparent" /> @@ -509,7 +501,7 @@ export const SecretItem = memo( animate={{ x: 0, opacity: 1 }} exit={{ x: -10, opacity: 0 }} > - + {isSubmitting ? ( ) : ( - + )} diff --git a/frontend/src/views/SecretMainPage/components/SecretListView/SecretListView.utils.ts b/frontend/src/views/SecretMainPage/components/SecretListView/SecretListView.utils.ts index fc8a745d5..40e949bc8 100644 --- a/frontend/src/views/SecretMainPage/components/SecretListView/SecretListView.utils.ts +++ b/frontend/src/views/SecretMainPage/components/SecretListView/SecretListView.utils.ts @@ -8,7 +8,7 @@ export enum SecretActionType { } 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())), idOverride: z.string().trim().optional(), valueOverride: z From 5f5f46eddf263262cab7f696dacab476b45cdffc Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Wed, 6 Mar 2024 05:05:55 +0100 Subject: [PATCH 5/5] Update secret-service.ts --- backend/src/services/secret/secret-service.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backend/src/services/secret/secret-service.ts b/backend/src/services/secret/secret-service.ts index 4c14edc0c..ecd13dae1 100644 --- a/backend/src/services/secret/secret-service.ts +++ b/backend/src/services/secret/secret-service.ts @@ -375,6 +375,10 @@ export const secretServiceFactory = ({ 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); if (!folder) throw new BadRequestError({ message: "Folder not found", name: "Create secret" }); const folderId = folder.id;