diff --git a/package-lock.json b/package-lock.json index d49f732..5b9828f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "proxywarden", - "version": "1.0.0", + "version": "1.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "proxywarden", - "version": "1.0.0", + "version": "1.0.1", "dependencies": { "@fontsource-variable/jetbrains-mono": "^5.2.8", "@tauri-apps/api": "^2.0.0", diff --git a/package.json b/package.json index 69b1654..a5ab3f3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "proxywarden", - "version": "1.0.0", + "version": "1.0.1", "private": true, "type": "module", "description": "Standalone Windows desktop proxy management app for ProxyWarden.", diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 83e4f73..a622f3c 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -2314,7 +2314,7 @@ dependencies = [ [[package]] name = "proxywarden" -version = "1.0.0" +version = "1.0.1" dependencies = [ "base64 0.22.1", "reqwest 0.12.28", @@ -2324,6 +2324,7 @@ dependencies = [ "tauri-build", "tauri-plugin-dialog", "url", + "uuid", ] [[package]] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 40759a6..0ba2591 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "proxywarden" -version = "1.0.0" +version = "1.0.1" description = "Standalone Windows desktop proxy management app for ProxyWarden." authors = ["ProxyWarden"] edition = "2021" @@ -20,3 +20,4 @@ tauri-plugin-dialog = "2.7.1" base64 = "0.22" reqwest = { version = "0.12", default-features = false, features = ["blocking", "rustls-tls", "socks"] } url = "2" +uuid = { version = "1", features = ["v4"] } diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index f5f57a6..d7286ff 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -232,8 +232,6 @@ pub struct LocalSingBoxStatusResponse { pub struct LocalSingBoxConfigDto { pub subscription_display_url: Option, pub has_subscription: bool, - pub device_hwid_display: Option, - pub has_device_hwid: bool, pub selected_server_tag: Option, pub listen_host: String, pub listen_port: u16, @@ -264,15 +262,6 @@ pub struct SubscriptionServerDto { #[serde(rename_all = "camelCase")] pub struct SaveSingBoxSubscriptionInputDto { pub subscription_url: String, - #[serde(default)] - pub device_hwid: Option, -} - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct SaveSingBoxDeviceHwidInputDto { - #[serde(default)] - pub device_hwid: Option, } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -684,14 +673,6 @@ pub fn save_singbox_subscription( save_singbox_subscription_to_storage(&state.storage(), input, &SystemClock) } -#[tauri::command] -pub fn save_singbox_device_hwid( - state: tauri::State<'_, CommandState>, - input: SaveSingBoxDeviceHwidInputDto, -) -> Result { - save_singbox_device_hwid_to_storage(&state.storage(), input, &SystemClock) -} - #[tauri::command] pub async fn fetch_singbox_subscription( state: tauri::State<'_, CommandState>, @@ -1432,9 +1413,7 @@ pub fn save_singbox_subscription_to_storage( let mut config = storage.read_local_singbox_config().map_err(storage_error)?; config.subscription_url = Some(subscription_url); - if let Some(device_hwid) = input.device_hwid { - config.device_hwid = normalize_device_hwid(&device_hwid)?; - } + ensure_device_hwid(&mut config); config.updated_at = Some(clock.now()); storage .write_local_singbox_config(&config) @@ -1462,6 +1441,14 @@ pub fn fetch_singbox_subscription_with_fetcher( ) })?; + let device_hwid_created = ensure_device_hwid(&mut config); + if device_hwid_created { + config.updated_at = Some(clock.now()); + storage + .write_local_singbox_config(&config) + .map_err(storage_error)?; + } + let identity = subscription::SubscriptionFetchIdentity::with_device_hwid(config.device_hwid.as_deref()); let cache = fetcher @@ -1501,7 +1488,6 @@ pub fn forget_singbox_subscription_in_storage( ) -> Result { let mut config = storage.read_local_singbox_config().map_err(storage_error)?; config.subscription_url = None; - config.device_hwid = None; config.selected_server_tag = None; config.updated_at = Some(clock.now()); storage @@ -1514,24 +1500,6 @@ pub fn forget_singbox_subscription_in_storage( read_singbox_status(storage) } -pub fn save_singbox_device_hwid_to_storage( - storage: &JsonStorage, - input: SaveSingBoxDeviceHwidInputDto, - clock: &impl Clock, -) -> Result { - let mut config = storage.read_local_singbox_config().map_err(storage_error)?; - config.device_hwid = match input.device_hwid { - Some(device_hwid) => normalize_device_hwid(&device_hwid)?, - None => None, - }; - config.updated_at = Some(clock.now()); - storage - .write_local_singbox_config(&config) - .map_err(storage_error)?; - - read_singbox_status(storage) -} - pub fn select_singbox_server_in_storage( storage: &JsonStorage, input: SelectSingBoxServerInputDto, @@ -1734,27 +1702,17 @@ fn validate_subscription_url(subscription_url: &str) -> Result<(), CommandError> Ok(()) } -fn normalize_device_hwid(raw_hwid: &str) -> Result, CommandError> { - let device_hwid = raw_hwid.trim(); - if device_hwid.is_empty() { - return Ok(None); +fn ensure_device_hwid(config: &mut LocalSingBoxConfig) -> bool { + if config + .device_hwid + .as_deref() + .is_some_and(|value| !value.trim().is_empty()) + { + return false; } - if device_hwid.chars().count() > 256 { - return Err(CommandError::new( - "singbox_device_hwid_invalid", - "HWID устройства должен быть не длиннее 256 символов.", - )); - } - - if !device_hwid.chars().all(|ch| ch.is_ascii_graphic()) { - return Err(CommandError::new( - "singbox_device_hwid_invalid", - "HWID устройства может содержать только печатные ASCII-символы без пробелов.", - )); - } - - Ok(Some(device_hwid.to_string())) + config.device_hwid = Some(uuid::Uuid::new_v4().hyphenated().to_string().to_uppercase()); + true } fn ping_subscription_server(server: &SubscriptionServer) -> PingServerResponse { @@ -4234,11 +4192,6 @@ impl From<&LocalSingBoxConfig> for LocalSingBoxConfigDto { .subscription_url .as_deref() .is_some_and(|value| !value.trim().is_empty()), - device_hwid_display: config.device_hwid_display(), - has_device_hwid: config - .device_hwid - .as_deref() - .is_some_and(|value| !value.trim().is_empty()), selected_server_tag: config.selected_server_tag.clone(), listen_host: config.listen_host.clone(), listen_port: config.listen_port, diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 4d9f0ad..aff92f6 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -51,7 +51,6 @@ fn main() { commands::get_singbox_setup_status, commands::resolve_profile_preview, commands::save_singbox_subscription, - commands::save_singbox_device_hwid, commands::fetch_singbox_subscription, commands::forget_singbox_subscription, commands::select_singbox_server, diff --git a/src-tauri/src/models.rs b/src-tauri/src/models.rs index 5166242..14501fe 100644 --- a/src-tauri/src/models.rs +++ b/src-tauri/src/models.rs @@ -159,10 +159,6 @@ impl LocalSingBoxConfig { .as_deref() .map(redact_subscription_url) } - - pub fn device_hwid_display(&self) -> Option { - self.device_hwid.as_deref().map(redact_device_hwid) - } } impl Default for LocalSingBoxConfig { @@ -278,27 +274,3 @@ pub fn redact_subscription_url(raw_url: &str) -> String { } } } - -pub fn redact_device_hwid(raw_hwid: &str) -> String { - let trimmed = raw_hwid.trim(); - if trimmed.is_empty() { - return String::new(); - } - - let length = trimmed.chars().count(); - if length <= 8 { - return "***".to_string(); - } - - let prefix = trimmed.chars().take(4).collect::(); - let suffix = trimmed - .chars() - .rev() - .take(4) - .collect::() - .chars() - .rev() - .collect::(); - - format!("{prefix}...{suffix}") -} diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index defa304..d6c1024 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "ProxyWarden", - "version": "1.0.0", + "version": "1.0.1", "identifier": "ru.dokops.proxywarden.windows", "build": { "beforeDevCommand": "npm run dev", diff --git a/src-tauri/tests/singbox_command_tests.rs b/src-tauri/tests/singbox_command_tests.rs index aea49c9..e87ef09 100644 --- a/src-tauri/tests/singbox_command_tests.rs +++ b/src-tauri/tests/singbox_command_tests.rs @@ -25,10 +25,9 @@ mod validation; use commands::{ fetch_singbox_subscription_with_fetcher, forget_singbox_subscription_in_storage, - generate_singbox_config_with_services, save_singbox_device_hwid_to_storage, - save_singbox_subscription_to_storage, select_singbox_server_in_storage, Clock, - SaveSingBoxDeviceHwidInputDto, SaveSingBoxSubscriptionInputDto, SelectSingBoxServerInputDto, - SubscriptionFetcher, + generate_singbox_config_with_services, save_singbox_subscription_to_storage, + select_singbox_server_in_storage, Clock, SaveSingBoxSubscriptionInputDto, + SelectSingBoxServerInputDto, SubscriptionFetcher, }; use models::{ ActivityLevel, ComponentId, LocalSingBoxConfig, ProxyProtocol, SubscriptionCache, @@ -50,7 +49,6 @@ fn saves_subscription_url_without_exposing_secret_query() { &storage, SaveSingBoxSubscriptionInputDto { subscription_url: " https://sub.example.test/path?token=secret ".to_string(), - device_hwid: Some(" hwid-1234567890 ".to_string()), }, &FixedClock, ) @@ -63,58 +61,12 @@ fn saves_subscription_url_without_exposing_secret_query() { config.subscription_url, Some("https://sub.example.test/path?token=secret".to_string()) ); - assert_eq!(config.device_hwid, Some("hwid-1234567890".to_string())); + assert_valid_generated_hwid(config.device_hwid.as_deref()); assert!(status.config.has_subscription); - assert!(status.config.has_device_hwid); assert_eq!( status.config.subscription_display_url, Some("https://sub.example.test/...".to_string()) ); - assert_eq!( - status.config.device_hwid_display, - Some("hwid...7890".to_string()) - ); - - cleanup(&root); -} - -#[test] -fn saves_and_clears_device_hwid_without_exposing_raw_value() { - let root = test_root("save-hwid"); - let storage = JsonStorage::new(root.clone()); - - let status = save_singbox_device_hwid_to_storage( - &storage, - SaveSingBoxDeviceHwidInputDto { - device_hwid: Some(" device-abcdef1234 ".to_string()), - }, - &FixedClock, - ) - .expect("device hwid should be saved"); - let config = storage - .read_local_singbox_config() - .expect("read local sing-box config"); - - assert_eq!(config.device_hwid, Some("device-abcdef1234".to_string())); - assert!(status.config.has_device_hwid); - assert_eq!( - status.config.device_hwid_display, - Some("devi...1234".to_string()) - ); - - let status = save_singbox_device_hwid_to_storage( - &storage, - SaveSingBoxDeviceHwidInputDto { device_hwid: None }, - &FixedClock, - ) - .expect("device hwid should be cleared"); - let config = storage - .read_local_singbox_config() - .expect("read local sing-box config"); - - assert_eq!(config.device_hwid, None); - assert!(!status.config.has_device_hwid); - assert_eq!(status.config.device_hwid_display, None); cleanup(&root); } @@ -128,7 +80,6 @@ fn rejects_non_http_subscription_url() { &storage, SaveSingBoxSubscriptionInputDto { subscription_url: "file:///C:/sub.txt".to_string(), - device_hwid: None, }, &FixedClock, ) @@ -147,7 +98,6 @@ fn fetches_subscription_cache_and_selects_first_server() { &storage, SaveSingBoxSubscriptionInputDto { subscription_url: "https://sub.example.test/path?token=secret".to_string(), - device_hwid: None, }, &FixedClock, ) @@ -186,17 +136,21 @@ fn fetches_subscription_with_saved_device_hwid() { &storage, SaveSingBoxSubscriptionInputDto { subscription_url: "https://sub.example.test/path?token=secret".to_string(), - device_hwid: Some("hwid-abcdef1234".to_string()), }, &FixedClock, ) - .expect("save subscription URL and HWID"); + .expect("save subscription URL and generated HWID"); + let expected_hwid = storage + .read_local_singbox_config() + .expect("read local sing-box config") + .device_hwid + .expect("generated HWID"); fetch_singbox_subscription_with_fetcher( &storage, &HwidAssertingFetcher { cache: sample_cache(), - expected_hwid: Some("hwid-abcdef1234"), + expected_hwid, }, &FixedClock, ) @@ -205,6 +159,33 @@ fn fetches_subscription_with_saved_device_hwid() { cleanup(&root); } +#[test] +fn fetch_generates_device_hwid_for_existing_subscription_without_one() { + let root = test_root("fetch-generates-hwid"); + let storage = JsonStorage::new(root.clone()); + storage + .write_local_singbox_config(&LocalSingBoxConfig { + subscription_url: Some("https://sub.example.test/path?token=secret".to_string()), + device_hwid: None, + ..LocalSingBoxConfig::default() + }) + .expect("write local sing-box config"); + + fetch_singbox_subscription_with_fetcher( + &storage, + &GeneratedHwidAssertingFetcher(sample_cache()), + &FixedClock, + ) + .expect("fetch subscription through mock"); + let config = storage + .read_local_singbox_config() + .expect("read local sing-box config"); + + assert_valid_generated_hwid(config.device_hwid.as_deref()); + + cleanup(&root); +} + #[test] fn selects_server_from_cached_subscription() { let root = test_root("select-server"); @@ -271,7 +252,7 @@ fn generate_writes_config_and_local_singbox_target() { storage .write_local_singbox_config(&LocalSingBoxConfig { subscription_url: Some("https://sub.example.test/path".to_string()), - device_hwid: Some("hwid-abcdef1234".to_string()), + device_hwid: Some("C34C14C9-94BC-4918-B053-A249BC117A91".to_string()), selected_server_tag: Some("nl-1".to_string()), ..LocalSingBoxConfig::default() }) @@ -335,10 +316,11 @@ fn generate_requires_cached_subscription() { fn forget_subscription_clears_url_selection_and_cache() { let root = test_root("forget-subscription"); let storage = JsonStorage::new(root.clone()); + let existing_hwid = "C34C14C9-94BC-4918-B053-A249BC117A91".to_string(); storage .write_local_singbox_config(&LocalSingBoxConfig { subscription_url: Some("https://sub.example.test/path".to_string()), - device_hwid: Some("hwid-abcdef1234".to_string()), + device_hwid: Some(existing_hwid.clone()), selected_server_tag: Some("nl-1".to_string()), ..LocalSingBoxConfig::default() }) @@ -358,7 +340,7 @@ fn forget_subscription_clears_url_selection_and_cache() { assert!(!status.config.has_subscription); assert_eq!(config.subscription_url, None); - assert_eq!(config.device_hwid, None); + assert_eq!(config.device_hwid, Some(existing_hwid)); assert_eq!(config.selected_server_tag, None); assert_eq!(cache, None); @@ -380,7 +362,7 @@ impl SubscriptionFetcher for MockFetcher { struct HwidAssertingFetcher { cache: SubscriptionCache, - expected_hwid: Option<&'static str>, + expected_hwid: String, } impl SubscriptionFetcher for HwidAssertingFetcher { @@ -390,7 +372,10 @@ impl SubscriptionFetcher for HwidAssertingFetcher { identity: &subscription::SubscriptionFetchIdentity, ) -> Result { assert_eq!(url, "https://sub.example.test/path?token=secret"); - assert_eq!(identity.device_hwid.as_deref(), self.expected_hwid); + assert_eq!( + identity.device_hwid.as_deref(), + Some(self.expected_hwid.as_str()) + ); assert_eq!(identity.app_name, "ProxyWarden"); assert!(identity.user_agent.starts_with("ProxyWarden/")); assert_eq!(identity.device_os, std::env::consts::OS); @@ -399,6 +384,28 @@ impl SubscriptionFetcher for HwidAssertingFetcher { } } +struct GeneratedHwidAssertingFetcher(SubscriptionCache); + +impl SubscriptionFetcher for GeneratedHwidAssertingFetcher { + fn fetch_subscription( + &self, + url: &str, + identity: &subscription::SubscriptionFetchIdentity, + ) -> Result { + assert_eq!(url, "https://sub.example.test/path?token=secret"); + assert_valid_generated_hwid(identity.device_hwid.as_deref()); + assert_eq!(identity.app_name, "ProxyWarden"); + assert!(identity.user_agent.starts_with("ProxyWarden/")); + Ok(self.0.clone()) + } +} + +fn assert_valid_generated_hwid(value: Option<&str>) { + let value = value.expect("generated HWID"); + uuid::Uuid::parse_str(value).expect("HWID should be a UUID"); + assert_eq!(value, value.to_ascii_uppercase()); +} + struct MockChecker; impl SingBoxConfigChecker for MockChecker { diff --git a/src-tauri/tests/storage_tests.rs b/src-tauri/tests/storage_tests.rs index 4eaec68..ec4ba5c 100644 --- a/src-tauri/tests/storage_tests.rs +++ b/src-tauri/tests/storage_tests.rs @@ -92,11 +92,6 @@ fn roundtrips_local_singbox_config_and_subscription_cache() { config.subscription_display_url(), Some("https://sub.example.test/...".to_string()) ); - assert_eq!( - config.device_hwid_display(), - Some("hwid...1234".to_string()) - ); - cleanup(&root); } diff --git a/src/api/tauriCommands.ts b/src/api/tauriCommands.ts index f80f11f..15829a3 100644 --- a/src/api/tauriCommands.ts +++ b/src/api/tauriCommands.ts @@ -199,18 +199,9 @@ export function getSingBoxSetupStatus(): Promise { return invoke('get_singbox_setup_status'); } -export function saveSingBoxSubscription( - subscriptionUrl: string, - deviceHwid?: string, -): Promise { +export function saveSingBoxSubscription(subscriptionUrl: string): Promise { return invoke('save_singbox_subscription', { - input: { subscriptionUrl, deviceHwid }, - }); -} - -export function saveSingBoxDeviceHwid(deviceHwid?: string): Promise { - return invoke('save_singbox_device_hwid', { - input: { deviceHwid }, + input: { subscriptionUrl }, }); } diff --git a/src/app/App.tsx b/src/app/App.tsx index 4d22065..1a02fe9 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -1,6 +1,6 @@ import { useEffect, useMemo, useRef, useState, type CSSProperties } from 'react'; import { open } from '@tauri-apps/plugin-dialog'; -import { Cpu, FileCode2, Fingerprint, FolderOpen, Gauge, Link2, ShieldAlert, Trash2, Wand2 } from 'lucide-react'; +import { Cpu, FileCode2, FolderOpen, Gauge, Link2, ShieldAlert, Trash2, Wand2 } from 'lucide-react'; import { applyProfiles, fetchSingBoxSubscription, @@ -19,7 +19,6 @@ import { pingSingBoxServer, restartAsAdmin, saveProfile, - saveSingBoxDeviceHwid, saveSingBoxSubscription, saveTarget, selectSingBoxServer, @@ -45,7 +44,7 @@ import { serviceControlState } from './viewModel'; type DraftItemType = Extract; type ProxiFyreAction = 'start' | 'stop' | 'restart' | 'install' | 'uninstall'; -type SingBoxAction = 'start' | 'stop' | 'install' | 'uninstall' | 'fetch' | 'forget' | 'identity' | 'generate' | 'ping'; +type SingBoxAction = 'start' | 'stop' | 'install' | 'uninstall' | 'fetch' | 'forget' | 'generate' | 'ping'; type RouteMode = 'external' | 'local-singbox'; type ServiceVisualState = 'active' | 'settling' | null; type PanelId = 'summary' | 'proxifyre' | 'proxy'; @@ -185,7 +184,6 @@ export function App() { const [singBoxStatus, setSingBoxStatus] = useState(null); const [singBoxSetupStatus, setSingBoxSetupStatus] = useState(null); const [subscriptionInput, setSubscriptionInput] = useState(''); - const [deviceHwidInput, setDeviceHwidInput] = useState(''); const [serverPings, setServerPings] = useState>({}); const [proxyCheck, setProxyCheck] = useState(null); const [adminStatus, setAdminStatus] = useState(null); @@ -713,7 +711,6 @@ export function App() { async function syncSingBoxSubscription() { const subscriptionUrl = subscriptionInput.trim(); - const deviceHwid = deviceHwidInput.trim(); if (!subscriptionUrl && !singBoxStatus?.config.hasSubscription) { showNotice({ kind: 'error', @@ -726,15 +723,12 @@ export function App() { setSingBoxAction('fetch'); try { if (subscriptionUrl) { - await saveSingBoxSubscription(subscriptionUrl, deviceHwid || undefined); - } else if (deviceHwid) { - await saveSingBoxDeviceHwid(deviceHwid); + await saveSingBoxSubscription(subscriptionUrl); } const status = await fetchSingBoxSubscription(); setSingBoxStatus(status); setComponents((current) => upsertComponent(current, status.component)); setSubscriptionInput(''); - setDeviceHwidInput(''); setServerPings({}); setProxyCheck(null); showNotice({ @@ -753,64 +747,6 @@ export function App() { } } - async function saveSingBoxDeviceHwidData() { - const deviceHwid = deviceHwidInput.trim(); - if (!deviceHwid) { - showNotice({ - kind: 'error', - title: 'HWID не указан', - text: 'Вставь hard ID устройства для заголовка X-Hwid.', - }); - return; - } - - setSingBoxAction('identity'); - try { - const status = await saveSingBoxDeviceHwid(deviceHwid); - setSingBoxStatus(status); - setComponents((current) => upsertComponent(current, status.component)); - setDeviceHwidInput(''); - showNotice({ - kind: 'success', - title: 'HWID сохранен', - text: status.config.deviceHwidDisplay - ? `Для подписки будет отправляться X-Hwid: ${status.config.deviceHwidDisplay}` - : 'Для подписки будет отправляться X-Hwid.', - }); - } catch (error) { - showNotice({ - kind: 'error', - title: 'HWID не сохранен', - text: errorMessage(error), - }); - } finally { - setSingBoxAction(null); - } - } - - async function forgetSingBoxDeviceHwidData() { - setSingBoxAction('identity'); - try { - const status = await saveSingBoxDeviceHwid(undefined); - setSingBoxStatus(status); - setComponents((current) => upsertComponent(current, status.component)); - setDeviceHwidInput(''); - showNotice({ - kind: 'info', - title: 'HWID очищен', - text: 'Заголовок X-Hwid больше не будет отправляться при загрузке подписки.', - }); - } catch (error) { - showNotice({ - kind: 'error', - title: 'HWID не очищен', - text: errorMessage(error), - }); - } finally { - setSingBoxAction(null); - } - } - async function forgetSingBoxSubscriptionData() { setSingBoxAction('forget'); setIsSingBoxMenuOpen(false); @@ -823,7 +759,7 @@ export function App() { showNotice({ kind: 'info', title: 'Подписка очищена', - text: 'Ссылка, HWID, cache и выбранный сервер Local sing-box удалены.', + text: 'Ссылка, cache и выбранный сервер Local sing-box удалены.', }); } catch (error) { showNotice({ @@ -1492,38 +1428,6 @@ export function App() { /> -
- - setDeviceHwidInput(event.target.value)} - placeholder={singBoxStatus?.config.deviceHwidDisplay ?? 'X-Hwid hard ID'} - spellCheck={false} - aria-label="Hard ID устройства для X-Hwid" - /> - - void forgetSingBoxDeviceHwidData()} - disabled={Boolean(singBoxAction) || !singBoxStatus?.config.hasDeviceHwid} - label="Очистить hard ID устройства" - tooltip="Очистить HWID" - icon={} - /> -
-
Серверы подписки
@@ -2662,7 +2566,6 @@ function singBoxDetailLines( `Файл: ${component?.path ?? 'не найден'}`, `Конфиг: ${status?.generatedConfigPath ?? 'не создан'}`, `Подписка: ${status?.config.subscriptionDisplayUrl ?? (status?.config.hasSubscription ? 'сохранена' : 'не загружена')}`, - `X-Hwid: ${status?.config.deviceHwidDisplay ?? (status?.config.hasDeviceHwid ? 'сохранен' : 'не задан')}`, `Состав: ${setupDetails}`, ]; } diff --git a/src/domain/types.ts b/src/domain/types.ts index 41123e7..c0a446e 100644 --- a/src/domain/types.ts +++ b/src/domain/types.ts @@ -71,8 +71,6 @@ export interface ComponentStatus { export interface LocalSingBoxConfig { subscriptionDisplayUrl?: string; hasSubscription: boolean; - deviceHwidDisplay?: string; - hasDeviceHwid: boolean; selectedServerTag?: string; listenHost: string; listenPort: number;