From 8c98565715a35a2d730ca66841354ad810bce08c Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Thu, 19 Dec 2024 17:47:39 +0800 Subject: [PATCH] feat: completed basic CRUD --- .../secret-approval-request-service.ts | 6 +- .../secret-replication-service.ts | 4 +- backend/src/server/routes/index.ts | 3 +- .../src/server/routes/v1/dashboard-router.ts | 5 ++ backend/src/server/routes/v3/secret-router.ts | 11 +++- .../external-migration-queue.ts | 9 ++- .../secret-import/secret-import-service.ts | 4 ++ .../secret-v2-bridge/secret-v2-bridge-dal.ts | 62 +++++++++++++++++-- .../secret-v2-bridge/secret-v2-bridge-fns.ts | 35 ++++++++++- .../secret-v2-bridge-service.ts | 17 +++-- .../secret-v2-bridge-types.ts | 6 +- backend/src/services/secret/secret-fns.ts | 4 ++ backend/src/services/secret/secret-queue.ts | 5 +- backend/src/services/secret/secret-service.ts | 6 +- backend/src/services/secret/secret-types.ts | 2 + 15 files changed, 157 insertions(+), 22 deletions(-) diff --git a/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts b/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts index 7be71b951..430f49214 100644 --- a/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts +++ b/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts @@ -92,7 +92,7 @@ type TSecretApprovalRequestServiceFactoryDep = { secretBlindIndexDAL: Pick; snapshotService: Pick; secretVersionDAL: Pick; - resourceMetadataDAL: Pick; + resourceMetadataDAL: Pick; secretVersionTagDAL: Pick; smtpService: Pick; userDAL: Pick; @@ -573,6 +573,7 @@ export const secretApprovalRequestServiceFactory = ({ const updatedSecrets = secretUpdationCommits.length ? await fnSecretV2BridgeBulkUpdate({ folderId, + orgId: actorOrgId, tx, inputSecrets: secretUpdationCommits.map((el) => { const encryptedValue = @@ -604,7 +605,8 @@ export const secretApprovalRequestServiceFactory = ({ secretDAL: secretV2BridgeDAL, secretVersionDAL: secretVersionV2BridgeDAL, secretTagDAL, - secretVersionTagDAL: secretVersionTagV2BridgeDAL + secretVersionTagDAL: secretVersionTagV2BridgeDAL, + resourceMetadataDAL }) : []; const deletedSecret = secretDeletionCommits.length diff --git a/backend/src/ee/services/secret-replication/secret-replication-service.ts b/backend/src/ee/services/secret-replication/secret-replication-service.ts index 53ef8b657..d65545226 100644 --- a/backend/src/ee/services/secret-replication/secret-replication-service.ts +++ b/backend/src/ee/services/secret-replication/secret-replication-service.ts @@ -57,7 +57,7 @@ type TSecretReplicationServiceFactoryDep = { >; secretVersionTagDAL: Pick; secretVersionV2TagBridgeDAL: Pick; - resourceMetadataDAL: Pick; + resourceMetadataDAL: Pick; secretQueueService: Pick; queueService: Pick; secretApprovalPolicyService: Pick; @@ -433,10 +433,12 @@ export const secretReplicationServiceFactory = ({ } if (locallyUpdatedSecrets.length) { await fnSecretV2BridgeBulkUpdate({ + orgId, folderId: destinationReplicationFolderId, secretVersionDAL: secretVersionV2BridgeDAL, secretDAL: secretV2BridgeDAL, tx, + resourceMetadataDAL, secretTagDAL, secretVersionTagDAL: secretVersionV2TagBridgeDAL, inputSecrets: locallyUpdatedSecrets.map((doc) => { diff --git a/backend/src/server/routes/index.ts b/backend/src/server/routes/index.ts index a7e257f3a..4cb88688e 100644 --- a/backend/src/server/routes/index.ts +++ b/backend/src/server/routes/index.ts @@ -1311,7 +1311,8 @@ export const registerRoutes = async ( folderDAL, secretDAL: secretV2BridgeDAL, queueService, - secretV2BridgeService + secretV2BridgeService, + resourceMetadataDAL }); const migrationService = externalMigrationServiceFactory({ diff --git a/backend/src/server/routes/v1/dashboard-router.ts b/backend/src/server/routes/v1/dashboard-router.ts index d3975bbc2..372fd04a1 100644 --- a/backend/src/server/routes/v1/dashboard-router.ts +++ b/backend/src/server/routes/v1/dashboard-router.ts @@ -17,6 +17,7 @@ import { getUserAgentType } from "@app/server/plugins/audit-log"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { SanitizedDynamicSecretSchema, secretRawSchema } from "@app/server/routes/sanitizedSchemas"; import { AuthMode } from "@app/services/auth/auth-type"; +import { ResourceMetadataSchema } from "@app/services/resource-metadata/resource-metadata-schema"; import { SecretsOrderBy } from "@app/services/secret/secret-types"; import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types"; @@ -116,6 +117,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => { secrets: secretRawSchema .extend({ secretPath: z.string().optional(), + secretMetadata: ResourceMetadataSchema.optional(), tags: SecretTagsSchema.pick({ id: true, slug: true, @@ -408,6 +410,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => { secrets: secretRawSchema .extend({ secretPath: z.string().optional(), + secretMetadata: ResourceMetadataSchema.optional(), tags: SecretTagsSchema.pick({ id: true, slug: true, @@ -693,6 +696,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => { secrets: secretRawSchema .extend({ secretPath: z.string().optional(), + secretMetadata: ResourceMetadataSchema.optional(), tags: SecretTagsSchema.pick({ id: true, slug: true, @@ -864,6 +868,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => { secrets: secretRawSchema .extend({ secretPath: z.string().optional(), + secretMetadata: ResourceMetadataSchema.optional(), tags: SecretTagsSchema.pick({ id: true, slug: true, diff --git a/backend/src/server/routes/v3/secret-router.ts b/backend/src/server/routes/v3/secret-router.ts index 2b03ca589..6cd0c32ab 100644 --- a/backend/src/server/routes/v3/secret-router.ts +++ b/backend/src/server/routes/v3/secret-router.ts @@ -206,6 +206,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { secrets: secretRawSchema .extend({ secretPath: z.string().optional(), + secretMetadata: ResourceMetadataSchema.optional(), tags: SecretTagsSchema.pick({ id: true, slug: true, @@ -349,7 +350,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { }) .extend({ name: z.string() }) .array() - .optional() + .optional(), + secretMetadata: ResourceMetadataSchema.optional() }) }) } @@ -561,6 +563,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { type: z.nativeEnum(SecretType).default(SecretType.Shared).describe(RAW_SECRETS.UPDATE.type), tagIds: z.string().array().optional().describe(RAW_SECRETS.UPDATE.tagIds), metadata: z.record(z.string()).optional(), + secretMetadata: ResourceMetadataSchema.optional(), secretReminderNote: z.string().optional().nullable().describe(RAW_SECRETS.UPDATE.secretReminderNote), secretReminderRepeatDays: z .number() @@ -598,8 +601,10 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { secretReminderNote: req.body.secretReminderNote, metadata: req.body.metadata, newSecretName: req.body.newSecretName, - secretComment: req.body.secretComment + secretComment: req.body.secretComment, + secretMetadata: req.body.secretMetadata }); + if (secretOperation.type === SecretProtectionType.Approval) { return { approval: secretOperation.approval }; } @@ -1853,6 +1858,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { secretComment: z.string().trim().optional().default("").describe(RAW_SECRETS.CREATE.secretComment), skipMultilineEncoding: z.boolean().optional().describe(RAW_SECRETS.CREATE.skipMultilineEncoding), metadata: z.record(z.string()).optional(), + secretMetadata: ResourceMetadataSchema.optional(), tagIds: z.string().array().optional().describe(RAW_SECRETS.CREATE.tagIds) }) .array() @@ -1955,6 +1961,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { newSecretName: z.string().min(1).optional().describe(RAW_SECRETS.UPDATE.newSecretName), tagIds: z.string().array().optional().describe(RAW_SECRETS.UPDATE.tagIds), secretReminderNote: z.string().optional().nullable().describe(RAW_SECRETS.UPDATE.secretReminderNote), + secretMetadata: ResourceMetadataSchema.optional(), secretReminderRepeatDays: z .number() .optional() diff --git a/backend/src/services/external-migration/external-migration-queue.ts b/backend/src/services/external-migration/external-migration-queue.ts index 3cbe8b616..e3d77e832 100644 --- a/backend/src/services/external-migration/external-migration-queue.ts +++ b/backend/src/services/external-migration/external-migration-queue.ts @@ -8,6 +8,7 @@ import { TProjectDALFactory } from "../project/project-dal"; import { TProjectServiceFactory } from "../project/project-service"; import { TProjectEnvDALFactory } from "../project-env/project-env-dal"; import { TProjectEnvServiceFactory } from "../project-env/project-env-service"; +import { TResourceMetadataDALFactory } from "../resource-metadata/resource-metadata-dal"; import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal"; import { TSecretTagDALFactory } from "../secret-tag/secret-tag-dal"; import { TSecretV2BridgeDALFactory } from "../secret-v2-bridge/secret-v2-bridge-dal"; @@ -35,6 +36,8 @@ export type TExternalMigrationQueueFactoryDep = { projectService: Pick; projectEnvService: Pick; secretV2BridgeService: Pick; + + resourceMetadataDAL: Pick; }; export type TExternalMigrationQueueFactory = ReturnType; @@ -52,7 +55,8 @@ export const externalMigrationQueueFactory = ({ secretVersionDAL, secretTagDAL, secretVersionTagDAL, - folderDAL + folderDAL, + resourceMetadataDAL }: TExternalMigrationQueueFactoryDep) => { const startImport = async (dto: { actorEmail: string; @@ -109,7 +113,8 @@ export const externalMigrationQueueFactory = ({ kmsService, projectService, projectEnvService, - secretV2BridgeService + secretV2BridgeService, + resourceMetadataDAL }); if (projectsNotImported.length) { diff --git a/backend/src/services/secret-import/secret-import-service.ts b/backend/src/services/secret-import/secret-import-service.ts index bb2c54372..3a62fb48a 100644 --- a/backend/src/services/secret-import/secret-import-service.ts +++ b/backend/src/services/secret-import/secret-import-service.ts @@ -160,6 +160,7 @@ export const secretImportServiceFactory = ({ if (secImport.isReplication && sourceFolder) { await secretQueueService.replicateSecrets({ secretPath: secImport.importPath, + orgId: actorOrgId, projectId, environmentSlug: importEnv.slug, pickOnlyImportIds: [secImport.id], @@ -169,6 +170,7 @@ export const secretImportServiceFactory = ({ } else { await secretQueueService.syncSecrets({ secretPath, + orgId: actorOrgId, projectId, environmentSlug: environment, actorId, @@ -340,6 +342,7 @@ export const secretImportServiceFactory = ({ await secretQueueService.syncSecrets({ secretPath, + orgId: actorOrgId, projectId, environmentSlug: environment, actor, @@ -415,6 +418,7 @@ export const secretImportServiceFactory = ({ if (membership && sourceFolder) { await secretQueueService.replicateSecrets({ + orgId: actorOrgId, secretPath: secretImportDoc.importPath, projectId, environmentSlug: secretImportDoc.importEnv.slug, diff --git a/backend/src/services/secret-v2-bridge/secret-v2-bridge-dal.ts b/backend/src/services/secret-v2-bridge/secret-v2-bridge-dal.ts index 3bdd5783f..b2db2712d 100644 --- a/backend/src/services/secret-v2-bridge/secret-v2-bridge-dal.ts +++ b/backend/src/services/secret-v2-bridge/secret-v2-bridge-dal.ts @@ -221,7 +221,9 @@ export const secretV2BridgeDALFactory = (db: TDbClient) => { const secs = await (tx || db.replicaNode())(TableName.SecretV2) .where({ folderId }) .where((bd) => { - void bd.whereNull("userId").orWhere({ userId: userId || null }); + void bd + .whereNull(`${TableName.SecretV2}.userId`) + .orWhere({ [`${TableName.SecretV2}.userId` as "userId"]: userId || null }); }) .leftJoin( TableName.SecretV2JnTag, @@ -233,10 +235,16 @@ export const secretV2BridgeDALFactory = (db: TDbClient) => { `${TableName.SecretV2JnTag}.${TableName.SecretTag}Id`, `${TableName.SecretTag}.id` ) + .leftJoin(TableName.ResourceMetadata, `${TableName.SecretV2}.id`, `${TableName.ResourceMetadata}.secretId`) .select(selectAllTableCols(TableName.SecretV2)) .select(db.ref("id").withSchema(TableName.SecretTag).as("tagId")) .select(db.ref("color").withSchema(TableName.SecretTag).as("tagColor")) .select(db.ref("slug").withSchema(TableName.SecretTag).as("tagSlug")) + .select( + db.ref("id").withSchema(TableName.ResourceMetadata).as("metadataId"), + db.ref("key").withSchema(TableName.ResourceMetadata).as("metadataKey"), + db.ref("value").withSchema(TableName.ResourceMetadata).as("metadataValue") + ) .orderBy("id", "asc"); const data = sqlNestRelationships({ @@ -253,6 +261,15 @@ export const secretV2BridgeDALFactory = (db: TDbClient) => { slug, name: slug }) + }, + { + key: "metadataId", + label: "secretMetadata" as const, + mapper: ({ metadataKey, metadataValue, metadataId }) => ({ + id: metadataId, + key: metadataKey, + value: metadataValue + }) } ] }); @@ -367,7 +384,9 @@ export const secretV2BridgeDALFactory = (db: TDbClient) => { } }) .where((bd) => { - void bd.whereNull(`${TableName.SecretV2}.userId`).orWhere({ userId: userId || null }); + void bd + .whereNull(`${TableName.SecretV2}.userId`) + .orWhere({ [`${TableName.SecretV2}.userId` as "userId"]: userId || null }); }) .leftJoin( TableName.SecretV2JnTag, @@ -379,13 +398,23 @@ export const secretV2BridgeDALFactory = (db: TDbClient) => { `${TableName.SecretV2JnTag}.${TableName.SecretTag}Id`, `${TableName.SecretTag}.id` ) + .leftJoin(TableName.ResourceMetadata, `${TableName.SecretV2}.id`, `${TableName.ResourceMetadata}.secretId`) .select( selectAllTableCols(TableName.SecretV2), - db.raw(`DENSE_RANK() OVER (ORDER BY "key" ${filters?.orderDirection ?? OrderByDirection.ASC}) as rank`) + db.raw( + `DENSE_RANK() OVER (ORDER BY "${TableName.SecretV2}".key ${ + filters?.orderDirection ?? OrderByDirection.ASC + }) as rank` + ) ) .select(db.ref("id").withSchema(TableName.SecretTag).as("tagId")) .select(db.ref("color").withSchema(TableName.SecretTag).as("tagColor")) .select(db.ref("slug").withSchema(TableName.SecretTag).as("tagSlug")) + .select( + db.ref("id").withSchema(TableName.ResourceMetadata).as("metadataId"), + db.ref("key").withSchema(TableName.ResourceMetadata).as("metadataKey"), + db.ref("value").withSchema(TableName.ResourceMetadata).as("metadataValue") + ) .where((bd) => { const slugs = filters?.tagSlugs?.filter(Boolean); if (slugs && slugs.length > 0) { @@ -425,6 +454,15 @@ export const secretV2BridgeDALFactory = (db: TDbClient) => { slug, name: slug }) + }, + { + key: "metadataId", + label: "secretMetadata" as const, + mapper: ({ metadataKey, metadataValue, metadataId }) => ({ + id: metadataId, + key: metadataKey, + value: metadataValue + }) } ] }); @@ -545,10 +583,17 @@ export const secretV2BridgeDALFactory = (db: TDbClient) => { `${TableName.SecretV2JnTag}.${TableName.SecretTag}Id`, `${TableName.SecretTag}.id` ) + .leftJoin(TableName.ResourceMetadata, `${TableName.SecretV2}.id`, `${TableName.ResourceMetadata}.secretId`) .select(selectAllTableCols(TableName.SecretV2)) .select(db.ref("id").withSchema(TableName.SecretTag).as("tagId")) .select(db.ref("color").withSchema(TableName.SecretTag).as("tagColor")) - .select(db.ref("slug").withSchema(TableName.SecretTag).as("tagSlug")); + .select(db.ref("slug").withSchema(TableName.SecretTag).as("tagSlug")) + .select( + db.ref("id").withSchema(TableName.ResourceMetadata).as("metadataId"), + db.ref("key").withSchema(TableName.ResourceMetadata).as("metadataKey"), + db.ref("value").withSchema(TableName.ResourceMetadata).as("metadataValue") + ); + const docs = sqlNestRelationships({ data: rawDocs, key: "id", @@ -563,6 +608,15 @@ export const secretV2BridgeDALFactory = (db: TDbClient) => { slug, name: slug }) + }, + { + key: "metadataId", + label: "secretMetadata" as const, + mapper: ({ metadataKey, metadataValue, metadataId }) => ({ + id: metadataId, + key: metadataKey, + value: metadataValue + }) } ] }); diff --git a/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts b/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts index e88487319..cc40b0f26 100644 --- a/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts +++ b/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts @@ -6,6 +6,7 @@ import { groupBy } from "@app/lib/fn"; import { logger } from "@app/lib/logger"; import { TProjectEnvDALFactory } from "../project-env/project-env-dal"; +import { ResourceMetadataDTO } from "../resource-metadata/resource-metadata-schema"; import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal"; import { TSecretV2BridgeDALFactory } from "./secret-v2-bridge-dal"; import { TFnSecretBulkDelete, TFnSecretBulkInsert, TFnSecretBulkUpdate } from "./secret-v2-bridge-types"; @@ -151,10 +152,12 @@ export const fnSecretBulkUpdate = async ({ tx, inputSecrets, folderId, + orgId, secretDAL, secretVersionDAL, secretTagDAL, - secretVersionTagDAL + secretVersionTagDAL, + resourceMetadataDAL }: TFnSecretBulkUpdate) => { const sanitizedInputSecrets = inputSecrets.map( ({ @@ -252,6 +255,34 @@ export const fnSecretBulkUpdate = async ({ } } + const inputSecretIdsWithMetadata = inputSecrets + .filter((sec) => Boolean(sec.data.secretMetadata)) + .map((sec) => sec.filter.id); + + await resourceMetadataDAL.delete( + { + $in: { + secretId: inputSecretIdsWithMetadata + } + }, + tx + ); + + await resourceMetadataDAL.insertMany( + inputSecrets.flatMap(({ filter: { id }, data: { secretMetadata } }) => { + if (secretMetadata) { + return secretMetadata.map(({ key, value }) => ({ + key, + value, + secretId: id, + orgId + })); + } + return []; + }), + tx + ); + return newSecrets.map((secret) => ({ ...secret, _id: secret.id })); }; @@ -591,6 +622,7 @@ export const reshapeBridgeSecret = ( color?: string | null; name: string; }[]; + secretMetadata?: ResourceMetadataDTO; } ) => ({ secretKey: secret.key, @@ -609,6 +641,7 @@ export const reshapeBridgeSecret = ( secretReminderRepeatDays: secret.reminderRepeatDays, secretReminderNote: secret.reminderNote, metadata: secret.metadata, + secretMetadata: secret.secretMetadata, createdAt: secret.createdAt, updatedAt: secret.updatedAt }); diff --git a/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts b/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts index 809a8b8c1..f58ff9d34 100644 --- a/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts +++ b/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts @@ -75,7 +75,7 @@ type TSecretV2BridgeServiceFactoryDep = { "insertV2Bridge" | "insertApprovalSecretV2Tags" >; snapshotService: Pick; - resourceMetadataDAL: Pick; + resourceMetadataDAL: Pick; }; export type TSecretV2BridgeServiceFactory = ReturnType; @@ -317,6 +317,7 @@ export const secretV2BridgeServiceFactory = ({ actorAuthMethod, projectId, secretPath, + secretMetadata, ...inputSecret }: TUpdateSecretDTO) => { const { permission, ForbidOnInvalidProjectType } = await permissionService.getProjectPermission( @@ -443,6 +444,8 @@ export const secretV2BridgeServiceFactory = ({ const updatedSecret = await secretDAL.transaction(async (tx) => fnSecretBulkUpdate({ folderId, + orgId: actorOrgId, + resourceMetadataDAL, inputSecrets: [ { filter: { id: secretId }, @@ -456,6 +459,7 @@ export const secretV2BridgeServiceFactory = ({ skipMultilineEncoding: inputSecret.skipMultilineEncoding, key: inputSecret.newSecretName || secretName, tags: inputSecret.tagIds, + secretMetadata, ...encryptedValue } } @@ -971,8 +975,8 @@ export const secretV2BridgeServiceFactory = ({ ? secretDAL.findOneWithTags({ folderId, type: secretType, - key: secretName, - userId: secretType === SecretType.Personal ? actorId : null + [`${TableName.SecretV2}.key` as "key"]: secretName, + [`${TableName.SecretV2}.userId` as "userId"]: secretType === SecretType.Personal ? actorId : null }) : secretVersionDAL .findOne({ @@ -1384,6 +1388,7 @@ export const secretV2BridgeServiceFactory = ({ const secrets = await secretDAL.transaction(async (tx) => fnSecretBulkUpdate({ folderId, + orgId: actorOrgId, tx, inputSecrets: inputSecrets.map((el) => { const originalSecret = secretsToUpdateInDBGroupedByKey[el.secretKey][0]; @@ -1407,6 +1412,7 @@ export const secretV2BridgeServiceFactory = ({ skipMultilineEncoding: el.skipMultilineEncoding, key: el.newSecretName || el.secretKey, tags: el.tagIds, + secretMetadata: el.secretMetadata, ...encryptedValue } }; @@ -1414,7 +1420,8 @@ export const secretV2BridgeServiceFactory = ({ secretDAL, secretVersionDAL, secretTagDAL, - secretVersionTagDAL + secretVersionTagDAL, + resourceMetadataDAL }) ); await snapshotService.performSnapshot(folderId); @@ -1855,6 +1862,8 @@ export const secretV2BridgeServiceFactory = ({ if (locallyUpdatedSecrets.length) { await fnSecretBulkUpdate({ folderId: destinationFolder.id, + orgId: actorOrgId, + resourceMetadataDAL, secretVersionDAL, secretDAL, tx, diff --git a/backend/src/services/secret-v2-bridge/secret-v2-bridge-types.ts b/backend/src/services/secret-v2-bridge/secret-v2-bridge-types.ts index 6eab637ff..64332cec2 100644 --- a/backend/src/services/secret-v2-bridge/secret-v2-bridge-types.ts +++ b/backend/src/services/secret-v2-bridge/secret-v2-bridge-types.ts @@ -78,6 +78,7 @@ export type TUpdateSecretDTO = TProjectPermission & { metadata?: { source?: string; }; + secretMetadata?: ResourceMetadataDTO; }; export type TDeleteSecretDTO = TProjectPermission & { @@ -116,6 +117,7 @@ export type TUpdateManySecretDTO = Omit & { tagIds?: string[]; secretReminderRepeatDays?: number | null; secretReminderNote?: string | null; + secretMetadata?: ResourceMetadataDTO; }[]; }; @@ -167,10 +169,12 @@ type TRequireReferenceIfValue = export type TFnSecretBulkUpdate = { folderId: string; + orgId: string; inputSecrets: { filter: Partial; - data: TRequireReferenceIfValue & { tags?: string[] }; + data: TRequireReferenceIfValue & { tags?: string[]; secretMetadata?: ResourceMetadataDTO }; }[]; + resourceMetadataDAL: Pick; secretDAL: Pick; secretVersionDAL: Pick; secretTagDAL: Pick; diff --git a/backend/src/services/secret/secret-fns.ts b/backend/src/services/secret/secret-fns.ts index d4f3fe345..29d381bfa 100644 --- a/backend/src/services/secret/secret-fns.ts +++ b/backend/src/services/secret/secret-fns.ts @@ -912,6 +912,7 @@ export const updateManySecretsRawFnFactory = ({ secretVersionTagV2BridgeDAL, secretVersionV2BridgeDAL, secretV2BridgeDAL, + resourceMetadataDAL, kmsService }: TUpdateManySecretsRawFnFactory) => { const getBotKeyFn = getBotKeyFnFactory(projectBotDAL, projectDAL); @@ -923,6 +924,7 @@ export const updateManySecretsRawFnFactory = ({ userId }: TUpdateManySecretsRawFn): Promise> => { const { botKey, shouldUseSecretV2Bridge } = await getBotKeyFn(projectId); + const project = await projectDAL.findById(projectId); const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath); if (!folder) @@ -991,11 +993,13 @@ export const updateManySecretsRawFnFactory = ({ const updatedSecrets = await secretDAL.transaction(async (tx) => fnSecretV2BridgeBulkUpdate({ folderId, + orgId: project.orgId, tx, inputSecrets: inputSecrets.map((el) => ({ filter: { id: secretsToUpdateInDBGroupedByKey[el.key][0].id, type: SecretType.Shared }, data: el })), + resourceMetadataDAL, secretDAL: secretV2BridgeDAL, secretVersionDAL: secretVersionV2BridgeDAL, secretTagDAL, diff --git a/backend/src/services/secret/secret-queue.ts b/backend/src/services/secret/secret-queue.ts index b8ad734f8..bd35f8bc3 100644 --- a/backend/src/services/secret/secret-queue.ts +++ b/backend/src/services/secret/secret-queue.ts @@ -104,7 +104,7 @@ type TSecretQueueFactoryDep = { auditLogService: Pick; orgService: Pick; projectUserMembershipRoleDAL: Pick; - resourceMetadataDAL: Pick; + resourceMetadataDAL: Pick; }; export type TGetSecrets = { @@ -318,7 +318,8 @@ export const secretQueueFactory = ({ kmsService, secretVersionV2BridgeDAL, secretV2BridgeDAL, - secretVersionTagV2BridgeDAL + secretVersionTagV2BridgeDAL, + resourceMetadataDAL }); /** diff --git a/backend/src/services/secret/secret-service.ts b/backend/src/services/secret/secret-service.ts index 0b8f7def6..89d44e51e 100644 --- a/backend/src/services/secret/secret-service.ts +++ b/backend/src/services/secret/secret-service.ts @@ -1533,7 +1533,8 @@ export const secretServiceFactory = ({ secretReminderRepeatDays, metadata, secretComment, - newSecretName + newSecretName, + secretMetadata }: TUpdateSecretRawDTO) => { const { botKey, shouldUseSecretV2Bridge } = await projectBotService.getBotKey(projectId); const policy = @@ -1585,7 +1586,8 @@ export const secretServiceFactory = ({ secretName, newSecretName, metadata, - secretValue + secretValue, + secretMetadata }); return { type: SecretProtectionType.Direct as const, secret }; } diff --git a/backend/src/services/secret/secret-types.ts b/backend/src/services/secret/secret-types.ts index 0d6fb4e29..662ff6ed4 100644 --- a/backend/src/services/secret/secret-types.ts +++ b/backend/src/services/secret/secret-types.ts @@ -231,6 +231,7 @@ export type TUpdateSecretRawDTO = TProjectPermission & { metadata?: { source?: string; }; + secretMetadata?: ResourceMetadataDTO; }; export type TDeleteSecretRawDTO = TProjectPermission & { @@ -435,6 +436,7 @@ export type TUpdateManySecretsRawFnFactory = { >; secretVersionV2BridgeDAL: Pick; secretVersionTagV2BridgeDAL: Pick; + resourceMetadataDAL: Pick; }; export type TUpdateManySecretsRawFn = {