Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
49a1ec8
docs: зафиксировать дизайн onboarding GUI
Ap3x0s Sep 22, 2026
b4f5235
docs: составить план onboarding GUI
Ap3x0s Sep 22, 2026
4b9d26e
feat: описать контракты onboarding и диагностики
Ap3x0s Sep 22, 2026
8868d1f
feat: хранить SSH-ключи в системном keychain
Ap3x0s Sep 22, 2026
8003e6e
feat: сделать импорт сервера идемпотентным
Ap3x0s Sep 22, 2026
c62134a
feat: разрешать SSH-ключ из системного хранилища
Ap3x0s Sep 22, 2026
564337e
feat: разрешить quickstart без email
Ap3x0s Sep 22, 2026
c0aa764
feat: добавить read-only диагностику Xrayebator
Ap3x0s Sep 22, 2026
0fc69a3
feat: подключить инспектор существующих серверов
Ap3x0s Sep 23, 2026
fbceb15
feat: подключить email mode и импорт через IPC
Ap3x0s Sep 23, 2026
6065c92
feat: разделить сценарии нового и существующего сервера
Ap3x0s Sep 23, 2026
9156d42
docs: описать импорт и безопасность SSH ключей
Ap3x0s Sep 23, 2026
2dc1adc
test: включить onboarding контракты в typecheck
Ap3x0s Sep 23, 2026
cf2605c
fix: убрать SIGPIPE из email/inspect validation теста
Ap3x0s Sep 23, 2026
33b5d90
docs: свести счётчики тестов с фактическим набором
Ap3x0s Sep 23, 2026
3539bc9
feat: разрешить пароль при импорте существующего сервера
Ap3x0s Sep 23, 2026
2a877e3
ui: onboarding-карточки в вертикальный стек и крупнее иконки
Ap3x0s Sep 23, 2026
f90303e
fix(quickstart): закрыть гонку apt-lock с per-package dpkg unattended…
Ap3x0s Sep 23, 2026
6335f19
docs: уточнить политику сохранения SSH-пароля
Ap3x0s Sep 24, 2026
7f0fca3
feat: сохранять SSH-пароль в системном keychain и автоподключаться
Ap3x0s Sep 24, 2026
ac2d0b7
docs: отразить SSH-пароль в keychain и auto-connect
Ap3x0s Sep 24, 2026
87e2c15
docs: описать apt-lock регрессию и обновить счётчики validation
Ap3x0s Sep 24, 2026
4ce997d
feat: живая консоль в мастере импорта существующего сервера
Ap3x0s Sep 24, 2026
d7f08ca
ui: понятный статус вместо абстрактного «доступ подтверждён»
Ap3x0s Sep 24, 2026
e07700a
ui: убрать + у кнопки Добавить и центрировать текст в шапке
Ap3x0s Sep 24, 2026
0cbc972
ui: перенести сводку доступа и «Изменить доступ» на карточку сервера
Ap3x0s Sep 24, 2026
cb8bee0
ui: убрать таблицу «Состояние установки» из профилей сервера
Ap3x0s Sep 24, 2026
6fef5da
docs: синхронизировать раскладку доступа и установки
Ap3x0s Sep 24, 2026
5d18887
ui: оформить доступ на карточке как панель, кнопку — по канону
Ap3x0s Sep 24, 2026
5bfbfca
ui: переложить карточку сервера по образцу и убрать плашку статуса
Ap3x0s Sep 24, 2026
5a877ea
docs: описать раскладку карточки с плитками
Ap3x0s Sep 24, 2026
42b21cc
ui: выровнять шапку карточки и увеличить значки плиток
Ap3x0s Sep 24, 2026
188df7d
fix: маскировать токен подписки в консоли развёртывания
Ap3x0s Sep 24, 2026
efcd7c0
docs: описать консоль импорта и маскирование токена
Ap3x0s Sep 24, 2026
b8160cd
docs: добавить раздел Unreleased в CHANGELOG
Ap3x0s Sep 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,26 @@

User-facing Xrayebator changes. The server manager and Electron application are published from the canonical `howdeploy/Xrayebator` repository.

## [Unreleased]

### Added

