A complete, secure, and modern registration portal for World of Warcraft: Mists of Pandaria (5.4.8) private servers. Built for TrinityCore-based cores (including repacks).
- Features
- Preview
- Quick Start
- One-Click Installer
- Release Packaging For The Installer
- Requirements
- Installation
- Admin Dashboard
- Customization
- Project Structure
- Security Notes
- Troubleshooting
- License
- 🔒 Security — CSRF tokens, Google reCAPTCHA v2, PDO prepared statements, PHP-execution blocking on uploads
- 🛡️ Rate Limiting — Automatic lockout after failed login attempts (configurable)
- 🗝️ Auth — SHA-1 password hashing matching the TrinityCore format
- 📧 Email — SMTP password recovery and ticket notifications via PHPMailer
- 📊 Live Stats — Real-time server status, player counts, and animated counters
- 🌍 Multilingual — English and Spanish included; easy to add more
- 🎨 Modern UI — Dark gaming theme, Bootstrap 5, responsive design
- ⚙️ Feature Flags — Toggle tickets, password recovery, reCAPTCHA, and maintenance mode from config
- 🧑💼 Admin Dashboard — Account management, ban/unban, ticket management, audit log, character lookup, IP bans, email broadcast
- 🎫 Ticket System — Database-stored support tickets with admin replies, status tracking, and user history
- 📰 News & FAQ — Configurable news section and FAQ accordion on the home page
- 🗳️ Vote System — Vote site links on the user dashboard (configurable)
- 🔗 Social Links — Discord, YouTube, X (Twitter), Instagram — each individually toggleable
# 1. Install XAMPP — https://www.apachefriends.org/
# 2. Serve this project from your Apache web root or a dedicated VirtualHost/Alias
# Do not run it from a subfolder such as /wow-legends without remapping DocumentRoot
# 3. Copy the sample config
copy config.sample.php config.php
# 4. Edit config.php with your DB credentials, realm info, site base URL, reCAPTCHA keys, etc.
# 5. Install PHP dependencies
composer install
# 6. Run the SQL setup (see Database Setup section below)
# 7. Start Apache from the XAMPP Control Panel (your repack already runs its own MySQL)
# 8. Visit the URL configured in config.php, for example http://localhost/Windows users can bootstrap a guided installer with PowerShell:
Open PowerShell as Administrator, then run:
irm "https://raw.githubusercontent.com/timoinglin/wow-mop-registration/main/install.ps1" | iexBefore running it, make sure your WoW repack is already installed and its database server is already running. The installer sets up the website and local web server; it does not install or start the repack itself.
If you do not already have a repack, you can get one from EmuCoach.
What the installer does:
- Checks that it is running as Administrator.
- Shows the prerequisites and asks whether to continue before making any changes.
- Checks whether XAMPP already exists and lets you choose whether to reuse it or stop.
- Installs XAMPP 8.2 with
wingetwhen needed. - Downloads the latest prepared release ZIP and deploys it into
C:\xampp\htdocs\. - Enables the required PHP extensions in XAMPP's
php.ini. - Creates
config.phpfromconfig.sample.phpwith safe defaults. - Prompts for database credentials, validates the MySQL server connection, verifies that the entered auth/characters database names exist, and offers to import
sql/setup.sql. - Starts Apache and opens
http://localhost/.
The installer intentionally disables advanced features in the generated config.php so the site can come up cleanly on first run:
recaptcharecover_passwordtickets
It also sets site.base_url to http://localhost and leaves social/client links empty.
After the installer finishes, open config.php and add your reCAPTCHA keys and SMTP settings before enabling those features.
Warning
The installer is designed for a fresh local XAMPP setup. If C:\xampp\htdocs\ already contains files, it offers to back them up and then replaces the web root contents so the app can run at http://localhost/.
The easiest way to run this project is with XAMPP, which bundles Apache and PHP in a single installer. Your repack already provides its own MySQL database, so you only need XAMPP for the web server.
| Requirement | Minimum | Recommended |
|---|---|---|
| PHP | 7.4 | 8.0+ |
| Apache | with mod_rewrite enabled |
Included in XAMPP |
| Composer | 2.x | Latest stable |
The following extensions must be enabled in php.ini. In XAMPP, open C:\xampp\php\php.ini, search for each extension, remove the leading ; to uncomment it, then restart Apache.
| Extension | Purpose |
|---|---|
pdo_mysql |
Database access |
openssl |
SMTP TLS/SSL for emails |
mbstring |
String handling |
hash |
SHA-1 password hashing (enabled by default in PHP 8) |
curl |
Recommended for reCAPTCHA and outbound HTTP requests |
gmp |
Big number math (optional, for SRP6) |
fileinfo |
MIME type checking for ticket attachments |
Clone the repo or download the ZIP, then serve it from your Apache site root:
C:\xampp\htdocs\
Important
This project currently uses root-relative URLs such as /login, /register, /assets/... and .htaccess rules that assume the app is mounted at the web root. If you keep the repo in a subfolder like C:\xampp\htdocs\wow-legends, configure an Apache VirtualHost or Alias so that folder is served as its own site root.
Copy config.sample.php to config.php:
config.sample.php → config.php
Open config.php and set:
| Setting | Description |
|---|---|
| Database | MySQL host, user, password, auth DB name, characters DB name |
| Realm | Realmlist address, realm name, expansion ID, server ports |
| Site | Site title, base URL |
| reCAPTCHA | Site key + secret from Google reCAPTCHA (v2 Checkbox) |
| SMTP | Email host, port, credentials for password recovery and ticket notifications |
| Client | External download link for the game client (Mega, MediaFire, etc.) |
| Social Links | Discord, YouTube, X (Twitter), Instagram URLs — leave empty to hide |
| News | Array of news entries shown on the home page |
| FAQ | Array of question/answer pairs for the FAQ accordion |
| Vote Sites | Array of vote site links shown on the user dashboard |
Tip
Common local DB credentials are often host=127.0.0.1, user=root, password=ascent, but database names vary by repack. Some installs use auth / characters, while others use mop_auth / mop_characters.
Important
Set site.base_url to the exact URL where the app is reachable. Password recovery emails build reset links from this value.
Important
The ticket system, admin audit log, and password recovery require extra tables in your auth database. Without these tables, those features will show database errors.
Open phpMyAdmin (your repack's DB manager), select the auth database, go to the SQL tab, and run the contents of sql/setup.sql:
-- This creates 3 tables:
-- 1. password_resets — for password recovery
-- 2. tickets — for the support ticket system
-- 3. admin_audit_log — for tracking admin actions
-- Compatible with MySQL 5.5.9+
-- See sql/setup.sql for the full scriptYou can also run it from the command line:
mysql -u root -pascent auth < sql/setup.sqlThe script uses CREATE TABLE IF NOT EXISTS, so it's safe to run multiple times.
The features block in config.php lets you toggle features without touching code:
'features' => [
'recaptcha' => true, // reCAPTCHA on all forms
'recover_password' => true, // Password recovery via email
'tickets' => true, // Support ticket system
'maintenance' => false, // Maintenance mode (GMs can still log in)
],
// Brute-force lockout settings (file-based, no DB table needed)
'security' => [
'max_login_attempts' => 5, // Failed attempts before lockout
'lockout_minutes' => 15, // Duration of lockout in minutes
],
// Message shown during maintenance
'maintenance_message' => 'The server is currently under maintenance.',| Flag | When false |
|---|---|
recaptcha |
reCAPTCHA widget hidden, JS not loaded, server-side check bypassed |
recover_password |
/recover and /reset_password redirect to /login; link hidden |
tickets |
/tickets redirects to /dashboard; menu item hidden |
maintenance |
All pages show a maintenance screen (GMs with level ≥ 9 are exempt) |
Social links appear in the hero section and footer. Set to empty string '' to hide any link:
'social' => [
'discord' => 'https://discord.gg/your-invite',
'youtube' => '', // hidden when empty
'twitter' => '',
'instagram' => '',
],News entries and FAQ items are also configured in config.php:
'news' => [
['title' => 'Server Launch!', 'date' => '2026-03-02', 'text' => 'We are live!', 'icon' => 'bi-megaphone'],
],
'faq' => [
['q' => 'Is it free to play?', 'a' => 'Yes, 100% free.'],
],
'vote_sites' => [
['name' => 'TopG', 'url' => 'https://topg.org/...', 'cooldown_hours' => 12],
],Run Composer after a normal clone:
composer installvendor/ is ignored by Git in this repo, so a fresh clone will not contain PHPMailer until Composer installs it. If you received a packaged copy that already includes vendor/, you can skip this step.
Pretty URLs (/login, /register) require Apache's mod_rewrite:
- Open
C:\xampp\apache\conf\httpd.conf - Find and uncomment:
LoadModule rewrite_module modules/mod_rewrite.so - Find your
<Directory>block and setAllowOverride All - Restart Apache
Accessible at /admin_dashboard for accounts with GM level ≥ 9.
| Tab | Features |
|---|---|
| Overview | Server status, registration chart (14 days), class distribution, recent bans, top characters |
| Accounts | Full account list with search/filter, inline Ban/Unban buttons, account detail modal (view chars, reset password, edit email, set GM level) |
| Tickets | View all support tickets, filter by status, reply to tickets, close/reopen |
| Audit Log | Chronological log of all admin actions (bans, unbans, edits, etc.) |
| Tools | Character lookup, IP ban management, server stats, email broadcast to all users |
All admin actions are logged to the admin_audit_log table automatically.
All user-facing text is in the lang/ folder:
lang/
├── en.php ← English
└── es.php ← Spanish
Edit the key-value pairs to change any text on the site:
// lang/en.php
'welcome' => 'Welcome to WoW Legends',
'index_lead' => 'Join our MoP private server!',Adding a new language:
- Copy
lang/en.phpto e.g.lang/de.php - Translate all values
- Add the new option to the language dropdown in
templates/header.php
All images are stored in assets/img/:
| File | Usage |
|---|---|
logo.webp |
Large hero logo on the homepage |
top-logo.webp |
Small navbar logo |
| Background images | .webp format recommended |
wow-legends/
├── .htaccess ← URL rewriting and basic hardening
├── .gitignore
├── assets/
│ ├── css/ ← style.css
│ └── img/ ← logos, backgrounds, race/class icons, screenshots
├── cache/
│ ├── login_history/ ← Per-user login history JSON files
│ └── rate_limit/ ← File-based login throttling data
├── includes/
│ ├── audit.php ← Admin audit log helper
│ ├── auth.php ← Password hashing, IP detection
│ ├── csrf.php ← CSRF token generation/validation
│ ├── db.php ← Database connections
│ ├── email.php ← PHPMailer send functions
│ ├── functions.php ← Backward-compat loader
│ ├── helpers.php ← WoW helpers (format playtime, gold, race/class names)
│ ├── lang.php ← Language loader
│ ├── login_history.php ← File-based login history helper
│ ├── rate_limiter.php ← File-based brute-force protection
│ └── recaptcha.php ← reCAPTCHA verification (respects feature flag)
├── lang/ ← Language files (en.php, es.php)
├── pages/
│ ├── admin_api.php ← AJAX API for admin actions
│ ├── admin_dashboard.php
│ ├── change_password.php
│ ├── dashboard.php
│ ├── login.php
│ ├── logout.php
│ ├── recover.php
│ ├── register.php
│ ├── reset_password.php
│ └── tickets.php
├── sql/
│ └── setup.sql ← Required tables (tickets, audit log, password resets)
├── templates/ ← header.php and footer.php
├── uploads/
│ ├── .htaccess ← Blocks PHP execution in uploads
│ └── tickets/ ← Ticket attachments
├── config.php ← Your config (gitignored)
├── config.sample.php ← Safe template to commit
├── favicon.ico
└── index.php ← Homepage / router
config.phpis in.gitignore— never commit it- The
uploads/folder has a.htaccessthat blocks PHP execution - All forms use CSRF tokens
- All DB queries use PDO prepared statements
- Directory listing is disabled via
Options -Indexes - Rate limiting protects login from brute-force attacks
- Admin actions are logged to
admin_audit_logwith IP, timestamp, and details
| Problem | Solution |
|---|---|
Links go to /login or /assets/... at the wrong location |
The app is being served from a subfolder. Serve it from the web root or map the repo folder to its own Apache VirtualHost/Alias. |
404 on /login, /register |
Enable mod_rewrite — see step 7 above |
| "Database error" on tickets or password recovery | Run sql/setup.sql on your auth database — see step 3 |
| "Invalid default value" when running SQL | Your MySQL is very old. Use the latest setup.sql which is compatible with MySQL 5.5.9+ |
| reCAPTCHA not showing | Check your site key/secret in config.php, or set recaptcha => false |
composer install fails or PHPMailer class is missing |
Install Composer dependencies in the project root. A fresh clone does not include vendor/. |
| Emails not sending | Verify SMTP credentials; for Gmail use an App Password |
| Blank page / 500 error | Check C:\xampp\php\logs\php_error_log for details |
| Admin dashboard not loading | Your account needs GM level ≥ 9 in the account_access table, and the route is /admin_dashboard |
This project is licensed under the MIT License.





