mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-11 06:29:04 +00:00
refactor: move overview resource env determination logic to the client side to preserve ordering of resources
This commit is contained in:
@@ -36,14 +36,21 @@ export const dynamicSecretDALFactory = (db: TDbClient) => {
|
||||
.whereIn("folderId", folderIds)
|
||||
.where((bd) => {
|
||||
if (search) {
|
||||
void bd.whereILike("name", `%${search}%`);
|
||||
void bd.whereILike(`${TableName.DynamicSecret}.name`, `%${search}%`);
|
||||
}
|
||||
})
|
||||
.leftJoin(TableName.SecretFolder, `${TableName.SecretFolder}.id`, `${TableName.DynamicSecret}.folderId`)
|
||||
.leftJoin(TableName.Environment, `${TableName.SecretFolder}.envId`, `${TableName.Environment}.id`)
|
||||
.select(
|
||||
selectAllTableCols(TableName.DynamicSecret),
|
||||
db.raw(`DENSE_RANK() OVER (ORDER BY "name" ${orderDirection ?? OrderByDirection.ASC}) as rank`)
|
||||
db.ref("slug").withSchema(TableName.Environment).as("environment"),
|
||||
db.raw(
|
||||
`DENSE_RANK() OVER (ORDER BY ${TableName.DynamicSecret}."name" ${
|
||||
orderDirection ?? OrderByDirection.ASC
|
||||
}) as rank`
|
||||
)
|
||||
)
|
||||
.orderBy(orderBy, orderDirection);
|
||||
.orderBy(`${TableName.DynamicSecret}.${orderBy}`, orderDirection);
|
||||
|
||||
if (limit) {
|
||||
const rankOffset = offset + 1;
|
||||
|
||||
@@ -486,15 +486,7 @@ export const dynamicSecretServiceFactory = ({
|
||||
...params
|
||||
});
|
||||
|
||||
// map dynamic secrets to their respective env
|
||||
const folderEnvMap: Map<string, string> = new Map(folders.map((folder) => [folder.id, folder.environment.slug]));
|
||||
const data: { [key: string]: Array<(typeof dynamicSecretCfg)[number]> } = {};
|
||||
dynamicSecretCfg.forEach((secret) => {
|
||||
const slug = folderEnvMap.get(secret.folderId);
|
||||
data[slug!] = [...(data[slug!] ?? []), secret];
|
||||
});
|
||||
|
||||
return data;
|
||||
return dynamicSecretCfg;
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
@@ -73,25 +73,21 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
folders: z.record(z.string(), SecretFoldersSchema.array()).optional(),
|
||||
dynamicSecrets: z.record(z.string(), SanitizedDynamicSecretSchema.array()).optional(),
|
||||
secrets: z
|
||||
.record(
|
||||
z.string(),
|
||||
secretRawSchema
|
||||
.extend({
|
||||
secretPath: z.string().optional(),
|
||||
tags: SecretTagsSchema.pick({
|
||||
id: true,
|
||||
slug: true,
|
||||
color: true
|
||||
})
|
||||
.extend({ name: z.string() })
|
||||
.array()
|
||||
.optional()
|
||||
})
|
||||
folders: SecretFoldersSchema.extend({ environment: z.string() }).array().optional(),
|
||||
dynamicSecrets: SanitizedDynamicSecretSchema.extend({ environment: z.string() }).array().optional(),
|
||||
secrets: secretRawSchema
|
||||
.extend({
|
||||
secretPath: z.string().optional(),
|
||||
tags: SecretTagsSchema.pick({
|
||||
id: true,
|
||||
slug: true,
|
||||
color: true
|
||||
})
|
||||
.extend({ name: z.string() })
|
||||
.array()
|
||||
)
|
||||
.optional()
|
||||
})
|
||||
.array()
|
||||
.optional(),
|
||||
totalFolderCount: z.number().optional(),
|
||||
totalDynamicSecretCount: z.number().optional(),
|
||||
@@ -166,9 +162,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
||||
});
|
||||
|
||||
// get the count of unique folder names to properly adjust remaining limit
|
||||
const uniqueFolderCount = new Set(
|
||||
Object.values(folders).flatMap((folderGroup) => folderGroup.flatMap((folder) => folder.name))
|
||||
).size;
|
||||
const uniqueFolderCount = new Set(folders.map((folder) => folder.name)).size;
|
||||
|
||||
remainingLimit -= uniqueFolderCount;
|
||||
adjustedOffset = 0;
|
||||
@@ -207,11 +201,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
||||
});
|
||||
|
||||
// get the count of unique dynamic secret names to properly adjust remaining limit
|
||||
const uniqueDynamicSecretsCount = new Set(
|
||||
Object.values(dynamicSecrets).flatMap((dynamicSecretGroup) =>
|
||||
dynamicSecretGroup.flatMap((dynamicSecret) => dynamicSecret.name)
|
||||
)
|
||||
).size;
|
||||
const uniqueDynamicSecretsCount = new Set(dynamicSecrets.map((dynamicSecret) => dynamicSecret.name)).size;
|
||||
|
||||
remainingLimit -= uniqueDynamicSecretsCount;
|
||||
adjustedOffset = 0;
|
||||
@@ -250,7 +240,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
||||
});
|
||||
|
||||
for await (const environment of environments) {
|
||||
const secretCountFromEnv = secrets[environment]?.length;
|
||||
const secretCountFromEnv = secrets.filter((secret) => secret.environment === environment).length;
|
||||
|
||||
if (secretCountFromEnv) {
|
||||
await server.services.auditLog.createAuditLog({
|
||||
|
||||
@@ -411,14 +411,20 @@ export const secretFolderDALFactory = (db: TDbClient) => {
|
||||
.where("isReserved", false)
|
||||
.where((bd) => {
|
||||
if (search) {
|
||||
void bd.whereILike("name", `%${search}%`);
|
||||
void bd.whereILike(`${TableName.SecretFolder}.name`, `%${search}%`);
|
||||
}
|
||||
})
|
||||
.leftJoin(TableName.Environment, `${TableName.Environment}.id`, `${TableName.SecretFolder}.envId`)
|
||||
.select(
|
||||
selectAllTableCols(TableName.SecretFolder),
|
||||
db.raw(`DENSE_RANK() OVER (ORDER BY "name" ${orderDirection ?? OrderByDirection.ASC}) as rank`)
|
||||
db.raw(
|
||||
`DENSE_RANK() OVER (ORDER BY ${TableName.SecretFolder}."name" ${
|
||||
orderDirection ?? OrderByDirection.ASC
|
||||
}) as rank`
|
||||
),
|
||||
db.ref("slug").withSchema(TableName.Environment).as("environment")
|
||||
)
|
||||
.orderBy(orderBy, orderDirection);
|
||||
.orderBy(`${TableName.SecretFolder}.${orderBy}`, orderDirection);
|
||||
|
||||
if (limit) {
|
||||
const rankOffset = offset + 1; // ranks start from 1
|
||||
|
||||
@@ -2,7 +2,7 @@ import { ForbiddenError, subject } from "@casl/ability";
|
||||
import path from "path";
|
||||
import { v4 as uuidv4, validate as uuidValidate } from "uuid";
|
||||
|
||||
import { TSecretFolders, TSecretFoldersInsert } from "@app/db/schemas";
|
||||
import { TSecretFoldersInsert } from "@app/db/schemas";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||
import { TSecretSnapshotServiceFactory } from "@app/ee/services/secret-snapshot/secret-snapshot-service";
|
||||
@@ -446,13 +446,12 @@ export const secretFolderServiceFactory = ({
|
||||
await permissionService.getProjectPermission(actor, actorId, projectId, actorAuthMethod, actorOrgId);
|
||||
|
||||
const envs = await projectEnvDAL.findBySlugs(projectId, environments);
|
||||
const data: { [key: string]: TSecretFolders[] } = {};
|
||||
|
||||
if (!envs.length)
|
||||
throw new BadRequestError({ message: "Environment(s) not found", name: "get project folder count" });
|
||||
|
||||
const parentFolders = await folderDAL.findBySecretPathMultiEnv(projectId, environments, secretPath);
|
||||
if (!parentFolders.length) return data;
|
||||
if (!parentFolders.length) return [];
|
||||
|
||||
const folders = await folderDAL.findByMultiEnv({
|
||||
environmentIds: envs.map((env) => env.id),
|
||||
@@ -460,14 +459,7 @@ export const secretFolderServiceFactory = ({
|
||||
...params
|
||||
});
|
||||
|
||||
// reorganize folders into respective envs
|
||||
const envMap: Map<string, string> = new Map(envs.map((env) => [env.id, env.slug]));
|
||||
folders.forEach((folder) => {
|
||||
const slug = envMap.get(folder.envId);
|
||||
data[slug!] = [...(data[slug!] ?? []), folder];
|
||||
});
|
||||
|
||||
return data;
|
||||
return folders;
|
||||
};
|
||||
|
||||
// get the unique count of folders within a project path
|
||||
|
||||
@@ -550,14 +550,8 @@ export const secretV2BridgeServiceFactory = ({
|
||||
|
||||
const folders = await folderDAL.findBySecretPathMultiEnv(projectId, environments, path);
|
||||
|
||||
const data: { [key: string]: typeof decryptedSecrets } = {};
|
||||
|
||||
if (!folders.length) {
|
||||
environments.forEach((env) => {
|
||||
data[env] = [];
|
||||
});
|
||||
|
||||
return data;
|
||||
return [];
|
||||
}
|
||||
|
||||
paths = folders.map((folder) => ({ folderId: folder.id, path, environment: folder.environment.slug }));
|
||||
@@ -593,11 +587,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
)
|
||||
);
|
||||
|
||||
decryptedSecrets.forEach((secret) => {
|
||||
data[secret.environment] = [...(data[secret.environment] ?? []), secret];
|
||||
});
|
||||
|
||||
return data;
|
||||
return decryptedSecrets;
|
||||
};
|
||||
|
||||
const getSecrets = async ({
|
||||
|
||||
Reference in New Issue
Block a user