mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-14 13:22:08 +00:00
PIT: general improvements and fixes
This commit is contained in:
@@ -3,13 +3,15 @@ import { Knex } from "knex";
|
||||
import { inMemoryKeyStore } from "@app/keystore/memory";
|
||||
|
||||
import { ProjectType, TableName } from "../schemas";
|
||||
import { getMigrationEnvConfig } from "./utils/env-config";
|
||||
import { getMigrationPITServices } from "./utils/services";
|
||||
|
||||
export async function up(knex: Knex): Promise<void> {
|
||||
const hasFolderCommitTable = await knex.schema.hasTable(TableName.FolderCommit);
|
||||
if (hasFolderCommitTable) {
|
||||
const keyStore = inMemoryKeyStore();
|
||||
const { folderCommitService } = await getMigrationPITServices({ db: knex, keyStore });
|
||||
const envConfig = getMigrationEnvConfig();
|
||||
const { folderCommitService } = await getMigrationPITServices({ db: knex, keyStore, envConfig });
|
||||
const projects = await knex(TableName.Project).where({ version: 3, type: ProjectType.SecretManager }).select("id");
|
||||
for (const project of projects) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
|
||||
@@ -64,7 +64,15 @@ export const getMigrationEncryptionServices = async ({ envConfig, db, keyStore }
|
||||
return { kmsService };
|
||||
};
|
||||
|
||||
export const getMigrationPITServices = async ({ db, keyStore }: { db: Knex; keyStore: TKeyStoreFactory }) => {
|
||||
export const getMigrationPITServices = async ({
|
||||
db,
|
||||
keyStore,
|
||||
envConfig
|
||||
}: {
|
||||
db: Knex;
|
||||
keyStore: TKeyStoreFactory;
|
||||
envConfig: TMigrationEnvConfig;
|
||||
}) => {
|
||||
const projectDAL = projectDALFactory(db);
|
||||
const folderCommitDAL = folderCommitDALFactory(db);
|
||||
const folderCommitChangesDAL = folderCommitChangesDALFactory(db);
|
||||
@@ -79,6 +87,33 @@ export const getMigrationPITServices = async ({ db, keyStore }: { db: Knex; keyS
|
||||
const secretV2BridgeDAL = secretV2BridgeDALFactory({ db, keyStore });
|
||||
const folderTreeCheckpointResourcesDAL = folderTreeCheckpointResourcesDALFactory(db);
|
||||
|
||||
const orgDAL = orgDALFactory(db);
|
||||
const kmsRootConfigDAL = kmsRootConfigDALFactory(db);
|
||||
const kmsDAL = kmskeyDALFactory(db);
|
||||
const internalKmsDAL = internalKmsDALFactory(db);
|
||||
|
||||
const hsmModule = initializeHsmModule(envConfig);
|
||||
hsmModule.initialize();
|
||||
|
||||
const hsmService = hsmServiceFactory({
|
||||
hsmModule: hsmModule.getModule(),
|
||||
envConfig
|
||||
});
|
||||
|
||||
const kmsService = kmsServiceFactory({
|
||||
kmsRootConfigDAL,
|
||||
keyStore,
|
||||
kmsDAL,
|
||||
internalKmsDAL,
|
||||
orgDAL,
|
||||
projectDAL,
|
||||
hsmService,
|
||||
envConfig
|
||||
});
|
||||
|
||||
await hsmService.startService();
|
||||
await kmsService.startService();
|
||||
|
||||
const folderCommitService = folderCommitServiceFactory({
|
||||
folderCommitDAL,
|
||||
folderCommitChangesDAL,
|
||||
@@ -92,7 +127,8 @@ export const getMigrationPITServices = async ({ db, keyStore }: { db: Knex; keyS
|
||||
projectDAL,
|
||||
folderCheckpointResourcesDAL,
|
||||
secretV2BridgeDAL,
|
||||
folderTreeCheckpointResourcesDAL
|
||||
folderTreeCheckpointResourcesDAL,
|
||||
kmsService
|
||||
});
|
||||
|
||||
return { folderCommitService };
|
||||
|
||||
@@ -267,7 +267,7 @@ export const registerPITRouter = async (server: FastifyZodProvider) => {
|
||||
body: z.object({
|
||||
folderId: z.string().trim(),
|
||||
deepRollback: z.boolean().default(false),
|
||||
message: z.string().trim().optional(),
|
||||
message: z.string().max(256).trim().optional(),
|
||||
envId: z.string().trim(),
|
||||
projectId: z.string().trim()
|
||||
}),
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
isSecretCommitChange
|
||||
} from "@app/services/folder-commit-changes/folder-commit-changes-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";
|
||||
|
||||
import { TPermissionServiceFactory } from "../permission/permission-service";
|
||||
@@ -21,6 +22,7 @@ type TPitServiceFactoryDep = {
|
||||
secretService: Pick<TSecretServiceFactory, "getSecretVersionsV2ByIds" | "getChangeVersions">;
|
||||
folderService: Pick<TSecretFolderServiceFactory, "getFolderById" | "getFolderVersions">;
|
||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||
folderDAL: Pick<TSecretFolderDALFactory, "findSecretPathByFolderIds">;
|
||||
};
|
||||
|
||||
export type TPitServiceFactory = ReturnType<typeof pitServiceFactory>;
|
||||
@@ -29,7 +31,8 @@ export const pitServiceFactory = ({
|
||||
folderCommitService,
|
||||
secretService,
|
||||
folderService,
|
||||
permissionService
|
||||
permissionService,
|
||||
folderDAL
|
||||
}: TPitServiceFactoryDep) => {
|
||||
const getCommitsCount = async ({
|
||||
actor,
|
||||
@@ -134,6 +137,8 @@ export const pitServiceFactory = ({
|
||||
commitId
|
||||
});
|
||||
|
||||
const [folderWithPath] = await folderDAL.findSecretPathByFolderIds(projectId, [changes.folderId]);
|
||||
|
||||
for (const change of changes.changes) {
|
||||
if (isSecretCommitChange(change)) {
|
||||
change.versions = await secretService.getChangeVersions(
|
||||
@@ -149,7 +154,9 @@ export const pitServiceFactory = ({
|
||||
actor,
|
||||
actorOrgId,
|
||||
actorAuthMethod,
|
||||
change.folderId
|
||||
changes.envId,
|
||||
projectId,
|
||||
folderWithPath?.path || ""
|
||||
);
|
||||
} else if (isFolderCommitChange(change)) {
|
||||
change.versions = await folderService.getFolderVersions(
|
||||
@@ -261,7 +268,9 @@ export const pitServiceFactory = ({
|
||||
actor,
|
||||
actorOrgId,
|
||||
actorAuthMethod,
|
||||
diff.folderId
|
||||
envId,
|
||||
projectId,
|
||||
diff.folderPath || ""
|
||||
);
|
||||
}
|
||||
} else if (change.type === ResourceType.FOLDER) {
|
||||
|
||||
@@ -598,7 +598,8 @@ export const registerRoutes = async (
|
||||
secretV2BridgeDAL,
|
||||
folderTreeCheckpointResourcesDAL,
|
||||
folderCommitQueueService,
|
||||
permissionService
|
||||
permissionService,
|
||||
kmsService
|
||||
});
|
||||
const scimService = scimServiceFactory({
|
||||
licenseService,
|
||||
@@ -1525,7 +1526,8 @@ export const registerRoutes = async (
|
||||
folderCommitService,
|
||||
secretService,
|
||||
folderService,
|
||||
permissionService
|
||||
permissionService,
|
||||
folderDAL
|
||||
});
|
||||
|
||||
const identityOidcAuthService = identityOidcAuthServiceFactory({
|
||||
|
||||
@@ -52,6 +52,7 @@ export type FolderCommitChange = BaseCommitChangeInfo & {
|
||||
folderVersion: string;
|
||||
folderChangeId: string;
|
||||
versions?: {
|
||||
version: string;
|
||||
name?: string;
|
||||
}[];
|
||||
};
|
||||
|
||||
@@ -36,6 +36,7 @@ const secretVersionSchema = z.object({
|
||||
|
||||
// Folder-specific versions schema
|
||||
const folderVersionSchema = z.object({
|
||||
version: z.string().optional(),
|
||||
name: z.string().optional()
|
||||
});
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import { Knex } from "knex";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { TSecretFolderVersions, TSecretVersionsV2 } from "@app/db/schemas";
|
||||
import { ProjectType, TSecretFolderVersions, TSecretVersionsV2 } from "@app/db/schemas";
|
||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||
|
||||
import { ActorType } from "../auth/auth-type";
|
||||
@@ -53,6 +53,10 @@ describe("folderCommitServiceFactory", () => {
|
||||
findLatestCommitByFolderIds: vi.fn().mockResolvedValue({})
|
||||
};
|
||||
|
||||
const mockKmsService = {
|
||||
createCipherPairWithDataKey: vi.fn().mockResolvedValue({})
|
||||
};
|
||||
|
||||
const mockFolderCommitChangesDAL = {
|
||||
create: vi.fn().mockResolvedValue({}),
|
||||
findByCommitId: vi.fn().mockResolvedValue([]),
|
||||
@@ -136,7 +140,8 @@ describe("folderCommitServiceFactory", () => {
|
||||
};
|
||||
|
||||
const mockProjectDAL = {
|
||||
findById: vi.fn().mockResolvedValue({})
|
||||
findById: vi.fn().mockResolvedValue({}),
|
||||
findProjectByEnvId: vi.fn().mockResolvedValue({})
|
||||
};
|
||||
|
||||
const mockFolderCommitQueueService = {
|
||||
@@ -181,7 +186,8 @@ describe("folderCommitServiceFactory", () => {
|
||||
secretV2BridgeDAL: mockSecretV2BridgeDAL,
|
||||
folderCommitQueueService: mockFolderCommitQueueService,
|
||||
// @ts-expect-error - Mock implementation doesn't need all interface methods for testing
|
||||
permissionService: mockPermissionService
|
||||
permissionService: mockPermissionService,
|
||||
kmsService: mockKmsService
|
||||
});
|
||||
});
|
||||
|
||||
@@ -408,6 +414,11 @@ describe("folderCommitServiceFactory", () => {
|
||||
{ folderVersionId: "folder-version-1", referencedFolderId: "folder-1" }
|
||||
]);
|
||||
mockFolderCommitDAL.findCommitsToRecreate.mockResolvedValue([]);
|
||||
mockProjectDAL.findProjectByEnvId.mockResolvedValue({
|
||||
id: "project-id",
|
||||
name: "test-project",
|
||||
type: ProjectType.SecretManager
|
||||
});
|
||||
|
||||
// Act
|
||||
const result = await folderCommitService.compareFolderStates({
|
||||
|
||||
@@ -17,6 +17,8 @@ import { TFolderCommitChangesDALFactory } from "../folder-commit-changes/folder-
|
||||
import { TFolderTreeCheckpointDALFactory } from "../folder-tree-checkpoint/folder-tree-checkpoint-dal";
|
||||
import { TFolderTreeCheckpointResourcesDALFactory } from "../folder-tree-checkpoint-resources/folder-tree-checkpoint-resources-dal";
|
||||
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 { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal";
|
||||
import { TSecretFolderVersionDALFactory } from "../secret-folder/secret-folder-version-dal";
|
||||
@@ -80,7 +82,7 @@ type BaseChange = {
|
||||
fromVersion?: string;
|
||||
};
|
||||
|
||||
type SecretChange = {
|
||||
type SecretChange = BaseChange & {
|
||||
type: ResourceType.SECRET;
|
||||
secretKey?: string;
|
||||
secretVersion?: string;
|
||||
@@ -98,7 +100,7 @@ type SecretChange = {
|
||||
}[];
|
||||
};
|
||||
|
||||
type FolderChange = {
|
||||
type FolderChange = BaseChange & {
|
||||
type: ResourceType.FOLDER;
|
||||
folderName?: string;
|
||||
folderVersion?: string;
|
||||
@@ -107,7 +109,7 @@ type FolderChange = {
|
||||
}[];
|
||||
};
|
||||
|
||||
export type ResourceChange = BaseChange & (SecretChange | FolderChange);
|
||||
export type ResourceChange = SecretChange | FolderChange;
|
||||
|
||||
type ActorInfo = {
|
||||
actorType: string;
|
||||
@@ -134,12 +136,13 @@ type TFolderCommitServiceFactoryDep = {
|
||||
folderVersionDAL: TSecretFolderVersionDALFactory;
|
||||
secretVersionV2BridgeDAL: TSecretVersionV2DALFactory;
|
||||
secretV2BridgeDAL: secretV2BridgeDal.TSecretV2BridgeDALFactory;
|
||||
projectDAL: Pick<TProjectDALFactory, "findById">;
|
||||
projectDAL: Pick<TProjectDALFactory, "findById" | "findProjectByEnvId">;
|
||||
folderCommitQueueService?: Pick<
|
||||
TFolderCommitQueueServiceFactory,
|
||||
"scheduleTreeCheckpoint" | "createFolderTreeCheckpoint"
|
||||
>;
|
||||
permissionService?: TPermissionServiceFactory;
|
||||
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
|
||||
};
|
||||
|
||||
export const folderCommitServiceFactory = ({
|
||||
@@ -157,7 +160,8 @@ export const folderCommitServiceFactory = ({
|
||||
secretV2BridgeDAL,
|
||||
folderTreeCheckpointResourcesDAL,
|
||||
folderCommitQueueService,
|
||||
permissionService
|
||||
permissionService,
|
||||
kmsService
|
||||
}: TFolderCommitServiceFactoryDep) => {
|
||||
const appCfg = getConfig();
|
||||
|
||||
@@ -394,6 +398,12 @@ export const folderCommitServiceFactory = ({
|
||||
throw new NotFoundError({ message: `Commit with ID ${targetCommitId} not found` });
|
||||
}
|
||||
|
||||
const project = await projectDAL.findProjectByEnvId(targetCommit.envId, tx);
|
||||
|
||||
if (!project) {
|
||||
throw new NotFoundError({ message: `No project found for envId ${targetCommit.envId}` });
|
||||
}
|
||||
|
||||
// If currentCommitId is not provided, mark all resources in target as creates
|
||||
if (!currentCommitId) {
|
||||
const targetState = await reconstructFolderState(targetCommitId, tx);
|
||||
@@ -565,7 +575,63 @@ export const folderCommitServiceFactory = ({
|
||||
}
|
||||
});
|
||||
|
||||
return differences;
|
||||
const removeNoChangeUpdate: string[] = [];
|
||||
|
||||
const { decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({
|
||||
type: KmsDataKey.SecretManager,
|
||||
projectId: project.id
|
||||
});
|
||||
|
||||
await Promise.all(
|
||||
differences.map(async (change) => {
|
||||
if (change.changeType === ChangeType.UPDATE) {
|
||||
if (change.type === ResourceType.FOLDER && change.folderVersion && change.fromVersion) {
|
||||
const versions = await folderVersionDAL.find({
|
||||
folderId: change.id,
|
||||
$in: {
|
||||
version: [Number(change.folderVersion), Number(change.fromVersion)]
|
||||
}
|
||||
});
|
||||
const versionsShaped = [...new Set(versions.map((version) => version.name))];
|
||||
if (versionsShaped.length === 1) {
|
||||
removeNoChangeUpdate.push(change.id);
|
||||
}
|
||||
} else if (change.type === ResourceType.SECRET && change.secretVersion && change.fromVersion) {
|
||||
const versions = await secretVersionV2BridgeDAL.findVersionsBySecretIdWithActors({
|
||||
secretId: change.id,
|
||||
projectId: project.id,
|
||||
secretVersions: [change.secretVersion, change.fromVersion]
|
||||
});
|
||||
const versionsShaped = versions.map((el) => ({
|
||||
secretKey: el.key,
|
||||
secretComment: el.encryptedComment
|
||||
? secretManagerDecryptor({ cipherTextBlob: el.encryptedComment }).toString()
|
||||
: "",
|
||||
skipMultilineEncoding: el.skipMultilineEncoding,
|
||||
secretReminderRepeatDays: el.reminderRepeatDays,
|
||||
tags: el.tags,
|
||||
metadata: el.metadata,
|
||||
secretReminderNote: el.reminderNote,
|
||||
secretValue: el.encryptedValue
|
||||
? secretManagerDecryptor({ cipherTextBlob: el.encryptedValue }).toString()
|
||||
: ""
|
||||
}));
|
||||
const uniqueVersions = versionsShaped.filter(
|
||||
(item, index, arr) =>
|
||||
arr.findIndex((other) =>
|
||||
Object.entries(item).every(
|
||||
([key, value]) => JSON.stringify(value) === JSON.stringify(other[key as keyof typeof other])
|
||||
)
|
||||
) === index
|
||||
);
|
||||
if (uniqueVersions.length === 1) {
|
||||
removeNoChangeUpdate.push(change.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
return differences.filter((change) => !removeNoChangeUpdate.includes(change.id));
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1375,6 +1441,63 @@ export const folderCommitServiceFactory = ({
|
||||
);
|
||||
};
|
||||
|
||||
const addNestedFolderChanges = async ({
|
||||
changes,
|
||||
beforeCommit,
|
||||
folderId,
|
||||
folderName,
|
||||
folderPath,
|
||||
step = 1,
|
||||
tx
|
||||
}: {
|
||||
changes: {
|
||||
folderId: string;
|
||||
folderName: string;
|
||||
changes: ResourceChange[];
|
||||
folderPath?: string;
|
||||
}[];
|
||||
beforeCommit: bigint;
|
||||
folderId: string;
|
||||
folderName?: string;
|
||||
folderPath?: string;
|
||||
step?: number;
|
||||
tx?: Knex;
|
||||
}) => {
|
||||
if (step > 20) {
|
||||
return;
|
||||
}
|
||||
const latestFolderCommit = await folderCommitDAL.findCommitBefore(folderId, beforeCommit, tx);
|
||||
if (!latestFolderCommit) {
|
||||
return;
|
||||
}
|
||||
const diff = await compareFolderStates({
|
||||
targetCommitId: latestFolderCommit.id,
|
||||
tx
|
||||
});
|
||||
changes.push({
|
||||
folderId,
|
||||
folderName: folderName || "",
|
||||
changes: diff,
|
||||
folderPath: folderPath || ""
|
||||
});
|
||||
|
||||
await Promise.all(
|
||||
diff.map(async (change) => {
|
||||
if (change.type === ResourceType.FOLDER && change.changeType === ChangeType.CREATE) {
|
||||
await addNestedFolderChanges({
|
||||
changes,
|
||||
beforeCommit,
|
||||
folderId: change.id,
|
||||
folderName: change.folderName,
|
||||
folderPath: `${folderPath}/${change.folderName}`,
|
||||
step: step + 1,
|
||||
tx
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const deepCompareFolder = async ({
|
||||
targetCommitId,
|
||||
envId,
|
||||
@@ -1463,7 +1586,12 @@ export const folderCommitServiceFactory = ({
|
||||
const folders = await folderDAL.findFoldersByRootAndIds({ rootId: targetCommit.folderId, folderIds }, tx);
|
||||
const sortedFolders = sortFoldersByHierarchy(folders);
|
||||
|
||||
const response = [];
|
||||
const response: {
|
||||
folderId: string;
|
||||
folderName: string;
|
||||
changes: ResourceChange[];
|
||||
folderPath?: string;
|
||||
}[] = [];
|
||||
for (const folder of sortedFolders) {
|
||||
const diff = folderDiffs.get(folder.id);
|
||||
if (diff) {
|
||||
@@ -1474,6 +1602,29 @@ export const folderCommitServiceFactory = ({
|
||||
changes: diff,
|
||||
folderPath: folderPath?.[0]?.path
|
||||
});
|
||||
const recreatedFolders = diff
|
||||
.filter(
|
||||
(change): change is FolderChange =>
|
||||
change.type === ResourceType.FOLDER && change.changeType === ChangeType.CREATE
|
||||
)
|
||||
.map((change) => ({
|
||||
id: change.id,
|
||||
folderName: change.folderName,
|
||||
folderPath: folderPath?.[0]?.path
|
||||
}));
|
||||
await Promise.all(
|
||||
recreatedFolders.map(async (change) => {
|
||||
const nestedFolderPath = folderPath?.[0]?.path;
|
||||
await addNestedFolderChanges({
|
||||
changes: response,
|
||||
beforeCommit: targetCommit.commitId,
|
||||
folderId: change.id,
|
||||
folderName: change.folderName,
|
||||
folderPath: `${nestedFolderPath !== "/" ? nestedFolderPath : ""}/${change.folderName}`,
|
||||
tx
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
return response;
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
TProjectsUpdate
|
||||
} from "@app/db/schemas";
|
||||
import { BadRequestError, DatabaseError, NotFoundError, UnauthorizedError } from "@app/lib/errors";
|
||||
import { ormify, selectAllTableCols, sqlNestRelationships } from "@app/lib/knex";
|
||||
import { buildFindFilter, ormify, selectAllTableCols, sqlNestRelationships } from "@app/lib/knex";
|
||||
|
||||
import { ActorType } from "../auth/auth-type";
|
||||
import { Filter, ProjectFilterType, SearchProjectSortBy } from "./project-types";
|
||||
@@ -425,6 +425,16 @@ export const projectDALFactory = (db: TDbClient) => {
|
||||
return { docs, totalCount: Number(docs?.[0]?.count ?? 0) };
|
||||
};
|
||||
|
||||
const findProjectByEnvId = async (envId: string, tx?: Knex) => {
|
||||
const project = await (tx || db.replicaNode())(TableName.Project)
|
||||
.leftJoin(TableName.Environment, `${TableName.Environment}.projectId`, `${TableName.Project}.id`)
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||
.where(buildFindFilter({ id: envId }, TableName.Environment))
|
||||
.select(selectAllTableCols(TableName.Project))
|
||||
.first();
|
||||
return project;
|
||||
};
|
||||
|
||||
return {
|
||||
...projectOrm,
|
||||
findUserProjects,
|
||||
@@ -437,6 +447,7 @@ export const projectDALFactory = (db: TDbClient) => {
|
||||
findProjectWithOrg,
|
||||
checkProjectUpgradeStatus,
|
||||
getProjectFromSplitId,
|
||||
searchProjects
|
||||
searchProjects,
|
||||
findProjectByEnvId
|
||||
};
|
||||
};
|
||||
|
||||
@@ -800,6 +800,7 @@ export const secretFolderServiceFactory = ({
|
||||
change.isUpdate || change.changeType === ChangeType.UPDATE ? [currentVersion, fromVersion] : [currentVersion]
|
||||
});
|
||||
return versions.map((v) => ({
|
||||
version: v.version?.toString() || "1",
|
||||
name: v.name
|
||||
}));
|
||||
};
|
||||
|
||||
@@ -2875,24 +2875,21 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actorAuthMethod,
|
||||
secretId,
|
||||
secretVersionNumbers,
|
||||
folderId
|
||||
secretPath,
|
||||
envId,
|
||||
projectId
|
||||
}: TGetSecretVersionsDTO & {
|
||||
secretVersionNumbers: string[];
|
||||
folderId: string;
|
||||
secretPath: string;
|
||||
envId: string;
|
||||
projectId: string;
|
||||
}) => {
|
||||
const folder = await folderDAL.findById(folderId);
|
||||
if (!folder) throw new NotFoundError({ message: `Folder with ID '${folderId}' not found` });
|
||||
|
||||
const [folderWithPath] = await folderDAL.findSecretPathByFolderIds(folder.projectId, [folder.id]);
|
||||
|
||||
if (!folderWithPath) {
|
||||
throw new NotFoundError({ message: `Folder with ID '${folder.id}' not found` });
|
||||
}
|
||||
const environment = await projectEnvDAL.findOne({ id: envId });
|
||||
|
||||
const { permission } = await permissionService.getProjectPermission({
|
||||
actor,
|
||||
actorId,
|
||||
projectId: folder.projectId,
|
||||
projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
@@ -2906,11 +2903,11 @@ export const secretV2BridgeServiceFactory = ({
|
||||
|
||||
const { decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({
|
||||
type: KmsDataKey.SecretManager,
|
||||
projectId: folder.projectId
|
||||
projectId
|
||||
});
|
||||
const secretVersions = await secretVersionDAL.findVersionsBySecretIdWithActors({
|
||||
secretId,
|
||||
projectId: folder.projectId,
|
||||
projectId,
|
||||
secretVersions: secretVersionNumbers
|
||||
});
|
||||
return secretVersions.map((el) => {
|
||||
@@ -2918,8 +2915,8 @@ export const secretV2BridgeServiceFactory = ({
|
||||
permission,
|
||||
ProjectPermissionSecretActions.ReadValue,
|
||||
{
|
||||
environment: folder.environment.envSlug,
|
||||
secretPath: folderWithPath.path,
|
||||
environment: environment.slug,
|
||||
secretPath,
|
||||
secretName: el.key,
|
||||
...(el.tags?.length && {
|
||||
secretTags: el.tags.map((tag) => tag.slug)
|
||||
@@ -2928,9 +2925,9 @@ export const secretV2BridgeServiceFactory = ({
|
||||
);
|
||||
|
||||
return reshapeBridgeSecret(
|
||||
folder.projectId,
|
||||
folder.environment.envSlug,
|
||||
folderWithPath.path,
|
||||
projectId,
|
||||
environment.slug,
|
||||
secretPath,
|
||||
{
|
||||
...el,
|
||||
value: el.encryptedValue ? secretManagerDecryptor({ cipherTextBlob: el.encryptedValue }).toString() : "",
|
||||
|
||||
@@ -2529,10 +2529,14 @@ export const secretServiceFactory = ({
|
||||
actorAuthMethod,
|
||||
secretId,
|
||||
secretVersions,
|
||||
folderId
|
||||
secretPath,
|
||||
envId,
|
||||
projectId
|
||||
}: TGetSecretVersionsDTO & {
|
||||
secretVersions: string[];
|
||||
folderId: string;
|
||||
secretPath: string;
|
||||
envId: string;
|
||||
projectId: string;
|
||||
}) => {
|
||||
const secretVersionV2 = await secretV2BridgeService.getSecretVersionsByIds({
|
||||
actorId,
|
||||
@@ -2540,8 +2544,10 @@ export const secretServiceFactory = ({
|
||||
actorOrgId,
|
||||
actorAuthMethod,
|
||||
secretId,
|
||||
folderId,
|
||||
secretVersionNumbers: secretVersions
|
||||
secretVersionNumbers: secretVersions,
|
||||
secretPath,
|
||||
envId,
|
||||
projectId
|
||||
});
|
||||
return secretVersionV2;
|
||||
};
|
||||
@@ -3317,7 +3323,9 @@ export const secretServiceFactory = ({
|
||||
actor: ActorType,
|
||||
actorOrgId: string,
|
||||
actorAuthMethod: ActorAuthMethod,
|
||||
folderId: string
|
||||
envId: string,
|
||||
projectId: string,
|
||||
secretPath: string
|
||||
) => {
|
||||
const currentVersion = change.secretVersion;
|
||||
const secretId = change.secretId ? change.secretId : change.id;
|
||||
@@ -3335,7 +3343,9 @@ export const secretServiceFactory = ({
|
||||
change.isUpdate || change.changeType === ChangeType.UPDATE
|
||||
? [currentVersion, previousVersion]
|
||||
: [currentVersion],
|
||||
folderId
|
||||
secretPath,
|
||||
envId,
|
||||
projectId
|
||||
});
|
||||
return versions?.map((v) => ({
|
||||
secretKey: v.secretKey,
|
||||
|
||||
Reference in New Issue
Block a user