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.
This commit is contained in:
Mauricio Siu
2026-03-29 08:58:42 -06:00
parent e38f07d286
commit 8ccdb66ced
5 changed files with 36 additions and 4 deletions

View File

@@ -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) {

View File

@@ -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,
});
}
}),
});

View File

@@ -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

View File

@@ -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)";

View File

@@ -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";