mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-06 01:26:43 +00:00
Addressed PR suggestions
This commit is contained in:
@@ -432,11 +432,17 @@ export const registerPITRouter = async (server: FastifyZodProvider) => {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
body: z.object({
|
body: z.object({
|
||||||
projectSlug: z.string().trim().optional(),
|
projectId: z.string().trim(),
|
||||||
workspaceId: z.string().trim().optional(),
|
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
|
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
message: z.string().trim(),
|
message: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.min(1)
|
||||||
|
.max(255)
|
||||||
|
.refine((message) => message.trim() !== "", {
|
||||||
|
message: "Commit message cannot be empty"
|
||||||
|
}),
|
||||||
changes: z.object({
|
changes: z.object({
|
||||||
secrets: z.object({
|
secrets: z.object({
|
||||||
create: z
|
create: z
|
||||||
@@ -500,7 +506,7 @@ export const registerPITRouter = async (server: FastifyZodProvider) => {
|
|||||||
.refine((name) => isValidFolderName(name), {
|
.refine((name) => isValidFolderName(name), {
|
||||||
message: "Invalid folder name. Only alphanumeric characters, dashes, and underscores are allowed."
|
message: "Invalid folder name. Only alphanumeric characters, dashes, and underscores are allowed."
|
||||||
}),
|
}),
|
||||||
description: z.string().optional(),
|
description: z.string().nullable().optional(),
|
||||||
id: z.string()
|
id: z.string()
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@@ -534,7 +540,7 @@ export const registerPITRouter = async (server: FastifyZodProvider) => {
|
|||||||
actor: req.permission.type,
|
actor: req.permission.type,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
projectId: req.body.workspaceId,
|
projectId: req.body.projectId,
|
||||||
environment: req.body.environment,
|
environment: req.body.environment,
|
||||||
secretPath: req.body.secretPath,
|
secretPath: req.body.secretPath,
|
||||||
message: req.body.message,
|
message: req.body.message,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { ActorAuthMethod, ActorType } from "@app/services/auth/auth-type";
|
|||||||
import { TFolderCommitDALFactory } from "@app/services/folder-commit/folder-commit-dal";
|
import { TFolderCommitDALFactory } from "@app/services/folder-commit/folder-commit-dal";
|
||||||
import {
|
import {
|
||||||
ResourceType,
|
ResourceType,
|
||||||
TCreateCommitChangeDTO,
|
TCommitResourceChangeDTO,
|
||||||
TFolderCommitServiceFactory
|
TFolderCommitServiceFactory
|
||||||
} from "@app/services/folder-commit/folder-commit-service";
|
} from "@app/services/folder-commit/folder-commit-service";
|
||||||
import {
|
import {
|
||||||
@@ -500,8 +500,7 @@ export const pitServiceFactory = ({
|
|||||||
|
|
||||||
const processNewCommitRaw = async ({
|
const processNewCommitRaw = async ({
|
||||||
actorId,
|
actorId,
|
||||||
projectSlug,
|
projectId,
|
||||||
projectId: optionalProjectId,
|
|
||||||
environment,
|
environment,
|
||||||
actor,
|
actor,
|
||||||
actorOrgId,
|
actorOrgId,
|
||||||
@@ -522,8 +521,7 @@ export const pitServiceFactory = ({
|
|||||||
}
|
}
|
||||||
}: {
|
}: {
|
||||||
actorId: string;
|
actorId: string;
|
||||||
projectSlug?: string;
|
projectId: string;
|
||||||
projectId?: string;
|
|
||||||
environment: string;
|
environment: string;
|
||||||
actor: ActorType;
|
actor: ActorType;
|
||||||
actorOrgId: string;
|
actorOrgId: string;
|
||||||
@@ -532,16 +530,6 @@ export const pitServiceFactory = ({
|
|||||||
message: string;
|
message: string;
|
||||||
changes: TProcessNewCommitRawDTO;
|
changes: TProcessNewCommitRawDTO;
|
||||||
}) => {
|
}) => {
|
||||||
if (!projectSlug && !optionalProjectId)
|
|
||||||
throw new BadRequestError({ message: "Must provide either project slug or projectId" });
|
|
||||||
|
|
||||||
let projectId = optionalProjectId as string;
|
|
||||||
if (!optionalProjectId && projectSlug) {
|
|
||||||
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
|
||||||
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
|
|
||||||
projectId = project.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
const policy =
|
const policy =
|
||||||
actor === ActorType.USER
|
actor === ActorType.USER
|
||||||
? await secretApprovalPolicyService.getSecretApprovalPolicy(projectId, environment, secretPath)
|
? await secretApprovalPolicyService.getSecretApprovalPolicy(projectId, environment, secretPath)
|
||||||
@@ -581,7 +569,7 @@ export const pitServiceFactory = ({
|
|||||||
message: `Folder with path '${secretPath}' in environment with slug '${environment}' not found`,
|
message: `Folder with path '${secretPath}' in environment with slug '${environment}' not found`,
|
||||||
name: "CreateManySecret"
|
name: "CreateManySecret"
|
||||||
});
|
});
|
||||||
const commitChanges: TCreateCommitChangeDTO[] = [];
|
const commitChanges: TCommitResourceChangeDTO[] = [];
|
||||||
|
|
||||||
if ((changes.folders?.create?.length ?? 0) > 0) {
|
if ((changes.folders?.create?.length ?? 0) > 0) {
|
||||||
await folderService.createManyFolders({
|
await folderService.createManyFolders({
|
||||||
@@ -605,7 +593,6 @@ export const pitServiceFactory = ({
|
|||||||
if ((changes.folders?.update?.length ?? 0) > 0) {
|
if ((changes.folders?.update?.length ?? 0) > 0) {
|
||||||
await folderService.updateManyFolders({
|
await folderService.updateManyFolders({
|
||||||
projectId,
|
projectId,
|
||||||
projectSlug: projectSlug || "",
|
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
actorOrgId,
|
actorOrgId,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/* eslint-disable no-nested-ternary */
|
/* eslint-disable no-nested-ternary */
|
||||||
import { ForbiddenError, subject } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ProjectMembershipRole,
|
ProjectMembershipRole,
|
||||||
@@ -1260,8 +1261,9 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
policy,
|
policy,
|
||||||
projectId,
|
projectId,
|
||||||
secretPath,
|
secretPath,
|
||||||
environment
|
environment,
|
||||||
}: TGenerateSecretApprovalRequestV2BridgeDTO) => {
|
trx: providedTx
|
||||||
|
}: TGenerateSecretApprovalRequestV2BridgeDTO & { trx?: Knex }) => {
|
||||||
if (actor === ActorType.SERVICE || actor === ActorType.Machine)
|
if (actor === ActorType.SERVICE || actor === ActorType.Machine)
|
||||||
throw new BadRequestError({ message: "Cannot use service token or machine token over protected branches" });
|
throw new BadRequestError({ message: "Cannot use service token or machine token over protected branches" });
|
||||||
|
|
||||||
@@ -1487,7 +1489,7 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const secretApprovalRequest = await secretApprovalRequestDAL.transaction(async (tx) => {
|
const executeApprovalRequestCreation = async (tx: Knex) => {
|
||||||
const doc = await secretApprovalRequestDAL.create(
|
const doc = await secretApprovalRequestDAL.create(
|
||||||
{
|
{
|
||||||
folderId,
|
folderId,
|
||||||
@@ -1549,7 +1551,11 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return { ...doc, commits: approvalCommits };
|
return { ...doc, commits: approvalCommits };
|
||||||
});
|
};
|
||||||
|
|
||||||
|
const secretApprovalRequest = providedTx
|
||||||
|
? await executeApprovalRequestCreation(providedTx)
|
||||||
|
: await secretApprovalRequestDAL.transaction(executeApprovalRequestCreation);
|
||||||
|
|
||||||
const user = await userDAL.findById(secretApprovalRequest.committerUserId);
|
const user = await userDAL.findById(secretApprovalRequest.committerUserId);
|
||||||
const env = await projectEnvDAL.findOne({ id: policy.envId });
|
const env = await projectEnvDAL.findOne({ id: policy.envId });
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ export enum ResourceType {
|
|||||||
FOLDER = "folder"
|
FOLDER = "folder"
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TCreateCommitChangeDTO = {
|
export type TCommitResourceChangeDTO = {
|
||||||
type: string;
|
type: string;
|
||||||
secretVersionId?: string;
|
secretVersionId?: string;
|
||||||
folderVersionId?: string;
|
folderVersionId?: string;
|
||||||
@@ -65,7 +65,7 @@ type TCreateCommitDTO = {
|
|||||||
};
|
};
|
||||||
message?: string;
|
message?: string;
|
||||||
folderId: string;
|
folderId: string;
|
||||||
changes: TCreateCommitChangeDTO[];
|
changes: TCommitResourceChangeDTO[];
|
||||||
omitIgnoreFilter?: boolean;
|
omitIgnoreFilter?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -897,16 +897,16 @@ export const folderCommitServiceFactory = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const newCommit = await folderCommitDAL.create(
|
const newCommit = await folderCommitDAL.create(
|
||||||
{
|
{
|
||||||
actorMetadata: metadata,
|
actorMetadata: metadata,
|
||||||
actorType: data.actor.type,
|
actorType: data.actor.type,
|
||||||
message: data.message,
|
message: data.message,
|
||||||
folderId: data.folderId,
|
folderId: data.folderId,
|
||||||
envId: folder.envId
|
envId: folder.envId
|
||||||
},
|
},
|
||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
|
|
||||||
const batchSize = 500;
|
const batchSize = 500;
|
||||||
const chunks = chunkArray(changes, batchSize);
|
const chunks = chunkArray(changes, batchSize);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import { buildFolderPath } from "@app/services/secret-folder/secret-folder-fns";
|
|||||||
import {
|
import {
|
||||||
ChangeType,
|
ChangeType,
|
||||||
CommitType,
|
CommitType,
|
||||||
TCreateCommitChangeDTO,
|
TCommitResourceChangeDTO,
|
||||||
TFolderCommitServiceFactory
|
TFolderCommitServiceFactory
|
||||||
} from "../folder-commit/folder-commit-service";
|
} from "../folder-commit/folder-commit-service";
|
||||||
import { TProjectDALFactory } from "../project/project-dal";
|
import { TProjectDALFactory } from "../project/project-dal";
|
||||||
@@ -251,15 +251,18 @@ export const secretFolderServiceFactory = ({
|
|||||||
folders,
|
folders,
|
||||||
tx: providedTx,
|
tx: providedTx,
|
||||||
commitChanges
|
commitChanges
|
||||||
}: TUpdateManyFoldersDTO & { tx?: Knex; commitChanges?: TCreateCommitChangeDTO[]; projectId?: string }) => {
|
}: TUpdateManyFoldersDTO & { tx?: Knex; commitChanges?: TCommitResourceChangeDTO[]; projectId?: string }) => {
|
||||||
let projectId = providedProjectId;
|
let projectId = providedProjectId;
|
||||||
if (!projectId) {
|
if (!projectId && projectSlug) {
|
||||||
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
||||||
if (!project) {
|
if (!project) {
|
||||||
throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
|
throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
|
||||||
}
|
}
|
||||||
projectId = project.id;
|
projectId = project.id;
|
||||||
}
|
}
|
||||||
|
if (!projectId) {
|
||||||
|
throw new BadRequestError({ message: "Must provide either project slug or projectId" });
|
||||||
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getProjectPermission({
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actor,
|
||||||
@@ -1010,7 +1013,7 @@ export const secretFolderServiceFactory = ({
|
|||||||
folders,
|
folders,
|
||||||
tx: providedTx,
|
tx: providedTx,
|
||||||
commitChanges
|
commitChanges
|
||||||
}: TCreateManyFoldersDTO & { tx?: Knex; commitChanges?: TCreateCommitChangeDTO[] }) => {
|
}: TCreateManyFoldersDTO & { tx?: Knex; commitChanges?: TCommitResourceChangeDTO[] }) => {
|
||||||
const { permission } = await permissionService.getProjectPermission({
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
@@ -1221,7 +1224,7 @@ export const secretFolderServiceFactory = ({
|
|||||||
folders,
|
folders,
|
||||||
tx: providedTx,
|
tx: providedTx,
|
||||||
commitChanges
|
commitChanges
|
||||||
}: TDeleteManyFoldersDTO & { tx?: Knex; commitChanges?: TCreateCommitChangeDTO[] }) => {
|
}: TDeleteManyFoldersDTO & { tx?: Knex; commitChanges?: TCommitResourceChangeDTO[] }) => {
|
||||||
const { permission } = await permissionService.getProjectPermission({
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export type TUpdateFolderDTO = {
|
|||||||
} & TProjectPermission;
|
} & TProjectPermission;
|
||||||
|
|
||||||
export type TUpdateManyFoldersDTO = {
|
export type TUpdateManyFoldersDTO = {
|
||||||
projectSlug: string;
|
projectSlug?: string;
|
||||||
folders: {
|
folders: {
|
||||||
environment: string;
|
environment: string;
|
||||||
path: string;
|
path: string;
|
||||||
@@ -75,7 +75,7 @@ export type TCreateManyFoldersDTO = {
|
|||||||
name: string;
|
name: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
path: string;
|
path: string;
|
||||||
description?: string;
|
description?: string | null;
|
||||||
}>;
|
}>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import { logger } from "@app/lib/logger";
|
|||||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||||
|
|
||||||
import { ActorType } from "../auth/auth-type";
|
import { ActorType } from "../auth/auth-type";
|
||||||
import { TCreateCommitChangeDTO, TFolderCommitServiceFactory } from "../folder-commit/folder-commit-service";
|
import { TCommitResourceChangeDTO, TFolderCommitServiceFactory } from "../folder-commit/folder-commit-service";
|
||||||
import { TKmsServiceFactory } from "../kms/kms-service";
|
import { TKmsServiceFactory } from "../kms/kms-service";
|
||||||
import { KmsDataKey } from "../kms/kms-types";
|
import { KmsDataKey } from "../kms/kms-types";
|
||||||
import { TProjectEnvDALFactory } from "../project-env/project-env-dal";
|
import { TProjectEnvDALFactory } from "../project-env/project-env-dal";
|
||||||
@@ -1477,7 +1477,7 @@ export const secretV2BridgeServiceFactory = ({
|
|||||||
secrets: inputSecrets,
|
secrets: inputSecrets,
|
||||||
tx: providedTx,
|
tx: providedTx,
|
||||||
commitChanges
|
commitChanges
|
||||||
}: TCreateManySecretDTO & { tx?: Knex; commitChanges?: TCreateCommitChangeDTO[] }) => {
|
}: TCreateManySecretDTO & { tx?: Knex; commitChanges?: TCommitResourceChangeDTO[] }) => {
|
||||||
const { permission } = await permissionService.getProjectPermission({
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
@@ -1652,7 +1652,7 @@ export const secretV2BridgeServiceFactory = ({
|
|||||||
mode: updateMode,
|
mode: updateMode,
|
||||||
tx: providedTx,
|
tx: providedTx,
|
||||||
commitChanges
|
commitChanges
|
||||||
}: TUpdateManySecretDTO & { tx?: Knex; commitChanges?: TCreateCommitChangeDTO[] }) => {
|
}: TUpdateManySecretDTO & { tx?: Knex; commitChanges?: TCommitResourceChangeDTO[] }) => {
|
||||||
const { permission } = await permissionService.getProjectPermission({
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
@@ -2013,7 +2013,7 @@ export const secretV2BridgeServiceFactory = ({
|
|||||||
actorOrgId,
|
actorOrgId,
|
||||||
tx: providedTx,
|
tx: providedTx,
|
||||||
commitChanges
|
commitChanges
|
||||||
}: TDeleteManySecretDTO & { tx?: Knex; commitChanges?: TCreateCommitChangeDTO[] }) => {
|
}: TDeleteManySecretDTO & { tx?: Knex; commitChanges?: TCommitResourceChangeDTO[] }) => {
|
||||||
const { permission } = await permissionService.getProjectPermission({
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { SecretsOrderBy } from "@app/services/secret/secret-types";
|
|||||||
import { TSecretFolderDALFactory } from "@app/services/secret-folder/secret-folder-dal";
|
import { TSecretFolderDALFactory } from "@app/services/secret-folder/secret-folder-dal";
|
||||||
import { TSecretTagDALFactory } from "@app/services/secret-tag/secret-tag-dal";
|
import { TSecretTagDALFactory } from "@app/services/secret-tag/secret-tag-dal";
|
||||||
|
|
||||||
import { TCreateCommitChangeDTO, TFolderCommitServiceFactory } from "../folder-commit/folder-commit-service";
|
import { TCommitResourceChangeDTO, TFolderCommitServiceFactory } from "../folder-commit/folder-commit-service";
|
||||||
import { TResourceMetadataDALFactory } from "../resource-metadata/resource-metadata-dal";
|
import { TResourceMetadataDALFactory } from "../resource-metadata/resource-metadata-dal";
|
||||||
import { ResourceMetadataDTO } from "../resource-metadata/resource-metadata-schema";
|
import { ResourceMetadataDTO } from "../resource-metadata/resource-metadata-schema";
|
||||||
import { TSecretV2BridgeDALFactory } from "./secret-v2-bridge-dal";
|
import { TSecretV2BridgeDALFactory } from "./secret-v2-bridge-dal";
|
||||||
@@ -167,7 +167,7 @@ export type TFnSecretBulkInsert = {
|
|||||||
folderId: string;
|
folderId: string;
|
||||||
orgId: string;
|
orgId: string;
|
||||||
tx?: Knex;
|
tx?: Knex;
|
||||||
commitChanges?: TCreateCommitChangeDTO[];
|
commitChanges?: TCommitResourceChangeDTO[];
|
||||||
inputSecrets: Array<
|
inputSecrets: Array<
|
||||||
Omit<TSecretsV2Insert, "folderId"> & {
|
Omit<TSecretsV2Insert, "folderId"> & {
|
||||||
tagIds?: string[];
|
tagIds?: string[];
|
||||||
@@ -215,7 +215,7 @@ export type TFnSecretBulkUpdate = {
|
|||||||
actorId?: string;
|
actorId?: string;
|
||||||
};
|
};
|
||||||
tx?: Knex;
|
tx?: Knex;
|
||||||
commitChanges?: TCreateCommitChangeDTO[];
|
commitChanges?: TCommitResourceChangeDTO[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TFnSecretBulkDelete = {
|
export type TFnSecretBulkDelete = {
|
||||||
@@ -225,7 +225,7 @@ export type TFnSecretBulkDelete = {
|
|||||||
actorId: string;
|
actorId: string;
|
||||||
actorType?: string;
|
actorType?: string;
|
||||||
tx?: Knex;
|
tx?: Knex;
|
||||||
commitChanges?: TCreateCommitChangeDTO[];
|
commitChanges?: TCommitResourceChangeDTO[];
|
||||||
secretDAL: Pick<TSecretV2BridgeDALFactory, "deleteMany">;
|
secretDAL: Pick<TSecretV2BridgeDALFactory, "deleteMany">;
|
||||||
secretQueueService: {
|
secretQueueService: {
|
||||||
removeSecretReminder: (data: TRemoveSecretReminderDTO, tx?: Knex) => Promise<void>;
|
removeSecretReminder: (data: TRemoveSecretReminderDTO, tx?: Knex) => Promise<void>;
|
||||||
|
|||||||
@@ -570,7 +570,7 @@ export type TProcessNewCommitRawDTO = {
|
|||||||
};
|
};
|
||||||
folders: {
|
folders: {
|
||||||
create?: { folderName: string; description?: string }[];
|
create?: { folderName: string; description?: string }[];
|
||||||
update?: { folderName: string; description?: string; id: string }[];
|
update?: { folderName: string; description?: string | null; id: string }[];
|
||||||
delete?: { folderName: string; id: string }[];
|
delete?: { folderName: string; id: string }[];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,13 +4,19 @@ export enum ReservedFolders {
|
|||||||
SecretReplication = "__reserve_replication_"
|
SecretReplication = "__reserve_replication_"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum PendingAction {
|
||||||
|
Create = "create",
|
||||||
|
Update = "update",
|
||||||
|
Delete = "delete"
|
||||||
|
}
|
||||||
|
|
||||||
export type TSecretFolder = {
|
export type TSecretFolder = {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
parentId?: string | null;
|
parentId?: string | null;
|
||||||
isPending?: boolean;
|
isPending?: boolean;
|
||||||
pendingAction?: string;
|
pendingAction?: PendingAction;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TSecretFolderWithPath = TSecretFolder & { path: string };
|
export type TSecretFolderWithPath = TSecretFolder & { path: string };
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
|
|
||||||
import { commitKeys } from "../folderCommits/queries";
|
import { commitKeys } from "../folderCommits/queries";
|
||||||
import { secretApprovalRequestKeys } from "../secretApprovalRequest/queries";
|
import { secretApprovalRequestKeys } from "../secretApprovalRequest/queries";
|
||||||
|
import { PendingAction } from "../secretFolders/types";
|
||||||
import { secretSnapshotKeys } from "../secretSnapshots/queries";
|
import { secretSnapshotKeys } from "../secretSnapshots/queries";
|
||||||
import { secretKeys } from "./queries";
|
import { secretKeys } from "./queries";
|
||||||
import {
|
import {
|
||||||
@@ -440,9 +441,20 @@ export const useCreateCommit = () => {
|
|||||||
>({
|
>({
|
||||||
mutationFn: async ({ workspaceId, environment, secretPath, pendingChanges, message }) => {
|
mutationFn: async ({ workspaceId, environment, secretPath, pendingChanges, message }) => {
|
||||||
const transformedSecretUpdates = pendingChanges.secrets
|
const transformedSecretUpdates = pendingChanges.secrets
|
||||||
.filter((change) => change.type === "update")
|
.filter((change) => change.type === PendingAction.Update)
|
||||||
.map((change: PendingSecretUpdate) => {
|
.map((change: PendingSecretUpdate) => {
|
||||||
const updatePayload: any = {
|
const updatePayload: {
|
||||||
|
secretKey: string;
|
||||||
|
newSecretName?: string;
|
||||||
|
secretValue?: string;
|
||||||
|
secretComment?: string;
|
||||||
|
skipMultilineEncoding?: boolean;
|
||||||
|
tagIds?: string[];
|
||||||
|
secretMetadata?: {
|
||||||
|
key: string;
|
||||||
|
value: string;
|
||||||
|
}[];
|
||||||
|
} = {
|
||||||
secretKey: change.secretKey
|
secretKey: change.secretKey
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -469,14 +481,14 @@ export const useCreateCommit = () => {
|
|||||||
return updatePayload;
|
return updatePayload;
|
||||||
});
|
});
|
||||||
const { data } = await apiRequest.post("/api/v1/pit/batch/commit", {
|
const { data } = await apiRequest.post("/api/v1/pit/batch/commit", {
|
||||||
workspaceId,
|
projectId: workspaceId,
|
||||||
environment,
|
environment,
|
||||||
secretPath,
|
secretPath,
|
||||||
changes: {
|
changes: {
|
||||||
secrets: {
|
secrets: {
|
||||||
create:
|
create:
|
||||||
pendingChanges.secrets
|
pendingChanges.secrets
|
||||||
.filter((change) => change.type === "create")
|
.filter((change) => change.type === PendingAction.Create)
|
||||||
.map((change) => ({
|
.map((change) => ({
|
||||||
secretKey: change.secretKey,
|
secretKey: change.secretKey,
|
||||||
secretValue: change.secretValue,
|
secretValue: change.secretValue,
|
||||||
@@ -485,13 +497,22 @@ export const useCreateCommit = () => {
|
|||||||
tagIds: change.tags?.map((tag) => tag.id),
|
tagIds: change.tags?.map((tag) => tag.id),
|
||||||
secretMetadata: change.secretMetadata
|
secretMetadata: change.secretMetadata
|
||||||
})) || [],
|
})) || [],
|
||||||
update: transformedSecretUpdates,
|
update: transformedSecretUpdates || [],
|
||||||
delete: pendingChanges.secrets.filter((change) => change.type === "delete") || []
|
delete:
|
||||||
|
pendingChanges.secrets.filter((change) => change.type === PendingAction.Delete) || []
|
||||||
},
|
},
|
||||||
folders: {
|
folders: {
|
||||||
create: pendingChanges.folders.filter((change) => change.type === "create") || [],
|
create:
|
||||||
update: pendingChanges.folders.filter((change) => change.type === "update") || [],
|
pendingChanges.folders.filter((change) => change.type === PendingAction.Create) || [],
|
||||||
delete: pendingChanges.folders.filter((change) => change.type === "delete") || []
|
update:
|
||||||
|
pendingChanges.folders
|
||||||
|
.filter((change) => change.type === PendingAction.Update)
|
||||||
|
.map((change) => ({
|
||||||
|
...change,
|
||||||
|
description: change.description || null
|
||||||
|
})) || [],
|
||||||
|
delete:
|
||||||
|
pendingChanges.folders.filter((change) => change.type === PendingAction.Delete) || []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
message
|
message
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { ProjectPermissionActions } from "@app/context";
|
import { ProjectPermissionActions } from "@app/context";
|
||||||
|
|
||||||
|
import { PendingAction } from "../secretFolders/types";
|
||||||
import type { WsTag } from "../tags/types";
|
import type { WsTag } from "../tags/types";
|
||||||
|
|
||||||
export enum SecretType {
|
export enum SecretType {
|
||||||
@@ -67,7 +68,7 @@ export type SecretV3RawSanitized = {
|
|||||||
secretReminderRecipients?: SecretReminderRecipient[];
|
secretReminderRecipients?: SecretReminderRecipient[];
|
||||||
rotationId?: string;
|
rotationId?: string;
|
||||||
isPending?: boolean;
|
isPending?: boolean;
|
||||||
pendingAction?: "create" | "update" | "delete";
|
pendingAction?: PendingAction;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SecretV3Raw = {
|
export type SecretV3Raw = {
|
||||||
|
|||||||
@@ -47,7 +47,9 @@ import { useGetProjectSecretsDetails } from "@app/hooks/api/dashboard";
|
|||||||
import { DashboardSecretsOrderBy } from "@app/hooks/api/dashboard/types";
|
import { DashboardSecretsOrderBy } from "@app/hooks/api/dashboard/types";
|
||||||
import { useGetFolderCommitsCount } from "@app/hooks/api/folderCommits";
|
import { useGetFolderCommitsCount } from "@app/hooks/api/folderCommits";
|
||||||
import { OrderByDirection } from "@app/hooks/api/generic/types";
|
import { OrderByDirection } from "@app/hooks/api/generic/types";
|
||||||
|
import { PendingAction } from "@app/hooks/api/secretFolders/types";
|
||||||
import { useCreateCommit } from "@app/hooks/api/secrets/mutations";
|
import { useCreateCommit } from "@app/hooks/api/secrets/mutations";
|
||||||
|
import { SecretV3RawSanitized } from "@app/hooks/api/types";
|
||||||
import { hasSecretReadValueOrDescribePermission } from "@app/lib/fn/permission";
|
import { hasSecretReadValueOrDescribePermission } from "@app/lib/fn/permission";
|
||||||
import { SecretRotationListView } from "@app/pages/secret-manager/SecretDashboardPage/components/SecretRotationListView";
|
import { SecretRotationListView } from "@app/pages/secret-manager/SecretDashboardPage/components/SecretRotationListView";
|
||||||
|
|
||||||
@@ -136,14 +138,22 @@ const Page = () => {
|
|||||||
}
|
}
|
||||||
}, [isBatchMode, workspaceId, environment, secretPath, loadPendingChanges]);
|
}, [isBatchMode, workspaceId, environment, secretPath, loadPendingChanges]);
|
||||||
|
|
||||||
const handleCreateCommit = (changes: PendingChanges, message: string) => {
|
const handleCreateCommit = async (changes: PendingChanges, message: string) => {
|
||||||
createCommit({
|
try {
|
||||||
workspaceId,
|
await createCommit({
|
||||||
environment,
|
workspaceId,
|
||||||
secretPath,
|
environment,
|
||||||
pendingChanges: changes,
|
secretPath,
|
||||||
message
|
pendingChanges: changes,
|
||||||
});
|
message
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
createNotification({
|
||||||
|
text: "Failed to commit changes",
|
||||||
|
type: "error"
|
||||||
|
});
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const canReadSecret = hasSecretReadValueOrDescribePermission(
|
const canReadSecret = hasSecretReadValueOrDescribePermission(
|
||||||
@@ -521,7 +531,7 @@ const Page = () => {
|
|||||||
|
|
||||||
pendingChanges.secrets.forEach((change) => {
|
pendingChanges.secrets.forEach((change) => {
|
||||||
switch (change.type) {
|
switch (change.type) {
|
||||||
case "create":
|
case PendingAction.Create:
|
||||||
mergedSecrets.unshift({
|
mergedSecrets.unshift({
|
||||||
id: change.id,
|
id: change.id,
|
||||||
key: change.secretKey,
|
key: change.secretKey,
|
||||||
@@ -534,11 +544,11 @@ const Page = () => {
|
|||||||
updatedAt: new Date().toISOString(),
|
updatedAt: new Date().toISOString(),
|
||||||
version: 1,
|
version: 1,
|
||||||
isPending: true,
|
isPending: true,
|
||||||
pendingAction: "create"
|
pendingAction: PendingAction.Create
|
||||||
} as any);
|
} as unknown as SecretV3RawSanitized);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "update":
|
case PendingAction.Update:
|
||||||
const updateIndex = mergedSecrets.findIndex((s) => s.key === change.secretKey);
|
const updateIndex = mergedSecrets.findIndex((s) => s.key === change.secretKey);
|
||||||
if (updateIndex >= 0) {
|
if (updateIndex >= 0) {
|
||||||
mergedSecrets[updateIndex] = {
|
mergedSecrets[updateIndex] = {
|
||||||
@@ -558,18 +568,18 @@ const Page = () => {
|
|||||||
: mergedSecrets[updateIndex].skipMultilineEncoding,
|
: mergedSecrets[updateIndex].skipMultilineEncoding,
|
||||||
secretMetadata: change.secretMetadata || mergedSecrets[updateIndex].secretMetadata,
|
secretMetadata: change.secretMetadata || mergedSecrets[updateIndex].secretMetadata,
|
||||||
isPending: true,
|
isPending: true,
|
||||||
pendingAction: "update"
|
pendingAction: PendingAction.Update
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "delete":
|
case PendingAction.Delete:
|
||||||
const deleteIndex = mergedSecrets.findIndex((s) => s.key === change.secretKey);
|
const deleteIndex = mergedSecrets.findIndex((s) => s.key === change.secretKey);
|
||||||
if (deleteIndex >= 0) {
|
if (deleteIndex >= 0) {
|
||||||
mergedSecrets[deleteIndex] = {
|
mergedSecrets[deleteIndex] = {
|
||||||
...mergedSecrets[deleteIndex],
|
...mergedSecrets[deleteIndex],
|
||||||
isPending: true,
|
isPending: true,
|
||||||
pendingAction: "delete"
|
pendingAction: PendingAction.Delete
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -591,18 +601,18 @@ const Page = () => {
|
|||||||
|
|
||||||
pendingChanges.folders.forEach((change) => {
|
pendingChanges.folders.forEach((change) => {
|
||||||
switch (change.type) {
|
switch (change.type) {
|
||||||
case "create":
|
case PendingAction.Create:
|
||||||
mergedFolders.unshift({
|
mergedFolders.unshift({
|
||||||
id: change.id,
|
id: change.id,
|
||||||
name: change.folderName,
|
name: change.folderName,
|
||||||
description: change.description,
|
description: change.description,
|
||||||
parentId: null,
|
parentId: null,
|
||||||
isPending: true,
|
isPending: true,
|
||||||
pendingAction: "create"
|
pendingAction: PendingAction.Create
|
||||||
} as any);
|
} as any);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "update":
|
case PendingAction.Update:
|
||||||
const updateIndex = mergedFolders.findIndex((f) => f.id === change.id);
|
const updateIndex = mergedFolders.findIndex((f) => f.id === change.id);
|
||||||
if (updateIndex >= 0) {
|
if (updateIndex >= 0) {
|
||||||
mergedFolders[updateIndex] = {
|
mergedFolders[updateIndex] = {
|
||||||
@@ -613,18 +623,18 @@ const Page = () => {
|
|||||||
? change.description
|
? change.description
|
||||||
: mergedFolders[updateIndex].description,
|
: mergedFolders[updateIndex].description,
|
||||||
isPending: true,
|
isPending: true,
|
||||||
pendingAction: "update"
|
pendingAction: PendingAction.Update
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "delete":
|
case PendingAction.Delete:
|
||||||
const deleteIndex = mergedFolders.findIndex((f) => f.id === change.id);
|
const deleteIndex = mergedFolders.findIndex((f) => f.id === change.id);
|
||||||
if (deleteIndex >= 0) {
|
if (deleteIndex >= 0) {
|
||||||
mergedFolders[deleteIndex] = {
|
mergedFolders[deleteIndex] = {
|
||||||
...mergedFolders[deleteIndex],
|
...mergedFolders[deleteIndex],
|
||||||
isPending: true,
|
isPending: true,
|
||||||
pendingAction: "delete"
|
pendingAction: PendingAction.Delete
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -758,9 +768,7 @@ const Page = () => {
|
|||||||
)}
|
)}
|
||||||
{(pendingChanges.secrets.length > 0 || pendingChanges.folders.length > 0) && (
|
{(pendingChanges.secrets.length > 0 || pendingChanges.folders.length > 0) && (
|
||||||
<CommitForm
|
<CommitForm
|
||||||
onCommit={async (changes, commitMessage) => {
|
onCommit={handleCreateCommit}
|
||||||
await handleCreateCommit(changes, commitMessage);
|
|
||||||
}}
|
|
||||||
environment={environment}
|
environment={environment}
|
||||||
workspaceId={workspaceId}
|
workspaceId={workspaceId}
|
||||||
secretPath={secretPath}
|
secretPath={secretPath}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { useRouter } from "@tanstack/react-router";
|
|||||||
import { createStore, StateCreator, StoreApi, useStore } from "zustand";
|
import { createStore, StateCreator, StoreApi, useStore } from "zustand";
|
||||||
import { useShallow } from "zustand/react/shallow";
|
import { useShallow } from "zustand/react/shallow";
|
||||||
|
|
||||||
|
import { PendingAction } from "@app/hooks/api/secretFolders/types";
|
||||||
import { SecretV3RawSanitized } from "@app/hooks/api/secrets/types";
|
import { SecretV3RawSanitized } from "@app/hooks/api/secrets/types";
|
||||||
|
|
||||||
// akhilmhdh: Don't remove this file if ur thinking why use zustand just for selected selects state
|
// akhilmhdh: Don't remove this file if ur thinking why use zustand just for selected selects state
|
||||||
@@ -19,7 +20,7 @@ export interface BasePendingChange {
|
|||||||
// Secret-related change types
|
// Secret-related change types
|
||||||
export interface PendingSecretCreate extends BasePendingChange {
|
export interface PendingSecretCreate extends BasePendingChange {
|
||||||
resourceType: "secret";
|
resourceType: "secret";
|
||||||
type: "create";
|
type: PendingAction.Create;
|
||||||
secretKey: string;
|
secretKey: string;
|
||||||
secretValue: string;
|
secretValue: string;
|
||||||
secretComment?: string;
|
secretComment?: string;
|
||||||
@@ -31,7 +32,7 @@ export interface PendingSecretCreate extends BasePendingChange {
|
|||||||
|
|
||||||
export interface PendingSecretUpdate extends BasePendingChange {
|
export interface PendingSecretUpdate extends BasePendingChange {
|
||||||
resourceType: "secret";
|
resourceType: "secret";
|
||||||
type: "update";
|
type: PendingAction.Update;
|
||||||
secretKey: string;
|
secretKey: string;
|
||||||
newSecretName?: string;
|
newSecretName?: string;
|
||||||
originalValue?: string;
|
originalValue?: string;
|
||||||
@@ -48,7 +49,7 @@ export interface PendingSecretUpdate extends BasePendingChange {
|
|||||||
|
|
||||||
export interface PendingSecretDelete extends BasePendingChange {
|
export interface PendingSecretDelete extends BasePendingChange {
|
||||||
resourceType: "secret";
|
resourceType: "secret";
|
||||||
type: "delete";
|
type: PendingAction.Delete;
|
||||||
secretKey: string;
|
secretKey: string;
|
||||||
secretValue: string;
|
secretValue: string;
|
||||||
}
|
}
|
||||||
@@ -56,7 +57,7 @@ export interface PendingSecretDelete extends BasePendingChange {
|
|||||||
// Folder-related change types
|
// Folder-related change types
|
||||||
export interface PendingFolderCreate extends BasePendingChange {
|
export interface PendingFolderCreate extends BasePendingChange {
|
||||||
resourceType: "folder";
|
resourceType: "folder";
|
||||||
type: "create";
|
type: PendingAction.Create;
|
||||||
id: string;
|
id: string;
|
||||||
folderName: string;
|
folderName: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
@@ -65,7 +66,7 @@ export interface PendingFolderCreate extends BasePendingChange {
|
|||||||
|
|
||||||
export interface PendingFolderUpdate extends BasePendingChange {
|
export interface PendingFolderUpdate extends BasePendingChange {
|
||||||
resourceType: "folder";
|
resourceType: "folder";
|
||||||
type: "update";
|
type: PendingAction.Update;
|
||||||
originalFolderName: string;
|
originalFolderName: string;
|
||||||
folderName: string;
|
folderName: string;
|
||||||
id: string;
|
id: string;
|
||||||
@@ -75,7 +76,7 @@ export interface PendingFolderUpdate extends BasePendingChange {
|
|||||||
|
|
||||||
export interface PendingFolderDelete extends BasePendingChange {
|
export interface PendingFolderDelete extends BasePendingChange {
|
||||||
resourceType: "folder";
|
resourceType: "folder";
|
||||||
type: "delete";
|
type: PendingAction.Delete;
|
||||||
id: string;
|
id: string;
|
||||||
folderName: string;
|
folderName: string;
|
||||||
folderPath: string;
|
folderPath: string;
|
||||||
@@ -248,43 +249,45 @@ const createBatchModeStore: StateCreator<CombinedState, [], [], BatchModeState>
|
|||||||
const newChanges = { ...state.pendingChanges };
|
const newChanges = { ...state.pendingChanges };
|
||||||
|
|
||||||
if (change.resourceType === "folder") {
|
if (change.resourceType === "folder") {
|
||||||
if (
|
const existingFolder =
|
||||||
change.type === "create" &&
|
state.existingFolderNames.has(change.folderName) ||
|
||||||
(state.existingFolderNames.has(change.folderName) ||
|
newChanges.folders.some((f) => f.folderName === change.folderName);
|
||||||
newChanges.folders.some((f) => f.folderName === change.folderName))
|
|
||||||
) {
|
if (change.type === PendingAction.Create && existingFolder) {
|
||||||
return { pendingChanges: newChanges };
|
return { pendingChanges: newChanges };
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
change.type === "update" &&
|
change.type === PendingAction.Update &&
|
||||||
change.folderName !== change.originalFolderName &&
|
change.folderName !== change.originalFolderName &&
|
||||||
(state.existingFolderNames.has(change.folderName) ||
|
existingFolder
|
||||||
newChanges.folders.some((f) => f.folderName === change.folderName))
|
|
||||||
) {
|
) {
|
||||||
return { pendingChanges: newChanges };
|
return { pendingChanges: newChanges };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (change.resourceType === "secret") {
|
if (change.resourceType === "secret") {
|
||||||
if (
|
const existingSecret =
|
||||||
change.type === "create" &&
|
state.existingSecretKeys.has(change.secretKey) ||
|
||||||
(state.existingSecretKeys.has(change.secretKey) ||
|
newChanges.secrets.some((s) => s.secretKey === change.secretKey);
|
||||||
newChanges.secrets.some((s) => s.secretKey === change.secretKey))
|
|
||||||
) {
|
if (change.type === PendingAction.Create && existingSecret) {
|
||||||
return { pendingChanges: newChanges };
|
return { pendingChanges: newChanges };
|
||||||
}
|
}
|
||||||
if (
|
|
||||||
change.type === "update" &&
|
const existingNewSecretName =
|
||||||
|
change.type === PendingAction.Update &&
|
||||||
change.newSecretName &&
|
change.newSecretName &&
|
||||||
change.newSecretName !== change.secretKey &&
|
change.newSecretName !== change.secretKey &&
|
||||||
(state.existingSecretKeys.has(change.newSecretName) ||
|
(state.existingSecretKeys.has(change.newSecretName) ||
|
||||||
newChanges.secrets.some(
|
newChanges.secrets.some(
|
||||||
(s) =>
|
(s) =>
|
||||||
(s.secretKey === change.newSecretName ||
|
(s.secretKey === change.newSecretName ||
|
||||||
(s.type === "update" && s.newSecretName === change.newSecretName)) &&
|
(s.type === PendingAction.Update &&
|
||||||
|
s.newSecretName === change.newSecretName)) &&
|
||||||
s.id !== change.id
|
s.id !== change.id
|
||||||
))
|
));
|
||||||
) {
|
|
||||||
|
if (existingNewSecretName) {
|
||||||
return { pendingChanges: newChanges };
|
return { pendingChanges: newChanges };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -292,10 +295,10 @@ const createBatchModeStore: StateCreator<CombinedState, [], [], BatchModeState>
|
|||||||
if (change.resourceType === "secret") {
|
if (change.resourceType === "secret") {
|
||||||
const secretChanges = [...newChanges.secrets];
|
const secretChanges = [...newChanges.secrets];
|
||||||
|
|
||||||
if (change.type === "create") {
|
if (change.type === PendingAction.Create) {
|
||||||
const existingCreateIndex = secretChanges.findIndex(
|
const existingCreateIndex = secretChanges.findIndex(
|
||||||
(c) =>
|
(c) =>
|
||||||
c.type === "create" &&
|
c.type === PendingAction.Create &&
|
||||||
(c.secretKey === change.secretKey || c.secretKey === change.originalKey)
|
(c.secretKey === change.secretKey || c.secretKey === change.originalKey)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -308,9 +311,9 @@ const createBatchModeStore: StateCreator<CombinedState, [], [], BatchModeState>
|
|||||||
} else {
|
} else {
|
||||||
secretChanges.push(change);
|
secretChanges.push(change);
|
||||||
}
|
}
|
||||||
} else if (change.type === "update") {
|
} else if (change.type === PendingAction.Update) {
|
||||||
const existingCreateIndex = secretChanges.findIndex(
|
const existingCreateIndex = secretChanges.findIndex(
|
||||||
(c) => c.type === "create" && c.id === change.id
|
(c) => c.type === PendingAction.Create && c.id === change.id
|
||||||
);
|
);
|
||||||
|
|
||||||
if (existingCreateIndex >= 0) {
|
if (existingCreateIndex >= 0) {
|
||||||
@@ -339,7 +342,7 @@ const createBatchModeStore: StateCreator<CombinedState, [], [], BatchModeState>
|
|||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
const existingUpdateIndex = secretChanges.findIndex(
|
const existingUpdateIndex = secretChanges.findIndex(
|
||||||
(c) => c.type === "update" && c.id === change.id
|
(c) => c.type === PendingAction.Update && c.id === change.id
|
||||||
);
|
);
|
||||||
|
|
||||||
if (existingUpdateIndex >= 0) {
|
if (existingUpdateIndex >= 0) {
|
||||||
@@ -394,9 +397,9 @@ const createBatchModeStore: StateCreator<CombinedState, [], [], BatchModeState>
|
|||||||
} else if (change.resourceType === "folder") {
|
} else if (change.resourceType === "folder") {
|
||||||
const folderChanges = [...newChanges.folders];
|
const folderChanges = [...newChanges.folders];
|
||||||
|
|
||||||
if (change.type === "create") {
|
if (change.type === PendingAction.Create) {
|
||||||
const existingCreateIndex = folderChanges.findIndex(
|
const existingCreateIndex = folderChanges.findIndex(
|
||||||
(c) => c.type === "create" && c.folderName === change.folderName
|
(c) => c.type === PendingAction.Create && c.folderName === change.folderName
|
||||||
);
|
);
|
||||||
|
|
||||||
if (existingCreateIndex >= 0) {
|
if (existingCreateIndex >= 0) {
|
||||||
@@ -408,9 +411,9 @@ const createBatchModeStore: StateCreator<CombinedState, [], [], BatchModeState>
|
|||||||
} else {
|
} else {
|
||||||
folderChanges.push(change);
|
folderChanges.push(change);
|
||||||
}
|
}
|
||||||
} else if (change.type === "update") {
|
} else if (change.type === PendingAction.Update) {
|
||||||
const existingCreateIndex = folderChanges.findIndex(
|
const existingCreateIndex = folderChanges.findIndex(
|
||||||
(c) => c.type === "create" && c.folderName === change.originalFolderName
|
(c) => c.type === PendingAction.Create && c.folderName === change.originalFolderName
|
||||||
);
|
);
|
||||||
|
|
||||||
if (existingCreateIndex >= 0) {
|
if (existingCreateIndex >= 0) {
|
||||||
@@ -426,7 +429,7 @@ const createBatchModeStore: StateCreator<CombinedState, [], [], BatchModeState>
|
|||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
const existingUpdateIndex = folderChanges.findIndex(
|
const existingUpdateIndex = folderChanges.findIndex(
|
||||||
(c) => c.type === "update" && c.id === change.id
|
(c) => c.type === PendingAction.Update && c.id === change.id
|
||||||
);
|
);
|
||||||
|
|
||||||
if (existingUpdateIndex >= 0) {
|
if (existingUpdateIndex >= 0) {
|
||||||
|
|||||||
+2
-1
@@ -74,6 +74,7 @@ import {
|
|||||||
} from "@app/hooks/api/dashboard/queries";
|
} from "@app/hooks/api/dashboard/queries";
|
||||||
import { UsedBySecretSyncs } from "@app/hooks/api/dashboard/types";
|
import { UsedBySecretSyncs } from "@app/hooks/api/dashboard/types";
|
||||||
import { secretApprovalRequestKeys } from "@app/hooks/api/secretApprovalRequest/queries";
|
import { secretApprovalRequestKeys } from "@app/hooks/api/secretApprovalRequest/queries";
|
||||||
|
import { PendingAction } from "@app/hooks/api/secretFolders/types";
|
||||||
import { fetchProjectSecrets, secretKeys } from "@app/hooks/api/secrets/queries";
|
import { fetchProjectSecrets, secretKeys } from "@app/hooks/api/secrets/queries";
|
||||||
import { ApiErrorTypes, SecretType, TApiErrors, WsTag } from "@app/hooks/api/types";
|
import { ApiErrorTypes, SecretType, TApiErrors, WsTag } from "@app/hooks/api/types";
|
||||||
import { SecretSearchInput } from "@app/pages/secret-manager/OverviewPage/components/SecretSearchInput";
|
import { SecretSearchInput } from "@app/pages/secret-manager/OverviewPage/components/SecretSearchInput";
|
||||||
@@ -193,7 +194,7 @@ export const ActionBar = ({
|
|||||||
const pendingFolderCreate: PendingFolderCreate = {
|
const pendingFolderCreate: PendingFolderCreate = {
|
||||||
id: folderId,
|
id: folderId,
|
||||||
resourceType: "folder",
|
resourceType: "folder",
|
||||||
type: "create",
|
type: PendingAction.Create,
|
||||||
folderName,
|
folderName,
|
||||||
description: description || undefined,
|
description: description || undefined,
|
||||||
parentPath: secretPath,
|
parentPath: secretPath,
|
||||||
|
|||||||
+22
-24
@@ -12,6 +12,7 @@ import {
|
|||||||
Modal,
|
Modal,
|
||||||
ModalContent
|
ModalContent
|
||||||
} from "@app/components/v2";
|
} from "@app/components/v2";
|
||||||
|
import { PendingAction } from "@app/hooks/api/secretFolders/types";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
PendingChange,
|
PendingChange,
|
||||||
@@ -106,11 +107,11 @@ const ChangeTable: React.FC<ChangeTableProps> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const getChangeBadge = (type: PendingChange["type"]) => {
|
const getChangeBadge = (type: PendingChange["type"]) => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "create":
|
case PendingAction.Create:
|
||||||
return <Badge variant="success">Created</Badge>;
|
return <Badge variant="success">Created</Badge>;
|
||||||
case "update":
|
case PendingAction.Update:
|
||||||
return <Badge variant="primary">Updated</Badge>;
|
return <Badge variant="primary">Updated</Badge>;
|
||||||
case "delete":
|
case PendingAction.Delete:
|
||||||
return <Badge variant="danger">Deleted</Badge>;
|
return <Badge variant="danger">Deleted</Badge>;
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
@@ -120,7 +121,7 @@ const ChangeTable: React.FC<ChangeTableProps> = ({
|
|||||||
const renderSecretChanges = () => {
|
const renderSecretChanges = () => {
|
||||||
if (change.resourceType !== "secret") return null;
|
if (change.resourceType !== "secret") return null;
|
||||||
|
|
||||||
if (change.type === "create") {
|
if (change.type === PendingAction.Create) {
|
||||||
return (
|
return (
|
||||||
<div className="mt-3 overflow-hidden rounded-md border border-mineshaft-700 bg-mineshaft-900">
|
<div className="mt-3 overflow-hidden rounded-md border border-mineshaft-700 bg-mineshaft-900">
|
||||||
<table className="w-full text-sm">
|
<table className="w-full text-sm">
|
||||||
@@ -171,7 +172,7 @@ const ChangeTable: React.FC<ChangeTableProps> = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (change.type === "update") {
|
if (change.type === PendingAction.Update) {
|
||||||
const hasKeyChange = change.newSecretName && change.secretKey !== change.newSecretName;
|
const hasKeyChange = change.newSecretName && change.secretKey !== change.newSecretName;
|
||||||
const hasValueChange = change.secretValue !== change.originalValue;
|
const hasValueChange = change.secretValue !== change.originalValue;
|
||||||
const hasCommentChange = change.secretComment !== change.originalComment;
|
const hasCommentChange = change.secretComment !== change.originalComment;
|
||||||
@@ -252,7 +253,7 @@ const ChangeTable: React.FC<ChangeTableProps> = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (change.type === "delete") {
|
if (change.type === PendingAction.Delete) {
|
||||||
return (
|
return (
|
||||||
<div className="mt-3 overflow-hidden rounded-md border border-mineshaft-700 bg-mineshaft-900">
|
<div className="mt-3 overflow-hidden rounded-md border border-mineshaft-700 bg-mineshaft-900">
|
||||||
<table className="w-full text-sm">
|
<table className="w-full text-sm">
|
||||||
@@ -275,7 +276,7 @@ const ChangeTable: React.FC<ChangeTableProps> = ({
|
|||||||
const renderFolderChanges = () => {
|
const renderFolderChanges = () => {
|
||||||
if (change.resourceType !== "folder") return null;
|
if (change.resourceType !== "folder") return null;
|
||||||
|
|
||||||
if (change.type === "create") {
|
if (change.type === PendingAction.Create) {
|
||||||
return (
|
return (
|
||||||
<div className="mt-3 overflow-hidden rounded-md border border-mineshaft-700 bg-mineshaft-900">
|
<div className="mt-3 overflow-hidden rounded-md border border-mineshaft-700 bg-mineshaft-900">
|
||||||
<table className="w-full text-sm">
|
<table className="w-full text-sm">
|
||||||
@@ -300,7 +301,7 @@ const ChangeTable: React.FC<ChangeTableProps> = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (change.type === "update") {
|
if (change.type === PendingAction.Update) {
|
||||||
const hasNameChange = change.folderName !== change.originalFolderName;
|
const hasNameChange = change.folderName !== change.originalFolderName;
|
||||||
const hasDescriptionChange = change.description !== change.originalDescription;
|
const hasDescriptionChange = change.description !== change.originalDescription;
|
||||||
|
|
||||||
@@ -334,7 +335,7 @@ const ChangeTable: React.FC<ChangeTableProps> = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (change.type === "delete") {
|
if (change.type === PendingAction.Delete) {
|
||||||
return (
|
return (
|
||||||
<div className="mt-3 overflow-hidden rounded-md border border-mineshaft-700 bg-mineshaft-900">
|
<div className="mt-3 overflow-hidden rounded-md border border-mineshaft-700 bg-mineshaft-900">
|
||||||
<table className="w-full text-sm">
|
<table className="w-full text-sm">
|
||||||
@@ -356,10 +357,12 @@ const ChangeTable: React.FC<ChangeTableProps> = ({
|
|||||||
|
|
||||||
const getChangeName = () => {
|
const getChangeName = () => {
|
||||||
if (change.resourceType === "secret") {
|
if (change.resourceType === "secret") {
|
||||||
return change.type === "update" ? change.newSecretName || change.secretKey : change.secretKey;
|
return change.type === PendingAction.Update
|
||||||
|
? change.newSecretName || change.secretKey
|
||||||
|
: change.secretKey;
|
||||||
}
|
}
|
||||||
if (change.resourceType === "folder") {
|
if (change.resourceType === "folder") {
|
||||||
return change.type === "update" ? change.originalFolderName : change.folderName;
|
return change.type === PendingAction.Update ? change.originalFolderName : change.folderName;
|
||||||
}
|
}
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
};
|
};
|
||||||
@@ -417,19 +420,14 @@ export const CommitForm: React.FC<CommitFormProps> = ({
|
|||||||
if (!commitMessage.trim()) {
|
if (!commitMessage.trim()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
await onCommit(pendingChanges, commitMessage);
|
||||||
try {
|
clearAllPendingChanges({
|
||||||
await onCommit(pendingChanges, commitMessage);
|
workspaceId,
|
||||||
clearAllPendingChanges({
|
environment,
|
||||||
workspaceId,
|
secretPath
|
||||||
environment,
|
});
|
||||||
secretPath
|
setIsModalOpen(false);
|
||||||
});
|
setCommitMessage("");
|
||||||
setIsModalOpen(false);
|
|
||||||
setCommitMessage("");
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Failed to commit changes:", error);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
+2
-1
@@ -12,6 +12,7 @@ import { InfisicalSecretInput } from "@app/components/v2/InfisicalSecretInput";
|
|||||||
import { ProjectPermissionActions, ProjectPermissionSub, useProjectPermission } from "@app/context";
|
import { ProjectPermissionActions, ProjectPermissionSub, useProjectPermission } from "@app/context";
|
||||||
import { getKeyValue } from "@app/helpers/parseEnvVar";
|
import { getKeyValue } from "@app/helpers/parseEnvVar";
|
||||||
import { useCreateSecretV3, useCreateWsTag, useGetWsTags } from "@app/hooks/api";
|
import { useCreateSecretV3, useCreateWsTag, useGetWsTags } from "@app/hooks/api";
|
||||||
|
import { PendingAction } from "@app/hooks/api/secretFolders/types";
|
||||||
import { SecretType } from "@app/hooks/api/types";
|
import { SecretType } from "@app/hooks/api/types";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -96,7 +97,7 @@ export const CreateSecretForm = ({
|
|||||||
if (isBatchMode) {
|
if (isBatchMode) {
|
||||||
const pendingSecretCreate: PendingSecretCreate = {
|
const pendingSecretCreate: PendingSecretCreate = {
|
||||||
id: key,
|
id: key,
|
||||||
type: "create",
|
type: PendingAction.Create,
|
||||||
secretKey: key,
|
secretKey: key,
|
||||||
secretValue: value || "",
|
secretValue: value || "",
|
||||||
secretComment: "",
|
secretComment: "",
|
||||||
|
|||||||
+11
-9
@@ -12,7 +12,7 @@ import { ROUTE_PATHS } from "@app/const/routes";
|
|||||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
|
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
|
||||||
import { usePopUp } from "@app/hooks";
|
import { usePopUp } from "@app/hooks";
|
||||||
import { useDeleteFolder, useUpdateFolder } from "@app/hooks/api";
|
import { useDeleteFolder, useUpdateFolder } from "@app/hooks/api";
|
||||||
import { TSecretFolder } from "@app/hooks/api/secretFolders/types";
|
import { PendingAction, TSecretFolder } from "@app/hooks/api/secretFolders/types";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
PendingFolderCreate,
|
PendingFolderCreate,
|
||||||
@@ -60,15 +60,17 @@ export const FolderListView = ({
|
|||||||
oldFolderDescription?: string
|
oldFolderDescription?: string
|
||||||
) => {
|
) => {
|
||||||
try {
|
try {
|
||||||
const { id: folderId, pendingAction, isPending } = popUp.updateFolder.data as TSecretFolder;
|
const updateFolderData = popUp.updateFolder.data;
|
||||||
|
if (!updateFolderData) throw new Error("Update folder data is required");
|
||||||
|
const { id: folderId, pendingAction, isPending } = updateFolderData as TSecretFolder;
|
||||||
|
|
||||||
if (isBatchMode) {
|
if (isBatchMode) {
|
||||||
const isEditingPendingCreation = isPending && pendingAction === "create";
|
const isEditingPendingCreation = isPending && pendingAction === PendingAction.Create;
|
||||||
|
|
||||||
if (isEditingPendingCreation) {
|
if (isEditingPendingCreation) {
|
||||||
const updatedCreate: PendingFolderCreate = {
|
const updatedCreate: PendingFolderCreate = {
|
||||||
id: folderId,
|
id: folderId,
|
||||||
type: "create",
|
type: PendingAction.Create,
|
||||||
folderName: newFolderName,
|
folderName: newFolderName,
|
||||||
description: newFolderDescription || undefined,
|
description: newFolderDescription || undefined,
|
||||||
parentPath: secretPath,
|
parentPath: secretPath,
|
||||||
@@ -84,7 +86,7 @@ export const FolderListView = ({
|
|||||||
} else {
|
} else {
|
||||||
const updateChange: PendingFolderUpdate = {
|
const updateChange: PendingFolderUpdate = {
|
||||||
id: folderId,
|
id: folderId,
|
||||||
type: "update",
|
type: PendingAction.Update,
|
||||||
originalFolderName: oldFolderName || "",
|
originalFolderName: oldFolderName || "",
|
||||||
folderName: newFolderName,
|
folderName: newFolderName,
|
||||||
originalDescription: oldFolderDescription,
|
originalDescription: oldFolderDescription,
|
||||||
@@ -144,7 +146,7 @@ export const FolderListView = ({
|
|||||||
folderName: folderData.name,
|
folderName: folderData.name,
|
||||||
folderPath: secretPath,
|
folderPath: secretPath,
|
||||||
resourceType: "folder",
|
resourceType: "folder",
|
||||||
type: "delete",
|
type: PendingAction.Delete,
|
||||||
timestamp: Date.now()
|
timestamp: Date.now()
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -197,9 +199,9 @@ export const FolderListView = ({
|
|||||||
className={twMerge(
|
className={twMerge(
|
||||||
"group flex cursor-pointer border-b border-mineshaft-600 hover:bg-mineshaft-700",
|
"group flex cursor-pointer border-b border-mineshaft-600 hover:bg-mineshaft-700",
|
||||||
isPending && "bg-mineshaft-700/60",
|
isPending && "bg-mineshaft-700/60",
|
||||||
pendingAction === "delete" && "border-l-2 border-l-red-600/75",
|
pendingAction === PendingAction.Delete && "border-l-2 border-l-red-600/75",
|
||||||
pendingAction === "update" && "border-l-2 border-l-yellow-600/75",
|
pendingAction === PendingAction.Update && "border-l-2 border-l-yellow-600/75",
|
||||||
pendingAction === "create" && "border-l-2 border-l-green-600/75"
|
pendingAction === PendingAction.Create && "border-l-2 border-l-green-600/75"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="flex w-11 items-center px-5 py-3 text-yellow-700">
|
<div className="flex w-11 items-center px-5 py-3 text-yellow-700">
|
||||||
|
|||||||
+10
-8
@@ -50,6 +50,7 @@ import { ProjectPermissionSecretActions } from "@app/context/ProjectPermissionCo
|
|||||||
import { hasSecretReadValueOrDescribePermission } from "@app/lib/fn/permission";
|
import { hasSecretReadValueOrDescribePermission } from "@app/lib/fn/permission";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { faEyeSlash, faKey, faRotate } from "@fortawesome/free-solid-svg-icons";
|
import { faEyeSlash, faKey, faRotate } from "@fortawesome/free-solid-svg-icons";
|
||||||
|
import { PendingAction } from "@app/hooks/api/secretFolders/types";
|
||||||
import {
|
import {
|
||||||
FontAwesomeSpriteName,
|
FontAwesomeSpriteName,
|
||||||
formSchema,
|
formSchema,
|
||||||
@@ -88,7 +89,7 @@ type Props = {
|
|||||||
}[];
|
}[];
|
||||||
}[];
|
}[];
|
||||||
isPending?: boolean;
|
isPending?: boolean;
|
||||||
pendingAction?: "create" | "update" | "delete";
|
pendingAction?: PendingAction;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SecretItem = memo(
|
export const SecretItem = memo(
|
||||||
@@ -201,6 +202,8 @@ export const SecretItem = memo(
|
|||||||
secretTags: selectedTagSlugs
|
secretTags: selectedTagSlugs
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
const isReadOnlySecret =
|
||||||
|
isReadOnly || isRotatedSecret || (isPending && pendingAction !== PendingAction.Update);
|
||||||
|
|
||||||
const { secretValueHidden } = secret;
|
const { secretValueHidden } = secret;
|
||||||
|
|
||||||
@@ -289,9 +292,9 @@ export const SecretItem = memo(
|
|||||||
isDirty && "border-primary-400/50",
|
isDirty && "border-primary-400/50",
|
||||||
isRotatedSecret && "bg-mineshaft-700/60",
|
isRotatedSecret && "bg-mineshaft-700/60",
|
||||||
isPending && "bg-mineshaft-700/60",
|
isPending && "bg-mineshaft-700/60",
|
||||||
pendingAction === "delete" && "border-l-2 border-l-red-600/75",
|
pendingAction === PendingAction.Delete && "border-l-2 border-l-red-600/75",
|
||||||
pendingAction === "update" && "border-l-2 border-l-yellow-600/75",
|
pendingAction === PendingAction.Update && "border-l-2 border-l-yellow-600/75",
|
||||||
pendingAction === "create" && "border-l-2 border-l-green-600/75"
|
pendingAction === PendingAction.Create && "border-l-2 border-l-green-600/75"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="group flex">
|
<div className="group flex">
|
||||||
@@ -383,9 +386,7 @@ export const SecretItem = memo(
|
|||||||
control={control}
|
control={control}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<InfisicalSecretInput
|
<InfisicalSecretInput
|
||||||
isReadOnly={
|
isReadOnly={isReadOnlySecret}
|
||||||
isReadOnly || isRotatedSecret || (isPending && pendingAction !== "update")
|
|
||||||
}
|
|
||||||
key="secret-value"
|
key="secret-value"
|
||||||
isVisible={isVisible && !secretValueHidden}
|
isVisible={isVisible && !secretValueHidden}
|
||||||
canEditButNotView={secretValueHidden && !isOverriden}
|
canEditButNotView={secretValueHidden && !isOverriden}
|
||||||
@@ -398,7 +399,8 @@ export const SecretItem = memo(
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{pendingAction !== "create" && pendingAction !== "delete" && (
|
{/* Only allow to open the side panel if the secret is not in a pending create or delete state */}
|
||||||
|
{pendingAction !== PendingAction.Create && pendingAction !== PendingAction.Delete && (
|
||||||
<div
|
<div
|
||||||
key="actions"
|
key="actions"
|
||||||
className="flex h-full flex-shrink-0 self-start transition-all group-hover:gap-x-2"
|
className="flex h-full flex-shrink-0 self-start transition-all group-hover:gap-x-2"
|
||||||
|
|||||||
+5
-4
@@ -11,6 +11,7 @@ import { dashboardKeys } from "@app/hooks/api/dashboard/queries";
|
|||||||
import { UsedBySecretSyncs } from "@app/hooks/api/dashboard/types";
|
import { UsedBySecretSyncs } from "@app/hooks/api/dashboard/types";
|
||||||
import { commitKeys } from "@app/hooks/api/folderCommits/queries";
|
import { commitKeys } from "@app/hooks/api/folderCommits/queries";
|
||||||
import { secretApprovalRequestKeys } from "@app/hooks/api/secretApprovalRequest/queries";
|
import { secretApprovalRequestKeys } from "@app/hooks/api/secretApprovalRequest/queries";
|
||||||
|
import { PendingAction } from "@app/hooks/api/secretFolders/types";
|
||||||
import { secretKeys } from "@app/hooks/api/secrets/queries";
|
import { secretKeys } from "@app/hooks/api/secrets/queries";
|
||||||
import { SecretType, SecretV3RawSanitized } from "@app/hooks/api/secrets/types";
|
import { SecretType, SecretV3RawSanitized } from "@app/hooks/api/secrets/types";
|
||||||
import { secretSnapshotKeys } from "@app/hooks/api/secretSnapshots/queries";
|
import { secretSnapshotKeys } from "@app/hooks/api/secretSnapshots/queries";
|
||||||
@@ -300,12 +301,12 @@ export const SecretListView = ({
|
|||||||
// shared secret change
|
// shared secret change
|
||||||
if (!isSharedSecUnchanged && !personalAction) {
|
if (!isSharedSecUnchanged && !personalAction) {
|
||||||
if (isBatchMode) {
|
if (isBatchMode) {
|
||||||
const isEditingPendingCreation = isPending && pendingAction === "create";
|
const isEditingPendingCreation = isPending && pendingAction === PendingAction.Create;
|
||||||
|
|
||||||
if (isEditingPendingCreation) {
|
if (isEditingPendingCreation) {
|
||||||
const updatedCreate: PendingSecretCreate = {
|
const updatedCreate: PendingSecretCreate = {
|
||||||
id: orgSecret.id,
|
id: orgSecret.id,
|
||||||
type: "create",
|
type: PendingAction.Create,
|
||||||
secretKey: key,
|
secretKey: key,
|
||||||
secretValue: value || "",
|
secretValue: value || "",
|
||||||
secretComment: comment || "",
|
secretComment: comment || "",
|
||||||
@@ -327,7 +328,7 @@ export const SecretListView = ({
|
|||||||
|
|
||||||
const updateChange: PendingSecretUpdate = {
|
const updateChange: PendingSecretUpdate = {
|
||||||
id: orgSecret.id,
|
id: orgSecret.id,
|
||||||
type: "update",
|
type: PendingAction.Update,
|
||||||
secretKey: trueOriginalSecret.key,
|
secretKey: trueOriginalSecret.key,
|
||||||
...(key !== trueOriginalSecret.key && { newSecretName: key }),
|
...(key !== trueOriginalSecret.key && { newSecretName: key }),
|
||||||
...(value !== trueOriginalSecret.value && {
|
...(value !== trueOriginalSecret.value && {
|
||||||
@@ -457,7 +458,7 @@ export const SecretListView = ({
|
|||||||
if (isBatchMode) {
|
if (isBatchMode) {
|
||||||
const deleteChange: PendingSecretDelete = {
|
const deleteChange: PendingSecretDelete = {
|
||||||
id: `${secretId}`,
|
id: `${secretId}`,
|
||||||
type: "delete",
|
type: PendingAction.Delete,
|
||||||
secretKey: key,
|
secretKey: key,
|
||||||
secretValue: value || "",
|
secretValue: value || "",
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
|
|||||||
Reference in New Issue
Block a user