Add decoy SNI plumbing, bundle wintun.dll, fix flag icons, add docs

- Прокидываем sni (decoy-хост) по обновлённому UDL через весь стек:
  guest-js -> Tauri-команда -> desktop/mobile -> Kotlin spawnSession.
  Список серверов пока статичный (backend еще не отдает sni), но логика
  похода в реальный /api/v1/nodes оставлена под флагом на будущее.
- Бандлим wintun.dll в Windows-инсталлятор через bundle.resources в
  tauri.windows.conf.json - раньше он копировался только для
  локального cargo run/tauri dev, но не попадал в NSIS/MSI.
- Чиним падение мобильной сборки: гитигнорённые UniFFI Kotlin-биндинги
  отстали от обновленного UDL (не хватало параметра sni).
- Флаги стран - локальные SVG вместо react-country-flag в CDN-режиме:
  тот бился об CSP и не грузился офлайн.
- Добавляем дерево README.md по структуре проекта и точечные
  комментарии в неочевидных местах кода.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Kirill
2026-07-02 19:29:29 +07:00
parent 16760c16ea
commit c852315d34
27 changed files with 464 additions and 57 deletions
+7
View File
@@ -0,0 +1,7 @@
# `src/lib/`
| Файл | Назначение |
|---|---|
| `api.ts` | REST-клиент бэкенда (`GET /api/v1/nodes`). Анонимная авторизация: генерирует/логинится по `seed` через `/auth/seed/*` ("Ghost Protocol"), кеширует короткоживущий JWT (~10 мин) в `localStorage`. Сейчас не задействован напрямую (`useNodesStore` работает в статическом режиме), но остаётся рабочим для будущего включения. |
| `platform.ts` | Детект платформы (`desktop`/`android`/`ios`/`web`). Сначала проверяет `window.__TAURI_INTERNALS__` — отличает реальный Tauri-webview от обычного браузера (например, `pnpm dev` без Tauri), и только внутри Tauri дальше уточняет ОС по `navigator.userAgent`, т.к. Tauri-рантайм один и тот же на всех платформах. |
| `utils.ts` | `cn()` — склейка classNames (`clsx` + `tailwind-merge`). |
+5
View File
@@ -22,6 +22,9 @@ export interface ServerNode {
countryCode: string;
ipAddress: string;
port: number;
// Домен-декой (SNI) — под него маскируется ClientHello при подключении
// именно к этому серверу. Должен совпадать с --decoy-host на сервере.
sni: string;
status: string;
currentLoad: number;
tunnelAddress: string;
@@ -37,6 +40,7 @@ interface RawVpnNode {
country_code: string;
ip_address: string;
port: number;
sni: string;
status: string;
current_load: number;
tunnel_address: string;
@@ -52,6 +56,7 @@ function mapNode(n: RawVpnNode): ServerNode {
countryCode: n.country_code,
ipAddress: n.ip_address,
port: n.port,
sni: n.sni,
status: n.status,
currentLoad: n.current_load,
tunnelAddress: n.tunnel_address,
+4
View File
@@ -1,9 +1,13 @@
export const getPlatform = () => {
const userAgent = navigator.userAgent.toLowerCase();
// Отличаем реальный Tauri-webview от обычного браузера (напр. pnpm dev
// без Tauri) — Tauri IPC там просто недоступен.
const isTauri = !!(window as any).__TAURI_INTERNALS__;
if (isTauri) {
// Рантайм Tauri один и тот же на всех платформах, поэтому конкретную ОС
// внутри него определяем по userAgent.
if (userAgent.includes("android")) return "android";
if (userAgent.includes("iphone") || userAgent.includes("ipad"))
return "ios";