diff --git a/package.json b/package.json index bdab07a5..f6bd120f 100644 --- a/package.json +++ b/package.json @@ -113,7 +113,7 @@ "typesafe-i18n": "^5.26.2", "typescript": "^5.3.2", "typescript-eslint-language-service": "^5.0.5", - "vite": "^4.5.2" + "vite": "^4.5.3" }, "volta": { "node": "20.5.1" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 18010520..09ec4188 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -223,7 +223,7 @@ importers: specifier: ^5.0.5 version: 5.0.5(@typescript-eslint/parser@6.13.1(eslint@8.55.0)(typescript@5.3.2))(eslint@8.55.0)(typescript@5.3.2) vite: - specifier: ^4.5.2 + specifier: ^4.5.3 version: 4.5.3(@types/node@20.10.3)(sass@1.69.5) packages: @@ -1775,11 +1775,8 @@ packages: resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} engines: {node: '>=14.16'} - caniuse-lite@1.0.30001566: - resolution: {integrity: sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==} - - caniuse-lite@1.0.30001651: - resolution: {integrity: sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==} + caniuse-lite@1.0.30001658: + resolution: {integrity: sha512-N2YVqWbJELVdrnsW5p+apoQyYt51aBMSsBZki1XZEfeBCexcM/sf4xiAHcXQBkuOwJBXtWF7aW1sYX6tKebPHw==} ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -5798,7 +5795,7 @@ snapshots: autoprefixer@10.4.16(postcss@8.4.32): dependencies: browserslist: 4.22.2 - caniuse-lite: 1.0.30001566 + caniuse-lite: 1.0.30001658 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.0.0 @@ -5857,14 +5854,14 @@ snapshots: browserslist@4.22.2: dependencies: - caniuse-lite: 1.0.30001566 + caniuse-lite: 1.0.30001658 electron-to-chromium: 1.4.601 node-releases: 2.0.14 update-browserslist-db: 1.0.13(browserslist@4.22.2) browserslist@4.23.3: dependencies: - caniuse-lite: 1.0.30001651 + caniuse-lite: 1.0.30001658 electron-to-chromium: 1.5.9 node-releases: 2.0.18 update-browserslist-db: 1.1.0(browserslist@4.23.3) @@ -5896,9 +5893,7 @@ snapshots: camelcase@7.0.1: {} - caniuse-lite@1.0.30001566: {} - - caniuse-lite@1.0.30001651: {} + caniuse-lite@1.0.30001658: {} ccount@2.0.1: {} diff --git a/src-tauri/.sqlx/query-e03e7215d2e481fe94cb640b89d568358d6a89de739cb10c665c5d305e6c94a9.json b/src-tauri/.sqlx/query-149bfe6602e397dc79a956f33e2373a6a3b08c8d615b404f9917c5158d4857dd.json similarity index 84% rename from src-tauri/.sqlx/query-e03e7215d2e481fe94cb640b89d568358d6a89de739cb10c665c5d305e6c94a9.json rename to src-tauri/.sqlx/query-149bfe6602e397dc79a956f33e2373a6a3b08c8d615b404f9917c5158d4857dd.json index 018f3568..57d096b3 100644 --- a/src-tauri/.sqlx/query-e03e7215d2e481fe94cb640b89d568358d6a89de739cb10c665c5d305e6c94a9.json +++ b/src-tauri/.sqlx/query-149bfe6602e397dc79a956f33e2373a6a3b08c8d615b404f9917c5158d4857dd.json @@ -1,10 +1,10 @@ { "db_name": "SQLite", - "query": "SELECT id \"id?\", name, pubkey, prvkey, address, server_pubkey, preshared_key, allowed_ips, endpoint, dns, persistent_keep_alive,\n route_all_traffic, pre_up, post_up, pre_down, post_down FROM tunnel WHERE server_pubkey = $1;", + "query": "SELECT id \"id: _\", name, pubkey, prvkey, address, server_pubkey, preshared_key, allowed_ips, endpoint, dns, persistent_keep_alive, route_all_traffic, pre_up, post_up, pre_down, post_down FROM tunnel WHERE server_pubkey = $1;", "describe": { "columns": [ { - "name": "id?", + "name": "id: _", "ordinal": 0, "type_info": "Int64" }, @@ -106,5 +106,5 @@ true ] }, - "hash": "e03e7215d2e481fe94cb640b89d568358d6a89de739cb10c665c5d305e6c94a9" + "hash": "149bfe6602e397dc79a956f33e2373a6a3b08c8d615b404f9917c5158d4857dd" } diff --git a/src-tauri/.sqlx/query-501754dcc5d012c155b1881f8f623ea7028fc6c0b4184d81a922c11d73779dd9.json b/src-tauri/.sqlx/query-7019051ceab584decf288e3e5e953562d3bed97b105a18d2312f12238d00d691.json similarity index 72% rename from src-tauri/.sqlx/query-501754dcc5d012c155b1881f8f623ea7028fc6c0b4184d81a922c11d73779dd9.json rename to src-tauri/.sqlx/query-7019051ceab584decf288e3e5e953562d3bed97b105a18d2312f12238d00d691.json index dc70e769..cb697ea3 100644 --- a/src-tauri/.sqlx/query-501754dcc5d012c155b1881f8f623ea7028fc6c0b4184d81a922c11d73779dd9.json +++ b/src-tauri/.sqlx/query-7019051ceab584decf288e3e5e953562d3bed97b105a18d2312f12238d00d691.json @@ -1,10 +1,10 @@ { "db_name": "SQLite", - "query": "SELECT id \"id?\", instance_id, pubkey, prvkey FROM wireguard_keys WHERE instance_id = $1;", + "query": "SELECT id \"id: _\", instance_id, pubkey, prvkey FROM wireguard_keys WHERE instance_id = $1;", "describe": { "columns": [ { - "name": "id?", + "name": "id: _", "ordinal": 0, "type_info": "Int64" }, @@ -34,5 +34,5 @@ false ] }, - "hash": "501754dcc5d012c155b1881f8f623ea7028fc6c0b4184d81a922c11d73779dd9" + "hash": "7019051ceab584decf288e3e5e953562d3bed97b105a18d2312f12238d00d691" } diff --git a/src-tauri/.sqlx/query-294b2d391d5cf01a2e756ae357869b9fb274d4254b479816b3892c9593f76b13.json b/src-tauri/.sqlx/query-98c6d082f2b635afa998eefa1624034d4babc9e3fd18236fd1c18e3c3abefd10.json similarity index 84% rename from src-tauri/.sqlx/query-294b2d391d5cf01a2e756ae357869b9fb274d4254b479816b3892c9593f76b13.json rename to src-tauri/.sqlx/query-98c6d082f2b635afa998eefa1624034d4babc9e3fd18236fd1c18e3c3abefd10.json index eef275ed..f28610a7 100644 --- a/src-tauri/.sqlx/query-294b2d391d5cf01a2e756ae357869b9fb274d4254b479816b3892c9593f76b13.json +++ b/src-tauri/.sqlx/query-98c6d082f2b635afa998eefa1624034d4babc9e3fd18236fd1c18e3c3abefd10.json @@ -1,10 +1,10 @@ { "db_name": "SQLite", - "query": "SELECT id \"id?\", name, pubkey, prvkey, address, server_pubkey, preshared_key, allowed_ips, endpoint, dns, persistent_keep_alive, route_all_traffic, pre_up, post_up, pre_down, post_down FROM tunnel WHERE id = $1;", + "query": "SELECT id \"id: _\", name, pubkey, prvkey, address, server_pubkey, preshared_key, allowed_ips, endpoint, dns, persistent_keep_alive, route_all_traffic, pre_up, post_up, pre_down, post_down FROM tunnel WHERE id = $1;", "describe": { "columns": [ { - "name": "id?", + "name": "id: _", "ordinal": 0, "type_info": "Int64" }, @@ -106,5 +106,5 @@ true ] }, - "hash": "294b2d391d5cf01a2e756ae357869b9fb274d4254b479816b3892c9593f76b13" + "hash": "98c6d082f2b635afa998eefa1624034d4babc9e3fd18236fd1c18e3c3abefd10" } diff --git a/src-tauri/.sqlx/query-25e253a71c188be173e3dce3c640e3028e88be06d10c112e4b4a16b1599f8657.json b/src-tauri/.sqlx/query-f76a3953576d685d4057541b04aabfafdb61c86b0e9486ff0561a7bd80fd6ba8.json similarity index 85% rename from src-tauri/.sqlx/query-25e253a71c188be173e3dce3c640e3028e88be06d10c112e4b4a16b1599f8657.json rename to src-tauri/.sqlx/query-f76a3953576d685d4057541b04aabfafdb61c86b0e9486ff0561a7bd80fd6ba8.json index 278bb272..5fec575d 100644 --- a/src-tauri/.sqlx/query-25e253a71c188be173e3dce3c640e3028e88be06d10c112e4b4a16b1599f8657.json +++ b/src-tauri/.sqlx/query-f76a3953576d685d4057541b04aabfafdb61c86b0e9486ff0561a7bd80fd6ba8.json @@ -1,10 +1,10 @@ { "db_name": "SQLite", - "query": "SELECT id \"id?\", name, pubkey, prvkey, address, server_pubkey, preshared_key, allowed_ips, endpoint, dns, persistent_keep_alive, route_all_traffic, pre_up, post_up, pre_down, post_down FROM tunnel;", + "query": "SELECT id \"id: _\", name, pubkey, prvkey, address, server_pubkey, preshared_key, allowed_ips, endpoint, dns, persistent_keep_alive, route_all_traffic, pre_up, post_up, pre_down, post_down FROM tunnel;", "describe": { "columns": [ { - "name": "id?", + "name": "id: _", "ordinal": 0, "type_info": "Int64" }, @@ -106,5 +106,5 @@ true ] }, - "hash": "25e253a71c188be173e3dce3c640e3028e88be06d10c112e4b4a16b1599f8657" + "hash": "f76a3953576d685d4057541b04aabfafdb61c86b0e9486ff0561a7bd80fd6ba8" } diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 37d5ae7e..cbebaeb8 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" dependencies = [ "gimli", ] @@ -17,6 +17,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + [[package]] name = "ahash" version = "0.7.8" @@ -137,9 +143,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8" [[package]] name = "arboard" @@ -202,13 +208,13 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7ebdfa2ebdab6b1760375fa7d6f382b9f486eac35fc994625a00e89280bdbb7" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" dependencies = [ "async-task", "concurrent-queue", - "fastrand 2.1.0", + "fastrand 2.1.1", "futures-lite 2.3.0", "slab", ] @@ -269,7 +275,7 @@ dependencies = [ "futures-lite 2.3.0", "parking", "polling 3.7.3", - "rustix 0.38.34", + "rustix 0.38.36", "slab", "tracing", "windows-sys 0.59.0", @@ -308,7 +314,7 @@ dependencies = [ "cfg-if", "event-listener 3.1.0", "futures-lite 1.13.0", - "rustix 0.38.34", + "rustix 0.38.36", "windows-sys 0.48.0", ] @@ -327,7 +333,7 @@ dependencies = [ "cfg-if", "event-listener 5.3.1", "futures-lite 2.3.0", - "rustix 0.38.34", + "rustix 0.38.36", "tracing", "windows-sys 0.59.0", ] @@ -340,7 +346,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -355,7 +361,7 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 0.38.34", + "rustix 0.38.36", "signal-hook-registry", "slab", "windows-sys 0.59.0", @@ -380,7 +386,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -391,13 +397,13 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.81" +version = "0.1.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" +checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -494,17 +500,17 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", - "miniz_oxide", + "miniz_oxide 0.8.0", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -621,18 +627,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" dependencies = [ "once_cell", - "proc-macro-crate 3.1.0", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", "syn_derive", ] [[package]] name = "brotli" -version = "3.5.0" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391" +checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -641,9 +647,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "2.5.1" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" +checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -700,9 +706,9 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fd4c6dcc3b0aea2f5c0b4b82c2b15fe39ddbc76041a310848f4706edf76bb31" +checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" [[package]] name = "byteorder" @@ -761,10 +767,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.13" +version = "1.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48" +checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476" dependencies = [ + "jobserver", + "libc", "shlex", ] @@ -839,9 +847,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.16" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" +checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" dependencies = [ "clap_builder", "clap_derive", @@ -849,9 +857,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.15" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" dependencies = [ "anstream", "anstyle", @@ -868,7 +876,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -1034,9 +1042,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] @@ -1148,7 +1156,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -1158,7 +1166,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" dependencies = [ "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -1184,7 +1192,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -1224,7 +1232,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -1235,7 +1243,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -1263,7 +1271,7 @@ dependencies = [ "prost", "prost-build", "rand 0.8.5", - "reqwest 0.12.5", + "reqwest 0.12.7", "rust-ini 0.21.1", "serde", "serde_json", @@ -1284,6 +1292,7 @@ dependencies = [ "tracing", "tracing-appender", "tracing-subscriber", + "vergen-git2", "webbrowser", "windows-service", "x25519-dalek", @@ -1291,8 +1300,8 @@ dependencies = [ [[package]] name = "defguard_wireguard_rs" -version = "0.4.6" -source = "git+https://github.com/DefGuard/wireguard-rs.git?rev=v0.4.6#6a325957fb6cc83f96dde730262a8b1b0efcedd6" +version = "0.4.7" +source = "git+https://github.com/DefGuard/wireguard-rs.git?rev=v0.4.7#ef1cf3714629bf5016fb38cbb7320451dc69fb09" dependencies = [ "base64 0.22.1", "libc", @@ -1348,7 +1357,38 @@ checksum = "d150dea618e920167e5973d70ae6ece4385b7164e0d799fe7c122dd0a5d912ad" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", +] + +[[package]] +name = "derive_builder" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd33f37ee6a119146a1781d3356a7c26028f83d779b2e04ecd45fdc75c76877b" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7431fa049613920234f22c47fdc33e6cf3ee83067091ea4277a3f8c4587aae38" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "derive_builder_macro" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4abae7035bf79b9877b779505d8cf3749285b80c43941eda66604841889451dc" +dependencies = [ + "derive_builder_core", + "syn 2.0.77", ] [[package]] @@ -1361,7 +1401,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -1569,7 +1609,7 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -1654,9 +1694,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fdeflate" @@ -1694,9 +1734,9 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.24" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf401df4a4e3872c4fe8151134cf483738e74b67fc934d6532c882b3d24a4550" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ "cfg-if", "libc", @@ -1712,12 +1752,21 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.31" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920" +checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" dependencies = [ "crc32fast", - "miniz_oxide", + "miniz_oxide 0.8.0", +] + +[[package]] +name = "fluent-uri" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17c704e9dbe1ddd863da1e6ff3567795087b1eb201ce80d8fa81162e1516500d" +dependencies = [ + "bitflags 1.3.2", ] [[package]] @@ -1764,7 +1813,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -1878,7 +1927,7 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" dependencies = [ - "fastrand 2.1.0", + "fastrand 2.1.1", "futures-core", "futures-io", "parking", @@ -1893,7 +1942,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -2075,11 +2124,23 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "getset" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e45727250e75cc04ff2846a66397da8ef2b3db8e40e0cef4df67950a07621eb9" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" [[package]] name = "gio" @@ -2111,6 +2172,19 @@ dependencies = [ "winapi", ] +[[package]] +name = "git2" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" +dependencies = [ + "bitflags 2.6.0", + "libc", + "libgit2-sys", + "log", + "url", +] + [[package]] name = "glib" version = "0.15.12" @@ -2164,9 +2238,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "globset" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" dependencies = [ "aho-corasick", "bstr", @@ -2253,7 +2327,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.4.0", + "indexmap 2.5.0", "slab", "tokio", "tokio-util", @@ -2262,9 +2336,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" dependencies = [ "atomic-waker", "bytes", @@ -2272,7 +2346,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.1.0", - "indexmap 2.4.0", + "indexmap 2.5.0", "slab", "tokio", "tokio-util", @@ -2497,7 +2571,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.5", + "h2 0.4.6", "http 1.1.0", "http-body 1.0.1", "httparse", @@ -2511,9 +2585,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.2" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", "http 1.1.0", @@ -2639,9 +2713,9 @@ dependencies = [ [[package]] name = "ignore" -version = "0.4.22" +version = "0.4.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" +checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" dependencies = [ "crossbeam-deque", "globset", @@ -2691,24 +2765,15 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown 0.14.5", "serde", ] -[[package]] -name = "infer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f178e61cdbfe084aa75a2f4f7a25a5bb09701a47ae1753608f194b15783c937a" -dependencies = [ - "cfb", -] - [[package]] name = "infer" version = "0.13.0" @@ -2760,9 +2825,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" [[package]] name = "is_terminal_polyfill" @@ -2850,6 +2915,15 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + [[package]] name = "jpeg-decoder" version = "0.3.1" @@ -2867,15 +2941,27 @@ dependencies = [ [[package]] name = "json-patch" -version = "1.4.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec9ad60d674508f3ca8f380a928cfe7b096bc729c4e2dbfe3852bc45da3ab30b" +checksum = "5b1fb8864823fad91877e6caea0baca82e49e8db50f8e5c9f9a453e27d3330fc" dependencies = [ + "jsonptr", "serde", "serde_json", "thiserror", ] +[[package]] +name = "jsonptr" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c6e529149475ca0b2820835d3dce8fcc41c6b943ca608d32f35b449255e4627" +dependencies = [ + "fluent-uri", + "serde", + "serde_json", +] + [[package]] name = "kqueue" version = "1.0.8" @@ -2948,6 +3034,18 @@ version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +[[package]] +name = "libgit2-sys" +version = "0.17.0+1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10472326a8a6477c3c20a64547b0059e4b0d086869eee31e6d7da728a8eb7224" +dependencies = [ + "cc", + "libc", + "libz-sys", + "pkg-config", +] + [[package]] name = "libloading" version = "0.7.4" @@ -2982,7 +3080,7 @@ checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ "bitflags 2.6.0", "libc", - "redox_syscall 0.5.3", + "redox_syscall", ] [[package]] @@ -2996,6 +3094,18 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "libz-sys" +version = "1.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-raw-sys" version = "0.3.8" @@ -3010,9 +3120,9 @@ checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "local-ip-address" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136ef34e18462b17bf39a7826f8f3bbc223341f8e83822beb8b77db9a3d49696" +checksum = "b435d7dd476416a905f9634dff8c330cee8d3168fdd1fbd472a17d1a75c00c3e" dependencies = [ "libc", "neli", @@ -3160,6 +3270,15 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + [[package]] name = "mio" version = "0.8.11" @@ -3657,9 +3776,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.3" +version = "0.36.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" +checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" dependencies = [ "memchr", ] @@ -3693,7 +3812,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -3704,9 +3823,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.3.1+3.3.1" +version = "300.3.2+3.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7259953d42a81bf137fbbd73bd30a8e1914d6dce43c2b90ed575783a22608b91" +checksum = "a211a18d945ef7e648cc6e0058f4c548ee46aab922ea203e0d30e966ea23647b" dependencies = [ "cc", ] @@ -3803,9 +3922,9 @@ dependencies = [ [[package]] name = "parking" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" @@ -3825,7 +3944,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.3", + "redox_syscall", "smallvec", "windows-targets 0.52.6", ] @@ -3858,7 +3977,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.4.0", + "indexmap 2.5.0", ] [[package]] @@ -3965,7 +4084,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -4012,7 +4131,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -4034,7 +4153,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" dependencies = [ "atomic-waker", - "fastrand 2.1.0", + "fastrand 2.1.1", "futures-io", ] @@ -4072,7 +4191,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016" dependencies = [ "base64 0.22.1", - "indexmap 2.4.0", + "indexmap 2.5.0", "quick-xml 0.32.0", "serde", "time", @@ -4088,7 +4207,7 @@ dependencies = [ "crc32fast", "fdeflate", "flate2", - "miniz_oxide", + "miniz_oxide 0.7.4", ] [[package]] @@ -4117,7 +4236,7 @@ dependencies = [ "concurrent-queue", "hermit-abi 0.4.0", "pin-project-lite", - "rustix 0.38.34", + "rustix 0.38.36", "tracing", "windows-sys 0.59.0", ] @@ -4145,12 +4264,12 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "prettyplease" -version = "0.2.20" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" +checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" dependencies = [ "proc-macro2", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -4165,11 +4284,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_edit 0.21.1", + "toml_edit 0.22.20", ] [[package]] @@ -4213,9 +4332,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13db3d3fde688c61e2446b4d843bc27a7e8af269a69440c0308021dc92333cc" +checksum = "3b2ecbe40f08db5c006b5764a2645f7f3f141ce756412ac9e1dd6087e6d32995" dependencies = [ "bytes", "prost-derive", @@ -4223,9 +4342,9 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb182580f71dd070f88d01ce3de9f4da5021db7115d2e1c3605a754153b77c1" +checksum = "f8650aabb6c35b860610e9cff5dc1af886c9e25073b7b1712a68972af4281302" dependencies = [ "bytes", "heck 0.5.0", @@ -4238,28 +4357,28 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.75", + "syn 2.0.77", "tempfile", ] [[package]] name = "prost-derive" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18bec9b0adc4eba778b33684b7ba3e7137789434769ee3ce3930463ef904cfca" +checksum = "acf0c195eebb4af52c752bec4f52f645da98b6e92077a04110c7f349477ae5ac" dependencies = [ "anyhow", "itertools", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] name = "prost-types" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee5168b05f49d4b0ca581206eb14a7b22fafd963efe729ac48eb03266e25cc2" +checksum = "60caa6738c7369b940c3d49246a8d1749323674c65cb13010134f5c9bad5b519" dependencies = [ "prost", ] @@ -4295,18 +4414,18 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.34.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f24d770aeca0eacb81ac29dfbc55ebcc09312fdd1f8bbecdc7e4a84e000e3b4" +checksum = "96a05e2e8efddfa51a84ca47cec303fac86c8541b686d37cac5efc0e094417bc" dependencies = [ "memchr", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -4404,15 +4523,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.5.3" @@ -4424,9 +4534,9 @@ dependencies = [ [[package]] name = "redox_users" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom 0.2.15", "libredox", @@ -4515,7 +4625,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "sync_wrapper 0.1.2", - "system-configuration", + "system-configuration 0.5.1", "tokio", "tokio-native-tls", "tokio-util", @@ -4530,16 +4640,16 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.5" +version = "0.12.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" +checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63" dependencies = [ "base64 0.22.1", "bytes", "encoding_rs", "futures-core", "futures-util", - "h2 0.4.5", + "h2 0.4.6", "http 1.1.0", "http-body 1.0.1", "http-body-util", @@ -4560,7 +4670,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "sync_wrapper 1.0.1", - "system-configuration", + "system-configuration 0.6.1", "tokio", "tokio-native-tls", "tower-service", @@ -4568,7 +4678,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg 0.52.0", + "windows-registry", ] [[package]] @@ -4612,9 +4722,9 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.7.44" +version = "0.7.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" +checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" dependencies = [ "bitvec", "bytecheck", @@ -4630,9 +4740,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.7.44" +version = "0.7.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" +checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" dependencies = [ "proc-macro2", "quote", @@ -4682,9 +4792,9 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.35.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" +checksum = "b082d80e3e3cc52b2ed634388d436fe1f4de6af5786cc2de9ba9737527bdf555" dependencies = [ "arrayvec", "borsh", @@ -4704,9 +4814,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] @@ -4727,9 +4837,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "3f55e80d50763938498dd5ebb18647174e0c76dc38c5505294bb224624f30f36" dependencies = [ "bitflags 2.6.0", "errno", @@ -4778,9 +4888,9 @@ checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" [[package]] name = "rustls-webpki" -version = "0.102.6" +version = "0.102.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" +checksum = "84678086bd54edf2b415183ed7a94d0efb049f1b646a33e22a36f3794be6ae56" dependencies = [ "ring", "rustls-pki-types", @@ -4810,11 +4920,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4889,31 +4999,31 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.208" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.208" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] name = "serde_json" -version = "1.0.125" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.5.0", "itoa 1.0.11", "memchr", "ryu", @@ -4928,7 +5038,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -4962,7 +5072,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.4.0", + "indexmap 2.5.0", "serde", "serde_derive", "serde_json", @@ -4979,14 +5089,14 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] name = "serialize-to-javascript" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9823f2d3b6a81d98228151fdeaf848206a7855a7a042bbf9bf870449a66cafb" +checksum = "04f3666a07a197cdb77cdf306c32be9b7f598d7060d50cfd4d5aa04bfd92f6c5" dependencies = [ "serde", "serde_json", @@ -4995,13 +5105,13 @@ dependencies = [ [[package]] name = "serialize-to-javascript-impl" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74064874e9f6a15f04c1f3cb627902d0e6b410abbf36668afa873c61889f1763" +checksum = "772ee033c0916d670af7860b6e1ef7d658a4629a6d0b4c8c3e67f09b3765b75d" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.77", ] [[package]] @@ -5172,9 +5282,9 @@ dependencies = [ [[package]] name = "sqlformat" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f895e3734318cc55f1fe66258926c9b910c124d47520339efecbb6c59cec7c1f" +checksum = "7bba3a93db0cc4f7bdece8bb09e77e2e785c20bfebf79eb8340ed80708048790" dependencies = [ "nom", "unicode_categories", @@ -5215,7 +5325,7 @@ dependencies = [ "futures-util", "hashlink", "hex", - "indexmap 2.4.0", + "indexmap 2.5.0", "log", "memchr", "once_cell", @@ -5463,7 +5573,7 @@ checksum = "f14a349c27ebe59faba22f933c9c734d428da7231e88a247e9d8c61eea964ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -5485,7 +5595,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -5507,9 +5617,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.75" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -5525,7 +5635,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -5539,6 +5649,9 @@ name = "sync_wrapper" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +dependencies = [ + "futures-core", +] [[package]] name = "system-configuration" @@ -5548,7 +5661,18 @@ checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", "core-foundation", - "system-configuration-sys", + "system-configuration-sys 0.5.0", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "system-configuration-sys 0.6.0", ] [[package]] @@ -5561,6 +5685,16 @@ dependencies = [ "libc", ] +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "system-deps" version = "5.0.0" @@ -5589,9 +5723,9 @@ dependencies = [ [[package]] name = "tao" -version = "0.16.9" +version = "0.16.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "575c856fc21e551074869dcfaad8f706412bd5b803dfa0fbf6881c4ff4bfafab" +checksum = "48d298c441a1da46e28e8ad8ec205aab7fd8cd71b9d10e05454224eef422e1ae" dependencies = [ "bitflags 1.3.2", "cairo-rs", @@ -5638,13 +5772,13 @@ dependencies = [ [[package]] name = "tao-macros" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec114582505d158b669b136e6851f85840c109819d77c42bb7c0709f727d18c2" +checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.77", ] [[package]] @@ -5672,9 +5806,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tauri" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "336bc661a3f3250853fa83c6e5245449ed1c26dce5dcb28bdee7efedf6278806" +checksum = "0e33e3ba00a3b05eb6c57ef135781717d33728b48acf914bb05629e74d897d29" dependencies = [ "anyhow", "bytes", @@ -5693,7 +5827,7 @@ dependencies = [ "http 0.2.12", "ignore", "indexmap 1.9.3", - "infer 0.9.0", + "infer", "objc", "once_cell", "percent-encoding", @@ -5725,9 +5859,9 @@ dependencies = [ [[package]] name = "tauri-build" -version = "1.5.3" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c6ec7a5c3296330c7818478948b422967ce4649094696c985f61d50076d29c" +checksum = "d5fb5a90a64241ddb7217d3210d844149070a911e87e8a107a707a1d4973f164" dependencies = [ "anyhow", "cargo_toml", @@ -5744,9 +5878,9 @@ dependencies = [ [[package]] name = "tauri-codegen" -version = "1.4.4" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1aed706708ff1200ec12de9cfbf2582b5d8ec05f6a7293911091effbd22036b" +checksum = "93a9e3f5cebf779a63bf24903e714ec91196c307d8249a0008b882424328bcda" dependencies = [ "base64 0.21.7", "brotli", @@ -5769,9 +5903,9 @@ dependencies = [ [[package]] name = "tauri-macros" -version = "1.4.5" +version = "1.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b88f831d2973ae4f81a706a0004e67dac87f2e4439973bbe98efbd73825d8ede" +checksum = "d1d0e989f54fe06c5ef0875c5e19cf96453d099a0a774d5192ab47e80471cdab" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -5784,7 +5918,7 @@ dependencies = [ [[package]] name = "tauri-plugin-log" version = "0.0.0" -source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v1#677bade9089f2963e5858cc5062e5504787eaf7f" +source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v1#077b3d44fb0c1b1377193dd93125ecf7c4ea04e4" dependencies = [ "byte-unit", "fern", @@ -5799,21 +5933,21 @@ dependencies = [ [[package]] name = "tauri-plugin-single-instance" version = "0.0.0" -source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v1#677bade9089f2963e5858cc5062e5504787eaf7f" +source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v1#077b3d44fb0c1b1377193dd93125ecf7c4ea04e4" dependencies = [ "log", "serde", "serde_json", "tauri", "thiserror", - "windows-sys 0.52.0", + "windows-sys 0.59.0", "zbus 3.15.2", ] [[package]] name = "tauri-plugin-window-state" version = "0.1.1" -source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v1#677bade9089f2963e5858cc5062e5504787eaf7f" +source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v1#077b3d44fb0c1b1377193dd93125ecf7c4ea04e4" dependencies = [ "bincode", "bitflags 2.6.0", @@ -5826,9 +5960,9 @@ dependencies = [ [[package]] name = "tauri-runtime" -version = "0.14.4" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3068ed62b63dedc705558f4248c7ecbd5561f0f8050949859ea0db2326f26012" +checksum = "f33fda7d213e239077fad52e96c6b734cecedb30c2382118b64f94cb5103ff3a" dependencies = [ "gtk", "http 0.2.12", @@ -5847,9 +5981,9 @@ dependencies = [ [[package]] name = "tauri-runtime-wry" -version = "0.14.9" +version = "0.14.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c3db170233096aa30330feadcd895bf9317be97e624458560a20e814db7955" +checksum = "18c447dcd9b0f09c7dc4b752cc33e72788805bfd761fbda5692d30c48289efec" dependencies = [ "arboard", "cocoa", @@ -5868,9 +6002,9 @@ dependencies = [ [[package]] name = "tauri-utils" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2826db448309d382dac14d520f0c0a40839b87b57b977e59cf5f296b3ace6a93" +checksum = "83a0c939e88d82903a0a7dfb28388b12a3c03504d6bd6086550edaa3b6d8beaa" dependencies = [ "brotli", "ctor", @@ -5878,7 +6012,7 @@ dependencies = [ "glob", "heck 0.5.0", "html5ever", - "infer 0.13.0", + "infer", "json-patch", "kuchikiki", "log", @@ -5913,9 +6047,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" dependencies = [ "cfg-if", - "fastrand 2.1.0", + "fastrand 2.1.1", "once_cell", - "rustix 0.38.34", + "rustix 0.38.36", "windows-sys 0.59.0", ] @@ -5953,7 +6087,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -6036,9 +6170,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.39.3" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", "bytes", @@ -6060,7 +6194,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -6086,9 +6220,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" dependencies = [ "futures-core", "pin-project-lite", @@ -6097,9 +6231,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", @@ -6156,31 +6290,20 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.5.0", "serde", "serde_spanned", "toml_datetime", "winnow 0.5.40", ] -[[package]] -name = "toml_edit" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" -dependencies = [ - "indexmap 2.4.0", - "toml_datetime", - "winnow 0.5.40", -] - [[package]] name = "toml_edit" version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.5.0", "serde", "serde_spanned", "toml_datetime", @@ -6189,16 +6312,16 @@ dependencies = [ [[package]] name = "tonic" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38659f4a91aba8598d27821589f5db7dddd94601e7a01b1e485a50e5484c7401" +checksum = "c6f6ba989e4b2c58ae83d862d3a3e27690b6e3ae630d0deb59f3697f32aa88ad" dependencies = [ "async-stream", "async-trait", "axum", "base64 0.22.1", "bytes", - "h2 0.4.5", + "h2 0.4.6", "http 1.1.0", "http-body 1.0.1", "http-body-util", @@ -6219,15 +6342,15 @@ dependencies = [ [[package]] name = "tonic-build" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "568392c5a2bd0020723e3f387891176aabafe36fd9fcd074ad309dfa0c8eb964" +checksum = "fe4ee8877250136bd7e3d2331632810a4df4ea5e004656990d8d66d2f5ee8a67" dependencies = [ "prettyplease", "proc-macro2", "prost-build", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -6294,7 +6417,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -6415,9 +6538,9 @@ dependencies = [ [[package]] name = "unicode-properties" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" +checksum = "52ea75f83c0137a9b98608359a5f1af8144876eb67bcb1ce837368e906a9f524" [[package]] name = "unicode-segmentation" @@ -6500,6 +6623,46 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "vergen" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c32e7318e93a9ac53693b6caccfb05ff22e04a44c7cf8a279051f24c09da286f" +dependencies = [ + "anyhow", + "derive_builder", + "rustversion", + "time", + "vergen-lib", +] + +[[package]] +name = "vergen-git2" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62c52cd2b2b8b7ec75fc20111b3022ac3ff83e4fc14b9497cfcfd39c54f9c67" +dependencies = [ + "anyhow", + "derive_builder", + "git2", + "rustversion", + "time", + "vergen", + "vergen-lib", +] + +[[package]] +name = "vergen-lib" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e06bee42361e43b60f363bad49d63798d0f42fb1768091812270eca00c784720" +dependencies = [ + "anyhow", + "derive_builder", + "getset", + "rustversion", +] + [[package]] name = "version-compare" version = "0.0.11" @@ -6603,7 +6766,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", "wasm-bindgen-shared", ] @@ -6637,7 +6800,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6663,13 +6826,13 @@ dependencies = [ [[package]] name = "wayland-backend" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90e11ce2ca99c97b940ee83edbae9da2d56a08f9ea8158550fd77fa31722993" +checksum = "056535ced7a150d45159d3a8dc30f91a2e2d588ca0b23f70e56033622b8016f6" dependencies = [ "cc", "downcast-rs", - "rustix 0.38.34", + "rustix 0.38.36", "scoped-tls", "smallvec", "wayland-sys", @@ -6677,12 +6840,12 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.5" +version = "0.31.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e321577a0a165911bdcfb39cf029302479d7527b517ee58ab0f6ad09edf0943" +checksum = "e3f45d1222915ef1fd2057220c1d9d9624b7654443ea35c3877f7a52bd0a5a2d" dependencies = [ "bitflags 2.6.0", - "rustix 0.38.34", + "rustix 0.38.36", "wayland-backend", "wayland-scanner", ] @@ -6714,20 +6877,20 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.31.4" +version = "0.31.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7b56f89937f1cf2ee1f1259cf2936a17a1f45d8f0aa1019fae6d470d304cfa6" +checksum = "597f2001b2e5fc1121e3d5b9791d3e78f05ba6bfa4641053846248e3a13661c3" dependencies = [ "proc-macro2", - "quick-xml 0.34.0", + "quick-xml 0.36.1", "quote", ] [[package]] name = "wayland-sys" -version = "0.31.4" +version = "0.31.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43676fe2daf68754ecf1d72026e4e6c15483198b5d24e888b74d3f22f887a148" +checksum = "efa8ac0d8e8ed3e3b5c9fc92c7881406a268e11555abe36493efabe649a29e09" dependencies = [ "dlib", "log", @@ -6855,11 +7018,11 @@ checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" [[package]] name = "whoami" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" +checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d" dependencies = [ - "redox_syscall 0.4.1", + "redox_syscall", "wasite", ] @@ -6971,6 +7134,26 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ee5e275231f07c6e240d14f34e1b635bf1faa1c76c57cfd59a5cdb9848e4278" +[[package]] +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-service" version = "0.7.0" @@ -6982,6 +7165,16 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -7340,9 +7533,9 @@ dependencies = [ [[package]] name = "wry" -version = "0.24.10" +version = "0.24.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00711278ed357350d44c749c286786ecac644e044e4da410d466212152383b45" +checksum = "c55c80b12287eb1ff7c365fc2f7a5037cb6181bd44c9fce81c8d1cf7605ffad6" dependencies = [ "base64 0.13.1", "block", @@ -7413,7 +7606,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" dependencies = [ "gethostname", - "rustix 0.38.34", + "rustix 0.38.36", "x11rb-protocol", ] @@ -7443,7 +7636,7 @@ checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" dependencies = [ "libc", "linux-raw-sys 0.4.14", - "rustix 0.38.34", + "rustix 0.38.36", ] [[package]] @@ -7555,10 +7748,10 @@ version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", "zvariant_utils 2.1.0", ] @@ -7602,7 +7795,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -7622,7 +7815,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -7671,10 +7864,10 @@ version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", "zvariant_utils 2.1.0", ] @@ -7697,5 +7890,5 @@ checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index f6bbf6d7..953fce51 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -14,6 +14,7 @@ authors = ["Defguard"] tauri-build = { version = "1.5", features = [] } tonic-build = { version = "0.12" } prost-build = { version = "0.13" } +vergen-git2 = { version = "1.0", features = ["build"] } [dependencies] anyhow = "1.0" @@ -21,7 +22,7 @@ base64 = "0.22" clap = { version = "4.5", features = ["derive", "env"] } chrono = { version = "0.4", features = ["serde"] } dark-light = "1.1" -defguard_wireguard_rs = { git = "https://github.com/DefGuard/wireguard-rs.git", rev = "v0.4.6" } +defguard_wireguard_rs = { git = "https://github.com/DefGuard/wireguard-rs.git", rev = "v0.4.7" } dirs = "5.0" lazy_static = "1.5" local-ip-address = "0.6" diff --git a/src-tauri/build.rs b/src-tauri/build.rs index 36881822..bcb19fb1 100644 --- a/src-tauri/build.rs +++ b/src-tauri/build.rs @@ -1,4 +1,10 @@ +use vergen_git2::{Emitter, Git2Builder}; + fn main() -> Result<(), Box> { + // set VERGEN_GIT_SHA env variable based on git commit hash + let git2 = Git2Builder::default().branch(true).sha(true).build()?; + Emitter::default().add_instructions(&git2)?.emit()?; + // compiling protos using path on build time let mut config = prost_build::Config::new(); // enable optional fields diff --git a/src-tauri/src/appstate.rs b/src-tauri/src/appstate.rs index e713690f..eaee36b4 100644 --- a/src-tauri/src/appstate.rs +++ b/src-tauri/src/appstate.rs @@ -133,12 +133,11 @@ impl AppState { &self, instance: &Instance, ) -> Result, crate::error::Error> { - let locations: HashSet = HashSet::from_iter( - Location::find_by_instance_id(&self.get_pool(), instance.id) - .await? - .iter() - .map(|location| location.id), - ); + let locations: HashSet = Location::find_by_instance_id(&self.get_pool(), instance.id) + .await? + .iter() + .map(|location| location.id) + .collect(); Ok(self .active_connections .lock() diff --git a/src-tauri/src/bin/defguard-client.rs b/src-tauri/src/bin/defguard-client.rs index 65f47559..66229d3e 100644 --- a/src-tauri/src/bin/defguard-client.rs +++ b/src-tauri/src/bin/defguard-client.rs @@ -31,6 +31,7 @@ use defguard_client::{ periodic::{config::poll_config, version::poll_version}, tray::{configure_tray_icon, handle_tray_event, reload_tray_menu}, utils::load_log_targets, + VERSION, }; use std::{env, str::FromStr}; @@ -142,6 +143,7 @@ async fn main() { .build(tauri::generate_context!()) .expect("error while running tauri application"); + info!("Starting ... version v{}", VERSION); // initialize database let app_handle = app.handle(); debug!("Initializing database connection"); diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index 90a5aaea..77b3e307 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -163,50 +163,79 @@ pub async fn save_device_config( app_state: State<'_, AppState>, handle: AppHandle, ) -> Result { - debug!("Received device configuration: {response:#?}."); + debug!("Saving device configuration: {response:#?}."); let mut transaction = app_state.get_pool().begin().await?; let instance_info = response .instance .expect("Missing instance info in device config response"); let mut instance: Instance = instance_info.into(); + if response.token.is_some() { + info!("Received polling token for instance {}", instance.name); + } else { + warn!( + "Missing polling token for instance {}, core and/or proxy services may need an update, configuration polling won't work", + instance.name, + ); + } instance.token = response.token; + debug!("Saving instance {}", instance.name); let instance = instance.save(&mut *transaction).await?; + info!("Saved instance {}", instance.name); let device = response .device .expect("Missing device info in device config response"); - let mut keys = WireguardKeys::new(instance.id, device.pubkey, private_key); - keys.save(&mut *transaction).await?; + let keys = WireguardKeys::new(instance.id, device.pubkey, private_key); + debug!( + "Saving wireguard key {} for instance {}({})", + keys.pubkey, instance.name, instance.id + ); + let keys = keys.save(&mut *transaction).await?; + info!( + "Saved wireguard key {} for instance {}({})", + keys.pubkey, instance.name, instance.id + ); for location in response.configs { let new_location = device_config_to_location(location, instance.id); - new_location.save(&mut *transaction).await?; + debug!( + "Saving location {} for instance {}({})", + new_location.name, instance.name, instance.id + ); + let new_location = new_location.save(&mut *transaction).await?; + info!( + "Saved location {} for instance {}({})", + new_location.name, instance.name, instance.id + ); } transaction.commit().await?; - info!("Instance created."); + info!("Instance {}({:?}) created.", instance.name, instance.id); trace!("Created following instance: {instance:#?}"); let locations = Location::find_by_instance_id(&app_state.get_pool(), instance.id).await?; trace!("Created following locations: {locations:#?}"); handle.emit_all(INSTANCE_UPDATE, ())?; + info!( + "Device configuration saved for instance {}({})", + instance.name, instance.id, + ); let res: SaveDeviceConfigResponse = SaveDeviceConfigResponse { locations, instance, }; - info!("Device configuration saved."); reload_tray_menu(&handle).await; Ok(res) } #[tauri::command(async)] -pub async fn all_instances(app_state: State<'_, AppState>) -> Result, Error> { +pub async fn all_instances(app_state: State<'_, AppState>) -> Result>, Error> { debug!("Retrieving all instances."); let instances = Instance::all(&app_state.get_pool()).await?; debug!("Found ({}) instances", instances.len()); trace!("Instances found: {instances:#?}"); - let mut instance_info: Vec = Vec::new(); - let connection_ids: Vec = app_state + let mut instance_info = Vec::new(); + let connection_ids = app_state .get_connection_id_by_type(&ConnectionType::Location) .await; for instance in instances { @@ -219,7 +248,7 @@ pub async fn all_instances(app_state: State<'_, AppState>) -> Result, app_state: State<'_, AppState>, -) -> Result, Error> { +) -> Result>, Error> { trace!("Location stats command received"); let from = parse_timestamp(from)?.naive_utc(); let aggregation = get_aggregation(from)?; - let stats: Vec = match connection_type { + let stats = match connection_type { ConnectionType::Location => LocationStats::all_by_location_id( &app_state.get_pool(), location_id, @@ -538,7 +567,7 @@ pub async fn last_connection( location_id: i64, connection_type: ConnectionType, app_state: State<'_, AppState>, -) -> Result, Error> { +) -> Result>, Error> { debug!("Retrieving last connection for location {location_id} with type {connection_type:?}"); if connection_type == ConnectionType::Location { if let Some(connection) = @@ -716,7 +745,7 @@ pub fn parse_tunnel_config(config: &str) -> Result { } #[tauri::command(async)] -pub async fn save_tunnel(mut tunnel: Tunnel, handle: AppHandle) -> Result<(), Error> { +pub async fn update_tunnel(mut tunnel: Tunnel, handle: AppHandle) -> Result<(), Error> { let app_state = handle.state::(); debug!("Received tunnel configuration: {tunnel:#?}"); tunnel.save(&app_state.get_pool()).await?; @@ -730,9 +759,24 @@ pub async fn save_tunnel(mut tunnel: Tunnel, handle: AppHandle) -> Result<(), Er Ok(()) } +#[tauri::command(async)] +pub async fn save_tunnel(tunnel: Tunnel, handle: AppHandle) -> Result<(), Error> { + let app_state = handle.state::(); + debug!("Received tunnel configuration: {tunnel:#?}"); + let tunnel = tunnel.save(&app_state.get_pool()).await?; + info!("Saved tunnel {tunnel:#?}"); + handle.emit_all( + LOCATION_UPDATE, + Payload { + message: "Tunnel saved".into(), + }, + )?; + Ok(()) +} + #[derive(Debug, Serialize, Deserialize)] -pub struct TunnelInfo { - pub id: Option, +pub struct TunnelInfo { + pub id: I, pub name: String, pub address: String, pub endpoint: String, @@ -742,7 +786,7 @@ pub struct TunnelInfo { } #[tauri::command(async)] -pub async fn all_tunnels(app_state: State<'_, AppState>) -> Result, Error> { +pub async fn all_tunnels(app_state: State<'_, AppState>) -> Result>, Error> { debug!("Retrieving all instances."); let tunnels = Tunnel::all(&app_state.get_pool()).await?; @@ -760,7 +804,7 @@ pub async fn all_tunnels(app_state: State<'_, AppState>) -> Result) -> Result, -) -> Result { +) -> Result, Error> { debug!("Retrieving Tunnel with ID {tunnel_id}."); if let Some(tunnel) = Tunnel::find_by_id(&app_state.get_pool(), tunnel_id).await? { diff --git a/src-tauri/src/database/models/connection.rs b/src-tauri/src/database/models/connection.rs index fc7251d5..ffa0d1a4 100644 --- a/src-tauri/src/database/models/connection.rs +++ b/src-tauri/src/database/models/connection.rs @@ -1,22 +1,25 @@ use chrono::{NaiveDateTime, Utc}; use serde::Serialize; -use sqlx::{query, query_as, FromRow}; +use sqlx::{query, query_as}; -use crate::{ - database::DbPool, error::Error, CommonConnection, CommonConnectionInfo, ConnectionType, -}; +use crate::{error::Error, CommonConnection, CommonConnectionInfo, ConnectionType}; -#[derive(FromRow, Debug, Serialize, Clone)] -pub struct Connection { - pub id: Option, +use super::{Id, NoId}; + +#[derive(Debug, Serialize, Clone)] +pub struct Connection { + pub id: I, pub location_id: i64, pub connected_from: String, pub start: NaiveDateTime, pub end: NaiveDateTime, } -impl Connection { - pub async fn save(&mut self, pool: &DbPool) -> Result<(), Error> { +impl Connection { + pub async fn save<'e, E>(self, executor: E) -> Result, Error> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { let result = query!( "INSERT INTO connection (location_id, connected_from, start, end) \ VALUES ($1, $2, $3, $4) RETURNING id;", @@ -25,28 +28,42 @@ impl Connection { self.start, self.end, ) - .fetch_one(pool) + .fetch_one(executor) .await?; - self.id = Some(result.id); - Ok(()) + Ok(Connection:: { + id: result.id, + location_id: self.location_id, + connected_from: self.connected_from, + start: self.start, + end: self.end, + }) } - pub async fn all_by_location_id(pool: &DbPool, location_id: i64) -> Result, Error> { + pub async fn all_by_location_id<'e, E>( + executor: E, + location_id: i64, + ) -> Result>, Error> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { let connections = query_as!( Connection, "SELECT id, location_id, connected_from, start, end \ FROM connection WHERE location_id = $1", location_id ) - .fetch_all(pool) + .fetch_all(executor) .await?; Ok(connections) } - pub async fn latest_by_location_id( - pool: &DbPool, + pub async fn latest_by_location_id<'e, E>( + executor: E, location_id: i64, - ) -> Result, Error> { + ) -> Result>, Error> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { let connection = query_as!( Connection, "SELECT id, location_id, connected_from, start, end \ @@ -54,14 +71,14 @@ impl Connection { ORDER BY end DESC LIMIT 1", location_id ) - .fetch_optional(pool) + .fetch_optional(executor) .await?; Ok(connection) } } /// Historical connection -#[derive(FromRow, Debug, Serialize)] +#[derive(Debug, Serialize)] pub struct ConnectionInfo { pub id: i64, pub location_id: i64, @@ -87,7 +104,13 @@ impl From for CommonConnectionInfo { } impl ConnectionInfo { - pub async fn all_by_location_id(pool: &DbPool, location_id: i64) -> Result, Error> { + pub async fn all_by_location_id<'e, E>( + executor: E, + location_id: i64, + ) -> Result, Error> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { // Because we store interface information for given timestamp select last upload and download // before connection ended // FIXME: Optimize query @@ -116,7 +139,7 @@ impl ConnectionInfo { ORDER BY start DESC", location_id ) - .fetch_all(pool) + .fetch_all(executor) .await?; Ok(connections) @@ -132,6 +155,7 @@ pub struct ActiveConnection { pub interface_name: String, pub connection_type: ConnectionType, } + impl ActiveConnection { #[must_use] pub fn new( @@ -151,10 +175,10 @@ impl ActiveConnection { } } -impl From<&ActiveConnection> for Connection { +impl From<&ActiveConnection> for Connection { fn from(active_connection: &ActiveConnection) -> Self { Connection { - id: None, + id: NoId, location_id: active_connection.location_id, connected_from: active_connection.connected_from.clone(), start: active_connection.start, @@ -163,8 +187,8 @@ impl From<&ActiveConnection> for Connection { } } -impl From for CommonConnection { - fn from(connection: Connection) -> Self { +impl From> for CommonConnection { + fn from(connection: Connection) -> Self { CommonConnection { id: connection.id, location_id: connection.location_id, diff --git a/src-tauri/src/database/models/instance.rs b/src-tauri/src/database/models/instance.rs index dcf449cf..0ed23f1b 100644 --- a/src-tauri/src/database/models/instance.rs +++ b/src-tauri/src/database/models/instance.rs @@ -1,10 +1,10 @@ -use crate::{database::DbPool, error::Error, proto}; use serde::{Deserialize, Serialize}; -use sqlx::{query, query_as, FromRow}; +use sqlx::{query, query_as}; use super::{Id, NoId}; +use crate::{error::Error, proto}; -#[derive(FromRow, Serialize, Deserialize, Debug)] +#[derive(Serialize, Deserialize, Debug)] pub struct Instance { pub id: I, pub name: String, @@ -55,48 +55,63 @@ impl Instance { Ok(()) } - pub async fn all(pool: &DbPool) -> Result, Error> { + pub async fn all<'e, E>(executor: E) -> Result, Error> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { let instances = query_as!( Self, "SELECT id \"id: _\", name, uuid, url, proxy_url, username, token \"token?\", disable_route_all_traffic FROM instance;" ) - .fetch_all(pool) + .fetch_all(executor) .await?; Ok(instances) } - pub async fn find_by_id(pool: &DbPool, id: i64) -> Result, Error> { + pub async fn find_by_id<'e, E>(executor: E, id: i64) -> Result, Error> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { let instance = query_as!( Self, "SELECT id \"id: _\", name, uuid, url, proxy_url, username, token \"token?\", disable_route_all_traffic FROM instance WHERE id = $1;", id ) - .fetch_optional(pool) + .fetch_optional(executor) .await?; Ok(instance) } - pub async fn find_by_uuid(pool: &DbPool, uuid: &str) -> Result, Error> { + pub async fn find_by_uuid<'e, E>(executor: E, uuid: &str) -> Result, Error> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { let instance = query_as!( Self, "SELECT id \"id: _\", name, uuid, url, proxy_url, username, token \"token?\", disable_route_all_traffic FROM instance WHERE uuid = $1;", uuid ) - .fetch_optional(pool) + .fetch_optional(executor) .await?; Ok(instance) } - pub async fn delete_by_id(pool: &DbPool, id: i64) -> Result<(), Error> { + pub async fn delete_by_id<'e, E>(executor: E, id: i64) -> Result<(), Error> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { // delete instance query!("DELETE FROM instance WHERE id = $1", id) - .execute(pool) + .execute(executor) .await?; Ok(()) } - pub async fn delete(&self, pool: &DbPool) -> Result<(), Error> { - Instance::delete_by_id(pool, self.id).await?; + pub async fn delete<'e, E>(&self, executor: E) -> Result<(), Error> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { + Instance::delete_by_id(executor, self.id).await?; Ok(()) } } @@ -126,8 +141,8 @@ impl Instance { where E: sqlx::Executor<'e, Database = sqlx::Sqlite>, { - let url = self.url.to_string(); - let proxy_url = self.proxy_url.to_string(); + let url = self.url.clone(); + let proxy_url = self.proxy_url.clone(); let result = query!( "INSERT INTO instance (name, uuid, url, proxy_url, username, token, disable_route_all_traffic) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING id;", self.name, @@ -153,9 +168,9 @@ impl Instance { } } -#[derive(FromRow, Debug, Serialize, Deserialize)] -pub struct InstanceInfo { - pub id: Option, +#[derive(Debug, Serialize, Deserialize)] +pub struct InstanceInfo { + pub id: I, pub name: String, pub uuid: String, pub url: String, diff --git a/src-tauri/src/database/models/location.rs b/src-tauri/src/database/models/location.rs index 1b6061a8..c8cb45ef 100644 --- a/src-tauri/src/database/models/location.rs +++ b/src-tauri/src/database/models/location.rs @@ -1,12 +1,12 @@ -use sqlx::{query, query_as, Error as SqlxError, FromRow}; +use sqlx::{query, query_as, Error as SqlxError}; use std::fmt::{Display, Formatter}; -use crate::{database::DbPool, error::Error}; +use crate::error::Error; use serde::{Deserialize, Serialize}; use super::{Id, NoId}; -#[derive(FromRow, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] pub struct Location { pub id: I, pub instance_id: i64, @@ -36,14 +36,17 @@ impl Display for Location { } impl Location { - pub async fn all(pool: &DbPool) -> Result, Error> { + pub async fn all<'e, E>(executor: E) -> Result, Error> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { let locations = query_as!( Self, "SELECT id \"id: _\", instance_id, name, address, pubkey, endpoint, allowed_ips, dns, network_id,\ route_all_traffic, mfa_enabled, keepalive_interval \ FROM location;" ) - .fetch_all(pool) + .fetch_all(executor) .await?; Ok(locations) } @@ -75,7 +78,10 @@ impl Location { Ok(()) } - pub async fn find_by_id(pool: &DbPool, location_id: i64) -> Result, SqlxError> { + pub async fn find_by_id<'e, E>(executor: E, location_id: i64) -> Result, SqlxError> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { query_as!( Self, "SELECT id \"id: _\", instance_id, name, address, pubkey, endpoint, allowed_ips, dns, network_id, \ @@ -83,14 +89,17 @@ impl Location { FROM location WHERE id = $1;", location_id ) - .fetch_optional(pool) + .fetch_optional(executor) .await } - pub async fn find_by_instance_id( - pool: &DbPool, + pub async fn find_by_instance_id<'e, E>( + executor: E, instance_id: i64, - ) -> Result, SqlxError> { + ) -> Result, SqlxError> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { query_as!( Self, "SELECT id \"id: _\", instance_id, name, address, pubkey, endpoint, allowed_ips, dns, network_id, \ @@ -98,11 +107,14 @@ impl Location { FROM location WHERE instance_id = $1;", instance_id ) - .fetch_all(pool) + .fetch_all(executor) .await } - pub async fn find_by_public_key(pool: &DbPool, pubkey: &str) -> Result { + pub async fn find_by_public_key<'e, E>(executor: E, pubkey: &str) -> Result + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { query_as!( Self, "SELECT id \"id: _\", instance_id, name, address, pubkey, endpoint, allowed_ips, dns, network_id, \ @@ -110,7 +122,7 @@ impl Location { FROM location WHERE pubkey = $1;", pubkey ) - .fetch_one(pool) + .fetch_one(executor) .await } diff --git a/src-tauri/src/database/models/location_stats.rs b/src-tauri/src/database/models/location_stats.rs index b988a9dc..978b3135 100644 --- a/src-tauri/src/database/models/location_stats.rs +++ b/src-tauri/src/database/models/location_stats.rs @@ -1,19 +1,19 @@ -use chrono::{NaiveDateTime, Utc}; -use sqlx::{query, query_as, FromRow}; use std::time::SystemTime; -use crate::{ - commands::DateTimeAggregation, - database::{DbPool, Location}, - error::Error, - CommonLocationStats, ConnectionType, -}; +use chrono::{NaiveDateTime, Utc}; use defguard_wireguard_rs::host::Peer; use serde::{Deserialize, Serialize}; +use sqlx::{query, query_as}; -#[derive(FromRow, Debug, Serialize, Deserialize)] -pub struct LocationStats { - id: Option, +use super::{Id, NoId}; +use crate::{ + commands::DateTimeAggregation, database::Location, error::Error, CommonLocationStats, + ConnectionType, +}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct LocationStats { + id: I, location_id: i64, upload: i64, download: i64, @@ -23,8 +23,8 @@ pub struct LocationStats { persistent_keepalive_interval: Option, } -impl From for CommonLocationStats { - fn from(location_stats: LocationStats) -> Self { +impl From> for CommonLocationStats { + fn from(location_stats: LocationStats) -> Self { CommonLocationStats { id: location_stats.id, location_id: location_stats.location_id, @@ -39,14 +39,17 @@ impl From for CommonLocationStats { } } -pub async fn peer_to_location_stats( +pub async fn peer_to_location_stats<'e, E>( peer: &Peer, listen_port: u32, - pool: &DbPool, -) -> Result { - let location = Location::find_by_public_key(pool, &peer.public_key.to_string()).await?; + executor: E, +) -> Result, Error> +where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, +{ + let location = Location::find_by_public_key(executor, &peer.public_key.to_string()).await?; Ok(LocationStats { - id: None, + id: NoId, location_id: location.id, upload: peer.tx_bytes as i64, download: peer.rx_bytes as i64, @@ -60,7 +63,7 @@ pub async fn peer_to_location_stats( }) } -impl LocationStats { +impl LocationStats { #[must_use] pub fn new( location_id: i64, @@ -72,7 +75,7 @@ impl LocationStats { persistent_keepalive_interval: Option, ) -> Self { LocationStats { - id: None, + id: NoId, location_id, upload, download, @@ -83,7 +86,10 @@ impl LocationStats { } } - pub async fn save(&mut self, pool: &DbPool) -> Result<(), Error> { + pub async fn save<'e, E>(self, executor: E) -> Result, Error> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { let result = query!( "INSERT INTO location_stats (location_id, upload, download, last_handshake, collected_at, listen_port, persistent_keepalive_interval) \ VALUES ($1, $2, $3, $4, $5, $6, $7) \ @@ -96,18 +102,32 @@ impl LocationStats { self.listen_port, self.persistent_keepalive_interval, ) - .fetch_one(pool) + .fetch_one(executor) .await?; - self.id = Some(result.id); - Ok(()) + + Ok(LocationStats:: { + id: result.id, + location_id: self.location_id, + upload: self.upload, + download: self.download, + last_handshake: self.last_handshake, + collected_at: self.collected_at, + listen_port: self.listen_port, + persistent_keepalive_interval: self.persistent_keepalive_interval, + }) } +} - pub async fn all_by_location_id( - pool: &DbPool, +impl LocationStats { + pub async fn all_by_location_id<'e, E>( + executor: E, location_id: i64, from: &NaiveDateTime, aggregation: &DateTimeAggregation, - ) -> Result, Error> { + ) -> Result, Error> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { let aggregation = aggregation.fstring(); let stats = query_as!( LocationStats, @@ -136,7 +156,7 @@ impl LocationStats { location_id, from ) - .fetch_all(pool) + .fetch_all(executor) .await?; Ok(stats) } diff --git a/src-tauri/src/database/models/mod.rs b/src-tauri/src/database/models/mod.rs index b2cf1f57..ce39cc48 100644 --- a/src-tauri/src/database/models/mod.rs +++ b/src-tauri/src/database/models/mod.rs @@ -1,3 +1,5 @@ +use serde::{Deserialize, Serialize}; + pub mod connection; pub mod instance; pub mod location; @@ -8,5 +10,5 @@ pub mod wireguard_keys; // Typestate structs to make working with optional ids easier pub type Id = i64; -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)] pub struct NoId; diff --git a/src-tauri/src/database/models/settings.rs b/src-tauri/src/database/models/settings.rs index 442deb0a..3510a225 100644 --- a/src-tauri/src/database/models/settings.rs +++ b/src-tauri/src/database/models/settings.rs @@ -1,7 +1,7 @@ use std::str::FromStr; use serde::{Deserialize, Serialize}; -use sqlx::{query, FromRow, Type}; +use sqlx::{query, Type}; use struct_patch::Patch; use strum::{AsRefStr, EnumString}; use tracing::Level; @@ -59,7 +59,7 @@ pub enum ClientView { Detail, } -#[derive(FromRow, Debug, Serialize, Deserialize, Patch)] +#[derive(Debug, Serialize, Deserialize, Patch)] #[patch_derive(Debug, Serialize, Deserialize)] pub struct Settings { #[serde(skip)] @@ -71,10 +71,26 @@ pub struct Settings { pub selected_view: Option, } +impl Default for Settings { + fn default() -> Self { + Self { + id: None, + log_level: SettingsLogLevel::Info, + theme: SettingsTheme::Light, + tray_icon_theme: TrayIconTheme::Color, + check_for_updates: true, + selected_view: None, + } + } +} + impl Settings { - pub async fn get(pool: &DbPool) -> Result { + pub async fn get<'e, E>(executor: E) -> Result + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { let query_res = query!("SELECT * FROM settings WHERE id = 1;") - .fetch_one(pool) + .fetch_one(executor) .await?; let settings = Self { id: Some(query_res.id), @@ -90,7 +106,10 @@ impl Settings { Ok(settings) } - pub async fn save(&mut self, pool: &DbPool) -> Result<(), Error> { + pub async fn save<'e, E>(&mut self, executor: E) -> Result<(), Error> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { query!( "UPDATE settings \ SET theme = $1, log_level = $2, tray_icon_theme = $3, check_for_updates = $4, selected_view = $5 \ @@ -101,39 +120,37 @@ impl Settings { self.check_for_updates, self.selected_view ) - .execute(pool) + .execute(executor) .await?; Ok(()) } - // checks if settings is empty and insert default settings if they not exist, this should be called before app start + /// Checks if settings are empty and inserts default settings if they do not exist. This should be called before app starts. pub async fn init_defaults(pool: &DbPool) -> Result<(), Error> { let current_config = query!("SELECT * FROM settings WHERE id = 1;") .fetch_optional(pool) .await?; if current_config.is_none() { - debug!("No settings found on app init."); - let mut init_theme = SettingsTheme::Light; + debug!("No settings found on app init, inserting defaults."); // check what system theme is currently in use and default to it. - if dark_light::detect() == dark_light::Mode::Dark { - debug!("Detected system theme dark, init theme ajusted."); - init_theme = SettingsTheme::Dark; + let theme = match dark_light::detect() { + dark_light::Mode::Default | dark_light::Mode::Light => SettingsTheme::Light, + dark_light::Mode::Dark => { + debug!("Detected system theme dark, init theme adjusted."); + SettingsTheme::Dark + } }; - let default_settings = Settings { - id: None, - log_level: SettingsLogLevel::Info, - theme: init_theme, - tray_icon_theme: TrayIconTheme::Color, - check_for_updates: true, - selected_view: None, + let settings = Settings { + theme, + ..Default::default() }; query!( "INSERT INTO settings (log_level, theme, tray_icon_theme, check_for_updates, selected_view) VALUES ($1, $2, $3, $4, $5);", - default_settings.log_level, - default_settings.theme, - default_settings.tray_icon_theme, - default_settings.check_for_updates, - default_settings.selected_view + settings.log_level, + settings.theme, + settings.tray_icon_theme, + settings.check_for_updates, + settings.selected_view ) .execute(pool) .await?; diff --git a/src-tauri/src/database/models/tunnel.rs b/src-tauri/src/database/models/tunnel.rs index dfe17cd5..5153a68b 100644 --- a/src-tauri/src/database/models/tunnel.rs +++ b/src-tauri/src/database/models/tunnel.rs @@ -1,22 +1,21 @@ +use super::{Id, NoId}; use std::time::SystemTime; use chrono::{NaiveDateTime, Utc}; use defguard_wireguard_rs::host::Peer; use serde::{Deserialize, Serialize}; use serde_with::{serde_as, NoneAsEmptyString}; -use sqlx::{query, query_as, Error as SqlxError, FromRow}; +use sqlx::{query, query_as, Error as SqlxError}; use crate::{ - commands::DateTimeAggregation, - database::{ActiveConnection, DbPool}, - error::Error, - CommonConnection, CommonConnectionInfo, CommonLocationStats, ConnectionType, + commands::DateTimeAggregation, database::ActiveConnection, error::Error, CommonConnection, + CommonConnectionInfo, CommonLocationStats, ConnectionType, }; #[serde_as] -#[derive(Debug, FromRow, Serialize, Deserialize)] -pub struct Tunnel { - pub id: Option, +#[derive(Debug, Serialize, Deserialize)] +pub struct Tunnel { + pub id: I, pub name: String, // user keys pub pubkey: String, @@ -45,7 +44,105 @@ pub struct Tunnel { pub post_down: Option, } -impl Tunnel { +impl Tunnel { + pub async fn save<'e, E>(&mut self, executor: E) -> Result<(), SqlxError> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { + query!( + "UPDATE tunnel SET name = $1, pubkey = $2, prvkey = $3, address = $4, \ + server_pubkey = $5, preshared_key = $6, allowed_ips = $7, endpoint = $8, dns = $9, \ + persistent_keep_alive = $10, route_all_traffic = $11, pre_up = $12, post_up = $13, pre_down = $14, post_down = $15 \ + WHERE id = $16;", + self.name, + self.pubkey, + self.prvkey, + self.address, + self.server_pubkey, + self.preshared_key, + self.allowed_ips, + self.endpoint, + self.dns, + self.persistent_keep_alive, + self.route_all_traffic, + self.pre_up, + self.post_up, + self.pre_down, + self.post_down, + self.id, + ) + .execute(executor) + .await?; + Ok(()) + } + + pub async fn delete<'e, E>(&self, executor: E) -> Result<(), Error> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { + Tunnel::delete_by_id(executor, self.id).await?; + Ok(()) + } + + pub async fn find_by_id<'e, E>(executor: E, tunnel_id: i64) -> Result, SqlxError> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { + query_as!( + Self, + "SELECT id \"id: _\", name, pubkey, prvkey, address, server_pubkey, preshared_key, allowed_ips, endpoint, dns, \ + persistent_keep_alive, route_all_traffic, pre_up, post_up, pre_down, post_down FROM tunnel WHERE id = $1;", + tunnel_id + ) + .fetch_optional(executor) + .await + } + + pub async fn all<'e, E>(executor: E) -> Result, SqlxError> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { + let tunnels = query_as!( + Self, + "SELECT id \"id: _\", name, pubkey, prvkey, address, server_pubkey, preshared_key, allowed_ips, endpoint, dns, \ + persistent_keep_alive, route_all_traffic, pre_up, post_up, pre_down, post_down FROM tunnel;" + ) + .fetch_all(executor) + .await?; + Ok(tunnels) + } + + pub async fn find_by_server_public_key<'e, E>( + executor: E, + pubkey: &str, + ) -> Result + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { + query_as!( + Self, + "SELECT id \"id: _\", name, pubkey, prvkey, address, server_pubkey, preshared_key, allowed_ips, endpoint, dns, persistent_keep_alive, \ + route_all_traffic, pre_up, post_up, pre_down, post_down \ + FROM tunnel WHERE server_pubkey = $1;", + pubkey + ) + .fetch_one(executor) + .await + } + + pub async fn delete_by_id<'e, E>(executor: E, id: i64) -> Result<(), Error> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { + // delete instance + query!("DELETE FROM tunnel WHERE id = $1", id) + .execute(executor) + .await?; + Ok(()) + } +} + +impl Tunnel { #[allow(clippy::too_many_arguments)] #[must_use] pub fn new( @@ -66,7 +163,7 @@ impl Tunnel { post_down: Option, ) -> Self { Tunnel { - id: None, + id: NoId, name, pubkey, prvkey, @@ -85,122 +182,58 @@ impl Tunnel { } } - pub async fn save(&mut self, pool: &DbPool) -> Result<(), SqlxError> { - match self.id { - None => { - // Insert a new record when there is no ID - let result = query!( - "INSERT INTO tunnel (name, pubkey, prvkey, address, server_pubkey, allowed_ips, preshared_key, \ - endpoint, dns, persistent_keep_alive, route_all_traffic, pre_up, post_up, pre_down, post_down) \ - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15) RETURNING id;", - self.name, - self.pubkey, - self.prvkey, - self.address, - self.server_pubkey, - self.allowed_ips, - self.preshared_key, - self.endpoint, - self.dns, - self.persistent_keep_alive, - self.route_all_traffic, - self.pre_up, - self.post_up, - self.pre_down, - self.post_down, - ) - .fetch_one(pool) - .await?; - self.id = Some(result.id); - } - Some(id) => { - // Update the existing record when there is an ID - query!( - "UPDATE tunnel SET name = $1, pubkey = $2, prvkey = $3, address = $4, \ - server_pubkey = $5, preshared_key = $6, allowed_ips = $7, endpoint = $8, dns = $9, \ - persistent_keep_alive = $10, route_all_traffic = $11, pre_up = $12, post_up = $13, pre_down = $14, post_down = $15 \ - WHERE id = $16;", - self.name, - self.pubkey, - self.prvkey, - self.address, - self.server_pubkey, - self.preshared_key, - self.allowed_ips, - self.endpoint, - self.dns, - self.persistent_keep_alive, - self.route_all_traffic, - self.pre_up, - self.post_up, - self.pre_down, - self.post_down, - id, - ) - .execute(pool) - .await?; - } - } - - Ok(()) - } - - pub async fn find_by_id(pool: &DbPool, tunnel_id: i64) -> Result, SqlxError> { - query_as!( - Self, - "SELECT id \"id?\", name, pubkey, prvkey, address, server_pubkey, preshared_key, allowed_ips, endpoint, dns, \ - persistent_keep_alive, route_all_traffic, pre_up, post_up, pre_down, post_down FROM tunnel WHERE id = $1;", - tunnel_id - ) - .fetch_optional(pool) - .await - } - - pub async fn all(pool: &DbPool) -> Result, SqlxError> { - let tunnels = query_as!( - Self, - "SELECT id \"id?\", name, pubkey, prvkey, address, server_pubkey, preshared_key, allowed_ips, endpoint, dns, \ - persistent_keep_alive, route_all_traffic, pre_up, post_up, pre_down, post_down FROM tunnel;" + pub async fn save<'e, E>(self, executor: E) -> Result, SqlxError> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { + // Insert a new record when there is no ID + let result = query!( + "INSERT INTO tunnel (name, pubkey, prvkey, address, server_pubkey, allowed_ips, preshared_key, \ + endpoint, dns, persistent_keep_alive, route_all_traffic, pre_up, post_up, pre_down, post_down) \ + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15) RETURNING id;", + self.name, + self.pubkey, + self.prvkey, + self.address, + self.server_pubkey, + self.allowed_ips, + self.preshared_key, + self.endpoint, + self.dns, + self.persistent_keep_alive, + self.route_all_traffic, + self.pre_up, + self.post_up, + self.pre_down, + self.post_down, ) - .fetch_all(pool) + .fetch_one(executor) .await?; - Ok(tunnels) - } - pub async fn find_by_server_public_key(pool: &DbPool, pubkey: &str) -> Result { - query_as!( - Self, - "SELECT id \"id?\", name, pubkey, prvkey, address, server_pubkey, preshared_key, allowed_ips, endpoint, dns, persistent_keep_alive, - route_all_traffic, pre_up, post_up, pre_down, post_down \ - FROM tunnel WHERE server_pubkey = $1;", - pubkey - ) - .fetch_one(pool) - .await - } - - pub async fn delete_by_id(pool: &DbPool, id: i64) -> Result<(), Error> { - // delete instance - query!("DELETE FROM tunnel WHERE id = $1", id) - .execute(pool) - .await?; - Ok(()) - } - - pub async fn delete(&self, pool: &DbPool) -> Result<(), Error> { - match self.id { - Some(id) => { - Tunnel::delete_by_id(pool, id).await?; - Ok(()) - } - None => Err(Error::NotFound), - } + Ok(Tunnel:: { + id: result.id, + name: self.name, + pubkey: self.pubkey, + prvkey: self.prvkey, + address: self.address, + server_pubkey: self.server_pubkey, + allowed_ips: self.allowed_ips, + preshared_key: self.preshared_key, + endpoint: self.endpoint, + dns: self.dns, + persistent_keep_alive: self.persistent_keep_alive, + route_all_traffic: self.route_all_traffic, + pre_up: self.pre_up, + post_up: self.post_up, + pre_down: self.pre_down, + post_down: self.post_down, + }) } } -#[derive(FromRow, Debug, Serialize, Deserialize)] -pub struct TunnelStats { - id: Option, +#[derive(Debug, Serialize, Deserialize)] +pub struct TunnelStats { + id: I, tunnel_id: i64, upload: i64, download: i64, @@ -210,7 +243,7 @@ pub struct TunnelStats { persistent_keepalive_interval: Option, } -impl TunnelStats { +impl TunnelStats { #[must_use] pub fn new( tunnel_id: i64, @@ -222,7 +255,7 @@ impl TunnelStats { persistent_keepalive_interval: Option, ) -> Self { TunnelStats { - id: None, + id: NoId, tunnel_id, upload, download, @@ -233,7 +266,10 @@ impl TunnelStats { } } - pub async fn save(&mut self, pool: &DbPool) -> Result<(), SqlxError> { + pub async fn save<'e, E>(self, executor: E) -> Result, SqlxError> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { let result = query!( "INSERT INTO tunnel_stats (tunnel_id, upload, download, last_handshake, collected_at, listen_port, persistent_keepalive_interval) \ VALUES ($1, $2, $3, $4, $5, $6, $7) \ @@ -246,18 +282,31 @@ impl TunnelStats { self.listen_port, self.persistent_keepalive_interval, ) - .fetch_one(pool) + .fetch_one(executor) .await?; - self.id = Some(result.id); - Ok(()) + Ok(TunnelStats:: { + id: result.id, + tunnel_id: self.tunnel_id, + upload: self.upload, + download: self.download, + last_handshake: self.last_handshake, + collected_at: self.collected_at, + listen_port: self.listen_port, + persistent_keepalive_interval: self.persistent_keepalive_interval, + }) } +} - pub async fn all_by_tunnel_id( - pool: &DbPool, +impl TunnelStats { + pub async fn all_by_tunnel_id<'e, E>( + executor: E, tunnel_id: i64, from: &NaiveDateTime, aggregation: &DateTimeAggregation, - ) -> Result, SqlxError> { + ) -> Result, SqlxError> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { let aggregation = aggregation.fstring(); let stats = query_as!( TunnelStats, @@ -284,21 +333,24 @@ impl TunnelStats { tunnel_id, from ) - .fetch_all(pool) + .fetch_all(executor) .await?; Ok(stats) } } -pub async fn peer_to_tunnel_stats( +pub async fn peer_to_tunnel_stats<'e, E>( peer: &Peer, listen_port: u32, - pool: &DbPool, -) -> Result { - let tunnel = Tunnel::find_by_server_public_key(pool, &peer.public_key.to_string()).await?; + executor: E, +) -> Result, Error> +where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, +{ + let tunnel = Tunnel::find_by_server_public_key(executor, &peer.public_key.to_string()).await?; Ok(TunnelStats { - id: None, - tunnel_id: tunnel.id.unwrap(), + id: NoId, + tunnel_id: tunnel.id, upload: peer.tx_bytes as i64, download: peer.rx_bytes as i64, last_handshake: peer.last_handshake.map_or(0, |ts| { @@ -311,9 +363,9 @@ pub async fn peer_to_tunnel_stats( }) } -#[derive(FromRow, Debug, Serialize, Clone)] -pub struct TunnelConnection { - pub id: Option, +#[derive(Debug, Serialize, Clone)] +pub struct TunnelConnection { + pub id: I, pub tunnel_id: i64, pub connected_from: String, pub start: NaiveDateTime, @@ -334,36 +386,32 @@ impl From for CommonConnectionInfo { } } -impl TunnelConnection { - pub async fn save(&mut self, pool: &DbPool) -> Result<(), Error> { - let result = query!( - "INSERT INTO tunnel_connection (tunnel_id, connected_from, start, end) \ - VALUES ($1, $2, $3, $4) \ - RETURNING id;", - self.tunnel_id, - self.connected_from, - self.start, - self.end, - ) - .fetch_one(pool) - .await?; - self.id = Some(result.id); - Ok(()) - } - - pub async fn all_by_tunnel_id(pool: &DbPool, tunnel_id: i64) -> Result, Error> { +impl TunnelConnection { + pub async fn all_by_tunnel_id<'e, E>( + executor: E, + tunnel_id: i64, + ) -> Result>, Error> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { let connections = query_as!( TunnelConnection, "SELECT id, tunnel_id, connected_from, start, end \ FROM tunnel_connection WHERE tunnel_id = $1", tunnel_id ) - .fetch_all(pool) + .fetch_all(executor) .await?; Ok(connections) } - pub async fn latest_by_tunnel_id(pool: &DbPool, tunnel_id: i64) -> Result, Error> { + pub async fn latest_by_tunnel_id<'e, E>( + executor: E, + tunnel_id: i64, + ) -> Result>, Error> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { let connection = query_as!( TunnelConnection, "SELECT id, tunnel_id, connected_from, start, end \ @@ -371,14 +419,41 @@ impl TunnelConnection { ORDER BY end DESC LIMIT 1", tunnel_id ) - .fetch_optional(pool) + .fetch_optional(executor) .await?; Ok(connection) } } +impl TunnelConnection { + pub async fn save<'e, E>(self, executor: E) -> Result, Error> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { + let result = query!( + "INSERT INTO tunnel_connection (tunnel_id, connected_from, start, end) \ + VALUES ($1, $2, $3, $4) \ + RETURNING id;", + self.tunnel_id, + self.connected_from, + self.start, + self.end, + ) + .fetch_one(executor) + .await?; + + Ok(TunnelConnection:: { + id: result.id, + tunnel_id: self.tunnel_id, + connected_from: self.connected_from, + start: self.start, + end: self.end, + }) + } +} + /// Historical connection -#[derive(FromRow, Debug, Serialize)] +#[derive(Debug, Serialize)] pub struct TunnelConnectionInfo { pub id: i64, pub tunnel_id: i64, @@ -390,7 +465,10 @@ pub struct TunnelConnectionInfo { } impl TunnelConnectionInfo { - pub async fn all_by_tunnel_id(pool: &DbPool, tunnel_id: i64) -> Result, Error> { + pub async fn all_by_tunnel_id<'e, E>(executor: E, tunnel_id: i64) -> Result, Error> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { // Because we store interface information for given timestamp select last upload and download // before connection ended // FIXME: Optimize query @@ -419,17 +497,17 @@ impl TunnelConnectionInfo { ORDER BY start DESC", tunnel_id ) - .fetch_all(pool) + .fetch_all(executor) .await?; Ok(connections) } } -impl From<&ActiveConnection> for TunnelConnection { +impl From<&ActiveConnection> for TunnelConnection { fn from(active_connection: &ActiveConnection) -> Self { TunnelConnection { - id: None, + id: NoId, tunnel_id: active_connection.location_id, connected_from: active_connection.connected_from.clone(), start: active_connection.start, @@ -439,9 +517,9 @@ impl From<&ActiveConnection> for TunnelConnection { } // Implementing From for TunnelConnection into CommonConnection -impl From for CommonConnection { - fn from(tunnel_connection: TunnelConnection) -> Self { - CommonConnection { +impl From> for CommonConnection { + fn from(tunnel_connection: TunnelConnection) -> Self { + CommonConnection:: { id: tunnel_connection.id, location_id: tunnel_connection.tunnel_id, // Assuming you want to map tunnel_id to location_id connected_from: tunnel_connection.connected_from, @@ -453,8 +531,8 @@ impl From for CommonConnection { } // Implement From trait for converting TunnelStats to CommonLocationStats -impl From for CommonLocationStats { - fn from(tunnel_stats: TunnelStats) -> Self { +impl From> for CommonLocationStats { + fn from(tunnel_stats: TunnelStats) -> Self { CommonLocationStats { id: tunnel_stats.id, location_id: tunnel_stats.tunnel_id, diff --git a/src-tauri/src/database/models/wireguard_keys.rs b/src-tauri/src/database/models/wireguard_keys.rs index ce776078..351cb7aa 100644 --- a/src-tauri/src/database/models/wireguard_keys.rs +++ b/src-tauri/src/database/models/wireguard_keys.rs @@ -1,27 +1,48 @@ -use crate::{database::DbPool, error::Error}; +use crate::error::Error; use sqlx::{query, query_as, Error as SqlxError}; +use super::{Id, NoId}; + // User key pair #[derive(Debug)] -pub struct WireguardKeys { - pub id: Option, +pub struct WireguardKeys { + pub id: I, pub instance_id: i64, pub pubkey: String, pub prvkey: String, } -impl WireguardKeys { +impl WireguardKeys { + pub async fn find_by_instance_id<'e, E>( + executor: E, + instance_id: i64, + ) -> Result, SqlxError> + where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, + { + query_as!( + Self, + "SELECT id \"id: _\", instance_id, pubkey, prvkey \ + FROM wireguard_keys WHERE instance_id = $1;", + instance_id + ) + .fetch_optional(executor) + .await + } +} + +impl WireguardKeys { #[must_use] pub fn new(instance_id: i64, pubkey: String, prvkey: String) -> Self { WireguardKeys { - id: None, + id: NoId, instance_id, pubkey, prvkey, } } - pub async fn save<'e, E>(&mut self, executor: E) -> Result<(), Error> + pub async fn save<'e, E>(self, executor: E) -> Result, Error> where E: sqlx::Executor<'e, Database = sqlx::Sqlite>, { @@ -36,21 +57,11 @@ impl WireguardKeys { ) .fetch_one(executor) .await?; - self.id = Some(result.id); - Ok(()) - } - - pub async fn find_by_instance_id( - pool: &DbPool, - instance_id: i64, - ) -> Result, SqlxError> { - query_as!( - Self, - "SELECT id \"id?\", instance_id, pubkey, prvkey \ - FROM wireguard_keys WHERE instance_id = $1;", - instance_id - ) - .fetch_optional(pool) - .await + Ok(WireguardKeys:: { + id: result.id, + instance_id: self.instance_id, + pubkey: self.pubkey, + prvkey: self.prvkey, + }) } } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 847a4bdf..714a655a 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -1,4 +1,5 @@ use chrono::NaiveDateTime; +use database::models::NoId; use serde::{Deserialize, Serialize}; pub mod appstate; pub mod commands; @@ -15,6 +16,8 @@ mod proto { tonic::include_proto!("defguard.proxy"); } +pub const VERSION: &str = concat!(env!("CARGO_PKG_VERSION"), "-", env!("VERGEN_GIT_SHA")); + /// Location type used in commands to check if we using tunnel or location #[derive(Debug, PartialEq, Deserialize, Serialize, Clone, Copy)] pub enum ConnectionType { @@ -42,8 +45,8 @@ pub struct CommonWireguardFields { /// Common fields for Connection and TunnelConnection due to shared command #[derive(Debug, Serialize, Deserialize)] -pub struct CommonConnection { - pub id: Option, +pub struct CommonConnection { + pub id: I, pub location_id: i64, pub connected_from: String, pub start: NaiveDateTime, @@ -53,8 +56,8 @@ pub struct CommonConnection { // Common fields for LocationStats and TunnelStats due to shared command #[derive(Debug, Serialize, Deserialize)] -pub struct CommonLocationStats { - pub id: Option, +pub struct CommonLocationStats { + pub id: I, pub location_id: i64, pub upload: i64, pub download: i64, diff --git a/src-tauri/src/periodic/config.rs b/src-tauri/src/periodic/config.rs index 36b2d87c..bd65b522 100644 --- a/src-tauri/src/periodic/config.rs +++ b/src-tauri/src/periodic/config.rs @@ -7,7 +7,7 @@ use crate::{ commands::{device_config_to_location, update_instance}, database::{ models::{Id, NoId}, - DbPool, Instance, Location, + Instance, Location, }, error::Error, events::{CONFIG_CHANGED, INSTANCE_UPDATE}, @@ -24,7 +24,15 @@ pub async fn poll_config(handle: AppHandle) { let state: State = handle.state(); let pool = state.get_pool(); loop { - let Ok(mut instances) = Instance::all(&pool).await else { + let Ok(mut transaction) = pool.begin().await else { + error!( + "Failed to begin db transaction, retrying in {}s", + INTERVAL_SECONDS.as_secs() + ); + sleep(INTERVAL_SECONDS).await; + continue; + }; + let Ok(mut instances) = Instance::all(&mut *transaction).await else { error!( "Failed to retireve instances, retrying in {}s", INTERVAL_SECONDS.as_secs() @@ -37,7 +45,7 @@ pub async fn poll_config(handle: AppHandle) { instances.len(), ); for instance in &mut instances { - if let Err(err) = poll_instance(&pool, instance, handle.clone()).await { + if let Err(err) = poll_instance(&mut *transaction, instance, handle.clone()).await { error!( "Failed to retrieve instance {}({}) config: {}", instance.name, instance.id, err @@ -49,6 +57,9 @@ pub async fn poll_config(handle: AppHandle) { ); } } + if let Err(err) = transaction.commit().await { + error!("Failed to commit config polling transaction, configuration won't be updated: {err}"); + } info!( "Retrieved configuration for {} instances, sleeping {}s", instances.len(), @@ -60,13 +71,16 @@ pub async fn poll_config(handle: AppHandle) { /// Retrieves configuration for given [`Instance`]. /// Updates the instance if there are no active connections, otherwise displays UI message. -pub async fn poll_instance( - pool: &DbPool, +pub async fn poll_instance<'e, E>( + executor: E, instance: &mut Instance, handle: AppHandle, -) -> Result<(), Error> { +) -> Result<(), Error> +where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, +{ // Query proxy api - let request = build_request(instance).await?; + let request = build_request(instance)?; let url = Url::from_str(&instance.proxy_url) .and_then(|url| url.join(POLLING_ENDPOINT)) .map_err(|_| { @@ -117,7 +131,7 @@ pub async fn poll_instance( } // Early return if config didn't change - if !config_changed(pool, instance, device_config).await? { + if !config_changed(executor, instance, device_config).await? { debug!( "Config for instance {}({}) didn't change", instance.name, instance.id @@ -160,12 +174,15 @@ pub async fn poll_instance( } /// Returns true if configuration in instance_info differs from current configuration -async fn config_changed( - pool: &DbPool, +async fn config_changed<'e, E>( + executor: E, instance: &Instance, device_config: &DeviceConfigResponse, -) -> Result { - let db_locations: Vec> = Location::find_by_instance_id(pool, instance.id) +) -> Result +where + E: sqlx::Executor<'e, Database = sqlx::Sqlite>, +{ + let db_locations: Vec> = Location::find_by_instance_id(executor, instance.id) .await? .into_iter() .map(Location::::from) @@ -183,7 +200,7 @@ async fn config_changed( } /// Retrieves pubkey & token to build InstanceInfoRequest -async fn build_request(instance: &Instance) -> Result { +fn build_request(instance: &Instance) -> Result { let token = &instance.token.as_ref().ok_or_else(|| { Error::InternalError(format!( "Instance {}({}) missing token", @@ -191,6 +208,6 @@ async fn build_request(instance: &Instance) -> Result for proto::Peer { }), tx_bytes: peer.tx_bytes, rx_bytes: peer.rx_bytes, - persistent_keepalive_interval: peer - .persistent_keepalive_interval - .map(|interval| interval as u32), + persistent_keepalive_interval: peer.persistent_keepalive_interval.map(u32::from), allowed_ips: peer .allowed_ips .into_iter() diff --git a/src-tauri/src/tray.rs b/src-tauri/src/tray.rs index 7eaf9e28..8e7704c2 100644 --- a/src-tauri/src/tray.rs +++ b/src-tauri/src/tray.rs @@ -31,12 +31,7 @@ pub async fn generate_tray_menu(app_state: State<'_, AppState>) -> Result &'static Path { /// Setup client interface pub async fn setup_interface_tunnel( - tunnel: &Tunnel, + tunnel: &Tunnel, interface_name: String, mut client: DesktopDaemonServiceClient, ) -> Result<(), Error> { @@ -577,7 +577,10 @@ pub async fn handle_connection_for_location( } /// Setup new connection for tunnel -pub async fn handle_connection_for_tunnel(tunnel: &Tunnel, handle: AppHandle) -> Result<(), Error> { +pub async fn handle_connection_for_tunnel( + tunnel: &Tunnel, + handle: AppHandle, +) -> Result<(), Error> { debug!( "Creating new interface connection for tunnel: {}", tunnel.name @@ -590,7 +593,7 @@ pub async fn handle_connection_for_tunnel(tunnel: &Tunnel, handle: AppHandle) -> setup_interface_tunnel(tunnel, interface_name.clone(), state.client.clone()).await?; let address = local_ip()?; let connection = ActiveConnection::new( - tunnel.id.expect("Missing Tunnel ID"), + tunnel.id, address.to_string(), interface_name.clone(), ConnectionType::Tunnel, @@ -626,7 +629,7 @@ pub async fn handle_connection_for_tunnel(tunnel: &Tunnel, handle: AppHandle) -> debug!("Spawning log watcher"); spawn_log_watcher_task( handle, - tunnel.id.expect("Missing Tunnel ID"), + tunnel.id, interface_name, ConnectionType::Tunnel, Level::DEBUG, @@ -683,8 +686,8 @@ pub async fn disconnect_interface( error!("Failed to remove interface: {error}"); return Err(Error::InternalError("Failed to remove interface".into())); } - let mut connection: Connection = active_connection.into(); - connection.save(&state.get_pool()).await?; + let connection: Connection = active_connection.into(); + let connection = connection.save(&state.get_pool()).await?; trace!("Saved connection: {connection:#?}"); debug!("Removed interface"); debug!("Saving connection"); @@ -704,8 +707,8 @@ pub async fn disconnect_interface( error!("{msg}"); return Err(Error::InternalError(msg)); } - let mut connection: TunnelConnection = active_connection.into(); - connection.save(&state.get_pool()).await?; + let connection: TunnelConnection = active_connection.into(); + let connection = connection.save(&state.get_pool()).await?; trace!("Saved connection: {connection:#?}"); } else { error!("Tunnel with ID {} not found", active_connection.location_id); diff --git a/src-tauri/src/wg_config.rs b/src-tauri/src/wg_config.rs index 9fa890b8..b94e6e4f 100644 --- a/src-tauri/src/wg_config.rs +++ b/src-tauri/src/wg_config.rs @@ -110,6 +110,8 @@ pub fn parse_wireguard_config(config: &str) -> Result const saveTunnel = async (tunnel: TunnelRequest) => invokeWrapper('save_tunnel', { tunnel: tunnel }); +const updateTunnel = async (tunnel: TunnelRequest) => + invokeWrapper('update_tunnel', { tunnel: tunnel }); + const getLocationDetails = async ( data: LocationDetailsRequest, ): Promise => invokeWrapper('location_interface_details', data); @@ -134,6 +137,7 @@ export const clientApi = { updateInstance, parseTunnelConfig, saveTunnel, + updateTunnel, openLink, getTunnelDetails, getLatestAppVersion, diff --git a/src/pages/client/clientAPI/types.ts b/src/pages/client/clientAPI/types.ts index c86110ea..e89c16fd 100644 --- a/src/pages/client/clientAPI/types.ts +++ b/src/pages/client/clientAPI/types.ts @@ -126,6 +126,7 @@ export type TauriCommandKey = | 'update_instance' | 'parse_tunnel_config' | 'save_tunnel' + | 'update_tunnel' | 'all_tunnels' | 'tunnel_details' | 'delete_tunnel' diff --git a/src/pages/client/pages/ClientEditTunnelPage/components/EditTunnelFormCard.tsx b/src/pages/client/pages/ClientEditTunnelPage/components/EditTunnelFormCard.tsx index ba44d639..036bbd00 100644 --- a/src/pages/client/pages/ClientEditTunnelPage/components/EditTunnelFormCard.tsx +++ b/src/pages/client/pages/ClientEditTunnelPage/components/EditTunnelFormCard.tsx @@ -67,7 +67,7 @@ const defaultValues: FormFields = { pre_down: '', post_down: '', }; -const { saveTunnel } = clientApi; +const { updateTunnel } = clientApi; const tunnelToForm = (tunnel: Tunnel): FormFields => { const { @@ -186,7 +186,7 @@ export const EditTunnelFormCard = ({ tunnel, submitRef }: Props) => { ); const handleValidSubmit: SubmitHandler = (values) => { - saveTunnel(values) + updateTunnel(values) .then(() => { navigate(routes.client.base, { replace: true }); toaster.success(LL.pages.client.pages.editTunnelPage.messages.editSuccess());