mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 18:27:36 +00:00
feat: resolved all ts issues on router schema and other functions
This commit is contained in:
@@ -3,16 +3,14 @@ import { z } from "zod";
|
|||||||
import {
|
import {
|
||||||
SecretApprovalRequestsReviewersSchema,
|
SecretApprovalRequestsReviewersSchema,
|
||||||
SecretApprovalRequestsSchema,
|
SecretApprovalRequestsSchema,
|
||||||
SecretApprovalRequestsSecretsSchema,
|
|
||||||
SecretsSchema,
|
|
||||||
SecretTagsSchema,
|
SecretTagsSchema,
|
||||||
SecretVersionsSchema,
|
|
||||||
UsersSchema
|
UsersSchema
|
||||||
} from "@app/db/schemas";
|
} from "@app/db/schemas";
|
||||||
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
||||||
import { ApprovalStatus, RequestState } from "@app/ee/services/secret-approval-request/secret-approval-request-types";
|
import { ApprovalStatus, RequestState } from "@app/ee/services/secret-approval-request/secret-approval-request-types";
|
||||||
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
|
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
|
||||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
|
import { secretRawSchema } from "@app/server/routes/sanitizedSchemas";
|
||||||
import { AuthMode } from "@app/services/auth/auth-type";
|
import { AuthMode } from "@app/services/auth/auth-type";
|
||||||
|
|
||||||
const approvalRequestUser = z.object({ userId: z.string() }).merge(
|
const approvalRequestUser = z.object({ userId: z.string() }).merge(
|
||||||
@@ -261,43 +259,30 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
|||||||
committerUser: approvalRequestUser,
|
committerUser: approvalRequestUser,
|
||||||
reviewers: approvalRequestUser.extend({ status: z.string() }).array(),
|
reviewers: approvalRequestUser.extend({ status: z.string() }).array(),
|
||||||
secretPath: z.string(),
|
secretPath: z.string(),
|
||||||
commits: SecretApprovalRequestsSecretsSchema.omit({ secretBlindIndex: true })
|
commits: secretRawSchema
|
||||||
|
.omit({ _id: true, environment: true, workspace: true, type: true, version: true })
|
||||||
.merge(
|
.merge(
|
||||||
z.object({
|
z.object({
|
||||||
tags: tagSchema,
|
tags: tagSchema,
|
||||||
secret: SecretsSchema.pick({
|
secret: z
|
||||||
id: true,
|
.object({
|
||||||
version: true,
|
id: z.string(),
|
||||||
secretKeyIV: true,
|
version: z.number(),
|
||||||
secretKeyTag: true,
|
secretKey: z.string(),
|
||||||
secretKeyCiphertext: true,
|
secretValue: z.string().optional(),
|
||||||
secretValueIV: true,
|
secretComment: z.string().optional()
|
||||||
secretValueTag: true,
|
})
|
||||||
secretValueCiphertext: true,
|
|
||||||
secretCommentIV: true,
|
|
||||||
secretCommentTag: true,
|
|
||||||
secretCommentCiphertext: true
|
|
||||||
})
|
|
||||||
.optional()
|
.optional()
|
||||||
.nullable(),
|
.nullable(),
|
||||||
secretVersion: SecretVersionsSchema.pick({
|
secretVersion: z
|
||||||
id: true,
|
.object({
|
||||||
version: true,
|
id: z.string(),
|
||||||
secretKeyIV: true,
|
version: z.number(),
|
||||||
secretKeyTag: true,
|
secretKey: z.string(),
|
||||||
secretKeyCiphertext: true,
|
secretValue: z.string().optional(),
|
||||||
secretValueIV: true,
|
secretComment: z.string().optional(),
|
||||||
secretValueTag: true,
|
tags: tagSchema
|
||||||
secretValueCiphertext: true,
|
})
|
||||||
secretCommentIV: true,
|
|
||||||
secretCommentTag: true,
|
|
||||||
secretCommentCiphertext: true
|
|
||||||
})
|
|
||||||
.merge(
|
|
||||||
z.object({
|
|
||||||
tags: tagSchema
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.optional()
|
.optional()
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { SecretVersionsSchema } from "@app/db/schemas";
|
|
||||||
import { readLimit } from "@app/server/config/rateLimiter";
|
import { readLimit } from "@app/server/config/rateLimiter";
|
||||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
|
import { secretRawSchema } from "@app/server/routes/sanitizedSchemas";
|
||||||
import { AuthMode } from "@app/services/auth/auth-type";
|
import { AuthMode } from "@app/services/auth/auth-type";
|
||||||
|
|
||||||
export const registerSecretVersionRouter = async (server: FastifyZodProvider) => {
|
export const registerSecretVersionRouter = async (server: FastifyZodProvider) => {
|
||||||
@@ -22,7 +22,7 @@ export const registerSecretVersionRouter = async (server: FastifyZodProvider) =>
|
|||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
secretVersions: SecretVersionsSchema.omit({ secretBlindIndex: true }).array()
|
secretVersions: secretRawSchema.array()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { SecretSnapshotsSchema, SecretTagsSchema, SecretVersionsSchema } from "@app/db/schemas";
|
import { SecretSnapshotsSchema, SecretTagsSchema } from "@app/db/schemas";
|
||||||
import { PROJECTS } from "@app/lib/api-docs";
|
import { PROJECTS } from "@app/lib/api-docs";
|
||||||
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
|
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
|
||||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
|
import { secretRawSchema } from "@app/server/routes/sanitizedSchemas";
|
||||||
import { AuthMode } from "@app/services/auth/auth-type";
|
import { AuthMode } from "@app/services/auth/auth-type";
|
||||||
|
|
||||||
export const registerSnapshotRouter = async (server: FastifyZodProvider) => {
|
export const registerSnapshotRouter = async (server: FastifyZodProvider) => {
|
||||||
@@ -27,7 +28,8 @@ export const registerSnapshotRouter = async (server: FastifyZodProvider) => {
|
|||||||
slug: z.string(),
|
slug: z.string(),
|
||||||
name: z.string()
|
name: z.string()
|
||||||
}),
|
}),
|
||||||
secretVersions: SecretVersionsSchema.omit({ secretBlindIndex: true })
|
secretVersions: secretRawSchema
|
||||||
|
.omit({ _id: true, environment: true, workspace: true, type: true, version: true })
|
||||||
.merge(
|
.merge(
|
||||||
z.object({
|
z.object({
|
||||||
tags: SecretTagsSchema.pick({
|
tags: SecretTagsSchema.pick({
|
||||||
|
|||||||
@@ -221,6 +221,15 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
);
|
);
|
||||||
secrets = encrypedSecrets.map((el) => ({
|
secrets = encrypedSecrets.map((el) => ({
|
||||||
...el,
|
...el,
|
||||||
|
secretKey: el.key,
|
||||||
|
id: el.id,
|
||||||
|
version: el.version,
|
||||||
|
secretValue: el.encryptedValue
|
||||||
|
? secretManagerDecryptor({ cipherTextBlob: el.encryptedValue }).toString()
|
||||||
|
: undefined,
|
||||||
|
secretComment: el.encryptedComment
|
||||||
|
? secretManagerDecryptor({ cipherTextBlob: el.encryptedComment }).toString()
|
||||||
|
: undefined,
|
||||||
secret: {
|
secret: {
|
||||||
secretKey: el.secret.key,
|
secretKey: el.secret.key,
|
||||||
id: el.secret.id,
|
id: el.secret.id,
|
||||||
@@ -249,6 +258,7 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
const encrypedSecrets = await secretApprovalRequestSecretDAL.findByRequestId(secretApprovalRequest.id);
|
const encrypedSecrets = await secretApprovalRequestSecretDAL.findByRequestId(secretApprovalRequest.id);
|
||||||
secrets = encrypedSecrets.map((el) => ({
|
secrets = encrypedSecrets.map((el) => ({
|
||||||
...el,
|
...el,
|
||||||
|
...decryptSecretWithBot(el, botKey),
|
||||||
secret: {
|
secret: {
|
||||||
id: el.secret.id,
|
id: el.secret.id,
|
||||||
version: el.secret.version,
|
version: el.secret.version,
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
import { ForbiddenError, subject } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
|
|
||||||
import { TableName, TSecretTagJunctionInsert, TSecretV2TagJunctionInsert } from "@app/db/schemas";
|
import { TableName, TSecretTagJunctionInsert, TSecretV2TagJunctionInsert } from "@app/db/schemas";
|
||||||
|
import { decryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto";
|
||||||
import { BadRequestError, InternalServerError } from "@app/lib/errors";
|
import { BadRequestError, InternalServerError } from "@app/lib/errors";
|
||||||
import { groupBy } from "@app/lib/fn";
|
import { groupBy } from "@app/lib/fn";
|
||||||
import { logger } from "@app/lib/logger";
|
import { logger } from "@app/lib/logger";
|
||||||
|
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||||
|
import { KmsDataKey } from "@app/services/kms/kms-types";
|
||||||
|
import { TProjectBotServiceFactory } from "@app/services/project-bot/project-bot-service";
|
||||||
import { TSecretDALFactory } from "@app/services/secret/secret-dal";
|
import { TSecretDALFactory } from "@app/services/secret/secret-dal";
|
||||||
import { TSecretVersionDALFactory } from "@app/services/secret/secret-version-dal";
|
import { TSecretVersionDALFactory } from "@app/services/secret/secret-version-dal";
|
||||||
import { TSecretVersionTagDALFactory } from "@app/services/secret/secret-version-tag-dal";
|
import { TSecretVersionTagDALFactory } from "@app/services/secret/secret-version-tag-dal";
|
||||||
@@ -45,6 +49,8 @@ type TSecretSnapshotServiceFactoryDep = {
|
|||||||
folderDAL: Pick<TSecretFolderDALFactory, "findById" | "findBySecretPath" | "delete" | "insertMany" | "find">;
|
folderDAL: Pick<TSecretFolderDALFactory, "findById" | "findBySecretPath" | "delete" | "insertMany" | "find">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||||
licenseService: Pick<TLicenseServiceFactory, "isValidLicense">;
|
licenseService: Pick<TLicenseServiceFactory, "isValidLicense">;
|
||||||
|
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
|
||||||
|
projectBotService: Pick<TProjectBotServiceFactory, "getBotKey">;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TSecretSnapshotServiceFactory = ReturnType<typeof secretSnapshotServiceFactory>;
|
export type TSecretSnapshotServiceFactory = ReturnType<typeof secretSnapshotServiceFactory>;
|
||||||
@@ -64,7 +70,9 @@ export const secretSnapshotServiceFactory = ({
|
|||||||
secretVersionV2BridgeDAL,
|
secretVersionV2BridgeDAL,
|
||||||
secretV2BridgeDAL,
|
secretV2BridgeDAL,
|
||||||
snapshotSecretV2BridgeDAL,
|
snapshotSecretV2BridgeDAL,
|
||||||
secretVersionV2TagBridgeDAL
|
secretVersionV2TagBridgeDAL,
|
||||||
|
kmsService,
|
||||||
|
projectBotService
|
||||||
}: TSecretSnapshotServiceFactoryDep) => {
|
}: TSecretSnapshotServiceFactoryDep) => {
|
||||||
const projectSecretSnapshotCount = async ({
|
const projectSecretSnapshotCount = async ({
|
||||||
environment,
|
environment,
|
||||||
@@ -144,9 +152,55 @@ export const secretSnapshotServiceFactory = ({
|
|||||||
const shouldUseBridge = snapshot.projectVersion === 3;
|
const shouldUseBridge = snapshot.projectVersion === 3;
|
||||||
let snapshotDetails;
|
let snapshotDetails;
|
||||||
if (shouldUseBridge) {
|
if (shouldUseBridge) {
|
||||||
snapshotDetails = await snapshotDAL.findSecretSnapshotV2DataById(id);
|
const { decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({
|
||||||
|
type: KmsDataKey.SecretManager,
|
||||||
|
projectId: snapshot.projectId
|
||||||
|
});
|
||||||
|
const encryptedSnapshotDetails = await snapshotDAL.findSecretSnapshotV2DataById(id);
|
||||||
|
snapshotDetails = {
|
||||||
|
...encryptedSnapshotDetails,
|
||||||
|
secretVersions: encryptedSnapshotDetails.secretVersions.map((el) => ({
|
||||||
|
...el,
|
||||||
|
secretKey: el.key,
|
||||||
|
secretValue: el.encryptedValue
|
||||||
|
? secretManagerDecryptor({ cipherTextBlob: el.encryptedValue }).toString()
|
||||||
|
: undefined,
|
||||||
|
secretComment: el.encryptedComment
|
||||||
|
? secretManagerDecryptor({ cipherTextBlob: el.encryptedComment }).toString()
|
||||||
|
: undefined
|
||||||
|
}))
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
snapshotDetails = await snapshotDAL.findSecretSnapshotDataById(id);
|
const encryptedSnapshotDetails = await snapshotDAL.findSecretSnapshotDataById(id);
|
||||||
|
const { botKey } = await projectBotService.getBotKey(snapshot.projectId);
|
||||||
|
if (!botKey) throw new BadRequestError({ message: "bot not found" });
|
||||||
|
snapshotDetails = {
|
||||||
|
...encryptedSnapshotDetails,
|
||||||
|
secretVersions: encryptedSnapshotDetails.secretVersions.map((el) => ({
|
||||||
|
...el,
|
||||||
|
secretKey: decryptSymmetric128BitHexKeyUTF8({
|
||||||
|
ciphertext: el.secretKeyCiphertext,
|
||||||
|
iv: el.secretKeyIV,
|
||||||
|
tag: el.secretKeyTag,
|
||||||
|
key: botKey
|
||||||
|
}),
|
||||||
|
secretValue: decryptSymmetric128BitHexKeyUTF8({
|
||||||
|
ciphertext: el.secretValueCiphertext,
|
||||||
|
iv: el.secretValueIV,
|
||||||
|
tag: el.secretValueTag,
|
||||||
|
key: botKey
|
||||||
|
}),
|
||||||
|
secretComment:
|
||||||
|
el.secretCommentTag && el.secretCommentIV && el.secretCommentCiphertext
|
||||||
|
? decryptSymmetric128BitHexKeyUTF8({
|
||||||
|
ciphertext: el.secretCommentCiphertext,
|
||||||
|
iv: el.secretCommentIV,
|
||||||
|
tag: el.secretCommentTag,
|
||||||
|
key: botKey
|
||||||
|
})
|
||||||
|
: ""
|
||||||
|
}))
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const fullFolderPath = await getFullFolderPath({
|
const fullFolderPath = await getFullFolderPath({
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ import { secretSnapshotServiceFactory } from "@app/ee/services/secret-snapshot/s
|
|||||||
import { snapshotDALFactory } from "@app/ee/services/secret-snapshot/snapshot-dal";
|
import { snapshotDALFactory } from "@app/ee/services/secret-snapshot/snapshot-dal";
|
||||||
import { snapshotFolderDALFactory } from "@app/ee/services/secret-snapshot/snapshot-folder-dal";
|
import { snapshotFolderDALFactory } from "@app/ee/services/secret-snapshot/snapshot-folder-dal";
|
||||||
import { snapshotSecretDALFactory } from "@app/ee/services/secret-snapshot/snapshot-secret-dal";
|
import { snapshotSecretDALFactory } from "@app/ee/services/secret-snapshot/snapshot-secret-dal";
|
||||||
|
import { snapshotSecretV2DALFactory } from "@app/ee/services/secret-snapshot/snapshot-secret-v2-dal";
|
||||||
import { trustedIpDALFactory } from "@app/ee/services/trusted-ip/trusted-ip-dal";
|
import { trustedIpDALFactory } from "@app/ee/services/trusted-ip/trusted-ip-dal";
|
||||||
import { trustedIpServiceFactory } from "@app/ee/services/trusted-ip/trusted-ip-service";
|
import { trustedIpServiceFactory } from "@app/ee/services/trusted-ip/trusted-ip-service";
|
||||||
import { TKeyStoreFactory } from "@app/keystore/keystore";
|
import { TKeyStoreFactory } from "@app/keystore/keystore";
|
||||||
@@ -235,7 +236,7 @@ export const registerRoutes = async (
|
|||||||
|
|
||||||
const secretV2BridgeDAL = secretV2BridgeDALFactory(db);
|
const secretV2BridgeDAL = secretV2BridgeDALFactory(db);
|
||||||
const secretVersionV2BridgeDAL = secretVersionV2BridgeDALFactory(db);
|
const secretVersionV2BridgeDAL = secretVersionV2BridgeDALFactory(db);
|
||||||
const secretVersionV2TagBridgeDAL = secretVersionV2TagBridgeDALFactory(db);
|
const secretVersionTagV2BridgeDAL = secretVersionV2TagBridgeDALFactory(db);
|
||||||
|
|
||||||
const integrationDAL = integrationDALFactory(db);
|
const integrationDAL = integrationDALFactory(db);
|
||||||
const integrationAuthDAL = integrationAuthDALFactory(db);
|
const integrationAuthDAL = integrationAuthDALFactory(db);
|
||||||
@@ -285,6 +286,7 @@ export const registerRoutes = async (
|
|||||||
const secretRotationDAL = secretRotationDALFactory(db);
|
const secretRotationDAL = secretRotationDALFactory(db);
|
||||||
const snapshotDAL = snapshotDALFactory(db);
|
const snapshotDAL = snapshotDALFactory(db);
|
||||||
const snapshotSecretDAL = snapshotSecretDALFactory(db);
|
const snapshotSecretDAL = snapshotSecretDALFactory(db);
|
||||||
|
const snapshotSecretV2BridgeDAL = snapshotSecretV2DALFactory(db);
|
||||||
const snapshotFolderDAL = snapshotFolderDALFactory(db);
|
const snapshotFolderDAL = snapshotFolderDALFactory(db);
|
||||||
|
|
||||||
const gitAppInstallSessionDAL = gitAppInstallSessionDALFactory(db);
|
const gitAppInstallSessionDAL = gitAppInstallSessionDALFactory(db);
|
||||||
@@ -665,7 +667,13 @@ export const registerRoutes = async (
|
|||||||
secretVersionDAL,
|
secretVersionDAL,
|
||||||
folderVersionDAL,
|
folderVersionDAL,
|
||||||
secretTagDAL,
|
secretTagDAL,
|
||||||
secretVersionTagDAL
|
secretVersionTagDAL,
|
||||||
|
projectBotService,
|
||||||
|
kmsService,
|
||||||
|
secretV2BridgeDAL,
|
||||||
|
secretVersionV2BridgeDAL,
|
||||||
|
snapshotSecretV2BridgeDAL,
|
||||||
|
secretVersionV2TagBridgeDAL: secretVersionTagV2BridgeDAL
|
||||||
});
|
});
|
||||||
const webhookService = webhookServiceFactory({
|
const webhookService = webhookServiceFactory({
|
||||||
permissionService,
|
permissionService,
|
||||||
@@ -689,7 +697,8 @@ export const registerRoutes = async (
|
|||||||
integrationDAL,
|
integrationDAL,
|
||||||
permissionService,
|
permissionService,
|
||||||
projectBotDAL,
|
projectBotDAL,
|
||||||
projectBotService
|
projectBotService,
|
||||||
|
kmsService
|
||||||
});
|
});
|
||||||
const secretQueueService = secretQueueFactory({
|
const secretQueueService = secretQueueFactory({
|
||||||
queueService,
|
queueService,
|
||||||
@@ -709,7 +718,11 @@ export const registerRoutes = async (
|
|||||||
secretVersionDAL,
|
secretVersionDAL,
|
||||||
secretBlindIndexDAL,
|
secretBlindIndexDAL,
|
||||||
secretTagDAL,
|
secretTagDAL,
|
||||||
secretVersionTagDAL
|
secretVersionTagDAL,
|
||||||
|
kmsService,
|
||||||
|
secretVersionV2BridgeDAL,
|
||||||
|
secretV2BridgeDAL,
|
||||||
|
secretVersionTagV2BridgeDAL
|
||||||
});
|
});
|
||||||
const secretImportService = secretImportServiceFactory({
|
const secretImportService = secretImportServiceFactory({
|
||||||
licenseService,
|
licenseService,
|
||||||
@@ -720,7 +733,9 @@ export const registerRoutes = async (
|
|||||||
secretImportDAL,
|
secretImportDAL,
|
||||||
projectDAL,
|
projectDAL,
|
||||||
secretDAL,
|
secretDAL,
|
||||||
secretQueueService
|
secretQueueService,
|
||||||
|
secretV2BridgeDAL,
|
||||||
|
kmsService
|
||||||
});
|
});
|
||||||
const secretBlindIndexService = secretBlindIndexServiceFactory({
|
const secretBlindIndexService = secretBlindIndexServiceFactory({
|
||||||
permissionService,
|
permissionService,
|
||||||
@@ -734,13 +749,39 @@ export const registerRoutes = async (
|
|||||||
secretQueueService,
|
secretQueueService,
|
||||||
secretDAL: secretV2BridgeDAL,
|
secretDAL: secretV2BridgeDAL,
|
||||||
permissionService,
|
permissionService,
|
||||||
secretVersionTagDAL: secretVersionV2TagBridgeDAL,
|
secretVersionTagDAL: secretVersionTagV2BridgeDAL,
|
||||||
secretTagDAL,
|
secretTagDAL,
|
||||||
projectEnvDAL,
|
projectEnvDAL,
|
||||||
secretImportDAL,
|
secretImportDAL,
|
||||||
secretApprovalRequestDAL,
|
secretApprovalRequestDAL,
|
||||||
secretApprovalPolicyService,
|
secretApprovalPolicyService,
|
||||||
secretApprovalRequestSecretDAL
|
secretApprovalRequestSecretDAL,
|
||||||
|
kmsService,
|
||||||
|
snapshotService
|
||||||
|
});
|
||||||
|
|
||||||
|
const secretApprovalRequestService = secretApprovalRequestServiceFactory({
|
||||||
|
permissionService,
|
||||||
|
projectBotService,
|
||||||
|
folderDAL,
|
||||||
|
secretDAL,
|
||||||
|
secretTagDAL,
|
||||||
|
secretApprovalRequestSecretDAL,
|
||||||
|
secretApprovalRequestReviewerDAL,
|
||||||
|
projectDAL,
|
||||||
|
secretVersionDAL,
|
||||||
|
secretBlindIndexDAL,
|
||||||
|
secretApprovalRequestDAL,
|
||||||
|
snapshotService,
|
||||||
|
secretVersionTagDAL,
|
||||||
|
secretQueueService,
|
||||||
|
kmsService,
|
||||||
|
secretV2BridgeDAL,
|
||||||
|
secretVersionV2BridgeDAL,
|
||||||
|
secretVersionTagV2BridgeDAL,
|
||||||
|
smtpService,
|
||||||
|
projectEnvDAL,
|
||||||
|
userDAL
|
||||||
});
|
});
|
||||||
|
|
||||||
const secretService = secretServiceFactory({
|
const secretService = secretServiceFactory({
|
||||||
@@ -760,7 +801,8 @@ export const registerRoutes = async (
|
|||||||
secretApprovalPolicyService,
|
secretApprovalPolicyService,
|
||||||
secretApprovalRequestDAL,
|
secretApprovalRequestDAL,
|
||||||
secretApprovalRequestSecretDAL,
|
secretApprovalRequestSecretDAL,
|
||||||
secretV2BridgeService
|
secretV2BridgeService,
|
||||||
|
secretApprovalRequestService
|
||||||
});
|
});
|
||||||
|
|
||||||
const secretSharingService = secretSharingServiceFactory({
|
const secretSharingService = secretSharingServiceFactory({
|
||||||
@@ -769,26 +811,6 @@ export const registerRoutes = async (
|
|||||||
orgDAL
|
orgDAL
|
||||||
});
|
});
|
||||||
|
|
||||||
const secretApprovalRequestService = secretApprovalRequestServiceFactory({
|
|
||||||
permissionService,
|
|
||||||
projectBotService,
|
|
||||||
folderDAL,
|
|
||||||
secretDAL,
|
|
||||||
secretTagDAL,
|
|
||||||
secretApprovalRequestSecretDAL,
|
|
||||||
secretApprovalRequestReviewerDAL,
|
|
||||||
projectDAL,
|
|
||||||
secretVersionDAL,
|
|
||||||
secretBlindIndexDAL,
|
|
||||||
secretApprovalRequestDAL,
|
|
||||||
snapshotService,
|
|
||||||
secretVersionTagDAL,
|
|
||||||
secretQueueService,
|
|
||||||
smtpService,
|
|
||||||
userDAL,
|
|
||||||
projectEnvDAL
|
|
||||||
});
|
|
||||||
|
|
||||||
const accessApprovalPolicyService = accessApprovalPolicyServiceFactory({
|
const accessApprovalPolicyService = accessApprovalPolicyServiceFactory({
|
||||||
accessApprovalPolicyDAL,
|
accessApprovalPolicyDAL,
|
||||||
accessApprovalPolicyApproverDAL,
|
accessApprovalPolicyApproverDAL,
|
||||||
@@ -822,11 +844,14 @@ export const registerRoutes = async (
|
|||||||
queueService,
|
queueService,
|
||||||
folderDAL,
|
folderDAL,
|
||||||
secretApprovalPolicyService,
|
secretApprovalPolicyService,
|
||||||
secretBlindIndexDAL,
|
|
||||||
secretApprovalRequestDAL,
|
secretApprovalRequestDAL,
|
||||||
secretApprovalRequestSecretDAL,
|
secretApprovalRequestSecretDAL,
|
||||||
secretQueueService,
|
secretQueueService,
|
||||||
projectBotService
|
projectBotService,
|
||||||
|
kmsService,
|
||||||
|
secretV2BridgeDAL,
|
||||||
|
secretVersionV2TagBridgeDAL: secretVersionTagV2BridgeDAL,
|
||||||
|
secretVersionV2BridgeDAL
|
||||||
});
|
});
|
||||||
const secretRotationQueue = secretRotationQueueFactory({
|
const secretRotationQueue = secretRotationQueueFactory({
|
||||||
telemetryService,
|
telemetryService,
|
||||||
@@ -834,7 +859,10 @@ export const registerRoutes = async (
|
|||||||
queue: queueService,
|
queue: queueService,
|
||||||
secretDAL,
|
secretDAL,
|
||||||
secretVersionDAL,
|
secretVersionDAL,
|
||||||
projectBotService
|
projectBotService,
|
||||||
|
secretVersionV2BridgeDAL,
|
||||||
|
secretV2BridgeDAL,
|
||||||
|
kmsService
|
||||||
});
|
});
|
||||||
|
|
||||||
const secretRotationService = secretRotationServiceFactory({
|
const secretRotationService = secretRotationServiceFactory({
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import { getUserAgentType } from "@app/server/plugins/audit-log";
|
|||||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
import { ActorType, AuthMode } from "@app/services/auth/auth-type";
|
import { ActorType, AuthMode } from "@app/services/auth/auth-type";
|
||||||
import { ProjectFilterType } from "@app/services/project/project-types";
|
import { ProjectFilterType } from "@app/services/project/project-types";
|
||||||
import { SecretOperations } from "@app/services/secret/secret-types";
|
import { SecretOperations, SecretProtectionType } from "@app/services/secret/secret-types";
|
||||||
import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types";
|
import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types";
|
||||||
|
|
||||||
import { secretRawSchema } from "../sanitizedSchemas";
|
import { secretRawSchema } from "../sanitizedSchemas";
|
||||||
@@ -442,14 +442,17 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
secretReminderNote: z.string().optional().nullable().describe(RAW_SECRETS.CREATE.secretReminderNote)
|
secretReminderNote: z.string().optional().nullable().describe(RAW_SECRETS.CREATE.secretReminderNote)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.union([
|
||||||
secret: secretRawSchema
|
z.object({
|
||||||
})
|
secret: secretRawSchema
|
||||||
|
}),
|
||||||
|
z.object({ approval: SecretApprovalRequestsSchema }).describe("When secret protection policy is enabled")
|
||||||
|
])
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const secret = await server.services.secret.createSecretRaw({
|
const secretOperation = await server.services.secret.createSecretRaw({
|
||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actor: req.permission.type,
|
actor: req.permission.type,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
@@ -466,7 +469,11 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
secretReminderNote: req.body.secretReminderNote,
|
secretReminderNote: req.body.secretReminderNote,
|
||||||
secretReminderRepeatDays: req.body.secretReminderRepeatDays
|
secretReminderRepeatDays: req.body.secretReminderRepeatDays
|
||||||
});
|
});
|
||||||
|
if (secretOperation.type === SecretProtectionType.Approval) {
|
||||||
|
return { approval: secretOperation.approval };
|
||||||
|
}
|
||||||
|
|
||||||
|
const { secret } = secretOperation;
|
||||||
await server.services.auditLog.createAuditLog({
|
await server.services.auditLog.createAuditLog({
|
||||||
projectId: req.body.workspaceId,
|
projectId: req.body.workspaceId,
|
||||||
...req.auditLogInfo,
|
...req.auditLogInfo,
|
||||||
@@ -542,14 +549,17 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
secretComment: z.string().optional().describe(RAW_SECRETS.UPDATE.secretComment)
|
secretComment: z.string().optional().describe(RAW_SECRETS.UPDATE.secretComment)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.union([
|
||||||
secret: secretRawSchema
|
z.object({
|
||||||
})
|
secret: secretRawSchema
|
||||||
|
}),
|
||||||
|
z.object({ approval: SecretApprovalRequestsSchema }).describe("When secret protection policy is enabled")
|
||||||
|
])
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const secret = await server.services.secret.updateSecretRaw({
|
const secretOperation = await server.services.secret.updateSecretRaw({
|
||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actor: req.permission.type,
|
actor: req.permission.type,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
@@ -568,6 +578,10 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
newSecretName: req.body.newSecretName,
|
newSecretName: req.body.newSecretName,
|
||||||
secretComment: req.body.secretComment
|
secretComment: req.body.secretComment
|
||||||
});
|
});
|
||||||
|
if (secretOperation.type === SecretProtectionType.Approval) {
|
||||||
|
return { approval: secretOperation.approval };
|
||||||
|
}
|
||||||
|
const { secret } = secretOperation;
|
||||||
|
|
||||||
await server.services.auditLog.createAuditLog({
|
await server.services.auditLog.createAuditLog({
|
||||||
projectId: req.body.workspaceId,
|
projectId: req.body.workspaceId,
|
||||||
@@ -628,14 +642,17 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
type: z.nativeEnum(SecretType).default(SecretType.Shared).describe(RAW_SECRETS.DELETE.type)
|
type: z.nativeEnum(SecretType).default(SecretType.Shared).describe(RAW_SECRETS.DELETE.type)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.union([
|
||||||
secret: secretRawSchema
|
z.object({
|
||||||
})
|
secret: secretRawSchema
|
||||||
|
}),
|
||||||
|
z.object({ approval: SecretApprovalRequestsSchema }).describe("When secret protection policy is enabled")
|
||||||
|
])
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const secret = await server.services.secret.deleteSecretRaw({
|
const secretOperation = await server.services.secret.deleteSecretRaw({
|
||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actor: req.permission.type,
|
actor: req.permission.type,
|
||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
@@ -646,6 +663,10 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
secretName: req.params.secretName,
|
secretName: req.params.secretName,
|
||||||
type: req.body.type
|
type: req.body.type
|
||||||
});
|
});
|
||||||
|
if (secretOperation.type === SecretProtectionType.Approval) {
|
||||||
|
return { approval: secretOperation.approval };
|
||||||
|
}
|
||||||
|
const { secret } = secretOperation;
|
||||||
|
|
||||||
await server.services.auditLog.createAuditLog({
|
await server.services.auditLog.createAuditLog({
|
||||||
projectId: req.body.workspaceId,
|
projectId: req.body.workspaceId,
|
||||||
@@ -1815,16 +1836,19 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
.min(1)
|
.min(1)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.union([
|
||||||
secrets: secretRawSchema.array()
|
z.object({
|
||||||
})
|
secrets: secretRawSchema.array()
|
||||||
|
}),
|
||||||
|
z.object({ approval: SecretApprovalRequestsSchema }).describe("When secret protection policy is enabled")
|
||||||
|
])
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const { environment, projectSlug, secretPath, secrets: inputSecrets } = req.body;
|
const { environment, projectSlug, secretPath, secrets: inputSecrets } = req.body;
|
||||||
|
|
||||||
const secrets = await server.services.secret.createManySecretsRaw({
|
const secretOperation = await server.services.secret.createManySecretsRaw({
|
||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actor: req.permission.type,
|
actor: req.permission.type,
|
||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
@@ -1835,6 +1859,10 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
projectId: req.body.workspaceId,
|
projectId: req.body.workspaceId,
|
||||||
secrets: inputSecrets
|
secrets: inputSecrets
|
||||||
});
|
});
|
||||||
|
if (secretOperation.type === SecretProtectionType.Approval) {
|
||||||
|
return { approval: secretOperation.approval };
|
||||||
|
}
|
||||||
|
const { secrets } = secretOperation;
|
||||||
|
|
||||||
await server.services.auditLog.createAuditLog({
|
await server.services.auditLog.createAuditLog({
|
||||||
projectId: secrets[0].workspace,
|
projectId: secrets[0].workspace,
|
||||||
@@ -1914,15 +1942,18 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
.min(1)
|
.min(1)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.union([
|
||||||
secrets: secretRawSchema.array()
|
z.object({
|
||||||
})
|
secrets: secretRawSchema.array()
|
||||||
|
}),
|
||||||
|
z.object({ approval: SecretApprovalRequestsSchema }).describe("When secret protection policy is enabled")
|
||||||
|
])
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const { environment, projectSlug, secretPath, secrets: inputSecrets } = req.body;
|
const { environment, projectSlug, secretPath, secrets: inputSecrets } = req.body;
|
||||||
const secrets = await server.services.secret.updateManySecretsRaw({
|
const secretOperation = await server.services.secret.updateManySecretsRaw({
|
||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actor: req.permission.type,
|
actor: req.permission.type,
|
||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
@@ -1933,6 +1964,10 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
projectId: req.body.workspaceId,
|
projectId: req.body.workspaceId,
|
||||||
secrets: inputSecrets
|
secrets: inputSecrets
|
||||||
});
|
});
|
||||||
|
if (secretOperation.type === SecretProtectionType.Approval) {
|
||||||
|
return { approval: secretOperation.approval };
|
||||||
|
}
|
||||||
|
const { secrets } = secretOperation;
|
||||||
|
|
||||||
await server.services.auditLog.createAuditLog({
|
await server.services.auditLog.createAuditLog({
|
||||||
projectId: secrets[0].workspace,
|
projectId: secrets[0].workspace,
|
||||||
@@ -1999,15 +2034,18 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
.min(1)
|
.min(1)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.union([
|
||||||
secrets: secretRawSchema.array()
|
z.object({
|
||||||
})
|
secrets: secretRawSchema.array()
|
||||||
|
}),
|
||||||
|
z.object({ approval: SecretApprovalRequestsSchema }).describe("When secret protection policy is enabled")
|
||||||
|
])
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const { environment, projectSlug, secretPath, secrets: inputSecrets } = req.body;
|
const { environment, projectSlug, secretPath, secrets: inputSecrets } = req.body;
|
||||||
const secrets = await server.services.secret.deleteManySecretsRaw({
|
const secretOperation = await server.services.secret.deleteManySecretsRaw({
|
||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actor: req.permission.type,
|
actor: req.permission.type,
|
||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
@@ -2018,6 +2056,10 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
projectId: req.body.workspaceId,
|
projectId: req.body.workspaceId,
|
||||||
secrets: inputSecrets
|
secrets: inputSecrets
|
||||||
});
|
});
|
||||||
|
if (secretOperation.type === SecretProtectionType.Approval) {
|
||||||
|
return { approval: secretOperation.approval };
|
||||||
|
}
|
||||||
|
const { secrets } = secretOperation;
|
||||||
|
|
||||||
await server.services.auditLog.createAuditLog({
|
await server.services.auditLog.createAuditLog({
|
||||||
projectId: secrets[0].workspace,
|
projectId: secrets[0].workspace,
|
||||||
|
|||||||
@@ -995,9 +995,20 @@ export const secretV2BridgeServiceFactory = ({
|
|||||||
actorOrgId
|
actorOrgId
|
||||||
);
|
);
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
|
||||||
|
const { decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({
|
||||||
|
type: KmsDataKey.SecretManager,
|
||||||
|
projectId: folder.projectId
|
||||||
|
});
|
||||||
const secretVersions = await secretVersionDAL.find({ secretId }, { offset, limit, sort: [["createdAt", "desc"]] });
|
const secretVersions = await secretVersionDAL.find({ secretId }, { offset, limit, sort: [["createdAt", "desc"]] });
|
||||||
return secretVersions;
|
return secretVersions.map((el) =>
|
||||||
|
reshapeBridgeSecret(folder.projectId, folder.environment.envSlug, "/", {
|
||||||
|
...el,
|
||||||
|
value: el.encryptedValue ? secretManagerDecryptor({ cipherTextBlob: el.encryptedValue }).toString() : undefined,
|
||||||
|
comment: el.encryptedComment
|
||||||
|
? secretManagerDecryptor({ cipherTextBlob: el.encryptedComment }).toString()
|
||||||
|
: undefined
|
||||||
|
})
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// this is a backfilling API for secret references
|
// this is a backfilling API for secret references
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ import {
|
|||||||
import { TSecretQueueFactory } from "./secret-queue";
|
import { TSecretQueueFactory } from "./secret-queue";
|
||||||
import {
|
import {
|
||||||
SecretOperations,
|
SecretOperations,
|
||||||
|
SecretProtectionType,
|
||||||
TAttachSecretTagsDTO,
|
TAttachSecretTagsDTO,
|
||||||
TBackFillSecretReferencesDTO,
|
TBackFillSecretReferencesDTO,
|
||||||
TCreateBulkSecretDTO,
|
TCreateBulkSecretDTO,
|
||||||
@@ -1228,7 +1229,7 @@ export const secretServiceFactory = ({
|
|||||||
: undefined;
|
: undefined;
|
||||||
if (shouldUseSecretV2Bridge) {
|
if (shouldUseSecretV2Bridge) {
|
||||||
if (policy) {
|
if (policy) {
|
||||||
return secretApprovalRequestService.generateSecretApprovalRequestV2Bridge({
|
const approval = await secretApprovalRequestService.generateSecretApprovalRequestV2Bridge({
|
||||||
policy,
|
policy,
|
||||||
secretPath,
|
secretPath,
|
||||||
environment,
|
environment,
|
||||||
@@ -1251,6 +1252,7 @@ export const secretServiceFactory = ({
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return { type: SecretProtectionType.Approval as const, approval };
|
||||||
}
|
}
|
||||||
|
|
||||||
const secret = await secretV2BridgeService.createSecret({
|
const secret = await secretV2BridgeService.createSecret({
|
||||||
@@ -1270,7 +1272,7 @@ export const secretServiceFactory = ({
|
|||||||
skipMultilineEncoding,
|
skipMultilineEncoding,
|
||||||
secretReminderRepeatDays
|
secretReminderRepeatDays
|
||||||
});
|
});
|
||||||
return secret;
|
return { secret, type: SecretProtectionType.Direct as const };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
||||||
@@ -1278,7 +1280,7 @@ export const secretServiceFactory = ({
|
|||||||
const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8(secretValue || "", botKey);
|
const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8(secretValue || "", botKey);
|
||||||
const secretCommentEncrypted = encryptSymmetric128BitHexKeyUTF8(secretComment || "", botKey);
|
const secretCommentEncrypted = encryptSymmetric128BitHexKeyUTF8(secretComment || "", botKey);
|
||||||
if (policy) {
|
if (policy) {
|
||||||
return secretApprovalRequestService.generateSecretApprovalRequest({
|
const approval = await secretApprovalRequestService.generateSecretApprovalRequest({
|
||||||
policy,
|
policy,
|
||||||
secretPath,
|
secretPath,
|
||||||
environment,
|
environment,
|
||||||
@@ -1306,6 +1308,7 @@ export const secretServiceFactory = ({
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return { type: SecretProtectionType.Approval as const, approval };
|
||||||
}
|
}
|
||||||
|
|
||||||
const secret = await createSecret({
|
const secret = await createSecret({
|
||||||
@@ -1333,7 +1336,7 @@ export const secretServiceFactory = ({
|
|||||||
tags: tagIds
|
tags: tagIds
|
||||||
});
|
});
|
||||||
|
|
||||||
return decryptSecretRaw(secret, botKey);
|
return { type: SecretProtectionType.Direct as const, secret: decryptSecretRaw(secret, botKey) };
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateSecretRaw = async ({
|
const updateSecretRaw = async ({
|
||||||
@@ -1362,7 +1365,7 @@ export const secretServiceFactory = ({
|
|||||||
: undefined;
|
: undefined;
|
||||||
if (shouldUseSecretV2Bridge) {
|
if (shouldUseSecretV2Bridge) {
|
||||||
if (policy) {
|
if (policy) {
|
||||||
return secretApprovalRequestService.generateSecretApprovalRequestV2Bridge({
|
const approval = await secretApprovalRequestService.generateSecretApprovalRequestV2Bridge({
|
||||||
policy,
|
policy,
|
||||||
secretPath,
|
secretPath,
|
||||||
environment,
|
environment,
|
||||||
@@ -1386,6 +1389,7 @@ export const secretServiceFactory = ({
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return { type: SecretProtectionType.Approval as const, approval };
|
||||||
}
|
}
|
||||||
const secret = await secretV2BridgeService.updateSecret({
|
const secret = await secretV2BridgeService.updateSecret({
|
||||||
secretReminderRepeatDays,
|
secretReminderRepeatDays,
|
||||||
@@ -1406,7 +1410,7 @@ export const secretServiceFactory = ({
|
|||||||
metadata,
|
metadata,
|
||||||
secretValue
|
secretValue
|
||||||
});
|
});
|
||||||
return secret;
|
return { type: SecretProtectionType.Direct as const, secret };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
||||||
@@ -1416,7 +1420,7 @@ export const secretServiceFactory = ({
|
|||||||
const secretKeyEncrypted = encryptSymmetric128BitHexKeyUTF8(newSecretName || secretName, botKey);
|
const secretKeyEncrypted = encryptSymmetric128BitHexKeyUTF8(newSecretName || secretName, botKey);
|
||||||
|
|
||||||
if (policy) {
|
if (policy) {
|
||||||
return secretApprovalRequestService.generateSecretApprovalRequest({
|
const approval = await secretApprovalRequestService.generateSecretApprovalRequest({
|
||||||
policy,
|
policy,
|
||||||
secretPath,
|
secretPath,
|
||||||
environment,
|
environment,
|
||||||
@@ -1447,6 +1451,7 @@ export const secretServiceFactory = ({
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return { approval, type: SecretProtectionType.Approval as const };
|
||||||
}
|
}
|
||||||
|
|
||||||
const secret = await updateSecret({
|
const secret = await updateSecret({
|
||||||
@@ -1477,7 +1482,7 @@ export const secretServiceFactory = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
await snapshotService.performSnapshot(secret.folderId);
|
await snapshotService.performSnapshot(secret.folderId);
|
||||||
return decryptSecretRaw(secret, botKey);
|
return { type: SecretProtectionType.Direct as const, secret: decryptSecretRaw(secret, botKey) };
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteSecretRaw = async ({
|
const deleteSecretRaw = async ({
|
||||||
@@ -1498,7 +1503,7 @@ export const secretServiceFactory = ({
|
|||||||
: undefined;
|
: undefined;
|
||||||
if (shouldUseSecretV2Bridge) {
|
if (shouldUseSecretV2Bridge) {
|
||||||
if (policy) {
|
if (policy) {
|
||||||
return secretApprovalRequestService.generateSecretApprovalRequestV2Bridge({
|
const approval = await secretApprovalRequestService.generateSecretApprovalRequestV2Bridge({
|
||||||
policy,
|
policy,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId,
|
||||||
@@ -1515,6 +1520,7 @@ export const secretServiceFactory = ({
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return { type: SecretProtectionType.Approval as const, approval };
|
||||||
}
|
}
|
||||||
const secret = await secretV2BridgeService.deleteSecret({
|
const secret = await secretV2BridgeService.deleteSecret({
|
||||||
secretName,
|
secretName,
|
||||||
@@ -1527,11 +1533,11 @@ export const secretServiceFactory = ({
|
|||||||
environment,
|
environment,
|
||||||
secretPath
|
secretPath
|
||||||
});
|
});
|
||||||
return secret;
|
return { type: SecretProtectionType.Direct as const, secret };
|
||||||
}
|
}
|
||||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
||||||
if (policy) {
|
if (policy) {
|
||||||
return secretApprovalRequestService.generateSecretApprovalRequest({
|
const approval = await secretApprovalRequestService.generateSecretApprovalRequest({
|
||||||
policy,
|
policy,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId,
|
||||||
@@ -1548,6 +1554,7 @@ export const secretServiceFactory = ({
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return { type: SecretProtectionType.Approval as const, approval };
|
||||||
}
|
}
|
||||||
const secret = await deleteSecret({
|
const secret = await deleteSecret({
|
||||||
secretName,
|
secretName,
|
||||||
@@ -1561,7 +1568,7 @@ export const secretServiceFactory = ({
|
|||||||
actorAuthMethod
|
actorAuthMethod
|
||||||
});
|
});
|
||||||
|
|
||||||
return decryptSecretRaw(secret, botKey);
|
return { type: SecretProtectionType.Direct as const, secret: decryptSecretRaw(secret, botKey) };
|
||||||
};
|
};
|
||||||
|
|
||||||
const createManySecretsRaw = async ({
|
const createManySecretsRaw = async ({
|
||||||
@@ -1593,7 +1600,7 @@ export const secretServiceFactory = ({
|
|||||||
: undefined;
|
: undefined;
|
||||||
if (shouldUseSecretV2Bridge) {
|
if (shouldUseSecretV2Bridge) {
|
||||||
if (policy) {
|
if (policy) {
|
||||||
return secretApprovalRequestService.generateSecretApprovalRequestV2Bridge({
|
const approval = await secretApprovalRequestService.generateSecretApprovalRequestV2Bridge({
|
||||||
policy,
|
policy,
|
||||||
secretPath,
|
secretPath,
|
||||||
environment,
|
environment,
|
||||||
@@ -1613,6 +1620,7 @@ export const secretServiceFactory = ({
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return { type: SecretProtectionType.Approval as const, approval };
|
||||||
}
|
}
|
||||||
const secrets = await secretV2BridgeService.createManySecret({
|
const secrets = await secretV2BridgeService.createManySecret({
|
||||||
secretPath,
|
secretPath,
|
||||||
@@ -1624,8 +1632,9 @@ export const secretServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
secrets: inputSecrets
|
secrets: inputSecrets
|
||||||
});
|
});
|
||||||
return secrets;
|
return { secrets, type: SecretProtectionType.Direct as const };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
||||||
const sanitizedSecrets = inputSecrets.map(
|
const sanitizedSecrets = inputSecrets.map(
|
||||||
({ secretComment, secretKey, metadata, tagIds, secretValue, skipMultilineEncoding }) => {
|
({ secretComment, secretKey, metadata, tagIds, secretValue, skipMultilineEncoding }) => {
|
||||||
@@ -1651,7 +1660,7 @@ export const secretServiceFactory = ({
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
if (policy) {
|
if (policy) {
|
||||||
return secretApprovalRequestService.generateSecretApprovalRequest({
|
const approval = await secretApprovalRequestService.generateSecretApprovalRequest({
|
||||||
policy,
|
policy,
|
||||||
secretPath,
|
secretPath,
|
||||||
environment,
|
environment,
|
||||||
@@ -1664,6 +1673,7 @@ export const secretServiceFactory = ({
|
|||||||
[SecretOperations.Create]: sanitizedSecrets
|
[SecretOperations.Create]: sanitizedSecrets
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return { type: SecretProtectionType.Approval as const, approval };
|
||||||
}
|
}
|
||||||
const secrets = await createManySecret({
|
const secrets = await createManySecret({
|
||||||
projectId,
|
projectId,
|
||||||
@@ -1676,9 +1686,12 @@ export const secretServiceFactory = ({
|
|||||||
secrets: sanitizedSecrets
|
secrets: sanitizedSecrets
|
||||||
});
|
});
|
||||||
|
|
||||||
return secrets.map((secret) =>
|
return {
|
||||||
decryptSecretRaw({ ...secret, workspace: projectId, environment, secretPath }, botKey)
|
type: SecretProtectionType.Direct as const,
|
||||||
);
|
secrets: secrets.map((secret) =>
|
||||||
|
decryptSecretRaw({ ...secret, workspace: projectId, environment, secretPath }, botKey)
|
||||||
|
)
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateManySecretsRaw = async ({
|
const updateManySecretsRaw = async ({
|
||||||
@@ -1709,7 +1722,7 @@ export const secretServiceFactory = ({
|
|||||||
: undefined;
|
: undefined;
|
||||||
if (shouldUseSecretV2Bridge) {
|
if (shouldUseSecretV2Bridge) {
|
||||||
if (policy) {
|
if (policy) {
|
||||||
return secretApprovalRequestService.generateSecretApprovalRequestV2Bridge({
|
const approval = await secretApprovalRequestService.generateSecretApprovalRequestV2Bridge({
|
||||||
policy,
|
policy,
|
||||||
secretPath,
|
secretPath,
|
||||||
environment,
|
environment,
|
||||||
@@ -1728,6 +1741,7 @@ export const secretServiceFactory = ({
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return { type: SecretProtectionType.Approval as const, approval };
|
||||||
}
|
}
|
||||||
const secrets = await secretV2BridgeService.updateManySecret({
|
const secrets = await secretV2BridgeService.updateManySecret({
|
||||||
secretPath,
|
secretPath,
|
||||||
@@ -1739,7 +1753,7 @@ export const secretServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
secrets: inputSecrets
|
secrets: inputSecrets
|
||||||
});
|
});
|
||||||
return secrets;
|
return { type: SecretProtectionType.Direct as const, secrets };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
||||||
@@ -1779,7 +1793,7 @@ export const secretServiceFactory = ({
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
if (policy) {
|
if (policy) {
|
||||||
return secretApprovalRequestService.generateSecretApprovalRequest({
|
const approval = await secretApprovalRequestService.generateSecretApprovalRequest({
|
||||||
policy,
|
policy,
|
||||||
secretPath,
|
secretPath,
|
||||||
environment,
|
environment,
|
||||||
@@ -1792,6 +1806,8 @@ export const secretServiceFactory = ({
|
|||||||
[SecretOperations.Update]: sanitizedSecrets
|
[SecretOperations.Update]: sanitizedSecrets
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return { type: SecretProtectionType.Approval as const, approval };
|
||||||
}
|
}
|
||||||
const secrets = await updateManySecret({
|
const secrets = await updateManySecret({
|
||||||
projectId,
|
projectId,
|
||||||
@@ -1804,9 +1820,12 @@ export const secretServiceFactory = ({
|
|||||||
secrets: sanitizedSecrets
|
secrets: sanitizedSecrets
|
||||||
});
|
});
|
||||||
|
|
||||||
return secrets.map((secret) =>
|
return {
|
||||||
decryptSecretRaw({ ...secret, workspace: projectId, environment, secretPath }, botKey)
|
type: SecretProtectionType.Direct as const,
|
||||||
);
|
secrets: secrets.map((secret) =>
|
||||||
|
decryptSecretRaw({ ...secret, workspace: projectId, environment, secretPath }, botKey)
|
||||||
|
)
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteManySecretsRaw = async ({
|
const deleteManySecretsRaw = async ({
|
||||||
@@ -1837,7 +1856,7 @@ export const secretServiceFactory = ({
|
|||||||
: undefined;
|
: undefined;
|
||||||
if (shouldUseSecretV2Bridge) {
|
if (shouldUseSecretV2Bridge) {
|
||||||
if (policy) {
|
if (policy) {
|
||||||
return secretApprovalRequestService.generateSecretApprovalRequestV2Bridge({
|
const approval = await secretApprovalRequestService.generateSecretApprovalRequestV2Bridge({
|
||||||
policy,
|
policy,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId,
|
||||||
@@ -1850,6 +1869,7 @@ export const secretServiceFactory = ({
|
|||||||
[SecretOperations.Delete]: inputSecrets
|
[SecretOperations.Delete]: inputSecrets
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return { type: SecretProtectionType.Approval as const, approval };
|
||||||
}
|
}
|
||||||
const secrets = await secretV2BridgeService.deleteManySecret({
|
const secrets = await secretV2BridgeService.deleteManySecret({
|
||||||
secretPath,
|
secretPath,
|
||||||
@@ -1861,13 +1881,13 @@ export const secretServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
secrets: inputSecrets
|
secrets: inputSecrets
|
||||||
});
|
});
|
||||||
return secrets;
|
return { type: SecretProtectionType.Direct as const, secrets };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
||||||
|
|
||||||
if (policy) {
|
if (policy) {
|
||||||
return secretApprovalRequestService.generateSecretApprovalRequest({
|
const approval = await secretApprovalRequestService.generateSecretApprovalRequest({
|
||||||
policy,
|
policy,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId,
|
||||||
@@ -1880,6 +1900,7 @@ export const secretServiceFactory = ({
|
|||||||
[SecretOperations.Delete]: inputSecrets.map((el) => ({ secretName: el.secretKey }))
|
[SecretOperations.Delete]: inputSecrets.map((el) => ({ secretName: el.secretKey }))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return { type: SecretProtectionType.Approval as const, approval };
|
||||||
}
|
}
|
||||||
const secrets = await deleteManySecret({
|
const secrets = await deleteManySecret({
|
||||||
projectId,
|
projectId,
|
||||||
@@ -1892,9 +1913,12 @@ export const secretServiceFactory = ({
|
|||||||
secrets: inputSecrets.map(({ secretKey, type = SecretType.Shared }) => ({ secretName: secretKey, type }))
|
secrets: inputSecrets.map(({ secretKey, type = SecretType.Shared }) => ({ secretName: secretKey, type }))
|
||||||
});
|
});
|
||||||
|
|
||||||
return secrets.map((secret) =>
|
return {
|
||||||
decryptSecretRaw({ ...secret, workspace: projectId, environment, secretPath }, botKey)
|
type: SecretProtectionType.Direct as const,
|
||||||
);
|
secrets: secrets.map((secret) =>
|
||||||
|
decryptSecretRaw({ ...secret, workspace: projectId, environment, secretPath }, botKey)
|
||||||
|
)
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const getSecretVersions = async ({
|
const getSecretVersions = async ({
|
||||||
@@ -1906,12 +1930,25 @@ export const secretServiceFactory = ({
|
|||||||
offset = 0,
|
offset = 0,
|
||||||
secretId
|
secretId
|
||||||
}: TGetSecretVersionsDTO) => {
|
}: TGetSecretVersionsDTO) => {
|
||||||
|
const secretVersionV2 = await secretV2BridgeService.getSecretVersions({
|
||||||
|
actorId,
|
||||||
|
actor,
|
||||||
|
actorOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
secretId
|
||||||
|
});
|
||||||
|
if (secretVersionV2) return secretVersionV2;
|
||||||
|
|
||||||
const secret = await secretDAL.findById(secretId);
|
const secret = await secretDAL.findById(secretId);
|
||||||
if (!secret) throw new BadRequestError({ message: "Failed to find secret" });
|
if (!secret) throw new BadRequestError({ message: "Failed to find secret" });
|
||||||
|
|
||||||
const folder = await folderDAL.findById(secret.folderId);
|
const folder = await folderDAL.findById(secret.folderId);
|
||||||
if (!folder) throw new BadRequestError({ message: "Failed to find secret" });
|
if (!folder) throw new BadRequestError({ message: "Failed to find secret" });
|
||||||
|
|
||||||
|
const { botKey } = await projectBotService.getBotKey(folder.projectId);
|
||||||
|
if (!botKey) throw new BadRequestError({ message: "bot not found" });
|
||||||
|
|
||||||
const { permission } = await permissionService.getProjectPermission(
|
const { permission } = await permissionService.getProjectPermission(
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
@@ -1920,9 +1957,18 @@ export const secretServiceFactory = ({
|
|||||||
actorOrgId
|
actorOrgId
|
||||||
);
|
);
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
|
||||||
|
|
||||||
const secretVersions = await secretVersionDAL.find({ secretId }, { offset, limit, sort: [["createdAt", "desc"]] });
|
const secretVersions = await secretVersionDAL.find({ secretId }, { offset, limit, sort: [["createdAt", "desc"]] });
|
||||||
return secretVersions;
|
return secretVersions.map((el) =>
|
||||||
|
decryptSecretRaw(
|
||||||
|
{
|
||||||
|
...el,
|
||||||
|
workspace: folder.projectId,
|
||||||
|
environment: folder.environment.envSlug,
|
||||||
|
secretPath: "/"
|
||||||
|
},
|
||||||
|
botKey
|
||||||
|
)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const attachTags = async ({
|
const attachTags = async ({
|
||||||
|
|||||||
@@ -444,3 +444,8 @@ export type TMoveSecretsDTO = {
|
|||||||
secretIds: string[];
|
secretIds: string[];
|
||||||
shouldOverwrite: boolean;
|
shouldOverwrite: boolean;
|
||||||
} & Omit<TProjectPermission, "projectId">;
|
} & Omit<TProjectPermission, "projectId">;
|
||||||
|
|
||||||
|
export enum SecretProtectionType {
|
||||||
|
Approval = "approval",
|
||||||
|
Direct = "direct"
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user