fix(email-renderer): validate basic media and spacer dimensions
Quality / quality (ubuntu-latest) (push) Failing after 0s
Quality / quality (windows-latest) (push) Canceled after 0s

This commit is contained in:
Clintchiz committed 2026-09-05 15:05:27 +05:30
1 parent 5e30d6a7d0
commit c1f4f42b21
3 files changed
+46 -10

No files matched your search

+8 -8
View File
@@ -49,13 +49,13 @@ export function ampLayoutCss(node: BlockNode): string {
return "";
}
const multilineText = (value: unknown) => html(value).replace(/\r\n?|\n/g, "<br />");
const imageDimension = (fallback: string): ValueSchema<string> => ({
const imageDimension = (fallback: string, minimum = 1): ValueSchema<string> => ({
kind: "string",
defaultValue: fallback,
parse(value = fallback, path = "value") {
return typeof value === "string" && /^\d{1,4}$/.test(value) && Number(value) > 0 && Number(value) <= 4000
return typeof value === "string" && /^\d{1,4}$/.test(value) && Number(value) >= minimum && Number(value) <= 4000
? { ok: true, value }
: { ok: false, errors: [{code:"email.image-dimension",message:"Image dimensions must be between 1 and 4000 pixels.",severity:"error",path}] };
: { ok: false, errors: [{code:"email.image-dimension",message:`Dimensions must be between ${minimum} and 4000 pixels.`,severity:"error",path}] };
},
});
const marketingImage = (node: BlockNode, target: "html" | "amp" | "mjml") => {
@@ -328,8 +328,8 @@ export const imageBlock = leaf(
object({
src: safeUrl({ schemes: ["https"] }),
alt: string({ max: 1_000, default: "" }),
width: string({ default: "600" }),
height: string({ default: "300" }),
width: imageDimension("600"),
height: imageDimension("300"),
decorative: boolean(false),
}) as never,
{
@@ -391,7 +391,7 @@ export const spacerBlock = leaf(
"content.spacer",
"Spacer",
"icon-[lucide--move-vertical]",
object({ height: string({ default: "24" }) }) as never,
object({ height: imageDimension("24", 0) }) as never,
{
emailHtml: ({ node }) =>
emailCell(
@@ -413,8 +413,8 @@ export const videoBlock = leaf(
href: safeUrl({ schemes: ["https"] }),
thumbnail: safeUrl({ schemes: ["https"] }),
alt: string({ max: 1_000, default: "Video thumbnail" }),
width: string({ default: "600" }),
height: string({ default: "338" }),
width: imageDimension("600"),
height: imageDimension("338"),
}) as never,
{
emailHtml: ({ node }) => emailCell(`<a href="${html(attrs(node).href)}" aria-label="${html(attrs(node).title)}"><img src="${html(attrs(node).thumbnail)}" alt="${html(attrs(node).alt)}" width="${html(attrs(node).width)}" height="${html(attrs(node).height)}" style="border:0;display:block;height:auto;width:100%;max-width:${html(attrs(node).width)}px;" /></a>`, node),