fix(tauri): forward deep-link URLs on Linux before CEF preflight exits secondary#2458
fix(tauri): forward deep-link URLs on Linux before CEF preflight exits secondary#2458M3gA-Mind wants to merge 2 commits into
Conversation
…s secondary On Linux, OAuth callbacks launch a second binary with the URL in argv. That secondary hits cef_preflight::check_default_cache() and exits(1) before Builder::setup() runs, silently dropping the URL. Adds deep_link_ipc.rs (Linux-only): the primary binds a Unix domain socket at $XDG_RUNTIME_DIR/com.openhuman.app-deeplink.sock before the CEF preflight check. A secondary instance that finds openhuman:// URLs in argv connects, writes them, and exits(0) — never reaching the preflight. On setup(), drain_pending_urls emits deep-link://new-url events to the app handle for each queued URL. This mirrors the Windows pre-CEF named-mutex guard (lib.rs:2092-2128) for the Linux case. Closes tinyhumansai#2359
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds a Linux-only Unix-socket IPC that forwards ChangesLinux deep-link IPC forwarding
Sequence DiagramsequenceDiagram
participant SecondaryProcess as Secondary Process
participant UnixSocket as Unix Socket
participant PrimaryProcess as Primary Process
SecondaryProcess->>SecondaryProcess: extract_deep_link_urls() from argv
alt URLs present
SecondaryProcess->>UnixSocket: try_forward_deep_links() connect & write
alt Primary listening
UnixSocket->>PrimaryProcess: newline-delimited openhuman:// URLs
SecondaryProcess->>SecondaryProcess: exit(0) with Forwarded result
else No primary
SecondaryProcess->>SecondaryProcess: return NoPrimary, continue to bind
end
else No URLs
SecondaryProcess->>SecondaryProcess: return NoUrls
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/src-tauri/src/deep_link_ipc.rs`:
- Around line 115-117: The debug logs currently print full deep-link URLs (which
may include secrets); add a helper function named redact_url_for_log(url: &str)
-> String that parses the URL and strips query and fragment (falling back to
"<invalid deep link>"), then use that helper wherever URLs are logged: replace
direct uses in the pending_queue() lock block (the log! call that prints url),
and the other logging sites referenced (around the handlers at the locations you
noted) to log redact_url_for_log(&url) instead of the raw url string; ensure the
pushed value into the pending queue remains the original url (only redact for
logging).
- Around line 141-145: The unconditional std::fs::remove_file(&path) before
binding can delete a live socket from another instance; change bind_and_listen()
to first attempt UnixListener::bind(&path) and only if that fails due to
"address in use" try to probe the existing socket with
UnixStream::connect(&path) (or equivalent) to determine if a server is alive; if
connect succeeds, return a suitable ForwardResult/err indicating another
instance is active, and if connect fails (stale socket), then unlink the file
and retry UnixListener::bind(&path). Ensure you specifically update the code
paths around bind_and_listen(), UnixListener::bind, and the remove_file usage to
perform bind-first, probe-with-UnixStream::connect, then remove_file+retry only
when confirmed stale.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: a326d97f-8d4d-4690-8171-0d2a4f862a63
📒 Files selected for processing (2)
app/src-tauri/src/deep_link_ipc.rsapp/src-tauri/src/lib.rs
Address CodeRabbit review on PR tinyhumansai#2458: 1. Add `redact_url_for_log()` helper that strips query string and fragment before logging deep-link URLs. OAuth callbacks carry tokens in the query string; logging the raw URL persists secrets in log files and crash reports. 2. Change `bind_and_listen()` from unconditional remove-then-bind to a bind-first approach: attempt bind, then on AddrInUse probe the existing socket with `UnixStream::connect` to distinguish a live primary (leave it alone, return None) from a stale socket after a crash (safe to remove and retry bind). Prevents a concurrent secondary from deleting a live primary's socket file.
M3gA-Mind
left a comment
There was a problem hiding this comment.
Both CodeRabbit items addressed in commit f4bebd6:
- Added
redact_url_for_log()helper that strips query/fragment before logging — OAuth tokens no longer appear in log output. - Changed
bind_and_listen()to bind-first: probes the existing socket withUnixStream::connectto distinguish live primary (skip) from stale socket after crash (remove+retry).
|
@graycyrus This Linux deep-link forwarding fix is also green and mergeable. It covers the Linux side of OAuth/deep-link delivery before CEF preflight exits a secondary instance (#2359). CodeRabbit approved/no actionable comments; please review/merge when you can. |
Summary
app/src-tauri/src/deep_link_ipc.rs— Linux-only (#[cfg(target_os = "linux")]) Unix domain socket-based pre-CEF deep-link forwarder.$XDG_RUNTIME_DIR/com.openhuman.app-deeplink.sock(fallback:/tmp/com_openhuman_app_deeplink_{uid}.sock) BEFOREcef_preflight::check_default_cache(). Queues any arriving URLs untilsetup()runs.exit(0)— never reaching the CEF preflight.drain_pending_urls(called insetup()after deep-link plugin registration) drains the queue and installs a live handler that emitsdeep-link://new-urlevents to theAppHandlefor all future arrivals.Problem
On Linux,
openhuman://OAuth callbacks launch a secondOpenHumanbinary with the URL asargv[1]. The secondary hitscef_preflight::check_default_cache()atlib.rs:2155which detects the CEF cache lock held by the primary and callsstd::process::exit(1)— beforeBuilder::build()orBuilder::setup()runs. Thetauri-plugin-single-instanceD-Bus forwarding andtauri-plugin-deep-linkregistration both live insetup(), so they never execute. The OAuth URL is silently dropped.Windows already has a fix: the pre-CEF named-mutex guard at
lib.rs:2092-2128detects secondaries and forwards URLs before any CEF init. This PR applies the equivalent pattern to Linux using Unix domain sockets.Solution
The fix inserts a guard at
lib.rslines 2152–2167 (between the Windows mutex guard and the CEF preflight). On Linux:Submission Checklist
deep_link_ipc.rs(socket_path_uses_xdg_runtime_dir,socket_path_fallback_has_uid,extract_deep_link_urls_filters_correctly,round_trip_bind_connect_forward,no_primary_returns_appropriate_result)cargo checkcleannix(already a dep withuserfeature),url(already a dep),tempfile(already in dev-deps)Closes #2359Impact
#[cfg(target_os = "linux")].openhuman://via Apple Events to the already-running process (RunEvent::Opened) — no secondary binary is launched, so no CEF race exists.Related
AI Authored PR Metadata
Linear Issue
Commit & Branch
Validation Run
pnpm --filter openhuman-app format:check— N/A (no frontend changes)pnpm typecheck— N/A (no frontend changes)cargo test --manifest-path app/src-tauri/Cargo.toml -- deep_link_ipc— gated to Linux, not compiled on macOS CIcargo fmt --manifest-path app/src-tauri/Cargo.toml --all -- --checkpasses;cargo check --manifest-path app/src-tauri/Cargo.tomlcleanValidation Blocked
command:cargo test --manifest-path app/src-tauri/Cargo.toml -- deep_link_ipcerror:All tests are#[cfg(target_os = "linux")]— not compiled on macOS dev machineimpact:Tests will run in CI on Linux. The socket round-trip logic has been code-reviewed; it follows the same pattern as the proven Windows mutex guard.Behavior Changes
openhuman://deep-link callbacks on Linux reach the running app and complete OAuthParity Contract
Duplicate / Superseded PR Handling
Summary by CodeRabbit