mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-15 18:15:53 +00:00
Merge remote-tracking branch 'origin/main' into misc/privilege-management-v2-transition
This commit is contained in:
@@ -159,7 +159,8 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
||||
id: z.string()
|
||||
}),
|
||||
body: z.object({
|
||||
status: z.enum([ApprovalStatus.APPROVED, ApprovalStatus.REJECTED])
|
||||
status: z.enum([ApprovalStatus.APPROVED, ApprovalStatus.REJECTED]),
|
||||
comment: z.string().optional()
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
@@ -175,8 +176,25 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorOrgId: req.permission.orgId,
|
||||
approvalId: req.params.id,
|
||||
status: req.body.status
|
||||
status: req.body.status,
|
||||
comment: req.body.comment
|
||||
});
|
||||
|
||||
await server.services.auditLog.createAuditLog({
|
||||
...req.auditLogInfo,
|
||||
orgId: req.permission.orgId,
|
||||
projectId: review.projectId,
|
||||
event: {
|
||||
type: EventType.SECRET_APPROVAL_REQUEST_REVIEW,
|
||||
metadata: {
|
||||
secretApprovalRequestId: review.requestId,
|
||||
reviewedBy: review.reviewerUserId,
|
||||
status: review.status as ApprovalStatus,
|
||||
comment: review.comment || ""
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return { review };
|
||||
}
|
||||
});
|
||||
@@ -267,7 +285,7 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
||||
environment: z.string(),
|
||||
statusChangedByUser: approvalRequestUser.optional(),
|
||||
committerUser: approvalRequestUser,
|
||||
reviewers: approvalRequestUser.extend({ status: z.string() }).array(),
|
||||
reviewers: approvalRequestUser.extend({ status: z.string(), comment: z.string().optional() }).array(),
|
||||
secretPath: z.string(),
|
||||
commits: secretRawSchema
|
||||
.omit({ _id: true, environment: true, workspace: true, type: true, version: true })
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
} from "@app/services/secret-sync/secret-sync-types";
|
||||
|
||||
import { KmipPermission } from "../kmip/kmip-enum";
|
||||
import { ApprovalStatus } from "../secret-approval-request/secret-approval-request-types";
|
||||
|
||||
export type TListProjectAuditLogDTO = {
|
||||
filter: {
|
||||
@@ -165,6 +166,7 @@ export enum EventType {
|
||||
SECRET_APPROVAL_REQUEST = "secret-approval-request",
|
||||
SECRET_APPROVAL_CLOSED = "secret-approval-closed",
|
||||
SECRET_APPROVAL_REOPENED = "secret-approval-reopened",
|
||||
SECRET_APPROVAL_REQUEST_REVIEW = "secret-approval-request-review",
|
||||
SIGN_SSH_KEY = "sign-ssh-key",
|
||||
ISSUE_SSH_CREDS = "issue-ssh-creds",
|
||||
CREATE_SSH_CA = "create-ssh-certificate-authority",
|
||||
@@ -1314,6 +1316,16 @@ interface SecretApprovalRequest {
|
||||
};
|
||||
}
|
||||
|
||||
interface SecretApprovalRequestReview {
|
||||
type: EventType.SECRET_APPROVAL_REQUEST_REVIEW;
|
||||
metadata: {
|
||||
secretApprovalRequestId: string;
|
||||
reviewedBy: string;
|
||||
status: ApprovalStatus;
|
||||
comment: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface SignSshKey {
|
||||
type: EventType.SIGN_SSH_KEY;
|
||||
metadata: {
|
||||
@@ -2482,4 +2494,5 @@ export type Event =
|
||||
| KmipOperationRevokeEvent
|
||||
| KmipOperationLocateEvent
|
||||
| KmipOperationRegisterEvent
|
||||
| CreateSecretRequestEvent;
|
||||
| CreateSecretRequestEvent
|
||||
| SecretApprovalRequestReview;
|
||||
|
||||
@@ -100,6 +100,7 @@ export const secretApprovalRequestDALFactory = (db: TDbClient) => {
|
||||
tx.ref("lastName").withSchema("committerUser").as("committerUserLastName"),
|
||||
tx.ref("reviewerUserId").withSchema(TableName.SecretApprovalRequestReviewer),
|
||||
tx.ref("status").withSchema(TableName.SecretApprovalRequestReviewer).as("reviewerStatus"),
|
||||
tx.ref("comment").withSchema(TableName.SecretApprovalRequestReviewer).as("reviewerComment"),
|
||||
tx.ref("email").withSchema("secretApprovalReviewerUser").as("reviewerEmail"),
|
||||
tx.ref("username").withSchema("secretApprovalReviewerUser").as("reviewerUsername"),
|
||||
tx.ref("firstName").withSchema("secretApprovalReviewerUser").as("reviewerFirstName"),
|
||||
@@ -162,8 +163,10 @@ export const secretApprovalRequestDALFactory = (db: TDbClient) => {
|
||||
reviewerEmail: email,
|
||||
reviewerLastName: lastName,
|
||||
reviewerUsername: username,
|
||||
reviewerFirstName: firstName
|
||||
}) => (userId ? { userId, status, email, firstName, lastName, username } : undefined)
|
||||
reviewerFirstName: firstName,
|
||||
reviewerComment: comment
|
||||
}) =>
|
||||
userId ? { userId, status, email, firstName, lastName, username, comment: comment ?? "" } : undefined
|
||||
},
|
||||
{
|
||||
key: "approverUserId",
|
||||
|
||||
@@ -320,6 +320,7 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
approvalId,
|
||||
actor,
|
||||
status,
|
||||
comment,
|
||||
actorId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
@@ -372,15 +373,18 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
return secretApprovalRequestReviewerDAL.create(
|
||||
{
|
||||
status,
|
||||
comment,
|
||||
requestId: secretApprovalRequest.id,
|
||||
reviewerUserId: actorId
|
||||
},
|
||||
tx
|
||||
);
|
||||
}
|
||||
return secretApprovalRequestReviewerDAL.updateById(review.id, { status }, tx);
|
||||
|
||||
return secretApprovalRequestReviewerDAL.updateById(review.id, { status, comment }, tx);
|
||||
});
|
||||
return reviewStatus;
|
||||
|
||||
return { ...reviewStatus, projectId: secretApprovalRequest.projectId };
|
||||
};
|
||||
|
||||
const updateApprovalStatus = async ({
|
||||
@@ -499,7 +503,7 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
if (!hasMinApproval && !isSoftEnforcement)
|
||||
throw new BadRequestError({ message: "Doesn't have minimum approvals needed" });
|
||||
|
||||
const { botKey, shouldUseSecretV2Bridge } = await projectBotService.getBotKey(projectId);
|
||||
const { botKey, shouldUseSecretV2Bridge, project } = await projectBotService.getBotKey(projectId);
|
||||
let mergeStatus;
|
||||
if (shouldUseSecretV2Bridge) {
|
||||
// this cycle if for bridged secrets
|
||||
@@ -857,7 +861,6 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
|
||||
if (isSoftEnforcement) {
|
||||
const cfg = getConfig();
|
||||
const project = await projectDAL.findProjectById(projectId);
|
||||
const env = await projectEnvDAL.findOne({ id: policy.envId });
|
||||
const requestedByUser = await userDAL.findOne({ id: actorId });
|
||||
const approverUsers = await userDAL.find({
|
||||
@@ -1152,7 +1155,8 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
environment: env.name,
|
||||
secretPath,
|
||||
projectId,
|
||||
requestId: secretApprovalRequest.id
|
||||
requestId: secretApprovalRequest.id,
|
||||
secretKeys: [...new Set(Object.values(data).flatMap((arr) => arr?.map((item) => item.secretName) ?? []))]
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1452,7 +1456,8 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
environment: env.name,
|
||||
secretPath,
|
||||
projectId,
|
||||
requestId: secretApprovalRequest.id
|
||||
requestId: secretApprovalRequest.id,
|
||||
secretKeys: [...new Set(Object.values(data).flatMap((arr) => arr?.map((item) => item.secretKey) ?? []))]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -80,6 +80,7 @@ export type TStatusChangeDTO = {
|
||||
export type TReviewRequestDTO = {
|
||||
approvalId: string;
|
||||
status: ApprovalStatus;
|
||||
comment?: string;
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
||||
export type TApprovalRequestCountDTO = TProjectPermission;
|
||||
|
||||
@@ -13,6 +13,7 @@ import { NotFoundError } from "@app/lib/errors";
|
||||
import { logger } from "@app/lib/logger";
|
||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||
import { QueueJobs, QueueName, TQueueServiceFactory } from "@app/queue";
|
||||
import { ActorType } from "@app/services/auth/auth-type";
|
||||
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";
|
||||
@@ -332,6 +333,7 @@ export const secretRotationQueueFactory = ({
|
||||
await secretVersionV2BridgeDAL.insertMany(
|
||||
updatedSecrets.map(({ id, updatedAt, createdAt, ...el }) => ({
|
||||
...el,
|
||||
actorType: ActorType.PLATFORM,
|
||||
secretId: id
|
||||
})),
|
||||
tx
|
||||
|
||||
@@ -7,6 +7,7 @@ import { decryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto";
|
||||
import { InternalServerError, NotFoundError } from "@app/lib/errors";
|
||||
import { groupBy } from "@app/lib/fn";
|
||||
import { logger } from "@app/lib/logger";
|
||||
import { ActorType } from "@app/services/auth/auth-type";
|
||||
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";
|
||||
@@ -370,7 +371,21 @@ export const secretSnapshotServiceFactory = ({
|
||||
const secrets = await secretV2BridgeDAL.insertMany(
|
||||
rollbackSnaps.flatMap(({ secretVersions, folderId }) =>
|
||||
secretVersions.map(
|
||||
({ latestSecretVersion, version, updatedAt, createdAt, secretId, envId, id, tags, ...el }) => ({
|
||||
({
|
||||
latestSecretVersion,
|
||||
version,
|
||||
updatedAt,
|
||||
createdAt,
|
||||
secretId,
|
||||
envId,
|
||||
id,
|
||||
tags,
|
||||
// exclude the bottom fields from the secret - they are for versioning only.
|
||||
userActorId,
|
||||
identityActorId,
|
||||
actorType,
|
||||
...el
|
||||
}) => ({
|
||||
...el,
|
||||
id: secretId,
|
||||
version: deletedTopLevelSecsGroupById[secretId] ? latestSecretVersion + 1 : latestSecretVersion,
|
||||
@@ -401,8 +416,18 @@ export const secretSnapshotServiceFactory = ({
|
||||
})),
|
||||
tx
|
||||
);
|
||||
const userActorId = actor === ActorType.USER ? actorId : undefined;
|
||||
const identityActorId = actor !== ActorType.USER ? actorId : undefined;
|
||||
const actorType = actor || ActorType.PLATFORM;
|
||||
|
||||
const secretVersions = await secretVersionV2BridgeDAL.insertMany(
|
||||
secrets.map(({ id, updatedAt, createdAt, ...el }) => ({ ...el, secretId: id })),
|
||||
secrets.map(({ id, updatedAt, createdAt, ...el }) => ({
|
||||
...el,
|
||||
secretId: id,
|
||||
userActorId,
|
||||
identityActorId,
|
||||
actorType
|
||||
})),
|
||||
tx
|
||||
);
|
||||
await secretVersionV2TagBridgeDAL.insertMany(
|
||||
|
||||
Reference in New Issue
Block a user