feat: update with review changes

This commit is contained in:
=
2025-04-12 00:36:21 +05:30
parent 7107a1b225
commit 9565ef29d0
8 changed files with 59 additions and 45 deletions

View File

@@ -119,7 +119,7 @@ type TSecretApprovalRequestServiceFactoryDep = {
| "bulkUpdate" | "bulkUpdate"
| "deleteMany" | "deleteMany"
| "find" | "find"
| "cacheInvalidateSecretByProjectId" | "invalidateSecretCacheByProjectId"
>; >;
secretVersionV2BridgeDAL: Pick<TSecretVersionV2DALFactory, "insertMany" | "findLatestVersionMany">; secretVersionV2BridgeDAL: Pick<TSecretVersionV2DALFactory, "insertMany" | "findLatestVersionMany">;
secretVersionTagV2BridgeDAL: Pick<TSecretVersionV2TagDALFactory, "insertMany">; secretVersionTagV2BridgeDAL: Pick<TSecretVersionV2TagDALFactory, "insertMany">;
@@ -870,7 +870,7 @@ export const secretApprovalRequestServiceFactory = ({
}); });
} }
await secretV2BridgeDAL.cacheInvalidateSecretByProjectId(projectId); await secretV2BridgeDAL.invalidateSecretCacheByProjectId(projectId);
await snapshotService.performSnapshot(folderId); await snapshotService.performSnapshot(folderId);
const [folder] = await folderDAL.findSecretPathByFolderIds(projectId, [folderId]); const [folder] = await folderDAL.findSecretPathByFolderIds(projectId, [folderId]);
if (!folder) { if (!folder) {

View File

@@ -52,7 +52,7 @@ type TSecretReplicationServiceFactoryDep = {
| "delete" | "delete"
| "upsertSecretReferences" | "upsertSecretReferences"
| "transaction" | "transaction"
| "cacheInvalidateSecretByProjectId" | "invalidateSecretCacheByProjectId"
>; >;
secretVersionV2BridgeDAL: Pick< secretVersionV2BridgeDAL: Pick<
TSecretVersionV2DALFactory, TSecretVersionV2DALFactory,
@@ -505,7 +505,7 @@ export const secretReplicationServiceFactory = ({
} }
}); });
await secretV2BridgeDAL.cacheInvalidateSecretByProjectId(projectId); await secretV2BridgeDAL.invalidateSecretCacheByProjectId(projectId);
await secretQueueService.syncSecrets({ await secretQueueService.syncSecrets({
projectId, projectId,
orgId, orgId,

View File

@@ -88,7 +88,7 @@ export type TSecretRotationV2ServiceFactoryDep = {
folderDAL: Pick<TSecretFolderDALFactory, "findBySecretPath" | "findBySecretPathMultiEnv">; folderDAL: Pick<TSecretFolderDALFactory, "findBySecretPath" | "findBySecretPathMultiEnv">;
secretV2BridgeDAL: Pick< secretV2BridgeDAL: Pick<
TSecretV2BridgeDALFactory, TSecretV2BridgeDALFactory,
"bulkUpdate" | "insertMany" | "deleteMany" | "upsertSecretReferences" | "find" | "cacheInvalidateSecretByProjectId" "bulkUpdate" | "insertMany" | "deleteMany" | "upsertSecretReferences" | "find" | "invalidateSecretCacheByProjectId"
>; >;
secretVersionV2BridgeDAL: Pick<TSecretVersionV2DALFactory, "insertMany">; secretVersionV2BridgeDAL: Pick<TSecretVersionV2DALFactory, "insertMany">;
secretVersionTagV2BridgeDAL: Pick<TSecretVersionV2TagDALFactory, "insertMany">; secretVersionTagV2BridgeDAL: Pick<TSecretVersionV2TagDALFactory, "insertMany">;
@@ -515,7 +515,7 @@ export const secretRotationV2ServiceFactory = ({
}); });
}); });
await secretV2BridgeDAL.cacheInvalidateSecretByProjectId(projectId); await secretV2BridgeDAL.invalidateSecretCacheByProjectId(projectId);
await snapshotService.performSnapshot(folder.id); await snapshotService.performSnapshot(folder.id);
await secretQueueService.syncSecrets({ await secretQueueService.syncSecrets({
orgId: connection.orgId, orgId: connection.orgId,
@@ -652,7 +652,7 @@ export const secretRotationV2ServiceFactory = ({
}); });
if (secretsMappingUpdated) { if (secretsMappingUpdated) {
await secretV2BridgeDAL.cacheInvalidateSecretByProjectId(projectId); await secretV2BridgeDAL.invalidateSecretCacheByProjectId(projectId);
await snapshotService.performSnapshot(folder.id); await snapshotService.performSnapshot(folder.id);
await secretQueueService.syncSecrets({ await secretQueueService.syncSecrets({
orgId: connection.orgId, orgId: connection.orgId,
@@ -779,7 +779,7 @@ export const secretRotationV2ServiceFactory = ({
} }
if (deleteSecrets) { if (deleteSecrets) {
await secretV2BridgeDAL.cacheInvalidateSecretByProjectId(projectId); await secretV2BridgeDAL.invalidateSecretCacheByProjectId(projectId);
await snapshotService.performSnapshot(folder.id); await snapshotService.performSnapshot(folder.id);
await secretQueueService.syncSecrets({ await secretQueueService.syncSecrets({
orgId: connection.orgId, orgId: connection.orgId,
@@ -938,7 +938,7 @@ export const secretRotationV2ServiceFactory = ({
} }
}); });
await secretV2BridgeDAL.cacheInvalidateSecretByProjectId(projectId); await secretV2BridgeDAL.invalidateSecretCacheByProjectId(projectId);
await snapshotService.performSnapshot(folder.id); await snapshotService.performSnapshot(folder.id);
await secretQueueService.syncSecrets({ await secretQueueService.syncSecrets({
orgId: connection.orgId, orgId: connection.orgId,

View File

@@ -48,7 +48,7 @@ type TSecretRotationQueueFactoryDep = {
secretRotationDAL: TSecretRotationDALFactory; secretRotationDAL: TSecretRotationDALFactory;
projectBotService: Pick<TProjectBotServiceFactory, "getBotKey">; projectBotService: Pick<TProjectBotServiceFactory, "getBotKey">;
secretDAL: Pick<TSecretDALFactory, "bulkUpdate" | "find">; secretDAL: Pick<TSecretDALFactory, "bulkUpdate" | "find">;
secretV2BridgeDAL: Pick<TSecretV2BridgeDALFactory, "bulkUpdate" | "find" | "cacheInvalidateSecretByProjectId">; secretV2BridgeDAL: Pick<TSecretV2BridgeDALFactory, "bulkUpdate" | "find" | "invalidateSecretCacheByProjectId">;
secretVersionDAL: Pick<TSecretVersionDALFactory, "insertMany" | "findLatestVersionMany">; secretVersionDAL: Pick<TSecretVersionDALFactory, "insertMany" | "findLatestVersionMany">;
secretVersionV2BridgeDAL: Pick<TSecretVersionV2DALFactory, "insertMany" | "findLatestVersionMany">; secretVersionV2BridgeDAL: Pick<TSecretVersionV2DALFactory, "insertMany" | "findLatestVersionMany">;
telemetryService: Pick<TTelemetryServiceFactory, "sendPostHogEvents">; telemetryService: Pick<TTelemetryServiceFactory, "sendPostHogEvents">;
@@ -340,7 +340,7 @@ export const secretRotationQueueFactory = ({
); );
}); });
await secretV2BridgeDAL.cacheInvalidateSecretByProjectId(secretRotation.projectId); await secretV2BridgeDAL.invalidateSecretCacheByProjectId(secretRotation.projectId);
} else { } else {
if (!botKey) if (!botKey)
throw new NotFoundError({ throw new NotFoundError({

View File

@@ -1,6 +1,6 @@
import crypto from "node:crypto"; import crypto from "node:crypto";
export const getCacheKey = (data: unknown) => export const generateCacheKeyFromData = (data: unknown) =>
crypto crypto
.createHash("md5") .createHash("md5")
.update(JSON.stringify(data)) .update(JSON.stringify(data))

View File

@@ -43,7 +43,7 @@ type TSecretImportServiceFactoryDep = {
secretImportDAL: TSecretImportDALFactory; secretImportDAL: TSecretImportDALFactory;
folderDAL: TSecretFolderDALFactory; folderDAL: TSecretFolderDALFactory;
secretDAL: Pick<TSecretDALFactory, "find">; secretDAL: Pick<TSecretDALFactory, "find">;
secretV2BridgeDAL: Pick<TSecretV2BridgeDALFactory, "find" | "cacheInvalidateSecretByProjectId">; secretV2BridgeDAL: Pick<TSecretV2BridgeDALFactory, "find" | "invalidateSecretCacheByProjectId">;
projectBotService: Pick<TProjectBotServiceFactory, "getBotKey">; projectBotService: Pick<TProjectBotServiceFactory, "getBotKey">;
projectDAL: Pick<TProjectDALFactory, "checkProjectUpgradeStatus">; projectDAL: Pick<TProjectDALFactory, "checkProjectUpgradeStatus">;
projectEnvDAL: TProjectEnvDALFactory; projectEnvDAL: TProjectEnvDALFactory;
@@ -184,7 +184,7 @@ export const secretImportServiceFactory = ({
}); });
} }
await secretV2BridgeDAL.cacheInvalidateSecretByProjectId(projectId); await secretV2BridgeDAL.invalidateSecretCacheByProjectId(projectId);
return { ...secImport, importEnv }; return { ...secImport, importEnv };
}; };
@@ -283,7 +283,7 @@ export const secretImportServiceFactory = ({
return doc; return doc;
}); });
await secretV2BridgeDAL.cacheInvalidateSecretByProjectId(projectId); await secretV2BridgeDAL.invalidateSecretCacheByProjectId(projectId);
return { ...updatedSecImport, importEnv: importedEnv }; return { ...updatedSecImport, importEnv: importedEnv };
}; };
@@ -358,7 +358,7 @@ export const secretImportServiceFactory = ({
actorId actorId
}); });
await secretV2BridgeDAL.cacheInvalidateSecretByProjectId(projectId); await secretV2BridgeDAL.invalidateSecretCacheByProjectId(projectId);
return secImport; return secImport;
}; };

View File

@@ -5,7 +5,7 @@ import { TDbClient } from "@app/db";
import { ProjectType, SecretsV2Schema, SecretType, TableName, TSecretsV2, TSecretsV2Update } from "@app/db/schemas"; import { ProjectType, SecretsV2Schema, SecretType, TableName, TSecretsV2, TSecretsV2Update } from "@app/db/schemas";
import { TKeyStoreFactory } from "@app/keystore/keystore"; import { TKeyStoreFactory } from "@app/keystore/keystore";
import { getConfig } from "@app/lib/config/env"; import { getConfig } from "@app/lib/config/env";
import { getCacheKey } from "@app/lib/crypto/cache"; import { generateCacheKeyFromData } from "@app/lib/crypto/cache";
import { BadRequestError, DatabaseError, NotFoundError } from "@app/lib/errors"; import { BadRequestError, DatabaseError, NotFoundError } from "@app/lib/errors";
import { import {
buildFindFilter, buildFindFilter,
@@ -34,7 +34,7 @@ export const SecretDalCacheKeys = {
) => { ) => {
return `${SecretDalCacheKeys.productKey}:${projectId}:${ return `${SecretDalCacheKeys.productKey}:${projectId}:${
TableName.SecretV2 TableName.SecretV2
}-dal:v${version}:find-by-folder-ids:${getCacheKey(cacheKey)}`; }-dal:v${version}:find-by-folder-ids:${generateCacheKeyFromData(cacheKey)}`;
}, },
findByFolderId: ( findByFolderId: (
projectId: string, projectId: string,
@@ -43,13 +43,15 @@ export const SecretDalCacheKeys = {
) => { ) => {
return `${SecretDalCacheKeys.productKey}:${projectId}:${ return `${SecretDalCacheKeys.productKey}:${projectId}:${
TableName.SecretV2 TableName.SecretV2
}-dal:v${version}:find-by-folder-id:${getCacheKey(cacheKey)}`; }-dal:v${version}:find-by-folder-id:${generateCacheKeyFromData(cacheKey)}`;
}, },
find: (projectId: string, version: number, ...args: Parameters<TSecretV2BridgeDALFactory["find"]>) => { find: (projectId: string, version: number, ...args: Parameters<TSecretV2BridgeDALFactory["find"]>) => {
const [filter, opts] = args; const [filter, opts] = args;
delete opts?.tx; delete opts?.tx;
delete opts?.useCache; delete opts?.useCache;
return `${SecretDalCacheKeys.productKey}:${projectId}:${TableName.SecretV2}-dal:v${version}:find:${getCacheKey({ return `${SecretDalCacheKeys.productKey}:${projectId}:${
TableName.SecretV2
}-dal:v${version}:find:${generateCacheKeyFromData({
filter, filter,
opts opts
})}`; })}`;
@@ -64,10 +66,11 @@ interface TSecretV2DalArg {
const SECRET_DAL_TTL = 5 * 60; const SECRET_DAL_TTL = 5 * 60;
const SECRET_DAL_VERSION_TTL = 15 * 60; const SECRET_DAL_VERSION_TTL = 15 * 60;
const MAX_SECRET_CACHE_BYTES = 25 * 1024 * 1024;
export const secretV2BridgeDALFactory = ({ db, keyStore }: TSecretV2DalArg) => { export const secretV2BridgeDALFactory = ({ db, keyStore }: TSecretV2DalArg) => {
const secretOrm = ormify(db, TableName.SecretV2); const secretOrm = ormify(db, TableName.SecretV2);
const cacheInvalidateSecretByProjectId = async (projectId: string) => { const invalidateSecretCacheByProjectId = async (projectId: string) => {
const secretDalVersionKey = SecretDalCacheKeys.getSecretDalVersion(projectId); const secretDalVersionKey = SecretDalCacheKeys.getSecretDalVersion(projectId);
await keyStore.incrementBy(secretDalVersionKey, 1); await keyStore.incrementBy(secretDalVersionKey, 1);
await keyStore.setExpiry(secretDalVersionKey, SECRET_DAL_VERSION_TTL); await keyStore.setExpiry(secretDalVersionKey, SECRET_DAL_VERSION_TTL);
@@ -228,11 +231,14 @@ export const secretV2BridgeDALFactory = ({ db, keyStore }: TSecretV2DalArg) => {
const encryptedComment = el.encryptedComment ? el.encryptedComment.toString("base64") : null; const encryptedComment = el.encryptedComment ? el.encryptedComment.toString("base64") : null;
return { ...el, encryptedValue, encryptedComment }; return { ...el, encryptedValue, encryptedComment };
}); });
await keyStore.setItemWithExpiry( const cache = JSON.stringify(cachedSecrets);
SecretDalCacheKeys.find(useCache.projectId, secretDalVersion, filter, opts), if (Buffer.byteLength(cache, "utf8") < MAX_SECRET_CACHE_BYTES) {
SECRET_DAL_TTL, await keyStore.setItemWithExpiry(
JSON.stringify(cachedSecrets) SecretDalCacheKeys.find(useCache.projectId, secretDalVersion, filter, opts),
); SECRET_DAL_TTL,
cache
);
}
} }
return data; return data;
@@ -437,11 +443,15 @@ export const secretV2BridgeDALFactory = ({ db, keyStore }: TSecretV2DalArg) => {
const encryptedComment = el.encryptedComment ? el.encryptedComment.toString("base64") : null; const encryptedComment = el.encryptedComment ? el.encryptedComment.toString("base64") : null;
return { ...el, encryptedValue, encryptedComment }; return { ...el, encryptedValue, encryptedComment };
}); });
await keyStore.setItemWithExpiry( const cache = JSON.stringify(newCachedSecrets);
SecretDalCacheKeys.findByFolderId(projectId, secretDalVersion, dto),
SECRET_DAL_TTL, if (Buffer.byteLength(cache, "utf8") < MAX_SECRET_CACHE_BYTES) {
JSON.stringify(newCachedSecrets) await keyStore.setItemWithExpiry(
); SecretDalCacheKeys.findByFolderId(projectId, secretDalVersion, dto),
SECRET_DAL_TTL,
cache
);
}
} }
return data; return data;
} catch (error) { } catch (error) {
@@ -696,11 +706,15 @@ export const secretV2BridgeDALFactory = ({ db, keyStore }: TSecretV2DalArg) => {
const encryptedComment = el.encryptedComment ? el.encryptedComment.toString("base64") : null; const encryptedComment = el.encryptedComment ? el.encryptedComment.toString("base64") : null;
return { ...el, encryptedValue, encryptedComment }; return { ...el, encryptedValue, encryptedComment };
}); });
await keyStore.setItemWithExpiry( const cache = JSON.stringify(cachedSecrets);
SecretDalCacheKeys.findByFolderIds(projectId, secretDalVersion, dto),
SECRET_DAL_TTL, if (Buffer.byteLength(cache, "utf8") < MAX_SECRET_CACHE_BYTES) {
JSON.stringify(cachedSecrets) await keyStore.setItemWithExpiry(
); SecretDalCacheKeys.findByFolderIds(projectId, secretDalVersion, dto),
SECRET_DAL_TTL,
cache
);
}
} }
return data; return data;
@@ -895,6 +909,6 @@ export const secretV2BridgeDALFactory = ({ db, keyStore }: TSecretV2DalArg) => {
countByFolderIds, countByFolderIds,
findOne, findOne,
find, find,
cacheInvalidateSecretByProjectId invalidateSecretCacheByProjectId
}; };
}; };

