Initial commit: UOMysticmoon backend (Express + MariaDB + JWT)

- Layered API (router -> controller -> model -> db), serverlinkr pattern
- Public / auth / admin route groups; posts, wiki, settings, users, activity models
- JWT httpOnly-cookie auth (Secure auto-detected: LAN HTTP + Pangolin HTTPS)
- Site LIVE/MAINTENANCE mode with admin preview bypass
- Dual file+console logging (info/warn/error/debug) + HTTP access logs
- Docker Compose (app + MariaDB), schema.sql + seed, .env.example
- Verified end-to-end against MariaDB (27/27 smoke checks)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-26 20:58:32 -05:00
commit eef79e2403
41 changed files with 4195 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
const nodemailer = require('nodemailer')
require('dotenv').config()
const { SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, CONTACT_TO } = process.env
function isConfigured() {
return Boolean(SMTP_HOST && CONTACT_TO)
}
let transporter = null
function getTransporter() {
if (!transporter) {
transporter = nodemailer.createTransport({
host: SMTP_HOST,
port: Number(SMTP_PORT) || 587,
secure: Number(SMTP_PORT) === 465,
auth: SMTP_USER ? { user: SMTP_USER, pass: SMTP_PASS } : undefined,
})
}
return transporter
}
/**
* Send a contact message. If SMTP is not configured, signals the caller to fall
* back to a mailto: link instead of throwing. Credentials come from env only.
*/
async function sendContactMessage({ name, email, message }) {
if (!isConfigured()) {
return { sent: false, fallback: 'mailto', email: CONTACT_TO || null }
}
await getTransporter().sendMail({
from: SMTP_USER || CONTACT_TO,
to: CONTACT_TO,
replyTo: email,
subject: `UOMysticmoon contact from ${name || 'a visitor'}`,
text: `From: ${name || 'unknown'} <${email || 'no email'}>\n\n${message}`,
})
return { sent: true }
}
module.exports = { isConfigured, sendContactMessage }