import { mkdtemp, readdir, readFile } from "node:fs/promises"
import { tmpdir } from "node:os"
import { join } from "node:path"
import pino from "pino"
import { describe, expect, it, vi } from "vitest"
import { loadConfig } from "../src/config/env.js"
import { EMAIL_TEMPLATES, type EmailTemplate, type EmailTemplates, type OrderEmailData, renderEmail } from "../src/emails/index.js"
import {
BrevoTransport,
ConsoleTransport,
EmailDeliveryError,
EmailSender,
type EmailTransport,
renderMessage,
ResendTransport,
} from "../src/services/email.js"
import { LogCapture, testConfig } from "./helpers.js"
const XSS = `&"'`
const EVIL_URL = "javascript:alert(1)"
const order: OrderEmailData = {
number: 12,
email: "cliente@example.com",
customerName: `Mario ${XSS}`,
guest: false,
items: [{ name: `Addolcitore ${XSS}`, quantity: 2, total: 238000 }],
itemTotal: 238000,
shippingTotal: 1500,
discountTotal: 0,
taxTotal: 43188,
total: 239500,
shippingAddress: ["Mario Rossi", `Via Roma 1 ${XSS}`, "20100 Milano (MI)"],
}
/** Dati di esempio per ogni template, con contenuti ostili nei campi testuali. */
const samples: { [K in EmailTemplate]: EmailTemplates[K] } = {
"verify-email": { firstName: `Mario ${XSS}`, link: "https://area.example.it/verify-email?token=abc" },
"reset-password": { firstName: `Mario ${XSS}`, link: "https://area.example.it/reset-password?token=abc" },
"register-existing": { firstName: `Mario ${XSS}`, forgotPasswordUrl: "https://area.example.it/forgot-password" },
"order-confirmation": { order, ordersUrl: "https://area.example.it/ordini" },
"order-placed-admin": { order },
"order-canceled": { order },
"order-shipped": { order, tracking: [{ number: `BRT${XSS}`, url: "https://track.example/BRT1" }] },
"quote-request-admin": {
name: `Ugo ${XSS}`,
email: "ugo@example.com",
phone: "333 1234567",
province: "TO",
summary: [{ label: "Soluzione", value: `Fotovoltaico ${XSS}` }],
adminUrl: "https://area.example.it/admin/preventivi/1",
},
"quote-request-received": {
name: `Ugo ${XSS}`,
solutionTitle: `Addolcitore ${XSS}`,
summary: [{ label: "Investimento", value: `1.500 € ${XSS}` }],
disclaimer: "Stima indicativa",
},
"quote-sent": {
firstName: `Ugo ${XSS}`,
quoteNumber: "2026-0007",
title: `Impianto FV 6 kW ${XSS}`,
amountCents: 990000,
validUntil: "2026-11-30",
link: "https://area.example.it/preventivi/7",
},
"ticket-reply": {
firstName: `Ugo ${XSS}`,
ticketSubject: `Perdita ${XSS}`,
message: `Riga 1\nRiga 2 ${XSS}`,
link: "https://area.example.it/ticket/3",
},
"staff-notification": {
title: `Nuovo ticket ${XSS}`,
intro: `Ticket da ${XSS}`,
rows: [{ label: "Oggetto", value: `Perdita ${XSS}` }],
url: "https://area.example.it/admin/ticket/1",
},
"installer-approved": { firstName: `Paolo ${XSS}`, businessName: `Impianti ${XSS}`, link: "https://area.example.it/installatori" },
"installer-rejected": { firstName: `Paolo ${XSS}`, businessName: `Impianti ${XSS}`, reason: `Motivo ${XSS}` },
"showroom-booking-confirmed": {
name: `Ugo ${XSS}`,
requestedAt: "2026-10-10T13:00:00.000Z",
people: 3,
notes: `Parcheggio ${XSS}`,
},
}
describe("template", () => {
it("c'è un esempio per ogni template registrato", () => {
expect(Object.keys(samples).sort()).toEqual([...EMAIL_TEMPLATES].sort())
})
for (const template of EMAIL_TEMPLATES) {
it(`${template}: oggetto, HTML con layout, testo; dati escapati`, () => {
const r = renderEmail(template, samples[template] as never)
expect(r.subject.length).toBeGreaterThan(5)
expect(r.subject).not.toMatch(/[\r\n]/)
expect(r.html).toMatch(/^/)
expect(r.html).toContain("ITI TECHNOLOGY")
expect(r.text).toContain("ITI TECHNOLOGY")
// Nessun contenuto ostile non escapato nell'HTML
expect(r.html).not.toContain("