fix: Add better validation for sender email
This commit is contained in:
@@ -186,7 +186,7 @@
|
|||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": ["to"],
|
"required": ["to", "from"],
|
||||||
"properties": {
|
"properties": {
|
||||||
"to": {
|
"to": {
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
@@ -277,7 +277,7 @@
|
|||||||
"description": "Sender with name and email"
|
"description": "Sender with name and email"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Custom from address (requires verified domain). Can be a string or an object with {name, email}."
|
"description": "Sender email address (requires verified domain). Required unless using a template that has a 'from' address configured. Can be a string (e.g., '[email protected]') or an object with {name, email} (e.g., {name: 'My App', email: '[email protected]'})."
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|||||||
@@ -68,7 +68,11 @@ export const ProjectSchemas = {
|
|||||||
update: z.object({
|
update: z.object({
|
||||||
name: z.string().min(1).max(100).optional(),
|
name: z.string().min(1).max(100).optional(),
|
||||||
tracking: z.nativeEnum(TrackingMode).optional(),
|
tracking: z.nativeEnum(TrackingMode).optional(),
|
||||||
language: z.string().length(2).regex(/^[a-z]{2}$/).optional(),
|
language: z
|
||||||
|
.string()
|
||||||
|
.length(2)
|
||||||
|
.regex(/^[a-z]{2}$/)
|
||||||
|
.optional(),
|
||||||
}),
|
}),
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
@@ -342,14 +346,29 @@ export const ActionSchemas = {
|
|||||||
template: uuid.optional(),
|
template: uuid.optional(),
|
||||||
subscribed: z.boolean().optional(),
|
subscribed: z.boolean().optional(),
|
||||||
name: z.string().optional(),
|
name: z.string().optional(),
|
||||||
from: z.union([
|
from: z
|
||||||
email, // Simple email string (backward compatible)
|
.union(
|
||||||
z.object({
|
[
|
||||||
// Object with name and email
|
email, // Simple email string (backward compatible)
|
||||||
name: z.string().optional(),
|
z.object({
|
||||||
email: email,
|
// Object with name and email
|
||||||
}),
|
name: z.string().optional(),
|
||||||
]),
|
email: email,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
{
|
||||||
|
errorMap: (issue, ctx) => {
|
||||||
|
if (issue.code === z.ZodIssueCode.invalid_union) {
|
||||||
|
return {
|
||||||
|
message:
|
||||||
|
'Invalid "from" field. Expected a valid email string (e.g., "[email protected]") or an object with an email field and optional name (e.g., {email: "[email protected]", name: "My App"})',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {message: ctx.defaultError};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.optional(),
|
||||||
reply: email.optional(),
|
reply: email.optional(),
|
||||||
headers: z.record(z.string().max(998)).optional(),
|
headers: z.record(z.string().max(998)).optional(),
|
||||||
data: jsonSchema.optional(),
|
data: jsonSchema.optional(),
|
||||||
@@ -364,23 +383,29 @@ export const ActionSchemas = {
|
|||||||
.max(10) // Maximum 10 attachments per email
|
.max(10) // Maximum 10 attachments per email
|
||||||
.optional(),
|
.optional(),
|
||||||
})
|
})
|
||||||
.refine(data => data.template ?? (data.subject && data.body), {
|
.superRefine((data, ctx) => {
|
||||||
message: 'Either template ID or both subject and body are required',
|
// Validate that either template or subject+body are provided
|
||||||
})
|
if (!data.template && !(data.subject && data.body)) {
|
||||||
.refine(
|
ctx.addIssue({
|
||||||
data => {
|
code: z.ZodIssueCode.custom,
|
||||||
// Validate total attachment size (sum of base64 strings should be reasonable)
|
message: 'Either template ID or both subject and body are required',
|
||||||
if (!data.attachments || data.attachments.length === 0) {
|
path: ['template'],
|
||||||
return true;
|
});
|
||||||
}
|
}
|
||||||
// Each base64 char = ~0.75 bytes, so 13.3M base64 chars ≈ 10MB actual data
|
|
||||||
|
// Validate total attachment size
|
||||||
|
if (data.attachments && data.attachments.length > 0) {
|
||||||
const totalBase64Length = data.attachments.reduce((sum, att) => sum + att.content.length, 0);
|
const totalBase64Length = data.attachments.reduce((sum, att) => sum + att.content.length, 0);
|
||||||
return totalBase64Length <= 13333333; // ~10MB limit
|
if (totalBase64Length > 13333333) {
|
||||||
},
|
// ~10MB limit
|
||||||
{
|
ctx.addIssue({
|
||||||
message: 'Total attachment size must not exceed 10MB',
|
code: z.ZodIssueCode.custom,
|
||||||
},
|
message: 'Total attachment size must not exceed 10MB',
|
||||||
),
|
path: ['attachments'],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
verify: z.object({
|
verify: z.object({
|
||||||
email,
|
email,
|
||||||
}),
|
}),
|
||||||
|
|||||||
Reference in New Issue
Block a user