diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dff87fe..31c3079 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,24 +32,14 @@ jobs: run: | if [ -f package-lock.json ]; then npm ci; else npm install; fi - - name: Typecheck worker (if tsconfig present) - run: | - if [ -f tsconfig.json ]; then - npx tsc --noEmit || true - fi + - name: Typecheck worker + run: npm run lint - name: Frontend install & build - working-directory: frontend - run: | - if [ -f package.json ]; then - if [ -f package-lock.json ]; then npm ci; else npm install; fi - npm run build --if-present - fi + run: npm run build:ui - - name: Smoke scripts - run: | - if [ -f scripts/smoke-test.mjs ]; then node scripts/smoke-test.mjs || true; fi - if [ -f test-offline.sh ]; then bash test-offline.sh || true; fi + - name: Smoke tests + run: npm test installer-syntax: name: Installer syntax diff --git a/.github/workflows/rolling-bundle.yml b/.github/workflows/rolling-bundle.yml new file mode 100644 index 0000000..d9b7a3e --- /dev/null +++ b/.github/workflows/rolling-bundle.yml @@ -0,0 +1,23 @@ +name: Rolling bundle + +on: + push: + branches: [main] + workflow_dispatch: + +permissions: + contents: write + +jobs: + bundle: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '20' + cache: npm + - name: Build & publish rolling + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: bash scripts/publish-rolling.sh diff --git a/.gitignore b/.gitignore index 1fe4bbb..309245e 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,8 @@ frontend/.next/ frontend/tsconfig.tsbuildinfo .wrangler/ .wrangler-dist/ +.wrangler-deploy.*.toml +.rolling/ dist-worker/ worker.js index.js @@ -67,3 +69,5 @@ uv.lock # Temp tmp/ temp/ +.deploy/ +*.cpuprofile diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..4a0a02c --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,142 @@ +# AGENTS.md — XRayMOD operating manual + +Living checklist for agents working in this fork. Follow phases in order. Report after each phase. Do **not** delete non-generated repo files unless the user explicitly says `approve cleanup`. + +## Checkout pin (update when syncing) + +| Field | Value | +|-------|-------| +| Branch | `main` (sync merged via PR #1; phases 3–7 on this line) | +| Upstream remote | `upstream` → `https://github.com/EvolveBeyond/XRayMOD.git` | +| Adopted upstream tip | `fed637e` (`main`, product **1.9.12**) | +| Merge commit | `7431daf` | +| Canonical version source | [`worker/lib/version.ts`](worker/lib/version.ts) — `XRayMOD_VERSION` / `XRayMOD_SCHEMA_VERSION` / `XRayMOD_BUILD` | +| Product version | **1.9.12** (not 5.1.1) | + +## Product intent + +Migrate from a “VPN/proxy panel” mindset to a **Secure VPN Infrastructure Control Plane**: + +- **Control plane**: Cloudflare Worker + D1 + panel UI (APIs, policy, subscriptions, onboarding). +- **Data plane**: user nodes / Xray / sing-box / gateways — **not** VPN traffic execution inside Workers. +- Cloudflare is an **Edge Provider** (security/control/edge endpoints), not the VPN runtime. +- Wizard is the **canonical** install/orchestrator; shell installers are deprecated primary path (mark, don’t delete without approval). +- Mini App / Telegram commerce / TWA stay **removed** (hard 404). Do not reintroduce from upstream merges. + +## Non-negotiable rules + +1. Read real execution paths before refactoring (`worker/` → router → API → D1). +2. Preserve local Lab / edge-ops / TWA-removal / login recovery unless explicitly superseded. +3. Prefer upstream dependency/security bumps when they don’t break Worker/UI builds. +4. No mass deletion of `installer/`, `backend/`, install scripts without cleanup audit + `approve cleanup`. +5. No claiming Cloudflare IPs are “clean”/residential or guaranteed to evade classification. +6. After every phase: build, test, inspect diff, update docs, report status. + +## Report cadence + +After each phase, report: + +1. What changed (paths) +2. `npm run lint` / `npm run build:ui` / `npm test` result +3. Blockers / decisions needed +4. Next phase id + +--- + +## Phased checklist + +### Phase 0 — Upstream sync + version truth — DONE + +- [x] Branch `sync/upstream-1.9.12` from fork tip +- [x] Merge `upstream/main` @ `fed637e` +- [x] Keep Lab + TWA removal; take upstream deps + remote API +- [x] Canonical version in `worker/lib/version.ts` +- [x] Lint + UI build + smoke tests green + +### Phase 1 — Post-sync stabilize + architectural audit — DONE + +- [x] Document current architecture → [`docs/architecture/current-state.md`](docs/architecture/current-state.md) +- [x] Confirm version identity 1.9.12 everywhere meaningful (`deploy-panel.sh` fixed) +- [x] Note merge overlays and known dual-stack (Worker vs `backend/` / `src/`) + +### Phase 2 — Cleanup audit only (no deletes) — DONE (awaiting approval) + +- [x] Inventory candidates → [`docs/architecture/cleanup-audit.md`](docs/architecture/cleanup-audit.md) +- [x] Classify candidates (no permanent deletes performed) +- [ ] **Stop** for user `approve cleanup` before any permanent deletes + +### Phase 3 — Domain renames + Edge Provider abstraction — DONE + +- [x] Introduce Edge Provider interface; Cloudflare as first implementation (`worker/lib/edge-provider/`) +- [x] Wire self-update CF HTTP through `CloudflareEdgeProvider.request` +- [x] Expose `edge_provider` capability summary on admin dashboard API +- [x] Domain aliases (`worker/lib/domain.ts`) + honest copy for former cleanip/disguise surfaces +- [x] Wizard `/api/wizard/capabilities` consumes Edge Provider reports + +### Phase 4 — Node Agent model + control/data-plane boundary — DONE + +- [x] Define Node Agent contract (heartbeat, config pull, health) — `worker/lib/node-agent.ts`, `worker/api/agents.ts` +- [x] Keep proxy/data-plane off Worker by default via `security.policy_json.disable_in_worker_proxy` +- [x] Secure agent auth (`xrm_node_` bearer); legacy `backends` listed as compatibility shim + +### Phase 5 — Wizard as canonical orchestrator — DONE + +- [x] Stateful wizard steps in `wizard.state_json`; OAuth called out as preferred +- [x] Versioned rolling artifacts (`releases/download/rolling/worker.mjs`) instead of raw `main/worker.js` +- [x] Deprecate shell installers as primary path (docs + banner), files kept + +### Phase 6 — Subscription / policy / security / dashboard — DONE + +- [x] Security policy engine (`worker/lib/security-policy.ts`) + admin dashboard / policy API +- [x] Node list UI enrolls agents; subscription still generated by control plane for node users +- [x] Honest edge-endpoint / origin-protection copy (no “clean IP” / stealth-as-camouflage claims) + +### Phase 7 — Docs / CI / operator runbooks — DONE + +- [x] [`DEPLOY.md`](DEPLOY.md) documents `ship-panel.sh`, `deploy-panel.sh`, `publish-rolling.sh` +- [x] GitHub Actions: [`ci.yml`](.github/workflows/ci.yml), [`rolling-bundle.yml`](.github/workflows/rolling-bundle.yml) +- [x] Shell installers marked deprecated in README + Wizard UI (files kept per cleanup audit) + +### Phase 8 — Ship surfaces (wizard UI + node agent script) — DONE + +- [x] Panel Wizard page consuming `/api/wizard` + `/api/wizard/capabilities` +- [x] `scripts/node-agent.sh` heartbeat/config pull loop +- [x] Wizard remote deploy uses rolling `worker.mjs` + `assets.tar.gz` + `run_worker_first` (same as `deploy-worker-module.py`) +- [x] OAuth PKCE endpoints: `/api/wizard/oauth/url` + `/api/wizard/oauth/callback` (requires operator OAuth app in kvstore for non-localhost redirect) +- [x] Commit + publish rolling + deploy live panel (operator): `bash scripts/ship-panel.sh` + +### Phase 2 remainder + +- [ ] **Stop** for user `approve cleanup` before any permanent deletes + +--- + +## What not to delete (without approval) + +- `installer/`, `install.sh`, `install.ps1`, `install.cmd`, `backend/`, `wizard/` source +- Database schema/migrations, CI workflows, security files, wrangler deploy config +- Compatibility layers still referenced by production Worker +- Anything classified `UNKNOWN` in the cleanup audit + +## Generated artifacts (may remove when rebuilding) + +- `frontend/.next/`, `frontend/out/` (rebuild via `npm run build:ui`) +- `node_modules/`, `.wrangler/` local state, `__pycache__/` + +## Default merge policy (future upstream pulls) + +| Area | Policy | +|------|--------| +| Version strings | Upstream 1.x lineage via `worker/lib/version.ts` | +| Telegram / TWA / store | Keep **our removal** | +| Lab / edge-ops / login recovery | Keep **ours** | +| Dependencies | Prefer **upstream** bumps if build stays green | +| Remote API | Keep merged upstream remote key/API routes | + +## Commands + +```bash +npm run lint +npm run build:ui +npm test +``` diff --git a/CHANGELOG.md b/CHANGELOG.md index 3facd11..f3fd44d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,14 +8,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added -- Telegram operator bot (`telegram-bot/`) — create / list / delete / update panels with Persian reply keyboard and step progress - Client-path Clean IP scan with ranked recommendations from the visitor network - Dual-author credit: Askar Niroomand & Pakrohk +### Removed +- Telegram Mini App (`/twa/*`), commerce/store, Telegram bot integration, and `telegram-bot/` + ### Changed - Panel UI branding normalized to XRayMOD (removed internal theme codenames from user-facing chrome) - README EN/FA: clearer install path and Cloudflare API token guide -- Telegram / panel Persian copy cleaned up (no casual assistant tone) +- Panel Persian copy cleaned up (no casual assistant tone) ### Fixed - Nested `/panel/*` routes loading `/_next` assets diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 99d9ea3..f5745ec 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -92,7 +92,7 @@ security: harden rate limit headers ``` Author identity must be your real name or consistent handle + valid email. -Do not commit as generic names like `engineer` / `مهندس`. +Do not commit as generic names like `engineer` / generic placeholder names. ## Coding standards diff --git a/DEPLOY.md b/DEPLOY.md index 61a1b7e..c2d87c2 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -16,20 +16,34 @@ Legacy Vite SPA lives under `src/` and is **not** used by `npm run deploy`. - Cloudflare account + API token (Edit Cloudflare Workers) - Account must **not** be disabled (`wrangler whoami` must succeed) -## Quick deploy +## Quick deploy (operator) + +**Preferred:** ship to an existing panel (preserves D1, uses `worker.mjs` + `run_worker_first`): ```bash -# 1. Install npm install +# ~/.xraymod/config.json from first deploy-panel.sh run +bash scripts/ship-panel.sh +``` + +**First panel** on a Cloudflare account: -# 2. Create D1 (once) +```bash +npm install +export CLOUDFLARE_API_TOKEN="…" +export CLOUDFLARE_ACCOUNT_ID="…" npx wrangler d1 create xraymod-db -# paste database_id into wrangler.toml +bash scripts/deploy-panel.sh xraymod +``` + +Publish rolling bundle for in-panel self-update / wizard remote deploy: -# 3. Build UI + deploy Worker -npm run deploy +```bash +bash scripts/publish-rolling.sh ``` +Legacy `npm run deploy` (wrangler from TS) can trigger CF Error 1101 on some accounts — avoid for production. + Panel URL after first install / bootstrap: ``` @@ -77,7 +91,6 @@ Most panel secrets live in **D1** (not CF env) after Gen 1.9.12. | `PAGES_URL` | Optional remote Pages origin (if not using ASSETS) | | `PANEL_RECOVERY` | `true` disables disguise (break-glass) | | `DISGUISE_PAGE` | Default `404` (also `1101`, `nginx`, …) | -| `ENABLE_TELEGRAM` | Telegram bot feature flag | | `CRYPTO_KEY` | Override default crypto key (set in production) | ## Admin Dashboard diff --git a/PUBLISH.md b/PUBLISH.md index be9f408..beeef9e 100644 --- a/PUBLISH.md +++ b/PUBLISH.md @@ -1,12 +1,12 @@ -# راهنمای صفر تا صد انتشار روی GitHub (اوپن‌سورس) +# Zero-to-Hero GitHub Publishing Guide (Open Source) -این فایل برای **صاحب پروژه** است (تو) — نه برای کاربر نهایی. +This file is for the **project owner** — not end users. --- -## نتیجه نهایی برای عموم +## End result for the public -کاربر فقط این را می‌زند: +Users only run: ```bash # Linux / macOS / Git Bash / WSL @@ -17,66 +17,66 @@ irm https://raw.githubusercontent.com/askarniroomand/XRayMOD/main/install.ps1 | ``` -و فقط وارد می‌کند: +And only enter: 1. Cloudflare API Token -2. نام کاربری -3. رمز عبور +2. Username +3. Password -→ پنل ساخته می‌شود و لینک‌های **SECURE PATH** چاپ می‌شود (`/{UUID}/panel` ، `/{UUID}/sub/...`). +→ The panel is created and **SECURE PATH** links are printed (`/{UUID}/panel`, `/{UUID}/sub/...`). -نسخه فعلی هدف: **1.9.12** — جزئیات در [CHANGELOG.md](CHANGELOG.md). +Target version: **1.9.12** — see [CHANGELOG.md](CHANGELOG.md) for details. --- -## پیش‌نیاز تو (ناشر) +## Prerequisites (publisher) -- اکانت GitHub (ریپو: `askarniroomand/XRayMOD` یا فورک خودت) -- `git` روی سیستم -- دسترسی push به ریپو +- GitHub account (repo: `askarniroomand/XRayMOD` or your fork) +- `git` on your system +- Push access to the repo --- -## مرحله ۱ — تمیز کردن قبل از push +## Step 1 — Clean up before push -- هیچ توکن Cloudflare داخل فایل‌ها نباشد -- `wrangler.toml` فقط placeholder داشته باشد (`REPLACE_WITH_YOUR_D1_ID`) -- `frontend/out` و `node_modules` در `.gitignore` باشند -- `LICENSE` و `README.md` و `install.sh` و `install.ps1` و `install.cmd` موجود باشند +- No Cloudflare tokens inside files +- `wrangler.toml` only has placeholders (`REPLACE_WITH_YOUR_D1_ID`) +- `frontend/out` and `node_modules` are in `.gitignore` +- `LICENSE`, `README.md`, `install.sh`, `install.ps1`, and `install.cmd` exist --- -## مرحله ۲ — کامیت و پوش +## Step 2 — Commit and push ```bash cd /Users/niroomand/Desktop/XRayMOD git status git add -A -git status # چک کن secret نباشد +git status # verify no secrets -git commit -m "release: open-source one-click installer + FA panel" +git commit -m "release: open-source one-click installer" git push -u origin main ``` -اگر ریپو جدید ساختی: +If you created a new repo: ```bash gh repo create askarniroomand/XRayMOD --public --source=. --remote=origin --push -# یا +# or git remote add origin https://github.com/YOUR_USER/XRayMOD.git git push -u origin main ``` --- -## مرحله ۳ — تست دستور عمومی +## Step 3 — Test the public command -**مهم:** بعد از push حدود ۱۰–۳۰ ثانیه صبر کن تا raw.githubusercontent.com آپدیت شود. +**Important:** After push, wait ~10–30 seconds for raw.githubusercontent.com to update. ```bash -# تست روی یک ماشین تمیز / ترمینال جدید: +# Test on a clean machine / new terminal: # Linux / macOS / Git Bash / WSL bash <(curl -fsSL https://raw.githubusercontent.com/askarniroomand/XRayMOD/main/install.sh) @@ -85,79 +85,79 @@ irm https://raw.githubusercontent.com/askarniroomand/XRayMOD/main/install.ps1 | ``` -اگر ریپو یا برنچت فرق دارد: +If your repo or branch differs: ```bash -# مثال فورک شخصی: +# Example personal fork: export XRAYMOD_REPO=https://github.com/YOUR_USER/XRayMOD.git export XRAYMOD_BRANCH=main bash <(curl -fsSL https://cdn.jsdelivr.net/gh/YOUR_USER/XRayMOD@main/install.sh) ``` -> `install.sh` داخلش `REPO_URL` را از `XRAYMOD_REPO` می‌خواند؛ پیش‌فرض `askarniroomand/XRayMOD` است. +> `install.sh` reads `REPO_URL` from `XRAYMOD_REPO`; default is `askarniroomand/XRayMOD`. --- -## مرحله ۴ — تنظیمات صفحه گیت‌هاب (اختیاری ولی حرفه‌ای) +## Step 4 — GitHub repo settings (optional but professional) -در Settings ریپو: +In repo Settings: -| مورد | پیشنهاد | -|------|---------| +| Item | Suggestion | +|------|------------| | Description | Modular proxy panel on Cloudflare Workers | | Website | https://t.me/MRROBOT_DT | | Topics | `cloudflare-workers`, `proxy`, `vless`, `panel`, `opensource` | -| License | MIT (از فایل LICENSE) | +| License | MIT (from LICENSE file) | -در About → تیک Issues / Discussions اگر می‌خواهی. +In About → enable Issues / Discussions if desired. --- -## مرحله ۵ — برند شخصی تو +## Step 5 — Your personal brand -| چیز | کجاست | -|-----|--------| -| پشتیبانی تلگرام | `https://t.me/MRROBOT_DT` — در `install.sh`, `install.ps1`, `installer/cli_deploy.py`, پنل `support` | -| آدرس نصب | README + `install.sh` (یونیکس) + `install.ps1` / `install.cmd` (ویندوز) | -| نام ریپو | `askarniroomand/XRayMOD` | +| Item | Location | +|------|----------| +| Telegram support | `https://t.me/MRROBOT_DT` — in `install.sh`, `install.ps1`, `installer/cli_deploy.py`, panel `support` | +| Install URL | README + `install.sh` (Unix) + `install.ps1` / `install.cmd` (Windows) | +| Repo name | `askarniroomand/XRayMOD` | -اگر یوزرنیم گیت‌هاب عوض شد، هر سه جای URL را عوض کن: +If your GitHub username changes, update URLs in all three places: - `install.sh` / `install.ps1` → `REPO_URL` / `XRAYMOD_REPO` -- `README.md` / `README.fa.md` -- این فایل `PUBLISH.md` +- `README.md` +- this file `PUBLISH.md` --- -## مرحله ۶ — به‌روزرسانی بعدی برای کاربران +## Step 6 — Future updates for users -هر بار که کد را push کنی روی `main`، کاربر با **همان یک دستور** آخرین نسخه را می‌گیرد (اسکریپت `git pull` / clone تازه می‌کند). +Every time you push to `main`, users get the latest version with **the same one-liner** (the script `git pull`s or fresh-clones). --- -## چک‌لیست قبل از اعلام عمومی +## Pre-launch checklist -- [ ] `git push origin main` موفق -- [ ] `curl -fsSL .../install.sh` بدون 404 -- [ ] `install.ps1` و `install.cmd` بدون 404 (ویندوز) -- [ ] تست کامل نصب با یک توکن تست -- [ ] لینک تلگرام پشتیبانی درست است -- [ ] توکن واقعی / پسورد واقعی داخل git نیست +- [ ] `git push origin main` succeeded +- [ ] `curl -fsSL .../install.sh` returns no 404 +- [ ] `install.ps1` and `install.cmd` return no 404 (Windows) +- [ ] Full install test with a test token +- [ ] Telegram support link is correct +- [ ] No real token / password in git --- -## عیب‌یابی رایج +## Common troubleshooting -| مشکل | راه حل | -|------|--------| -| `404` روی install.sh / install.ps1 | push نشده یا نام برنچ/ریپو اشتباه | -| Node error | Node 18+ نصب شود | -| Token invalid | قالب Edit Cloudflare Workers | -| workers.dev 1101 | اکانت CF / subdomain؛ پشتیبانی بده | -| Bootstrap fail | چند ثانیه صبر؛ دوباره install | +| Problem | Fix | +|---------|-----| +| `404` on install.sh / install.ps1 | Not pushed or wrong branch/repo name | +| Node error | Install Node 18+ | +| Token invalid | Use Edit Cloudflare Workers template | +| workers.dev 1101 | CF account / subdomain issue; contact support | +| Bootstrap fail | Wait a few seconds; retry install | --- -## پشتیبانی کاربران +## User support -هدایت همه به: **https://t.me/MRROBOT_DT** +Direct everyone to: **https://t.me/MRROBOT_DT** diff --git a/README.fa.md b/README.fa.md deleted file mode 100644 index 66411b7..0000000 --- a/README.fa.md +++ /dev/null @@ -1,337 +0,0 @@ -

