Merge branch 'main' into ENG-2685

This commit is contained in:
x
2025-04-30 13:41:14 -04:00
19 changed files with 494 additions and 126 deletions
@@ -69,6 +69,5 @@ export const listTeamCityProjects = async (appConnection: TTeamCityConnection) =
}
);
// Filter out the root project. Should not be seen by users.
return resp.data.project.filter((proj) => proj.id !== "_Root");
return resp.data.project;
};
@@ -171,6 +171,19 @@ export const secretImportDALFactory = (db: TDbClient) => {
}
};
const getFolderImports = async (secretPath: string, environmentId: string, tx?: Knex) => {
try {
const folderImports = await (tx || db.replicaNode())(TableName.SecretImport)
.where({ importPath: secretPath, importEnv: environmentId })
.join(TableName.SecretFolder, `${TableName.SecretImport}.folderId`, `${TableName.SecretFolder}.id`)
.join(TableName.Environment, `${TableName.SecretFolder}.envId`, `${TableName.Environment}.id`)
.select(db.ref("id").withSchema(TableName.SecretFolder).as("folderId"));
return folderImports;
} catch (error) {
throw new DatabaseError({ error, name: "get secret imports" });
}
};
const getFolderIsImportedBy = async (
secretPath: string,
environmentId: string,
@@ -203,7 +216,8 @@ export const secretImportDALFactory = (db: TDbClient) => {
db.ref("name").withSchema(TableName.Environment).as("envName"),
db.ref("slug").withSchema(TableName.Environment).as("envSlug"),
db.ref("id").withSchema(TableName.SecretFolder).as("folderId"),
db.ref("secretKey").withSchema(TableName.SecretReferenceV2).as("referencedSecretKey")
db.ref("secretKey").withSchema(TableName.SecretReferenceV2).as("referencedSecretKey"),
db.ref("environment").withSchema(TableName.SecretReferenceV2).as("referencedSecretEnv")
);
const folderResults = folderImports.map(({ envName, envSlug, folderName, folderId }) => ({
@@ -214,13 +228,14 @@ export const secretImportDALFactory = (db: TDbClient) => {
}));
const secretResults = secretReferences.map(
({ envName, envSlug, secretId, folderName, folderId, referencedSecretKey }) => ({
({ envName, envSlug, secretId, folderName, folderId, referencedSecretKey, referencedSecretEnv }) => ({
envName,
envSlug,
secretId,
folderName,
folderId,
referencedSecretKey
referencedSecretKey,
referencedSecretEnv
})
);
@@ -235,6 +250,7 @@ export const secretImportDALFactory = (db: TDbClient) => {
secrets: {
secretId: string;
referencedSecretKey: string;
referencedSecretEnv: string;
}[];
folderId: string;
folderImported: boolean;
@@ -264,7 +280,11 @@ export const secretImportDALFactory = (db: TDbClient) => {
if ("secretId" in item && item.secretId) {
updatedAcc[env].folders[folder].secrets = [
...updatedAcc[env].folders[folder].secrets,
{ secretId: item.secretId, referencedSecretKey: item.referencedSecretKey }
{
secretId: item.secretId,
referencedSecretKey: item.referencedSecretKey,
referencedSecretEnv: item.referencedSecretEnv
}
];
} else {
updatedAcc[env].folders[folder].folderImported = true;
@@ -309,6 +329,7 @@ export const secretImportDALFactory = (db: TDbClient) => {
findLastImportPosition,
updateAllPosition,
getProjectImportCount,
getFolderIsImportedBy
getFolderIsImportedBy,
getFolderImports
};
};
@@ -808,7 +808,7 @@ export const secretImportServiceFactory = ({
actorOrgId,
secrets
}: TGetSecretImportsDTO & {
secrets: { secretKey: string; secretValue: string }[] | undefined;
secrets: { secretKey: string; secretValue: string; id: string }[] | undefined;
}) => {
const { permission } = await permissionService.getProjectPermission({
actor,
@@ -877,7 +877,8 @@ export const secretImportServiceFactory = ({
)
.map((otherSecret) => ({
secretId: secret.secretKey,
referencedSecretKey: otherSecret.secretKey
referencedSecretKey: otherSecret.secretKey,
referencedSecretEnv: environment
}));
}) || [];
if (locallyReferenced.length > 0) {
@@ -56,11 +56,12 @@ export type FolderResult = {
export type SecretResult = {
secretId: string;
referencedSecretKey: string;
referencedSecretEnv: string;
} & FolderResult;
export type FolderInfo = {
folderName: string;
secrets?: { secretId: string; referencedSecretKey: string }[];
secrets?: { secretId: string; referencedSecretKey: string; referencedSecretEnv: string }[];
folderId: string;
folderImported: boolean;
envSlug?: string;
@@ -23,6 +23,7 @@ import {
TDeleteSecretSyncDTO,
TFindSecretSyncByIdDTO,
TFindSecretSyncByNameDTO,
TListSecretSyncsByFolderId,
TListSecretSyncsByProjectId,
TSecretSync,
TTriggerSecretSyncImportSecretsByIdDTO,
@@ -31,12 +32,14 @@ import {
TUpdateSecretSyncDTO
} from "@app/services/secret-sync/secret-sync-types";
import { TSecretImportDALFactory } from "../secret-import/secret-import-dal";
import { TSecretSyncDALFactory } from "./secret-sync-dal";
import { SECRET_SYNC_CONNECTION_MAP, SECRET_SYNC_NAME_MAP } from "./secret-sync-maps";
import { TSecretSyncQueueFactory } from "./secret-sync-queue";
type TSecretSyncServiceFactoryDep = {
secretSyncDAL: TSecretSyncDALFactory;
secretImportDAL: TSecretImportDALFactory;
appConnectionService: Pick<TAppConnectionServiceFactory, "connectAppConnectionById">;
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission" | "getOrgPermission">;
projectBotService: Pick<TProjectBotServiceFactory, "getBotKey">;
@@ -53,6 +56,7 @@ export type TSecretSyncServiceFactory = ReturnType<typeof secretSyncServiceFacto
export const secretSyncServiceFactory = ({
secretSyncDAL,
folderDAL,
secretImportDAL,
permissionService,
appConnectionService,
projectBotService,
@@ -85,6 +89,37 @@ export const secretSyncServiceFactory = ({
return secretSyncs as TSecretSync[];
};
const listSecretSyncsBySecretPath = async (
{ projectId, secretPath, environment }: TListSecretSyncsByFolderId,
actor: OrgServiceActor
) => {
const { permission } = await permissionService.getProjectPermission({
actor: actor.type,
actorId: actor.id,
actorAuthMethod: actor.authMethod,
actorOrgId: actor.orgId,
actionProjectType: ActionProjectType.SecretManager,
projectId
});
if (permission.cannot(ProjectPermissionSecretSyncActions.Read, ProjectPermissionSub.SecretSyncs)) {
return [];
}
const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
if (!folder) return [];
const folderImports = await secretImportDAL.getFolderImports(secretPath, folder.envId);
const secretSyncs = await secretSyncDAL.find({
$in: {
folderId: folderImports.map((folderImport) => folderImport.folderId).concat(folder.id)
}
});
return secretSyncs as TSecretSync[];
};
const findSecretSyncById = async ({ destination, syncId }: TFindSecretSyncByIdDTO, actor: OrgServiceActor) => {
const secretSync = await secretSyncDAL.findById(syncId);
@@ -518,6 +553,7 @@ export const secretSyncServiceFactory = ({
return {
listSecretSyncOptions,
listSecretSyncsByProjectId,
listSecretSyncsBySecretPath,
findSecretSyncById,
findSecretSyncByName,
createSecretSync,
@@ -144,6 +144,13 @@ export type TListSecretSyncsByProjectId = {
destination?: SecretSync;
};
export type TListSecretSyncsByFolderId = {
projectId: string;
secretPath: string;
environment: string;
destination?: SecretSync;
};
export type TFindSecretSyncByIdDTO = {
syncId: string;
destination: SecretSync;