From ee54fdabe1573ce30ee48f334ebff4981d7b2ece Mon Sep 17 00:00:00 2001 From: Akhil Mohan Date: Tue, 17 Oct 2023 15:38:30 +0530 Subject: [PATCH] feat: changed secret update to use id --- backend/src/controllers/v3/secretsController.ts | 4 +++- backend/src/helpers/secrets.ts | 15 ++++++++++++++- .../interfaces/services/SecretService/index.ts | 1 + backend/src/validation/secrets.ts | 1 + frontend/src/hooks/api/secrets/mutations.tsx | 2 ++ frontend/src/hooks/api/secrets/types.ts | 1 + .../components/SecretListView/SecretListView.tsx | 8 ++++++-- .../SecretOverviewPage/SecretOverviewPage.tsx | 4 ++-- .../SecretOverviewTableRow/SecretEditRow.tsx | 8 ++++---- .../SecretOverviewTableRow.tsx | 2 +- 10 files changed, 35 insertions(+), 11 deletions(-) diff --git a/backend/src/controllers/v3/secretsController.ts b/backend/src/controllers/v3/secretsController.ts index 4db0dca943..16675acd13 100644 --- a/backend/src/controllers/v3/secretsController.ts +++ b/backend/src/controllers/v3/secretsController.ts @@ -476,7 +476,7 @@ export const getSecrets = async (req: Request, res: Response) => { if (folderId && folderId !== "root") { const folder = await Folder.findOne({ workspace: workspaceId, environment }); - if (!folder) throw BadRequestError({ message: "Folder not found" }); + if (!folder) return res.send({ secrets: [] }); secretPath = getFolderWithPathFromId(folder.nodes, folderId).folderPath; } @@ -673,6 +673,7 @@ export const updateSecretByName = async (req: Request, res: Response) => { secretValueCiphertext, secretValueTag, secretValueIV, + secretId, type, environment, secretPath, @@ -741,6 +742,7 @@ export const updateSecretByName = async (req: Request, res: Response) => { workspaceId: new Types.ObjectId(workspaceId), environment, type, + secretId, authData: req.authData, newSecretName, secretValueCiphertext, diff --git a/backend/src/helpers/secrets.ts b/backend/src/helpers/secrets.ts index ea6f4a2544..4dd34df8f1 100644 --- a/backend/src/helpers/secrets.ts +++ b/backend/src/helpers/secrets.ts @@ -790,6 +790,7 @@ export const getSecretHelper = async ({ export const updateSecretHelper = async ({ secretName, workspaceId, + secretId, environment, type, authData, @@ -812,11 +813,20 @@ export const updateSecretHelper = async ({ workspaceId: new Types.ObjectId(workspaceId) }); - const oldSecretBlindIndex = await generateSecretBlindIndexWithSaltHelper({ + let oldSecretBlindIndex = await generateSecretBlindIndexWithSaltHelper({ secretName, salt }); + if (secretId) { + const secret = await Secret.findOne({ + workspace: workspaceId, + environment, + _id: secretId + }).select("secretBlindIndex"); + if (secret && secret.secretBlindIndex) oldSecretBlindIndex = secret.secretBlindIndex; + } + let secret: ISecret | null = null; const folderId = await getFolderIdFromServiceToken(workspaceId, environment, secretPath); @@ -891,6 +901,9 @@ export const updateSecretHelper = async ({ skipMultilineEncoding, secretBlindIndex: newSecretNameBlindIndex, $inc: { version: 1 } + }, + { + new: true } ); } diff --git a/backend/src/interfaces/services/SecretService/index.ts b/backend/src/interfaces/services/SecretService/index.ts index 203f0e178e..a2d9c5bb52 100644 --- a/backend/src/interfaces/services/SecretService/index.ts +++ b/backend/src/interfaces/services/SecretService/index.ts @@ -44,6 +44,7 @@ export interface GetSecretParams { export interface UpdateSecretParams { secretName: string; newSecretName?: string; + secretId?: string; secretKeyCiphertext?: string; secretKeyIV?: string; secretKeyTag?: string; diff --git a/backend/src/validation/secrets.ts b/backend/src/validation/secrets.ts index 264eb72713..174ffa7912 100644 --- a/backend/src/validation/secrets.ts +++ b/backend/src/validation/secrets.ts @@ -353,6 +353,7 @@ export const UpdateSecretByNameV3 = z.object({ body: z.object({ workspaceId: z.string().trim(), environment: z.string().trim(), + secretId: z.string().trim().optional(), type: z.enum([SECRET_SHARED, SECRET_PERSONAL]), secretPath: z.string().trim().default("/"), secretValueCiphertext: z.string().trim(), diff --git a/frontend/src/hooks/api/secrets/mutations.tsx b/frontend/src/hooks/api/secrets/mutations.tsx index ce66819118..a516589e56 100644 --- a/frontend/src/hooks/api/secrets/mutations.tsx +++ b/frontend/src/hooks/api/secrets/mutations.tsx @@ -131,6 +131,7 @@ export const useUpdateSecretV3 = ({ mutationFn: async ({ secretPath = "/", type, + secretId, environment, workspaceId, secretName, @@ -157,6 +158,7 @@ export const useUpdateSecretV3 = ({ environment, type, secretPath, + secretId, ...encryptSecret(randomBytes, newSecretName ?? secretName, secretValue, secretComment), tags, skipMultilineEncoding, diff --git a/frontend/src/hooks/api/secrets/types.ts b/frontend/src/hooks/api/secrets/types.ts index ceccf286ca..b4c32d16dc 100644 --- a/frontend/src/hooks/api/secrets/types.ts +++ b/frontend/src/hooks/api/secrets/types.ts @@ -109,6 +109,7 @@ export type TUpdateSecretsV3DTO = { skipMultilineEncoding?: boolean; newSecretName?: string; secretName: string; + secretId?: string; secretValue: string; secretComment?: string; tags?: string[]; diff --git a/frontend/src/views/SecretMainPage/components/SecretListView/SecretListView.tsx b/frontend/src/views/SecretMainPage/components/SecretListView/SecretListView.tsx index 1a09fe796c..f5268c4277 100644 --- a/frontend/src/views/SecretMainPage/components/SecretListView/SecretListView.tsx +++ b/frontend/src/views/SecretMainPage/components/SecretListView/SecretListView.tsx @@ -153,6 +153,7 @@ export const SecretListView = ({ workspaceId, secretPath, secretName: key, + secretId, secretValue: value || "", type, latestFileKey: decryptFileKey, @@ -201,11 +202,14 @@ export const SecretListView = ({ try { // personal secret change if (overrideAction === "deleted") { - await handleSecretOperation("delete", "personal", oldKey); + await handleSecretOperation("delete", "personal", oldKey, { + secretId: orgSecret.idOverride + }); } else if (overrideAction && idOverride) { await handleSecretOperation("update", "personal", oldKey, { value: valueOverride, newKey: hasKeyChanged ? key : undefined, + secretId: orgSecret.idOverride, skipMultilineEncoding: modSecret.skipMultilineEncoding }); } else if (overrideAction) { @@ -218,6 +222,7 @@ export const SecretListView = ({ value, tags: tagIds, comment, + secretId: orgSecret._id, newKey: hasKeyChanged ? key : undefined, skipMultilineEncoding: modSecret.skipMultilineEncoding }); @@ -308,7 +313,6 @@ export const SecretListView = ({ > {namespace} - {filteredSecrets.map((secret) => ( { } }; - const handleSecretUpdate = async (env: string, key: string, value: string) => { + const handleSecretUpdate = async (env: string, key: string, value: string, secretId?: string) => { try { await updateSecretV3({ environment: env, workspaceId, secretPath, + secretId, secretName: key, secretValue: value, type: "shared", @@ -242,7 +243,6 @@ export const SecretOverviewPage = () => { ); const canViewOverviewPage = Boolean(userAvailableEnvs.length); - const filteredSecretNames = secKeys ?.filter((name) => name.toUpperCase().includes(searchFilter.toUpperCase())) .sort((a, b) => (sortDir === "asc" ? a.localeCompare(b) : b.localeCompare(a))); diff --git a/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretEditRow.tsx b/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretEditRow.tsx index 06a58172d1..478d990861 100644 --- a/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretEditRow.tsx +++ b/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretEditRow.tsx @@ -18,7 +18,7 @@ type Props = { environment: string; secretPath: string; onSecretCreate: (env: string, key: string, value: string) => Promise; - onSecretUpdate: (env: string, key: string, value: string) => Promise; + onSecretUpdate: (env: string, key: string, value: string, secretId?: string) => Promise; onSecretDelete: (env: string, key: string, secretId?: string) => Promise; }; @@ -42,7 +42,7 @@ export const SecretEditRow = ({ formState: { isDirty, isSubmitting } } = useForm({ values: { - value: defaultValue + value: defaultValue || null } }); const [isDeleting, setIsDeleting] = useToggle(); @@ -70,7 +70,7 @@ export const SecretEditRow = ({ if (isCreatable) { await onSecretCreate(environment, secretName, value); } else { - await onSecretUpdate(environment, secretName, value); + await onSecretUpdate(environment, secretName, value, secretId); } } reset({ value }); @@ -80,7 +80,7 @@ export const SecretEditRow = ({ setIsDeleting.on(); try { await onSecretDelete(environment, secretName, secretId); - reset({ value: undefined }); + reset({ value: null }); } finally { setIsDeleting.off(); } diff --git a/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretOverviewTableRow.tsx b/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretOverviewTableRow.tsx index 35a0e734ff..8671d2da94 100644 --- a/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretOverviewTableRow.tsx +++ b/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretOverviewTableRow.tsx @@ -23,7 +23,7 @@ type Props = { expandableColWidth: number; getSecretByKey: (slug: string, key: string) => DecryptedSecret | undefined; onSecretCreate: (env: string, key: string, value: string) => Promise; - onSecretUpdate: (env: string, key: string, value: string) => Promise; + onSecretUpdate: (env: string, key: string, value: string, secretId?: string) => Promise; onSecretDelete: (env: string, key: string, secretId?: string) => Promise; };