# AtomCMS — Next.js 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. --- ## Requirements | Component | Version | |---|---| | Node.js | >= 22 | | pnpm | >= 10.33.4 | | MySQL / MariaDB | 8.0+ / 10.6+ | | Redis | optional (caching / rate limiting) | --- ## 1. Database Setup This CMS **shares** the database with the Arcturus Morningstar emulator. You need an existing (or empty) database. **Create a new database:** ```sql CREATE DATABASE IF NOT EXISTS atomcms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ``` **Use an existing emulator database:** Point `DATABASE_URL` to your existing database — the CMS reads the emulator tables (`users`, `users_currency`, `bans`, etc.) directly. **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) ```