lomavuokraus/lib/mailer.ts
2025-11-24 18:55:07 +02:00

87 lines
2.8 KiB
TypeScript

import fs from 'fs';
import nodemailer from 'nodemailer';
import type SMTPTransport from 'nodemailer/lib/smtp-transport';
import path from 'path';
type MailOptions = {
to: string;
subject: string;
text: string;
html?: string;
};
async function createTransport() {
const {
SMTP_HOST,
SMTP_PORT,
SMTP_USER,
SMTP_PASS,
SMTP_FROM,
SMTP_TLS,
SMTP_SSL,
SMTP_REJECT_UNAUTHORIZED,
DKIM_SELECTOR,
DKIM_DOMAIN,
DKIM_PRIVATE_KEY_PATH,
} = process.env;
if (!SMTP_HOST || !SMTP_PORT || !SMTP_USER || !SMTP_PASS || !SMTP_FROM) {
throw new Error('SMTP configuration is missing required environment variables');
}
const secure = SMTP_SSL === 'true';
const requireTLS = SMTP_TLS === 'true';
const transporterOptions: SMTPTransport.Options = {
host: SMTP_HOST,
port: Number(SMTP_PORT),
secure,
requireTLS,
auth: { user: SMTP_USER, pass: SMTP_PASS },
};
if (SMTP_REJECT_UNAUTHORIZED === 'false') {
transporterOptions.tls = { rejectUnauthorized: false };
}
if (DKIM_SELECTOR && DKIM_DOMAIN && DKIM_PRIVATE_KEY_PATH) {
const keyPath = path.resolve(process.cwd(), DKIM_PRIVATE_KEY_PATH);
if (fs.existsSync(keyPath)) {
transporterOptions.dkim = {
domainName: DKIM_DOMAIN,
keySelector: DKIM_SELECTOR,
privateKey: fs.readFileSync(keyPath, 'utf8'),
};
}
}
return nodemailer.createTransport(transporterOptions);
}
let cachedTransport: nodemailer.Transporter | null = null;
async function getTransport() {
if (cachedTransport) return cachedTransport;
cachedTransport = await createTransport();
return cachedTransport;
}
export async function sendMail({ to, subject, text, html }: MailOptions) {
const transporter = await getTransport();
const from = process.env.SMTP_FROM!;
return transporter.sendMail({ from, to, subject, text, html: html ?? text });
}
export async function sendVerificationEmail(to: string, link: string) {
const subject = 'Verify your email for lomavuokraus.fi';
const text = `Please verify your email by visiting: ${link}\n\nIf you did not request this, you can ignore this email.`;
const html = `<p>Please verify your email by clicking <a href="${link}">this link</a>.</p><p>If you did not request this, you can ignore this email.</p>`;
return sendMail({ to, subject, text, html });
}
export async function sendPasswordResetEmail(to: string, link: string) {
const subject = 'Reset your password for lomavuokraus.fi';
const text = `We received a request to reset your password.\n\nReset here: ${link}\n\nIf you did not request this, you can ignore this email.`;
const html = `<p>We received a request to reset your password.</p><p><a href="${link}">Reset your password</a></p><p>If you did not request this, you can ignore this email.</p>`;
return sendMail({ to, subject, text, html });
}