# V1PER X BOT — Namecheap Shared Hosting (cPanel / Node.js Selector)

> Namecheap shared hosting uses **CloudLinux + Node.js Selector (Setup Node.js App)** and does NOT allow node-gyp native compiles for most plans. We therefore use:
> - **`sql.js`** = pure-JS WASM SQLite (zero native binding needed)
> - **Prebuilt templates** = terser + javascript-obfuscator runs LOCALLY on YOUR PC before upload — never on Namecheap
> - **CommonJS (`*.cjs`)** files — avoids ESM / "type":"module" friction with old Passenger / Selector versions

---

## Step 1 — Run locally ONE time (to build bundles + create first license)

On **your own computer** (Windows / macOS / Linux, Node 18+):

```bash
cd Bot
npm install --no-audit --no-fund
node scripts/prebuild-bundle.cjs                  # PROD + DEV obfuscated templates -> data/*.tpl
node scripts/create-admin-license.cjs -u "Owner" -d 365 -dev 3
# SAVE: the V1PER-XXXX-XXXX-XXXX license key it prints
```

After this, the following **READY-TO-UPLOAD** files exist:
- `data/prebuilt-bot-prod.js.tpl`
- `data/prebuilt-bot-dev.js.tpl`
- `data/license-creator-tmp.db` → RENAME this single-file DB to `data/bot.db` (or create new via admin API after upload).

---

## Step 2 — Create `.env` locally, upload after filling

```bash
cp .env.example .env
```

Use these **Namecheap-safe** settings — pick Node 20 LTS in cPanel Selector:

```env
NODE_ENV=production
PORT=0
DATABASE_PATH=./data/bot.db
JWT_SECRET=<48+ random chars>
SESSION_SECRET=<another 48+ random chars>
ADMIN_SECRET=<another 48+ random chars>
ALLOWED_ORIGINS=*
SESSION_TTL_MINUTES=30
RATE_LIMIT_AUTH_WINDOW_MS=900000
RATE_LIMIT_AUTH_MAX=15
BOT_VERSION=1.1.0-sharedhost
```

---

## Step 3 — Namecheap cPanel → Setup Node.js App

1. Login to cPanel (namecheap.com → Account → Login to cPanel).
2. Find the icon **Setup Node.js App** (under SOFTWARE section).
3. Click **Create Application** (top right).
4. Fill the form:
   | Field | Value |
   |---|---|
   | Node.js version | **20.x (LTS, even)** |
   | Application mode | Production |
   | Application root | `v1per-bot` (create a new folder BELOW `public_html`, **not inside it**) |
   | Application URL | Select the domain / subdomain (e.g. `bot.asmonix.com`). If you need HTTPS on the subdomain, first add the subdomain in cPanel → **Domains** + enable **AutoSSL** → **Run AutoSSL** after a few minutes. |
   | Application startup file | `server.cjs` |
5. Click **Create** (do NOT click `Run NPM Install` — we upload `node_modules` preinstalled).
6. After creation you'll see: **App root directory**: `/home/youruser/v1per-bot` and a **`source` helper** command `source /home/youruser/nodevenv/v1per-bot/20/bin/activate && cd /home/youruser/v1per-bot` — copy it for later, but Namecheap's UI already activates the env automatically for your app.

---

## Step 4 — Upload project via cPanel File Manager / FTP

Use **cPanel File Manager** (or FileZilla FTP) to upload:

```
/home/youruser/v1per-bot/            (Application root from Step 3)
├── server.cjs                       ← entry point (Passenger uses this)
├── package.json
├── .env                             ← Step 2 (CHMOD 600 after upload via File Manager → Permissions)
├── .htaccess                        ← upload it into public_html BOT DOCROOT (see Step 5)
├── bot.js                           ← 401 stub (harmless; server.cjs also returns 401 on /bot.js)
├── bot.txt / bot3.txt               ← DO NOT NEED inside public_html (they're under app root, blocked by .htaccess public paths above)
├── public/
│   └── loader.js                    ← auth UI loader
├── server/
│   ├── db.cjs
│   ├── auth.cjs
│   ├── admin.cjs
│   ├── botDelivery.cjs
│   ├── security.cjs
│   └── rateLimit.cjs
├── data/
│   ├── prebuilt-bot-prod.js.tpl     ← prebuilt from Step 1
│   ├── prebuilt-bot-dev.js.tpl
│   └── bot.db                       ← your sqlite DB (CHMOD 600). From Step 1, rename license-creator-tmp.db
└── node_modules/                    ← entire folder uploaded from your local install
```