- Optional email during deployment: `quickstart --without-email` registers Certbot with `--register-unsafely-without-email` instead of substituting a fake address; the GUI offers both modes and explains that renewal notices and ACME account recovery are unavailable without an email.
- Separate "deploy a new server" and "connect an existing server" flows. Import is strictly read-only (`xrayebator inspect --json`), recognizes Xrayebator installations only, and imports a partially configured server with honest component statuses.
- SSH login password is stored in the operating-system keychain after the first successful authentication and reused across restarts; the server card keeps only its non-secret credential id.
- Server card shows a summary of the saved access (`user@host:port`, where the secret lives) with a three-dot menu to change it, plus the reported OS, active route count and SSH user as icon tiles.
- The import wizard shows a live console of the work performed, alongside the step index.

### Changed

- Server Settings auto-connects with saved credentials and shows the profile panel directly; the access form appears only when there is no saved secret or a connection failed. The installation-status table was removed as a duplicate of the deployment and import consoles.
- The subscription token is masked in the deployment log and import console, because it is a bearer credential.

### Fixed

- `quickstart` no longer fails with `apt-get install nginx failed` when `unattended-upgrades` holds the apt/dpkg lock: every install waits for an active `unattended-upgrade` worker within a 12-minute budget and passes `-o DPkg::Lock::Timeout=180`.
- Bash validation scripts no longer die with `tr: write error: Broken pipe` on Ubuntu (`pipefail` plus an early-exiting reader).

## [0.5.0] - 2026-09-22

The first combined release of the updated server manager and **Xrayebator Desktop GUI**.
Expand Down
7 changes: 4 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Xrayebator — automated Xray Reality VPN manager for bypassing DPI censorship i
## Validation

