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..303c58621 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 Boolean(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/components/v2/Dropdown/Dropdown.tsx b/frontend/src/components/v2/Dropdown/Dropdown.tsx index 99a148bbe..3870cc74e 100644 --- a/frontend/src/components/v2/Dropdown/Dropdown.tsx +++ b/frontend/src/components/v2/Dropdown/Dropdown.tsx @@ -24,7 +24,7 @@ export const DropdownMenuContent = forwardRef 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 diff --git a/frontend/src/pages/integrations/aws-parameter-store/create.tsx b/frontend/src/pages/integrations/aws-parameter-store/create.tsx index 5af4a86c2..5a73aa7bd 100644 --- a/frontend/src/pages/integrations/aws-parameter-store/create.tsx +++ b/frontend/src/pages/integrations/aws-parameter-store/create.tsx @@ -17,6 +17,7 @@ import { useCreateIntegration } from "@app/hooks/api"; import { useGetIntegrationAuthAwsKmsKeys } from "@app/hooks/api/integrationAuth/queries"; import { + Badge, Button, Card, CardTitle, @@ -245,8 +246,8 @@ export default function AWSParameterStoreCreateIntegrationPage() { className="w-full border border-mineshaft-500" > {awsRegions.map((awsRegion) => ( - - {awsRegion.name} + + {awsRegion.name} {awsRegion.slug} ))} diff --git a/frontend/src/pages/integrations/aws-secret-manager/create.tsx b/frontend/src/pages/integrations/aws-secret-manager/create.tsx index d18379789..ceddb5ade 100644 --- a/frontend/src/pages/integrations/aws-secret-manager/create.tsx +++ b/frontend/src/pages/integrations/aws-secret-manager/create.tsx @@ -18,6 +18,7 @@ import { useGetIntegrationAuthAwsKmsKeys } from "@app/hooks/api/integrationAuth/ import { IntegrationMappingBehavior } from "@app/hooks/api/integrations/types"; import { + Badge, Button, Card, CardTitle, @@ -267,8 +268,12 @@ export default function AWSSecretManagerCreateIntegrationPage() { className="w-full border border-mineshaft-500" > {awsRegions.map((awsRegion) => ( - - {awsRegion.name} + + {awsRegion.name} {awsRegion.slug} ))} diff --git a/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretOverviewTableRow.tsx b/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretOverviewTableRow.tsx index 287269838..c71480e59 100644 --- a/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretOverviewTableRow.tsx +++ b/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretOverviewTableRow.tsx @@ -73,7 +73,7 @@ export const SecretOverviewTableRow = ({ >
-
+
{importCount > 0 && ( -
- - {importCount} -
+ + Total import count{" "} + (matching filters) +

+ } + > +
+ + {importCount} +
+
)} {folderCount > 0 && ( -
- - {folderCount} -
+ + Total folder count{" "} + (matching filters) +

+ } + > +
+ + {folderCount} +
+
)} {dynamicSecretCount > 0 && ( -
- - {dynamicSecretCount} -
+ + Total dynamic secret count{" "} + (matching filters) +

+ } + > +
+ + {dynamicSecretCount} +
+
)} {secretCount > 0 && ( -
- - {secretCount} -
+ + Total secret count{" "} + (matching filters) +

+ } + > +
+ + {secretCount} +
+
)}
); diff --git a/frontend/src/views/Settings/OrgSettingsPage/components/OrgEncryptionTab/AwsKmsForm.tsx b/frontend/src/views/Settings/OrgSettingsPage/components/OrgEncryptionTab/AwsKmsForm.tsx index aef80cbce..b180462ca 100644 --- a/frontend/src/views/Settings/OrgSettingsPage/components/OrgEncryptionTab/AwsKmsForm.tsx +++ b/frontend/src/views/Settings/OrgSettingsPage/components/OrgEncryptionTab/AwsKmsForm.tsx @@ -2,7 +2,7 @@ import { Controller, useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { createNotification } from "@app/components/notifications"; -import { Button, FormControl, Input, Select, SelectItem } from "@app/components/v2"; +import { Badge, Button, FormControl, Input, Select, SelectItem } from "@app/components/v2"; import { useOrganization } from "@app/context"; import { useAddExternalKms, useUpdateExternalKms } from "@app/hooks/api"; import { @@ -244,7 +244,7 @@ export const AwsKmsForm = ({ onCompleted, onCancel, kms }: Props) => { > {AWS_REGIONS.map((awsRegion) => ( - {awsRegion.name} ({awsRegion.slug}) + {awsRegion.name} {awsRegion.slug} ))}