Skip to content

fix(tauri): forward Windows local-runtime OAuth callbacks#2469

Merged
M3gA-Mind merged 4 commits into
tinyhumansai:mainfrom
Jessomadic:fix/windows-oauth-local-runtime-2462-2466
May 22, 2026
Merged

fix(tauri): forward Windows local-runtime OAuth callbacks#2469
M3gA-Mind merged 4 commits into
tinyhumansai:mainfrom
Jessomadic:fix/windows-oauth-local-runtime-2462-2466

Conversation

@Jessomadic
Copy link
Copy Markdown
Contributor

@Jessomadic Jessomadic commented May 22, 2026

Summary

  • Add a Windows-only pre-CEF named-pipe bridge for openhuman:// callbacks.
  • Forward OAuth deep-link argv from the secondary process to the primary before the existing CEF mutex guard exits.
  • Drain queued URLs after Tauri deep-link registration so the existing frontend listener handles login normally.
  • Restore missing German i18n keys and update the Windows installer workflow to use pnpm so CI and the manual Windows build pass.

Root Cause

The Windows pre-CEF mutex guard exits secondary OpenHuman.exe launches before Tauri's single-instance/deep-link plugins can run. Browser OAuth callbacks arrive as a secondary launch with openhuman://auth?token=..., so the callback URL was dropped while the already-running app only regained focus.

User Impact

This should unblock Windows local runtime sign-in when users choose Google or GitHub and the browser callback says it will reopen OpenHuman.

Closes #2462
Closes #2466

Validation

  • cargo fmt --manifest-path app/src-tauri/Cargo.toml --all -- --check
  • git diff --check
  • cargo metadata --manifest-path app/src-tauri/Cargo.toml --format-version 1 --no-deps
  • pnpm i18n:check
  • Upstream PR checks passing on latest head 3f49b679.
  • Manual Windows installer workflow passed in Jessomadic/openhuman Actions run 26261894271, producing windows-msi and windows-nsis artifacts.

Blocked locally:

  • cargo test --manifest-path app/src-tauri/Cargo.toml deep_link_ipc_windows --lib reached native build scripts but could not complete because this machine is missing libclang.dll for whisper-rs-sys and ninja for cef-dll-sys.

Summary by CodeRabbit

  • New Features

    • Improved deep-link handling on Windows to ensure URLs open correctly when multiple instances are running.
  • Documentation

    • Added German translations for new subconscious and MCP server settings features.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 22, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 160a382b-710f-4290-9fa2-e92c1b75305d

📥 Commits

Reviewing files that changed from the base of the PR and between 7fe3dd0 and 3f49b67.

📒 Files selected for processing (6)
  • .github/workflows/build-windows.yml
  • app/src-tauri/Cargo.toml
  • app/src-tauri/src/deep_link_ipc_windows.rs
  • app/src-tauri/src/lib.rs
  • app/src/lib/i18n/chunks/de-3.ts
  • app/src/lib/i18n/chunks/de-5.ts

📝 Walkthrough

Walkthrough

This PR adds Windows-specific named-pipe inter-process communication to forward OAuth and deep-link callbacks from secondary instances to the primary instance, solving a pre-CEF startup delivery problem. It also updates the Windows CI workflow to use pnpm and adds German translations for MCP and subconscious features.

Changes

Windows Deep-Link IPC System

Layer / File(s) Summary
Build and dependency configuration
.github/workflows/build-windows.yml, app/src-tauri/Cargo.toml
Windows CI workflow enables Corepack and switches to pnpm install --frozen-lockfile; Cargo.toml extends windows-sys features with Win32_Storage_FileSystem, Win32_System_IO, and Win32_System_Pipes for named-pipe operations.
Deep-Link IPC module implementation
app/src-tauri/src/deep_link_ipc_windows.rs
New module implements named-pipe based URL forwarding: secondary instances collect openhuman:// URLs from CLI arguments, retry-open the primary's pipe for writing, and send URLs; the primary spawns a background listener thread that reads URLs, logs redacted forms, and dispatches them to an installed handler or queues them until Tauri setup; unit tests cover URL extraction, redaction, and pipe naming.
Integration into app startup
app/src-tauri/src/lib.rs
Windows builds declare the new module and wire it into the pre-CEF single-instance path: secondary instances invoke try_forward_deep_links() before exiting, primary instances bind the listener via bind_and_listen() and drain queued URLs via drain_pending_urls() during setup.

German Localization Updates

Layer / File(s) Summary
Subconscious and MCP translations
app/src/lib/i18n/chunks/de-3.ts, app/src/lib/i18n/chunks/de-5.ts
Added German i18n entries for subconscious provider unavailability and settings; added MCP developer menu and server settings translations with client names, error messages, and section labels; relocated existing integration-trigger translations.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

  • tinyhumansai/openhuman#1723: Both modify the Windows pre-CEF single-instance startup logic and windows-sys features; this PR extends that foundation with deep-link URL forwarding.
  • tinyhumansai/openhuman#2229: Both target Windows OAuth/deep-link callback delivery; this PR uses custom named-pipe IPC while the related PR explores Tauri's built-in single-instance plugin.

Suggested labels

bug

Suggested reviewers

  • senamakel
  • graycyrus

