SPB Git

Repository Public

e2e-smtp-sink.ts 1.6 KB 29 lines typescript

1import { appendFileSync } from "node:fs";2import { SMTPServer } from "smtp-server";3import { simpleParser } from "mailparser";45/**6 * Test-only SMTP server for the end-to-end run: accepts every message on 127.0.0.1 and appends what it received7 * (parsed) to a JSON-lines file. The application talks to it through its real SMTP transport.8 * Recipients starting with "bounce@" are rejected, to exercise the retry path.9 */10const file = process.env.SPCAL_TEST_OUTBOX ?? "/tmp/spcal-e2e-outbox.jsonl";11const port = Number(process.env.SMTP_SINK_PORT ?? 2526);12const server = new SMTPServer({13  authOptional: true, disabledCommands: ["STARTTLS"],14  onRcptTo(address, _session, cb) { cb(address.address.startsWith("bounce@") ? Object.assign(new Error("mailbox unavailable"), { responseCode: 550 }) : undefined); },15  onData(stream, _session, cb) {16    simpleParser(stream).then((m) => {17      const cal = m.attachments.find((a) => a.contentType.startsWith("text/calendar"));18      const to = Array.isArray(m.to) ? m.to[0]?.value[0]?.address : m.to?.value[0]?.address;19      appendFileSync(file, JSON.stringify({20        to, subject: m.subject, text: m.text ?? "", html: typeof m.html === "string" ? m.html : "", replyTo: m.replyTo?.value[0]?.address ?? null,21        ics: cal ? { method: /METHOD:(\w+)/.exec(cal.content.toString("utf8"))?.[1] ?? "", content: cal.content.toString("utf8") } : null,22      }) + "\n");23      cb();24    }, (e) => cb(e));25  },26});27server.listen(port, "127.0.0.1", () => console.log(`smtp sink on 127.0.0.1:${port} → ${file}`));28process.on("SIGTERM", () => server.close(() => process.exit(0)));29
Files main
Menu

Theme