Add more generic SMTP options

This commit is contained in:
2026-03-08 17:31:33 +01:00
parent 193fcb3791
commit 1b6848917c
4 changed files with 83 additions and 38 deletions

View File

@@ -1,13 +1,24 @@
import { Resend } from "resend";
import nodemailer from "nodemailer";
import { render } from "@react-email/render";
import { InvitationEmail } from "./templates/invitation";
function getResend(): Resend {
const key = process.env.RESEND_API_KEY;
if (!key) throw new Error("RESEND_API_KEY is not configured");
return new Resend(key);
function createTransport() {
const host = process.env.SMTP_HOST;
if (!host) throw new Error("SMTP_HOST is not configured");
return nodemailer.createTransport({
host,
port: parseInt(process.env.SMTP_PORT ?? "587"),
secure: process.env.SMTP_SECURE === "true",
auth:
process.env.SMTP_USER && process.env.SMTP_PASS
? { user: process.env.SMTP_USER, pass: process.env.SMTP_PASS }
: undefined,
});
}
const FROM = () => process.env.EMAIL_FROM ?? "CubeAdmin <noreply@example.com>";
export async function sendMagicLinkEmail({
email,
url,
@@ -17,14 +28,13 @@ export async function sendMagicLinkEmail({
url: string;
token: string;
}): Promise<void> {
const { error } = await getResend().emails.send({
from: process.env.EMAIL_FROM ?? "CubeAdmin <noreply@example.com>",
await createTransport().sendMail({
from: FROM(),
to: email,
subject: "Your CubeAdmin sign-in link",
html: `<p>Click the link below to sign in to CubeAdmin. This link expires in 1 hour.</p><p><a href="${url}">${url}</a></p>`,
text: `Sign in to CubeAdmin: ${url}\n\nThis link expires in 1 hour.`,
});
if (error) throw new Error(`Failed to send magic link email: ${error.message}`);
}
export async function sendInvitationEmail({
@@ -38,16 +48,12 @@ export async function sendInvitationEmail({
inviteUrl: string;
role: string;
}): Promise<void> {
const html = await render(
InvitationEmail({ invitedByName, inviteUrl, role }),
);
const { error } = await getResend().emails.send({
from: process.env.EMAIL_FROM ?? "CubeAdmin <noreply@example.com>",
const html = await render(InvitationEmail({ invitedByName, inviteUrl, role }));
await createTransport().sendMail({
from: FROM(),
to,
subject: `You've been invited to CubeAdmin`,
html,
text: `${invitedByName} invited you to CubeAdmin as ${role}.\n\nAccept your invitation: ${inviteUrl}\n\nThis link expires in 48 hours.`,
});
if (error) throw new Error(`Failed to send email: ${error.message}`);
}