# MU Online API Bridge

Secure Node.js service that sits between the **MU Online MSSQL database** and the **public website** (TanStack Worker on Cloudflare).

The website never connects directly to MSSQL — it only talks to this bridge over HTTPS, with every request signed by HMAC-SHA256 so unauthorized clients are rejected even if they discover the URL.

---

## What this bridge does

| Endpoint                        | Method | Purpose                                                 | DB access |
|--------------------------------|--------|---------------------------------------------------------|-----------|
| `GET  /health`                 | GET    | Liveness probe (no signature required)                  | none      |
| `GET  /api/server-status`      | GET    | Online player count + server time                       | read      |
| `GET  /api/rankings/players`   | GET    | Top players (?season=&limit=)                           | read      |
| `GET  /api/rankings/guilds`    | GET    | Top guilds                                              | read      |
| `GET  /api/rankings/classes`   | GET    | Class population stats                                  | read      |
| `POST /api/account/check`      | POST   | Check if username/email is taken                        | read      |
| `POST /api/account/create`     | POST   | Register new account (MU password hash on this side)    | write     |
| `POST /api/account/verify`     | POST   | Verify credentials (used by website login)              | read      |
| `POST /api/shop/credit`        | POST   | Credit cash shop points after a verified purchase       | write     |
| `POST /api/shop/grant-item`    | POST   | Add item to a character's vault                         | write     |

All `/api/*` endpoints require **two headers**:
- `X-Bridge-Key:    <BRIDGE_API_KEY>`
- `X-Bridge-Signature: <hex-hmac-sha256(timestamp + "." + method + "." + path + "." + body, BRIDGE_HMAC_SECRET)>`
- `X-Bridge-Timestamp: <unix-seconds>` — rejected if older than 60s (prevents replay attacks)

---

## Setup on `162.19.247.50`

```bash
# 1. Copy this folder to the server
scp -r api-bridge/ user@162.19.247.50:/opt/muonline-api/

# 2. SSH in
ssh user@162.19.247.50
cd /opt/muonline-api

# 3. Install Node 20+ if not present
# (Windows: download from nodejs.org. Linux: nvm install 20)

# 4. Install dependencies
npm install

# 5. Create .env file (NEVER commit this)
cp .env.example .env
nano .env   # fill in real values, see below

# 6. Test it
npm start
# → Bridge listening on :8080

# 7. Register as a service (Linux systemd shown; on Windows use NSSM)
sudo cp deploy/muonline-api.service /etc/systemd/system/
sudo systemctl enable --now muonline-api
sudo systemctl status muonline-api

# 8. Put it behind HTTPS
# Easiest: install Caddy, point a subdomain (e.g. api.yourmu.com) at this server,
# Caddy auto-issues a TLS cert and proxies to localhost:8080.
# See deploy/Caddyfile for an example.
```

---

## .env values

```bash
# MSSQL connection — these stay ON THIS MACHINE, never leave it
SQL_DB_HOST=162.19.247.50
SQL_DB_PORT=1433
SQL_DB_NAME=MuOnline
SQL_DB_USER=mu_web_api          # ← create a dedicated user, NOT sa
SQL_DB_PASS=<strong-password>

# HTTP bridge auth — share these with the Lovable site as Cloud secrets
BRIDGE_API_KEY=<random-32-byte-hex>
BRIDGE_HMAC_SECRET=<random-64-byte-hex>

# Optional
BRIDGE_PORT=8080
BRIDGE_ALLOWED_ORIGINS=https://yourmu.com,https://yourproject.lovable.app
NODE_ENV=production
```

Generate secrets:
```bash
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"  # API key
node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"  # HMAC secret
```

---

## ⚠️ Security checklist (READ THIS)

1. **Stop using `sa`.** Create a dedicated SQL user with the minimum needed grants. SQL script in `deploy/sql/01-create-web-user.sql`.
2. **Block port 1433 at the firewall** from the public internet. Only `localhost` should reach MSSQL.
3. **Only port 443** (HTTPS for the bridge) should be public.
4. **Never put the bridge URL in client-side code.** It is called only from server functions.
5. **Rotate `BRIDGE_HMAC_SECRET`** if you ever suspect it leaked. Update on both sides.
6. **Adjust `dbo.MEMB_INFO` columns** in `src/queries.js` to match your specific MU server build (Season 6, GMO, etc.) — column names differ between distributions.

---

## Customizing for your MU build

This bridge ships with **standard Season 6 schema queries**. If your server uses a custom build (custom guild table, custom rankings formula, etc.) edit `src/queries.js`. All SQL is centralized there.