There IS automated test coverage (despite what older notes said):
- **`validation/`** — 24 Bash test scripts, including `test-main-readiness-regressions.sh`, covering migrations, VLESS URL generation, transaction safety, dedup, firewall, menu numbering, the bypass/sni-change/port-change CLIs, quickstart and audit regressions. They run on the host (`bash validation/test-*.sh`); CI installs `jq`, `uuidgen` and `ripgrep` on Ubuntu. A bare Windows Git Bash checkout is not equivalent to the Linux environment.
- **`validation/`** — 26 Bash test scripts, including `test-main-readiness-regressions.sh`, covering migrations, VLESS URL generation, transaction safety, dedup, firewall, menu numbering, the bypass/sni-change/port-change CLIs, quickstart, email/inspect regressions, apt-lock race regressions and audit regressions. They run on the host (`bash validation/test-*.sh`); CI installs `jq`, `uuidgen` and `ripgrep` on Ubuntu. A bare Windows Git Bash checkout is not equivalent to the Linux environment.
- **`gui-legacy/tests/`** — 16 pytest modules covering SSH, deploy, connection, subscription and TUN runtime (legacy PySide6 GUI). Run with the GUI venv: `gui-legacy/.venv/Scripts/python -m pytest gui-legacy/tests`.
- **GUI (Electron)** — Vitest unit tests in `tests/`: `npm test`, plus `npm run typecheck`.
- **CI** — `.github/workflows/ci-linux.yml` runs the full `validation/` suite; `.github/workflows/gui-release.yml` runs `ruff` + `pytest gui-legacy/tests` and builds Windows/macOS bundles; `.github/workflows/release.yml` ships the Electron app.
Expand Down Expand Up @@ -127,15 +127,16 @@ Do NOT use raw `jq ... > temp && mv temp file` — always go through `safe_jq_wr
- `main` — stable, releases every 1-2 months
- `dev` — quick fixes, weekly or biweekly
- `experimental` — latest features, several times per week
- This checkout is currently on `main`; do not assume `experimental` is the working branch.
- This checkout is currently on `dev`; do not assume `experimental` is the working branch.

## CLI commands

Apart from the interactive menu (`sudo xrayebator`), the script exposes subcommands used by the GUI and by automation. They are dispatched at the very bottom of `xrayebator` (the `case "${1:-}" in ... esac` block guarded by `XRAYEBATOR_SOURCED`):

- `xrayebator update` — update only the Xray-core binary; `xrayebator update <branch>` self-updates the manager from the canonical raw branch and then updates Xray-core.
- `xrayebator-update [branch]` — separate full `update.sh` lifecycle workflow; without a branch it displays `.current_branch` and opens interactive branch selection.
- `xrayebator quickstart --email <email>` — UI CLI used by the desktop app: runs the broad setup/migration path, provisions the subscription endpoint, creates a standard **schema-v3 multi-route** HAPP profile (7 routes including `xhttp-legacy`), and prints JSON with `subscription_url`. The implementation currently tolerates migration failures in this non-interactive path; verify the resulting profile and services after deployment.
- `xrayebator quickstart --email <email>` — UI CLI used by the desktop app: runs the broad setup/migration path, provisions the subscription endpoint, creates a standard **schema-v3 multi-route** HAPP profile (7 routes including `xhttp-legacy`), and prints JSON with `subscription_url`. The implementation currently tolerates migration failures in this non-interactive path; verify the resulting profile and services after deployment. Email mode is explicit: `quickstart --without-email` runs the same path but registers Certbot/ACME with `--register-unsafely-without-email` (no renewal notices, no email-based account recovery; never substitute a fake address). The GUI passes exactly one of the two forms.
- `xrayebator inspect --json` — read-only install probe for the GUI "connect existing server" import: reports manager/Xray/profiles/subscription markers as one JSON object on stdout (diagnostics to stderr only). It must not migrate, install, restart, open firewall or write anything; `validation/test-quickstart-email-and-inspect.sh` guards these invariants statically.
- `xrayebator happ-setup` — reduced existing-install HAPP path; ensures the subscription service and a usable multi-route profile, verifies a real public TLS endpoint when subscription markers are missing, and prints JSON with `subscription_url`. It does not have the same migration breadth as quickstart.
- `xrayebator probe-test` — probe-test candidate SNIs from `sni_list.txt` and print reachability scores.
- `xrayebator profiles` — print all profiles as a flat JSON array (used by the GUI "Server settings" page).
Expand Down
19 changes: 8 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,17 +290,13 @@ What the GUI can do:

| Page | Operations |
|---|---|
| Dashboard | Server cards with reachability status, open, settings, delete; language switch |
| Add server | Deploy a new VPS: upload `install.sh` + `xrayebator`, run the install, place the binary, run `quickstart --email`, save the server and the `subscription_url` |
| Server keys | Refresh the subscription, copy the URL, show `vless://` links and QR codes |
| Dashboard | Server cards with reachability and installation status; an empty screen offers “Deploy a new server” or “Connect an existing server”; language switch |
| Add server | Deploy a new VPS with an explicit email choice: `quickstart --email` or `quickstart --without-email`; save the server and public subscription |
| Connect existing | Import a recognized Xrayebator installation over SSH (password or key) using read-only `xrayebator inspect --json`; partial installs are saved with diagnostics, without automatic repair |
| Server keys | Refresh the public subscription, copy the URL, show `vless://` links and QR codes |
| Server settings | SSH access by password or private key, direct root or sudo; list/create/delete profiles, change fingerprint, SNI and port, plus update or uninstall Xrayebator on the server |

Root + password is the one-click default; key authentication and sudo are optional. SSH passwords,
sudo passwords, key passphrases and private-key contents stay only in renderer memory for the active
form/session and are sent to the main process per operation. The app persists the server card,
connection preferences, `subscription_url`, fetched `vless://` links and the pinned SSH host-key
fingerprint. The subscription URL and VLESS links are bearer/client credentials: protect local app data
and revoke the subscription through the terminal workflow after a leak.
Root + password is the one-click default; key authentication and sudo are optional. A selected private key and a successfully used SSH login password are stored in the operating-system keychain via `keytar` and reused across later SSH operations and app restarts; the server card keeps only their non-secret credential ids and display name. A distinct sudo password and an encrypted-key passphrase are never persisted and are requested again when needed. If the OS keychain is unavailable, there is no plaintext fallback: the secret remains in main-process memory for the current app session and the UI warns that it must be entered again after restart. The app also persists the `subscription_url`, fetched `vless://` links and pinned SSH host-key fingerprint. The subscription URL and VLESS links are bearer/client credentials: protect local app data and revoke the subscription through the terminal workflow after a leak.

