diff --git a/backend/src/ee/controllers/v1/secretSnapshotController.ts b/backend/src/ee/controllers/v1/secretSnapshotController.ts index 34640506a..445add15a 100644 --- a/backend/src/ee/controllers/v1/secretSnapshotController.ts +++ b/backend/src/ee/controllers/v1/secretSnapshotController.ts @@ -13,13 +13,20 @@ import { */ export const getSecretSnapshot = async (req: Request, res: Response) => { const { secretSnapshotId } = req.params; + const secretSnapshot = await SecretSnapshot.findById(secretSnapshotId) .lean() - .populate<{ secretVersions: ISecretVersion[] }>("secretVersions") + .populate<{ secretVersions: ISecretVersion[] }>({ + path: 'secretVersions', + populate: { + path: 'tags', + model: 'Tag' + } + }) .populate<{ folderVersion: TFolderRootVersionSchema }>("folderVersion"); - + if (!secretSnapshot) throw new Error("Failed to find secret snapshot"); - + const folderId = secretSnapshot.folderId; // to show only the folder required secrets secretSnapshot.secretVersions = secretSnapshot.secretVersions.filter( diff --git a/backend/src/ee/models/secretVersion.ts b/backend/src/ee/models/secretVersion.ts index ea2a9fd2a..b915e640e 100644 --- a/backend/src/ee/models/secretVersion.ts +++ b/backend/src/ee/models/secretVersion.ts @@ -27,6 +27,7 @@ export interface ISecretVersion { keyEncoding: "utf8" | "base64"; createdAt: string; folder?: string; + tags?: string[]; } const secretVersionSchema = new Schema( @@ -112,6 +113,11 @@ const secretVersionSchema = new Schema( type: String, required: true, }, + tags: { + ref: 'Tag', + type: [Schema.Types.ObjectId], + default: [] + }, }, { timestamps: true, diff --git a/backend/src/helpers/secrets.ts b/backend/src/helpers/secrets.ts index 193c82698..69ca78e7e 100644 --- a/backend/src/helpers/secrets.ts +++ b/backend/src/helpers/secrets.ts @@ -185,26 +185,56 @@ const generateSecretBlindIndexHelper = async ({ workspaceId: Types.ObjectId; }) => { // check if workspace blind index data exists + const encryptionKey = await getEncryptionKey(); + const rootEncryptionKey = await getRootEncryptionKey(); + const secretBlindIndexData = await SecretBlindIndexData.findOne({ workspace: workspaceId, - }); + }).select('+algorithm +keyEncoding'); if (!secretBlindIndexData) throw SecretBlindIndexDataNotFoundError(); - // decrypt workspace salt - const salt = decryptSymmetric128BitHexKeyUTF8({ - ciphertext: secretBlindIndexData.encryptedSaltCiphertext, - iv: secretBlindIndexData.saltIV, - tag: secretBlindIndexData.saltTag, - key: await getEncryptionKey(), - }); + let salt; + if ( + rootEncryptionKey && + secretBlindIndexData.keyEncoding === ENCODING_SCHEME_BASE64 + ) { + salt = client.decryptSymmetric( + secretBlindIndexData.encryptedSaltCiphertext, + rootEncryptionKey, + secretBlindIndexData.saltIV, + secretBlindIndexData.saltTag + ); - const secretBlindIndex = await generateSecretBlindIndexWithSaltHelper({ - secretName, - salt, - }); + const secretBlindIndex = await generateSecretBlindIndexWithSaltHelper({ + secretName, + salt, + }); - return secretBlindIndex; + return secretBlindIndex; + } else if ( + encryptionKey && + secretBlindIndexData.keyEncoding === ENCODING_SCHEME_UTF8 + ) { + // decrypt workspace salt + salt = decryptSymmetric128BitHexKeyUTF8({ + ciphertext: secretBlindIndexData.encryptedSaltCiphertext, + iv: secretBlindIndexData.saltIV, + tag: secretBlindIndexData.saltTag, + key: encryptionKey, + }); + + const secretBlindIndex = await generateSecretBlindIndexWithSaltHelper({ + secretName, + salt, + }); + + return secretBlindIndex; + } + + throw InternalServerError({ + message: 'Failed to generate secret blind index' + }); }; /** diff --git a/backend/src/utils/setup/backfillData.ts b/backend/src/utils/setup/backfillData.ts index ba56e266b..5886ff776 100644 --- a/backend/src/utils/setup/backfillData.ts +++ b/backend/src/utils/setup/backfillData.ts @@ -335,6 +335,33 @@ export const backfillSecretFolders = async () => { } ); + await SecretVersion.updateMany( + { + folder: { + $exists: false, + }, + }, + { + $set: { + folder: "root", + }, + } + ); + + // Back fill because tags were missing in secret versions + await SecretVersion.updateMany( + { + tags: { + $exists: false, + }, + }, + { + $set: { + tags: [], + }, + } + ); + let secretSnapshots = await SecretSnapshot.find({ environment: { $exists: false, @@ -352,12 +379,15 @@ export const backfillSecretFolders = async () => { groupSnapByEnv[secVer.environment].push(secVer); }); - const newSnapshots = Object.keys(groupSnapByEnv).map((snapEnv) => ({ - ...secSnapshot.toObject({ virtuals: false }), - _id: new Types.ObjectId(), - environment: snapEnv, - secretVersions: groupSnapByEnv[snapEnv], - })); + const newSnapshots = Object.keys(groupSnapByEnv).map((snapEnv) => { + const secretIdsOfEnvGroup = groupSnapByEnv[snapEnv] ? groupSnapByEnv[snapEnv].map(secretVersion => secretVersion._id) : [] + return { + ...secSnapshot.toObject({ virtuals: false }), + _id: new Types.ObjectId(), + environment: snapEnv, + secretVersions: secretIdsOfEnvGroup, + } + }); await SecretSnapshot.insertMany(newSnapshots); await secSnapshot.delete(); diff --git a/backend/src/validation/workspace.ts b/backend/src/validation/workspace.ts index 1cbdca420..b7a04634f 100644 --- a/backend/src/validation/workspace.ts +++ b/backend/src/validation/workspace.ts @@ -51,7 +51,6 @@ export const validateClientForWorkspace = async ({ requiredPermissions?: string[]; requireBlindIndicesEnabled: boolean; }) => { - const workspace = await Workspace.findById(workspaceId); if (!workspace) throw WorkspaceNotFoundError({