mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-16 19:28:35 +00:00
Merge branch 'main' into feat/remindersImprovement
This commit is contained in:
@@ -2,7 +2,14 @@ import { ForbiddenError, MongoAbility, subject } from "@casl/ability";
|
||||
import { Knex } from "knex";
|
||||
import { z } from "zod";
|
||||
|
||||
import { ProjectMembershipRole, SecretsV2Schema, SecretType, TableName, TSecretsV2 } from "@app/db/schemas";
|
||||
import {
|
||||
ActionProjectType,
|
||||
ProjectMembershipRole,
|
||||
SecretsV2Schema,
|
||||
SecretType,
|
||||
TableName,
|
||||
TSecretsV2
|
||||
} from "@app/db/schemas";
|
||||
import {
|
||||
hasSecretReadValueOrDescribePermission,
|
||||
throwIfMissingSecretReadValueOrDescribePermission
|
||||
@@ -28,7 +35,7 @@ import { logger } from "@app/lib/logger";
|
||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||
|
||||
import { ActorType } from "../auth/auth-type";
|
||||
import { TFolderCommitServiceFactory } from "../folder-commit/folder-commit-service";
|
||||
import { TCommitResourceChangeDTO, TFolderCommitServiceFactory } from "../folder-commit/folder-commit-service";
|
||||
import { TKmsServiceFactory } from "../kms/kms-service";
|
||||
import { KmsDataKey } from "../kms/kms-types";
|
||||
import { TProjectEnvDALFactory } from "../project-env/project-env-dal";
|
||||
@@ -239,7 +246,8 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actorId,
|
||||
projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
|
||||
const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
|
||||
@@ -394,7 +402,8 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actorId,
|
||||
projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
|
||||
if (inputSecret.newSecretName === "") {
|
||||
@@ -620,7 +629,8 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actorId,
|
||||
projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
|
||||
const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
|
||||
@@ -756,7 +766,8 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actorId,
|
||||
projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret);
|
||||
}
|
||||
@@ -801,7 +812,8 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actorId,
|
||||
projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret);
|
||||
|
||||
@@ -900,7 +912,8 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actorId,
|
||||
projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
if (!isInternal) {
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret);
|
||||
@@ -953,7 +966,8 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actorId,
|
||||
projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret);
|
||||
|
||||
@@ -1251,7 +1265,8 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actorId,
|
||||
projectId: secret.projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
@@ -1314,7 +1329,8 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actorId,
|
||||
projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
|
||||
const folder = await folderDAL.findBySecretPath(projectId, environment, path);
|
||||
@@ -1519,14 +1535,17 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actorOrgId,
|
||||
environment,
|
||||
projectId,
|
||||
secrets: inputSecrets
|
||||
}: TCreateManySecretDTO) => {
|
||||
secrets: inputSecrets,
|
||||
tx: providedTx,
|
||||
commitChanges
|
||||
}: TCreateManySecretDTO & { tx?: Knex; commitChanges?: TCommitResourceChangeDTO[] }) => {
|
||||
const { permission } = await permissionService.getProjectPermission({
|
||||
actor,
|
||||
actorId,
|
||||
projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
|
||||
const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
|
||||
@@ -1603,8 +1622,8 @@ export const secretV2BridgeServiceFactory = ({
|
||||
const { encryptor: secretManagerEncryptor, decryptor: secretManagerDecryptor } =
|
||||
await kmsService.createCipherPairWithDataKey({ type: KmsDataKey.SecretManager, projectId });
|
||||
|
||||
const newSecrets = await secretDAL.transaction(async (tx) =>
|
||||
fnSecretBulkInsert({
|
||||
const executeBulkInsert = async (tx: Knex) => {
|
||||
return fnSecretBulkInsert({
|
||||
inputSecrets: inputSecrets.map((el) => {
|
||||
const references = secretReferencesGroupByInputSecretKey[el.secretKey]?.nestedReferences;
|
||||
|
||||
@@ -1626,6 +1645,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
};
|
||||
}),
|
||||
folderId,
|
||||
commitChanges,
|
||||
orgId: actorOrgId,
|
||||
secretDAL,
|
||||
resourceMetadataDAL,
|
||||
@@ -1638,8 +1658,13 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actorId
|
||||
},
|
||||
tx
|
||||
})
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
const newSecrets = providedTx
|
||||
? await executeBulkInsert(providedTx)
|
||||
: await secretDAL.transaction(executeBulkInsert);
|
||||
|
||||
await secretDAL.invalidateSecretCacheByProjectId(projectId);
|
||||
await snapshotService.performSnapshot(folderId);
|
||||
await secretQueueService.syncSecrets({
|
||||
@@ -1686,14 +1711,17 @@ export const secretV2BridgeServiceFactory = ({
|
||||
projectId,
|
||||
secretPath: defaultSecretPath = "/",
|
||||
secrets: inputSecrets,
|
||||
mode: updateMode
|
||||
}: TUpdateManySecretDTO) => {
|
||||
mode: updateMode,
|
||||
tx: providedTx,
|
||||
commitChanges
|
||||
}: TUpdateManySecretDTO & { tx?: Knex; commitChanges?: TCommitResourceChangeDTO[] }) => {
|
||||
const { permission } = await permissionService.getProjectPermission({
|
||||
actor,
|
||||
actorId,
|
||||
projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
|
||||
const secretsToUpdateGroupByPath = groupBy(inputSecrets, (el) => el.secretPath || defaultSecretPath);
|
||||
@@ -1716,18 +1744,20 @@ export const secretV2BridgeServiceFactory = ({
|
||||
const { encryptor: secretManagerEncryptor, decryptor: secretManagerDecryptor } =
|
||||
await kmsService.createCipherPairWithDataKey({ type: KmsDataKey.SecretManager, projectId });
|
||||
|
||||
const updatedSecrets: Array<
|
||||
TSecretsV2 & {
|
||||
secretPath: string;
|
||||
tags: {
|
||||
id: string;
|
||||
slug: string;
|
||||
color?: string | null;
|
||||
name: string;
|
||||
}[];
|
||||
}
|
||||
> = [];
|
||||
await secretDAL.transaction(async (tx) => {
|
||||
// Function to execute the bulk update operation
|
||||
const executeBulkUpdate = async (tx: Knex) => {
|
||||
const updatedSecrets: Array<
|
||||
TSecretsV2 & {
|
||||
secretPath: string;
|
||||
tags: {
|
||||
id: string;
|
||||
slug: string;
|
||||
color?: string | null;
|
||||
name: string;
|
||||
}[];
|
||||
}
|
||||
> = [];
|
||||
|
||||
for await (const folder of folders) {
|
||||
if (!folder) throw new NotFoundError({ message: "Folder not found" });
|
||||
|
||||
@@ -1846,7 +1876,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
{
|
||||
operator: "eq",
|
||||
field: `${TableName.SecretV2}.key` as "key",
|
||||
value: el.secretKey
|
||||
value: el.newSecretName as string
|
||||
},
|
||||
{
|
||||
operator: "eq",
|
||||
@@ -1900,6 +1930,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
orgId: actorOrgId,
|
||||
folderCommitService,
|
||||
tx,
|
||||
commitChanges,
|
||||
inputSecrets: secretsToUpdate.map((el) => {
|
||||
const originalSecret = secretsToUpdateInDBGroupedByKey[el.secretKey][0];
|
||||
const encryptedValue =
|
||||
@@ -1977,7 +2008,13 @@ export const secretV2BridgeServiceFactory = ({
|
||||
updatedSecrets.push(...bulkInsertedSecrets.map((el) => ({ ...el, secretPath: folder.path })));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return updatedSecrets;
|
||||
};
|
||||
|
||||
const updatedSecrets = providedTx
|
||||
? await executeBulkUpdate(providedTx)
|
||||
: await secretDAL.transaction(executeBulkUpdate);
|
||||
|
||||
await secretDAL.invalidateSecretCacheByProjectId(projectId);
|
||||
await Promise.allSettled(folders.map((el) => (el?.id ? snapshotService.performSnapshot(el.id) : undefined)));
|
||||
@@ -2034,14 +2071,17 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actor,
|
||||
actorId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
}: TDeleteManySecretDTO) => {
|
||||
actorOrgId,
|
||||
tx: providedTx,
|
||||
commitChanges
|
||||
}: TDeleteManySecretDTO & { tx?: Knex; commitChanges?: TCommitResourceChangeDTO[] }) => {
|
||||
const { permission } = await permissionService.getProjectPermission({
|
||||
actor,
|
||||
actorId,
|
||||
projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
|
||||
const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
|
||||
@@ -2094,24 +2134,29 @@ export const secretV2BridgeServiceFactory = ({
|
||||
);
|
||||
});
|
||||
|
||||
const executeBulkDelete = async (tx: Knex) => {
|
||||
return fnSecretBulkDelete({
|
||||
secretDAL,
|
||||
secretQueueService,
|
||||
folderCommitService,
|
||||
secretVersionDAL,
|
||||
inputSecrets: inputSecrets.map(({ type, secretKey }) => ({
|
||||
secretKey,
|
||||
type: type || SecretType.Shared
|
||||
})),
|
||||
projectId,
|
||||
folderId,
|
||||
actorId,
|
||||
actorType: actor,
|
||||
commitChanges,
|
||||
tx
|
||||
});
|
||||
};
|
||||
|
||||
try {
|
||||
const secretsDeleted = await secretDAL.transaction(async (tx) =>
|
||||
fnSecretBulkDelete({
|
||||
secretDAL,
|
||||
secretQueueService,
|
||||
folderCommitService,
|
||||
secretVersionDAL,
|
||||
inputSecrets: inputSecrets.map(({ type, secretKey }) => ({
|
||||
secretKey,
|
||||
type: type || SecretType.Shared
|
||||
})),
|
||||
projectId,
|
||||
folderId,
|
||||
actorId,
|
||||
actorType: actor,
|
||||
tx
|
||||
})
|
||||
);
|
||||
const secretsDeleted = providedTx
|
||||
? await executeBulkDelete(providedTx)
|
||||
: await secretDAL.transaction(executeBulkDelete);
|
||||
|
||||
await secretDAL.invalidateSecretCacheByProjectId(projectId);
|
||||
await snapshotService.performSnapshot(folderId);
|
||||
@@ -2197,7 +2242,8 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actorId,
|
||||
projectId: folder.projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
|
||||
const canRead =
|
||||
@@ -2262,7 +2308,8 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actorId,
|
||||
projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
|
||||
if (!hasRole(ProjectMembershipRole.Admin))
|
||||
@@ -2309,7 +2356,8 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actorId,
|
||||
projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
|
||||
const sourceFolder = await folderDAL.findBySecretPath(projectId, sourceEnvironment, sourceSecretPath);
|
||||
@@ -2693,7 +2741,8 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actorId,
|
||||
projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
@@ -2786,7 +2835,8 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actorId,
|
||||
projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
environment,
|
||||
@@ -2910,7 +2960,8 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actorId,
|
||||
projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
|
||||
const canRead =
|
||||
|
||||
Reference in New Issue
Block a user