From 34f836bc16c8213892c9e469f433f6f4633389c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Thu, 19 Jun 2025 15:45:29 +0200 Subject: [PATCH 1/7] Use BoringTun --- src-tauri/Cargo.lock | 139 ++++++++++++++++++++++++++- src-tauri/Cargo.toml | 3 +- src-tauri/cli/src/bin/dg.rs | 3 +- src-tauri/src/bin/defguard-client.rs | 19 ---- src-tauri/src/service/mod.rs | 23 +++-- 5 files changed, 156 insertions(+), 31 deletions(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index c4d7c34d..c6401175 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -17,6 +17,16 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + [[package]] name = "ahash" version = "0.7.8" @@ -638,6 +648,15 @@ dependencies = [ "wyz", ] +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + [[package]] name = "block" version = "0.1.6" @@ -684,6 +703,29 @@ dependencies = [ "piper", ] +[[package]] +name = "boringtun" +version = "0.6.0" +dependencies = [ + "aead", + "base64 0.22.1", + "blake2", + "chacha20poly1305", + "hex", + "hmac", + "ip_network", + "ip_network_table", + "libc", + "nix 0.30.1", + "parking_lot", + "ring", + "socket2 0.5.10", + "thiserror 2.0.12", + "tracing", + "untrusted", + "x25519-dalek", +] + [[package]] name = "borsh" version = "1.5.7" @@ -897,6 +939,30 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +dependencies = [ + "aead", + "chacha20", + "cipher", + "poly1305", + "zeroize", +] + [[package]] name = "chrono" version = "0.4.41" @@ -912,6 +978,17 @@ dependencies = [ "windows-link", ] +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", + "zeroize", +] + [[package]] name = "clap" version = "4.5.40" @@ -1229,6 +1306,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", + "rand_core 0.6.4", "typenum", ] @@ -1412,10 +1490,9 @@ dependencies = [ [[package]] name = "defguard_wireguard_rs" version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ed457218300b436c4da81cd4f78bae85c1d630f817a216817ef3702e9e615e" dependencies = [ "base64 0.22.1", + "boringtun", "libc", "log", "netlink-packet-core", @@ -2954,6 +3031,15 @@ dependencies = [ "cfb", ] +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + [[package]] name = "instant" version = "0.1.13" @@ -2974,6 +3060,28 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "ip_network" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2f047c0a98b2f299aa5d6d7088443570faae494e9ae1305e48be000c9e0eb1" + +[[package]] +name = "ip_network_table" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4099b7cfc5c5e2fe8c5edf3f6f7adf7a714c9cc697534f63a5a5da30397cb2c0" +dependencies = [ + "ip_network", + "ip_network_table-deps-treebitmap", +] + +[[package]] +name = "ip_network_table-deps-treebitmap" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e537132deb99c0eb4b752f0346b6a836200eaaa3516dd7e5514b63930a09e5d" + [[package]] name = "ipnet" version = "2.11.0" @@ -3885,6 +3993,12 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + [[package]] name = "openssl" version = "0.10.73" @@ -4331,6 +4445,17 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + [[package]] name = "potential_utf" version = "0.1.2" @@ -6758,6 +6883,16 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + [[package]] name = "untrusted" version = "0.9.0" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index a05c73a3..e0e16dee 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -3,7 +3,8 @@ members = ["cli", "common"] default-members = [".", "cli"] [workspace.dependencies] -defguard_wireguard_rs = { version = "0.7.4" } +# defguard_wireguard_rs = { version = "0.7.4" } +defguard_wireguard_rs = { path = "../../wireguard-rs" } [workspace.package] authors = ["Defguard"] diff --git a/src-tauri/cli/src/bin/dg.rs b/src-tauri/cli/src/bin/dg.rs index 036f56ad..d011691f 100644 --- a/src-tauri/cli/src/bin/dg.rs +++ b/src-tauri/cli/src/bin/dg.rs @@ -159,7 +159,8 @@ async fn connect(config: CliConfig, trigger: Arc) -> Result<(), CliError #[cfg(not(target_os = "macos"))] let wgapi = WGApi::::new(ifname.to_string()).expect("Failed to setup WireGuard API"); #[cfg(target_os = "macos")] - let wgapi = WGApi::::new(ifname.to_string()).expect("Failed to setup WireGuard API"); + let mut wgapi = + WGApi::::new(ifname.to_string()).expect("Failed to setup WireGuard API"); #[cfg(not(windows))] { diff --git a/src-tauri/src/bin/defguard-client.rs b/src-tauri/src/bin/defguard-client.rs index 33eb3856..65c731cf 100644 --- a/src-tauri/src/bin/defguard-client.rs +++ b/src-tauri/src/bin/defguard-client.rs @@ -18,8 +18,6 @@ use defguard_client::{ VERSION, }; use log::{Level, LevelFilter}; -#[cfg(target_os = "macos")] -use tauri::{api::process, Env}; use tauri::{Builder, Manager, RunEvent, State, SystemTray, WindowEvent}; use tauri_plugin_log::LogTarget; @@ -41,23 +39,6 @@ static LOG_INCLUDES: LazyLock> = LazyLock::new(load_log_targets); #[tokio::main] async fn main() { - // add bundled `wireguard-go` binary to PATH - #[cfg(target_os = "macos")] - { - debug!("Adding bundled wireguard-go binary to PATH"); - let current_bin_path = - process::current_binary(&Env::default()).expect("Failed to get current binary path"); - let current_bin_dir = current_bin_path - .parent() - .expect("Failed to get current binary directory"); - let current_path = env::var("PATH").expect("Failed to get current PATH variable"); - env::set_var( - "PATH", - format!("{current_path}:{}", current_bin_dir.to_str().unwrap()), - ); - debug!("Added binary dir {current_bin_dir:?} to PATH"); - } - let app = Builder::default() .invoke_handler(tauri::generate_handler![ all_locations, diff --git a/src-tauri/src/service/mod.rs b/src-tauri/src/service/mod.rs index 171bf8e3..93cc64ac 100644 --- a/src-tauri/src/service/mod.rs +++ b/src-tauri/src/service/mod.rs @@ -11,6 +11,7 @@ use std::{ net::{IpAddr, Ipv4Addr, SocketAddr}, pin::Pin, str::FromStr, + sync::RwLock, time::{Duration, SystemTime, UNIX_EPOCH}, }; @@ -54,8 +55,13 @@ pub enum DaemonError { TransportError(#[from] tonic::transport::Error), } -#[derive(Debug, Default)] -pub struct DaemonService { +#[derive(Default)] +pub(crate) struct DaemonService { + // Map of running `WGApi`s; key is interface name. + #[cfg(target_os = "macos")] + wgapis: RwLock>>, + #[cfg(not(target_os = "macos"))] + wgapis: HashMap>, stats_period: Duration, } @@ -63,6 +69,7 @@ impl DaemonService { #[must_use] pub fn new(config: &Config) -> Self { Self { + wgapis: RwLock::new(HashMap::new()), stats_period: Duration::from_secs(config.stats_period), } } @@ -109,8 +116,11 @@ impl DesktopDaemonService for DaemonService { .into(); let ifname = &config.name; let _span = info_span!("create_interface", interface_name = &ifname).entered(); - // setup WireGuard API - let wgapi = setup_wgapi(ifname)?; + // Setup WireGuard API. + let mut wgapis_map = self.wgapis.write().unwrap(); + let wgapi = wgapis_map + .entry(ifname.clone()) + .or_insert(setup_wgapi(ifname)?); #[cfg(not(windows))] { @@ -327,10 +337,7 @@ pub async fn run_server(config: Config) -> anyhow::Result<()> { let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), DAEMON_HTTP_PORT); let daemon_service = DaemonService::new(&config); - info!( - "Defguard daemon version {} started, listening on {addr}", - VERSION - ); + info!("Defguard daemon version {VERSION} started, listening on {addr}"); debug!("Defguard daemon configuration: {config:?}"); Server::builder() From 3cf0e81a727d95ab76473cb72a05ed83cdc1a4c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Mon, 29 Sep 2025 12:29:41 +0200 Subject: [PATCH 2/7] Handle WGApi --- package.json | 6 +- pnpm-lock.yaml | 319 ++++++++++++++-------------- src-tauri/Cargo.lock | 401 +++++++++++++++++++++++++++++++++++ src-tauri/src/service/mod.rs | 70 +++--- 4 files changed, 607 insertions(+), 189 deletions(-) diff --git a/package.json b/package.json index ee8a6109..d4095836 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "lodash-es": "^4.17.21", "merge-refs": "^2.0.0", "millify": "^6.1.0", - "motion": "^12.23.21", + "motion": "^12.23.22", "p-timeout": "^6.1.4", "prop-types": "^15.8.1", "radash": "^12.1.1", @@ -115,9 +115,9 @@ "@types/file-saver": "^2.0.7", "@types/lodash-es": "^4.17.12", "@types/node": "^24.5.2", - "@types/react": "^19.1.13", + "@types/react": "^19.1.15", "@types/react-dom": "^19.1.9", - "@vitejs/plugin-react": "^5.0.3", + "@vitejs/plugin-react": "^5.0.4", "@vitejs/plugin-react-swc": "^4.1.0", "autoprefixer": "^10.4.21", "npm-run-all": "^4.1.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b2cd5ffb..4e3d63ad 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -100,7 +100,7 @@ importers: version: 1.0.3 html-react-parser: specifier: ^5.2.6 - version: 5.2.6(@types/react@19.1.13)(react@19.1.1) + version: 5.2.6(@types/react@19.1.15)(react@19.1.1) itertools: specifier: ^2.5.0 version: 2.5.0 @@ -112,13 +112,13 @@ importers: version: 4.17.21 merge-refs: specifier: ^2.0.0 - version: 2.0.0(@types/react@19.1.13) + version: 2.0.0(@types/react@19.1.15) millify: specifier: ^6.1.0 version: 6.1.0 motion: - specifier: ^12.23.21 - version: 12.23.21(@emotion/is-prop-valid@1.4.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + specifier: ^12.23.22 + version: 12.23.22(@emotion/is-prop-valid@1.4.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) p-timeout: specifier: ^6.1.4 version: 6.1.4 @@ -148,7 +148,7 @@ importers: version: 3.5.0(react@19.1.1) react-markdown: specifier: ^10.1.0 - version: 10.1.0(@types/react@19.1.13)(react@19.1.1) + version: 10.1.0(@types/react@19.1.15)(react@19.1.1) react-qr-code: specifier: ^2.0.18 version: 2.0.18(react@19.1.1) @@ -163,7 +163,7 @@ importers: version: 1.0.26(react-dom@19.1.1(react@19.1.1))(react@19.1.1) recharts: specifier: ^3.2.1 - version: 3.2.1(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react-is@18.3.1)(react@19.1.1)(redux@5.0.1) + version: 3.2.1(@types/react@19.1.15)(react-dom@19.1.1(react@19.1.1))(react-is@18.3.1)(react@19.1.1)(redux@5.0.1) rehype-sanitize: specifier: ^6.0.0 version: 6.0.0 @@ -178,14 +178,14 @@ importers: version: 3.25.76 zustand: specifier: ^5.0.8 - version: 5.0.8(@types/react@19.1.13)(immer@10.1.3)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) + version: 5.0.8(@types/react@19.1.15)(immer@10.1.3)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) devDependencies: '@biomejs/biome': specifier: ^2.2.4 version: 2.2.4 '@hookform/devtools': specifier: ^4.4.0 - version: 4.4.0(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 4.4.0(@types/react@19.1.15)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@svgr/cli': specifier: ^8.1.0 version: 8.1.0(typescript@5.9.2) @@ -208,14 +208,14 @@ importers: specifier: ^24.5.2 version: 24.5.2 '@types/react': - specifier: ^19.1.13 - version: 19.1.13 + specifier: ^19.1.15 + version: 19.1.15 '@types/react-dom': specifier: ^19.1.9 - version: 19.1.9(@types/react@19.1.13) + version: 19.1.9(@types/react@19.1.15) '@vitejs/plugin-react': - specifier: ^5.0.3 - version: 5.0.3(vite@7.1.7(@types/node@24.5.2)(sass@1.92.1)(yaml@2.8.1)) + specifier: ^5.0.4 + version: 5.0.4(vite@7.1.7(@types/node@24.5.2)(sass@1.92.1)(yaml@2.8.1)) '@vitejs/plugin-react-swc': specifier: ^4.1.0 version: 4.1.0(vite@7.1.7(@types/node@24.5.2)(sass@1.92.1)(yaml@2.8.1)) @@ -765,113 +765,116 @@ packages: '@rolldown/pluginutils@1.0.0-beta.35': resolution: {integrity: sha512-slYrCpoxJUqzFDDNlvrOYRazQUNRvWPjXA17dAOISY3rDMxX6k8K4cj2H+hEYMHF81HO3uNd5rHVigAWRM5dSg==} - '@rollup/rollup-android-arm-eabi@4.52.2': - resolution: {integrity: sha512-o3pcKzJgSGt4d74lSZ+OCnHwkKBeAbFDmbEm5gg70eA8VkyCuC/zV9TwBnmw6VjDlRdF4Pshfb+WE9E6XY1PoQ==} + '@rolldown/pluginutils@1.0.0-beta.38': + resolution: {integrity: sha512-N/ICGKleNhA5nc9XXQG/kkKHJ7S55u0x0XUJbbkmdCnFuoRkM1Il12q9q0eX19+M7KKUEPw/daUPIRnxhcxAIw==} + + '@rollup/rollup-android-arm-eabi@4.52.3': + resolution: {integrity: sha512-h6cqHGZ6VdnwliFG1NXvMPTy/9PS3h8oLh7ImwR+kl+oYnQizgjxsONmmPSb2C66RksfkfIxEVtDSEcJiO0tqw==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.52.2': - resolution: {integrity: sha512-cqFSWO5tX2vhC9hJTK8WAiPIm4Q8q/cU8j2HQA0L3E1uXvBYbOZMhE2oFL8n2pKB5sOCHY6bBuHaRwG7TkfJyw==} + '@rollup/rollup-android-arm64@4.52.3': + resolution: {integrity: sha512-wd+u7SLT/u6knklV/ifG7gr5Qy4GUbH2hMWcDauPFJzmCZUAJ8L2bTkVXC2niOIxp8lk3iH/QX8kSrUxVZrOVw==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.52.2': - resolution: {integrity: sha512-vngduywkkv8Fkh3wIZf5nFPXzWsNsVu1kvtLETWxTFf/5opZmflgVSeLgdHR56RQh71xhPhWoOkEBvbehwTlVA==} + '@rollup/rollup-darwin-arm64@4.52.3': + resolution: {integrity: sha512-lj9ViATR1SsqycwFkJCtYfQTheBdvlWJqzqxwc9f2qrcVrQaF/gCuBRTiTolkRWS6KvNxSk4KHZWG7tDktLgjg==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.52.2': - resolution: {integrity: sha512-h11KikYrUCYTrDj6h939hhMNlqU2fo/X4NB0OZcys3fya49o1hmFaczAiJWVAFgrM1NCP6RrO7lQKeVYSKBPSQ==} + '@rollup/rollup-darwin-x64@4.52.3': + resolution: {integrity: sha512-+Dyo7O1KUmIsbzx1l+4V4tvEVnVQqMOIYtrxK7ncLSknl1xnMHLgn7gddJVrYPNZfEB8CIi3hK8gq8bDhb3h5A==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.52.2': - resolution: {integrity: sha512-/eg4CI61ZUkLXxMHyVlmlGrSQZ34xqWlZNW43IAU4RmdzWEx0mQJ2mN/Cx4IHLVZFL6UBGAh+/GXhgvGb+nVxw==} + '@rollup/rollup-freebsd-arm64@4.52.3': + resolution: {integrity: sha512-u9Xg2FavYbD30g3DSfNhxgNrxhi6xVG4Y6i9Ur1C7xUuGDW3banRbXj+qgnIrwRN4KeJ396jchwy9bCIzbyBEQ==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.52.2': - resolution: {integrity: sha512-QOWgFH5X9+p+S1NAfOqc0z8qEpJIoUHf7OWjNUGOeW18Mx22lAUOiA9b6r2/vpzLdfxi/f+VWsYjUOMCcYh0Ng==} + '@rollup/rollup-freebsd-x64@4.52.3': + resolution: {integrity: sha512-5M8kyi/OX96wtD5qJR89a/3x5x8x5inXBZO04JWhkQb2JWavOWfjgkdvUqibGJeNNaz1/Z1PPza5/tAPXICI6A==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.52.2': - resolution: {integrity: sha512-kDWSPafToDd8LcBYd1t5jw7bD5Ojcu12S3uT372e5HKPzQt532vW+rGFFOaiR0opxePyUkHrwz8iWYEyH1IIQA==} + '@rollup/rollup-linux-arm-gnueabihf@4.52.3': + resolution: {integrity: sha512-IoerZJ4l1wRMopEHRKOO16e04iXRDyZFZnNZKrWeNquh5d6bucjezgd+OxG03mOMTnS1x7hilzb3uURPkJ0OfA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.52.2': - resolution: {integrity: sha512-gKm7Mk9wCv6/rkzwCiUC4KnevYhlf8ztBrDRT9g/u//1fZLapSRc+eDZj2Eu2wpJ+0RzUKgtNijnVIB4ZxyL+w==} + '@rollup/rollup-linux-arm-musleabihf@4.52.3': + resolution: {integrity: sha512-ZYdtqgHTDfvrJHSh3W22TvjWxwOgc3ThK/XjgcNGP2DIwFIPeAPNsQxrJO5XqleSlgDux2VAoWQ5iJrtaC1TbA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.52.2': - resolution: {integrity: sha512-66lA8vnj5mB/rtDNwPgrrKUOtCLVQypkyDa2gMfOefXK6rcZAxKLO9Fy3GkW8VkPnENv9hBkNOFfGLf6rNKGUg==} + '@rollup/rollup-linux-arm64-gnu@4.52.3': + resolution: {integrity: sha512-NcViG7A0YtuFDA6xWSgmFb6iPFzHlf5vcqb2p0lGEbT+gjrEEz8nC/EeDHvx6mnGXnGCC1SeVV+8u+smj0CeGQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.52.2': - resolution: {integrity: sha512-s+OPucLNdJHvuZHuIz2WwncJ+SfWHFEmlC5nKMUgAelUeBUnlB4wt7rXWiyG4Zn07uY2Dd+SGyVa9oyLkVGOjA==} + '@rollup/rollup-linux-arm64-musl@4.52.3': + resolution: {integrity: sha512-d3pY7LWno6SYNXRm6Ebsq0DJGoiLXTb83AIPCXl9fmtIQs/rXoS8SJxxUNtFbJ5MiOvs+7y34np77+9l4nfFMw==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loong64-gnu@4.52.2': - resolution: {integrity: sha512-8wTRM3+gVMDLLDdaT6tKmOE3lJyRy9NpJUS/ZRWmLCmOPIJhVyXwjBo+XbrrwtV33Em1/eCTd5TuGJm4+DmYjw==} + '@rollup/rollup-linux-loong64-gnu@4.52.3': + resolution: {integrity: sha512-3y5GA0JkBuirLqmjwAKwB0keDlI6JfGYduMlJD/Rl7fvb4Ni8iKdQs1eiunMZJhwDWdCvrcqXRY++VEBbvk6Eg==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.52.2': - resolution: {integrity: sha512-6yqEfgJ1anIeuP2P/zhtfBlDpXUb80t8DpbYwXQ3bQd95JMvUaqiX+fKqYqUwZXqdJDd8xdilNtsHM2N0cFm6A==} + '@rollup/rollup-linux-ppc64-gnu@4.52.3': + resolution: {integrity: sha512-AUUH65a0p3Q0Yfm5oD2KVgzTKgwPyp9DSXc3UA7DtxhEb/WSPfbG4wqXeSN62OG5gSo18em4xv6dbfcUGXcagw==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.52.2': - resolution: {integrity: sha512-sshYUiYVSEI2B6dp4jMncwxbrUqRdNApF2c3bhtLAU0qA8Lrri0p0NauOsTWh3yCCCDyBOjESHMExonp7Nzc0w==} + '@rollup/rollup-linux-riscv64-gnu@4.52.3': + resolution: {integrity: sha512-1makPhFFVBqZE+XFg3Dkq+IkQ7JvmUrwwqaYBL2CE+ZpxPaqkGaiWFEWVGyvTwZace6WLJHwjVh/+CXbKDGPmg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.52.2': - resolution: {integrity: sha512-duBLgd+3pqC4MMwBrKkFxaZerUxZcYApQVC5SdbF5/e/589GwVvlRUnyqMFbM8iUSb1BaoX/3fRL7hB9m2Pj8Q==} + '@rollup/rollup-linux-riscv64-musl@4.52.3': + resolution: {integrity: sha512-OOFJa28dxfl8kLOPMUOQBCO6z3X2SAfzIE276fwT52uXDWUS178KWq0pL7d6p1kz7pkzA0yQwtqL0dEPoVcRWg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.52.2': - resolution: {integrity: sha512-tzhYJJidDUVGMgVyE+PmxENPHlvvqm1KILjjZhB8/xHYqAGeizh3GBGf9u6WdJpZrz1aCpIIHG0LgJgH9rVjHQ==} + '@rollup/rollup-linux-s390x-gnu@4.52.3': + resolution: {integrity: sha512-jMdsML2VI5l+V7cKfZx3ak+SLlJ8fKvLJ0Eoa4b9/vCUrzXKgoKxvHqvJ/mkWhFiyp88nCkM5S2v6nIwRtPcgg==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.52.2': - resolution: {integrity: sha512-opH8GSUuVcCSSyHHcl5hELrmnk4waZoVpgn/4FDao9iyE4WpQhyWJ5ryl5M3ocp4qkRuHfyXnGqg8M9oKCEKRA==} + '@rollup/rollup-linux-x64-gnu@4.52.3': + resolution: {integrity: sha512-tPgGd6bY2M2LJTA1uGq8fkSPK8ZLYjDjY+ZLK9WHncCnfIz29LIXIqUgzCR0hIefzy6Hpbe8Th5WOSwTM8E7LA==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.52.2': - resolution: {integrity: sha512-LSeBHnGli1pPKVJ79ZVJgeZWWZXkEe/5o8kcn23M8eMKCUANejchJbF/JqzM4RRjOJfNRhKJk8FuqL1GKjF5oQ==} + '@rollup/rollup-linux-x64-musl@4.52.3': + resolution: {integrity: sha512-BCFkJjgk+WFzP+tcSMXq77ymAPIxsX9lFJWs+2JzuZTLtksJ2o5hvgTdIcZ5+oKzUDMwI0PfWzRBYAydAHF2Mw==} cpu: [x64] os: [linux] - '@rollup/rollup-openharmony-arm64@4.52.2': - resolution: {integrity: sha512-uPj7MQ6/s+/GOpolavm6BPo+6CbhbKYyZHUDvZ/SmJM7pfDBgdGisFX3bY/CBDMg2ZO4utfhlApkSfZ92yXw7Q==} + '@rollup/rollup-openharmony-arm64@4.52.3': + resolution: {integrity: sha512-KTD/EqjZF3yvRaWUJdD1cW+IQBk4fbQaHYJUmP8N4XoKFZilVL8cobFSTDnjTtxWJQ3JYaMgF4nObY/+nYkumA==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.52.2': - resolution: {integrity: sha512-Z9MUCrSgIaUeeHAiNkm3cQyst2UhzjPraR3gYYfOjAuZI7tcFRTOD+4cHLPoS/3qinchth+V56vtqz1Tv+6KPA==} + '@rollup/rollup-win32-arm64-msvc@4.52.3': + resolution: {integrity: sha512-+zteHZdoUYLkyYKObGHieibUFLbttX2r+58l27XZauq0tcWYYuKUwY2wjeCN9oK1Um2YgH2ibd6cnX/wFD7DuA==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.52.2': - resolution: {integrity: sha512-+GnYBmpjldD3XQd+HMejo+0gJGwYIOfFeoBQv32xF/RUIvccUz20/V6Otdv+57NE70D5pa8W/jVGDoGq0oON4A==} + '@rollup/rollup-win32-ia32-msvc@4.52.3': + resolution: {integrity: sha512-of1iHkTQSo3kr6dTIRX6t81uj/c/b15HXVsPcEElN5sS859qHrOepM5p9G41Hah+CTqSh2r8Bm56dL2z9UQQ7g==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.52.2': - resolution: {integrity: sha512-ApXFKluSB6kDQkAqZOKXBjiaqdF1BlKi+/eqnYe9Ee7U2K3pUDKsIyr8EYm/QDHTJIM+4X+lI0gJc3TTRhd+dA==} + '@rollup/rollup-win32-x64-gnu@4.52.3': + resolution: {integrity: sha512-s0hybmlHb56mWVZQj8ra9048/WZTPLILKxcvcq+8awSZmyiSUZjjem1AhU3Tf4ZKpYhK4mg36HtHDOe8QJS5PQ==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.52.2': - resolution: {integrity: sha512-ARz+Bs8kY6FtitYM96PqPEVvPXqEZmPZsSkXvyX19YzDqkCaIlhCieLLMI5hxO9SRZ2XtCtm8wxhy0iJ2jxNfw==} + '@rollup/rollup-win32-x64-msvc@4.52.3': + resolution: {integrity: sha512-zGIbEVVXVtauFgl3MRwGWEN36P5ZGenHRMgNw88X5wEhEBpq0XrMEZwOn07+ICrwM17XO5xfMZqh0OldCH5VTA==} cpu: [x64] os: [win32] @@ -1294,8 +1297,8 @@ packages: peerDependencies: '@types/react': ^19.0.0 - '@types/react@19.1.13': - resolution: {integrity: sha512-hHkbU/eoO3EG5/MZkuFSKmYqPbSVk5byPFa3e7y/8TybHiLMACgI8seVYlicwk7H5K/rI2px9xrQp/C+AUDTiQ==} + '@types/react@19.1.15': + resolution: {integrity: sha512-+kLxJpaJzXybyDyFXYADyP1cznTO8HSuBpenGlnKOAkH4hyNINiywvXS/tGJhsrGGP/gM185RA3xpjY0Yg4erA==} '@types/unist@2.0.11': resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} @@ -1323,8 +1326,8 @@ packages: peerDependencies: vite: ^4 || ^5 || ^6 || ^7 - '@vitejs/plugin-react@5.0.3': - resolution: {integrity: sha512-PFVHhosKkofGH0Yzrw1BipSedTH68BFF8ZWy1kfUpCtJcouXXY0+racG8sExw7hw0HoX36813ga5o3LTWZ4FUg==} + '@vitejs/plugin-react@5.0.4': + resolution: {integrity: sha512-La0KD0vGkVkSk6K+piWDKRUyg8Rl5iAIKRMH0vMJI0Eg47bq1eOxmoObAaQG37WMW9MSyk7Cs8EIWwJC1PtzKA==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 @@ -1377,8 +1380,8 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - baseline-browser-mapping@2.8.6: - resolution: {integrity: sha512-wrH5NNqren/QMtKUEEJf7z86YjfqW/2uw3IL3/xpqZUC95SSVIFXYQeeGjL6FT/X68IROu6RMehZQS5foy2BXw==} + baseline-browser-mapping@2.8.9: + resolution: {integrity: sha512-hY/u2lxLrbecMEWSB0IpGzGyDyeoMFQhCvZd2jGFSE5I17Fh01sYUBPCJtkWERw7zrac9+cIghxm/ytJa2X8iA==} hasBin: true boolbase@1.0.0: @@ -1428,8 +1431,8 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-lite@1.0.30001743: - resolution: {integrity: sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw==} + caniuse-lite@1.0.30001745: + resolution: {integrity: sha512-ywt6i8FzvdgrrrGbr1jZVObnVv6adj+0if2/omv9cmR2oiZs30zL4DIyaptKcbOrBdOIc74QTMoJvSE2QHh5UQ==} ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -1673,8 +1676,8 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} - electron-to-chromium@1.5.223: - resolution: {integrity: sha512-qKm55ic6nbEmagFlTFczML33rF90aU+WtrJ9MdTCThrcvDNdUHN4p6QfVN78U06ZmguqXIyMPyYhw2TrbDUwPQ==} + electron-to-chromium@1.5.227: + resolution: {integrity: sha512-ITxuoPfJu3lsNWUi2lBM2PaBPYgH3uqmxut5vmBxgYvyI4AlJ6P3Cai1O76mOrkJCBzq0IxWg/NtqOrpu/0gKA==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1772,8 +1775,8 @@ packages: fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} - framer-motion@12.23.21: - resolution: {integrity: sha512-UWDtzzPdRA3UpSNGril5HjUtPF1Uo/BCt5VKG/YQ8tVpSkAZ22+q8o+hYO0C1uDAZuotQjcfzsTsDtQxD46E/Q==} + framer-motion@12.23.22: + resolution: {integrity: sha512-ZgGvdxXCw55ZYvhoZChTlG6pUuehecgvEAJz0BHoC5pQKW1EC5xf1Mul1ej5+ai+pVY0pylyFfdl45qnM1/GsA==} peerDependencies: '@emotion/is-prop-valid': '*' react: ^18.0.0 || ^19.0.0 @@ -2271,8 +2274,8 @@ packages: motion-utils@12.23.6: resolution: {integrity: sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==} - motion@12.23.21: - resolution: {integrity: sha512-FzgbQNeZXHWXXEKmpfenYvF5wdc5i7lT/Kwr3xV4dmGVsU7Y30QcgCZsWHAlE/4McAWhNGbOAhgdiabXZ1EjnA==} + motion@12.23.22: + resolution: {integrity: sha512-iSq6X9vLHbeYwmHvhK//+U74ROaPnZmBuy60XZzqNl0QtZkWfoZyMDHYnpKuWFv0sNMqHgED8aCXk94LCoQPGg==} peerDependencies: '@emotion/is-prop-valid': '*' react: ^18.0.0 || ^19.0.0 @@ -2587,8 +2590,8 @@ packages: engines: {node: '>= 0.4'} hasBin: true - rollup@4.52.2: - resolution: {integrity: sha512-I25/2QgoROE1vYV+NQ1En9T9UFB9Cmfm2CJ83zZOlaDpvz29wGQSZXWKw7MiNXau7wYgB/T9fVIdIuEQ+KbiiA==} + rollup@4.52.3: + resolution: {integrity: sha512-RIDh866U8agLgiIcdpB+COKnlCreHJLfIhWC3LVflku5YHfpnsIKigRZeFfMfCc4dVcqNVfQQ5gO/afOck064A==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -3175,7 +3178,7 @@ snapshots: '@emotion/memoize@0.9.0': {} - '@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1)': + '@emotion/react@11.14.0(@types/react@19.1.15)(react@19.1.1)': dependencies: '@babel/runtime': 7.28.4 '@emotion/babel-plugin': 11.13.5 @@ -3187,7 +3190,7 @@ snapshots: hoist-non-react-statics: 3.3.2 react: 19.1.1 optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.15 transitivePeerDependencies: - supports-color @@ -3201,18 +3204,18 @@ snapshots: '@emotion/sheet@1.4.0': {} - '@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1)': + '@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.15)(react@19.1.1))(@types/react@19.1.15)(react@19.1.1)': dependencies: '@babel/runtime': 7.28.4 '@emotion/babel-plugin': 11.13.5 '@emotion/is-prop-valid': 1.4.0 - '@emotion/react': 11.14.0(@types/react@19.1.13)(react@19.1.1) + '@emotion/react': 11.14.0(@types/react@19.1.15)(react@19.1.1) '@emotion/serialize': 1.3.3 '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.1.1) '@emotion/utils': 1.4.2 react: 19.1.1 optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.15 transitivePeerDependencies: - supports-color @@ -3337,10 +3340,10 @@ snapshots: '@shikijs/types': 3.13.0 '@shikijs/vscode-textmate': 10.0.2 - '@hookform/devtools@4.4.0(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@hookform/devtools@4.4.0(@types/react@19.1.15)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: - '@emotion/react': 11.14.0(@types/react@19.1.13)(react@19.1.1) - '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1) + '@emotion/react': 11.14.0(@types/react@19.1.15)(react@19.1.1) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.1.15)(react@19.1.1))(@types/react@19.1.15)(react@19.1.1) '@types/lodash': 4.17.20 little-state-machine: 4.8.1(react@19.1.1) lodash: 4.17.21 @@ -3451,7 +3454,7 @@ snapshots: '@react-hook/passive-layout-effect': 1.2.1(react@19.1.1) react: 19.1.1 - '@reduxjs/toolkit@2.9.0(react-redux@9.2.0(@types/react@19.1.13)(react@19.1.1)(redux@5.0.1))(react@19.1.1)': + '@reduxjs/toolkit@2.9.0(react-redux@9.2.0(@types/react@19.1.15)(react@19.1.1)(redux@5.0.1))(react@19.1.1)': dependencies: '@standard-schema/spec': 1.0.0 '@standard-schema/utils': 0.3.0 @@ -3461,76 +3464,78 @@ snapshots: reselect: 5.1.1 optionalDependencies: react: 19.1.1 - react-redux: 9.2.0(@types/react@19.1.13)(react@19.1.1)(redux@5.0.1) + react-redux: 9.2.0(@types/react@19.1.15)(react@19.1.1)(redux@5.0.1) '@remix-run/router@1.23.0': {} '@rolldown/pluginutils@1.0.0-beta.35': {} - '@rollup/rollup-android-arm-eabi@4.52.2': + '@rolldown/pluginutils@1.0.0-beta.38': {} + + '@rollup/rollup-android-arm-eabi@4.52.3': optional: true - '@rollup/rollup-android-arm64@4.52.2': + '@rollup/rollup-android-arm64@4.52.3': optional: true - '@rollup/rollup-darwin-arm64@4.52.2': + '@rollup/rollup-darwin-arm64@4.52.3': optional: true - '@rollup/rollup-darwin-x64@4.52.2': + '@rollup/rollup-darwin-x64@4.52.3': optional: true - '@rollup/rollup-freebsd-arm64@4.52.2': + '@rollup/rollup-freebsd-arm64@4.52.3': optional: true - '@rollup/rollup-freebsd-x64@4.52.2': + '@rollup/rollup-freebsd-x64@4.52.3': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.52.2': + '@rollup/rollup-linux-arm-gnueabihf@4.52.3': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.52.2': + '@rollup/rollup-linux-arm-musleabihf@4.52.3': optional: true - '@rollup/rollup-linux-arm64-gnu@4.52.2': + '@rollup/rollup-linux-arm64-gnu@4.52.3': optional: true - '@rollup/rollup-linux-arm64-musl@4.52.2': + '@rollup/rollup-linux-arm64-musl@4.52.3': optional: true - '@rollup/rollup-linux-loong64-gnu@4.52.2': + '@rollup/rollup-linux-loong64-gnu@4.52.3': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.52.2': + '@rollup/rollup-linux-ppc64-gnu@4.52.3': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.52.2': + '@rollup/rollup-linux-riscv64-gnu@4.52.3': optional: true - '@rollup/rollup-linux-riscv64-musl@4.52.2': + '@rollup/rollup-linux-riscv64-musl@4.52.3': optional: true - '@rollup/rollup-linux-s390x-gnu@4.52.2': + '@rollup/rollup-linux-s390x-gnu@4.52.3': optional: true - '@rollup/rollup-linux-x64-gnu@4.52.2': + '@rollup/rollup-linux-x64-gnu@4.52.3': optional: true - '@rollup/rollup-linux-x64-musl@4.52.2': + '@rollup/rollup-linux-x64-musl@4.52.3': optional: true - '@rollup/rollup-openharmony-arm64@4.52.2': + '@rollup/rollup-openharmony-arm64@4.52.3': optional: true - '@rollup/rollup-win32-arm64-msvc@4.52.2': + '@rollup/rollup-win32-arm64-msvc@4.52.3': optional: true - '@rollup/rollup-win32-ia32-msvc@4.52.2': + '@rollup/rollup-win32-ia32-msvc@4.52.3': optional: true - '@rollup/rollup-win32-x64-gnu@4.52.2': + '@rollup/rollup-win32-x64-gnu@4.52.3': optional: true - '@rollup/rollup-win32-x64-msvc@4.52.2': + '@rollup/rollup-win32-x64-msvc@4.52.3': optional: true '@shikijs/engine-oniguruma@3.13.0': @@ -3932,11 +3937,11 @@ snapshots: '@types/parse-json@4.0.2': {} - '@types/react-dom@19.1.9(@types/react@19.1.13)': + '@types/react-dom@19.1.9(@types/react@19.1.15)': dependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.15 - '@types/react@19.1.13': + '@types/react@19.1.15': dependencies: csstype: 3.1.3 @@ -3963,12 +3968,12 @@ snapshots: transitivePeerDependencies: - '@swc/helpers' - '@vitejs/plugin-react@5.0.3(vite@7.1.7(@types/node@24.5.2)(sass@1.92.1)(yaml@2.8.1))': + '@vitejs/plugin-react@5.0.4(vite@7.1.7(@types/node@24.5.2)(sass@1.92.1)(yaml@2.8.1))': dependencies: '@babel/core': 7.28.4 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.4) '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.4) - '@rolldown/pluginutils': 1.0.0-beta.35 + '@rolldown/pluginutils': 1.0.0-beta.38 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 vite: 7.1.7(@types/node@24.5.2)(sass@1.92.1)(yaml@2.8.1) @@ -4007,7 +4012,7 @@ snapshots: autoprefixer@10.4.21(postcss@8.5.6): dependencies: browserslist: 4.26.2 - caniuse-lite: 1.0.30001743 + caniuse-lite: 1.0.30001745 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 @@ -4028,7 +4033,7 @@ snapshots: balanced-match@1.0.2: {} - baseline-browser-mapping@2.8.6: {} + baseline-browser-mapping@2.8.9: {} boolbase@1.0.0: {} @@ -4048,9 +4053,9 @@ snapshots: browserslist@4.26.2: dependencies: - baseline-browser-mapping: 2.8.6 - caniuse-lite: 1.0.30001743 - electron-to-chromium: 1.5.223 + baseline-browser-mapping: 2.8.9 + caniuse-lite: 1.0.30001745 + electron-to-chromium: 1.5.227 node-releases: 2.0.21 update-browserslist-db: 1.1.3(browserslist@4.26.2) @@ -4077,7 +4082,7 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001743: {} + caniuse-lite@1.0.30001745: {} ccount@2.0.1: {} @@ -4317,7 +4322,7 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 - electron-to-chromium@1.5.223: {} + electron-to-chromium@1.5.227: {} emoji-regex@8.0.0: {} @@ -4471,7 +4476,7 @@ snapshots: fraction.js@4.3.7: {} - framer-motion@12.23.21(@emotion/is-prop-valid@1.4.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + framer-motion@12.23.22(@emotion/is-prop-valid@1.4.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: motion-dom: 12.23.21 motion-utils: 12.23.6 @@ -4611,7 +4616,7 @@ snapshots: domhandler: 5.0.3 htmlparser2: 10.0.0 - html-react-parser@5.2.6(@types/react@19.1.13)(react@19.1.1): + html-react-parser@5.2.6(@types/react@19.1.15)(react@19.1.1): dependencies: domhandler: 5.0.3 html-dom-parser: 5.1.1 @@ -4619,7 +4624,7 @@ snapshots: react-property: 2.0.2 style-to-js: 1.1.17 optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.15 html-url-attributes@3.0.1: {} @@ -4950,9 +4955,9 @@ snapshots: memorystream@0.3.1: {} - merge-refs@2.0.0(@types/react@19.1.13): + merge-refs@2.0.0(@types/react@19.1.15): optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.15 micromark-core-commonmark@2.0.3: dependencies: @@ -5115,9 +5120,9 @@ snapshots: motion-utils@12.23.6: {} - motion@12.23.21(@emotion/is-prop-valid@1.4.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + motion@12.23.22(@emotion/is-prop-valid@1.4.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: - framer-motion: 12.23.21(@emotion/is-prop-valid@1.4.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + framer-motion: 12.23.22(@emotion/is-prop-valid@1.4.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) tslib: 2.8.1 optionalDependencies: '@emotion/is-prop-valid': 1.4.0 @@ -5293,11 +5298,11 @@ snapshots: dependencies: react: 19.1.1 - react-markdown@10.1.0(@types/react@19.1.13)(react@19.1.1): + react-markdown@10.1.0(@types/react@19.1.15)(react@19.1.1): dependencies: '@types/hast': 3.0.4 '@types/mdast': 4.0.4 - '@types/react': 19.1.13 + '@types/react': 19.1.15 devlop: 1.1.0 hast-util-to-jsx-runtime: 2.3.6 html-url-attributes: 3.0.1 @@ -5319,13 +5324,13 @@ snapshots: qr.js: 0.0.0 react: 19.1.1 - react-redux@9.2.0(@types/react@19.1.13)(react@19.1.1)(redux@5.0.1): + react-redux@9.2.0(@types/react@19.1.15)(react@19.1.1)(redux@5.0.1): dependencies: '@types/use-sync-external-store': 0.0.6 react: 19.1.1 use-sync-external-store: 1.5.0(react@19.1.1) optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.15 redux: 5.0.1 react-refresh@0.17.0: {} @@ -5363,9 +5368,9 @@ snapshots: readdirp@4.1.2: {} - recharts@3.2.1(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react-is@18.3.1)(react@19.1.1)(redux@5.0.1): + recharts@3.2.1(@types/react@19.1.15)(react-dom@19.1.1(react@19.1.1))(react-is@18.3.1)(react@19.1.1)(redux@5.0.1): dependencies: - '@reduxjs/toolkit': 2.9.0(react-redux@9.2.0(@types/react@19.1.13)(react@19.1.1)(redux@5.0.1))(react@19.1.1) + '@reduxjs/toolkit': 2.9.0(react-redux@9.2.0(@types/react@19.1.15)(react@19.1.1)(redux@5.0.1))(react@19.1.1) clsx: 2.1.1 decimal.js-light: 2.5.1 es-toolkit: 1.39.10 @@ -5374,7 +5379,7 @@ snapshots: react: 19.1.1 react-dom: 19.1.1(react@19.1.1) react-is: 18.3.1 - react-redux: 9.2.0(@types/react@19.1.13)(react@19.1.1)(redux@5.0.1) + react-redux: 9.2.0(@types/react@19.1.15)(react@19.1.1)(redux@5.0.1) reselect: 5.1.1 tiny-invariant: 1.3.3 use-sync-external-store: 1.5.0(react@19.1.1) @@ -5443,32 +5448,32 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - rollup@4.52.2: + rollup@4.52.3: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.52.2 - '@rollup/rollup-android-arm64': 4.52.2 - '@rollup/rollup-darwin-arm64': 4.52.2 - '@rollup/rollup-darwin-x64': 4.52.2 - '@rollup/rollup-freebsd-arm64': 4.52.2 - '@rollup/rollup-freebsd-x64': 4.52.2 - '@rollup/rollup-linux-arm-gnueabihf': 4.52.2 - '@rollup/rollup-linux-arm-musleabihf': 4.52.2 - '@rollup/rollup-linux-arm64-gnu': 4.52.2 - '@rollup/rollup-linux-arm64-musl': 4.52.2 - '@rollup/rollup-linux-loong64-gnu': 4.52.2 - '@rollup/rollup-linux-ppc64-gnu': 4.52.2 - '@rollup/rollup-linux-riscv64-gnu': 4.52.2 - '@rollup/rollup-linux-riscv64-musl': 4.52.2 - '@rollup/rollup-linux-s390x-gnu': 4.52.2 - '@rollup/rollup-linux-x64-gnu': 4.52.2 - '@rollup/rollup-linux-x64-musl': 4.52.2 - '@rollup/rollup-openharmony-arm64': 4.52.2 - '@rollup/rollup-win32-arm64-msvc': 4.52.2 - '@rollup/rollup-win32-ia32-msvc': 4.52.2 - '@rollup/rollup-win32-x64-gnu': 4.52.2 - '@rollup/rollup-win32-x64-msvc': 4.52.2 + '@rollup/rollup-android-arm-eabi': 4.52.3 + '@rollup/rollup-android-arm64': 4.52.3 + '@rollup/rollup-darwin-arm64': 4.52.3 + '@rollup/rollup-darwin-x64': 4.52.3 + '@rollup/rollup-freebsd-arm64': 4.52.3 + '@rollup/rollup-freebsd-x64': 4.52.3 + '@rollup/rollup-linux-arm-gnueabihf': 4.52.3 + '@rollup/rollup-linux-arm-musleabihf': 4.52.3 + '@rollup/rollup-linux-arm64-gnu': 4.52.3 + '@rollup/rollup-linux-arm64-musl': 4.52.3 + '@rollup/rollup-linux-loong64-gnu': 4.52.3 + '@rollup/rollup-linux-ppc64-gnu': 4.52.3 + '@rollup/rollup-linux-riscv64-gnu': 4.52.3 + '@rollup/rollup-linux-riscv64-musl': 4.52.3 + '@rollup/rollup-linux-s390x-gnu': 4.52.3 + '@rollup/rollup-linux-x64-gnu': 4.52.3 + '@rollup/rollup-linux-x64-musl': 4.52.3 + '@rollup/rollup-openharmony-arm64': 4.52.3 + '@rollup/rollup-win32-arm64-msvc': 4.52.3 + '@rollup/rollup-win32-ia32-msvc': 4.52.3 + '@rollup/rollup-win32-x64-gnu': 4.52.3 + '@rollup/rollup-win32-x64-msvc': 4.52.3 fsevents: 2.3.3 rxjs@7.8.2: @@ -5848,7 +5853,7 @@ snapshots: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.52.2 + rollup: 4.52.3 tinyglobby: 0.2.15 optionalDependencies: '@types/node': 24.5.2 @@ -5931,9 +5936,9 @@ snapshots: zod@3.25.76: {} - zustand@5.0.8(@types/react@19.1.13)(immer@10.1.3)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)): + zustand@5.0.8(@types/react@19.1.15)(immer@10.1.3)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)): optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.1.15 immer: 10.1.3 react: 19.1.1 use-sync-external-store: 1.5.0(react@19.1.1) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index af4029f9..e94e613e 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -17,6 +17,16 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + [[package]] name = "ahash" version = "0.7.8" @@ -206,6 +216,48 @@ dependencies = [ "zbus", ] +[[package]] +name = "askama" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4744ed2eef2645831b441d8f5459689ade2ab27c854488fbab1fbe94fce1a7" +dependencies = [ + "askama_derive", + "itoa", + "percent-encoding", + "serde", + "serde_json", +] + +[[package]] +name = "askama_derive" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d661e0f57be36a5c14c48f78d09011e67e0cb618f269cca9f2fd8d15b68c46ac" +dependencies = [ + "askama_parser", + "basic-toml", + "memchr", + "proc-macro2", + "quote", + "rustc-hash", + "serde", + "serde_derive", + "syn 2.0.106", +] + +[[package]] +name = "askama_parser" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf315ce6524c857bb129ff794935cf6d42c82a6cff60526fe2a63593de4d0d4f" +dependencies = [ + "memchr", + "serde", + "serde_derive", + "winnow 0.7.13", +] + [[package]] name = "async-broadcast" version = "0.7.2" @@ -531,6 +583,15 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" +[[package]] +name = "basic-toml" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a" +dependencies = [ + "serde", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -558,6 +619,15 @@ dependencies = [ "wyz", ] +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -598,6 +668,30 @@ dependencies = [ "piper", ] +[[package]] +name = "boringtun" +version = "0.6.0" +dependencies = [ + "aead", + "base64 0.22.1", + "blake2", + "chacha20poly1305", + "hex", + "hmac", + "ip_network", + "ip_network_table", + "libc", + "nix", + "parking_lot", + "ring", + "socket2", + "thiserror 2.0.17", + "tracing", + "uniffi", + "untrusted", + "x25519-dalek", +] + [[package]] name = "borsh" version = "1.5.7" @@ -826,6 +920,30 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +dependencies = [ + "aead", + "chacha20", + "cipher", + "poly1305", + "zeroize", +] + [[package]] name = "chrono" version = "0.4.42" @@ -840,6 +958,17 @@ dependencies = [ "windows-link 0.2.0", ] +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", + "zeroize", +] + [[package]] name = "clap" version = "4.5.48" @@ -1102,6 +1231,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", + "rand_core 0.6.4", "typenum", ] @@ -1343,6 +1473,7 @@ name = "defguard_wireguard_rs" version = "0.7.8" dependencies = [ "base64 0.22.1", + "boringtun", "libc", "log", "netlink-packet-core", @@ -1911,6 +2042,15 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs-err" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" +dependencies = [ + "autocfg", +] + [[package]] name = "funty" version = "2.0.0" @@ -2317,6 +2457,17 @@ dependencies = [ "system-deps", ] +[[package]] +name = "goblin" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b363a30c165f666402fe6a3024d3bec7ebc898f96a4a23bd1c99f8dbf3f4f47" +dependencies = [ + "log", + "plain", + "scroll", +] + [[package]] name = "gtk" version = "0.18.2" @@ -2836,6 +2987,15 @@ dependencies = [ "cfb", ] +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + [[package]] name = "io-uring" version = "0.7.10" @@ -2847,6 +3007,28 @@ dependencies = [ "libc", ] +[[package]] +name = "ip_network" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2f047c0a98b2f299aa5d6d7088443570faae494e9ae1305e48be000c9e0eb1" + +[[package]] +name = "ip_network_table" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4099b7cfc5c5e2fe8c5edf3f6f7adf7a714c9cc697534f63a5a5da30397cb2c0" +dependencies = [ + "ip_network", + "ip_network_table-deps-treebitmap", +] + +[[package]] +name = "ip_network_table-deps-treebitmap" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e537132deb99c0eb4b752f0346b6a836200eaaa3516dd7e5514b63930a09e5d" + [[package]] name = "ipnet" version = "2.11.0" @@ -3853,6 +4035,12 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + [[package]] name = "open" version = "5.3.2" @@ -4278,6 +4466,12 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + [[package]] name = "plist" version = "1.8.0" @@ -4331,6 +4525,17 @@ dependencies = [ "windows-sys 0.61.1", ] +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + [[package]] name = "potential_utf" version = "0.1.3" @@ -5215,6 +5420,26 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "scroll" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ab8598aa408498679922eff7fa985c25d58a90771bd6be794434c5277eab1a6" +dependencies = [ + "scroll_derive", +] + +[[package]] +name = "scroll_derive" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1783eabc414609e28a5ba76aee5ddd52199f7107a0b24c2e9746a1ecc34a683d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "seahash" version = "4.1.0" @@ -5551,6 +5776,12 @@ dependencies = [ "serde", ] +[[package]] +name = "smawk" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" + [[package]] name = "socket2" version = "0.6.0" @@ -6565,6 +6796,15 @@ dependencies = [ "utf-8", ] +[[package]] +name = "textwrap" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" +dependencies = [ + "smawk", +] + [[package]] name = "thiserror" version = "1.0.69" @@ -6771,6 +7011,15 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + [[package]] name = "toml" version = "0.8.2" @@ -7223,6 +7472,149 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +[[package]] +name = "uniffi" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6d968cb62160c11f2573e6be724ef8b1b18a277aededd17033f8a912d73e2b4" +dependencies = [ + "anyhow", + "camino", + "cargo_metadata", + "clap", + "uniffi_bindgen", + "uniffi_build", + "uniffi_core", + "uniffi_macros", + "uniffi_pipeline", +] + +[[package]] +name = "uniffi_bindgen" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b39ef1acbe1467d5d210f274fae344cb6f8766339330cb4c9688752899bf6b" +dependencies = [ + "anyhow", + "askama", + "camino", + "cargo_metadata", + "fs-err", + "glob", + "goblin", + "heck 0.5.0", + "indexmap 2.11.4", + "once_cell", + "serde", + "tempfile", + "textwrap", + "toml 0.5.11", + "uniffi_internal_macros", + "uniffi_meta", + "uniffi_pipeline", + "uniffi_udl", +] + +[[package]] +name = "uniffi_build" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6683e6b665423cddeacd89a3f97312cf400b2fb245a26f197adaf65c45d505b2" +dependencies = [ + "anyhow", + "camino", + "uniffi_bindgen", +] + +[[package]] +name = "uniffi_core" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2d990b553d6b9a7ee9c3ae71134674739913d52350b56152b0e613595bb5a6f" +dependencies = [ + "anyhow", + "bytes", + "once_cell", + "static_assertions", +] + +[[package]] +name = "uniffi_internal_macros" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04f4f224becf14885c10e6e400b95cc4d1985738140cb194ccc2044563f8a56b" +dependencies = [ + "anyhow", + "indexmap 2.11.4", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "uniffi_macros" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b481d385af334871d70904e6a5f129be7cd38c18fcf8dd8fd1f646b426a56d58" +dependencies = [ + "camino", + "fs-err", + "once_cell", + "proc-macro2", + "quote", + "serde", + "syn 2.0.106", + "toml 0.5.11", + "uniffi_meta", +] + +[[package]] +name = "uniffi_meta" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f817868a3b171bb7bf259e882138d104deafde65684689b4694c846d322491" +dependencies = [ + "anyhow", + "siphasher 0.3.11", + "uniffi_internal_macros", + "uniffi_pipeline", +] + +[[package]] +name = "uniffi_pipeline" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b147e133ad7824e32426b90bc41fda584363563f2ba747f590eca1fd6fd14e6" +dependencies = [ + "anyhow", + "heck 0.5.0", + "indexmap 2.11.4", + "tempfile", + "uniffi_internal_macros", +] + +[[package]] +name = "uniffi_udl" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caed654fb73da5abbc7a7e9c741532284532ba4762d6fe5071372df22a41730a" +dependencies = [ + "anyhow", + "textwrap", + "uniffi_meta", + "weedle2", +] + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + [[package]] name = "untrusted" version = "0.9.0" @@ -7716,6 +8108,15 @@ dependencies = [ "windows-core 0.61.2", ] +[[package]] +name = "weedle2" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "998d2c24ec099a87daf9467808859f9d82b61f1d9c9701251aea037f514eae0e" +dependencies = [ + "nom", +] + [[package]] name = "weezl" version = "0.1.10" diff --git a/src-tauri/src/service/mod.rs b/src-tauri/src/service/mod.rs index 3dd67e7f..3e277efc 100644 --- a/src-tauri/src/service/mod.rs +++ b/src-tauri/src/service/mod.rs @@ -13,7 +13,7 @@ use std::{ net::IpAddr, pin::Pin, str::FromStr, - sync::RwLock, + sync::{Arc, RwLock}, time::{Duration, SystemTime, UNIX_EPOCH}, }; #[cfg(unix)] @@ -74,13 +74,16 @@ pub enum DaemonError { TransportError(#[from] tonic::transport::Error), } +type IfName = String; +#[cfg(not(target_os = "macos"))] +type WG = WGApi; +#[cfg(target_os = "macos")] +type WG = WGApi; + #[derive(Default)] pub(crate) struct DaemonService { // Map of running `WGApi`s; key is interface name. - #[cfg(target_os = "macos")] - wgapis: RwLock>>, - #[cfg(not(target_os = "macos"))] - wgapis: HashMap>, + wgapis: Arc>>, stats_period: Duration, } @@ -88,7 +91,7 @@ impl DaemonService { #[must_use] pub fn new(config: &Config) -> Self { Self { - wgapis: RwLock::new(HashMap::new()), + wgapis: Arc::new(RwLock::new(HashMap::new())), stats_period: Duration::from_secs(config.stats_period), } } @@ -96,23 +99,9 @@ impl DaemonService { type InterfaceDataStream = Pin> + Send>>; -#[cfg(not(target_os = "macos"))] -#[allow(clippy::result_large_err)] -pub fn setup_wgapi(ifname: &str) -> Result, Status> { - let wgapi = WGApi::::new(ifname.to_string()).map_err(|err| { - let msg = format!("Failed to setup kernel WireGuard API for interface {ifname}: {err}"); - error!("{msg}"); - Status::new(Code::Internal, msg) - })?; - - Ok(wgapi) -} - -#[cfg(target_os = "macos")] -#[allow(clippy::result_large_err)] -pub fn setup_wgapi(ifname: &str) -> Result, Status> { - let wgapi = WGApi::::new(ifname.to_string()).map_err(|err| { - let msg = format!("Failed to setup userspace WireGuard API for interface {ifname}: {err}"); +fn setup_wgapi(ifname: &str) -> Result { + let wgapi = WG::new(ifname).map_err(|err| { + let msg = format!("Failed to setup WireGuard API for interface {ifname}: {err}"); error!("{msg}"); Status::new(Code::Internal, msg) })?; @@ -140,7 +129,10 @@ impl DesktopDaemonService for DaemonService { let ifname = &config.name; let _span = info_span!("create_interface", interface_name = &ifname).entered(); // Setup WireGuard API. - let mut wgapis_map = self.wgapis.write().unwrap(); + let Ok(mut wgapis_map) = self.wgapis.write() else { + error!("Failed to acquire read-write lock for WGApis"); + return Err(Status::new(Code::Internal, "read-write lock error")); + }; let wgapi = wgapis_map .entry(ifname.clone()) .or_insert(setup_wgapi(ifname)?); @@ -231,7 +223,17 @@ impl DesktopDaemonService for DaemonService { let _span = info_span!("remove_interface", interface_name = &ifname).entered(); debug!("Removing interface {ifname}"); - let wgapi = setup_wgapi(&ifname)?; + let wgapi = { + let Ok(mut wgapis_map) = self.wgapis.write() else { + error!("Failed to acquire read-write lock for WGApis"); + return Err(Status::new(Code::Internal, "read-write lock error")); + }; + let Some(wgapi) = wgapis_map.remove(&ifname) else { + error!("Unknown interface {ifname}"); + return Err(Status::new(Code::Internal, "unknown interface")); + }; + wgapi + }; #[cfg(not(windows))] { @@ -268,8 +270,7 @@ impl DesktopDaemonService for DaemonService { ); let span = info_span!("read_interface_data", interface_name = &ifname); - // Setup WireGuard API. - let wgapi = setup_wgapi(&ifname)?; + let wgapis = Arc::clone(&self.wgapis); let mut interval = interval(self.stats_period); let (tx, rx) = mpsc::channel(64); @@ -288,7 +289,18 @@ impl DesktopDaemonService for DaemonService { interval.tick().await; debug!( "Gathering network usage statistics for client's network activity on {ifname}"); - match wgapi.read_interface_data() { + let result = { + let Ok(wgapis_map) = wgapis.read() else { + error!("Failed to acquire read-write lock for WGApis"); + break; + }; + let Some(wgapi) = wgapis_map.get(&ifname) else { + error!("Unknown interface {ifname}"); + break; + }; + wgapi.read_interface_data() + }; + match result { Ok(mut host) => { let peers = &mut host.peers; debug!( @@ -297,7 +309,7 @@ impl DesktopDaemonService for DaemonService { ); // Filter out never connected peers. peers.retain(|_, peer| { - // Last handshake time-stamp must exist... + // Last handshake time-stamp must exist. if let Some(last_hs) = peer.last_handshake { // ...and not be UNIX epoch. if last_hs != SystemTime::UNIX_EPOCH From fd94b2c476cbc50f375ab1b015c30231cb548ed5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Wed, 1 Oct 2025 13:43:50 +0200 Subject: [PATCH 3/7] Handle statistics tasks --- package.json | 6 +- pnpm-lock.yaml | 199 ++++++++++++++++++----------------- src-tauri/Cargo.lock | 24 ++--- src-tauri/Cargo.toml | 4 +- src-tauri/src/service/mod.rs | 22 +++- 5 files changed, 137 insertions(+), 118 deletions(-) diff --git a/package.json b/package.json index d4095836..322b1bb0 100644 --- a/package.json +++ b/package.json @@ -114,8 +114,8 @@ "@tauri-apps/cli": "^2.8.4", "@types/file-saver": "^2.0.7", "@types/lodash-es": "^4.17.12", - "@types/node": "^24.5.2", - "@types/react": "^19.1.15", + "@types/node": "^24.6.1", + "@types/react": "^19.1.16", "@types/react-dom": "^19.1.9", "@vitejs/plugin-react": "^5.0.4", "@vitejs/plugin-react-swc": "^4.1.0", @@ -126,7 +126,7 @@ "sass": "~1.92.1", "typedoc": "^0.28.13", "typesafe-i18n": "^5.26.2", - "typescript": "^5.9.2", + "typescript": "^5.9.3", "vite": "^7.1.7" }, "volta": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4e3d63ad..5f28b2d6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -100,7 +100,7 @@ importers: version: 1.0.3 html-react-parser: specifier: ^5.2.6 - version: 5.2.6(@types/react@19.1.15)(react@19.1.1) + version: 5.2.6(@types/react@19.1.16)(react@19.1.1) itertools: specifier: ^2.5.0 version: 2.5.0 @@ -112,7 +112,7 @@ importers: version: 4.17.21 merge-refs: specifier: ^2.0.0 - version: 2.0.0(@types/react@19.1.15) + version: 2.0.0(@types/react@19.1.16) millify: specifier: ^6.1.0 version: 6.1.0 @@ -148,7 +148,7 @@ importers: version: 3.5.0(react@19.1.1) react-markdown: specifier: ^10.1.0 - version: 10.1.0(@types/react@19.1.15)(react@19.1.1) + version: 10.1.0(@types/react@19.1.16)(react@19.1.1) react-qr-code: specifier: ^2.0.18 version: 2.0.18(react@19.1.1) @@ -163,7 +163,7 @@ importers: version: 1.0.26(react-dom@19.1.1(react@19.1.1))(react@19.1.1) recharts: specifier: ^3.2.1 - version: 3.2.1(@types/react@19.1.15)(react-dom@19.1.1(react@19.1.1))(react-is@18.3.1)(react@19.1.1)(redux@5.0.1) + version: 3.2.1(@types/react@19.1.16)(react-dom@19.1.1(react@19.1.1))(react-is@18.3.1)(react@19.1.1)(redux@5.0.1) rehype-sanitize: specifier: ^6.0.0 version: 6.0.0 @@ -178,17 +178,17 @@ importers: version: 3.25.76 zustand: specifier: ^5.0.8 - version: 5.0.8(@types/react@19.1.15)(immer@10.1.3)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) + version: 5.0.8(@types/react@19.1.16)(immer@10.1.3)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) devDependencies: '@biomejs/biome': specifier: ^2.2.4 version: 2.2.4 '@hookform/devtools': specifier: ^4.4.0 - version: 4.4.0(@types/react@19.1.15)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 4.4.0(@types/react@19.1.16)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@svgr/cli': specifier: ^8.1.0 - version: 8.1.0(typescript@5.9.2) + version: 8.1.0(typescript@5.9.3) '@tanstack/react-query': specifier: ^5.90.2 version: 5.90.2(react@19.1.1) @@ -205,20 +205,20 @@ importers: specifier: ^4.17.12 version: 4.17.12 '@types/node': - specifier: ^24.5.2 - version: 24.5.2 + specifier: ^24.6.1 + version: 24.6.1 '@types/react': - specifier: ^19.1.15 - version: 19.1.15 + specifier: ^19.1.16 + version: 19.1.16 '@types/react-dom': specifier: ^19.1.9 - version: 19.1.9(@types/react@19.1.15) + version: 19.1.9(@types/react@19.1.16) '@vitejs/plugin-react': specifier: ^5.0.4 - version: 5.0.4(vite@7.1.7(@types/node@24.5.2)(sass@1.92.1)(yaml@2.8.1)) + version: 5.0.4(vite@7.1.7(@types/node@24.6.1)(sass@1.92.1)(yaml@2.8.1)) '@vitejs/plugin-react-swc': specifier: ^4.1.0 - version: 4.1.0(vite@7.1.7(@types/node@24.5.2)(sass@1.92.1)(yaml@2.8.1)) + version: 4.1.0(vite@7.1.7(@types/node@24.6.1)(sass@1.92.1)(yaml@2.8.1)) autoprefixer: specifier: ^10.4.21 version: 10.4.21(postcss@8.5.6) @@ -236,16 +236,16 @@ importers: version: 1.92.1 typedoc: specifier: ^0.28.13 - version: 0.28.13(typescript@5.9.2) + version: 0.28.13(typescript@5.9.3) typesafe-i18n: specifier: ^5.26.2 - version: 5.26.2(typescript@5.9.2) + version: 5.26.2(typescript@5.9.3) typescript: - specifier: ^5.9.2 - version: 5.9.2 + specifier: ^5.9.3 + version: 5.9.3 vite: specifier: ^7.1.7 - version: 7.1.7(@types/node@24.5.2)(sass@1.92.1)(yaml@2.8.1) + version: 7.1.7(@types/node@24.6.1)(sass@1.92.1)(yaml@2.8.1) packages: @@ -1286,8 +1286,8 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/node@24.5.2': - resolution: {integrity: sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==} + '@types/node@24.6.1': + resolution: {integrity: sha512-ljvjjs3DNXummeIaooB4cLBKg2U6SPI6Hjra/9rRIy7CpM0HpLtG9HptkMKAb4HYWy5S7HUvJEuWgr/y0U8SHw==} '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} @@ -1297,8 +1297,8 @@ packages: peerDependencies: '@types/react': ^19.0.0 - '@types/react@19.1.15': - resolution: {integrity: sha512-+kLxJpaJzXybyDyFXYADyP1cznTO8HSuBpenGlnKOAkH4hyNINiywvXS/tGJhsrGGP/gM185RA3xpjY0Yg4erA==} + '@types/react@19.1.16': + resolution: {integrity: sha512-WBM/nDbEZmDUORKnh5i1bTnAz6vTohUf9b8esSMu+b24+srbaxa04UbJgWx78CVfNXA20sNu0odEIluZDFdCog==} '@types/unist@2.0.11': resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} @@ -1431,8 +1431,8 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-lite@1.0.30001745: - resolution: {integrity: sha512-ywt6i8FzvdgrrrGbr1jZVObnVv6adj+0if2/omv9cmR2oiZs30zL4DIyaptKcbOrBdOIc74QTMoJvSE2QHh5UQ==} + caniuse-lite@1.0.30001746: + resolution: {integrity: sha512-eA7Ys/DGw+pnkWWSE/id29f2IcPHVoE8wxtvE5JdvD2V28VTDPy1yEeo11Guz0sJ4ZeGRcm3uaTcAqK1LXaphA==} ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -1676,8 +1676,8 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} - electron-to-chromium@1.5.227: - resolution: {integrity: sha512-ITxuoPfJu3lsNWUi2lBM2PaBPYgH3uqmxut5vmBxgYvyI4AlJ6P3Cai1O76mOrkJCBzq0IxWg/NtqOrpu/0gKA==} + electron-to-chromium@1.5.228: + resolution: {integrity: sha512-nxkiyuqAn4MJ1QbobwqJILiDtu/jk14hEAWaMiJmNPh1Z+jqoFlBFZjdXwLWGeVSeu9hGLg6+2G9yJaW8rBIFA==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1807,6 +1807,10 @@ packages: functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} + gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -1994,8 +1998,8 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} - is-generator-function@1.1.0: - resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} engines: {node: '>= 0.4'} is-glob@4.0.3: @@ -2808,8 +2812,8 @@ packages: peerDependencies: typescript: '>=3.5.1' - typescript@5.9.2: - resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} hasBin: true @@ -2820,8 +2824,8 @@ packages: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} - undici-types@7.12.0: - resolution: {integrity: sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==} + undici-types@7.13.0: + resolution: {integrity: sha512-Ov2Rr9Sx+fRgagJ5AX0qvItZG/JKKoBRAVITs1zk7IqZGTJUwgUr7qoYBpWwakpWilTZFM98rG/AFRocu10iIQ==} unified@11.0.5: resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} @@ -3178,7 +3182,7 @@ snapshots: '@emotion/memoize@0.9.0': {} - '@emotion/react@11.14.0(@types/react@19.1.15)(react@19.1.1)': + '@emotion/react@11.14.0(@types/react@19.1.16)(react@19.1.1)': dependencies: '@babel/runtime': 7.28.4 '@emotion/babel-plugin': 11.13.5 @@ -3190,7 +3194,7 @@ snapshots: hoist-non-react-statics: 3.3.2 react: 19.1.1 optionalDependencies: - '@types/react': 19.1.15 + '@types/react': 19.1.16 transitivePeerDependencies: - supports-color @@ -3204,18 +3208,18 @@ snapshots: '@emotion/sheet@1.4.0': {} - '@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.15)(react@19.1.1))(@types/react@19.1.15)(react@19.1.1)': + '@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.16)(react@19.1.1))(@types/react@19.1.16)(react@19.1.1)': dependencies: '@babel/runtime': 7.28.4 '@emotion/babel-plugin': 11.13.5 '@emotion/is-prop-valid': 1.4.0 - '@emotion/react': 11.14.0(@types/react@19.1.15)(react@19.1.1) + '@emotion/react': 11.14.0(@types/react@19.1.16)(react@19.1.1) '@emotion/serialize': 1.3.3 '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.1.1) '@emotion/utils': 1.4.2 react: 19.1.1 optionalDependencies: - '@types/react': 19.1.15 + '@types/react': 19.1.16 transitivePeerDependencies: - supports-color @@ -3340,10 +3344,10 @@ snapshots: '@shikijs/types': 3.13.0 '@shikijs/vscode-textmate': 10.0.2 - '@hookform/devtools@4.4.0(@types/react@19.1.15)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@hookform/devtools@4.4.0(@types/react@19.1.16)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: - '@emotion/react': 11.14.0(@types/react@19.1.15)(react@19.1.1) - '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.1.15)(react@19.1.1))(@types/react@19.1.15)(react@19.1.1) + '@emotion/react': 11.14.0(@types/react@19.1.16)(react@19.1.1) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.1.16)(react@19.1.1))(@types/react@19.1.16)(react@19.1.1) '@types/lodash': 4.17.20 little-state-machine: 4.8.1(react@19.1.1) lodash: 4.17.21 @@ -3454,7 +3458,7 @@ snapshots: '@react-hook/passive-layout-effect': 1.2.1(react@19.1.1) react: 19.1.1 - '@reduxjs/toolkit@2.9.0(react-redux@9.2.0(@types/react@19.1.15)(react@19.1.1)(redux@5.0.1))(react@19.1.1)': + '@reduxjs/toolkit@2.9.0(react-redux@9.2.0(@types/react@19.1.16)(react@19.1.1)(redux@5.0.1))(react@19.1.1)': dependencies: '@standard-schema/spec': 1.0.0 '@standard-schema/utils': 0.3.0 @@ -3464,7 +3468,7 @@ snapshots: reselect: 5.1.1 optionalDependencies: react: 19.1.1 - react-redux: 9.2.0(@types/react@19.1.15)(react@19.1.1)(redux@5.0.1) + react-redux: 9.2.0(@types/react@19.1.16)(react@19.1.1)(redux@5.0.1) '@remix-run/router@1.23.0': {} @@ -3633,12 +3637,12 @@ snapshots: '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.28.4) '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.28.4) - '@svgr/cli@8.1.0(typescript@5.9.2)': + '@svgr/cli@8.1.0(typescript@5.9.3)': dependencies: - '@svgr/core': 8.1.0(typescript@5.9.2) - '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.9.2)) - '@svgr/plugin-prettier': 8.1.0(@svgr/core@8.1.0(typescript@5.9.2)) - '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@5.9.2))(typescript@5.9.2) + '@svgr/core': 8.1.0(typescript@5.9.3) + '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3)) + '@svgr/plugin-prettier': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3)) + '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3))(typescript@5.9.3) camelcase: 6.3.0 chalk: 4.1.2 commander: 9.5.0 @@ -3649,12 +3653,12 @@ snapshots: - supports-color - typescript - '@svgr/core@8.1.0(typescript@5.9.2)': + '@svgr/core@8.1.0(typescript@5.9.3)': dependencies: '@babel/core': 7.28.4 '@svgr/babel-preset': 8.1.0(@babel/core@7.28.4) camelcase: 6.3.0 - cosmiconfig: 8.3.6(typescript@5.9.2) + cosmiconfig: 8.3.6(typescript@5.9.3) snake-case: 3.0.4 transitivePeerDependencies: - supports-color @@ -3665,26 +3669,26 @@ snapshots: '@babel/types': 7.28.4 entities: 4.5.0 - '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.9.2))': + '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.9.3))': dependencies: '@babel/core': 7.28.4 '@svgr/babel-preset': 8.1.0(@babel/core@7.28.4) - '@svgr/core': 8.1.0(typescript@5.9.2) + '@svgr/core': 8.1.0(typescript@5.9.3) '@svgr/hast-util-to-babel-ast': 8.0.0 svg-parser: 2.0.4 transitivePeerDependencies: - supports-color - '@svgr/plugin-prettier@8.1.0(@svgr/core@8.1.0(typescript@5.9.2))': + '@svgr/plugin-prettier@8.1.0(@svgr/core@8.1.0(typescript@5.9.3))': dependencies: - '@svgr/core': 8.1.0(typescript@5.9.2) + '@svgr/core': 8.1.0(typescript@5.9.3) deepmerge: 4.3.1 prettier: 2.8.8 - '@svgr/plugin-svgo@8.1.0(@svgr/core@8.1.0(typescript@5.9.2))(typescript@5.9.2)': + '@svgr/plugin-svgo@8.1.0(@svgr/core@8.1.0(typescript@5.9.3))(typescript@5.9.3)': dependencies: - '@svgr/core': 8.1.0(typescript@5.9.2) - cosmiconfig: 8.3.6(typescript@5.9.2) + '@svgr/core': 8.1.0(typescript@5.9.3) + cosmiconfig: 8.3.6(typescript@5.9.3) deepmerge: 4.3.1 svgo: 3.3.2 transitivePeerDependencies: @@ -3931,17 +3935,17 @@ snapshots: '@types/ms@2.1.0': {} - '@types/node@24.5.2': + '@types/node@24.6.1': dependencies: - undici-types: 7.12.0 + undici-types: 7.13.0 '@types/parse-json@4.0.2': {} - '@types/react-dom@19.1.9(@types/react@19.1.15)': + '@types/react-dom@19.1.9(@types/react@19.1.16)': dependencies: - '@types/react': 19.1.15 + '@types/react': 19.1.16 - '@types/react@19.1.15': + '@types/react@19.1.16': dependencies: csstype: 3.1.3 @@ -3960,15 +3964,15 @@ snapshots: '@use-gesture/core': 10.3.1 react: 19.1.1 - '@vitejs/plugin-react-swc@4.1.0(vite@7.1.7(@types/node@24.5.2)(sass@1.92.1)(yaml@2.8.1))': + '@vitejs/plugin-react-swc@4.1.0(vite@7.1.7(@types/node@24.6.1)(sass@1.92.1)(yaml@2.8.1))': dependencies: '@rolldown/pluginutils': 1.0.0-beta.35 '@swc/core': 1.13.5 - vite: 7.1.7(@types/node@24.5.2)(sass@1.92.1)(yaml@2.8.1) + vite: 7.1.7(@types/node@24.6.1)(sass@1.92.1)(yaml@2.8.1) transitivePeerDependencies: - '@swc/helpers' - '@vitejs/plugin-react@5.0.4(vite@7.1.7(@types/node@24.5.2)(sass@1.92.1)(yaml@2.8.1))': + '@vitejs/plugin-react@5.0.4(vite@7.1.7(@types/node@24.6.1)(sass@1.92.1)(yaml@2.8.1))': dependencies: '@babel/core': 7.28.4 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.4) @@ -3976,7 +3980,7 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.38 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 7.1.7(@types/node@24.5.2)(sass@1.92.1)(yaml@2.8.1) + vite: 7.1.7(@types/node@24.6.1)(sass@1.92.1)(yaml@2.8.1) transitivePeerDependencies: - supports-color @@ -4012,7 +4016,7 @@ snapshots: autoprefixer@10.4.21(postcss@8.5.6): dependencies: browserslist: 4.26.2 - caniuse-lite: 1.0.30001745 + caniuse-lite: 1.0.30001746 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 @@ -4054,8 +4058,8 @@ snapshots: browserslist@4.26.2: dependencies: baseline-browser-mapping: 2.8.9 - caniuse-lite: 1.0.30001745 - electron-to-chromium: 1.5.227 + caniuse-lite: 1.0.30001746 + electron-to-chromium: 1.5.228 node-releases: 2.0.21 update-browserslist-db: 1.1.3(browserslist@4.26.2) @@ -4082,7 +4086,7 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001745: {} + caniuse-lite@1.0.30001746: {} ccount@2.0.1: {} @@ -4153,14 +4157,14 @@ snapshots: path-type: 4.0.0 yaml: 1.10.2 - cosmiconfig@8.3.6(typescript@5.9.2): + cosmiconfig@8.3.6(typescript@5.9.3): dependencies: import-fresh: 3.3.1 js-yaml: 4.1.0 parse-json: 5.2.0 path-type: 4.0.0 optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 cross-spawn@6.0.6: dependencies: @@ -4322,7 +4326,7 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 - electron-to-chromium@1.5.227: {} + electron-to-chromium@1.5.228: {} emoji-regex@8.0.0: {} @@ -4504,6 +4508,8 @@ snapshots: functions-have-names@1.2.3: {} + generator-function@2.0.1: {} + gensync@1.0.0-beta.2: {} get-caller-file@2.0.5: {} @@ -4616,7 +4622,7 @@ snapshots: domhandler: 5.0.3 htmlparser2: 10.0.0 - html-react-parser@5.2.6(@types/react@19.1.15)(react@19.1.1): + html-react-parser@5.2.6(@types/react@19.1.16)(react@19.1.1): dependencies: domhandler: 5.0.3 html-dom-parser: 5.1.1 @@ -4624,7 +4630,7 @@ snapshots: react-property: 2.0.2 style-to-js: 1.1.17 optionalDependencies: - '@types/react': 19.1.15 + '@types/react': 19.1.16 html-url-attributes@3.0.1: {} @@ -4721,9 +4727,10 @@ snapshots: is-fullwidth-code-point@3.0.0: {} - is-generator-function@1.1.0: + is-generator-function@1.1.2: dependencies: call-bound: 1.0.4 + generator-function: 2.0.1 get-proto: 1.0.1 has-tostringtag: 1.0.2 safe-regex-test: 1.1.0 @@ -4955,9 +4962,9 @@ snapshots: memorystream@0.3.1: {} - merge-refs@2.0.0(@types/react@19.1.15): + merge-refs@2.0.0(@types/react@19.1.16): optionalDependencies: - '@types/react': 19.1.15 + '@types/react': 19.1.16 micromark-core-commonmark@2.0.3: dependencies: @@ -5298,11 +5305,11 @@ snapshots: dependencies: react: 19.1.1 - react-markdown@10.1.0(@types/react@19.1.15)(react@19.1.1): + react-markdown@10.1.0(@types/react@19.1.16)(react@19.1.1): dependencies: '@types/hast': 3.0.4 '@types/mdast': 4.0.4 - '@types/react': 19.1.15 + '@types/react': 19.1.16 devlop: 1.1.0 hast-util-to-jsx-runtime: 2.3.6 html-url-attributes: 3.0.1 @@ -5324,13 +5331,13 @@ snapshots: qr.js: 0.0.0 react: 19.1.1 - react-redux@9.2.0(@types/react@19.1.15)(react@19.1.1)(redux@5.0.1): + react-redux@9.2.0(@types/react@19.1.16)(react@19.1.1)(redux@5.0.1): dependencies: '@types/use-sync-external-store': 0.0.6 react: 19.1.1 use-sync-external-store: 1.5.0(react@19.1.1) optionalDependencies: - '@types/react': 19.1.15 + '@types/react': 19.1.16 redux: 5.0.1 react-refresh@0.17.0: {} @@ -5368,9 +5375,9 @@ snapshots: readdirp@4.1.2: {} - recharts@3.2.1(@types/react@19.1.15)(react-dom@19.1.1(react@19.1.1))(react-is@18.3.1)(react@19.1.1)(redux@5.0.1): + recharts@3.2.1(@types/react@19.1.16)(react-dom@19.1.1(react@19.1.1))(react-is@18.3.1)(react@19.1.1)(redux@5.0.1): dependencies: - '@reduxjs/toolkit': 2.9.0(react-redux@9.2.0(@types/react@19.1.15)(react@19.1.1)(redux@5.0.1))(react@19.1.1) + '@reduxjs/toolkit': 2.9.0(react-redux@9.2.0(@types/react@19.1.16)(react@19.1.1)(redux@5.0.1))(react@19.1.1) clsx: 2.1.1 decimal.js-light: 2.5.1 es-toolkit: 1.39.10 @@ -5379,7 +5386,7 @@ snapshots: react: 19.1.1 react-dom: 19.1.1(react@19.1.1) react-is: 18.3.1 - react-redux: 9.2.0(@types/react@19.1.15)(react@19.1.1)(redux@5.0.1) + react-redux: 9.2.0(@types/react@19.1.16)(react@19.1.1)(redux@5.0.1) reselect: 5.1.1 tiny-invariant: 1.3.3 use-sync-external-store: 1.5.0(react@19.1.1) @@ -5733,20 +5740,20 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typedoc@0.28.13(typescript@5.9.2): + typedoc@0.28.13(typescript@5.9.3): dependencies: '@gerrit0/mini-shiki': 3.13.0 lunr: 2.3.9 markdown-it: 14.1.0 minimatch: 9.0.5 - typescript: 5.9.2 + typescript: 5.9.3 yaml: 2.8.1 - typesafe-i18n@5.26.2(typescript@5.9.2): + typesafe-i18n@5.26.2(typescript@5.9.3): dependencies: - typescript: 5.9.2 + typescript: 5.9.3 - typescript@5.9.2: {} + typescript@5.9.3: {} uc.micro@2.1.0: {} @@ -5757,7 +5764,7 @@ snapshots: has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 - undici-types@7.12.0: {} + undici-types@7.13.0: {} unified@11.0.5: dependencies: @@ -5847,7 +5854,7 @@ snapshots: d3-time: 3.1.0 d3-timer: 3.0.1 - vite@7.1.7(@types/node@24.5.2)(sass@1.92.1)(yaml@2.8.1): + vite@7.1.7(@types/node@24.6.1)(sass@1.92.1)(yaml@2.8.1): dependencies: esbuild: 0.25.10 fdir: 6.5.0(picomatch@4.0.3) @@ -5856,7 +5863,7 @@ snapshots: rollup: 4.52.3 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.5.2 + '@types/node': 24.6.1 fsevents: 2.3.3 sass: 1.92.1 yaml: 2.8.1 @@ -5877,7 +5884,7 @@ snapshots: is-async-function: 2.1.1 is-date-object: 1.1.0 is-finalizationregistry: 1.1.1 - is-generator-function: 1.1.0 + is-generator-function: 1.1.2 is-regex: 1.2.1 is-weakref: 1.1.1 isarray: 2.0.5 @@ -5936,9 +5943,9 @@ snapshots: zod@3.25.76: {} - zustand@5.0.8(@types/react@19.1.15)(immer@10.1.3)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)): + zustand@5.0.8(@types/react@19.1.16)(immer@10.1.3)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)): optionalDependencies: - '@types/react': 19.1.15 + '@types/react': 19.1.16 immer: 10.1.3 react: 19.1.1 use-sync-external-store: 1.5.0(react@19.1.1) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index e94e613e..ef1f348c 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -111,9 +111,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" @@ -509,9 +509,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "axum" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98e529aee37b5c8206bb4bf4c44797127566d72f76952c970bd3d1e85de8f4e2" +checksum = "8a18ed336352031311f4e0b4dd2ff392d4fbb370777c9d18d7fc9d7359f73871" dependencies = [ "axum-core", "bytes", @@ -534,9 +534,9 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ac7a6beb1182c7e30253ee75c3e918080bfb83f5a3023bcdf7209d85fd147e6" +checksum = "59446ce19cd142f8833f856eb31f3eb097812d1479ab224f54d72428ca21ea22" dependencies = [ "bytes", "futures-core", @@ -829,9 +829,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1de8bc0aa9e9385ceb3bf0c152e3a9b9544f6c4a912c8ae504e80c1f0368603" +checksum = "276a59bf2b2c967788139340c9f0c5b12d7fd6630315c15c217e559de85d2609" dependencies = [ "serde_core", ] @@ -4087,9 +4087,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-src" -version = "300.5.2+3.5.2" +version = "300.5.3+3.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d270b79e2926f5150189d475bc7e9d2c69f9c4697b185fa917d5a32b792d21b4" +checksum = "dc6bad8cd0233b63971e232cc9c5e83039375b8586d2312f31fda85db8f888c2" dependencies = [ "cc", ] @@ -8962,9 +8962,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" dependencies = [ "zeroize_derive", ] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 33c4fdfe..a3cf00cf 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -91,8 +91,8 @@ tauri-plugin-fs = "2" tauri-plugin-http = { version = "2", features = ["unsafe-headers"] } tauri-plugin-log = "2" tauri-plugin-notification = "2" -tauri-plugin-opener = "2.5.0" -tauri-plugin-os = "2.3.1" +tauri-plugin-opener = "2" +tauri-plugin-os = "2" tauri-plugin-single-instance = { version = "2", features = ["deep-link"] } tauri-plugin-window-state = "2" thiserror.workspace = true diff --git a/src-tauri/src/service/mod.rs b/src-tauri/src/service/mod.rs index 3e277efc..431a79f4 100644 --- a/src-tauri/src/service/mod.rs +++ b/src-tauri/src/service/mod.rs @@ -13,7 +13,7 @@ use std::{ net::IpAddr, pin::Pin, str::FromStr, - sync::{Arc, RwLock}, + sync::{Arc, Mutex, RwLock}, time::{Duration, SystemTime, UNIX_EPOCH}, }; #[cfg(unix)] @@ -38,7 +38,7 @@ use proto::{ }; #[cfg(unix)] use tokio::net::UnixListener; -use tokio::{sync::mpsc, time::interval}; +use tokio::{sync::mpsc, task::JoinHandle, time::interval}; #[cfg(unix)] use tokio_stream::wrappers::UnixListenerStream; use tonic::{ @@ -85,6 +85,7 @@ pub(crate) struct DaemonService { // Map of running `WGApi`s; key is interface name. wgapis: Arc>>, stats_period: Duration, + stat_tasks: Arc>>>, } impl DaemonService { @@ -93,6 +94,7 @@ impl DaemonService { Self { wgapis: Arc::new(RwLock::new(HashMap::new())), stats_period: Duration::from_secs(config.stats_period), + stat_tasks: Arc::new(Mutex::new(HashMap::new())), } } } @@ -223,6 +225,14 @@ impl DesktopDaemonService for DaemonService { let _span = info_span!("remove_interface", interface_name = &ifname).entered(); debug!("Removing interface {ifname}"); + // Stop stats task. + if let Ok(mut tasks) = self.stat_tasks.lock() { + if let Some(handle) = tasks.remove(&ifname) { + info!("Stopping statistics collector task for interface {ifname}"); + handle.abort(); + } + } + let wgapi = { let Ok(mut wgapis_map) = self.wgapis.write() else { error!("Failed to acquire read-write lock for WGApis"); @@ -263,7 +273,7 @@ impl DesktopDaemonService for DaemonService { request: tonic::Request, ) -> Result, Status> { let request = request.into_inner(); - let ifname = request.interface_name; + let ifname = request.interface_name.clone(); debug!( "Received a request to start a new network usage stats data stream for interface \ {ifname}" @@ -277,8 +287,7 @@ impl DesktopDaemonService for DaemonService { span.in_scope(|| { info!("Spawning statistics collector task for interface {ifname}"); }); - - tokio::spawn( + let handle = tokio::spawn( async move { // Helper map to track if peer data is actually changing to avoid sending duplicate // stats. @@ -356,6 +365,9 @@ impl DesktopDaemonService for DaemonService { } .instrument(span), ); + if let Ok(mut tasks) = self.stat_tasks.lock() { + tasks.insert(request.interface_name, handle); + } let output_stream = ReceiverStream::new(rx); Ok(Response::new( From 701505a8366d1d4eaa99d4e60309184becd1e3e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Thu, 2 Oct 2025 13:30:41 +0200 Subject: [PATCH 4/7] Pin defguard_wireguard_rs --- package.json | 12 +- pnpm-lock.yaml | 380 +++++++++++++++++++++---------------------- src-tauri/Cargo.lock | 12 +- src-tauri/Cargo.toml | 2 +- 4 files changed, 204 insertions(+), 202 deletions(-) diff --git a/package.json b/package.json index 322b1bb0..0950fc0f 100644 --- a/package.json +++ b/package.json @@ -87,10 +87,10 @@ "p-timeout": "^6.1.4", "prop-types": "^15.8.1", "radash": "^12.1.1", - "react": "^19.1.1", + "react": "^19.2.0", "react-auth-code-input": "^3.2.1", "react-click-away-listener": "^2.4.0", - "react-dom": "^19.1.1", + "react-dom": "^19.2.0", "react-hook-form": "^7.63.0", "react-loading-skeleton": "^3.5.0", "react-markdown": "^10.1.0", @@ -114,9 +114,9 @@ "@tauri-apps/cli": "^2.8.4", "@types/file-saver": "^2.0.7", "@types/lodash-es": "^4.17.12", - "@types/node": "^24.6.1", - "@types/react": "^19.1.16", - "@types/react-dom": "^19.1.9", + "@types/node": "^24.6.2", + "@types/react": "^19.2.0", + "@types/react-dom": "^19.2.0", "@vitejs/plugin-react": "^5.0.4", "@vitejs/plugin-react-swc": "^4.1.0", "autoprefixer": "^10.4.21", @@ -127,7 +127,7 @@ "typedoc": "^0.28.13", "typesafe-i18n": "^5.26.2", "typescript": "^5.9.3", - "vite": "^7.1.7" + "vite": "^7.1.8" }, "volta": { "node": "20.5.1" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5f28b2d6..11375949 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,13 +10,13 @@ importers: dependencies: '@floating-ui/react': specifier: ^0.27.16 - version: 0.27.16(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 0.27.16(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@hookform/resolvers': specifier: ^3.10.0 - version: 3.10.0(react-hook-form@7.63.0(react@19.1.1)) + version: 3.10.0(react-hook-form@7.63.0(react@19.2.0)) '@react-hook/resize-observer': specifier: ^2.0.2 - version: 2.0.2(react@19.1.1) + version: 2.0.2(react@19.2.0) '@stablelib/base64': specifier: ^2.0.1 version: 2.0.1 @@ -28,7 +28,7 @@ importers: version: 5.90.2 '@tanstack/react-virtual': specifier: 3.13.12 - version: 3.13.12(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 3.13.12(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@tauri-apps/api': specifier: ^2.8.0 version: 2.8.0 @@ -67,7 +67,7 @@ importers: version: 8.1.2 '@use-gesture/react': specifier: ^10.3.1 - version: 10.3.1(react@19.1.1) + version: 10.3.1(react@19.2.0) byte-size: specifier: ^9.0.1 version: 9.0.1 @@ -100,7 +100,7 @@ importers: version: 1.0.3 html-react-parser: specifier: ^5.2.6 - version: 5.2.6(@types/react@19.1.16)(react@19.1.1) + version: 5.2.6(@types/react@19.2.0)(react@19.2.0) itertools: specifier: ^2.5.0 version: 2.5.0 @@ -112,13 +112,13 @@ importers: version: 4.17.21 merge-refs: specifier: ^2.0.0 - version: 2.0.0(@types/react@19.1.16) + version: 2.0.0(@types/react@19.2.0) millify: specifier: ^6.1.0 version: 6.1.0 motion: specifier: ^12.23.22 - version: 12.23.22(@emotion/is-prop-valid@1.4.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 12.23.22(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) p-timeout: specifier: ^6.1.4 version: 6.1.4 @@ -129,41 +129,41 @@ importers: specifier: ^12.1.1 version: 12.1.1 react: - specifier: ^19.1.1 - version: 19.1.1 + specifier: ^19.2.0 + version: 19.2.0 react-auth-code-input: specifier: ^3.2.1 - version: 3.2.1(react@19.1.1) + version: 3.2.1(react@19.2.0) react-click-away-listener: specifier: ^2.4.0 - version: 2.4.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 2.4.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react-dom: - specifier: ^19.1.1 - version: 19.1.1(react@19.1.1) + specifier: ^19.2.0 + version: 19.2.0(react@19.2.0) react-hook-form: specifier: ^7.63.0 - version: 7.63.0(react@19.1.1) + version: 7.63.0(react@19.2.0) react-loading-skeleton: specifier: ^3.5.0 - version: 3.5.0(react@19.1.1) + version: 3.5.0(react@19.2.0) react-markdown: specifier: ^10.1.0 - version: 10.1.0(@types/react@19.1.16)(react@19.1.1) + version: 10.1.0(@types/react@19.2.0)(react@19.2.0) react-qr-code: specifier: ^2.0.18 - version: 2.0.18(react@19.1.1) + version: 2.0.18(react@19.2.0) react-router-dom: specifier: ^6.30.1 - version: 6.30.1(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 6.30.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react-use-websocket: specifier: ^4.13.0 version: 4.13.0 react-virtualized-auto-sizer: specifier: ^1.0.26 - version: 1.0.26(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 1.0.26(react-dom@19.2.0(react@19.2.0))(react@19.2.0) recharts: specifier: ^3.2.1 - version: 3.2.1(@types/react@19.1.16)(react-dom@19.1.1(react@19.1.1))(react-is@18.3.1)(react@19.1.1)(redux@5.0.1) + version: 3.2.1(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react-is@18.3.1)(react@19.2.0)(redux@5.0.1) rehype-sanitize: specifier: ^6.0.0 version: 6.0.0 @@ -172,29 +172,29 @@ importers: version: 7.8.2 use-breakpoint: specifier: ^4.0.6 - version: 4.0.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 4.0.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) zod: specifier: ^3.25.76 version: 3.25.76 zustand: specifier: ^5.0.8 - version: 5.0.8(@types/react@19.1.16)(immer@10.1.3)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) + version: 5.0.8(@types/react@19.2.0)(immer@10.1.3)(react@19.2.0)(use-sync-external-store@1.6.0(react@19.2.0)) devDependencies: '@biomejs/biome': specifier: ^2.2.4 version: 2.2.4 '@hookform/devtools': specifier: ^4.4.0 - version: 4.4.0(@types/react@19.1.16)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 4.4.0(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@svgr/cli': specifier: ^8.1.0 version: 8.1.0(typescript@5.9.3) '@tanstack/react-query': specifier: ^5.90.2 - version: 5.90.2(react@19.1.1) + version: 5.90.2(react@19.2.0) '@tanstack/react-query-devtools': specifier: ^5.90.2 - version: 5.90.2(@tanstack/react-query@5.90.2(react@19.1.1))(react@19.1.1) + version: 5.90.2(@tanstack/react-query@5.90.2(react@19.2.0))(react@19.2.0) '@tauri-apps/cli': specifier: ^2.8.4 version: 2.8.4 @@ -205,20 +205,20 @@ importers: specifier: ^4.17.12 version: 4.17.12 '@types/node': - specifier: ^24.6.1 - version: 24.6.1 + specifier: ^24.6.2 + version: 24.6.2 '@types/react': - specifier: ^19.1.16 - version: 19.1.16 + specifier: ^19.2.0 + version: 19.2.0 '@types/react-dom': - specifier: ^19.1.9 - version: 19.1.9(@types/react@19.1.16) + specifier: ^19.2.0 + version: 19.2.0(@types/react@19.2.0) '@vitejs/plugin-react': specifier: ^5.0.4 - version: 5.0.4(vite@7.1.7(@types/node@24.6.1)(sass@1.92.1)(yaml@2.8.1)) + version: 5.0.4(vite@7.1.8(@types/node@24.6.2)(sass@1.92.1)(yaml@2.8.1)) '@vitejs/plugin-react-swc': specifier: ^4.1.0 - version: 4.1.0(vite@7.1.7(@types/node@24.6.1)(sass@1.92.1)(yaml@2.8.1)) + version: 4.1.0(vite@7.1.8(@types/node@24.6.2)(sass@1.92.1)(yaml@2.8.1)) autoprefixer: specifier: ^10.4.21 version: 10.4.21(postcss@8.5.6) @@ -244,8 +244,8 @@ importers: specifier: ^5.9.3 version: 5.9.3 vite: - specifier: ^7.1.7 - version: 7.1.7(@types/node@24.6.1)(sass@1.92.1)(yaml@2.8.1) + specifier: ^7.1.8 + version: 7.1.8(@types/node@24.6.2)(sass@1.92.1)(yaml@2.8.1) packages: @@ -1286,19 +1286,19 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/node@24.6.1': - resolution: {integrity: sha512-ljvjjs3DNXummeIaooB4cLBKg2U6SPI6Hjra/9rRIy7CpM0HpLtG9HptkMKAb4HYWy5S7HUvJEuWgr/y0U8SHw==} + '@types/node@24.6.2': + resolution: {integrity: sha512-d2L25Y4j+W3ZlNAeMKcy7yDsK425ibcAOO2t7aPTz6gNMH0z2GThtwENCDc0d/Pw9wgyRqE5Px1wkV7naz8ang==} '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} - '@types/react-dom@19.1.9': - resolution: {integrity: sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==} + '@types/react-dom@19.2.0': + resolution: {integrity: sha512-brtBs0MnE9SMx7px208g39lRmC5uHZs96caOJfTjFcYSLHNamvaSMfJNagChVNkup2SdtOxKX1FDBkRSJe1ZAg==} peerDependencies: - '@types/react': ^19.0.0 + '@types/react': ^19.2.0 - '@types/react@19.1.16': - resolution: {integrity: sha512-WBM/nDbEZmDUORKnh5i1bTnAz6vTohUf9b8esSMu+b24+srbaxa04UbJgWx78CVfNXA20sNu0odEIluZDFdCog==} + '@types/react@19.2.0': + resolution: {integrity: sha512-1LOH8xovvsKsCBq1wnT4ntDUdCJKmnEakhsuoUSy6ExlHCkGP2hqnatagYTgFk6oeL0VU31u7SNjunPN+GchtA==} '@types/unist@2.0.11': resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} @@ -1380,8 +1380,8 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - baseline-browser-mapping@2.8.9: - resolution: {integrity: sha512-hY/u2lxLrbecMEWSB0IpGzGyDyeoMFQhCvZd2jGFSE5I17Fh01sYUBPCJtkWERw7zrac9+cIghxm/ytJa2X8iA==} + baseline-browser-mapping@2.8.10: + resolution: {integrity: sha512-uLfgBi+7IBNay8ECBO2mVMGZAc1VgZWEChxm4lv+TobGdG82LnXMjuNGo/BSSZZL4UmkWhxEHP2f5ziLNwGWMA==} hasBin: true boolbase@1.0.0: @@ -1397,8 +1397,8 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.26.2: - resolution: {integrity: sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==} + browserslist@4.26.3: + resolution: {integrity: sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -2454,10 +2454,10 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom@19.1.1: - resolution: {integrity: sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==} + react-dom@19.2.0: + resolution: {integrity: sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==} peerDependencies: - react: ^19.1.1 + react: ^19.2.0 react-hook-form@7.63.0: resolution: {integrity: sha512-ZwueDMvUeucovM2VjkCf7zIHcs1aAlDimZu2Hvel5C5907gUzMpm4xCrQXtRzCvsBqFjonB4m3x4LzCFI1ZKWA==} @@ -2533,8 +2533,8 @@ packages: react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 || ^19.0.0 - react@19.1.1: - resolution: {integrity: sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==} + react@19.2.0: + resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==} engines: {node: '>=0.10.0'} read-pkg@3.0.0: @@ -2619,8 +2619,8 @@ packages: engines: {node: '>=14.0.0'} hasBin: true - scheduler@0.26.0: - resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} @@ -2863,8 +2863,8 @@ packages: peerDependencies: react: '>=16.13' - use-sync-external-store@1.5.0: - resolution: {integrity: sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==} + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -2884,8 +2884,8 @@ packages: victory-vendor@37.3.6: resolution: {integrity: sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==} - vite@7.1.7: - resolution: {integrity: sha512-VbA8ScMvAISJNJVbRDTJdCwqQoAareR/wutevKanhR2/1EkoXVZVkkORaYm/tNVCjP/UDTKtcw3bAkwOUdedmA==} + vite@7.1.8: + resolution: {integrity: sha512-oBXvfSHEOL8jF+R9Am7h59Up07kVVGH1NrFGFoEG6bPDZP3tGpQhvkBpy5x7U6+E6wZCu9OihsWgJqDbQIm8LQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -3041,7 +3041,7 @@ snapshots: dependencies: '@babel/compat-data': 7.28.4 '@babel/helper-validator-option': 7.27.1 - browserslist: 4.26.2 + browserslist: 4.26.3 lru-cache: 5.1.1 semver: 6.3.1 @@ -3182,19 +3182,19 @@ snapshots: '@emotion/memoize@0.9.0': {} - '@emotion/react@11.14.0(@types/react@19.1.16)(react@19.1.1)': + '@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0)': dependencies: '@babel/runtime': 7.28.4 '@emotion/babel-plugin': 11.13.5 '@emotion/cache': 11.14.0 '@emotion/serialize': 1.3.3 - '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.1.1) + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.0) '@emotion/utils': 1.4.2 '@emotion/weak-memoize': 0.4.0 hoist-non-react-statics: 3.3.2 - react: 19.1.1 + react: 19.2.0 optionalDependencies: - '@types/react': 19.1.16 + '@types/react': 19.2.0 transitivePeerDependencies: - supports-color @@ -3208,26 +3208,26 @@ snapshots: '@emotion/sheet@1.4.0': {} - '@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.16)(react@19.1.1))(@types/react@19.1.16)(react@19.1.1)': + '@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react@19.2.0)': dependencies: '@babel/runtime': 7.28.4 '@emotion/babel-plugin': 11.13.5 '@emotion/is-prop-valid': 1.4.0 - '@emotion/react': 11.14.0(@types/react@19.1.16)(react@19.1.1) + '@emotion/react': 11.14.0(@types/react@19.2.0)(react@19.2.0) '@emotion/serialize': 1.3.3 - '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.1.1) + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.0) '@emotion/utils': 1.4.2 - react: 19.1.1 + react: 19.2.0 optionalDependencies: - '@types/react': 19.1.16 + '@types/react': 19.2.0 transitivePeerDependencies: - supports-color '@emotion/unitless@0.10.0': {} - '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.1.1)': + '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.2.0)': dependencies: - react: 19.1.1 + react: 19.2.0 '@emotion/utils@1.4.2': {} @@ -3320,18 +3320,18 @@ snapshots: '@floating-ui/core': 1.7.3 '@floating-ui/utils': 0.2.10 - '@floating-ui/react-dom@2.1.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@floating-ui/react-dom@2.1.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@floating-ui/dom': 1.7.4 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) - '@floating-ui/react@0.27.16(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@floating-ui/react@0.27.16(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: - '@floating-ui/react-dom': 2.1.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@floating-ui/react-dom': 2.1.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@floating-ui/utils': 0.2.10 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) tabbable: 6.2.0 '@floating-ui/utils@0.2.10': {} @@ -3344,25 +3344,25 @@ snapshots: '@shikijs/types': 3.13.0 '@shikijs/vscode-textmate': 10.0.2 - '@hookform/devtools@4.4.0(@types/react@19.1.16)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@hookform/devtools@4.4.0(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: - '@emotion/react': 11.14.0(@types/react@19.1.16)(react@19.1.1) - '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.1.16)(react@19.1.1))(@types/react@19.1.16)(react@19.1.1) + '@emotion/react': 11.14.0(@types/react@19.2.0)(react@19.2.0) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react@19.2.0) '@types/lodash': 4.17.20 - little-state-machine: 4.8.1(react@19.1.1) + little-state-machine: 4.8.1(react@19.2.0) lodash: 4.17.21 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - react-simple-animate: 3.5.3(react-dom@19.1.1(react@19.1.1)) - use-deep-compare-effect: 1.8.1(react@19.1.1) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + react-simple-animate: 3.5.3(react-dom@19.2.0(react@19.2.0)) + use-deep-compare-effect: 1.8.1(react@19.2.0) uuid: 8.3.2 transitivePeerDependencies: - '@types/react' - supports-color - '@hookform/resolvers@3.10.0(react-hook-form@7.63.0(react@19.1.1))': + '@hookform/resolvers@3.10.0(react-hook-form@7.63.0(react@19.2.0))': dependencies: - react-hook-form: 7.63.0(react@19.1.1) + react-hook-form: 7.63.0(react@19.2.0) '@jridgewell/gen-mapping@0.3.13': dependencies: @@ -3444,21 +3444,21 @@ snapshots: '@parcel/watcher-win32-x64': 2.5.1 optional: true - '@react-hook/latest@1.0.3(react@19.1.1)': + '@react-hook/latest@1.0.3(react@19.2.0)': dependencies: - react: 19.1.1 + react: 19.2.0 - '@react-hook/passive-layout-effect@1.2.1(react@19.1.1)': + '@react-hook/passive-layout-effect@1.2.1(react@19.2.0)': dependencies: - react: 19.1.1 + react: 19.2.0 - '@react-hook/resize-observer@2.0.2(react@19.1.1)': + '@react-hook/resize-observer@2.0.2(react@19.2.0)': dependencies: - '@react-hook/latest': 1.0.3(react@19.1.1) - '@react-hook/passive-layout-effect': 1.2.1(react@19.1.1) - react: 19.1.1 + '@react-hook/latest': 1.0.3(react@19.2.0) + '@react-hook/passive-layout-effect': 1.2.1(react@19.2.0) + react: 19.2.0 - '@reduxjs/toolkit@2.9.0(react-redux@9.2.0(@types/react@19.1.16)(react@19.1.1)(redux@5.0.1))(react@19.1.1)': + '@reduxjs/toolkit@2.9.0(react-redux@9.2.0(@types/react@19.2.0)(react@19.2.0)(redux@5.0.1))(react@19.2.0)': dependencies: '@standard-schema/spec': 1.0.0 '@standard-schema/utils': 0.3.0 @@ -3467,8 +3467,8 @@ snapshots: redux-thunk: 3.1.0(redux@5.0.1) reselect: 5.1.1 optionalDependencies: - react: 19.1.1 - react-redux: 9.2.0(@types/react@19.1.16)(react@19.1.1)(redux@5.0.1) + react: 19.2.0 + react-redux: 9.2.0(@types/react@19.2.0)(react@19.2.0)(redux@5.0.1) '@remix-run/router@1.23.0': {} @@ -3750,22 +3750,22 @@ snapshots: '@tanstack/query-devtools@5.90.1': {} - '@tanstack/react-query-devtools@5.90.2(@tanstack/react-query@5.90.2(react@19.1.1))(react@19.1.1)': + '@tanstack/react-query-devtools@5.90.2(@tanstack/react-query@5.90.2(react@19.2.0))(react@19.2.0)': dependencies: '@tanstack/query-devtools': 5.90.1 - '@tanstack/react-query': 5.90.2(react@19.1.1) - react: 19.1.1 + '@tanstack/react-query': 5.90.2(react@19.2.0) + react: 19.2.0 - '@tanstack/react-query@5.90.2(react@19.1.1)': + '@tanstack/react-query@5.90.2(react@19.2.0)': dependencies: '@tanstack/query-core': 5.90.2 - react: 19.1.1 + react: 19.2.0 - '@tanstack/react-virtual@3.13.12(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@tanstack/react-virtual@3.13.12(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@tanstack/virtual-core': 3.13.12 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) '@tanstack/virtual-core@3.13.12': {} @@ -3935,17 +3935,17 @@ snapshots: '@types/ms@2.1.0': {} - '@types/node@24.6.1': + '@types/node@24.6.2': dependencies: undici-types: 7.13.0 '@types/parse-json@4.0.2': {} - '@types/react-dom@19.1.9(@types/react@19.1.16)': + '@types/react-dom@19.2.0(@types/react@19.2.0)': dependencies: - '@types/react': 19.1.16 + '@types/react': 19.2.0 - '@types/react@19.1.16': + '@types/react@19.2.0': dependencies: csstype: 3.1.3 @@ -3959,20 +3959,20 @@ snapshots: '@use-gesture/core@10.3.1': {} - '@use-gesture/react@10.3.1(react@19.1.1)': + '@use-gesture/react@10.3.1(react@19.2.0)': dependencies: '@use-gesture/core': 10.3.1 - react: 19.1.1 + react: 19.2.0 - '@vitejs/plugin-react-swc@4.1.0(vite@7.1.7(@types/node@24.6.1)(sass@1.92.1)(yaml@2.8.1))': + '@vitejs/plugin-react-swc@4.1.0(vite@7.1.8(@types/node@24.6.2)(sass@1.92.1)(yaml@2.8.1))': dependencies: '@rolldown/pluginutils': 1.0.0-beta.35 '@swc/core': 1.13.5 - vite: 7.1.7(@types/node@24.6.1)(sass@1.92.1)(yaml@2.8.1) + vite: 7.1.8(@types/node@24.6.2)(sass@1.92.1)(yaml@2.8.1) transitivePeerDependencies: - '@swc/helpers' - '@vitejs/plugin-react@5.0.4(vite@7.1.7(@types/node@24.6.1)(sass@1.92.1)(yaml@2.8.1))': + '@vitejs/plugin-react@5.0.4(vite@7.1.8(@types/node@24.6.2)(sass@1.92.1)(yaml@2.8.1))': dependencies: '@babel/core': 7.28.4 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.4) @@ -3980,7 +3980,7 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.38 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 7.1.7(@types/node@24.6.1)(sass@1.92.1)(yaml@2.8.1) + vite: 7.1.8(@types/node@24.6.2)(sass@1.92.1)(yaml@2.8.1) transitivePeerDependencies: - supports-color @@ -4015,7 +4015,7 @@ snapshots: autoprefixer@10.4.21(postcss@8.5.6): dependencies: - browserslist: 4.26.2 + browserslist: 4.26.3 caniuse-lite: 1.0.30001746 fraction.js: 4.3.7 normalize-range: 0.1.2 @@ -4037,7 +4037,7 @@ snapshots: balanced-match@1.0.2: {} - baseline-browser-mapping@2.8.9: {} + baseline-browser-mapping@2.8.10: {} boolbase@1.0.0: {} @@ -4055,13 +4055,13 @@ snapshots: fill-range: 7.1.1 optional: true - browserslist@4.26.2: + browserslist@4.26.3: dependencies: - baseline-browser-mapping: 2.8.9 + baseline-browser-mapping: 2.8.10 caniuse-lite: 1.0.30001746 electron-to-chromium: 1.5.228 node-releases: 2.0.21 - update-browserslist-db: 1.1.3(browserslist@4.26.2) + update-browserslist-db: 1.1.3(browserslist@4.26.3) byte-size@9.0.1: {} @@ -4480,15 +4480,15 @@ snapshots: fraction.js@4.3.7: {} - framer-motion@12.23.22(@emotion/is-prop-valid@1.4.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + framer-motion@12.23.22(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: motion-dom: 12.23.21 motion-utils: 12.23.6 tslib: 2.8.1 optionalDependencies: '@emotion/is-prop-valid': 1.4.0 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) fs.realpath@1.0.0: {} @@ -4622,15 +4622,15 @@ snapshots: domhandler: 5.0.3 htmlparser2: 10.0.0 - html-react-parser@5.2.6(@types/react@19.1.16)(react@19.1.1): + html-react-parser@5.2.6(@types/react@19.2.0)(react@19.2.0): dependencies: domhandler: 5.0.3 html-dom-parser: 5.1.1 - react: 19.1.1 + react: 19.2.0 react-property: 2.0.2 style-to-js: 1.1.17 optionalDependencies: - '@types/react': 19.1.16 + '@types/react': 19.2.0 html-url-attributes@3.0.1: {} @@ -4823,9 +4823,9 @@ snapshots: dependencies: uc.micro: 2.1.0 - little-state-machine@4.8.1(react@19.1.1): + little-state-machine@4.8.1(react@19.2.0): dependencies: - react: 19.1.1 + react: 19.2.0 load-json-file@4.0.0: dependencies: @@ -4962,9 +4962,9 @@ snapshots: memorystream@0.3.1: {} - merge-refs@2.0.0(@types/react@19.1.16): + merge-refs@2.0.0(@types/react@19.2.0): optionalDependencies: - '@types/react': 19.1.16 + '@types/react': 19.2.0 micromark-core-commonmark@2.0.3: dependencies: @@ -5127,14 +5127,14 @@ snapshots: motion-utils@12.23.6: {} - motion@12.23.22(@emotion/is-prop-valid@1.4.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + motion@12.23.22(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: - framer-motion: 12.23.22(@emotion/is-prop-valid@1.4.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + framer-motion: 12.23.22(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) tslib: 2.8.1 optionalDependencies: '@emotion/is-prop-valid': 1.4.0 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) ms@2.1.3: {} @@ -5279,42 +5279,42 @@ snapshots: radash@12.1.1: {} - react-auth-code-input@3.2.1(react@19.1.1): + react-auth-code-input@3.2.1(react@19.2.0): dependencies: - react: 19.1.1 + react: 19.2.0 - react-click-away-listener@2.4.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + react-click-away-listener@2.4.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) - react-dom@19.1.1(react@19.1.1): + react-dom@19.2.0(react@19.2.0): dependencies: - react: 19.1.1 - scheduler: 0.26.0 + react: 19.2.0 + scheduler: 0.27.0 - react-hook-form@7.63.0(react@19.1.1): + react-hook-form@7.63.0(react@19.2.0): dependencies: - react: 19.1.1 + react: 19.2.0 react-is@16.13.1: {} react-is@18.3.1: {} - react-loading-skeleton@3.5.0(react@19.1.1): + react-loading-skeleton@3.5.0(react@19.2.0): dependencies: - react: 19.1.1 + react: 19.2.0 - react-markdown@10.1.0(@types/react@19.1.16)(react@19.1.1): + react-markdown@10.1.0(@types/react@19.2.0)(react@19.2.0): dependencies: '@types/hast': 3.0.4 '@types/mdast': 4.0.4 - '@types/react': 19.1.16 + '@types/react': 19.2.0 devlop: 1.1.0 hast-util-to-jsx-runtime: 2.3.6 html-url-attributes: 3.0.1 mdast-util-to-hast: 13.2.0 - react: 19.1.1 + react: 19.2.0 remark-parse: 11.0.0 remark-rehype: 11.1.2 unified: 11.0.5 @@ -5325,47 +5325,47 @@ snapshots: react-property@2.0.2: {} - react-qr-code@2.0.18(react@19.1.1): + react-qr-code@2.0.18(react@19.2.0): dependencies: prop-types: 15.8.1 qr.js: 0.0.0 - react: 19.1.1 + react: 19.2.0 - react-redux@9.2.0(@types/react@19.1.16)(react@19.1.1)(redux@5.0.1): + react-redux@9.2.0(@types/react@19.2.0)(react@19.2.0)(redux@5.0.1): dependencies: '@types/use-sync-external-store': 0.0.6 - react: 19.1.1 - use-sync-external-store: 1.5.0(react@19.1.1) + react: 19.2.0 + use-sync-external-store: 1.6.0(react@19.2.0) optionalDependencies: - '@types/react': 19.1.16 + '@types/react': 19.2.0 redux: 5.0.1 react-refresh@0.17.0: {} - react-router-dom@6.30.1(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + react-router-dom@6.30.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: '@remix-run/router': 1.23.0 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - react-router: 6.30.1(react@19.1.1) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + react-router: 6.30.1(react@19.2.0) - react-router@6.30.1(react@19.1.1): + react-router@6.30.1(react@19.2.0): dependencies: '@remix-run/router': 1.23.0 - react: 19.1.1 + react: 19.2.0 - react-simple-animate@3.5.3(react-dom@19.1.1(react@19.1.1)): + react-simple-animate@3.5.3(react-dom@19.2.0(react@19.2.0)): dependencies: - react-dom: 19.1.1(react@19.1.1) + react-dom: 19.2.0(react@19.2.0) react-use-websocket@4.13.0: {} - react-virtualized-auto-sizer@1.0.26(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + react-virtualized-auto-sizer@1.0.26(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) - react@19.1.1: {} + react@19.2.0: {} read-pkg@3.0.0: dependencies: @@ -5375,21 +5375,21 @@ snapshots: readdirp@4.1.2: {} - recharts@3.2.1(@types/react@19.1.16)(react-dom@19.1.1(react@19.1.1))(react-is@18.3.1)(react@19.1.1)(redux@5.0.1): + recharts@3.2.1(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react-is@18.3.1)(react@19.2.0)(redux@5.0.1): dependencies: - '@reduxjs/toolkit': 2.9.0(react-redux@9.2.0(@types/react@19.1.16)(react@19.1.1)(redux@5.0.1))(react@19.1.1) + '@reduxjs/toolkit': 2.9.0(react-redux@9.2.0(@types/react@19.2.0)(react@19.2.0)(redux@5.0.1))(react@19.2.0) clsx: 2.1.1 decimal.js-light: 2.5.1 es-toolkit: 1.39.10 eventemitter3: 5.0.1 immer: 10.1.3 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) react-is: 18.3.1 - react-redux: 9.2.0(@types/react@19.1.16)(react@19.1.1)(redux@5.0.1) + react-redux: 9.2.0(@types/react@19.2.0)(react@19.2.0)(redux@5.0.1) reselect: 5.1.1 tiny-invariant: 1.3.3 - use-sync-external-store: 1.5.0(react@19.1.1) + use-sync-external-store: 1.6.0(react@19.2.0) victory-vendor: 37.3.6 transitivePeerDependencies: - '@types/react' @@ -5514,7 +5514,7 @@ snapshots: optionalDependencies: '@parcel/watcher': 2.5.1 - scheduler@0.26.0: {} + scheduler@0.27.0: {} semver@5.7.2: {} @@ -5799,26 +5799,26 @@ snapshots: unist-util-is: 6.0.0 unist-util-visit-parents: 6.0.1 - update-browserslist-db@1.1.3(browserslist@4.26.2): + update-browserslist-db@1.1.3(browserslist@4.26.3): dependencies: - browserslist: 4.26.2 + browserslist: 4.26.3 escalade: 3.2.0 picocolors: 1.1.1 - use-breakpoint@4.0.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + use-breakpoint@4.0.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) - use-deep-compare-effect@1.8.1(react@19.1.1): + use-deep-compare-effect@1.8.1(react@19.2.0): dependencies: '@babel/runtime': 7.28.4 dequal: 2.0.3 - react: 19.1.1 + react: 19.2.0 - use-sync-external-store@1.5.0(react@19.1.1): + use-sync-external-store@1.6.0(react@19.2.0): dependencies: - react: 19.1.1 + react: 19.2.0 uuid@8.3.2: {} @@ -5854,7 +5854,7 @@ snapshots: d3-time: 3.1.0 d3-timer: 3.0.1 - vite@7.1.7(@types/node@24.6.1)(sass@1.92.1)(yaml@2.8.1): + vite@7.1.8(@types/node@24.6.2)(sass@1.92.1)(yaml@2.8.1): dependencies: esbuild: 0.25.10 fdir: 6.5.0(picomatch@4.0.3) @@ -5863,7 +5863,7 @@ snapshots: rollup: 4.52.3 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.6.1 + '@types/node': 24.6.2 fsevents: 2.3.3 sass: 1.92.1 yaml: 2.8.1 @@ -5943,11 +5943,11 @@ snapshots: zod@3.25.76: {} - zustand@5.0.8(@types/react@19.1.16)(immer@10.1.3)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)): + zustand@5.0.8(@types/react@19.2.0)(immer@10.1.3)(react@19.2.0)(use-sync-external-store@1.6.0(react@19.2.0)): optionalDependencies: - '@types/react': 19.1.16 + '@types/react': 19.2.0 immer: 10.1.3 - react: 19.1.1 - use-sync-external-store: 1.5.0(react@19.1.1) + react: 19.2.0 + use-sync-external-store: 1.6.0(react@19.2.0) zwitch@2.0.4: {} diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index ef1f348c..1e7eb2ce 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -671,6 +671,7 @@ dependencies = [ [[package]] name = "boringtun" version = "0.6.0" +source = "git+https://github.com/DefGuard/wireguard-rs?rev=42d478b980cb3f7549f20f2f492c896a7389a79d#42d478b980cb3f7549f20f2f492c896a7389a79d" dependencies = [ "aead", "base64 0.22.1", @@ -1470,7 +1471,8 @@ dependencies = [ [[package]] name = "defguard_wireguard_rs" -version = "0.7.8" +version = "0.8.0" +source = "git+https://github.com/DefGuard/wireguard-rs?rev=42d478b980cb3f7549f20f2f492c896a7389a79d#42d478b980cb3f7549f20f2f492c896a7389a79d" dependencies = [ "base64 0.22.1", "boringtun", @@ -5318,9 +5320,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.6" +version = "0.103.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8572f3c2cb9934231157b45499fc41e1f58c589fdfb81a844ba873265e80f8eb" +checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" dependencies = [ "ring", "rustls-pki-types", @@ -7377,9 +7379,9 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "uds_windows" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index a3cf00cf..e63fd2b2 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -4,7 +4,7 @@ default-members = [".", "cli"] [workspace.dependencies] clap = { version = "4.5", features = ["cargo", "derive", "env"] } -defguard_wireguard_rs = { path = "../../wireguard-rs" } +defguard_wireguard_rs = { git = "https://github.com/DefGuard/wireguard-rs", rev = "42d478b980cb3f7549f20f2f492c896a7389a79d" } dirs-next = "2.0" prost = "0.14" reqwest = { version = "0.12", features = ["cookies", "json"] } From e03a6c3c3bdcf4f2e9eca25b062cc5de4d268a7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Fri, 3 Oct 2025 11:06:41 +0200 Subject: [PATCH 5/7] Fix dg --- src-tauri/Cargo.lock | 4 ++-- src-tauri/cli/src/bin/dg.rs | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 1e7eb2ce..ff54a0eb 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -96,9 +96,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.20" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", diff --git a/src-tauri/cli/src/bin/dg.rs b/src-tauri/cli/src/bin/dg.rs index e74b681d..1252de10 100644 --- a/src-tauri/cli/src/bin/dg.rs +++ b/src-tauri/cli/src/bin/dg.rs @@ -156,7 +156,8 @@ async fn connect(config: CliConfig, ifname: String, trigger: Arc) -> Res debug!("Connecting to network {network_name}."); #[cfg(not(target_os = "macos"))] - let wgapi = WGApi::::new(ifname.to_string()).expect("Failed to setup WireGuard API"); + let mut wgapi = + WGApi::::new(ifname.to_string()).expect("Failed to setup WireGuard API"); #[cfg(target_os = "macos")] let mut wgapi = WGApi::::new(ifname.to_string()).expect("Failed to setup WireGuard API"); From 32e2be93e64eecb2a426dfb63f32aa80ee85b891 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Fri, 3 Oct 2025 11:15:19 +0200 Subject: [PATCH 6/7] Make cargo-deny happy --- src-tauri/deny.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/src-tauri/deny.toml b/src-tauri/deny.toml index f0d3f368..9e62bad1 100644 --- a/src-tauri/deny.toml +++ b/src-tauri/deny.toml @@ -106,6 +106,7 @@ allow = [ "Apache-2.0", "Apache-2.0 WITH LLVM-exception", "MPL-2.0", + "BSD-2-Clause", "BSD-3-Clause", "Unicode-3.0", "Unicode-DFS-2016", # unicode-ident From 240618a58baf86ffaea2fa59ac9737bb8ce17d9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Fri, 3 Oct 2025 11:35:02 +0200 Subject: [PATCH 7/7] Remove references to wireguard-go --- .github/workflows/release.yaml | 44 ------------------- .../resources-macos/resources/uninstall.sh | 4 -- src-tauri/resources-macos/scripts/postinstall | 4 -- src-tauri/src/bin/defguard-client.rs | 19 -------- 4 files changed, 71 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index a9073548..f233bd26 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -5,40 +5,6 @@ on: - v*.*.* jobs: - build-wireguard-go: - strategy: - fail-fast: false - matrix: - architecture: [arm64, amd64] - runs-on: [self-hosted, macOS] - steps: - - uses: actions/checkout@v5 - with: - repository: WireGuard/wireguard-go - ref: master - fetch-depth: 0 - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: "1.24" - - name: Build wireguard-go binary - run: make - env: - GOOS: darwin - GOARCH: ${{ matrix.architecture }} - - name: Upload binary artifact arm64 - if: matrix.architecture == 'arm64' - uses: actions/upload-artifact@v4 - with: - name: wireguard-go-aarch64-apple-darwin - path: wireguard-go - - name: Upload binary artifact amd64 - if: matrix.architecture == 'amd64' - uses: actions/upload-artifact@v4 - with: - name: wireguard-go-x86_64-apple-darwin - path: wireguard-go - create-release: name: create-release runs-on: self-hosted @@ -221,7 +187,6 @@ jobs: build-macos: needs: - create-release - - build-wireguard-go strategy: fail-fast: false matrix: @@ -267,15 +232,6 @@ jobs: run: brew install protobuf - name: Install ARM target run: rustup target add aarch64-apple-darwin - - name: Download wireguard-go binary - uses: actions/download-artifact@v4 - with: - name: wireguard-go-${{ matrix.target }} - path: src-tauri/resources-macos/binaries - - name: Rename wireguard-go binary - run: | - ls -l src-tauri/resources-macos/binaries - mv src-tauri/resources-macos/binaries/wireguard-go src-tauri/resources-macos/binaries/wireguard-go-${{ matrix.target }} - name: Unlock keychain run: security -v unlock-keychain -p "${{ secrets.KEYCHAIN_PASSWORD }}" /Users/admin/Library/Keychains/login.keychain - name: Build app diff --git a/src-tauri/resources-macos/resources/uninstall.sh b/src-tauri/resources-macos/resources/uninstall.sh index 9004910e..629344c2 100644 --- a/src-tauri/resources-macos/resources/uninstall.sh +++ b/src-tauri/resources-macos/resources/uninstall.sh @@ -2,7 +2,6 @@ SERVICE_BINARY=defguard-service DAEMON_PROPERTY_FILE=net.defguard.plist -WIREGUARD_GO_BINARY=wireguard-go DAEMON_NAME=net.defguard PACKAGE_ID=net.defguard @@ -12,9 +11,6 @@ if (( $EUID != 0 )); then exit fi -# Remove wireguard-go shortcut at /usr/local/bin -rm -f /usr/local/bin/${WIREGUARD_GO_BINARY} - # Remove service shortcut at /usr/local/bin rm -f /usr/local/bin/${SERVICE_BINARY} diff --git a/src-tauri/resources-macos/scripts/postinstall b/src-tauri/resources-macos/scripts/postinstall index d660c2a9..b1ed66ba 100755 --- a/src-tauri/resources-macos/scripts/postinstall +++ b/src-tauri/resources-macos/scripts/postinstall @@ -2,7 +2,6 @@ SERVICE_BINARY=defguard-service DAEMON_PROPERTY_FILE=net.defguard.plist -WIREGUARD_GO_BINARY=wireguard-go DAEMON_NAME=net.defguard APP_BUNDLE=defguard-client.app PRODUCT_HOME=/Applications/${APP_BUNDLE} @@ -13,9 +12,6 @@ echo "Post installation process started" mkdir -p /usr/local/bin -# Add wireguard-go shortcut to /usr/local/bin -ln -sf ${BINARY_PATH}/${WIREGUARD_GO_BINARY} /usr/local/bin/${WIREGUARD_GO_BINARY} - # Add service shortcut to /usr/local/bin ln -sf ${BINARY_PATH}/${SERVICE_BINARY} /usr/local/bin/${SERVICE_BINARY} diff --git a/src-tauri/src/bin/defguard-client.rs b/src-tauri/src/bin/defguard-client.rs index c9a337d3..9d1fa467 100644 --- a/src-tauri/src/bin/defguard-client.rs +++ b/src-tauri/src/bin/defguard-client.rs @@ -25,8 +25,6 @@ use defguard_client::{ VERSION, }; use log::{Level, LevelFilter}; -#[cfg(target_os = "macos")] -use tauri::{process, Env}; use tauri::{AppHandle, Builder, Manager, RunEvent, WindowEvent}; use tauri_plugin_log::{Target, TargetKind}; @@ -113,23 +111,6 @@ async fn startup(app_handle: &AppHandle) { } fn main() { - // add bundled `wireguard-go` binary to PATH - #[cfg(target_os = "macos")] - { - debug!("Adding bundled wireguard-go binary to PATH"); - let current_bin_path = - process::current_binary(&Env::default()).expect("Failed to get current binary path"); - let current_bin_dir = current_bin_path - .parent() - .expect("Failed to get current binary directory"); - let current_path = env::var("PATH").expect("Failed to get current PATH variable"); - env::set_var( - "PATH", - format!("{current_path}:{}", current_bin_dir.to_str().unwrap()), - ); - debug!("Added binary dir {} to PATH", current_bin_dir.display()); - } - let app = Builder::default() .invoke_handler(tauri::generate_handler![ all_locations,