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:
@@ -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`). |
|
||||
@@ -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,
|
||||
|
||||
@@ -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";
|
||||
|
||||
Reference in New Issue
Block a user