The GUI exposes only a subset of the terminal menu. Bypass, `probe-test`, subscription revoke,
`happ-setup`, cascade, self-steal and service logs/status remain terminal-only. See
Expand All @@ -314,8 +310,9 @@ npm run dev # Electron + Vite dev server
npm run build # compile the renderer and the main process
```

Electron checks: `npm test` runs the 9 unit files in `tests/`; `npm run typecheck` checks the
TypeScript surface. `npm run build` produces the app bundle. On native Windows, the POSIX-only
Electron checks: `npm test` runs the 14 unit files in `tests/`; `npm run typecheck` checks the
TypeScript surface, including the strict onboarding contracts in `tests/type-contracts/`.
`npm run build` produces the app bundle. On native Windows, the POSIX-only
`tests/unit/shell-command.test.ts` may fail because `/bin/sh` is absent; Linux CI is the source of truth.
See [Testing](docs/testing.md#desktop-gui) and [Electron Desktop GUI](docs/desktop-gui.md).

Expand Down
18 changes: 8 additions & 10 deletions README.ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -286,16 +286,13 @@ xrayebator (bash) ──► /usr/local/etc/xray/

| Страница | Операции |
|---|---|
| Dashboard | Карточки серверов со статусом доступности: открыть, настройки, удалить; переключатель языка |
| Добавить сервер | Развернуть новый VPS: загрузить `install.sh` + `xrayebator`, запустить установку, положить бинарь, выполнить `quickstart --email`, сохранить сервер и `subscription_url` |
| Ключи сервера | Обновить подписку, скопировать URL, показать ссылки `vless://` и QR-коды |
| Dashboard | Карточки серверов со статусом доступности и установки; пустой экран предлагает «Развернуть новый сервер» или «Подключить существующий»; переключатель языка |
| Добавить сервер | Развернуть VPS с явным выбором email: `quickstart --email` или `quickstart --without-email`; сохранить сервер и публичную подписку |
| Подключить существующий | Импорт распознанной установки Xrayebator по SSH (пароль или ключ) через read-only `xrayebator inspect --json`; частичные установки сохраняются с диагностикой без автоисправления |
| Ключи сервера | Обновить публичную подписку, скопировать URL, показать ссылки `vless://` и QR-коды |
| Настройки сервера | SSH по паролю или приватному ключу, прямой root или sudo; список/создание/удаление профилей, смена fingerprint, SNI и порта, обновление или удаление Xrayebator |

SSH-пароли, sudo-пароли, passphrase и содержимое приватного ключа живут только в активной форме/операции
и не сохраняются. Локально сохраняются карточка сервера, настройки подключения, `subscription_url`,
полученные ссылки `vless://` и закреплённый SSH host-key fingerprint. URL подписки и VLESS-ссылки —
bearer/client credentials: защищайте локальные данные приложения и после утечки отзывайте подписку
через терминальный workflow.
Выбранные приватный ключ и успешно использованный SSH-пароль сохраняются через `keytar` в системном keychain и повторно используются при следующих SSH-операциях и после перезапуска приложения; в карточке сервера хранятся только несекретные credential id и отображаемое имя ключа. Отдельный sudo-пароль и passphrase зашифрованного ключа не сохраняются и запрашиваются заново. Если системный keychain недоступен, plaintext-фолбека нет: секрет остаётся в памяти main process до завершения текущего сеанса, а GUI предупреждает, что после перезапуска его нужно ввести снова. Также локально сохраняются `subscription_url`, ссылки `vless://` и закреплённый SSH host-key fingerprint. Это bearer/client credentials: защищайте локальные данные и при утечке отзывайте подписку через терминальный workflow.

