Commit Graph

2 Commits

Author SHA1 Message Date
f8652c2399 Modernize email: Gmail OAuth2 sending, configured under Settings
Retire env-var SMTP basic-auth and send the contact form through Gmail over
OAuth2 (SMTP XOAUTH2), configured in Admin -> Settings -> Email via an in-app
"Connect Gmail" consent flow. Reuses the existing google SSO OAuth client; the
captured refresh token is stored AES-GCM-encrypted (write-only over the API,
never returned), mirroring the auth-provider and Discord-bot secret patterns.

- schema: new email_config singleton table (mirrors bot_config)
- model: emailConfig.{db,model} with encrypted refresh token + getSafe/getWithSecret
- mailer: nodemailer OAuth2 transport (client id/secret from the google provider
  row), contact recipient = contact_email setting, mailto: fallback preserved,
  plus sendTest()
- routes/controller: /admin/email config, connect start+callback (ssoState CSRF
  + PKCE), test, disconnect
- client: EmailDelivery section on the Settings page + api methods; Settings copy
  now spells out that contact_email is the delivery recipient
- docs/env: drop SMTP_*/CONTACT_TO from env examples; update README/BACKEND_DESIGN
- tests: emailConfig.model + mailer suites (8 new; full suite 142 pass)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XKeCQEJZr1AFJN4Bgcmvh3
2026-07-07 22:29:27 -05:00
eef79e2403 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>
2026-06-26 20:58:32 -05:00