mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-18 02:56:57 +00:00
feat(secrets-ui): Improve SecretDashboard table to support multiple changes on a single commit
This commit is contained in:
@@ -67,6 +67,7 @@ export const getAllSecretReferences = (maybeSecretReference: string) => {
|
||||
export const fnSecretBulkInsert = async ({
|
||||
// TODO: Pick types here
|
||||
folderId,
|
||||
commitChanges,
|
||||
orgId,
|
||||
inputSecrets,
|
||||
secretDAL,
|
||||
@@ -134,28 +135,32 @@ export const fnSecretBulkInsert = async ({
|
||||
tx
|
||||
);
|
||||
|
||||
const commitChanges = secretVersions
|
||||
const changes = secretVersions
|
||||
.filter(({ type }) => type === SecretType.Shared)
|
||||
.map((sv) => ({
|
||||
type: CommitType.ADD,
|
||||
secretVersionId: sv.id
|
||||
}));
|
||||
|
||||
if (commitChanges.length > 0) {
|
||||
await folderCommitService.createCommit(
|
||||
{
|
||||
actor: {
|
||||
type: actorType || ActorType.PLATFORM,
|
||||
metadata: {
|
||||
id: actor?.actorId
|
||||
}
|
||||
if (changes.length > 0) {
|
||||
if (commitChanges) {
|
||||
commitChanges.push(...changes);
|
||||
} else {
|
||||
await folderCommitService.createCommit(
|
||||
{
|
||||
actor: {
|
||||
type: actorType || ActorType.PLATFORM,
|
||||
metadata: {
|
||||
id: actor?.actorId
|
||||
}
|
||||
},
|
||||
message: "Secret Created",
|
||||
folderId,
|
||||
changes
|
||||
},
|
||||
message: "Secret Created",
|
||||
folderId,
|
||||
changes: commitChanges
|
||||
},
|
||||
tx
|
||||
);
|
||||
tx
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
await secretDAL.upsertSecretReferences(
|
||||
@@ -209,6 +214,7 @@ export const fnSecretBulkUpdate = async ({
|
||||
tx,
|
||||
inputSecrets,
|
||||
folderId,
|
||||
commitChanges,
|
||||
orgId,
|
||||
secretDAL,
|
||||
secretVersionDAL,
|
||||
@@ -359,28 +365,32 @@ export const fnSecretBulkUpdate = async ({
|
||||
{ tx }
|
||||
);
|
||||
|
||||
const commitChanges = secretVersions
|
||||
const changes = secretVersions
|
||||
.filter(({ type }) => type === SecretType.Shared)
|
||||
.map((sv) => ({
|
||||
type: CommitType.ADD,
|
||||
isUpdate: true,
|
||||
secretVersionId: sv.id
|
||||
}));
|
||||
if (commitChanges.length > 0) {
|
||||
await folderCommitService.createCommit(
|
||||
{
|
||||
actor: {
|
||||
type: actorType || ActorType.PLATFORM,
|
||||
metadata: {
|
||||
id: actor?.actorId
|
||||
}
|
||||
if (changes.length > 0) {
|
||||
if (commitChanges) {
|
||||
commitChanges.push(...changes);
|
||||
} else {
|
||||
await folderCommitService.createCommit(
|
||||
{
|
||||
actor: {
|
||||
type: actorType || ActorType.PLATFORM,
|
||||
metadata: {
|
||||
id: actor?.actorId
|
||||
}
|
||||
},
|
||||
message: "Secret Updated",
|
||||
folderId,
|
||||
changes
|
||||
},
|
||||
message: "Secret Updated",
|
||||
folderId,
|
||||
changes: commitChanges
|
||||
},
|
||||
tx
|
||||
);
|
||||
tx
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return secretsWithTags.map((secret) => ({ ...secret, _id: secret.id }));
|
||||
@@ -395,7 +405,8 @@ export const fnSecretBulkDelete = async ({
|
||||
secretDAL,
|
||||
secretQueueService,
|
||||
folderCommitService,
|
||||
secretVersionDAL
|
||||
secretVersionDAL,
|
||||
commitChanges
|
||||
}: TFnSecretBulkDelete) => {
|
||||
const deletedSecrets = await secretDAL.deleteMany(
|
||||
inputSecrets.map(({ type, secretKey }) => ({
|
||||
@@ -421,27 +432,31 @@ export const fnSecretBulkDelete = async ({
|
||||
tx
|
||||
);
|
||||
|
||||
const commitChanges = deletedSecrets
|
||||
const changes = deletedSecrets
|
||||
.filter(({ type }) => type === SecretType.Shared)
|
||||
.map(({ id }) => ({
|
||||
type: CommitType.DELETE,
|
||||
secretVersionId: secretVersions[id].id
|
||||
}));
|
||||
if (commitChanges.length > 0) {
|
||||
await folderCommitService.createCommit(
|
||||
{
|
||||
actor: {
|
||||
type: actorType || ActorType.PLATFORM,
|
||||
metadata: {
|
||||
id: actorId
|
||||
}
|
||||
if (changes.length > 0) {
|
||||
if (commitChanges) {
|
||||
commitChanges.push(...changes);
|
||||
} else {
|
||||
await folderCommitService.createCommit(
|
||||
{
|
||||
actor: {
|
||||
type: actorType || ActorType.PLATFORM,
|
||||
metadata: {
|
||||
id: actorId
|
||||
}
|
||||
},
|
||||
message: "Secret Deleted",
|
||||
folderId,
|
||||
changes
|
||||
},
|
||||
message: "Secret Deleted",
|
||||
folderId,
|
||||
changes: commitChanges
|
||||
},
|
||||
tx
|
||||
);
|
||||
tx
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return deletedSecrets;
|
||||
|
||||
@@ -28,7 +28,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 { TCreateCommitChangeDTO, 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";
|
||||
@@ -1474,8 +1474,10 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actorOrgId,
|
||||
environment,
|
||||
projectId,
|
||||
secrets: inputSecrets
|
||||
}: TCreateManySecretDTO) => {
|
||||
secrets: inputSecrets,
|
||||
tx: providedTx,
|
||||
commitChanges
|
||||
}: TCreateManySecretDTO & { tx?: Knex; commitChanges?: TCreateCommitChangeDTO[] }) => {
|
||||
const { permission } = await permissionService.getProjectPermission({
|
||||
actor,
|
||||
actorId,
|
||||
@@ -1558,8 +1560,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;
|
||||
|
||||
@@ -1581,6 +1583,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
};
|
||||
}),
|
||||
folderId,
|
||||
commitChanges,
|
||||
orgId: actorOrgId,
|
||||
secretDAL,
|
||||
resourceMetadataDAL,
|
||||
@@ -1593,8 +1596,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({
|
||||
@@ -1641,8 +1649,10 @@ export const secretV2BridgeServiceFactory = ({
|
||||
projectId,
|
||||
secretPath: defaultSecretPath = "/",
|
||||
secrets: inputSecrets,
|
||||
mode: updateMode
|
||||
}: TUpdateManySecretDTO) => {
|
||||
mode: updateMode,
|
||||
tx: providedTx,
|
||||
commitChanges
|
||||
}: TUpdateManySecretDTO & { tx?: Knex; commitChanges?: TCreateCommitChangeDTO[] }) => {
|
||||
const { permission } = await permissionService.getProjectPermission({
|
||||
actor,
|
||||
actorId,
|
||||
@@ -1671,18 +1681,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" });
|
||||
|
||||
@@ -1801,7 +1813,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
{
|
||||
operator: "eq",
|
||||
field: `${TableName.SecretV2}.key` as "key",
|
||||
value: el.secretKey
|
||||
value: el.newSecretName as string
|
||||
},
|
||||
{
|
||||
operator: "eq",
|
||||
@@ -1855,6 +1867,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
orgId: actorOrgId,
|
||||
folderCommitService,
|
||||
tx,
|
||||
commitChanges,
|
||||
inputSecrets: secretsToUpdate.map((el) => {
|
||||
const originalSecret = secretsToUpdateInDBGroupedByKey[el.secretKey][0];
|
||||
const encryptedValue =
|
||||
@@ -1934,7 +1947,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)));
|
||||
@@ -1991,8 +2010,10 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actor,
|
||||
actorId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
}: TDeleteManySecretDTO) => {
|
||||
actorOrgId,
|
||||
tx: providedTx,
|
||||
commitChanges
|
||||
}: TDeleteManySecretDTO & { tx?: Knex; commitChanges?: TCreateCommitChangeDTO[] }) => {
|
||||
const { permission } = await permissionService.getProjectPermission({
|
||||
actor,
|
||||
actorId,
|
||||
@@ -2051,24 +2072,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);
|
||||
|
||||
@@ -8,7 +8,7 @@ import { SecretsOrderBy } from "@app/services/secret/secret-types";
|
||||
import { TSecretFolderDALFactory } from "@app/services/secret-folder/secret-folder-dal";
|
||||
import { TSecretTagDALFactory } from "@app/services/secret-tag/secret-tag-dal";
|
||||
|
||||
import { TFolderCommitServiceFactory } from "../folder-commit/folder-commit-service";
|
||||
import { TCreateCommitChangeDTO, TFolderCommitServiceFactory } from "../folder-commit/folder-commit-service";
|
||||
import { TResourceMetadataDALFactory } from "../resource-metadata/resource-metadata-dal";
|
||||
import { ResourceMetadataDTO } from "../resource-metadata/resource-metadata-schema";
|
||||
import { TSecretV2BridgeDALFactory } from "./secret-v2-bridge-dal";
|
||||
@@ -167,6 +167,7 @@ export type TFnSecretBulkInsert = {
|
||||
folderId: string;
|
||||
orgId: string;
|
||||
tx?: Knex;
|
||||
commitChanges?: TCreateCommitChangeDTO[];
|
||||
inputSecrets: Array<
|
||||
Omit<TSecretsV2Insert, "folderId"> & {
|
||||
tagIds?: string[];
|
||||
@@ -214,6 +215,7 @@ export type TFnSecretBulkUpdate = {
|
||||
actorId?: string;
|
||||
};
|
||||
tx?: Knex;
|
||||
commitChanges?: TCreateCommitChangeDTO[];
|
||||
};
|
||||
|
||||
export type TFnSecretBulkDelete = {
|
||||
@@ -223,6 +225,7 @@ export type TFnSecretBulkDelete = {
|
||||
actorId: string;
|
||||
actorType?: string;
|
||||
tx?: Knex;
|
||||
commitChanges?: TCreateCommitChangeDTO[];
|
||||
secretDAL: Pick<TSecretV2BridgeDALFactory, "deleteMany">;
|
||||
secretQueueService: {
|
||||
removeSecretReminder: (data: TRemoveSecretReminderDTO, tx?: Knex) => Promise<void>;
|
||||
|
||||
Reference in New Issue
Block a user