From afd6dd52575f246a2fc283a0be1e37ca2e3d183b Mon Sep 17 00:00:00 2001 From: Scott Wilson Date: Thu, 26 Sep 2024 17:50:57 -0700 Subject: [PATCH] improvement: improve query param boolean handling for dashboard queries and move dashboard router to v1 --- .../routes/{v3 => v1}/dashboard-router.ts | 56 +++++++------------ backend/src/server/routes/v1/index.ts | 4 ++ backend/src/server/routes/v3/index.ts | 2 - frontend/src/hooks/api/dashboard/queries.tsx | 20 +------ 4 files changed, 28 insertions(+), 54 deletions(-) rename backend/src/server/routes/{v3 => v1}/dashboard-router.ts (94%) diff --git a/backend/src/server/routes/v3/dashboard-router.ts b/backend/src/server/routes/v1/dashboard-router.ts similarity index 94% rename from backend/src/server/routes/v3/dashboard-router.ts rename to backend/src/server/routes/v1/dashboard-router.ts index c66e5e912..a1d3320ad 100644 --- a/backend/src/server/routes/v3/dashboard-router.ts +++ b/backend/src/server/routes/v1/dashboard-router.ts @@ -17,6 +17,20 @@ import { AuthMode } from "@app/services/auth/auth-type"; import { SecretsOrderBy } from "@app/services/secret/secret-types"; import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types"; +// handle querystring boolean values +const booleanSchema = z + .union([z.boolean(), z.string().trim()]) + .transform((value) => { + if (typeof value === "string") { + // ie if not empty, 0 or false, return true + return !!value && Number(value) !== 0 && value.toLowerCase() !== "false"; + } + + return value; + }) + .optional() + .default(true); + export const registerDashboardRouter = async (server: FastifyZodProvider) => { server.route({ method: "GET", @@ -57,21 +71,9 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => { .describe(DASHBOARD.SECRET_OVERVIEW_LIST.orderDirection) .optional(), search: z.string().trim().describe(DASHBOARD.SECRET_OVERVIEW_LIST.search).optional(), - includeSecrets: z.coerce - .boolean() - .optional() - .default(true) - .describe(DASHBOARD.SECRET_OVERVIEW_LIST.includeSecrets), - includeFolders: z.coerce - .boolean() - .optional() - .default(true) - .describe(DASHBOARD.SECRET_OVERVIEW_LIST.includeFolders), - includeDynamicSecrets: z.coerce - .boolean() - .optional() - .default(true) - .describe(DASHBOARD.SECRET_OVERVIEW_LIST.includeDynamicSecrets) + includeSecrets: booleanSchema.describe(DASHBOARD.SECRET_OVERVIEW_LIST.includeSecrets), + includeFolders: booleanSchema.describe(DASHBOARD.SECRET_OVERVIEW_LIST.includeFolders), + includeDynamicSecrets: booleanSchema.describe(DASHBOARD.SECRET_OVERVIEW_LIST.includeDynamicSecrets) }), response: { 200: z.object({ @@ -354,26 +356,10 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => { .optional(), search: z.string().trim().describe(DASHBOARD.SECRET_DETAILS_LIST.search).optional(), tags: z.string().trim().transform(decodeURIComponent).describe(DASHBOARD.SECRET_DETAILS_LIST.tags).optional(), - includeSecrets: z.coerce - .boolean() - .optional() - .default(true) - .describe(DASHBOARD.SECRET_DETAILS_LIST.includeSecrets), - includeFolders: z.coerce - .boolean() - .optional() - .default(true) - .describe(DASHBOARD.SECRET_DETAILS_LIST.includeFolders), - includeDynamicSecrets: z.coerce - .boolean() - .optional() - .default(true) - .describe(DASHBOARD.SECRET_DETAILS_LIST.includeDynamicSecrets), - includeImports: z.coerce - .boolean() - .optional() - .default(true) - .describe(DASHBOARD.SECRET_DETAILS_LIST.includeImports) + includeSecrets: booleanSchema.describe(DASHBOARD.SECRET_DETAILS_LIST.includeSecrets), + includeFolders: booleanSchema.describe(DASHBOARD.SECRET_DETAILS_LIST.includeFolders), + includeDynamicSecrets: booleanSchema.describe(DASHBOARD.SECRET_DETAILS_LIST.includeDynamicSecrets), + includeImports: booleanSchema.describe(DASHBOARD.SECRET_DETAILS_LIST.includeImports) }), response: { 200: z.object({ diff --git a/backend/src/server/routes/v1/index.ts b/backend/src/server/routes/v1/index.ts index d13d0db80..d46b361b3 100644 --- a/backend/src/server/routes/v1/index.ts +++ b/backend/src/server/routes/v1/index.ts @@ -1,3 +1,5 @@ +import { registerDashboardRouter } from "@app/server/routes/v1/dashboard-router"; + import { registerAdminRouter } from "./admin-router"; import { registerAuthRoutes } from "./auth-router"; import { registerProjectBotRouter } from "./bot-router"; @@ -101,4 +103,6 @@ export const registerV1Routes = async (server: FastifyZodProvider) => { await server.register(registerIdentityRouter, { prefix: "/identities" }); await server.register(registerSecretSharingRouter, { prefix: "/secret-sharing" }); await server.register(registerUserEngagementRouter, { prefix: "/user-engagement" }); + + await server.register(registerDashboardRouter, { prefix: "/dashboard" }); }; diff --git a/backend/src/server/routes/v3/index.ts b/backend/src/server/routes/v3/index.ts index f77c25c73..6a061a635 100644 --- a/backend/src/server/routes/v3/index.ts +++ b/backend/src/server/routes/v3/index.ts @@ -1,4 +1,3 @@ -import { registerDashboardRouter } from "./dashboard-router"; import { registerLoginRouter } from "./login-router"; import { registerSecretBlindIndexRouter } from "./secret-blind-index-router"; import { registerSecretRouter } from "./secret-router"; @@ -11,5 +10,4 @@ export const registerV3Routes = async (server: FastifyZodProvider) => { await server.register(registerUserRouter, { prefix: "/users" }); await server.register(registerSecretRouter, { prefix: "/secrets" }); await server.register(registerSecretBlindIndexRouter, { prefix: "/workspaces" }); - await server.register(registerDashboardRouter, { prefix: "/dashboard" }); }; diff --git a/frontend/src/hooks/api/dashboard/queries.tsx b/frontend/src/hooks/api/dashboard/queries.tsx index 38c07b6cf..29fcbe895 100644 --- a/frontend/src/hooks/api/dashboard/queries.tsx +++ b/frontend/src/hooks/api/dashboard/queries.tsx @@ -48,21 +48,15 @@ export const dashboardKeys = { }; export const fetchProjectSecretsOverview = async ({ - includeFolders, - includeSecrets, - includeDynamicSecrets, environments, ...params }: TGetDashboardProjectSecretsOverviewDTO) => { const { data } = await apiRequest.get( - "/api/v3/dashboard/secrets-overview", + "/api/v1/dashboard/secrets-overview", { params: { ...params, - environments: encodeURIComponent(environments.join(",")), - includeFolders: includeFolders ? "1" : "", - includeSecrets: includeSecrets ? "1" : "", - includeDynamicSecrets: includeDynamicSecrets ? "1" : "" + environments: encodeURIComponent(environments.join(",")) } } ); @@ -71,22 +65,14 @@ export const fetchProjectSecretsOverview = async ({ }; export const fetchProjectSecretsDetails = async ({ - includeFolders, - includeImports, - includeSecrets, - includeDynamicSecrets, tags, ...params }: TGetDashboardProjectSecretsDetailsDTO) => { const { data } = await apiRequest.get( - "/api/v3/dashboard/secrets-details", + "/api/v1/dashboard/secrets-details", { params: { ...params, - includeImports: includeImports ? "1" : "", - includeFolders: includeFolders ? "1" : "", - includeSecrets: includeSecrets ? "1" : "", - includeDynamicSecrets: includeDynamicSecrets ? "1" : "", tags: encodeURIComponent( Object.entries(tags) // eslint-disable-next-line @typescript-eslint/no-unused-vars