From 8ccdb66cedd92643f1414ffd6048b779527580ca Mon Sep 17 00:00:00 2001 From: Mauricio Siu Date: Sun, 29 Mar 2026 08:58:42 -0600 Subject: [PATCH] feat(destinations): enhance validation for additionalFlags in destination settings - Introduced regex validation for the `additionalFlags` field to ensure proper flag formatting. - Updated error handling in the API router to provide clearer feedback on validation issues. - Refactored the database schema to align with the new validation rules for additionalFlags. - Added a new validation module for destination-related checks. --- .../destination/handle-destinations.tsx | 19 +++++++++++++++++-- .../dokploy/server/api/routers/destination.ts | 9 ++++++++- packages/server/src/db/schema/destination.ts | 8 +++++++- .../server/src/db/validations/destination.ts | 3 +++ packages/server/src/index.ts | 1 + 5 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 packages/server/src/db/validations/destination.ts diff --git a/apps/dokploy/components/dashboard/settings/destination/handle-destinations.tsx b/apps/dokploy/components/dashboard/settings/destination/handle-destinations.tsx index b2d8240b1..25a3a1048 100644 --- a/apps/dokploy/components/dashboard/settings/destination/handle-destinations.tsx +++ b/apps/dokploy/components/dashboard/settings/destination/handle-destinations.tsx @@ -35,6 +35,10 @@ import { } from "@/components/ui/select"; import { cn } from "@/lib/utils"; import { api } from "@/utils/api"; +import { + ADDITIONAL_FLAG_ERROR, + ADDITIONAL_FLAG_REGEX, +} from "@dokploy/server/db/validations/destination"; import { S3_PROVIDERS } from "./constants"; const addDestination = z.object({ @@ -47,7 +51,14 @@ const addDestination = z.object({ endpoint: z.string().min(1, "Endpoint is required"), serverId: z.string().optional(), additionalFlags: z - .array(z.object({ value: z.string().min(1, "Flag cannot be empty") })) + .array( + z.object({ + value: z + .string() + .min(1, "Flag cannot be empty") + .regex(ADDITIONAL_FLAG_REGEX, ADDITIONAL_FLAG_ERROR), + }), + ) .optional(), }); @@ -140,9 +151,12 @@ export const HandleDestinations = ({ destinationId }: Props) => { } setOpen(false); }) - .catch(() => { + .catch((e) => { toast.error( `Error ${destinationId ? "Updating" : "Creating"} the Destination`, + { + description: e.message, + }, ); }); }; @@ -154,6 +168,7 @@ export const HandleDestinations = ({ destinationId }: Props) => { "secretAccessKey", "bucket", "endpoint", + "additionalFlags", ]); if (!result) { diff --git a/apps/dokploy/server/api/routers/destination.ts b/apps/dokploy/server/api/routers/destination.ts index 7f0c3bc18..9f528c16c 100644 --- a/apps/dokploy/server/api/routers/destination.ts +++ b/apps/dokploy/server/api/routers/destination.ts @@ -169,7 +169,14 @@ export const destinationRouter = createTRPCRouter({ }); return result; } catch (error) { - throw error; + throw new TRPCError({ + code: "BAD_REQUEST", + message: + error instanceof Error + ? error?.message + : "Error connecting to bucket", + cause: error, + }); } }), }); diff --git a/packages/server/src/db/schema/destination.ts b/packages/server/src/db/schema/destination.ts index d7b13d99f..c479679fe 100644 --- a/packages/server/src/db/schema/destination.ts +++ b/packages/server/src/db/schema/destination.ts @@ -3,6 +3,10 @@ import { pgTable, text, timestamp } from "drizzle-orm/pg-core"; import { createInsertSchema } from "drizzle-zod"; import { nanoid } from "nanoid"; import { z } from "zod"; +import { + ADDITIONAL_FLAG_ERROR, + ADDITIONAL_FLAG_REGEX, +} from "../validations/destination"; import { organization } from "./account"; import { backups } from "./backups"; @@ -45,7 +49,9 @@ const createSchema = createInsertSchema(destinations, { endpoint: z.string(), secretAccessKey: z.string(), region: z.string(), - additionalFlags: z.array(z.string()).default([]), + additionalFlags: z + .array(z.string().regex(ADDITIONAL_FLAG_REGEX, ADDITIONAL_FLAG_ERROR)) + .default([]), }); export const apiCreateDestination = createSchema diff --git a/packages/server/src/db/validations/destination.ts b/packages/server/src/db/validations/destination.ts new file mode 100644 index 000000000..d342646b4 --- /dev/null +++ b/packages/server/src/db/validations/destination.ts @@ -0,0 +1,3 @@ +export const ADDITIONAL_FLAG_REGEX = /^--[a-zA-Z0-9-]+(=[a-zA-Z0-9._:/@-]+)?$/; +export const ADDITIONAL_FLAG_ERROR = + "Invalid flag format. Must start with -- (e.g. --s3-sign-accept-encoding=false)"; diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 4ccdb0b99..22e8872bd 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -1,6 +1,7 @@ export * from "./auth/random-password"; export * from "./constants/index"; export * from "./db/constants"; +export * from "./db/validations/destination"; export * from "./db/validations/domain"; export * from "./db/validations/index"; export * from "./lib/auth";