diff --git a/README.md b/README.md index b6cd0e73..23c6e483 100644 --- a/README.md +++ b/README.md @@ -1,64 +1,320 @@ -# atomcms-next +# AtomCMS — Next.js -AtomCMS (Laravel) converted to **Next.js 16** (App Router) + **Prisma 7** against the -same Arcturus-emulator MySQL/MariaDB database. Auth via NextAuth (argon2id/bcrypt + -md5→argon2id upgrade), RCON to the emulator, full public site + admin panel. +AtomCMS (originally Laravel) converted to **Next.js 16** (App Router) with **Prisma 7** against the same Arcturus Morningstar MySQL/MariaDB database. +NextAuth for authentication (argon2id/bcrypt + md5→argon2id upgrade), RCON to the emulator, full public site + admin panel. -## Try it now (no database) +--- -The dev/preview server is already running — open: +## Requirements -> **http://localhost:3000** +| Component | Version | +|---|---| +| Node.js | >= 22 | +| pnpm | >= 10.33.4 | +| MySQL / MariaDB | 8.0+ / 10.6+ | +| Redis | optional (caching / rate limiting) | -Public pages render with fallback defaults (empty data). Login / register / admin -need a database (below). +--- -## Try it for real (your AtomCMS database) +## 1. Database Setup -Point it at your live (or a copy of your) AtomCMS database to log in with real -accounts and see real data: +This CMS **shares** the database with the Arcturus Morningstar emulator. +You need an existing (or empty) database. -1. Edit `atomcms-next/.env`: - ```dotenv - DATABASE_URL=mysql://USER:PASSWORD@HOST:3306/DBNAME - DATABASE_CONNECT_TIMEOUT_MS=10000 - AUTH_SECRET=any-long-random-string-at-least-32-chars - HOTEL_NAME=YourHotel - # Optional emulator link (for RCON: give credits, ban, motto, disconnect): - RCON_HOST=127.0.0.1 - RCON_PORT=3001 - ``` -2. Restart the server (`pnpm -C atomcms-next start`, or `pnpm dev`). -3. Log in at `/login` with any existing account. Staff (rank ≥ `min_staff_rank`, - default 7) get the **/admin** panel. New users can `/register`. +**Create a new database:** -It reads the schema you already have — no migrations are run against the emulator -tables (introspect/conform only). `prisma generate` is already done; if you add -tables, `pnpm -C atomcms-next prisma:generate`. - -## Run it yourself - -```bash -cd atomcms-next -pnpm install # already done -pnpm dev # dev server (hot reload) on :3000 -# or: -pnpm build && pnpm start # production -pnpm typecheck # tsc --noEmit -pnpm test # vitest (unit tests) +```sql +CREATE DATABASE IF NOT EXISTS atomcms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ``` -## What's built +**Use an existing emulator database:** +Point `DATABASE_URL` to your existing database — the CMS reads the emulator tables (`users`, `users_currency`, `bans`, etc.) directly. -- **Public:** home, news (+comments/reactions), shop, marketplace, community, - rankings, staff, photos, guilds, rares, leaderboard, help (+tickets), profile - `/u/` (badges/photos/guestbook), client launcher `/client` (SSO ticket), - login / register / logout, settings, voucher redeem. -- **Admin (`/admin`, staff-gated):** users (give currency/motto/rank/alert/kick via - RCON), rooms, articles, catalog, vouchers, badges, radio, achievements, - rare-values, photos, bans, applications, word-filter, IP, logs, teams, - housekeeping, permissions, emulator config, email templates, calendar, - subscriptions, CMS settings. -- **Core:** Prisma data layer (190 models), NextAuth auth core (byte-compatible - argon2id/bcrypt/md5 + SSO ticket + Laravel encrypter + TOTP), RCON client + - currency service, atom visual theme (self-hosted Nunito). +**Create CMS tables:** +After configuring `.env`, run the migration script (step 5). This only creates CMS-owned tables (`website_*`, `radio_*`, etc.). + +--- + +## 2. Environment Variables + +Copy `.env.example` to `.env` and fill in: + +```bash +cp .env.example .env +``` + +### Required + +```dotenv +DATABASE_URL=mysql://user:password@127.0.0.1:3306/atomcms +AUTH_SECRET= # at least 32 chars, random string +HOTEL_NAME=YourHotel +APP_URL=http://localhost:3000 +``` + +### Database pool (tunable) + +```dotenv +DATABASE_POOL_SIZE=40 +DATABASE_IDLE_TIMEOUT_MS=300000 +DATABASE_CONNECT_TIMEOUT_MS=10000 +``` + +### Password settings + +```dotenv +CONVERT_PASSWORDS=false # set to true to upgrade old md5 hashes to argon2id on login +PASSWORD_HASH=bcrypt # bcrypt (default) or argon2id +``` + +### Laravel APP_KEY (for 2FA) + +Only needed to read existing **Laravel-encrypted 2FA secrets**: + +```dotenv +APP_KEY=base64:xxxxxxxxxxxxxxxxxxxxxxxxxxxxx== +``` + +### RCON (emulator link) + +For live credits, badges, motto changes, rank changes, kick/ban: + +```dotenv +RCON_HOST=127.0.0.1 +RCON_PORT=3001 +``` + +### Badge upload (emulator directory) + +```dotenv +BADGE_UPLOAD_DIR=/path/to/emulator/assets/c_images/album1584 +``` + +### Email (password reset / notifications) + +Two options — **Resend** (recommended, simple) or **SMTP**: + +```dotenv +# Resend (preferred) +RESEND_API_KEY=re_xxxxxxxxxxxxxxxxxxxx + +# OR SMTP: +SMTP_HOST=smtp.example.com +SMTP_PORT=587 +SMTP_USER=user +SMTP_PASSWORD=password +SMTP_FROM=noreply@yourhotel.nl +``` + +### OAuth (Discord / Google) + +```dotenv +DISCORD_CLIENT_ID= +DISCORD_CLIENT_SECRET= +GOOGLE_CLIENT_ID= +GOOGLE_CLIENT_SECRET= +``` + +### PayPal (credit purchases) + +```dotenv +PAYPAL_CLIENT_ID= +PAYPAL_SECRET= +PAYPAL_API=https://api-m.sandbox.paypal.com # sandbox = test, live = https://api-m.paypal.com +``` + +### Redis (caching / rate limiting) + +```dotenv +REDIS_URL=redis://127.0.0.1:6379 +``` + +### AI content moderation (Comments / Guestbook) + +```dotenv +OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx +``` + +### Notifications / logging + +```dotenv +DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/... +ALERT_EMAIL=admin@yourhotel.nl +LOG_LEVEL=info # debug | info | warn | error +``` + +### Emulator JAR backup (jobs worker) + +```dotenv +EMULATOR_JAR_PATH=/path/to/emulator.jar +EMULATOR_BACKUP_DIR=/path/to/backups +EMULATOR_BACKUP_KEEP=7 # number of backups to keep +``` + +--- + +## 3. Install Dependencies + +```bash +pnpm install +``` + +--- + +## 4. Generate Prisma Client + +```bash +pnpm prisma:generate +``` + +This generates TypeScript types in `src/generated/prisma/`. + +--- + +## 5. Run CMS Migrations + +```bash +pnpm db:migrate +``` + +This executes the SQL files in `prisma/migrations/` on the database and creates the CMS tables (9 migrations). + +**Check status:** + +```bash +pnpm db:migrate:status +``` + +--- + +## 6. Configure Website Settings + +After starting (step 7) and logging in as admin: + +1. Go to **Admin → CMS Settings** (`/admin/settings`) +2. At minimum, configure: + - `hotel_name` — your hotel name + - `habbo_imaging_url` — avatar image URL (default: `https://www.habbo.com/habbo-imaging/avatarimage`) + - `nitro_client_url` — Nitro client URL (see `update-Nitrov3.sh`) + - `logo_url` — path to your logo + - `cms_favicon` — favicon URL + - `min_staff_rank` — minimum rank for admin access (default: 7) + - Optionally: theme colors, CAPTCHA, VPN blocking, etc. + +--- + +## 7. Start the Site + +### Development (hot reload) + +```bash +pnpm dev +``` + +### Production + +```bash +pnpm build && pnpm start +``` + +### TypeScript check + +```bash +pnpm typecheck +``` + +### Run tests + +```bash +pnpm test +``` + +--- + +## 8. Jobs Worker (Background Tasks) + +Run this as a persistent process (e.g. via systemd / screen / PM2): + +```bash +pnpm jobs:worker +``` + +This executes: +- **Daily at 03:00** — Emulator JAR backup (only if `EMULATOR_JAR_PATH` + `EMULATOR_BACKUP_DIR` are set) +- **Daily at 04:00** — Clean up old login logs (>30 days) and expired password reset tokens (>7 days) + +--- + +## 9. First Login + +1. Open `http://localhost:3000` in your browser +2. Register an account via `/register` **OR** log in with an existing account +3. To get admin access, your rank must be >= `min_staff_rank` (default 7) + - Set it directly in the database: `UPDATE users SET rank = 7 WHERE username = 'yourname';` +4. Go to `/admin` for the admin panel + +--- + +## Optional Integrations + +### Emulator — RCON + +For live actions (credits, badges, rank changes, kick/ban), the Arcturus emulator must be running with RCON enabled on the same `RCON_HOST:RCON_PORT`. + +### Client — Nitro + +The `/client` page loads the Nitro client. Configure the client URL in `website_settings` via **Admin → CMS Settings** (`nitro_client_url`). + +### Radio + +If you use a radio (e.g. Azuracast), configure: +- `radio_now_playing_api_url` +- `radio_listeners_api_url` + +### CAPTCHA + +Supports Cloudflare Turnstile and Google reCAPTCHA. Configure in **Admin → CMS Settings**: +- `captcha_provider` — `turnstile` or `recaptcha` +- `turnstile_site_key` / `turnstile_secret` +- `recaptcha_site_key` / `recaptcha_secret` + +### Theme + +12 preset themes available via **Admin → Theme** (`/admin/theme`), plus fully customizable colors. + +--- + +## Database Overview + +| Component | Type | Migrations | +|---|---|---| +| Emulator tables (users, items, rooms, etc.) | Existing Arcturus schema | None — CMS reads only | +| CMS tables (website_*, radio_*, etc.) | CMS-owned | `prisma/migrations/*.sql` (9 files) | +| Migration tracking | `cms_migrations` table | Auto-created | + +--- + +## Project Structure + +``` +├── prisma/ +│ ├── schema.prisma # ~190 models (emulator + CMS) +│ └── migrations/ # 9 SQL migrations for CMS tables +├── scripts/ +│ ├── apply-migrations.ts # migration runner +│ └── jobs-worker.ts # background tasks (backups, cleanup) +├── src/ +│ ├── app/ # Next.js App Router (pages + API) +│ ├── actions/ # Server Actions +│ ├── components/ # UI components (top-header, navigation, etc.) +│ ├── lib/ +│ │ ├── auth/ # NextAuth + password hashes + 2FA +│ │ ├── services/ # RCON, email, currency, PayPal, etc. +│ │ ├── prisma.ts # database connection +│ │ └── redis.ts # Redis client +│ ├── messages/ # i18n (en, nl, de, fr, es, it) +│ └── env.ts # Zod validation for environment variables +├── public/assets/ # images, icons, fonts +├── .env.example # example configuration +└── update-Nitrov3.sh # emulator + Nitro updater (Remco) +```