109 lines
3.3 KiB
JavaScript
109 lines
3.3 KiB
JavaScript
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;
|
|
let smtpError = "";
|
|
try {
|
|
delivered = await deliverViaSmtp(entry);
|
|
} catch (error) {
|
|
smtpError = String(error && error.message ? error.message : error);
|
|
entry.smtpError = smtpError;
|
|
}
|
|
entry.delivered = delivered;
|
|
entry.transport = delivered ? "smtp" : "outbox-fallback";
|
|
await ctx.appendMailOutbox(entry);
|
|
return {
|
|
ok: true,
|
|
delivered,
|
|
transport: delivered ? "smtp" : "outbox-fallback",
|
|
smtpError: smtpError || null
|
|
};
|
|
},
|
|
async health() {
|
|
const config = readTransportConfig();
|
|
if (config.host && !nodemailer) {
|
|
return { ok: false, message: "nodemailer nicht installiert" };
|
|
}
|
|
return { ok: true };
|
|
}
|
|
};
|
|
}
|
|
|
|
module.exports = {
|
|
createPlugin
|
|
};
|