View File

@@ -331,7 +331,7 @@ export const secretV2BridgeServiceFactory = ({
return createdSecret; return createdSecret;
}); });
await secretDAL.cacheInvalidateSecretByProjectId(projectId); await secretDAL.invalidateSecretCacheByProjectId(projectId);
if (inputSecret.type === SecretType.Shared) { if (inputSecret.type === SecretType.Shared) {
await snapshotService.performSnapshot(folderId); await snapshotService.performSnapshot(folderId);
await secretQueueService.syncSecrets({ await secretQueueService.syncSecrets({
@@ -540,7 +540,7 @@ export const secretV2BridgeServiceFactory = ({
projectId projectId
}); });
await secretDAL.cacheInvalidateSecretByProjectId(projectId); await secretDAL.invalidateSecretCacheByProjectId(projectId);
if (inputSecret.type === SecretType.Shared) { if (inputSecret.type === SecretType.Shared) {
await snapshotService.performSnapshot(folderId); await snapshotService.performSnapshot(folderId);
await secretQueueService.syncSecrets({ await secretQueueService.syncSecrets({
@@ -649,7 +649,7 @@ export const secretV2BridgeServiceFactory = ({
}) })
); );
await secretDAL.cacheInvalidateSecretByProjectId(projectId); await secretDAL.invalidateSecretCacheByProjectId(projectId);
if (inputSecret.type === SecretType.Shared) { if (inputSecret.type === SecretType.Shared) {
await snapshotService.performSnapshot(folderId); await snapshotService.performSnapshot(folderId);
await secretQueueService.syncSecrets({ await secretQueueService.syncSecrets({
@@ -1552,7 +1552,7 @@ export const secretV2BridgeServiceFactory = ({
tx tx
}) })
); );
await secretDAL.cacheInvalidateSecretByProjectId(projectId); await secretDAL.invalidateSecretCacheByProjectId(projectId);
await snapshotService.performSnapshot(folderId); await snapshotService.performSnapshot(folderId);
await secretQueueService.syncSecrets({ await secretQueueService.syncSecrets({
actor, actor,
@@ -1892,7 +1892,7 @@ export const secretV2BridgeServiceFactory = ({
} }
}); });
await secretDAL.cacheInvalidateSecretByProjectId(projectId); await secretDAL.invalidateSecretCacheByProjectId(projectId);
await Promise.allSettled(folders.map((el) => (el?.id ? snapshotService.performSnapshot(el.id) : undefined))); await Promise.allSettled(folders.map((el) => (el?.id ? snapshotService.performSnapshot(el.id) : undefined)));
await Promise.allSettled( await Promise.allSettled(
folders.map((el) => folders.map((el) =>
@@ -2024,7 +2024,7 @@ export const secretV2BridgeServiceFactory = ({
}) })
); );
await secretDAL.cacheInvalidateSecretByProjectId(projectId); await secretDAL.invalidateSecretCacheByProjectId(projectId);
await snapshotService.performSnapshot(folderId); await snapshotService.performSnapshot(folderId);
await secretQueueService.syncSecrets({ await secretQueueService.syncSecrets({
actor, actor,
@@ -2549,7 +2549,7 @@ export const secretV2BridgeServiceFactory = ({
}); });
if (isDestinationUpdated || isSourceUpdated) { if (isDestinationUpdated || isSourceUpdated) {
await secretDAL.cacheInvalidateSecretByProjectId(projectId); await secretDAL.invalidateSecretCacheByProjectId(projectId);
} }
if (isDestinationUpdated) { if (isDestinationUpdated) {
await snapshotService.performSnapshot(destinationFolder.id); await snapshotService.performSnapshot(destinationFolder.id);
@@ -2729,7 +2729,7 @@ export const secretV2BridgeServiceFactory = ({
generatePaths(folderMap).map(({ folderId, path }) => [folderId, path === "/" ? path : path.substring(1)]) generatePaths(folderMap).map(({ folderId, path }) => [folderId, path === "/" ? path : path.substring(1)])
); );
const secrets = await secretDAL.findByFolderIds({ folderIds: folders.map((f) => f.id), projectId }); const secrets = await secretDAL.findByFolderIds({ folderIds: folders.map((f) => f.id), projectId, useCache: true });
const { decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({ const { decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.SecretManager, type: KmsDataKey.SecretManager,