100 lines
3.3 KiB
TypeScript
100 lines
3.3 KiB
TypeScript
import nodemailer from "nodemailer";
|
|
import type SMTPTransport from "nodemailer/lib/smtp-transport";
|
|
import type { SmtpSettings } from "@/lib/admin/types";
|
|
import { getSmtpSettings, isSmtpConfigured, updateSmtpDeliveryStatus, updateSmtpTestStatus } from "./config";
|
|
import { contactTemplate, repairTemplate, testTemplate } from "./templates";
|
|
import type { ContactMailInput, MailSendResult, RepairMailInput } from "./types";
|
|
|
|
function sanitizeMailError(error: unknown) {
|
|
const message = error instanceof Error ? error.message : "Unbekannter SMTP-Fehler";
|
|
return message
|
|
.replace(/AUTH PLAIN\s+\S+/gi, "AUTH PLAIN [redacted]")
|
|
.replace(/AUTH LOGIN\s+\S+/gi, "AUTH LOGIN [redacted]")
|
|
.replace(/password[=:]\S+/gi, "password=[redacted]")
|
|
.slice(0, 500);
|
|
}
|
|
|
|
function createTransport(settings: SmtpSettings) {
|
|
const secure = settings.security === "tls";
|
|
const requireTLS = settings.security === "starttls";
|
|
const options: SMTPTransport.Options = {
|
|
host: settings.host,
|
|
port: Number(settings.port),
|
|
secure,
|
|
requireTLS,
|
|
auth: {
|
|
user: settings.username,
|
|
pass: settings.password,
|
|
},
|
|
};
|
|
|
|
if (settings.security === "none") {
|
|
options.auth = settings.username && settings.password ? options.auth : undefined;
|
|
options.ignoreTLS = true;
|
|
}
|
|
|
|
return nodemailer.createTransport(options);
|
|
}
|
|
|
|
async function sendConfiguredMail(input: {
|
|
subject: string;
|
|
text: string;
|
|
html: string;
|
|
replyTo?: string;
|
|
}): Promise<MailSendResult> {
|
|
const settings = await getSmtpSettings();
|
|
if (!isSmtpConfigured(settings)) return { ok: false, error: "SMTP nicht konfiguriert." };
|
|
|
|
try {
|
|
const transport = createTransport(settings);
|
|
await transport.sendMail({
|
|
from: settings.fromAddress,
|
|
to: settings.recipientAddress,
|
|
bcc: settings.bccAddress || undefined,
|
|
replyTo: input.replyTo || settings.replyToAddress || undefined,
|
|
subject: input.subject,
|
|
text: input.text,
|
|
html: input.html,
|
|
});
|
|
return { ok: true };
|
|
} catch (error) {
|
|
return { ok: false, error: sanitizeMailError(error) };
|
|
}
|
|
}
|
|
|
|
export async function sendTestMail() {
|
|
const template = testTemplate();
|
|
const result = await sendConfiguredMail(template);
|
|
await updateSmtpTestStatus({
|
|
lastTestAt: new Date().toISOString(),
|
|
lastTestStatus: result.ok ? "success" : "error",
|
|
lastError: result.ok ? "" : result.error,
|
|
});
|
|
return result;
|
|
}
|
|
|
|
export async function sendContactInquiryMail(input: ContactMailInput) {
|
|
const template = contactTemplate(input);
|
|
const result = await sendConfiguredMail({ ...template, replyTo: input.email });
|
|
if (result.error !== "SMTP nicht konfiguriert.") {
|
|
await updateSmtpDeliveryStatus({
|
|
lastDeliveryAt: new Date().toISOString(),
|
|
lastDeliveryStatus: result.ok ? "success" : "error",
|
|
lastError: result.ok ? "" : result.error,
|
|
});
|
|
}
|
|
return result;
|
|
}
|
|
|
|
export async function sendRepairInquiryMail(input: RepairMailInput) {
|
|
const template = repairTemplate(input);
|
|
const result = await sendConfiguredMail({ ...template, replyTo: input.email });
|
|
if (result.error !== "SMTP nicht konfiguriert.") {
|
|
await updateSmtpDeliveryStatus({
|
|
lastDeliveryAt: new Date().toISOString(),
|
|
lastDeliveryStatus: result.ok ? "success" : "error",
|
|
lastError: result.ok ? "" : result.error,
|
|
});
|
|
}
|
|
return result;
|
|
}
|