mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Fix tag and metadata insert/update logic on revert/rollback and fix tree checkpoint logic to exclude reserved folders
This commit is contained in:
@@ -17,8 +17,10 @@ import { kmsRootConfigDALFactory } from "@app/services/kms/kms-root-config-dal";
|
||||
import { kmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
import { orgDALFactory } from "@app/services/org/org-dal";
|
||||
import { projectDALFactory } from "@app/services/project/project-dal";
|
||||
import { resourceMetadataDALFactory } from "@app/services/resource-metadata/resource-metadata-dal";
|
||||
import { secretFolderDALFactory } from "@app/services/secret-folder/secret-folder-dal";
|
||||
import { secretFolderVersionDALFactory } from "@app/services/secret-folder/secret-folder-version-dal";
|
||||
import { secretTagDALFactory } from "@app/services/secret-tag/secret-tag-dal";
|
||||
import { secretV2BridgeDALFactory } from "@app/services/secret-v2-bridge/secret-v2-bridge-dal";
|
||||
import { secretVersionV2BridgeDALFactory } from "@app/services/secret-v2-bridge/secret-version-dal";
|
||||
import { userDALFactory } from "@app/services/user/user-dal";
|
||||
@@ -86,11 +88,13 @@ export const getMigrationPITServices = async ({
|
||||
const folderCheckpointResourcesDAL = folderCheckpointResourcesDALFactory(db);
|
||||
const secretV2BridgeDAL = secretV2BridgeDALFactory({ db, keyStore });
|
||||
const folderTreeCheckpointResourcesDAL = folderTreeCheckpointResourcesDALFactory(db);
|
||||
const secretTagDAL = secretTagDALFactory(db);
|
||||
|
||||
const orgDAL = orgDALFactory(db);
|
||||
const kmsRootConfigDAL = kmsRootConfigDALFactory(db);
|
||||
const kmsDAL = kmskeyDALFactory(db);
|
||||
const internalKmsDAL = internalKmsDALFactory(db);
|
||||
const resourceMetadataDAL = resourceMetadataDALFactory(db);
|
||||
|
||||
const hsmModule = initializeHsmModule(envConfig);
|
||||
hsmModule.initialize();
|
||||
@@ -128,7 +132,9 @@ export const getMigrationPITServices = async ({
|
||||
folderCheckpointResourcesDAL,
|
||||
secretV2BridgeDAL,
|
||||
folderTreeCheckpointResourcesDAL,
|
||||
kmsService
|
||||
kmsService,
|
||||
secretTagDAL,
|
||||
resourceMetadataDAL
|
||||
});
|
||||
|
||||
return { folderCommitService };
|
||||
|
||||
@@ -202,7 +202,7 @@ export const registerPITRouter = async (server: FastifyZodProvider) => {
|
||||
}),
|
||||
querystring: z.object({
|
||||
folderId: z.string().trim(),
|
||||
envId: z.string().trim(),
|
||||
environment: z.string().trim(),
|
||||
deepRollback: booleanSchema.default(false),
|
||||
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||
projectId: z.string().trim()
|
||||
@@ -228,7 +228,7 @@ export const registerPITRouter = async (server: FastifyZodProvider) => {
|
||||
projectId: req.query.projectId,
|
||||
commitId: req.params.commitId,
|
||||
folderId: req.query.folderId,
|
||||
envId: req.query.envId,
|
||||
environment: req.query.environment,
|
||||
deepRollback: req.query.deepRollback,
|
||||
secretPath: req.query.secretPath
|
||||
});
|
||||
@@ -243,7 +243,7 @@ export const registerPITRouter = async (server: FastifyZodProvider) => {
|
||||
folderId: req.query.folderId,
|
||||
deepRollback: req.query.deepRollback,
|
||||
diffsCount: result.length.toString(),
|
||||
env: req.query.envId,
|
||||
environment: req.query.environment,
|
||||
folderPath: req.query.secretPath
|
||||
}
|
||||
}
|
||||
@@ -268,7 +268,7 @@ export const registerPITRouter = async (server: FastifyZodProvider) => {
|
||||
folderId: z.string().trim(),
|
||||
deepRollback: z.boolean().default(false),
|
||||
message: z.string().max(256).trim().optional(),
|
||||
envId: z.string().trim(),
|
||||
environment: z.string().trim(),
|
||||
projectId: z.string().trim()
|
||||
}),
|
||||
response: {
|
||||
@@ -292,7 +292,7 @@ export const registerPITRouter = async (server: FastifyZodProvider) => {
|
||||
folderId: req.body.folderId,
|
||||
deepRollback: req.body.deepRollback,
|
||||
message: req.body.message,
|
||||
envId: req.body.envId
|
||||
environment: req.body.environment
|
||||
});
|
||||
|
||||
await server.services.auditLog.createAuditLog({
|
||||
@@ -302,7 +302,7 @@ export const registerPITRouter = async (server: FastifyZodProvider) => {
|
||||
type: EventType.PIT_ROLLBACK_COMMIT,
|
||||
metadata: {
|
||||
targetCommitId: req.params.commitId,
|
||||
envId: req.body.envId,
|
||||
environment: req.body.environment,
|
||||
folderId: req.body.folderId,
|
||||
deepRollback: req.body.deepRollback,
|
||||
message: req.body.message || "Rollback to previous commit",
|
||||
|
||||
@@ -2959,7 +2959,7 @@ interface PitRollbackCommitEvent {
|
||||
deepRollback: boolean;
|
||||
message: string;
|
||||
totalChanges: string;
|
||||
envId: string;
|
||||
environment: string;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2988,7 +2988,7 @@ interface PitCompareFolderStatesEvent {
|
||||
folderId: string;
|
||||
deepRollback: boolean;
|
||||
diffsCount: string;
|
||||
env: string;
|
||||
environment: string;
|
||||
folderPath: string;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
isFolderCommitChange,
|
||||
isSecretCommitChange
|
||||
} from "@app/services/folder-commit-changes/folder-commit-changes-dal";
|
||||
import { TProjectEnvDALFactory } from "@app/services/project-env/project-env-dal";
|
||||
import { TSecretServiceFactory } from "@app/services/secret/secret-service";
|
||||
import { TSecretFolderDALFactory } from "@app/services/secret-folder/secret-folder-dal";
|
||||
import { TSecretFolderServiceFactory } from "@app/services/secret-folder/secret-folder-service";
|
||||
@@ -23,6 +24,7 @@ type TPitServiceFactoryDep = {
|
||||
folderService: Pick<TSecretFolderServiceFactory, "getFolderById" | "getFolderVersions">;
|
||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||
folderDAL: Pick<TSecretFolderDALFactory, "findSecretPathByFolderIds">;
|
||||
projectEnvDAL: Pick<TProjectEnvDALFactory, "findOne">;
|
||||
};
|
||||
|
||||
export type TPitServiceFactory = ReturnType<typeof pitServiceFactory>;
|
||||
@@ -32,7 +34,8 @@ export const pitServiceFactory = ({
|
||||
secretService,
|
||||
folderService,
|
||||
permissionService,
|
||||
folderDAL
|
||||
folderDAL,
|
||||
projectEnvDAL
|
||||
}: TPitServiceFactoryDep) => {
|
||||
const getCommitsCount = async ({
|
||||
actor,
|
||||
@@ -183,7 +186,7 @@ export const pitServiceFactory = ({
|
||||
projectId,
|
||||
commitId,
|
||||
folderId,
|
||||
envId,
|
||||
environment,
|
||||
deepRollback,
|
||||
secretPath
|
||||
}: {
|
||||
@@ -194,7 +197,7 @@ export const pitServiceFactory = ({
|
||||
projectId: string;
|
||||
commitId: string;
|
||||
folderId: string;
|
||||
envId: string;
|
||||
environment: string;
|
||||
deepRollback: boolean;
|
||||
secretPath: string;
|
||||
}) => {
|
||||
@@ -216,6 +219,11 @@ export const pitServiceFactory = ({
|
||||
projectId
|
||||
});
|
||||
|
||||
const env = await projectEnvDAL.findOne({
|
||||
projectId,
|
||||
slug: environment
|
||||
});
|
||||
|
||||
if (!latestCommit) {
|
||||
throw new NotFoundError({ message: "Latest commit not found" });
|
||||
}
|
||||
@@ -224,7 +232,7 @@ export const pitServiceFactory = ({
|
||||
if (deepRollback) {
|
||||
diffs = await folderCommitService.deepCompareFolder({
|
||||
targetCommitId: targetCommit.id,
|
||||
envId,
|
||||
envId: env.id,
|
||||
projectId
|
||||
});
|
||||
} else {
|
||||
@@ -268,7 +276,7 @@ export const pitServiceFactory = ({
|
||||
actor,
|
||||
actorOrgId,
|
||||
actorAuthMethod,
|
||||
envId,
|
||||
env.id,
|
||||
projectId,
|
||||
diff.folderPath || ""
|
||||
);
|
||||
@@ -295,7 +303,7 @@ export const pitServiceFactory = ({
|
||||
folderId,
|
||||
deepRollback,
|
||||
message,
|
||||
envId
|
||||
environment
|
||||
}: {
|
||||
actor: ActorType;
|
||||
actorId: string;
|
||||
@@ -306,7 +314,7 @@ export const pitServiceFactory = ({
|
||||
folderId: string;
|
||||
deepRollback: boolean;
|
||||
message?: string;
|
||||
envId: string;
|
||||
environment: string;
|
||||
}) => {
|
||||
const { permission: userPermission } = await permissionService.getProjectPermission({
|
||||
actor,
|
||||
@@ -346,16 +354,21 @@ export const pitServiceFactory = ({
|
||||
projectId
|
||||
});
|
||||
|
||||
if (!targetCommit || targetCommit.folderId !== folderId || targetCommit.envId !== envId) {
|
||||
const env = await projectEnvDAL.findOne({
|
||||
projectId,
|
||||
slug: environment
|
||||
});
|
||||
|
||||
if (!targetCommit || targetCommit.folderId !== folderId || targetCommit.envId !== env.id) {
|
||||
throw new NotFoundError({ message: "Target commit not found" });
|
||||
}
|
||||
|
||||
if (!latestCommit || latestCommit.envId !== envId) {
|
||||
if (!latestCommit || latestCommit.envId !== env.id) {
|
||||
throw new NotFoundError({ message: "Latest commit not found" });
|
||||
}
|
||||
|
||||
if (deepRollback) {
|
||||
await folderCommitService.deepRollbackFolder(commitId, envId, actorId, actor, projectId, message);
|
||||
await folderCommitService.deepRollbackFolder(commitId, env.id, actorId, actor, projectId, message);
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
@@ -426,20 +439,6 @@ export const pitServiceFactory = ({
|
||||
projectId: string;
|
||||
commitId: string;
|
||||
}) => {
|
||||
const { permission: userPermission } = await permissionService.getProjectPermission({
|
||||
actor,
|
||||
actorId,
|
||||
projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
|
||||
ForbiddenError.from(userPermission).throwUnlessCan(
|
||||
ProjectPermissionCommitsActions.Read,
|
||||
ProjectPermissionSub.Commits
|
||||
);
|
||||
|
||||
const commit = await folderCommitService.getCommitById({
|
||||
commitId,
|
||||
actor,
|
||||
|
||||
@@ -422,7 +422,7 @@ export const secretReplicationServiceFactory = ({
|
||||
return {
|
||||
op: operation,
|
||||
requestId: approvalRequestDoc.id,
|
||||
metadata: doc.metadata,
|
||||
metadata: doc.metadata ? JSON.stringify(doc.metadata) : [],
|
||||
secretMetadata: JSON.stringify(doc.secretMetadata),
|
||||
key: doc.key,
|
||||
encryptedValue: doc.encryptedValue,
|
||||
@@ -454,7 +454,7 @@ export const secretReplicationServiceFactory = ({
|
||||
inputSecrets: locallyCreatedSecrets.map((doc) => {
|
||||
return {
|
||||
type: doc.type,
|
||||
metadata: doc.metadata,
|
||||
metadata: doc.metadata ? JSON.stringify(doc.metadata) : [],
|
||||
key: doc.key,
|
||||
encryptedValue: doc.encryptedValue,
|
||||
encryptedComment: doc.encryptedComment,
|
||||
@@ -484,7 +484,7 @@ export const secretReplicationServiceFactory = ({
|
||||
},
|
||||
data: {
|
||||
type: doc.type,
|
||||
metadata: doc.metadata,
|
||||
metadata: doc.metadata ? JSON.stringify(doc.metadata) : [],
|
||||
key: doc.key,
|
||||
encryptedValue: doc.encryptedValue as Buffer,
|
||||
encryptedComment: doc.encryptedComment,
|
||||
|
||||
@@ -599,7 +599,9 @@ export const registerRoutes = async (
|
||||
folderTreeCheckpointResourcesDAL,
|
||||
folderCommitQueueService,
|
||||
permissionService,
|
||||
kmsService
|
||||
kmsService,
|
||||
secretTagDAL,
|
||||
resourceMetadataDAL
|
||||
});
|
||||
const scimService = scimServiceFactory({
|
||||
licenseService,
|
||||
@@ -1527,7 +1529,8 @@ export const registerRoutes = async (
|
||||
secretService,
|
||||
folderService,
|
||||
permissionService,
|
||||
folderDAL
|
||||
folderDAL,
|
||||
projectEnvDAL
|
||||
});
|
||||
|
||||
const identityOidcAuthService = identityOidcAuthServiceFactory({
|
||||
|
||||
@@ -153,6 +153,20 @@ describe("folderCommitServiceFactory", () => {
|
||||
getProjectPermission: vi.fn().mockResolvedValue({})
|
||||
};
|
||||
|
||||
const mockSecretTagDAL = {
|
||||
findSecretTagsByVersionId: vi.fn().mockResolvedValue([]),
|
||||
saveTagsToSecretV2: vi.fn().mockResolvedValue([]),
|
||||
findSecretTagsBySecretId: vi.fn().mockResolvedValue([]),
|
||||
deleteTagsToSecretV2: vi.fn().mockResolvedValue([]),
|
||||
saveTagsToSecretVersionV2: vi.fn().mockResolvedValue([])
|
||||
};
|
||||
|
||||
const mockResourceMetadataDAL = {
|
||||
find: vi.fn().mockResolvedValue([]),
|
||||
insertMany: vi.fn().mockResolvedValue([]),
|
||||
delete: vi.fn().mockResolvedValue([])
|
||||
};
|
||||
|
||||
let folderCommitService: TFolderCommitServiceFactory;
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -187,7 +201,9 @@ describe("folderCommitServiceFactory", () => {
|
||||
folderCommitQueueService: mockFolderCommitQueueService,
|
||||
// @ts-expect-error - Mock implementation doesn't need all interface methods for testing
|
||||
permissionService: mockPermissionService,
|
||||
kmsService: mockKmsService
|
||||
kmsService: mockKmsService,
|
||||
secretTagDAL: mockSecretTagDAL,
|
||||
resourceMetadataDAL: mockResourceMetadataDAL
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -2,7 +2,13 @@
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
import { Knex } from "knex";
|
||||
|
||||
import { ActionProjectType, TSecretFolders, TSecretFolderVersions, TSecretVersionsV2 } from "@app/db/schemas";
|
||||
import {
|
||||
ActionProjectType,
|
||||
TSecretFolders,
|
||||
TSecretFolderVersions,
|
||||
TSecretV2TagJunctionInsert,
|
||||
TSecretVersionsV2
|
||||
} from "@app/db/schemas";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import { ProjectPermissionCommitsActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
@@ -20,8 +26,10 @@ import { TIdentityDALFactory } from "../identity/identity-dal";
|
||||
import { TKmsServiceFactory } from "../kms/kms-service";
|
||||
import { KmsDataKey } from "../kms/kms-types";
|
||||
import { TProjectDALFactory } from "../project/project-dal";
|
||||
import { TResourceMetadataDALFactory } from "../resource-metadata/resource-metadata-dal";
|
||||
import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal";
|
||||
import { TSecretFolderVersionDALFactory } from "../secret-folder/secret-folder-version-dal";
|
||||
import { TSecretTagDALFactory } from "../secret-tag/secret-tag-dal";
|
||||
import * as secretV2BridgeDal from "../secret-v2-bridge/secret-v2-bridge-dal";
|
||||
import { TSecretVersionV2DALFactory } from "../secret-v2-bridge/secret-version-dal";
|
||||
import { TUserDALFactory } from "../user/user-dal";
|
||||
@@ -143,6 +151,15 @@ type TFolderCommitServiceFactoryDep = {
|
||||
>;
|
||||
permissionService?: TPermissionServiceFactory;
|
||||
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
|
||||
secretTagDAL: Pick<
|
||||
TSecretTagDALFactory,
|
||||
| "findSecretTagsByVersionId"
|
||||
| "saveTagsToSecretV2"
|
||||
| "findSecretTagsBySecretId"
|
||||
| "deleteTagsToSecretV2"
|
||||
| "saveTagsToSecretVersionV2"
|
||||
>;
|
||||
resourceMetadataDAL: Pick<TResourceMetadataDALFactory, "find" | "insertMany" | "delete">;
|
||||
};
|
||||
|
||||
export const folderCommitServiceFactory = ({
|
||||
@@ -161,7 +178,9 @@ export const folderCommitServiceFactory = ({
|
||||
folderTreeCheckpointResourcesDAL,
|
||||
folderCommitQueueService,
|
||||
permissionService,
|
||||
kmsService
|
||||
kmsService,
|
||||
secretTagDAL,
|
||||
resourceMetadataDAL
|
||||
}: TFolderCommitServiceFactoryDep) => {
|
||||
const appCfg = getConfig();
|
||||
|
||||
@@ -738,6 +757,11 @@ export const folderCommitServiceFactory = ({
|
||||
tx?: Knex
|
||||
) => {
|
||||
const commitChanges = [];
|
||||
const folder = await folderDAL.findById(folderId, tx);
|
||||
if (!folder) {
|
||||
return [];
|
||||
}
|
||||
const project = await projectDAL.findById(folder.projectId, tx);
|
||||
|
||||
// Filter only secret changes using discriminated union
|
||||
const secretChanges = changes.filter(
|
||||
@@ -774,12 +798,25 @@ export const folderCommitServiceFactory = ({
|
||||
encryptedValue: secretVersion.encryptedValue,
|
||||
encryptedComment: secretVersion.encryptedComment,
|
||||
userId: secretVersion.userId,
|
||||
metadata: secretVersion.metadata,
|
||||
folderId
|
||||
}
|
||||
];
|
||||
await secretV2BridgeDAL.insertMany(newSecret, tx);
|
||||
|
||||
const metadata: { key: string; value: string }[] =
|
||||
(secretVersion.metadata as { key: string; value: string }[]) || [];
|
||||
if (metadata.length > 0) {
|
||||
await resourceMetadataDAL.insertMany(
|
||||
metadata.map(({ key, value }) => ({
|
||||
key,
|
||||
value,
|
||||
secretId: change.id,
|
||||
orgId: project.orgId
|
||||
})),
|
||||
tx
|
||||
);
|
||||
}
|
||||
|
||||
const newVersion = await secretVersionV2BridgeDAL.create(
|
||||
{
|
||||
folderId,
|
||||
@@ -792,15 +829,29 @@ export const folderCommitServiceFactory = ({
|
||||
reminderNote: secretVersion.reminderNote,
|
||||
reminderRepeatDays: secretVersion.reminderRepeatDays,
|
||||
userId: secretVersion.userId,
|
||||
metadata: secretVersion.metadata,
|
||||
actorType: actorInfo.actorType,
|
||||
envId: secretVersion.envId,
|
||||
metadata: JSON.stringify(metadata),
|
||||
...(actorInfo.actorType === ActorType.IDENTITY && { identityActorId: actorInfo.actorId }),
|
||||
...(actorInfo.actorType === ActorType.USER && { userActorId: actorInfo.actorId })
|
||||
},
|
||||
tx
|
||||
);
|
||||
|
||||
const secretTagsToBeInsert: TSecretV2TagJunctionInsert[] = [];
|
||||
const secretTags = await secretTagDAL.findSecretTagsByVersionId(secretVersion.id, tx);
|
||||
secretTags.forEach((tag) => {
|
||||
secretTagsToBeInsert.push({ secrets_v2Id: change.id, secret_tagsId: tag.secret_tagsId });
|
||||
});
|
||||
await secretTagDAL.saveTagsToSecretV2(secretTagsToBeInsert, tx);
|
||||
await secretTagDAL.saveTagsToSecretVersionV2(
|
||||
secretTagsToBeInsert.map((tag) => ({
|
||||
secret_tagsId: tag.secret_tagsId,
|
||||
secret_versions_v2Id: newVersion.id
|
||||
})),
|
||||
tx
|
||||
);
|
||||
|
||||
commitChanges.push({
|
||||
type: ChangeType.ADD,
|
||||
secretVersionId: newVersion.id
|
||||
@@ -821,12 +872,26 @@ export const folderCommitServiceFactory = ({
|
||||
reminderRepeatDays: secretVersion?.reminderRepeatDays,
|
||||
encryptedValue: secretVersion?.encryptedValue,
|
||||
encryptedComment: secretVersion?.encryptedComment,
|
||||
userId: secretVersion?.userId,
|
||||
metadata: secretVersion?.metadata
|
||||
userId: secretVersion?.userId
|
||||
},
|
||||
tx
|
||||
);
|
||||
|
||||
const metadata: { key: string; value: string }[] =
|
||||
(secretVersion.metadata as { key: string; value: string }[]) || [];
|
||||
await resourceMetadataDAL.delete({ secretId: change.id }, tx);
|
||||
if (metadata.length > 0) {
|
||||
await resourceMetadataDAL.insertMany(
|
||||
metadata.map(({ key, value }) => ({
|
||||
key,
|
||||
value,
|
||||
secretId: change.id,
|
||||
orgId: project.orgId
|
||||
})),
|
||||
tx
|
||||
);
|
||||
}
|
||||
|
||||
const newVersion = await secretVersionV2BridgeDAL.create(
|
||||
{
|
||||
version: nextVersion,
|
||||
@@ -837,7 +902,7 @@ export const folderCommitServiceFactory = ({
|
||||
reminderNote: secretVersion.reminderNote,
|
||||
reminderRepeatDays: secretVersion.reminderRepeatDays,
|
||||
userId: secretVersion.userId,
|
||||
metadata: secretVersion.metadata,
|
||||
metadata: JSON.stringify(metadata),
|
||||
actorType: actorInfo.actorType,
|
||||
envId: secretVersion.envId,
|
||||
folderId,
|
||||
@@ -848,6 +913,32 @@ export const folderCommitServiceFactory = ({
|
||||
tx
|
||||
);
|
||||
|
||||
let secretTagsToBeInsert: TSecretV2TagJunctionInsert[] = [];
|
||||
const secretTagsToBeDelete: string[] = [];
|
||||
const secretTags = await secretTagDAL.findSecretTagsByVersionId(secretVersion.id, tx);
|
||||
secretTags.forEach((tag) => {
|
||||
secretTagsToBeInsert.push({ secrets_v2Id: change.id, secret_tagsId: tag.secret_tagsId });
|
||||
});
|
||||
const currentTags = await secretTagDAL.findSecretTagsBySecretId(change.id, tx);
|
||||
currentTags.forEach((tag) => {
|
||||
if (!secretTagsToBeInsert.find((t) => t.secret_tagsId === tag.secret_tagsId)) {
|
||||
secretTagsToBeDelete.push(tag.secret_tagsId);
|
||||
secretTagsToBeInsert = secretTagsToBeInsert.filter((t) => t.secret_tagsId !== tag.secret_tagsId);
|
||||
}
|
||||
});
|
||||
await secretTagDAL.saveTagsToSecretV2(secretTagsToBeInsert, tx);
|
||||
await secretTagDAL.saveTagsToSecretVersionV2(
|
||||
secretTagsToBeInsert.map((tag) => ({
|
||||
secret_tagsId: tag.secret_tagsId,
|
||||
secret_versions_v2Id: newVersion.id
|
||||
})),
|
||||
tx
|
||||
);
|
||||
await secretTagDAL.deleteTagsToSecretV2(
|
||||
{ $in: { secret_tagsId: secretTagsToBeDelete }, secrets_v2Id: change.id },
|
||||
tx
|
||||
);
|
||||
|
||||
commitChanges.push({
|
||||
type: ChangeType.ADD,
|
||||
isUpdate: true,
|
||||
@@ -1126,7 +1217,7 @@ export const folderCommitServiceFactory = ({
|
||||
actorOrgId,
|
||||
projectId
|
||||
});
|
||||
return folderCommitDAL.findById(commitId, tx);
|
||||
return folderCommitDAL.findById(commitId, tx, projectId);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -548,6 +548,7 @@ export const secretFolderDALFactory = (db: TDbClient) => {
|
||||
try {
|
||||
const folders = await (tx || db.replicaNode())(TableName.SecretFolder)
|
||||
.where({ envId })
|
||||
.andWhere({ isReserved: false })
|
||||
.select(selectAllTableCols(TableName.SecretFolder));
|
||||
return folders;
|
||||
} catch (error) {
|
||||
|
||||
@@ -11,6 +11,7 @@ export const secretTagDALFactory = (db: TDbClient) => {
|
||||
const secretTagOrm = ormify(db, TableName.SecretTag);
|
||||
const secretJnTagOrm = ormify(db, TableName.JnSecretTag);
|
||||
const secretV2JnTagOrm = ormify(db, TableName.SecretV2JnTag);
|
||||
const secretVersionV2TagOrm = ormify(db, TableName.SecretVersionV2Tag);
|
||||
|
||||
const findManyTagsById = async (projectId: string, ids: string[], tx?: Knex) => {
|
||||
try {
|
||||
@@ -48,14 +49,39 @@ export const secretTagDALFactory = (db: TDbClient) => {
|
||||
}
|
||||
};
|
||||
|
||||
const findSecretTagsByVersionId = async (versionId: string, tx?: Knex) => {
|
||||
try {
|
||||
const tags = await (tx || db.replicaNode())(TableName.SecretVersionV2Tag)
|
||||
.where(`${TableName.SecretVersionV2Tag}.${TableName.SecretVersionV2}Id`, versionId)
|
||||
.select(selectAllTableCols(TableName.SecretVersionV2Tag));
|
||||
return tags;
|
||||
} catch (error) {
|
||||
throw new DatabaseError({ error, name: "Find all by version id" });
|
||||
}
|
||||
};
|
||||
|
||||
const findSecretTagsBySecretId = async (secretId: string, tx?: Knex) => {
|
||||
try {
|
||||
const tags = await (tx || db.replicaNode())(TableName.SecretV2JnTag)
|
||||
.where(`${TableName.SecretV2JnTag}.${TableName.SecretV2}Id`, secretId)
|
||||
.select(selectAllTableCols(TableName.SecretV2JnTag));
|
||||
return tags;
|
||||
} catch (error) {
|
||||
throw new DatabaseError({ error, name: "Find all by secret id" });
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
...secretTagOrm,
|
||||
saveTagsToSecret: secretJnTagOrm.insertMany,
|
||||
deleteTagsToSecret: secretJnTagOrm.delete,
|
||||
saveTagsToSecretV2: secretV2JnTagOrm.batchInsert,
|
||||
deleteTagsToSecretV2: secretV2JnTagOrm.delete,
|
||||
saveTagsToSecretVersionV2: secretVersionV2TagOrm.insertMany,
|
||||
findSecretTagsByProjectId,
|
||||
deleteTagsManySecret,
|
||||
findManyTagsById
|
||||
findManyTagsById,
|
||||
findSecretTagsByVersionId,
|
||||
findSecretTagsBySecretId
|
||||
};
|
||||
};
|
||||
|
||||
@@ -128,7 +128,7 @@ export const fnSecretBulkInsert = async ({
|
||||
userActorId,
|
||||
identityActorId,
|
||||
actorType,
|
||||
metadata: el.metadata ? JSON.stringify(el.metadata) : null,
|
||||
metadata: el.metadata ? JSON.stringify(el.metadata) : [],
|
||||
secretId: newSecretGroupedByKeyName[el.key][0].id
|
||||
})),
|
||||
tx
|
||||
@@ -274,7 +274,7 @@ export const fnSecretBulkUpdate = async ({
|
||||
userId,
|
||||
encryptedComment,
|
||||
version,
|
||||
metadata: metadata ? JSON.stringify(metadata) : null,
|
||||
metadata: metadata ? JSON.stringify(metadata) : [],
|
||||
reminderNote,
|
||||
encryptedValue,
|
||||
reminderRepeatDays,
|
||||
|
||||
@@ -2885,7 +2885,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
envId: string;
|
||||
projectId: string;
|
||||
}) => {
|
||||
const environment = await projectEnvDAL.findOne({ id: envId });
|
||||
const environment = await projectEnvDAL.findOne({ id: envId, projectId });
|
||||
|
||||
const { permission } = await permissionService.getProjectPermission({
|
||||
actor,
|
||||
|
||||
@@ -31,16 +31,16 @@ export const commitKeys = {
|
||||
rollbackPreview: ({
|
||||
folderId,
|
||||
commitId,
|
||||
envId,
|
||||
envSlug,
|
||||
projectId,
|
||||
deepRollback
|
||||
}: {
|
||||
folderId: string;
|
||||
commitId: string;
|
||||
envId: string;
|
||||
envSlug: string;
|
||||
projectId: string;
|
||||
deepRollback: boolean;
|
||||
}) => [{ folderId, commitId, envId, projectId, deepRollback }, "rollback-preview"] as const
|
||||
}) => [{ folderId, commitId, envSlug, projectId, deepRollback }, "rollback-preview"] as const
|
||||
};
|
||||
|
||||
const fetchFolderCommitsCount = async ({
|
||||
@@ -111,7 +111,7 @@ export const fetchCommitDetails = async (workspaceId: string, commitId: string)
|
||||
export const fetchRollbackPreview = async (
|
||||
folderId: string,
|
||||
commitId: string,
|
||||
envId: string,
|
||||
envSlug: string,
|
||||
workspaceId: string,
|
||||
deepRollback: boolean,
|
||||
secretPath: string
|
||||
@@ -121,7 +121,7 @@ export const fetchRollbackPreview = async (
|
||||
{
|
||||
params: {
|
||||
folderId,
|
||||
envId,
|
||||
environment: envSlug,
|
||||
deepRollback,
|
||||
secretPath,
|
||||
projectId: workspaceId
|
||||
@@ -137,7 +137,7 @@ const fetchRollback = async (
|
||||
workspaceId: string,
|
||||
deepRollback: boolean,
|
||||
message?: string,
|
||||
envId?: string
|
||||
envSlug?: string
|
||||
) => {
|
||||
const { data } = await apiRequest.post<{ success: boolean }>(
|
||||
`/api/v1/pit/commits/${commitId}/rollback`,
|
||||
@@ -145,7 +145,7 @@ const fetchRollback = async (
|
||||
folderId,
|
||||
deepRollback,
|
||||
message,
|
||||
envId,
|
||||
environment: envSlug,
|
||||
projectId: workspaceId
|
||||
}
|
||||
);
|
||||
@@ -195,7 +195,7 @@ export const useCommitRollback = ({
|
||||
deepRollback,
|
||||
environment,
|
||||
directory,
|
||||
envId
|
||||
envSlug
|
||||
}: {
|
||||
workspaceId: string;
|
||||
commitId: string;
|
||||
@@ -203,12 +203,12 @@ export const useCommitRollback = ({
|
||||
deepRollback: boolean;
|
||||
environment: string;
|
||||
directory: string;
|
||||
envId: string;
|
||||
envSlug: string;
|
||||
}) => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (message: string) =>
|
||||
fetchRollback(folderId, commitId, workspaceId, deepRollback, message, envId),
|
||||
fetchRollback(folderId, commitId, workspaceId, deepRollback, message, envSlug),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: [
|
||||
@@ -280,15 +280,15 @@ export const useGetCommitDetails = (workspaceId: string, commitId: string) => {
|
||||
export const useGetRollbackPreview = (
|
||||
folderId: string,
|
||||
commitId: string,
|
||||
envId: string,
|
||||
envSlug: string,
|
||||
projectId: string,
|
||||
deepRollback: boolean,
|
||||
secretPath: string
|
||||
) => {
|
||||
return useQuery({
|
||||
queryKey: commitKeys.rollbackPreview({ folderId, commitId, envId, projectId, deepRollback }),
|
||||
queryKey: commitKeys.rollbackPreview({ folderId, commitId, envSlug, projectId, deepRollback }),
|
||||
queryFn: () =>
|
||||
fetchRollbackPreview(folderId, commitId, envId, projectId, deepRollback, secretPath),
|
||||
fetchRollbackPreview(folderId, commitId, envSlug, projectId, deepRollback, secretPath),
|
||||
enabled: Boolean(folderId) && Boolean(commitId)
|
||||
});
|
||||
};
|
||||
|
||||
@@ -127,13 +127,13 @@ export const RollbackPreviewTab = (): JSX.Element => {
|
||||
deepRollback,
|
||||
environment: envSlug,
|
||||
directory: secretPath,
|
||||
envId: currentWorkspace.environments.find((e) => e.slug === envSlug)?.id || ""
|
||||
envSlug
|
||||
});
|
||||
|
||||
const { data: rollbackChangesNested, isLoading } = useGetRollbackPreview(
|
||||
folderId,
|
||||
selectedCommitId,
|
||||
currentWorkspace.environments.find((e) => e.slug === envSlug)?.id || "",
|
||||
envSlug,
|
||||
currentWorkspace.id,
|
||||
deepRollback,
|
||||
secretPath
|
||||
|
||||
Reference in New Issue
Block a user