- XrayMOD -

- -

- پنل مخفی و مدرن مدیریت پروکسی روی Cloudflare Workers
- اوپن‌سورس · سرورلس · صفحه وضعیت کاربر · ساب هوشمند · نصب یک‌خطی -

- -

- MIT - Release - Stars - TG - EN - Author -

- -

- معرفی · - ساخت توکن · - نصب سریع · - بعد از نصب · - امنیت -

- ---- - -## XRayMOD چیه؟ - -**XRayMOD** یک پنل **self-hosted** و **serverless** برای ساخت و مدیریت کاربر و لینک سابسکرایبشن روی **Cloudflare Workers + D1** است. - -به‌جای اجارهٔ دائمی VPS فقط برای پنل، کنترل‌پلن روی لبهٔ Cloudflare اجرا می‌شود؛ داشبورد ادمین، صفحه وضعیت کاربر، ساب هوشمند و پوسته‌های استیلث را یک‌جا دارید. - -> **مسئولیت اپراتور:** رعایت قوانین Cloudflare، قوانین محلی و استفادهٔ مجاز بر عهدهٔ شماست. این نرم‌افزار زیرساخت است — نه مجوز حمله به شبکه‌هایی که مال شما نیستند. - ---- - -## چرا به درد می‌خورد؟ - -| مشکل رایج | کاری که XRayMOD می‌کند | -|:----------|:------------------------| -| هزینه و نگهداری VPS برای پنل کوچک | اجرا روی Workers + D1 | -| اسکنر و حدس مسیر پنل | **SECURE PATH** اجباری (UUID تصادفی) — بدون آن همه چیز **۴۰۴** | -| سوال مداوم کاربر: «حجمم چقدر مونده؟» | صفحه `/{SECURE}/me/` با QR و کپی | -| ساب ساده و ضعیف | بستهٔ هوشمند تا ۱۰ کانفیگ (IP تمیز، پورت CF، …) | -| شبکه‌های فیلترشده | پوسته‌های جعلی + مسیرهای طعمه (Canary) | - ---- - -## قابلیت‌ها - -| | قابلیت | توضیح کوتاه | -|:--:|:-------|:------------| -| 🥷 | **SECURE PATH اجباری** | پنل / API / ساب / پورتال فقط زیر UUID | -| 🛡 | **داشبورد ادمین** | کاربر، آپدیت، دامنه سفارشی، kill switch، ایمیل CF | -| 📊 | **صفحه وضعیت کاربر** | حجم، روز باقی‌مانده، QR — بدون لاگین ادمین | -| 🎯 | **ساب هوشمند** | مستقیم + IP تمیز + پورت‌های CF · فرمت Clash / sing-box | -| 🥷 | **استیلث** | ۴۰۴ خاموش · CF 1101 · nginx · GitHub · WordPress | -| 🕳 | **Canary** | مسیر جعلی برای لاگ اسکنر بدون لو رفتن پنل | -| 💾 | **بک‌آپ و Audit** | خروجی/ورودی تنظیمات · تاریخچه اکشن ادمین | -| 📡 | **Clean IP آگاه از ISP** | پیشنهاد بهتر وقتی داده موجود باشد | -| 🔐 | **سخت‌سازی ادمین** | ایمیل CF · 2FA · rate limit | -| ⚡ | **نصب یک‌خطی** | ویندوز / لینوکس / مک / WSL | -| 📱 | **کلاینت‌ها** | v2rayNG ≥۲.۲.۳ · sing-box ≥۱.۱۲ · Hiddify · Streisand · Clash | - ---- - -## پیش‌نیازها - -### سیستم شما -- ویندوز ۱۰+، macOS ۱۲+، یا لینوکس جدید -- اینترنت به `api.cloudflare.com` و GitHub -- امکان اجرای **PowerShell** یا **Bash** - -### اکانت Cloudflare -- اکانت Cloudflare (پلن رایگان برای بسیاری از استفاده‌های شخصی کافی است) -- اجازه ساخت **Workers** و دیتابیس **D1** -- یک **API Token** با دسترسی ویرایش Workers (بخش بعد) - -### اختیاری (نصب دستی / توسعه) -- Node.js ۲۰+ -- npm ۱۰+ -- Wrangler ۳+ - ---- - -## ساخت توکن API در Cloudflare - -توکن **به این ریپوی گیت‌هاب آپلود نمی‌شود**. فقط روی سیستم خودتان می‌ماند و برای APIهای Cloudflare استفاده می‌شود. ترجیحاً **توکن محدود (scoped)** بسازید، نه Global API Key. - -### مرحله‌به‌مرحله - -1. وارد [داشبورد Cloudflare](https://dash.cloudflare.com) شوید. -2. از گوشه بالا راست روی آواتار → **My Profile** → **API Tokens**. - لینک مستقیم: [https://dash.cloudflare.com/profile/api-tokens](https://dash.cloudflare.com/profile/api-tokens) -3. روی **Create Token** بزدید. -4. در بخش قالب‌ها، **Edit Cloudflare Workers** را انتخاب کنید → **Use template**. - این قالب پیشنهادی رسمی برای شروع با XRayMOD است. -5. تنظیمات را مرور کنید (در صورت تمایل محدودتر کنید): - - **Account resources** → فقط همان اکانتی که می‌خواهید پنل را روی آن بسازید - - **Zone resources** → فقط اگر دامنه سفارشی می‌بندید؛ وگرنه می‌توانید مطابق قالب پیش بروید -6. **Continue to summary** → **Create Token**. -7. توکن را **یک‌بار** کپی کنید و در پسوردمنجر ذخیره کنید. Cloudflare دوباره نشانش نمی‌دهد. -8. وقتی نصب‌کننده پرسید، همان توکن را وارد کنید. - -### توکن برای چه کارهایی مصرف می‌شود؟ - -| کار | چرا | -|:----|:----| -| ساخت / آپدیت Worker | میزبانی پنل و لبه پروکسی | -| ساخت / اتصال D1 | ذخیره کاربر و تنظیمات | -| دامنه سفارشی (اختیاری) | وصل کردن دامنه به Worker | - -### چک‌لیست ایمنی - -- [ ] توکن را در Issue، PR، گروه تلگرام یا دیسکورد نفرستید -- [ ] داخل گیت یا اسکرین‌شات عمومی نگذارید -- [ ] اگر لو رفت، فوراً Rotate / Revoke کنید -- [ ] بعد از نصب روی سیستم یک‌بارمصرف، توکن قدیمی را باطل کنید - -> اگر اکانت Cloudflare مشکل پرداخت / تعلیق داشته باشد، نصب شکست می‌خورد تا وضعیت اکانت درست شود. - ---- - -## نصب سریع (حدود ۵ دقیقه) - -### ۱) یک دستور را اجرا کنید - -#### ویندوز — PowerShell (اعلان با `PS` شروع می‌شود) - -```powershell -irm https://raw.githubusercontent.com/askarniroomand/XRayMOD/main/install.ps1 | iex -``` - -#### ویندوز — CMD (بدون `PS`) - -```cmd -powershell -NoProfile -ExecutionPolicy Bypass -Command "iex (iwr -UseBasicParsing 'https://raw.githubusercontent.com/askarniroomand/XRayMOD/main/install.ps1').Content" -``` - -#### لینوکس / مک / WSL - -```bash -bash <(curl -fsSL https://raw.githubusercontent.com/askarniroomand/XRayMOD/main/install.sh) -``` - -اسکریپت خودش ابزارها را آماده می‌کند، سورس را می‌گیرد و پنل را می‌سازد. برای مسیر یک‌خطی **نصب git اجباری نیست**. - -### ۲) فقط سه ورودی بدهید - -| مرحله | ورودی | نکنه | -|:-----:|:------|:-----| -| ۱ | 🔑 توکن Cloudflare | طبق بخش بالا | -| ۲ | 👤 نام کاربری ادمین | بعداً بهتر است ایمیل CF را در پنل ببندید | -| ۳ | 🔒 رمز عبور | رمز قوی و یکتا | - -بقیه خودکار است: D1 · ساخت UI · دیپلوی Worker · bootstrap · چاپ لینک‌ها - -### ۳) لینک‌هایی که نصب‌کننده چاپ می‌کند را ذخیره کنید - -| لینک | کاربرد | -|:-----|:-------| -| `//login` | ورود ادمین (خصوصی نگه دارید) | -| `//panel` | داشبورد | -| `//sub/` | ساب اپ‌ها (پیش‌فرض Base64) | -| `//me/` | صفحه وضعیت کاربر | -| `…/sub/?format=clash` | خروجی Clash / Mihomo | -| `…/sub/?format=singbox` | خروجی sing-box | - -> ⚠️ از نسل ۱.۹.۱۲ به بعد، مسیرهای برهنه مثل `/panel` یا `/sub/...` **بدون** SECURE PATH همه **۴۰۴** هستند. همیشه UUID مسیر را در لینک داشته باشید. جزئیات: [CHANGELOG-1.9.12.md](CHANGELOG-1.9.12.md) - ---- - -## بعد از نصب - -1. بروید به `//login` و با یوزر/رمزی که ساختید وارد شوید. -2. یک کاربر آزمایشی با حجم و تاریخ انقضا بسازید. -3. لینک **ساب** را در Hiddify / v2rayNG / Clash / sing-box ایمپورت کنید. -4. `/{SECURE}/me/` را در مرورگر باز کنید و وضعیت را چک کنید. -5. در تنظیمات ادمین، پوسته‌ٔ **استیلث** را انتخاب کنید و (پیشنهادی) ورود با **ایمیل Cloudflare** را فعال کنید. -6. `SECURE_PATH`، آدرس Worker و رمز ادمین را در پسوردمنجر ذخیره کنید. - -**کلاینت‌های پیشنهادی:** v2rayNG ≥ ۲.۲.۳ (Hev TUN) · sing-box ≥ ۱.۱۲ · Streisand · Hiddify · Clash - ---- - -## نصب دستی (برای توسعه‌دهنده) - -
-گام‌به‌گام: کلون → D1 → بیلد → دیپلوی - -
- -```bash -git clone https://github.com/askarniroomand/XRayMOD.git -cd XRayMOD -npm install -npm install --prefix frontend -npm run build:ui -npx wrangler login -npx wrangler d1 create xraymod-db -# database_id را در wrangler.toml بگذارید -npx wrangler deploy -``` - -راه‌اندازی اولیه ادمین: - -```bash -curl -X POST "https://WORKER.workers.dev/install" \ - -H "Content-Type: application/json" \ - -d '{"username":"admin","password":"YourStrongPass123"}' -``` - -ورود: - -```text -https://WORKER.workers.dev//login -https://WORKER.workers.dev//panel -``` - -ساب و وضعیت: - -```text -https://WORKER.workers.dev//sub/ -https://WORKER.workers.dev//me/ -``` - -جزئیات بیشتر: [DEPLOY.md](./DEPLOY.md) - -
- ---- - -## معماری خلاصه - -```mermaid -graph TD - Internet[اینترنت] --> Edge[لبه Cloudflare Worker] - Edge --> Gate[دروازه SECURE PATH ۴۰۴ خاموش] - Edge --> Disguise[پوسته‌های جعلی \/ استاتیک] - Edge --> Admin[API ادمین + داشبورد] - Edge --> Sub[اندپوینت سابسکرایبشن] - Edge --> Portal["پورتال \/{SECURE}\/me"] - Edge --> D1[(D1 دیتابیس - کاربر، تنظیمات، audit)] -``` - -| مسیر | نقش | -|:-----|:----| -| `worker/` | **منبع حقیقت تولید** — روتینگ، احراز هویت، ساب، پورتال | -| `frontend/` | UI پنل ادمین | -| `installer/` + `install.*` | نصب روی اکانت Cloudflare | -| `telegram-bot/` | ربات اختیاری برای ساخت/حذف/آپدیت چند پنل | -| `backend/` | آزمایش‌های قدیمی پایتون — برای دیپلوی Workers لازم نیست | - ---- - -## سوالات پرتکرار - -
-آیا VPS لازم است؟ - -برای خود پنل خیر. کنترل‌پلن روی Workers + D1 است. نود/بک‌اند پروکسی موضوع جداگانه‌ای است. -
- -
-پلن رایگان Cloudflare کافی است؟ - -برای خیلی از استفاده‌های شخصی بله. با رشد ترافیک، سقف Workers و D1 را زیر نظر بگیرید. -
- -
-توکن کجا ذخیره می‌شود؟ - -فقط روی ماشین شما هنگام نصب و فقط به API کلودفلر فرستاده می‌شود. داخل ریپو نرود. ببینید [SECURITY.md](./SECURITY.md). -
- -
-چرا روی /panel خطای ۴۰۴ می‌گیرم؟ - -نسل ۱.۹.۱۲ پیشوند UUID (SECURE PATH) را اجباری کرده. لینک کامل چاپ‌شده توسط نصب‌کننده را استفاده کنید. -
- -
-Hiddify / v2rayNG پشتیبانی می‌شود؟ - -بله. لینک ساب را ایمپورت کنید. فرمت Clash و sing-box با پارامتر `format` در دسترس است. -
- -
-باگ امنیتی را کجا گزارش کنم؟ - -خصوصی به تلگرام [@MRROBOT_DT](https://t.me/MRROBOT_DT) — Issue عمومی با توکن/رمز نسازید. -
- ---- - -## پشتیبانی - -

- Telegram -

- -سوال، باگ یا پیشنهاد را در تلگرام بفرستید. -**لینک پنل، رمز و توکن را عمومی نفرستید.** - -نسخه انگلیسی و جزئیات بیشتر: [README.md](README.md) - ---- - -## مشارکت - -بخوانید: [CONTRIBUTING.md](./CONTRIBUTING.md) و [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md) - -```bash -git clone https://github.com/askarniroomand/XRayMOD.git -cd XRayMOD -npm install -# برنچ بسازید، تغییر دهید، PR به main بزنید -``` - -PRهای مستندات و تست‌ها عالی‌اند برای شروع. - ---- - -## نویسنده‌ها - -| | گیت‌هاب | -|:--|:--------| -| عسکر نیرومند | [@askarniroomand](https://github.com/askarniroomand) | -| Pakrohk | [@Pakrohk](https://github.com/Pakrohk) | - ---- - -## لایسنس - -[MIT](LICENSE) © Askar Niroomand & Pakrohk diff --git a/README.md b/README.md index ce436a5..2edc301 100644 --- a/README.md +++ b/README.md @@ -1,472 +1,268 @@ -

- XRayMOD — stealth proxy panel on Cloudflare Workers -

+# XRayMOD -

- Open-source · Serverless · Stealth-aware
- Modern VLESS / Trojan / VMess control plane on Cloudflare Workers + D1
- Admin dashboard · User status portal · Smart subscription · Disguise skins · One-line install -

+**Secure VPN Infrastructure Control Plane** on Cloudflare Workers + D1. -

- MIT - Release - CF - TS - CI - Stars - TG -

+XRayMOD is the **control plane**: admin APIs, policy, subscriptions, onboarding, and origin protection for the panel. **Data-plane** VPN/proxy traffic runs on your **Node Agents** (Xray / sing-box / gateways)—not inside Workers. Cloudflare is an **Edge Provider** (Workers, D1, edge endpoints), not a VPN runtime. -

- English · - فارسی · - Quick start · - API token · - Features · - Security · - Contributing -

+Cloudflare anycast addresses are **not** “clean”, residential, or guaranteed to evade classification. ---- +> **Operator responsibility:** Comply with Cloudflare’s terms, local laws, and acceptable-use rules. This software is infrastructure tooling—not authorization to access networks you do not control. - +--- -# XRayMOD +

+ MIT + Release + CF + CI +

-**XRayMOD** is an open-source, serverless control plane for managing proxy users and subscription links on **Cloudflare Workers** with **D1** storage. +| | | +|:--|:--| +| **Product version** | **1.9.12** ([`worker/lib/version.ts`](worker/lib/version.ts)) | +| **Canonical UI** | Next.js static export → Worker assets | +| **Canonical install** | In-panel Wizard + rolling release bundle | +| **Shell installers** | Deprecated compatibility path (kept, not deleted) | -You get a practical admin UI, a user-facing status page, smart subscription bundles, and optional disguise surfaces — without renting a VPS for the panel itself. +--- -> **Operator responsibility:** Comply with Cloudflare’s terms, local laws, and acceptable-use rules. This is infrastructure software — not permission to attack networks you do not control. +## Architecture ---- +```text +Clients / Admin browser + │ + ▼ + Cloudflare Edge (Worker) + │ + ├── SECURE PATH gate → silent 404 without UUID + ├── Admin API + Dashboard + ├── Subscription + /me portal + ├── Wizard / self-update + └── D1 (users, policy, kvstore) + │ + └── Node Agents (heartbeat, config pull) → Xray / sing-box +``` -## Why operators use it +| Plane | Where | Role | +|:------|:------|:-----| +| Control | `worker/` + `frontend/` + D1 | Auth, users, subs, policy, onboarding | +| Data | Your VPS / Node Agent | Proxy protocols and user traffic | +| Edge | Cloudflare | Workers, D1, optional edge endpoints | -| Pain | What XRayMOD does | -|:-----|:------------------| -| VPS cost & babysitting for a small panel | Runs on Cloudflare Workers + D1 (edge, pay-as-you-go) | -| Panel scanners & path guessing | Compulsory **SECURE PATH** (random UUID); bare `/panel` → silent **404** | -| End users asking “how much traffic left?” | Public `/{SECURE}/me/` portal with QR & copy | -| Weak subscription UX | Top-10 smart bundle: direct + clean IPs + CF ports + fingerprints | -| Hostile / filtered networks | Disguise skins + canary traps | +Details: [`docs/architecture/current-state.md`](docs/architecture/current-state.md) · [`AGENTS.md`](AGENTS.md) --- ## Features -| | Feature | Detail | -|:--:|:--------|:-------| -| 🥷 | **Compulsory SECURE PATH** | Panel / API / sub / portal only under a random UUID | -| 🛡 | **Admin dashboard** | Users · update check · CF-email login · custom domains · kill switch | -| 📊 | **User status portal** | Traffic, days left, QR — no admin login for end users | -| 🎯 | **Smart subscription** | Direct + clean IPs + CF ports · Clash / sing-box formats | -| 🥷 | **Stealth skins** | Silent 404 · CF 1101 · nginx · GitHub · WordPress · Access Denied | -| 🕳 | **Canary traps** | Fake paths log scanners without exposing the panel | -| 💾 | **Backup & audit** | Export/import · remote settings sync · admin action history | -| 📡 | **ISP-aware clean IPs** | Better picks for constrained carriers when data is available | -| 🔐 | **Admin hardening** | CF email login · 2FA · rate limiting · SECURE PATH | -| ⚡ | **One-line install** | Windows PowerShell/CMD · Linux · macOS · WSL | -| 📱 | **Client-ready** | v2rayNG ≥2.2.3 · sing-box ≥1.12 · Hiddify · Streisand · Clash | - ---- - -## Tech stack - -| Layer | Technology | -|:------|:-----------| -| Runtime | Cloudflare Workers | -| Database | Cloudflare D1 (SQLite at the edge) | -| Language | TypeScript | -| Admin UI | Next.js (static export into Worker assets) | -| Installers | Bash · PowerShell | -| Tooling | Wrangler · npm | - -```mermaid -graph TD - Internet --> Edge[Cloudflare Edge Worker] - Edge --> Gate[SECURE PATH gate - silent 404] - Edge --> Disguise[Disguise / static responses] - Edge --> Admin[Admin API + Admin Dashboard] - Edge --> Sub[Subscription endpoints] - Edge --> Portal["/{SECURE}/me user portal"] - Edge --> D1[(D1 Database - users, settings, audit)] -``` +- **Compulsory SECURE PATH** — panel, API, subscription, and portal only under a random UUID; bare `/panel` → 404 +- **Admin dashboard** — users, nodes/agents, protocols, settings, Lab, origin protection +- **Node Agents** — enroll with `xrm_node_` bearer; heartbeat + config pull (`scripts/node-agent.sh`) +- **Wizard** — token/OAuth → plan capabilities → deploy **rolling** `worker.mjs` + UI assets +- **Security policy** — kill switch, optional disable in-Worker proxy, monthly caps +- **Subscriptions** — Base64 / Clash / sing-box; user status at `/{SECURE}/me/` +- **Origin protection** — disguise skins + canary paths (panel camouflage, not VPN traffic hiding) +- **Self-update** — Admin pulls GitHub `rolling` release onto the same Worker (D1 preserved) +- **Honest edge copy** — no “clean IP / stealth VPN” claims for Cloudflare anycast --- ## Requirements -### Your machine -- Windows 10+, macOS 12+, or modern Linux -- Internet access to `api.cloudflare.com` and GitHub -- Ability to run **PowerShell** or **Bash** - -### Cloudflare -- A Cloudflare account (Free plan is enough for many personal setups) -- Permission to create **Workers** and **D1** databases -- An **API token** with Workers edit rights (see next section) - -### Optional (manual / contributor workflow) -- Node.js **20+** -- npm **10+** -- Wrangler **3+** +- Cloudflare account with Workers + D1 +- API token with **Edit Cloudflare Workers** (scoped; never commit) +- Node.js **20+** and npm for operator / contributor deploys +- Optional: `gh` CLI to publish the rolling release --- -## Create a Cloudflare API token - -The installer never uploads your token to this GitHub repo. It stays on your machine and is used only against Cloudflare APIs. Prefer a **scoped token**, not Global API Key. - -### Step-by-step - -1. Sign in to the [Cloudflare Dashboard](https://dash.cloudflare.com). -2. Open **My Profile** (top-right avatar) → **API Tokens**. - Direct link: [https://dash.cloudflare.com/profile/api-tokens](https://dash.cloudflare.com/profile/api-tokens) -3. Click **Create Token**. -4. Under **API token templates**, choose **Edit Cloudflare Workers** → **Use template**. - This is the recommended starter for XRayMOD. -5. Review (and tighten if you want): - - **Account resources** → include only the account you will deploy to - - **Zone resources** → only if you will attach custom domains (otherwise you can leave as the template suggests) -6. Click **Continue to summary** → **Create Token**. -7. **Copy the token once** and store it in a password manager. Cloudflare will not show it again. -8. Paste it into the XRayMOD installer when prompted. - -### What the token is used for - -| Action | Why | -|:-------|:----| -| Create / update Worker | Host the panel + proxy edge | -| Create / bind D1 | Persist users & settings | -| Optional custom domain | Route your domain to the Worker | - -### Safety checklist +## Quick start -- [ ] Do **not** paste the token into Issues, PRs, Discord, or Telegram groups -- [ ] Do **not** commit it to git or put it in screenshots -- [ ] Rotate the token if it ever leaks -- [ ] Prefer revoking old tokens after you finish a one-off machine install +### Preferred: ship an existing panel -> If Cloudflare shows account/payment errors, fix billing / account status first — `wrangler whoami` (or the installer) will fail until the account is healthy. - ---- - -## Quick start (≈5 minutes) - -### 1) Run the installer +```bash +git clone https://github.com/askarniroomand/XRayMOD.git +cd XRayMOD +npm install +# Config from first deploy: ~/.xraymod/config.json + cf_api_token +bash scripts/ship-panel.sh +``` -**Windows PowerShell** (prompt starts with `PS`): +Open: -```powershell -irm https://raw.githubusercontent.com/askarniroomand/XRayMOD/main/install.ps1 | iex +```text +https://.workers.dev//login +https://.workers.dev//panel ``` -**Windows CMD**: +### First panel on an account -```cmd -powershell -NoProfile -ExecutionPolicy Bypass -Command "iex (iwr -UseBasicParsing 'https://raw.githubusercontent.com/askarniroomand/XRayMOD/main/install.ps1').Content" +```bash +export CLOUDFLARE_API_TOKEN="…" +export CLOUDFLARE_ACCOUNT_ID="…" +npx wrangler d1 create xraymod-db +bash scripts/deploy-panel.sh xraymod ``` -**Linux / macOS / WSL**: +Uses `worker.mjs` + UI assets via the Cloudflare API (`run_worker_first`). Avoid `wrangler deploy` from TypeScript source for production—some accounts hit real Error 1101. + +### Rolling bundle (self-update / Wizard remote deploy) ```bash -bash <(curl -fsSL https://raw.githubusercontent.com/askarniroomand/XRayMOD/main/install.sh) +bash scripts/publish-rolling.sh ``` -### 2) Answer three prompts +Publishes `worker.mjs` + `assets.tar.gz` to the GitHub release tag [`rolling`](https://github.com/askarniroomand/XRayMOD/releases/tag/rolling). -| Step | You enter | Notes | -|:----:|:----------|:------| -| 1 | Cloudflare API token | From the section above | -| 2 | Admin username | Prefer binding CF email later in the panel | -| 3 | Admin password | Use a long, unique password | +Full runbook: [`DEPLOY.md`](DEPLOY.md) -Everything else (Node tooling, clone, D1, UI build, Worker deploy, bootstrap) is automated. **Git is not required** on your machine for the one-line path. +--- -### 3) Save the URLs the installer prints +## Cloudflare API token -| URL pattern | Purpose | -|:------------|:--------| -| `/{SECURE_PATH}/login` | Admin login — keep private | -| `/{SECURE_PATH}/panel` | Admin dashboard | -| `/{SECURE_PATH}/sub/` | Subscription (Base64 by default) | -| `/{SECURE_PATH}/me/` | User traffic / days / QR | -| `…/sub/?format=clash` | Clash / Mihomo YAML | -| `…/sub/?format=singbox` | sing-box JSON | +1. [API Tokens](https://dash.cloudflare.com/profile/api-tokens) → **Create Token** +2. Template **Edit Cloudflare Workers** → tighten account scope +3. Copy once; store in a password manager +4. Use with installer / Wizard / `ship-panel.sh` only against Cloudflare APIs -> **Gen 1.9.12+:** Bare `/panel`, `/api/*`, `/sub/*` **without** the SECURE PATH return **404**. Always share links that include the UUID path. See [CHANGELOG-1.9.12.md](CHANGELOG-1.9.12.md). +Never paste tokens into Issues, PRs, chat, or git. --- -## After install — first 10 minutes +## After install + +1. Sign in at `/{SECURE_PATH}/login` +2. Create a test user; import the subscription into your client +3. Open `/{SECURE_PATH}/me/` for the status portal +4. Enroll a Node Agent under **Nodes** if you run data-plane on a VPS +5. Configure origin protection under **Stealth** / Admin as needed +6. Store SECURE PATH, hostname, and admin password offline -1. Open `/{SECURE_PATH}/login` and sign in with the credentials you set. -2. Create a test user (traffic + expiry). -3. Copy the **subscription** link into Hiddify / v2rayNG / Clash / sing-box. -4. Open `/{SECURE_PATH}/me/` in a browser to verify the status portal. -5. In Admin settings, pick a **disguise skin** and (recommended) bind **Cloudflare email** as login. -6. Store `SECURE_PATH`, Worker hostname, and admin password in your password manager. +Bare `/panel`, `/api/*`, `/sub/*` **without** SECURE PATH return **404**. --- -## Manual install (developers) +## Deprecated shell installers -
-Clone → D1 → build → deploy +One-line scripts remain for compatibility only. Prefer Wizard + `ship-panel.sh`. -```bash -git clone https://github.com/askarniroomand/XRayMOD.git -cd XRayMOD -npm install -npm install --prefix frontend -npm run build:ui -npx wrangler login -npx wrangler d1 create xraymod-db -# paste database_id into wrangler.toml -npx wrangler deploy -``` +
+Windows / Unix one-liners (legacy) -Bootstrap admin (first time): +**PowerShell:** -```bash -curl -X POST "https://YOUR_WORKER.workers.dev/install" \ - -H "Content-Type: application/json" \ - -d '{"username":"admin","password":"YourStrongPass123"}' +```powershell +irm https://raw.githubusercontent.com/askarniroomand/XRayMOD/main/install.ps1 | iex ``` -Then open: +**Linux / macOS / WSL:** -```text -https://YOUR_WORKER.workers.dev//login -https://YOUR_WORKER.workers.dev//panel +```bash +bash <(curl -fsSL https://raw.githubusercontent.com/askarniroomand/XRayMOD/main/install.sh) ``` -More detail: [DEPLOY.md](./DEPLOY.md). -
--- -## Architecture +## Project layout -### High-level - -```mermaid -graph TD - Clients[Clients v2rayNG, etc.] --> Edge[Cloudflare Network Worker] - Admin[Admin browser] --> Edge - Edge --> Router[Worker router.ts] - Router --> Processors[processors/] - Router --> Proxy[proxy/] - Router --> API[api/] - Router --> Portal[user-portal] - Portal --> D1[(D1 SQLite)] - API --> D1 +```text +XRayMOD/ +├── worker/ # Production Worker (API, router, policy, agents) +├── frontend/ # Next.js admin UI (static export) +├── scripts/ # ship-panel, deploy-worker-module, publish-rolling, node-agent +├── docs/ # Architecture & cleanup audit +├── installer/ # Legacy installer WebUI (deprecated primary path) +├── install.sh|.ps1 # Legacy one-line installers +├── wrangler.toml # Bindings template +├── DEPLOY.md # Operator runbook +├── AGENTS.md # Agent / fork operating manual +└── LICENSE ``` -### Canonical source of truth - -| Path | Role | -|:-----|:-----| -| `worker/` | **Production runtime** — routing, auth, sub, portal | -| `frontend/` | Admin panel UI | -| `installer/` + `install.*` | Bootstrap onto a Cloudflare account | -| `telegram-bot/` | Optional multi-panel Telegram operator bot | -| `docs/` | Human documentation and assets | -| `backend/` | Legacy / optional Python experiments — **not** required for Workers deploy | - -### Request flow (simplified) - -1. Request hits Worker `fetch` (`worker/index.ts`) -2. Router classifies: install · static · API · subscription · proxy · portal -3. Auth middleware gates admin APIs -4. D1 reads/writes users and settings -5. Response is panel JSON/HTML, subscription payload, or a disguise page +Canonical runtime is **`worker/`**. Treat `backend/` and legacy Vite under `src/` as non-production unless you know otherwise. --- -## Project structure - -```mermaid -graph TD - Root[XRayMOD/] --> Worker[worker/] - Root --> Frontend[frontend/] - Root --> Installer[installer/] - Root --> Bot[telegram-bot/] - Root --> Docs[docs/] - Root --> Scripts[scripts/] - Root --> InstallSh[install.sh] - Root --> InstallPs1[install.ps1] - Root --> Wrangler[wrangler.toml] - - Worker --> Api[api/] - Worker --> Processors[processors/] - Worker --> Proxy[proxy/] - Worker --> Lib[lib/] - Worker --> Index[index.ts] - Worker --> Router[router.ts] -``` - ---- - -## Configuration +## Development -| Variable / setting | Where | Notes | -|:-------------------|:------|:------| -| API token | Installer prompt only | Never commit | -| D1 `database_id` | Local wrangler config after install | Template uses placeholders in git | -| Access UUID / SECURE PATH | Generated at deploy | Treat as a secret path | -| Admin credentials | Bootstrap install | Rotate if leaked | -| Disguise mode | Panel settings | Skin for unknown routes | -| Protocol options | Panel / API | VLESS · Trojan · VMess related settings | +```bash +npm install +npm install --prefix frontend +npm run lint # tsc --noEmit +npm run build:ui # frontend → frontend/out +npm test # smoke tests +npm run dev:worker # local wrangler (after UI build) +``` -See `.env.example` and [SECURITY.md](./SECURITY.md). +CI: [`.github/workflows/ci.yml`](.github/workflows/ci.yml) · rolling publish: [`rolling-bundle.yml`](.github/workflows/rolling-bundle.yml) --- -## API overview +## API surface (overview) -Admin APIs are path-scoped behind the panel access UUID. +Admin routes require session auth and live under `/{SECURE_PATH}/api/…`. -| Area | Methods | Notes | -|:-----|:--------|:------| -| Auth login/logout | POST | Rate-limited | -| Users CRUD | GET/POST/PATCH/DELETE | Admin session required | -| Settings | GET/PUT | Admin session required | -| Nodes / backends | GET/POST | Admin session required | -| Subscription | GET | User UUID; `format` query param | -| Health | GET | Liveness | +| Area | Path prefix | Notes | +|:-----|:------------|:------| +| Auth | `/api/login`, `/api/logout` | Rate-limited | +| Users / configs / protocols | `/api/users`, `/api/configs`, … | Admin | +| Node Agents | `/api/agents` | Enroll / heartbeat / config | +| Wizard | `/api/wizard` | Setup, capabilities, deploy, OAuth PKCE | +| Admin / Lab | `/api/admin`, `/api/lab` | Update, policy, ops | +| Subscription | `/sub/` | `?format=clash\|singbox` | +| Health | `/api/health` | Liveness behind SECURE PATH | -> Full OpenAPI export is on the roadmap. Until then, inspect `worker/api/*` and panel network calls. +Inspect `worker/api/*` and panel network traffic for details. Public OpenAPI is not shipped yet. --- -## Roadmap +## Security -- [x] Workers + D1 panel core -- [x] `/me` status portal -- [x] Smart subscription bundle -- [x] One-line cross-platform install -- [ ] Public OpenAPI document -- [ ] Miniflare unit/integration tests in CI -- [ ] Signed release artifacts -- [ ] Multi-language panel UI packs -- [ ] Hardened error responses (no internal leakage) - -See [ROADMAP.md](./ROADMAP.md) and [CHANGELOG.md](./CHANGELOG.md). - ---- - -## Known issues - -| Issue | Severity | Workaround | -|:------|:---------|:-----------| -| GitHub raw CDN can cache install scripts briefly | Medium | Re-run after a minute | -| Dual historical trees (`backend/` vs Worker) may confuse new contributors | Medium | Treat `worker/` as canonical | -| Limited automated tests in early public tags | Medium | Use smoke / e2e scripts; contribute tests | -| Some 500 paths may be too verbose | Low–Med | Prefer generic client errors | - -Issues: https://github.com/askarniroomand/XRayMOD/issues +- SECURE PATH is a secret URL component—treat it like a credential +- Prefer Cloudflare email bind / strong admin password; rotate on leak +- Report vulnerabilities privately (see [`SECURITY.md`](SECURITY.md))—do not open public issues with secrets +- In-Worker proxy can be disabled via security policy (`disable_in_worker_proxy`) --- ## FAQ -
-Is a VPS required? - -No for the control plane. The panel runs on Cloudflare Workers + D1. Proxy backends/nodes are a separate concern depending on how you route user traffic. -
- -
-Does the free Cloudflare plan work? - -Yes for many personal setups. Watch Workers request limits and D1 quotas as you scale. -
- -
-Where is my API token stored? - -Only on your machine during install, sent only to Cloudflare APIs. Never commit it. See [SECURITY.md](./SECURITY.md). -
- -
-Why do I get 404 on /panel? - -Gen 1.9.12 requires the SECURE PATH UUID prefix. Use the full URL printed by the installer. -
- -
-Can I use Hiddify / v2rayNG? - -Yes. Import the subscription URL. Clash and sing-box formats are available via query parameters. -
- -
-How do I report a security issue? +**Do I need a VPS?** +Not for the control plane. You need nodes/agents if you terminate user proxy traffic off-Worker. -Privately via Telegram [@MRROBOT_DT](https://t.me/MRROBOT_DT) — do not open a public issue with secrets. -
+**Why 404 on `/panel`?** +SECURE PATH is required. Use the full URL from install/bootstrap. -
-Is this legal? +**How do I update a live panel?** +`bash scripts/ship-panel.sh`, or Admin → self-update after `publish-rolling.sh`. -Laws vary. You are solely responsible for lawful use and compliance with Cloudflare’s terms. -
+**Can I delete old installers?** +Only after an explicit cleanup approval. See [`docs/architecture/cleanup-audit.md`](docs/architecture/cleanup-audit.md). --- ## Contributing -Read [CONTRIBUTING.md](./CONTRIBUTING.md) and [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md). +See [`CONTRIBUTING.md`](CONTRIBUTING.md) and [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md). ```bash git clone https://github.com/askarniroomand/XRayMOD.git cd XRayMOD npm install -# open a feature branch, make changes, PR against main +# feature branch → PR against main ``` -Small docs PRs and tests are excellent first contributions. - --- -## Changelog & versioning +## License & authors -- [CHANGELOG.md](./CHANGELOG.md) -- Semantic versioning: `MAJOR.MINOR.PATCH` -- GitHub Releases via tag `vX.Y.Z` +MIT — see [`LICENSE`](LICENSE). ---- - -## License - -MIT © Askar Niroomand & Pakrohk — see [LICENSE](./LICENSE). - ---- - -## Authors - -| | GitHub | -|:--|:-------| +| Author | GitHub | +|:-------|:-------| | Askar Niroomand | [@askarniroomand](https://github.com/askarniroomand) | | Pakrohk | [@Pakrohk](https://github.com/Pakrohk) | ---- - -## Contact - -| Channel | Link | -|:--------|:-----| -| Authors | [@askarniroomand](https://github.com/askarniroomand) · [@Pakrohk](https://github.com/Pakrohk) | -| Telegram | [t.me/MRROBOT_DT](https://t.me/MRROBOT_DT) | -| Security | [SECURITY.md](./SECURITY.md) | -| Persian docs | [README.fa.md](./README.fa.md) | - ---- - -

- XRayMOD · Cloudflare Workers + D1 -

+Changelog: [`CHANGELOG.md`](CHANGELOG.md) · Roadmap: [`ROADMAP.md`](ROADMAP.md) diff --git a/ROADMAP.md b/ROADMAP.md index bc7e19c..4050a5a 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -32,11 +32,10 @@ - [x] Automatic clean IP scanning + Iranian ISP detection ## Phase 4: External Server Bridge -- [x] Telegram Bot integration (user notifications, management commands) - [x] Backend mode — VPS registration + auto-install script -- [ ] TON Wallet integration (payments, withdrawals) - [x] Bridge API between Worker and external server - [ ] Real-time notifications via WebSocket +- ~~Telegram Bot / Mini App / store / TON wallet~~ — removed from product ## Phase 5: WARP Integration - [ ] WARP account registration @@ -54,8 +53,8 @@ - [ ] NAT64 transition support ## Phase 7: Multi-Language & UX -- [x] Bilingual documentation (English + فارسی) -- [ ] RTL layout for Persian UI +- [x] English documentation +- [ ] ~~RTL layout for Persian UI~~ (removed — English only) - [ ] Guided setup wizard (/install) - [ ] Backup & Restore (export/import settings) - [ ] Daily traffic charts with upload/download split diff --git a/docs/architecture/cleanup-audit.md b/docs/architecture/cleanup-audit.md new file mode 100644 index 0000000..5c3374f --- /dev/null +++ b/docs/architecture/cleanup-audit.md @@ -0,0 +1,111 @@ +# Cleanup audit + +**Date:** 2026-08-16 +**Branch:** `sync/upstream-1.9.12` +**Policy:** Identify only. **Do not delete** non-generated paths until the user replies with explicit `approve cleanup` (and a DELETE list). + +See [AGENTS.md](../../AGENTS.md) Phase 2 and migration §2.5. + +--- + +## Definitely obsolete / removed product (keep 404 guards) + +| Path | Type | Reason | Referenced by | Replacement | Risk if deleted | +|------|------|--------|---------------|-------------|-----------------| +| Former `telegram-bot/` | DEAD_CODE | Product removed | None (dir gone) | Hard 404 in `worker/index.ts` / router / static | N/A — already gone | +| Former `frontend/app/twa/**` | DEAD_CODE | Product removed | 404 guards only | Panel routes | N/A — already gone | +| Commerce / bot API routes | DEAD_CODE | Product removed | 404 for `/api/commerce` | None | Keep guards | + +--- + +## Generated artifacts (safe to regenerate / ignore in git) + +| Path | Type | Reason | Notes | +|------|------|--------|-------| +| `frontend/.next/` | GENERATED_ARTIFACT | Next build cache | Rebuild via `npm run build:ui` | +| `frontend/out/` | GENERATED_ARTIFACT | Static export consumed by Wrangler assets | Rebuild before deploy | +| `node_modules/` | GENERATED_ARTIFACT | npm install | — | +| `.wrangler/` | GENERATED_ARTIFACT | Local CF state | Do not commit | +| `installer/__pycache__/` | GENERATED_ARTIFACT | Python bytecode | — | +| `.rolling/` | GENERATED_ARTIFACT / EXPERIMENTAL | Rolling bundle scratch | Confirm before any delete | + +--- + +## Competing / legacy runtimes (keep for migration) + +| Path | Type | Reason | Referenced by | Replacement | Deletion risk | +|------|------|--------|---------------|-------------|----------------| +| `backend/` | LEGACY_BUT_POTENTIALLY_USEFUL | Alternate Python control API | Docs / historical | Worker APIs | **High** — may still be used by operators | +| `src/` (+ `src/LEGACY.md`) | DUPLICATE / LEGACY | Old Vite React app | Root tsconfig historically | `frontend/` | Medium — exclude from lint already | +| `components/`, `lib/` (repo root) | DUPLICATE / UNKNOWN | Appear leftover from Vite panel | Possibly `src/` | `frontend/components` | Medium — reference-check before delete | +| `wizard/` | LEGACY_BUT_POTENTIALLY_USEFUL | Wizard Worker script package | Install/docs | Evolve into Phase 5 orchestrator | **High** — intended primary path | +| `installer/` | OBSOLETE_INSTALLER (as *primary*) | Python CLI deploy still works | `install.sh`, README | Wizard | **High** without migration | +| `install.sh`, `install.ps1`, `install.cmd` | OBSOLETE_INSTALLER (as *primary*) | Banner + README mark deprecated; files kept | README / users | Wizard | **High** without `approve cleanup` | +| `build-worker.sh`, `test-offline.sh` | UNKNOWN | Helper scripts | CI/local? | Document or fold into npm scripts | Medium | + +--- + +## Data-plane on Worker (architectural debt — do not delete yet) + +| Path | Type | Reason | Notes | +|------|------|--------|-------| +| `worker/proxy/**` | LEGACY_BUT_POTENTIALLY_USEFUL | In-Worker VLESS/Trojan/SS | Target: Node Agent data plane; needs migration plan | +| `worker/processors/**` | LEGACY_BUT_POTENTIALLY_USEFUL | Excluded from `tsc` include | Same | +| `worker/api/backends.ts` + `installer/backend-install.sh` | LEGACY_BUT_POTENTIALLY_USEFUL | Proto–Node Agent | Evolve, don’t rip | + +--- + +## Docs / marketing drift + +| Path | Type | Reason | Action | +|------|------|--------|--------| +| `ROADMAP.md` Phase 4 Telegram line | UNUSED_DOCUMENTATION (partial) | Struck through but roadmap still “panel” oriented | Update in Phase 7 | +| Stealth / “clean IP” copy in UI | UNUSED_DOCUMENTATION (partial) | Reworded in Phase 6 | Keep routes; language updated | + +--- + +## Keep (canonical production) + +- `worker/**` (except eventual proxy retirement after agent parity) +- `frontend/app/**`, `frontend/components/**`, `frontend/lib/**` +- `worker/lib/version.ts`, schema, auth, subscription, lab, remote API +- `.github/workflows/**`, `SECURITY.md`, wrangler config templates +- `scripts/deploy-panel.sh`, `scripts/smoke-test.mjs` + +--- + +## Proposed DELETE list (NOT approved) + +```text +DELETE +(none — awaiting user `approve cleanup`) + +DEPRECATE_ONLY +- install.sh / install.ps1 / install.cmd as primary onboarding (docs + wizard messaging) +- backend/ as production control plane +- src/ Vite app as production UI + +REGENERATE_OK +- frontend/.next +- frontend/out (after build:ui) +``` + +--- + +## Reference-check notes (Phase 2) + +Before any future deletion of `backend/`, `src/`, or root `components/`/`lib/`: + +1. `rg` for imports and README links. +2. Confirm no release scripts package those trees. +3. Add deprecation notices for one release if still referenced. + +--- + +## Gate + +**Status:** Audit complete. Waiting for explicit user approval language: + +`approve cleanup` + +with an agreed DELETE subset before removing any non-generated file. diff --git a/docs/architecture/current-state.md b/docs/architecture/current-state.md new file mode 100644 index 0000000..444ad60 --- /dev/null +++ b/docs/architecture/current-state.md @@ -0,0 +1,47 @@ +# Current architecture state + +**Date:** 2026-08-18 +**Branch:** `main` +**Product version:** 1.9.12 (`worker/lib/version.ts`) +**Schema soft version:** `XRayMOD_SCHEMA_VERSION = '5'` + +Control plane = Cloudflare Worker + D1 + panel UI. Data plane = Node Agents (Xray / sing-box). Cloudflare is an Edge Provider, not a VPN runtime. + +--- + +## Production runtime + +| Layer | Location | Role | +|-------|----------|------| +| Worker entry | `worker/index.ts` | `fetch` + cron; hard-404 `/twa` `/bot` `/api/commerce` | +| Router | `worker/router.ts` | Schema → optional in-Worker proxy (policy-gated) → secure-path → APIs | +| Storage | D1 | Users, configs, protocols, kvstore, backends, remote_api_keys, agent records in kvstore | +| Static UI | `frontend/out` | Next.js export | +| Edge Provider | `worker/lib/edge-provider/` | Cloudflare API + capability reports | +| Node Agents | `worker/api/agents.ts` | Enroll / heartbeat / config pull / health | +| Security policy | `worker/lib/security-policy.ts` | Kill switch, in-Worker proxy disable, caps | + +**In-Worker proxy** (`worker/proxy/`) remains for compatibility. Set `disable_in_worker_proxy` on the admin dashboard to return HTTP 501 for WS/gRPC/XHTTP upgrades. + +--- + +## Domain aliases (compatibility) + +| Legacy | Canonical meaning | +|--------|-------------------| +| backend | Legacy VPS row; listed beside Node Agents | +| cleanip | Edge endpoint latency probe (not “clean/residential”) | +| disguise / stealth | Origin protection for the panel UI | + +--- + +## Onboarding + +Canonical: Wizard (`/install`, `/api/wizard`) using **rolling** GitHub release assets. +Deprecated primary: `install.sh` / `install.ps1` / `install.cmd` / `installer/` (kept until `approve cleanup`). + +--- + +## Next + +Destructive file removal still needs explicit `approve cleanup`. See [`cleanup-audit.md`](cleanup-audit.md). diff --git a/frontend/app/globals.css b/frontend/app/globals.css index 359d451..db70c3c 100644 --- a/frontend/app/globals.css +++ b/frontend/app/globals.css @@ -25,8 +25,8 @@ --info: #5eb0ff; --radius: 0.65rem; --radius-lg: 0.9rem; - --font-display: "Syne", "Vazirmatn", ui-sans-serif, system-ui, sans-serif; - --font-body: "Manrope", "Vazirmatn", ui-sans-serif, system-ui, sans-serif; + --font-display: "Syne", ui-sans-serif, system-ui, sans-serif; + --font-body: "Manrope", ui-sans-serif, system-ui, sans-serif; --font-mono: "IBM Plex Mono", ui-monospace, monospace; } @@ -45,10 +45,6 @@ body { letter-spacing: -0.011em; } -[dir="rtl"] body { - font-family: "Vazirmatn", var(--font-body); -} - /* Ink field + aperture glow + fine scan lines */ body::before { content: ""; diff --git a/frontend/app/layout.tsx b/frontend/app/layout.tsx index 0bdf3cb..35ce116 100644 --- a/frontend/app/layout.tsx +++ b/frontend/app/layout.tsx @@ -5,7 +5,7 @@ import { Providers } from './providers'; export const metadata: Metadata = { title: 'XrayMOD', - description: 'XRayMOD — stealth proxy panel on Cloudflare Workers', + description: 'XRayMOD — secure VPN infrastructure control plane on Cloudflare Workers', robots: 'noindex, nofollow', }; @@ -18,12 +18,12 @@ export const viewport: Viewport = { export default function RootLayout({ children }: { children: React.ReactNode }) { return ( - + @@ -38,7 +38,7 @@ export default function RootLayout({ children }: { children: React.ReactNode }) background: '#101b2a', border: '1px solid rgba(140,175,210,0.16)', color: '#e8eef6', - fontFamily: 'Manrope, Vazirmatn, sans-serif', + fontFamily: 'Manrope, sans-serif', }, }} /> diff --git a/frontend/app/login/page.tsx b/frontend/app/login/page.tsx index 1bc9f3c..4794a0a 100644 --- a/frontend/app/login/page.tsx +++ b/frontend/app/login/page.tsx @@ -36,13 +36,13 @@ export default function LoginPage() { setRequire2fa(true); setChallenge(data.challenge); setError(''); - toast.message('کد Authenticator را وارد کنید'); + toast.message('Enter your Authenticator code'); setLoading(false); return; } if (data?.success) { - toast.success('ورود موفق'); + toast.success('Signed in successfully'); if (data.initialConfig) { try { sessionStorage.setItem('xraymod_initial', JSON.stringify(data.initialConfig)); @@ -50,31 +50,42 @@ export default function LoginPage() { /* ignore */ } } - goPanel('/panel'); + // Prefer server panel path if provided + const panelPath = + typeof data.panelPath === 'string' && data.panelPath + ? data.panelPath + : '/panel'; + goPanel(panelPath.startsWith('/') ? panelPath : `/${panelPath}`); return; } - setError(data?.message || data?.error || 'نام کاربری یا رمز اشتباه است'); + setError(data?.message || data?.error || 'Invalid username or password'); } catch { - setError('خطای شبکه — API در دسترس نیست'); + setError('Network error — API unavailable'); } finally { setLoading(false); } }; return ( -
-
+
+
-
-
+
+
-

- XrayMOD +

+ XrayMOD

-

- {require2fa ? 'تأیید دو مرحله‌ای' : 'ورود امن به کنترل‌پلین'} +

+ {require2fa ? 'Two-factor verification' : 'Secure panel sign-in'}

@@ -82,42 +93,45 @@ export default function LoginPage() { {!require2fa && ( <>
-
-