GUI предоставляет только подмножество терминального меню. Bypass, `probe-test`, revoke подписки,
`happ-setup`, каскад, self-steal и логи/статус сервисов остаются терминальными операциями. Полная
Expand All @@ -309,8 +306,9 @@ npm run dev # Electron + Vite dev server
npm run build # скомпилировать renderer и main process
```

Проверки Electron: `npm test` гоняет 9 unit-файлов из `tests/`; `npm run typecheck` проверяет
TypeScript, а `npm run build` собирает приложение. На нативном Windows POSIX-тест
Проверки Electron: `npm test` гоняет 14 unit-файлов из `tests/`; `npm run typecheck` проверяет
TypeScript, включая строгие onboarding-контракты из `tests/type-contracts/`, а `npm run build`
собирает приложение. На нативном Windows POSIX-тест
`tests/unit/shell-command.test.ts` может падать из-за отсутствия `/bin/sh`; источник истины — Linux CI.
См. [Тестирование](docs/ru/testing.md#десктоп-gui) и [справочник Electron GUI](docs/ru/desktop-gui.md).

Expand Down
17 changes: 8 additions & 9 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -274,15 +274,13 @@ GUI 的功能:

| 页面 | 操作 |
|---|---|
| Dashboard | 服务器卡片与连通状态:打开、设置、删除;语言切换 |
| 添加服务器 | 部署新 VPS:上传 `install.sh` 与 `xrayebator`,运行安装,放置二进制,执行 `quickstart --email`,保存服务器与 `subscription_url` |
| 服务器密钥 | 刷新订阅、复制链接、显示 `vless://` 链接与二维码 |
| Dashboard | 服务器卡片与连通/安装状态;空页面提供“部署新服务器”或“连接现有服务器”;语言切换 |
| 添加服务器 | 显式选择是否提供 email:`quickstart --email` 或 `quickstart --without-email`;保存服务器与公网订阅 |
| 连接现有服务器 | 通过 SSH(密码或密钥)和只读 `xrayebator inspect --json` 导入已识别的 Xrayebator;部分安装会连同诊断状态保存,不自动修复 |
| 服务器密钥 | 刷新公网订阅、复制链接、显示 `vless://` 链接与二维码 |
| 服务器设置 | 使用 SSH 密码或私钥、直接 root 或 sudo:列出/创建/删除配置档,修改指纹、SNI 和端口,以及更新或卸载服务器上的 Xrayebator |

SSH 密码、sudo 密码、私钥口令和私钥内容只在当前表单/操作期间保存在内存中,不会持久化。
本地会保存服务器卡片、连接偏好、`subscription_url`、获取到的 `vless://` 链接和固定的 SSH host-key
fingerprint。订阅 URL 和 VLESS 链接属于 bearer/client credentials:请保护本地应用数据,泄露后
通过终端 workflow 吊销订阅。
选中的私钥与成功登录时使用过的 SSH 密码都会通过 `keytar` 保存在操作系统钥匙串中,之后的 SSH 操作和应用重启均可复用;服务器卡片只保存非敏感的 credential id 和显示文件名。单独的 sudo 密码与加密私钥口令不会持久化,需要时重新输入。系统钥匙串不可用时不会写入明文回退文件:密钥仅保留在 main process 内存中直到当前会话结束,界面会提示重启后需重新输入。应用还会保存 `subscription_url`、获取到的 `vless://` 链接和固定的 SSH host-key fingerprint。这些是 bearer/client credentials:请保护本地应用数据,泄露后通过终端 workflow 吊销订阅。

GUI 只暴露终端菜单的一个子集。bypass、`probe-test`、订阅吊销、`happ-setup`、级联、self-steal
以及服务日志/状态仍需从终端执行。完整的 Electron GUI 边界、安全模型与打包说明见
Expand All @@ -296,8 +294,9 @@ npm run dev # Electron + Vite dev server
npm run build # 编译 renderer 与 main process
```

Electron 检查:`npm test` 运行 `tests/` 中的 9 个单元测试文件;`npm run typecheck` 检查 TypeScript,
`npm run build` 构建应用。在原生 Windows 上,POSIX 专用测试 `tests/unit/shell-command.test.ts`
Electron 检查:`npm test` 运行 `tests/` 中的 14 个单元测试文件;`npm run typecheck` 检查 TypeScript,
包含 `tests/type-contracts/` 中严格的 onboarding 契约;`npm run build` 构建应用。在原生 Windows 上,POSIX 专用测试
`tests/unit/shell-command.test.ts`
可能因缺少 `/bin/sh` 而失败;Linux CI 是事实来源。参见[测试](docs/zh-CN/testing.md#桌面图形界面)
和 [Electron 桌面 GUI](docs/zh-CN/desktop-gui.md)。

Expand Down
Loading
Loading