Enforce required on string/multiselect variables without explicit bounds
required:true only worked by accident: a bare z.string() or z.array(...) accepts "" / [] just fine, so a required field with no minLength (e.g. secret tokens like webhookToken, apiKey) could be submitted empty and the run would start anyway. Required now implies min(1) when no stricter bound is already configured, for both string and multiselect fields. This is the single schema shared by the client form resolver and the server run-creation route, so both now reject it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,12 @@ function fieldSchema(variable: VariableConfig): z.ZodTypeAny {
|
|||||||
switch (variable.type) {
|
switch (variable.type) {
|
||||||
case "string": {
|
case "string": {
|
||||||
let s = z.string();
|
let s = z.string();
|
||||||
if (variable.minLength !== undefined) s = s.min(variable.minLength);
|
// `required` alone has to reject "" even when the author didn't set an explicit
|
||||||
|
// minLength - otherwise an empty string satisfies a bare z.string() and the run starts
|
||||||
|
// with a "required" field effectively unset.
|
||||||
|
const minLength =
|
||||||
|
variable.minLength ?? (variable.required ? 1 : undefined);
|
||||||
|
if (minLength !== undefined) s = s.min(minLength);
|
||||||
if (variable.maxLength !== undefined) s = s.max(variable.maxLength);
|
if (variable.maxLength !== undefined) s = s.max(variable.maxLength);
|
||||||
if (variable.pattern) s = s.regex(new RegExp(variable.pattern));
|
if (variable.pattern) s = s.regex(new RegExp(variable.pattern));
|
||||||
field = s;
|
field = s;
|
||||||
@@ -26,10 +31,13 @@ function fieldSchema(variable: VariableConfig): z.ZodTypeAny {
|
|||||||
case "enum":
|
case "enum":
|
||||||
field = z.enum(variable.choices as [string, ...string[]]);
|
field = z.enum(variable.choices as [string, ...string[]]);
|
||||||
break;
|
break;
|
||||||
case "multiselect":
|
case "multiselect": {
|
||||||
field = z.array(z.enum(variable.choices as [string, ...string[]]));
|
let arr = z.array(z.enum(variable.choices as [string, ...string[]]));
|
||||||
|
if (variable.required) arr = arr.min(1);
|
||||||
|
field = arr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!variable.required) {
|
if (!variable.required) {
|
||||||
field = field.optional().or(z.literal(""));
|
field = field.optional().or(z.literal(""));
|
||||||
|
|||||||
Reference in New Issue
Block a user