checkpoint

This commit is contained in:
=
2024-07-30 23:11:04 +05:30
parent ef2816b2ee
commit 643d13b0ec
7 changed files with 432 additions and 103 deletions
+151 -11
View File
@@ -39,6 +39,12 @@ import {
TUpdateManySecretsRawFn,
TUpdateManySecretsRawFnFactory
} from "./secret-types";
import { KmsDataKey } from "../kms/kms-types";
import {
fnSecretBulkInsert as fnSecretV2BridgeBulkInsert,
fnSecretBulkUpdate as fnSecretV2BridgeBulkUpdate,
getAllNestedSecretReferences as getAllNestedSecretReferencesV2Bridge
} from "@app/services/secret-v2-bridge/secret-v2-bridge-fns";
export const generateSecretBlindIndexBySalt = async (secretName: string, secretBlindIndexDoc: TSecretBlindIndexes) => {
const appCfg = getConfig();
@@ -679,7 +685,11 @@ export const createManySecretsRawFnFactory = ({
secretBlindIndexDAL,
secretTagDAL,
secretVersionTagDAL,
folderDAL
folderDAL,
secretVersionV2BridgeDAL,
secretV2BridgeDAL,
secretVersionTagV2BridgeDAL,
kmsService
}: TCreateManySecretsRawFnFactory) => {
const getBotKeyFn = getBotKeyFnFactory(projectBotDAL, projectDAL);
const createManySecretsRawFn = async ({
@@ -689,10 +699,7 @@ export const createManySecretsRawFnFactory = ({
secrets,
userId
}: TCreateManySecretsRawFn) => {
const { botKey } = await getBotKeyFn(projectId);
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
await projectDAL.checkProjectUpgradeStatus(projectId);
const { botKey, shouldUseSecretV2Bridge } = await getBotKeyFn(projectId);
const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
if (!folder)
@@ -701,6 +708,62 @@ export const createManySecretsRawFnFactory = ({
name: "Create secret"
});
const folderId = folder.id;
if (shouldUseSecretV2Bridge) {
const { encryptor: secretManagerEncryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.SecretManager,
projectId
});
const secretsStoredInDB = await secretV2BridgeDAL.findBySecretKeys(
folderId,
secrets.map((el) => ({
key: el.secretName,
type: SecretType.Shared
}))
);
if (secretsStoredInDB.length)
throw new BadRequestError({
message: `Secret already exist: ${secretsStoredInDB.map((el) => el.key).join(",")}`
});
const inputSecrets = secrets.map((secret) => {
return {
type: secret.type,
userId: secret.type === SecretType.Personal ? userId : null,
key: secret.secretName,
encryptedValue: secretManagerEncryptor({ plainText: Buffer.from(secret.secretValue) }).cipherTextBlob,
encryptedComent: secret.secretComment
? secretManagerEncryptor({ plainText: Buffer.from(secret.secretComment) }).cipherTextBlob
: null,
skipMultilineEncoding: secret.skipMultilineEncoding,
tags: secret.tags,
references: getAllNestedSecretReferencesV2Bridge(secret.secretValue)
};
});
// get all tags
const tagIds = inputSecrets.flatMap(({ tags = [] }) => tags);
const tags = tagIds.length ? await secretTagDAL.findManyTagsById(projectId, tagIds) : [];
if (tags.length !== tagIds.length) throw new BadRequestError({ message: "Tag not found" });
const newSecrets = await secretDAL.transaction(async (tx) =>
fnSecretV2BridgeBulkInsert({
inputSecrets: inputSecrets.map((el) => ({
...el,
version: 1,
tagIds: el.tags
})),
folderId,
secretDAL: secretV2BridgeDAL,
secretVersionDAL: secretVersionV2BridgeDAL,
secretTagDAL,
secretVersionTagDAL: secretVersionTagV2BridgeDAL,
tx
})
);
return newSecrets;
}
const blindIndexCfg = await secretBlindIndexDAL.findOne({ projectId });
if (!blindIndexCfg) throw new BadRequestError({ message: "Blind index not found", name: "Create secret" });
@@ -715,6 +778,7 @@ export const createManySecretsRawFnFactory = ({
secretDAL
});
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
const inputSecrets = secrets.map((secret) => {
const secretKeyEncrypted = encryptSymmetric128BitHexKeyUTF8(secret.secretName, botKey);
const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8(secret.secretValue || "", botKey);
@@ -777,7 +841,11 @@ export const updateManySecretsRawFnFactory = ({
secretBlindIndexDAL,
secretTagDAL,
secretVersionTagDAL,
folderDAL
folderDAL,
secretVersionTagV2BridgeDAL,
secretVersionV2BridgeDAL,
secretV2BridgeDAL,
kmsService
}: TUpdateManySecretsRawFnFactory) => {
const getBotKeyFn = getBotKeyFnFactory(projectBotDAL, projectDAL);
const updateManySecretsRawFn = async ({
@@ -786,11 +854,8 @@ export const updateManySecretsRawFnFactory = ({
path: secretPath,
secrets, // consider accepting instead ciphertext secrets
userId
}: TUpdateManySecretsRawFn): Promise<Array<TSecrets & { _id: string }>> => {
const { botKey } = await getBotKeyFn(projectId);
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
await projectDAL.checkProjectUpgradeStatus(projectId);
}: TUpdateManySecretsRawFn): Promise<Array<{ id: string }>> => {
const { botKey, shouldUseSecretV2Bridge } = await getBotKeyFn(projectId);
const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
if (!folder)
@@ -799,7 +864,82 @@ export const updateManySecretsRawFnFactory = ({
name: "Update secret"
});
const folderId = folder.id;
if (shouldUseSecretV2Bridge) {
const { encryptor: secretManagerEncryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.SecretManager,
projectId
});
const secretsToUpdate = await secretV2BridgeDAL.findBySecretKeys(
folderId,
secrets.map((el) => ({
key: el.secretName,
type: SecretType.Shared
}))
);
if (secretsToUpdate.length !== secrets.length)
throw new BadRequestError({ message: `Secret not exist: ${secretsToUpdate.map((el) => el.key).join(",")}` });
// now find any secret that needs to update its name
// same process as above
const secretsWithNewName = secrets.filter(({ newSecretName }) => Boolean(newSecretName));
if (secretsWithNewName.length) {
const secretsWithNewNameInDB = await secretV2BridgeDAL.findBySecretKeys(
folderId,
secrets.map((el) => ({
key: el.secretName,
type: SecretType.Shared
}))
);
if (secretsWithNewNameInDB.length)
throw new BadRequestError({
message: `Secret not exist: ${secretsWithNewName.map((el) => el.newSecretName).join(",")}`
});
}
const secretsToUpdateInDBGroupedByKey = groupBy(secretsToUpdate, (i) => i.key);
const inputSecrets = secrets.map((secret) => {
if (secret.newSecretName === "") {
throw new BadRequestError({ message: "New secret name cannot be empty" });
}
return {
type: secret.type,
userId: secret.type === SecretType.Personal ? userId : null,
key: secret.newSecretName || secret.secretName,
encryptedValue: secretManagerEncryptor({ plainText: Buffer.from(secret.secretValue) }).cipherTextBlob,
encryptedComent: secret.secretComment
? secretManagerEncryptor({ plainText: Buffer.from(secret.secretComment) }).cipherTextBlob
: null,
skipMultilineEncoding: secret.skipMultilineEncoding,
tags: secret.tags,
references: getAllNestedSecretReferencesV2Bridge(secret.secretValue)
};
});
const tagIds = inputSecrets.flatMap(({ tags = [] }) => tags);
const tags = tagIds.length ? await secretTagDAL.findManyTagsById(projectId, tagIds) : [];
if (tagIds.length !== tags.length) throw new BadRequestError({ message: "Tag not found" });
const updatedSecrets = await secretDAL.transaction(async (tx) =>
fnSecretV2BridgeBulkUpdate({
folderId,
tx,
inputSecrets: inputSecrets.map((el) => ({
filter: { id: secretsToUpdateInDBGroupedByKey[el.key][0].id, type: SecretType.Shared },
data: el
})),
secretDAL: secretV2BridgeDAL,
secretVersionDAL: secretVersionV2BridgeDAL,
secretTagDAL,
secretVersionTagDAL: secretVersionTagV2BridgeDAL
})
);
return updatedSecrets;
}
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
const blindIndexCfg = await secretBlindIndexDAL.findOne({ projectId });
if (!blindIndexCfg) throw new BadRequestError({ message: "Blind index not found", name: "Update secret" });