let nodemailer = null; try { nodemailer = require("nodemailer"); } catch { nodemailer = null; } async function createPlugin(ctx) { let transporter = null; let transportKey = ""; function readTransportConfig() { const host = String(ctx.getSetting("host", ctx.env.SMTP_HOST || "")).trim(); const portRaw = Number(ctx.getSetting("port", ctx.env.SMTP_PORT || 587)); const secure = String(ctx.getSetting("secure", ctx.env.SMTP_SECURE || "false")) === "true"; const authUser = String(ctx.getSetting("authUser", ctx.env.SMTP_USER || "")).trim(); const authPass = String(ctx.getSetting("authPass", ctx.env.SMTP_PASS || "")).trim(); const allowInvalidCert = String(ctx.getSetting("allowInvalidCert", ctx.env.SMTP_ALLOW_INVALID_CERT || "false")) === "true"; return { host, port: Number.isFinite(portRaw) && portRaw > 0 ? portRaw : 587, secure, authUser, authPass, allowInvalidCert }; } async function deliverViaSmtp(entry) { const config = readTransportConfig(); if (!config.host || !nodemailer) { return false; } const key = JSON.stringify(config); if (!transporter || transportKey !== key) { transporter = nodemailer.createTransport({ host: config.host, port: config.port, secure: config.secure, auth: config.authUser ? { user: config.authUser, pass: config.authPass } : undefined, tls: config.allowInvalidCert ? { rejectUnauthorized: false } : undefined }); transportKey = key; } await transporter.sendMail({ from: entry.from, to: entry.to, replyTo: entry.replyTo || undefined, subject: entry.subject, text: entry.text, html: entry.html || undefined }); return true; } return { async execute(action, input) { if (action !== "send_challenge") { throw new Error(`Unknown action: ${action}`); } const payload = input && input.payload ? input.payload : {}; const recipient = input && input.recipient ? String(input.recipient) : ""; if (!recipient) { throw new Error("recipient missing"); } const entry = { at: new Date().toISOString(), via: "rms.auth.smtp_relay", to: recipient, from: String(ctx.getSetting("from", ctx.env.SMTP_FROM || "noreply@arcg.at")), replyTo: String(ctx.getSetting("replyTo", ctx.env.SMTP_REPLY_TO || "")), subject: String(payload.subject || "ARCG Login"), text: String(payload.text || ""), html: String(payload.html || "") }; let delivered = false; try { delivered = await deliverViaSmtp(entry); } catch (error) { entry.smtpError = String(error && error.message ? error.message : error); } entry.delivered = delivered; entry.transport = delivered ? "smtp" : "outbox-fallback"; await ctx.appendMailOutbox(entry); return { ok: true, delivered, transport: delivered ? "smtp" : "outbox-fallback" }; }, async health() { const config = readTransportConfig(); if (config.host && !nodemailer) { return { ok: false, message: "nodemailer nicht installiert" }; } return { ok: true }; } }; } module.exports = { createPlugin };