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,90 @@
const posts = require('../../../model/posts/posts.model')
const wiki = require('../../../model/wiki/wiki.model')
const settings = require('../../../model/settings/settings.model')
const mailer = require('../../../utils/mailer')
const log = require('../../../utils/logger')('public')
async function getSettings(req, res) {
try {
return res.json(await settings.getPublic())
} catch (err) {
return res.status(500).json({ message: 'Internal Server Error' })
}
}
async function getStatus(req, res) {
try {
return res.json({
mode: (await settings.get('site_mode')) || 'live',
status_message: (await settings.get('status_message')) || '',
})
} catch (err) {
return res.status(500).json({ message: 'Internal Server Error' })
}
}
async function getPosts(req, res) {
const { category } = req.params
if (!posts.isValidUrlCategory(category)) {
return res.status(404).json({ message: 'Unknown category' })
}
try {
return res.json(await posts.listPublished(category))
} catch (err) {
return res.status(500).json({ message: 'Internal Server Error' })
}
}
async function getPost(req, res) {
const { category, idOrSlug } = req.params
if (!posts.isValidUrlCategory(category)) {
return res.status(404).json({ message: 'Unknown category' })
}
try {
const post = await posts.getPublished(category, idOrSlug)
if (!post) return res.status(404).json({ message: 'Not found' })
return res.json(post)
} catch (err) {
return res.status(500).json({ message: 'Internal Server Error' })
}
}
async function getWikiList(req, res) {
try {
return res.json(await wiki.list())
} catch (err) {
return res.status(500).json({ message: 'Internal Server Error' })
}
}
async function getWikiPage(req, res) {
try {
const page = await wiki.getBySlug(req.params.slug)
if (!page) return res.status(404).json({ message: 'Not found' })
return res.json(page)
} catch (err) {
return res.status(500).json({ message: 'Internal Server Error' })
}
}
async function contact(req, res) {
const { name, email, message } = req.body
try {
const result = await mailer.sendContactMessage({ name, email, message })
return res.json(result)
} catch (err) {
log.error('contact send failed', err)
return res.status(502).json({ message: 'Could not send message right now.' })
}
}
module.exports = {
getSettings,
getStatus,
getPosts,
getPost,
getWikiList,
getWikiPage,
contact,
}