initialize generic rms-software repository
Add the reusable RMS core application (server, web UI, plugins, tests, tools) with generic defaults, GPL licensing, and maintainer context documentation so deployments can consume this repo as software source independent of station-specific overlays.
This commit is contained in:
101
plugins/rms.auth.smtp_relay/index.js
Normal file
101
plugins/rms.auth.smtp_relay/index.js
Normal file
@@ -0,0 +1,101 @@
|
||||
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
|
||||
};
|
||||
Reference in New Issue
Block a user