### How to upload `node_modules/`

Namecheap shared hosting does **not** allow `npm install` with native bindings for many plans. Safest:

1. Locally, zip `node_modules/` into `node_modules.zip`.
2. Upload via File Manager → `v1per-bot/` → Upload.
3. In File Manager, right click the zip → Extract.

Make sure `node_modules/sql.js/dist/sql-wasm.wasm` exists after extraction — it's the WASM binary for SQLite.

### `.env` permissions

```
File Manager → select .env → Permissions → 0600 (rw-------)
File Manager → select data/bot.db → Permissions → 0600 (rw-------)
```

---

## Step 5 — Map domain to the Node app

Namecheap **Setup Node.js App** creates a Passenger mapping automatically. However, if the bot lives on a **subdomain** and you want extra protection:

1. Put `.htaccess` **inside the DOCROOT of bot.asmonix.com** (e.g. `/home/youruser/public_html/bot` OR `/home/youruser/bot.asmonix.com` depending on your subdomain mapping). Do NOT delete any Passenger-generated `SetHandler/SetEnv` lines that Namecheap already wrote — paste the security content **below them**.

2. Open the application again in **Setup Node.js App**, ensure the URL dropdown points to `bot.asmonix.com` / subdomain, and click **Restart** (top right stop icon → play icon).

---

## Step 6 — Verify it works

Run these from your **local PC terminal** (replace domain):

```bash
# Health
curl -s https://bot.asmonix.com/health | jq .
# -> {"ok":true,"service":"v1per-x-bot","version":"1.1.0-sharedhost"}

# Unauthorized /api/bot — must 401
curl -s -o /dev/null -w "%{http_code}\n" https://bot.asmonix.com/api/bot
# -> 401

# Old public bot.js URL — must 401
curl -s -o /dev/null -w "%{http_code}\n" https://bot.asmonix.com/bot.js
# -> 401

# Loader.js public — must 200
curl -s -o /dev/null -w "%{http_code}\n" https://bot.asmonix.com/loader.js
# -> 200

# Auth with VALID key you saved in Step 1
curl -s -X POST https://bot.asmonix.com/api/auth \
  -H "Content-Type: application/json" \
  -d '{"license_key":"V1PER-YOUR-XXXX-XXXX"}' | jq .
# -> {"success":true,"token":"...","expires_in":1800}

# Then with that token, GET /api/bot must 200 + return a large JS body (the obfuscated bot)
curl -s -H "Authorization: Bearer <TOKEN_HERE>" https://bot.asmonix.com/api/bot | wc -c
# -> Should be >= 200000 bytes (obfuscated size varies)
```

### Bookmarklet user test

1. Chrome → Bookmarks → Bookmark manager → Add new bookmark.
2. Name = `V1PER X BOT`, URL/Location =
   ```js
   javascript:(function(){var s=document.createElement('script');s.src='https://bot.asmonix.com/loader.js?'+Date.now();s.async=1;document.head.appendChild(s);})();
   ```
3. Open target page → click bookmark → green auth window appears → paste key → ACTIVATE → bot UI loads.

---

## Step 7 — Daily operations (cURL admin commands)

All work remotely from any PC — no SSH needed.

