Add seed/Telegram login button and traffic usage indicator

New non-blocking login panel on the Home screen (seed backup/restore +
Telegram magic-link via the bot deep-link, polled through the new backend
endpoints) — uses its own popover instead of a full-screen Dialog so the
burger menu stays clickable while it's open. VpnStats now shows a used/limit
usage bar backed by a new useUsageStore.

Also registers tauri-plugin-shell (needed to open the t.me deep-link) and
threads an optional auth token from the app down through TunnelConfig to the
proxy client (desktop + Android), for instances running --require-auth.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-07 00:31:27 +07:00
parent bf50824833
commit 0cb6ad2860
17 changed files with 596 additions and 26 deletions
+1
View File
@@ -2,6 +2,7 @@
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_vpn::init())
.plugin(tauri_plugin_shell::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
@@ -42,7 +42,10 @@ data class TunnelConfig @JsonCreator constructor(
@JsonProperty("excludedApps") val excludedApps: List<String>,
@JsonProperty("excludedDomains") val excludedDomains: List<String>,
// Новое поле для режима песочницы
@JsonProperty("allowedApps") val allowedApps: List<String>? = null
@JsonProperty("allowedApps") val allowedApps: List<String>? = null,
// Bearer-токен клиента для проверки авторизации на прокси (--require-auth);
// null — сервер не требует авторизацию, либо приложение ещё не залогинено.
@JsonProperty("authToken") val authToken: String? = null
) : Parcelable
class TunVpnService : VpnService() {
@@ -122,7 +125,8 @@ class TunVpnService : VpnService() {
cacheDir.absolutePath,
config.killswitchEnabled,
config.excludedApps,
config.excludedDomains
config.excludedDomains,
config.authToken
)
triggerVibration(true)
sendStatusBroadcast("connected")
@@ -9,6 +9,8 @@ export interface TunnelConfig {
excludedApps: string[];
excludedDomains: string[];
allowedApps?: string[];
/** Bearer-токен для прокси-инстансов с `--require-auth`; `undefined` — не проверяется. */
authToken?: string;
}
export interface TrafficStatsResponse {
@@ -57,6 +57,7 @@ impl<R: Runtime> VpnInterface<R> for Vpn<R> {
config.killswitch_enabled,
config.excluded_apps.clone(),
config.excluded_domains.clone(),
config.auth_token.clone(),
);
// Сохраняем сессию
@@ -12,6 +12,11 @@ pub struct TunnelConfig {
pub excluded_domains: Vec<String>,
#[serde(default)]
pub allowed_apps: Vec<String>,
/// Bearer-токен клиента для проверки авторизации на прокси
/// (`--require-auth`); `None` — сервер не требует авторизацию, либо
/// приложение ещё не залогинено.
#[serde(default)]
pub auth_token: Option<String>,
}
#[derive(Debug, Deserialize, Serialize)]