import * as aws from "@aws-sdk/client-ses"; import { defaultProvider } from "@aws-sdk/credential-provider-node"; import { render } from "@react-email/render"; import { createTransport, Transporter } from "nodemailer"; import type Mail from "nodemailer/lib/mailer"; import React from "react"; import * as templates from "./templates"; type Templates = typeof templates; type TemplateName = keyof typeof templates; type TemplateProps = React.ComponentProps< TemplateComponent >; type TemplateComponent = Templates[T]; const env = process.env["NODE" + "_ENV"] || "development"; let transport: Transporter; const getTransport = () => { if (transport) { // Reuse the transport if it exists return transport; } if (env === "test") { transport = createTransport({ port: 4025 }); return transport; } switch (process.env.EMAIL_PROVIDER) { case "ses": { const ses = new aws.SES({ region: process.env["AWS" + "_REGION"], credentialDefaultProvider: defaultProvider, }); transport = createTransport({ SES: { ses, aws, sendingRate: 10, }, }); } break; default: { const hasAuth = process.env.SMTP_USER || process.env.SMTP_PWD; transport = createTransport({ host: process.env.SMTP_HOST, port: process.env.SMTP_PORT ? parseInt(process.env.SMTP_PORT) : undefined, secure: process.env.SMTP_SECURE === "true", auth: hasAuth ? { user: process.env.SMTP_USER, pass: process.env.SMTP_PWD, } : undefined, tls: process.env.SMTP_TLS_ENABLED === "true" ? { ciphers: "SSLv3", rejectUnauthorized: false, } : undefined, }); } } return transport; }; type SendEmailOptions = { to: string; subject: string; props: TemplateProps; onError?: () => void; }; export const sendEmail = async ( templateName: T, options: SendEmailOptions, ) => { if (!process.env.SUPPORT_EMAIL) { console.info("SUPPORT_EMAIL not configured - skipping email send"); return; } const Template = templates[templateName] as TemplateComponent; const html = render(