🐰 Named pipes dance in Windows air,
Deep links forwarded with utmost care,
Secondary whispers to primary's ear,
OAuth tokens delivered loud and clear!
German words now grace the UI scene, 🌍

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'fix(tauri): forward Windows local-runtime OAuth callbacks' accurately summarizes the main change: implementing a Windows-specific mechanism to forward OAuth deep-link callbacks to the primary process.
Linked Issues check ✅ Passed The PR successfully addresses both linked issues: implementing named-pipe forwarding for OAuth callbacks (#2462, #2466) to fix Windows deep-link handling, including necessary Windows-sys features, workflow updates, and i18n translations.
Out of Scope Changes check ✅ Passed All changes are in-scope: Windows deep-link forwarding logic, Cargo feature additions for Win32 APIs, i18n German translations for MCP support and UI text, and CI workflow updates to use pnpm—all supporting the core OAuth callback fix.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Jessomadic Jessomadic marked this pull request as ready for review May 22, 2026 01:41
@Jessomadic Jessomadic requested a review from a team May 22, 2026 01:41
@coderabbitai coderabbitai Bot added the bug label May 22, 2026
@YOMXXX
Copy link
Copy Markdown
Contributor

YOMXXX commented May 22, 2026

@graycyrus @senamakel This is currently the highest-impact user-facing blocker I found in today's issue triage: it addresses the Windows sign-in/deep-link loop reported in #2466 and likely #2462/#2473. Latest effective CI is green, CodeRabbit approved/no actionable comments, and the PR is mergeable. Please prioritize human review/merge if the implementation direction looks acceptable.

Copy link
Copy Markdown
Contributor

@M3gA-Mind M3gA-Mind left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Windows OAuth callback — pre-CEF named-pipe bridge

Clean, well-scoped fix. The root cause (pre-CEF mutex guard exiting secondary before Tauri's single-instance/deep-link plugins can run) is correctly diagnosed, and the three-phase solution — secondary forwards via pipe → primary listens → drain on deep-link registration — maps directly to the problem. The fix is Windows-only and properly gated with #![cfg(target_os = "windows")] in the module file plus call sites behind #[cfg(windows)] in lib.rs.

A few things done well: redact_url_for_log strips query/fragment before logging so OAuth tokens never appear in logs or Sentry breadcrumbs; unit tests cover arg filtering, URL redaction, and pipe name stability; the yarn → pnpm CI fix unblocks the Windows workflow for everyone.

Change summary

Area Files Summary
Tauri shell (Windows) deep_link_ipc_windows.rs (new, 373 LOC) Named-pipe bridge: secondary forwards URLs, primary listens and drains
Tauri shell (Windows) lib.rs Wires bridge into the pre-CEF mutex secondary-exit path and setup()
Cargo Cargo.toml Adds Win32_Storage_FileSystem, Win32_System_IO, Win32_System_Pipes
CI build-windows.yml Corepack + pnpm install --frozen-lockfile
i18n de-3.ts, de-5.ts Restores missing German translations for subconscious + MCP server settings

One minor note inline; no blockers.

}
}

if let Ok(mut queue) = pending_queue().lock() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[minor] Two separate lock acquisitions create a narrow TOCTOU window.

If a URL arrives from the pipe thread after the live_handler lock is released (handler seen as None) but before pending_queue is locked here, drain_pending_urls can fire on the setup thread between those two points — it sets the handler and drains the queue — leaving the URL pushed into an already-drained queue with no subsequent drain scheduled.

The window is startup-only (only open until setup() runs) and realistically only reachable if a second OAuth callback fires while the app is still initialising, so the blast radius is negligible in practice. A straightforward fix is to hold a single combined lock through both operations, or to check the handler again after acquiring the queue lock:

if let Ok(mut queue) = pending_queue().lock() {
    // Re-check handler under the queue lock to close the TOCTOU window
    if let Ok(guard) = live_handler().lock() {
        if let Some(ref handler) = *guard {
            handler(url);
            return;
        }
    }
    queue.push(url);
}

Copy link
Copy Markdown
Contributor

@M3gA-Mind M3gA-Mind left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pr-manager: TOCTOU fix below is required before merge. The fix has been committed locally on pr/2469 — apply the patch to your branch and push. All other checks (typecheck, lint, cargo check core + tauri) pass.

}
}

if let Ok(mut queue) = pending_queue().lock() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix (applied locally, needs push to PR branch): Addressing the TOCTOU window flagged by @M3gA-Mind.

Acquire pending_queue first, then re-check live_handler under that lock. This closes the window where drain_pending_urls could fire between the two separate lock acquisitions.

fn dispatch_url(url: String) {
    if let Ok(mut queue) = pending_queue().lock() {
        // Re-check handler under the queue lock to close the TOCTOU window:
        // if drain_pending_urls fires between releasing the handler lock and
        // acquiring the queue lock, the URL would be pushed into an already-
        // drained queue with no subsequent drain scheduled.
        if let Ok(guard) = live_handler().lock() {
            if let Some(ref handler) = *guard {
                handler(url);
                return;
            }
        }
        log::debug!(
            \"[deep-link-ipc] queued URL before setup: {}\",
            redact_url_for_log(&url)
        );
        queue.push(url);
    }
}

Please apply this patch to your branch and push.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OAuth deep link "openhuman://auth?token=..." is ignored on Windows 11 — app stays on login screen No local runtime works

3 participants