Files
CubeAdmin/lib/email/index.ts
2026-03-08 17:31:33 +01:00

60 lines
1.6 KiB
TypeScript

import nodemailer from "nodemailer";
import { render } from "@react-email/render";
import { InvitationEmail } from "./templates/invitation";
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,
token: _token,
}: {
email: string;
url: string;
token: string;
}): Promise<void> {
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.`,
});
}
export async function sendInvitationEmail({
to,
invitedByName,
inviteUrl,
role,
}: {
to: string;
invitedByName: string;
inviteUrl: string;
role: string;
}): Promise<void> {
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.`,
});
}