Files
OE6DXD 1c6d9e8e98 make OTP plugin inherit SMTP relay configuration
Use rms.auth.smtp_relay settings as the primary source for OTP mail transport (host/port/auth/tls/from/replyTo), with existing OTP/env values only as fallback. This lets OTP delivery work immediately when relay settings are already configured.
2026-03-16 14:13:07 +01:00

126 lines
3.9 KiB
JavaScript

let nodemailer = null;
try {
nodemailer = require("nodemailer");
} catch {
nodemailer = null;
}
async function createPlugin(ctx) {
let transporter = null;
let transportKey = "";
function readTransportConfig() {
const relaySetting = typeof ctx.getPluginSetting === "function"
? (key, fallback = null) => ctx.getPluginSetting("rms.auth.smtp_relay", key, fallback)
: (_key, fallback = null) => fallback;
const host = String(
relaySetting("host", ctx.getSetting("host", ctx.env.SMTP_HOST || ""))
).trim();
const portRaw = Number(
relaySetting("port", ctx.getSetting("port", ctx.env.SMTP_PORT || 587))
);
const secure = String(
relaySetting("secure", ctx.getSetting("secure", ctx.env.SMTP_SECURE || "false"))
) === "true";
const authUser = String(
relaySetting("authUser", ctx.getSetting("authUser", ctx.env.SMTP_USER || ""))
).trim();
const authPass = String(
relaySetting("authPass", ctx.getSetting("authPass", ctx.env.SMTP_PASS || ""))
).trim();
const allowInvalidCert = String(
relaySetting("allowInvalidCert", ctx.getSetting("allowInvalidCert", ctx.env.SMTP_ALLOW_INVALID_CERT || "false"))
) === "true";
const from = String(
relaySetting("from", ctx.getSetting("from", ctx.env.SMTP_FROM || "noreply@arcg.at"))
).trim() || "noreply@arcg.at";
const replyTo = String(
relaySetting("replyTo", ctx.getSetting("replyTo", ctx.env.SMTP_REPLY_TO || ""))
).trim();
return {
host,
port: Number.isFinite(portRaw) && portRaw > 0 ? portRaw : 587,
secure,
authUser,
authPass,
allowInvalidCert,
from,
replyTo
};
}
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 transportConfig = readTransportConfig();
const entry = {
at: new Date().toISOString(),
via: "rms.auth.otp_email",
to: recipient,
from: transportConfig.from,
replyTo: transportConfig.replyTo,
subject: String(payload.subject || "ARCG OTP"),
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
};