Fix folder path and environment on secret imports

This commit is contained in:
Carlos Monastyrski
2025-09-03 13:26:22 -03:00
parent 65f0597bd8
commit 4e16b0ac8f
7 changed files with 85 additions and 8 deletions
@@ -59,7 +59,7 @@ type TSecretReplicationServiceFactoryDep = {
TSecretVersionV2DALFactory, TSecretVersionV2DALFactory,
"find" | "insertMany" | "update" | "findLatestVersionMany" "find" | "insertMany" | "update" | "findLatestVersionMany"
>; >;
secretImportDAL: Pick<TSecretImportDALFactory, "find" | "updateById" | "findByFolderIds">; secretImportDAL: Pick<TSecretImportDALFactory, "find" | "updateById" | "findByFolderIds" | "findById">;
folderDAL: Pick< folderDAL: Pick<
TSecretFolderDALFactory, TSecretFolderDALFactory,
"findSecretPathByFolderIds" | "findBySecretPath" | "create" | "findOne" | "findByManySecretPath" "findSecretPathByFolderIds" | "findBySecretPath" | "create" | "findOne" | "findByManySecretPath"
@@ -39,7 +39,7 @@ const getIntegrationSecretsV2 = async (
}, },
secretV2BridgeDAL: Pick<TSecretV2BridgeDALFactory, "find" | "findByFolderId">, secretV2BridgeDAL: Pick<TSecretV2BridgeDALFactory, "find" | "findByFolderId">,
folderDAL: Pick<TSecretFolderDALFactory, "findByManySecretPath">, folderDAL: Pick<TSecretFolderDALFactory, "findByManySecretPath">,
secretImportDAL: Pick<TSecretImportDALFactory, "find" | "findByFolderIds"> secretImportDAL: Pick<TSecretImportDALFactory, "find" | "findByFolderIds" | "findById">
) => { ) => {
const content: Record<string, boolean> = {}; const content: Record<string, boolean> = {};
if (dto.depth > MAX_SYNC_SECRET_DEPTH) { if (dto.depth > MAX_SYNC_SECRET_DEPTH) {
@@ -300,7 +300,7 @@ export const deleteIntegrationSecrets = async ({
projectBotService: Pick<TProjectBotServiceFactory, "getBotKey">; projectBotService: Pick<TProjectBotServiceFactory, "getBotKey">;
secretV2BridgeDAL: Pick<TSecretV2BridgeDALFactory, "find" | "findByFolderId">; secretV2BridgeDAL: Pick<TSecretV2BridgeDALFactory, "find" | "findByFolderId">;
folderDAL: Pick<TSecretFolderDALFactory, "findByManySecretPath" | "findBySecretPath">; folderDAL: Pick<TSecretFolderDALFactory, "findByManySecretPath" | "findBySecretPath">;
secretImportDAL: Pick<TSecretImportDALFactory, "find" | "findByFolderIds">; secretImportDAL: Pick<TSecretImportDALFactory, "find" | "findByFolderIds" | "findById">;
secretDAL: Pick<TSecretDALFactory, "findByFolderId">; secretDAL: Pick<TSecretDALFactory, "findByFolderId">;
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">; kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
}) => { }) => {
@@ -40,7 +40,7 @@ type TIntegrationServiceFactoryDep = {
projectBotService: TProjectBotServiceFactory; projectBotService: TProjectBotServiceFactory;
secretQueueService: Pick<TSecretQueueFactory, "syncIntegrations">; secretQueueService: Pick<TSecretQueueFactory, "syncIntegrations">;
secretV2BridgeDAL: Pick<TSecretV2BridgeDALFactory, "find" | "findByFolderId">; secretV2BridgeDAL: Pick<TSecretV2BridgeDALFactory, "find" | "findByFolderId">;
secretImportDAL: Pick<TSecretImportDALFactory, "find" | "findByFolderIds">; secretImportDAL: Pick<TSecretImportDALFactory, "find" | "findByFolderIds" | "findById">;
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">; kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
secretDAL: Pick<TSecretDALFactory, "findByFolderId">; secretDAL: Pick<TSecretDALFactory, "findByFolderId">;
}; };
@@ -1,3 +1,5 @@
import RE2 from "re2";
import { SecretType, TSecretImports, TSecrets, TSecretsV2 } from "@app/db/schemas"; import { SecretType, TSecretImports, TSecrets, TSecretsV2 } from "@app/db/schemas";
import { groupBy, unique } from "@app/lib/fn"; import { groupBy, unique } from "@app/lib/fn";
@@ -54,6 +56,77 @@ type TSecretImportSecretsV2 = {
const LEVEL_BREAK = 10; const LEVEL_BREAK = 10;
const getImportUniqKey = (envSlug: string, path: string) => `${envSlug}=${path}`; const getImportUniqKey = (envSlug: string, path: string) => `${envSlug}=${path}`;
/**
* Processes reserved imports by resolving them to their replication source.
*/
const processReservedImports = async <
T extends {
isReserved?: boolean | null;
importPath: string;
importEnv: { id: string; slug: string; name: string };
folderId: string;
}
>(
imports: T[],
secretImportDAL: Pick<TSecretImportDALFactory, "findById">
): Promise<T[]> => {
const reservedImportIds: string[] = [];
imports.forEach((secretImport) => {
if (secretImport.isReserved) {
const reservedMatch = new RE2("/__reserve_replication_([a-f0-9-]{36})").exec(secretImport.importPath);
if (reservedMatch) {
const referencedImportId = reservedMatch[1];
reservedImportIds.push(referencedImportId);
}
}
});
if (reservedImportIds.length === 0) {
return imports;
}
try {
const importDetailsMap = new Map<
string,
{ importPath: string; importEnv: { id: string; slug: string; name: string } }
>();
/* eslint-disable no-await-in-loop */
for (const importId of reservedImportIds) {
const referencedImport = await secretImportDAL.findById(importId);
if (referencedImport) {
importDetailsMap.set(importId, {
importPath: referencedImport.importPath,
importEnv: referencedImport.importEnv
});
}
}
/* eslint-enable no-await-in-loop */
return imports.map((secretImport) => {
if (secretImport.isReserved) {
const reservedMatch = new RE2("/__reserve_replication_([a-f0-9-]{36})").exec(secretImport.importPath);
if (reservedMatch) {
const referencedImportId = reservedMatch[1];
const referencedDetails = importDetailsMap.get(referencedImportId);
if (referencedDetails) {
return {
...secretImport,
importPath: referencedDetails.importPath,
importEnv: referencedDetails.importEnv
};
}
}
}
return secretImport;
});
} catch (error) {
return imports;
}
};
export const fnSecretsFromImports = async ({ export const fnSecretsFromImports = async ({
allowedImports: possibleCyclicImports, allowedImports: possibleCyclicImports,
folderDAL, folderDAL,
@@ -167,7 +240,7 @@ export const fnSecretsV2FromImports = async ({
folderDAL: Pick<TSecretFolderDALFactory, "findByManySecretPath">; folderDAL: Pick<TSecretFolderDALFactory, "findByManySecretPath">;
viewSecretValue: boolean; viewSecretValue: boolean;
secretDAL: Pick<TSecretV2BridgeDALFactory, "find">; secretDAL: Pick<TSecretV2BridgeDALFactory, "find">;
secretImportDAL: Pick<TSecretImportDALFactory, "findByFolderIds">; secretImportDAL: Pick<TSecretImportDALFactory, "findByFolderIds" | "findById">;
decryptor: (value?: Buffer | null) => string; decryptor: (value?: Buffer | null) => string;
expandSecretReferences?: (inputSecret: { expandSecretReferences?: (inputSecret: {
value?: string; value?: string;
@@ -188,6 +261,10 @@ export const fnSecretsV2FromImports = async ({
})[]; })[];
}[] = [{ secretImports: rootSecretImports, depth: 0, parentImportedSecrets: [] }]; }[] = [{ secretImports: rootSecretImports, depth: 0, parentImportedSecrets: [] }];
const processedSecretImports = await processReservedImports(rootSecretImports, secretImportDAL);
stack[0] = { secretImports: processedSecretImports, depth: 0, parentImportedSecrets: [] };
const processedImports: TSecretImportSecretsV2[] = []; const processedImports: TSecretImportSecretsV2[] = [];
while (stack.length) { while (stack.length) {
@@ -80,7 +80,7 @@ type TSecretSyncQueueFactoryDep = {
| "deleteMany" | "deleteMany"
| "invalidateSecretCacheByProjectId" | "invalidateSecretCacheByProjectId"
>; >;
secretImportDAL: Pick<TSecretImportDALFactory, "find" | "findByFolderIds">; secretImportDAL: Pick<TSecretImportDALFactory, "find" | "findByFolderIds" | "findById">;
secretSyncDAL: Pick<TSecretSyncDALFactory, "findById" | "find" | "updateById" | "deleteById">; secretSyncDAL: Pick<TSecretSyncDALFactory, "findById" | "find" | "updateById" | "deleteById">;
auditLogService: Pick<TAuditLogServiceFactory, "createAuditLog">; auditLogService: Pick<TAuditLogServiceFactory, "createAuditLog">;
projectMembershipDAL: Pick<TProjectMembershipDALFactory, "findAllProjectMembers">; projectMembershipDAL: Pick<TProjectMembershipDALFactory, "findAllProjectMembers">;
@@ -108,7 +108,7 @@ type TSecretV2BridgeServiceFactoryDep = {
| "findBySecretPathMultiEnv" | "findBySecretPathMultiEnv"
| "findSecretPathByFolderIds" | "findSecretPathByFolderIds"
>; >;
secretImportDAL: Pick<TSecretImportDALFactory, "find" | "findByFolderIds">; secretImportDAL: Pick<TSecretImportDALFactory, "find" | "findByFolderIds" | "findById">;
secretQueueService: Pick<TSecretQueueFactory, "syncSecrets" | "handleSecretReminder" | "removeSecretReminder">; secretQueueService: Pick<TSecretQueueFactory, "syncSecrets" | "handleSecretReminder" | "removeSecretReminder">;
secretApprovalPolicyService: Pick<TSecretApprovalPolicyServiceFactory, "getSecretApprovalPolicy">; secretApprovalPolicyService: Pick<TSecretApprovalPolicyServiceFactory, "getSecretApprovalPolicy">;
secretApprovalRequestDAL: Pick<TSecretApprovalRequestDALFactory, "create" | "transaction">; secretApprovalRequestDAL: Pick<TSecretApprovalRequestDALFactory, "create" | "transaction">;
+1 -1
View File
@@ -86,7 +86,7 @@ type TSecretQueueFactoryDep = {
integrationAuthService: Pick<TIntegrationAuthServiceFactory, "getIntegrationAccessToken">; integrationAuthService: Pick<TIntegrationAuthServiceFactory, "getIntegrationAccessToken">;
folderDAL: TSecretFolderDALFactory; folderDAL: TSecretFolderDALFactory;
secretDAL: TSecretDALFactory; secretDAL: TSecretDALFactory;
secretImportDAL: Pick<TSecretImportDALFactory, "find" | "findByFolderIds">; secretImportDAL: Pick<TSecretImportDALFactory, "find" | "findByFolderIds" | "findById">;
webhookDAL: Pick<TWebhookDALFactory, "findAllWebhooks" | "transaction" | "update" | "bulkUpdate">; webhookDAL: Pick<TWebhookDALFactory, "findAllWebhooks" | "transaction" | "update" | "bulkUpdate">;
projectEnvDAL: Pick<TProjectEnvDALFactory, "findOne" | "find">; projectEnvDAL: Pick<TProjectEnvDALFactory, "findOne" | "find">;
projectDAL: TProjectDALFactory; projectDAL: TProjectDALFactory;