diff --git a/backend/src/ee/controllers/v1/secretController.ts b/backend/src/ee/controllers/v1/secretController.ts index 9ba3c77e3..2dcc3c2c7 100644 --- a/backend/src/ee/controllers/v1/secretController.ts +++ b/backend/src/ee/controllers/v1/secretController.ts @@ -54,23 +54,20 @@ export const getSecretVersions = async (req: Request, res: Response) => { } } */ - const { secretId, workspaceId, environment, folderId } = req.params; + const { secretId } = req.params; const offset: number = parseInt(req.query.offset as string); const limit: number = parseInt(req.query.limit as string); const secretVersions = await SecretVersion.find({ - secret: secretId, - workspace: workspaceId, - environment, - folder: folderId, + secret: secretId }) .sort({ createdAt: -1 }) .skip(offset) .limit(limit); return res.status(200).send({ - secretVersions, + secretVersions }); }; @@ -135,7 +132,7 @@ export const rollbackSecretVersion = async (req: Request, res: Response) => { // validate secret version const oldSecretVersion = await SecretVersion.findOne({ secret: secretId, - version, + version }).select("+secretBlindIndex"); if (!oldSecretVersion) throw new Error("Failed to find secret version"); @@ -154,7 +151,7 @@ export const rollbackSecretVersion = async (req: Request, res: Response) => { secretValueTag, algorithm, folder, - keyEncoding, + keyEncoding } = oldSecretVersion; // update secret @@ -162,7 +159,7 @@ export const rollbackSecretVersion = async (req: Request, res: Response) => { secretId, { $inc: { - version: 1, + version: 1 }, workspace, type, @@ -177,10 +174,10 @@ export const rollbackSecretVersion = async (req: Request, res: Response) => { secretValueTag, folderId: folder, algorithm, - keyEncoding, + keyEncoding }, { - new: true, + new: true } ); @@ -204,17 +201,17 @@ export const rollbackSecretVersion = async (req: Request, res: Response) => { secretValueTag, folder, algorithm, - keyEncoding, + keyEncoding }).save(); // take secret snapshot await EESecretService.takeSecretSnapshot({ workspaceId: secret.workspace, environment, - folderId: folder, + folderId: folder }); return res.status(200).send({ - secret, + secret }); }; diff --git a/frontend/src/hooks/api/secrets/queries.tsx b/frontend/src/hooks/api/secrets/queries.tsx index cc1d40aba..397f68aa7 100644 --- a/frontend/src/hooks/api/secrets/queries.tsx +++ b/frontend/src/hooks/api/secrets/queries.tsx @@ -81,76 +81,79 @@ export const useGetProjectSecrets = ({ enabled: Boolean(decryptFileKey && workspaceId && env) && !isPaused, queryKey: secretKeys.getProjectSecret(workspaceId, env, folderId), queryFn: () => fetchProjectEncryptedSecrets(workspaceId, env, folderId), - select: useCallback((data: EncryptedSecret[]) => { - const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY") as string; - const latestKey = decryptFileKey; - const key = decryptAssymmetric({ - ciphertext: latestKey.encryptedKey, - nonce: latestKey.nonce, - publicKey: latestKey.sender.publicKey, - privateKey: PRIVATE_KEY - }); - - const sharedSecrets: DecryptedSecret[] = []; - const personalSecrets: Record = {}; - // this used for add-only mode in dashboard - // type won't be there thus only one key is shown - const duplicateSecretKey: Record = {}; - data.forEach((encSecret: EncryptedSecret) => { - const secretKey = decryptSymmetric({ - ciphertext: encSecret.secretKeyCiphertext, - iv: encSecret.secretKeyIV, - tag: encSecret.secretKeyTag, - key + select: useCallback( + (data: EncryptedSecret[]) => { + const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY") as string; + const latestKey = decryptFileKey; + const key = decryptAssymmetric({ + ciphertext: latestKey.encryptedKey, + nonce: latestKey.nonce, + publicKey: latestKey.sender.publicKey, + privateKey: PRIVATE_KEY }); - const secretValue = decryptSymmetric({ - ciphertext: encSecret.secretValueCiphertext, - iv: encSecret.secretValueIV, - tag: encSecret.secretValueTag, - key - }); + const sharedSecrets: DecryptedSecret[] = []; + const personalSecrets: Record = {}; + // this used for add-only mode in dashboard + // type won't be there thus only one key is shown + const duplicateSecretKey: Record = {}; + data.forEach((encSecret: EncryptedSecret) => { + const secretKey = decryptSymmetric({ + ciphertext: encSecret.secretKeyCiphertext, + iv: encSecret.secretKeyIV, + tag: encSecret.secretKeyTag, + key + }); - const secretComment = decryptSymmetric({ - ciphertext: encSecret.secretCommentCiphertext, - iv: encSecret.secretCommentIV, - tag: encSecret.secretCommentTag, - key - }); + const secretValue = decryptSymmetric({ + ciphertext: encSecret.secretValueCiphertext, + iv: encSecret.secretValueIV, + tag: encSecret.secretValueTag, + key + }); - const decryptedSecret = { - _id: encSecret._id, - env: encSecret.environment, - key: secretKey, - value: secretValue, - tags: encSecret.tags, - comment: secretComment, - createdAt: encSecret.createdAt, - updatedAt: encSecret.updatedAt - }; + const secretComment = decryptSymmetric({ + ciphertext: encSecret.secretCommentCiphertext, + iv: encSecret.secretCommentIV, + tag: encSecret.secretCommentTag, + key + }); - if (encSecret.type === "personal") { - personalSecrets[`${decryptedSecret.key}-${decryptedSecret.env}`] = { - id: encSecret._id, - value: secretValue + const decryptedSecret = { + _id: encSecret._id, + env: encSecret.environment, + key: secretKey, + value: secretValue, + tags: encSecret.tags, + comment: secretComment, + createdAt: encSecret.createdAt, + updatedAt: encSecret.updatedAt }; - } else { - if (!duplicateSecretKey?.[`${decryptedSecret.key}-${decryptedSecret.env}`]) { - sharedSecrets.push(decryptedSecret); + + if (encSecret.type === "personal") { + personalSecrets[`${decryptedSecret.key}-${decryptedSecret.env}`] = { + id: encSecret._id, + value: secretValue + }; + } else { + if (!duplicateSecretKey?.[`${decryptedSecret.key}-${decryptedSecret.env}`]) { + sharedSecrets.push(decryptedSecret); + } + duplicateSecretKey[`${decryptedSecret.key}-${decryptedSecret.env}`] = true; } - duplicateSecretKey[`${decryptedSecret.key}-${decryptedSecret.env}`] = true; - } - }); - sharedSecrets.forEach((val) => { - const dupKey = `${val.key}-${val.env}`; - if (personalSecrets?.[dupKey]) { - val.idOverride = personalSecrets[dupKey].id; - val.valueOverride = personalSecrets[dupKey].value; - val.overrideAction = "modified"; - } - }); - return { secrets: sharedSecrets }; - }, [decryptFileKey]) + }); + sharedSecrets.forEach((val) => { + const dupKey = `${val.key}-${val.env}`; + if (personalSecrets?.[dupKey]) { + val.idOverride = personalSecrets[dupKey].id; + val.valueOverride = personalSecrets[dupKey].value; + val.overrideAction = "modified"; + } + }); + return { secrets: sharedSecrets }; + }, + [decryptFileKey] + ) }); export const useGetProjectSecretsByKey = ({ @@ -167,82 +170,85 @@ export const useGetProjectSecretsByKey = ({ // right now secretpath is passed as folderid as only this is used in overview queryKey: secretKeys.getProjectSecret(workspaceId, env, secretPath), queryFn: () => fetchProjectEncryptedSecrets(workspaceId, env, folderId, secretPath), - select: useCallback((data: EncryptedSecret[]) => { - const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY") as string; - const latestKey = decryptFileKey; - const key = decryptAssymmetric({ - ciphertext: latestKey.encryptedKey, - nonce: latestKey.nonce, - publicKey: latestKey.sender.publicKey, - privateKey: PRIVATE_KEY - }); - - const sharedSecrets: Record = {}; - const personalSecrets: Record = {}; - // this used for add-only mode in dashboard - // type won't be there thus only one key is shown - const duplicateSecretKey: Record = {}; - const uniqSecKeys: Record = {}; - data.forEach((encSecret: EncryptedSecret) => { - const secretKey = decryptSymmetric({ - ciphertext: encSecret.secretKeyCiphertext, - iv: encSecret.secretKeyIV, - tag: encSecret.secretKeyTag, - key - }); - if (!uniqSecKeys?.[secretKey]) uniqSecKeys[secretKey] = true; - - const secretValue = decryptSymmetric({ - ciphertext: encSecret.secretValueCiphertext, - iv: encSecret.secretValueIV, - tag: encSecret.secretValueTag, - key + select: useCallback( + (data: EncryptedSecret[]) => { + const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY") as string; + const latestKey = decryptFileKey; + const key = decryptAssymmetric({ + ciphertext: latestKey.encryptedKey, + nonce: latestKey.nonce, + publicKey: latestKey.sender.publicKey, + privateKey: PRIVATE_KEY }); - const secretComment = decryptSymmetric({ - ciphertext: encSecret.secretCommentCiphertext, - iv: encSecret.secretCommentIV, - tag: encSecret.secretCommentTag, - key - }); + const sharedSecrets: Record = {}; + const personalSecrets: Record = {}; + // this used for add-only mode in dashboard + // type won't be there thus only one key is shown + const duplicateSecretKey: Record = {}; + const uniqSecKeys: Record = {}; + data.forEach((encSecret: EncryptedSecret) => { + const secretKey = decryptSymmetric({ + ciphertext: encSecret.secretKeyCiphertext, + iv: encSecret.secretKeyIV, + tag: encSecret.secretKeyTag, + key + }); + if (!uniqSecKeys?.[secretKey]) uniqSecKeys[secretKey] = true; - const decryptedSecret = { - _id: encSecret._id, - env: encSecret.environment, - key: secretKey, - value: secretValue, - tags: encSecret.tags, - comment: secretComment, - createdAt: encSecret.createdAt, - updatedAt: encSecret.updatedAt - }; + const secretValue = decryptSymmetric({ + ciphertext: encSecret.secretValueCiphertext, + iv: encSecret.secretValueIV, + tag: encSecret.secretValueTag, + key + }); - if (encSecret.type === "personal") { - personalSecrets[`${decryptedSecret.key}-${decryptedSecret.env}`] = { - id: encSecret._id, - value: secretValue + const secretComment = decryptSymmetric({ + ciphertext: encSecret.secretCommentCiphertext, + iv: encSecret.secretCommentIV, + tag: encSecret.secretCommentTag, + key + }); + + const decryptedSecret = { + _id: encSecret._id, + env: encSecret.environment, + key: secretKey, + value: secretValue, + tags: encSecret.tags, + comment: secretComment, + createdAt: encSecret.createdAt, + updatedAt: encSecret.updatedAt }; - } else { - if (!duplicateSecretKey?.[`${decryptedSecret.key}-${decryptedSecret.env}`]) { - if (!sharedSecrets?.[secretKey]) sharedSecrets[secretKey] = []; - sharedSecrets[secretKey].push(decryptedSecret); - } - duplicateSecretKey[`${decryptedSecret.key}-${decryptedSecret.env}`] = true; - } - }); - Object.keys(sharedSecrets).forEach((secName) => { - sharedSecrets[secName].forEach((val) => { - const dupKey = `${val.key}-${val.env}`; - if (personalSecrets?.[dupKey]) { - val.idOverride = personalSecrets[dupKey].id; - val.valueOverride = personalSecrets[dupKey].value; - val.overrideAction = "modified"; + + if (encSecret.type === "personal") { + personalSecrets[`${decryptedSecret.key}-${decryptedSecret.env}`] = { + id: encSecret._id, + value: secretValue + }; + } else { + if (!duplicateSecretKey?.[`${decryptedSecret.key}-${decryptedSecret.env}`]) { + if (!sharedSecrets?.[secretKey]) sharedSecrets[secretKey] = []; + sharedSecrets[secretKey].push(decryptedSecret); + } + duplicateSecretKey[`${decryptedSecret.key}-${decryptedSecret.env}`] = true; } }); - }); + Object.keys(sharedSecrets).forEach((secName) => { + sharedSecrets[secName].forEach((val) => { + const dupKey = `${val.key}-${val.env}`; + if (personalSecrets?.[dupKey]) { + val.idOverride = personalSecrets[dupKey].id; + val.valueOverride = personalSecrets[dupKey].value; + val.overrideAction = "modified"; + } + }); + }); - return { secrets: sharedSecrets, uniqueSecCount: Object.keys(uniqSecKeys).length }; - }, [decryptFileKey]) + return { secrets: sharedSecrets, uniqueSecCount: Object.keys(uniqSecKeys).length }; + }, + [decryptFileKey] + ) }); const fetchEncryptedSecretVersion = async (secretId: string, offset: number, limit: number) => { @@ -263,29 +269,32 @@ export const useGetSecretVersion = (dto: GetSecretVersionsDTO) => enabled: Boolean(dto.secretId && dto.decryptFileKey), queryKey: secretKeys.getSecretVersion(dto.secretId), queryFn: () => fetchEncryptedSecretVersion(dto.secretId, dto.offset, dto.limit), - select: useCallback((data: EncryptedSecretVersion[]) => { - const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY") as string; - const latestKey = dto.decryptFileKey; - const key = decryptAssymmetric({ - ciphertext: latestKey.encryptedKey, - nonce: latestKey.nonce, - publicKey: latestKey.sender.publicKey, - privateKey: PRIVATE_KEY - }); + select: useCallback( + (data: EncryptedSecretVersion[]) => { + const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY") as string; + const latestKey = dto.decryptFileKey; + const key = decryptAssymmetric({ + ciphertext: latestKey.encryptedKey, + nonce: latestKey.nonce, + publicKey: latestKey.sender.publicKey, + privateKey: PRIVATE_KEY + }); - return data - .map((el) => ({ - createdAt: el.createdAt, - id: el._id, - value: decryptSymmetric({ - ciphertext: el.secretValueCiphertext, - iv: el.secretValueIV, - tag: el.secretValueTag, - key - }) - })) - .sort((a, b) => b.createdAt.localeCompare(a.createdAt)); - }, []) + return data + .map((el) => ({ + createdAt: el.createdAt, + id: el._id, + value: decryptSymmetric({ + ciphertext: el.secretValueCiphertext, + iv: el.secretValueIV, + tag: el.secretValueTag, + key + }) + })) + .sort((a, b) => b.createdAt.localeCompare(a.createdAt)); + }, + [dto.decryptFileKey] + ) }); export const useBatchSecretsOp = () => { diff --git a/frontend/src/views/DashboardPage/components/SecretDetailDrawer/SecretDetailDrawer.tsx b/frontend/src/views/DashboardPage/components/SecretDetailDrawer/SecretDetailDrawer.tsx index bfd4eabda..ab5c8719f 100644 --- a/frontend/src/views/DashboardPage/components/SecretDetailDrawer/SecretDetailDrawer.tsx +++ b/frontend/src/views/DashboardPage/components/SecretDetailDrawer/SecretDetailDrawer.tsx @@ -193,8 +193,8 @@ export const SecretDetailDrawer = ({
-
Value:
-
{value}
+
Value:
+
{value}
))}