import { Knex } from "knex"; import { TDbClient } from "@app/db"; import { SecretApprovalRequestsSecretsSchema, SecretApprovalRequestsSecretsV2Schema, TableName, TSecretApprovalRequestsSecrets, TSecretTags } from "@app/db/schemas"; import { DatabaseError, NotFoundError } from "@app/lib/errors"; import { ormify, selectAllTableCols, sqlNestRelationships } from "@app/lib/knex"; export type TSecretApprovalRequestSecretDALFactory = ReturnType; export const secretApprovalRequestSecretDALFactory = (db: TDbClient) => { const secretApprovalRequestSecretOrm = ormify(db, TableName.SecretApprovalRequestSecret); const secretApprovalRequestSecretTagOrm = ormify(db, TableName.SecretApprovalRequestSecretTag); const secretApprovalRequestSecretV2TagOrm = ormify(db, TableName.SecretApprovalRequestSecretTagV2); const secretApprovalRequestSecretV2Orm = ormify(db, TableName.SecretApprovalRequestSecretV2); const bulkUpdateNoVersionIncrement = async (data: TSecretApprovalRequestsSecrets[], tx?: Knex) => { try { const existingApprovalSecrets = await secretApprovalRequestSecretOrm.find( { $in: { id: data.map((el) => el.id) } }, { tx } ); if (existingApprovalSecrets.length !== data.length) { throw new NotFoundError({ message: "Some of the secret approvals do not exist" }); } if (data.length === 0) return []; const updatedApprovalSecrets = await (tx || db)(TableName.SecretApprovalRequestSecret) .insert(data) .onConflict("id") // this will cause a conflict then merge the data .merge() // Merge the data with the existing data .returning("*"); return updatedApprovalSecrets; } catch (error) { throw new DatabaseError({ error, name: "bulk update secret" }); } }; const findByRequestId = async (requestId: string, tx?: Knex) => { try { const doc = await (tx || db.replicaNode())({ secVerTag: TableName.SecretTag }) .from(TableName.SecretApprovalRequestSecret) .where({ requestId }) .leftJoin( TableName.SecretApprovalRequestSecretTag, `${TableName.SecretApprovalRequestSecret}.id`, `${TableName.SecretApprovalRequestSecretTag}.secretId` ) .leftJoin(TableName.SecretTag, `${TableName.SecretApprovalRequestSecretTag}.tagId`, `${TableName.SecretTag}.id`) .leftJoin(TableName.Secret, `${TableName.SecretApprovalRequestSecret}.secretId`, `${TableName.Secret}.id`) .leftJoin( TableName.SecretVersion, `${TableName.SecretVersion}.id`, `${TableName.SecretApprovalRequestSecret}.secretVersion` ) .leftJoin( TableName.SecretVersionTag, `${TableName.SecretVersionTag}.${TableName.SecretVersion}Id`, `${TableName.SecretVersion}.id` ) .leftJoin( db.ref(TableName.SecretTag).as("secVerTag"), `${TableName.SecretVersionTag}.${TableName.SecretTag}Id`, db.ref("id").withSchema("secVerTag") ) .select(selectAllTableCols(TableName.SecretApprovalRequestSecret)) .select({ secVerTagId: "secVerTag.id", secVerTagColor: "secVerTag.color", secVerTagSlug: "secVerTag.slug" }) .select( db.ref("id").withSchema(TableName.SecretTag).as("tagId"), db.ref("id").withSchema(TableName.SecretApprovalRequestSecretTag).as("tagJnId"), db.ref("color").withSchema(TableName.SecretTag).as("tagColor"), db.ref("slug").withSchema(TableName.SecretTag).as("tagSlug") ) .select( db.ref("secretBlindIndex").withSchema(TableName.Secret).as("orgSecBlindIndex"), db.ref("version").withSchema(TableName.Secret).as("orgSecVersion"), db.ref("secretKeyIV").withSchema(TableName.Secret).as("orgSecKeyIV"), db.ref("secretKeyTag").withSchema(TableName.Secret).as("orgSecKeyTag"), db.ref("secretKeyCiphertext").withSchema(TableName.Secret).as("orgSecKeyCiphertext"), db.ref("secretValueIV").withSchema(TableName.Secret).as("orgSecValueIV"), db.ref("secretValueTag").withSchema(TableName.Secret).as("orgSecValueTag"), db.ref("secretValueCiphertext").withSchema(TableName.Secret).as("orgSecValueCiphertext"), db.ref("secretCommentIV").withSchema(TableName.Secret).as("orgSecCommentIV"), db.ref("secretCommentTag").withSchema(TableName.Secret).as("orgSecCommentTag"), db.ref("secretCommentCiphertext").withSchema(TableName.Secret).as("orgSecCommentCiphertext") ) .select( db.ref("version").withSchema(TableName.SecretVersion).as("secVerVersion"), db.ref("secretKeyIV").withSchema(TableName.SecretVersion).as("secVerKeyIV"), db.ref("secretKeyTag").withSchema(TableName.SecretVersion).as("secVerKeyTag"), db.ref("secretKeyCiphertext").withSchema(TableName.SecretVersion).as("secVerKeyCiphertext"), db.ref("secretValueIV").withSchema(TableName.SecretVersion).as("secVerValueIV"), db.ref("secretValueTag").withSchema(TableName.SecretVersion).as("secVerValueTag"), db.ref("secretValueCiphertext").withSchema(TableName.SecretVersion).as("secVerValueCiphertext"), db.ref("secretCommentIV").withSchema(TableName.SecretVersion).as("secVerCommentIV"), db.ref("secretCommentTag").withSchema(TableName.SecretVersion).as("secVerCommentTag"), db.ref("secretCommentCiphertext").withSchema(TableName.SecretVersion).as("secVerCommentCiphertext") ); const formatedDoc = sqlNestRelationships({ data: doc, key: "id", parentMapper: (data) => SecretApprovalRequestsSecretsSchema.omit({ secretVersion: true }).parse(data), childrenMapper: [ { key: "tagJnId", label: "tags" as const, mapper: ({ tagId: id, tagSlug: slug, tagColor: color }) => ({ id, name: slug, slug, color }) }, { key: "secretId", label: "secret" as const, mapper: ({ orgSecKeyIV, orgSecKeyTag, orgSecValueIV, orgSecVersion, orgSecValueTag, orgSecCommentIV, orgSecBlindIndex, orgSecCommentTag, orgSecKeyCiphertext, orgSecValueCiphertext, orgSecCommentCiphertext, secretId }) => secretId ? { id: secretId, version: orgSecVersion, secretBlindIndex: orgSecBlindIndex, secretKeyIV: orgSecKeyIV, secretKeyTag: orgSecKeyTag, secretKeyCiphertext: orgSecKeyCiphertext, secretValueIV: orgSecValueIV, secretValueTag: orgSecValueTag, secretValueCiphertext: orgSecValueCiphertext, secretCommentIV: orgSecCommentIV, secretCommentTag: orgSecCommentTag, secretCommentCiphertext: orgSecCommentCiphertext } : undefined }, { key: "secretVersion", label: "secretVersion" as const, mapper: ({ secVerCommentIV, secVerCommentCiphertext, secVerCommentTag, secVerValueCiphertext, secVerKeyIV, secVerKeyTag, secVerValueIV, secretVersion, secVerValueTag, secVerKeyCiphertext, secVerVersion }) => secretVersion ? { version: secVerVersion, id: secretVersion, secretKeyIV: secVerKeyIV, secretKeyTag: secVerKeyTag, secretKeyCiphertext: secVerKeyCiphertext, secretValueIV: secVerValueIV, secretValueTag: secVerValueTag, secretValueCiphertext: secVerValueCiphertext, secretCommentIV: secVerCommentIV, secretCommentTag: secVerCommentTag, secretCommentCiphertext: secVerCommentCiphertext } : undefined, childrenMapper: [ { key: "secVerTagId", label: "tags" as const, mapper: ({ secVerTagId: id, secVerTagSlug: slug, secVerTagColor: color }) => ({ // eslint-disable-next-line id, // eslint-disable-next-line name: slug, // eslint-disable-next-line slug, // eslint-disable-next-line color }) } ] } ] }); return formatedDoc?.map(({ secret, secretVersion, ...el }) => ({ ...el, secret: secret?.[0], secretVersion: secretVersion?.[0] })); } catch (error) { throw new DatabaseError({ error, name: "FindByRequestId" }); } }; const findByRequestIdBridgeSecretV2 = async (requestId: string, tx?: Knex) => { try { const doc = await (tx || db.replicaNode())({ secVerTag: TableName.SecretTag }) .from(TableName.SecretApprovalRequestSecretV2) .where({ requestId }) .leftJoin( TableName.SecretApprovalRequestSecretTagV2, `${TableName.SecretApprovalRequestSecretV2}.id`, `${TableName.SecretApprovalRequestSecretTagV2}.secretId` ) .leftJoin( TableName.SecretTag, `${TableName.SecretApprovalRequestSecretTagV2}.tagId`, `${TableName.SecretTag}.id` ) .leftJoin(TableName.SecretV2, `${TableName.SecretApprovalRequestSecretV2}.secretId`, `${TableName.SecretV2}.id`) .leftJoin( TableName.SecretVersionV2, `${TableName.SecretVersionV2}.id`, `${TableName.SecretApprovalRequestSecretV2}.secretVersion` ) .leftJoin( TableName.SecretVersionV2Tag, `${TableName.SecretVersionV2Tag}.${TableName.SecretVersionV2}Id`, `${TableName.SecretVersionV2}.id` ) .leftJoin( db.ref(TableName.SecretTag).as("secVerTag"), `${TableName.SecretVersionV2Tag}.${TableName.SecretTag}Id`, db.ref("id").withSchema("secVerTag") ) .leftJoin(TableName.ResourceMetadata, `${TableName.SecretV2}.id`, `${TableName.ResourceMetadata}.secretId`) .leftJoin( TableName.SecretRotationV2SecretMapping, `${TableName.SecretV2}.id`, `${TableName.SecretRotationV2SecretMapping}.secretId` ) .select(selectAllTableCols(TableName.SecretApprovalRequestSecretV2)) .select({ secVerTagId: "secVerTag.id", secVerTagColor: "secVerTag.color", secVerTagSlug: "secVerTag.slug" }) .select( db.ref("id").withSchema(TableName.SecretTag).as("tagId"), db.ref("id").withSchema(TableName.SecretApprovalRequestSecretTagV2).as("tagJnId"), db.ref("color").withSchema(TableName.SecretTag).as("tagColor"), db.ref("slug").withSchema(TableName.SecretTag).as("tagSlug") ) .select( db.ref("version").withSchema(TableName.SecretV2).as("orgSecVersion"), db.ref("key").withSchema(TableName.SecretV2).as("orgSecKey"), db.ref("encryptedValue").withSchema(TableName.SecretV2).as("orgSecValue"), db.ref("encryptedComment").withSchema(TableName.SecretV2).as("orgSecComment") ) .select( db.ref("version").withSchema(TableName.SecretVersionV2).as("secVerVersion"), db.ref("key").withSchema(TableName.SecretVersionV2).as("secVerKey"), db.ref("encryptedValue").withSchema(TableName.SecretVersionV2).as("secVerValue"), db.ref("encryptedComment").withSchema(TableName.SecretVersionV2).as("secVerComment") ) .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") ) .select(db.ref("rotationId").withSchema(TableName.SecretRotationV2SecretMapping)); const formatedDoc = sqlNestRelationships({ data: doc, key: "id", parentMapper: (data) => SecretApprovalRequestsSecretsV2Schema.omit({ secretVersion: true }).parse(data), childrenMapper: [ { key: "tagJnId", label: "tags" as const, mapper: ({ tagId: id, tagSlug: slug, tagColor: color }) => ({ id, name: slug, slug, color }) }, { key: "secretId", label: "secret" as const, mapper: ({ orgSecVersion, orgSecKey, orgSecValue, orgSecComment, secretId, rotationId }) => secretId ? { id: secretId, version: orgSecVersion, key: orgSecKey, encryptedValue: orgSecValue, encryptedComment: orgSecComment, isRotatedSecret: Boolean(rotationId), rotationId } : undefined }, { key: "secretVersion", label: "secretVersion" as const, mapper: ({ secretVersion, secVerVersion, secVerKey, secVerValue, secVerComment }) => secretVersion ? { version: secVerVersion, id: secretVersion, key: secVerKey, encryptedValue: secVerValue, encryptedComment: secVerComment } : undefined, childrenMapper: [ { key: "secVerTagId", label: "tags" as const, mapper: ({ secVerTagId: id, secVerTagSlug: slug, secVerTagColor: color }) => ({ // eslint-disable-next-line id, // eslint-disable-next-line name: slug, // eslint-disable-next-line slug, // eslint-disable-next-line color }) } ] }, { key: "metadataId", label: "oldSecretMetadata" as const, mapper: ({ metadataKey, metadataValue, metadataId }) => ({ id: metadataId, key: metadataKey, value: metadataValue }) } ] }); return formatedDoc?.map(({ secret, secretVersion, ...el }) => ({ ...el, secret: secret?.[0], secretVersion: secretVersion?.[0] })); } catch (error) { throw new DatabaseError({ error, name: "FindByRequestId" }); } }; // special query for migration to v2 secret const findByProjectId = async (projectId: string, tx?: Knex) => { try { const docs = await (tx || db)(TableName.SecretApprovalRequestSecret) .join( TableName.SecretApprovalRequest, `${TableName.SecretApprovalRequest}.id`, `${TableName.SecretApprovalRequestSecret}.requestId` ) .join(TableName.SecretFolder, `${TableName.SecretApprovalRequest}.folderId`, `${TableName.SecretFolder}.id`) .join(TableName.Environment, `${TableName.SecretFolder}.envId`, `${TableName.Environment}.id`) .leftJoin( TableName.SecretApprovalRequestSecretTag, `${TableName.SecretApprovalRequestSecret}.id`, `${TableName.SecretApprovalRequestSecretTag}.secretId` ) .where({ projectId }) .select(selectAllTableCols(TableName.SecretApprovalRequestSecret)) .select( db.ref("id").withSchema(TableName.SecretApprovalRequestSecretTag).as("secretApprovalTagId"), db.ref("secretId").withSchema(TableName.SecretApprovalRequestSecretTag).as("secretApprovalTagSecretId"), db.ref("tagId").withSchema(TableName.SecretApprovalRequestSecretTag).as("secretApprovalTagSecretTagId"), db.ref("createdAt").withSchema(TableName.SecretApprovalRequestSecretTag).as("secretApprovalTagCreatedAt"), db.ref("updatedAt").withSchema(TableName.SecretApprovalRequestSecretTag).as("secretApprovalTagUpdatedAt") ); const formatedDoc = sqlNestRelationships({ data: docs, key: "id", parentMapper: (data) => SecretApprovalRequestsSecretsSchema.parse(data), childrenMapper: [ { key: "secretApprovalTagId", label: "tags" as const, mapper: ({ secretApprovalTagSecretId, secretApprovalTagId, secretApprovalTagUpdatedAt, secretApprovalTagCreatedAt }) => ({ secretApprovalTagSecretId, secretApprovalTagId, secretApprovalTagUpdatedAt, secretApprovalTagCreatedAt }) } ] }); return formatedDoc; } catch (error) { throw new DatabaseError({ error, name: "FindByRequestId" }); } }; return { ...secretApprovalRequestSecretOrm, insertV2Bridge: secretApprovalRequestSecretV2Orm.insertMany, findByRequestId, findByRequestIdBridgeSecretV2, bulkUpdateNoVersionIncrement, findByProjectId, insertApprovalSecretTags: secretApprovalRequestSecretTagOrm.insertMany, insertApprovalSecretV2Tags: secretApprovalRequestSecretV2TagOrm.insertMany }; };