diff --git a/AGENTS.md b/AGENTS.md index e391a5e..7573b09 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -56,6 +56,7 @@ donutbrowser/ │ ├── app/ # Test-only Tauri harness that injects the private driver │ ├── lib/ # WebDriver, CDP, fixtures, app-session helpers │ └── tests/ # Smoke, UI, entity, integration, sync, browser suites +├── patches/ # pnpm compatibility patches for secured dependencies ├── flake.nix # Nix development environment └── .github/workflows/ # CI/CD pipelines ``` diff --git a/e2e/app/Cargo.lock b/e2e/app/Cargo.lock index fca1cff..b90de46 100644 --- a/e2e/app/Cargo.lock +++ b/e2e/app/Cargo.lock @@ -7980,8 +7980,9 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.31.10" -source = "git+https://github.com/Smithay/wayland-rs?rev=d07c4f91f28b42e5a485823ffd9d8d5a210b1053#d07c4f91f28b42e5a485823ffd9d8d5a210b1053" +version = "0.31.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "338e30461b3a2b67d70eb30a6d89f8e0c93a833e07d2ae89085cd070c4a00ac0" dependencies = [ "proc-macro2", "quick-xml", diff --git a/e2e/app/Cargo.toml b/e2e/app/Cargo.toml index cde01b3..ddab55c 100644 --- a/e2e/app/Cargo.toml +++ b/e2e/app/Cargo.toml @@ -7,6 +7,3 @@ publish = false [dependencies] donutbrowser-lib = { package = "donutbrowser", path = "../../src-tauri", features = ["e2e"] } tauri-plugin-cross-platform-webdriver = { path = "../../../tauri-cross-platform-webdriver/crates/tauri-plugin-cross-platform-webdriver" } - -[patch.crates-io] -wayland-scanner = { git = "https://github.com/Smithay/wayland-rs", rev = "d07c4f91f28b42e5a485823ffd9d8d5a210b1053" } diff --git a/patches/brace-expansion@5.0.8.patch b/patches/brace-expansion@5.0.8.patch new file mode 100644 index 0000000..9c7f4ec --- /dev/null +++ b/patches/brace-expansion@5.0.8.patch @@ -0,0 +1,40 @@ +diff --git a/dist/commonjs/index.d.ts b/dist/commonjs/index.d.ts +index f3e2de9d87e1ce462517e49f35733bed8bdf85af..6c84d87835182d0670981dc15f488c2a7d061c98 100644 +--- a/dist/commonjs/index.d.ts ++++ b/dist/commonjs/index.d.ts +@@ -5,4 +5,5 @@ export type BraceExpansionOptions = { + maxLength?: number; + }; + export declare function expand(str: string, options?: BraceExpansionOptions): string[]; ++export default expand; + //# sourceMappingURL=index.d.ts.map +diff --git a/dist/commonjs/index.js b/dist/commonjs/index.js +index be9df86be09c7655787a65c55ae6da01858894c3..071ad97532f30155cb56d7f2662fa99122ca628a 100644 +--- a/dist/commonjs/index.js ++++ b/dist/commonjs/index.js +@@ -260,4 +260,5 @@ function expand_(str, max, maxLength, isTop) { + } + return acc; + } ++module.exports = Object.assign(expand, exports); + //# sourceMappingURL=index.js.map +diff --git a/dist/esm/index.d.ts b/dist/esm/index.d.ts +index f3e2de9d87e1ce462517e49f35733bed8bdf85af..6c84d87835182d0670981dc15f488c2a7d061c98 100644 +--- a/dist/esm/index.d.ts ++++ b/dist/esm/index.d.ts +@@ -5,4 +5,5 @@ export type BraceExpansionOptions = { + maxLength?: number; + }; + export declare function expand(str: string, options?: BraceExpansionOptions): string[]; ++export default expand; + //# sourceMappingURL=index.d.ts.map +diff --git a/dist/esm/index.js b/dist/esm/index.js +index 6dc0392fc0feedb811e63d70a30be2736af17a3a..81ea182fa5dbc3c60fa4cec4cb549fa256a903e4 100644 +--- a/dist/esm/index.js ++++ b/dist/esm/index.js +@@ -256,4 +256,5 @@ function expand_(str, max, maxLength, isTop) { + } + return acc; + } ++export default expand; + //# sourceMappingURL=index.js.map diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 107b969..000f075 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,7 +7,7 @@ settings: overrides: picomatch@>=4.0.0 <4.0.4: '>=4.0.4' path-to-regexp@>=8.0.0 <8.4.0: '>=8.4.0' - postcss@<8.5.10: '>=8.5.12' + postcss@<8.5.18: '>=8.5.18' fast-xml-parser@<5.7.0: '>=5.7.2' fast-uri@<3.1.2: '>=3.1.2 <4' fast-xml-builder@<1.2.0: '>=1.2.0' @@ -19,11 +19,12 @@ overrides: js-yaml@<3.15.0: '>=3.15.0 <4' js-yaml@>=4.0.0 <4.3.0: '>=4.3.0 <5' '@babel/core@<7.29.6': '>=7.29.6 <8' - brace-expansion@<1.1.16: '>=1.1.16 <2' - brace-expansion@>=2.0.0 <2.1.2: '>=2.1.2 <3' - brace-expansion@>=3.0.0 <5.0.7: '>=5.0.7 <6' + brace-expansion@<5.0.8: 5.0.8 sharp@<0.35.0: '>=0.35.0 <0.36' +patchedDependencies: + brace-expansion@5.0.8: 6f8c2bb08760f9abf1133095a5475f8ac32a360b9dcbcb85e4750dd1b616339e + importers: .: @@ -2826,9 +2827,6 @@ packages: peerDependencies: '@babel/core': '>=7.29.6 <8' - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - balanced-match@4.0.4: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} @@ -2851,15 +2849,9 @@ packages: bowser@2.14.1: resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==} - brace-expansion@1.1.16: - resolution: {integrity: sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==} - - brace-expansion@2.1.2: - resolution: {integrity: sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==} - - brace-expansion@5.0.7: - resolution: {integrity: sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==} - engines: {node: 18 || 20 || >=22} + brace-expansion@5.0.8: + resolution: {integrity: sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==} + engines: {node: 20 || >=22} browserslist@4.28.4: resolution: {integrity: sha512-MTc8i/x9jBQd1iMw2CFGS+rwMa07eYjLR0CCTLDACl9xhxy+nIs3KeML/biicXtk9JrZ6dnnTatmc7ErPXIxqw==} @@ -3038,9 +3030,6 @@ packages: component-emitter@1.3.1: resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - concat-stream@2.0.0: resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} engines: {'0': node >= 6.0} @@ -4101,8 +4090,8 @@ packages: resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} engines: {node: ^18.17.0 || >=20.5.0} - nanoid@3.3.15: - resolution: {integrity: sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==} + nanoid@3.3.16: + resolution: {integrity: sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -4295,8 +4284,8 @@ packages: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} - postcss@8.5.15: - resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} + postcss@8.5.23: + resolution: {integrity: sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==} engines: {node: ^10 || ^12 || >=14} postcss@8.5.23: @@ -7364,7 +7353,7 @@ snapshots: '@alloc/quick-lru': 5.2.0 '@tailwindcss/node': 4.3.2 '@tailwindcss/oxide': 4.3.2 - postcss: 8.5.15 + postcss: 8.5.23 tailwindcss: 4.3.2 '@tanstack/react-table@8.21.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': @@ -8018,8 +8007,6 @@ snapshots: babel-preset-current-node-syntax: 1.2.0(@babel/core@8.0.1) optional: true - balanced-match@1.0.2: {} - balanced-match@4.0.4: {} base64-js@1.5.1: {} @@ -8048,16 +8035,7 @@ snapshots: bowser@2.14.1: {} - brace-expansion@1.1.16: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@2.1.2: - dependencies: - balanced-match: 1.0.2 - - brace-expansion@5.0.7: + brace-expansion@5.0.8(patch_hash=6f8c2bb08760f9abf1133095a5475f8ac32a360b9dcbcb85e4750dd1b616339e): dependencies: balanced-match: 4.0.4 @@ -8222,8 +8200,6 @@ snapshots: component-emitter@1.3.1: {} - concat-map@0.0.1: {} - concat-stream@2.0.0: dependencies: buffer-from: 1.1.2 @@ -9353,15 +9329,15 @@ snapshots: minimatch@10.2.5: dependencies: - brace-expansion: 5.0.7 + brace-expansion: 5.0.8(patch_hash=6f8c2bb08760f9abf1133095a5475f8ac32a360b9dcbcb85e4750dd1b616339e) minimatch@3.1.5: dependencies: - brace-expansion: 1.1.16 + brace-expansion: 5.0.8(patch_hash=6f8c2bb08760f9abf1133095a5475f8ac32a360b9dcbcb85e4750dd1b616339e) minimatch@9.0.9: dependencies: - brace-expansion: 2.1.2 + brace-expansion: 5.0.8(patch_hash=6f8c2bb08760f9abf1133095a5475f8ac32a360b9dcbcb85e4750dd1b616339e) minimist@1.2.8: {} @@ -9392,7 +9368,7 @@ snapshots: mute-stream@2.0.0: {} - nanoid@3.3.15: {} + nanoid@3.3.16: {} nanoid@3.3.16: {} @@ -9556,9 +9532,9 @@ snapshots: pluralize@8.0.0: {} - postcss@8.5.15: + postcss@8.5.23: dependencies: - nanoid: 3.3.15 + nanoid: 3.3.16 picocolors: 1.1.1 source-map-js: 1.2.1 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index a93934d..daf1a7c 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -22,7 +22,7 @@ confirmModulesPurge: false overrides: picomatch@>=4.0.0 <4.0.4: '>=4.0.4' path-to-regexp@>=8.0.0 <8.4.0: '>=8.4.0' - postcss@<8.5.10: '>=8.5.12' + postcss@<8.5.18: '>=8.5.18' fast-xml-parser@<5.7.0: '>=5.7.2' fast-uri@<3.1.2: '>=3.1.2 <4' fast-xml-builder@<1.2.0: '>=1.2.0' @@ -34,9 +34,7 @@ overrides: js-yaml@<3.15.0: '>=3.15.0 <4' js-yaml@>=4.0.0 <4.3.0: '>=4.3.0 <5' '@babel/core@<7.29.6': '>=7.29.6 <8' - brace-expansion@<1.1.16: '>=1.1.16 <2' - brace-expansion@>=2.0.0 <2.1.2: '>=2.1.2 <3' - brace-expansion@>=3.0.0 <5.0.7: '>=5.0.7 <6' + brace-expansion@<5.0.8: 5.0.8 sharp@<0.35.0: '>=0.35.0 <0.36' allowBuilds: @@ -97,3 +95,6 @@ minimumReleaseAgeExclude: - '@aws-sdk/nested-clients@3.997.29' - '@aws-sdk/s3-request-presigner@3.1081.0' - '@aws-sdk/token-providers@3.1081.0' + +patchedDependencies: + brace-expansion@5.0.8: patches/brace-expansion@5.0.8.patch diff --git a/src-tauri/.cargo/audit.toml b/src-tauri/.cargo/audit.toml deleted file mode 100644 index 5665c8f..0000000 --- a/src-tauri/.cargo/audit.toml +++ /dev/null @@ -1,17 +0,0 @@ -# cargo-audit configuration -# -# The ignored advisories below all concern `quick-xml` 0.39.4, which is pulled in -# ONLY by `wayland-scanner` (Linux clipboard support via arboard → -# tauri-plugin-clipboard-manager). `wayland-scanner` pins `quick-xml ^0.39`, so -# no patched release (>= 0.41.0) is reachable through that dependency chain. -# -# `wayland-scanner` uses quick-xml at build time to parse the Wayland protocol -# XML definitions that ship inside the crate — trusted, bundled input, never -# attacker-controlled — so the denial-of-service vectors these advisories -# describe do not apply. Our own direct dependency is already on the patched -# quick-xml 0.41. Remove these entries once wayland-scanner bumps its requirement. -[advisories] -ignore = [ - "RUSTSEC-2026-0194", # quick-xml: quadratic runtime on duplicate start-tag attribute names - "RUSTSEC-2026-0195", # quick-xml: unbounded namespace-declaration allocation in NsReader -] diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index be2f36e..db1bde9 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -7904,8 +7904,9 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.31.10" -source = "git+https://github.com/Smithay/wayland-rs?rev=d07c4f91f28b42e5a485823ffd9d8d5a210b1053#d07c4f91f28b42e5a485823ffd9d8d5a210b1053" +version = "0.31.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "338e30461b3a2b67d70eb30a6d89f8e0c93a833e07d2ae89085cd070c4a00ac0" dependencies = [ "proc-macro2", "quick-xml", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index d92bf4d..a79cad5 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -187,9 +187,3 @@ default = ["custom-protocol"] # DO NOT remove this custom-protocol = ["tauri/custom-protocol"] e2e = [] - -# wayland-scanner 0.31.10 still pins vulnerable quick-xml 0.39. Upstream fixed -# RUSTSEC-2026-0194 and RUSTSEC-2026-0195, but has not published the fix yet. -# Remove this patch after the next wayland-scanner release is in the lockfile. -[patch.crates-io] -wayland-scanner = { git = "https://github.com/Smithay/wayland-rs", rev = "d07c4f91f28b42e5a485823ffd9d8d5a210b1053" } diff --git a/src-tauri/src/app_auto_updater.rs b/src-tauri/src/app_auto_updater.rs index e417ba0..9cc77bd 100644 --- a/src-tauri/src/app_auto_updater.rs +++ b/src-tauri/src/app_auto_updater.rs @@ -1742,16 +1742,16 @@ impl AppAutoUpdater { let proxy_ids: Vec = proxy_configs.into_iter().map(|config| config.id).collect(); let vpn_ids: Vec = vpn_configs.into_iter().map(|config| config.id).collect(); - let stop_proxies = futures_util::future::join_all( - proxy_ids - .iter() - .map(|id| crate::proxy_runner::stop_proxy_process(id)), - ); - let stop_vpns = futures_util::future::join_all( - vpn_ids - .iter() - .map(|id| crate::vpn_worker_runner::stop_vpn_worker(id)), - ); + let stop_proxies = futures_util::future::join_all(proxy_ids.iter().map(|id| async move { + crate::proxy_runner::stop_proxy_process(id) + .await + .map_err(|error| error.to_string()) + })); + let stop_vpns = futures_util::future::join_all(vpn_ids.iter().map(|id| async move { + crate::vpn_worker_runner::stop_vpn_worker(id) + .await + .map_err(|error| error.to_string()) + })); let (proxy_results, vpn_results) = tokio::join!(stop_proxies, stop_vpns); for result in proxy_results.into_iter().chain(vpn_results) { @@ -2326,6 +2326,13 @@ not-a-hash Donut_0.29.0_amd64.deb assert!(hooks.contains("Delete \"$INSTDIR\\donut-proxy.exe\"")); } + #[test] + fn test_windows_installer_preparation_future_is_send() { + fn assert_send(_: T) {} + + assert_send(AppAutoUpdater::prepare_windows_installer()); + } + #[test] fn test_platform_specific_download_urls() { let updater = AppAutoUpdater::instance();