diff --git a/app/src-tauri/Cargo.lock b/app/src-tauri/Cargo.lock index abdba067f4..bef84a5631 100644 --- a/app/src-tauri/Cargo.lock +++ b/app/src-tauri/Cargo.lock @@ -7999,6 +7999,7 @@ dependencies = [ "serde", "serde_json", "tauri", + "tauri-plugin-deep-link", "thiserror 2.0.18", "tracing", "windows-sys 0.60.2", diff --git a/app/src-tauri/Cargo.toml b/app/src-tauri/Cargo.toml index 47d2b61773..c217fd699e 100644 --- a/app/src-tauri/Cargo.toml +++ b/app/src-tauri/Cargo.toml @@ -50,8 +50,10 @@ tauri-plugin-opener = "2" # `cef::initialize(...) != 1` cache-lock panic seen in production # (Sentry OPENHUMAN-TAURI-A). The plugin acquires a per-identifier # lock before any tauri::Builder work happens, so the secondary -# process exits cleanly after handing its argv to the primary. -tauri-plugin-single-instance = "2" +# process exits cleanly after handing its argv to the primary. The `deep-link` +# feature forwards second-launch deep-link payloads to the primary instance on +# Windows/Linux, which is required for hot-instance OAuth callbacks. +tauri-plugin-single-instance = { version = "2", features = ["deep-link"] } # Auto-update for the Tauri shell itself. The core sidecar already has its own # updater (see `core_update.rs`); this plugin handles the .app/.exe/.AppImage # bundle. Both are needed because shipping a new RPC method requires both diff --git a/app/src-tauri/src/lib.rs b/app/src-tauri/src/lib.rs index b3d3ea1dd8..222d83e8f0 100644 --- a/app/src-tauri/src/lib.rs +++ b/app/src-tauri/src/lib.rs @@ -3714,4 +3714,34 @@ mod tests { None => std::env::remove_var("PATH"), } } + + /// Regression guard for issue #2228: `tauri-plugin-single-instance` must + /// enable the `deep-link` feature so that second-launch deep-link payloads + /// (e.g. `openhuman://oauth/...` callbacks from Windows/Linux system + /// browsers) are forwarded into the primary instance. Without it, hot OAuth + /// callbacks silently no-op while only focusing the existing window. + #[test] + fn single_instance_dep_enables_deep_link_feature() { + let manifest_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("Cargo.toml"); + let manifest = + std::fs::read_to_string(&manifest_path).expect("read app/src-tauri/Cargo.toml"); + let parsed: toml::Value = manifest.parse().expect("parse Cargo.toml"); + + let dep = parsed + .get("dependencies") + .and_then(|d| d.get("tauri-plugin-single-instance")) + .expect("tauri-plugin-single-instance dependency must exist"); + + let features = dep.get("features").and_then(|f| f.as_array()).expect( + "tauri-plugin-single-instance must be a table with a `features` array \ + — issue #2228 requires the `deep-link` feature to forward hot-instance \ + OAuth callbacks on Windows/Linux", + ); + + assert!( + features.iter().any(|v| v.as_str() == Some("deep-link")), + "tauri-plugin-single-instance must enable the `deep-link` feature \ + (issue #2228 — hot-instance OAuth callback forwarding)" + ); + } }