```bash
ADM="<YOUR ADMIN_SECRET from .env>"
BASE="https://bot.asmonix.com"

# Create user license (90 days, 2 devices)
curl -s -X POST $BASE/api/admin/licenses -H "X-Admin-Secret: $ADM" -H 'Content-Type: application/json' \
  -d '{"user_name":"Alice","days":90,"max_devices":2,"notes":"standard plan"}' | jq .

# List licenses
curl -s $BASE/api/admin/licenses -H "X-Admin-Secret: $ADM" | jq .

# Disable license id=7 (instantly kills sessions)
curl -s -X PATCH $BASE/api/admin/licenses/7/disable -H "X-Admin-Secret: $ADM" | jq .

# Enable again
curl -s -X PATCH $BASE/api/admin/licenses/7/enable -H "X-Admin-Secret: $ADM" | jq .

# Extend 30 days
curl -s -X PATCH $BASE/api/admin/licenses/7/extend \
  -H "X-Admin-Secret: $ADM" -H 'Content-Type: application/json' -d '{"days":30}' | jq .

# Change device limit to 5
curl -s -X PATCH $BASE/api/admin/licenses/7/device-limit \
  -H "X-Admin-Secret: $ADM" -H 'Content-Type: application/json' -d '{"max_devices":5}' | jq .

# Revoke all sessions for license id=7 (force re-auth)
curl -s -X POST $BASE/api/admin/licenses/7/revoke-sessions -H "X-Admin-Secret: $ADM" | jq .

# Delete license
curl -s -X DELETE $BASE/api/admin/licenses/7 -H "X-Admin-Secret: $ADM" | jq .
```

---

## Troubleshooting (Namecheap-specific)

| Symptom | Fix |
|---|---|
| 503 "Node app failed to start" | Check `v1per-bot/stderr.log` and `v1per-bot/stdout.log` via cPanel File Manager. 99% it's wrong path to `server.cjs` or missing `DATABASE_PATH=./data/bot.db` folder. |
| `/api/bot` returns "SERVER_MISCONFIGURED" | `JWT_SECRET` or `SESSION_SECRET` or `ADMIN_SECRET` empty in `.env`. |
| `/api/bot` returns prebuild error (prod) | Forgot to run `node scripts/prebuild-bundle.cjs` locally and upload `data/prebuilt-bot-prod.js.tpl`. |
| sql.js "Cannot open /sql-wasm.wasm" 404 | **No browser concern, server-side only** — ensure `node_modules/sql.js/dist/` was uploaded with the `.wasm` file intact. |
| Uploaded `bot.db` has wrong license | DB is fully portable: just overwrite `data/bot.db` and click **Restart** in Setup Node.js App. |
| 500 on first auth (sql busy) | sql.js is single-writer; 30s autosync + debouncer handle it. If persists: restart the Node app + chmod 666 data folder (last resort). |
| Sessions not persisting across page reloads | User's browser blocks 3rd-party localStorage on trading site. Works 99% on desktop; for strict Safari, they just re-paste key every 30 min (acceptable UX). |

---

## File Tree (uploaded)

```
/home/youruser/v1per-bot/                ← cPanel App Root (NOT web-accessible)
├── .env                                 (CHMOD 600)
├── package.json
├── server.cjs                           (Passenger startup)
├── server/                              (never web-accessible)
│   ├── db.cjs / auth.cjs / admin.cjs / botDelivery.cjs / security.cjs / rateLimit.cjs
├── public/
│   └── loader.js                        (auth UI / bookmarklet entry)
├── data/
│   ├── bot.db                           (WASM SQLite, 600)
│   ├── prebuilt-bot-prod.js.tpl
│   └── prebuilt-bot-dev.js.tpl
└── node_modules/
    └── sql.js/dist/sql-wasm.wasm        (required — WASM)
    └── express/cors/helmet/jsonwebtoken/...

<bot.asmonix.com DOCROOT>/              ← public_html/bot or subdomain dir
└── .htaccess                            (Namecheap Passenger handlers + security headers)
```

### Why two file trees?

Namecheap **Node.js Selector** runs your app above document root. The `.htaccess` in the domain's public dir tells Apache/Cloudlinux Passenger to route HTTP traffic to your Node process. Project sources above docroot are **never statically served** even if `.htaccess` rules break — defense-in-depth.
