Skip to content

fix(webview/slack): first-load + Google auth (#1036)#1249

Open
oxoxDev wants to merge 11 commits intotinyhumansai:mainfrom
oxoxDev:fix/1036-slack-first-load-google-auth
Open

fix(webview/slack): first-load + Google auth (#1036)#1249
oxoxDev wants to merge 11 commits intotinyhumansai:mainfrom
oxoxDev:fix/1036-slack-first-load-google-auth

Conversation

@oxoxDev
Copy link
Copy Markdown
Contributor

@oxoxDev oxoxDev commented May 5, 2026

Summary

  • Fixes Slack Google SSO by treating Slack as a provider that supports Google OAuth parent-navigation inside the embedded webview.
  • Extends Slack's in-app host allowlist with the narrow Google OAuth/resource hosts needed for the auth flow, without allowing bare google.com.
  • Adds reveal diagnostics that log provider, account, trigger (load/watchdog), elapsed spawn-to-reveal time, and bounds for future first-paint investigations.
  • Adds Rust and frontend unit coverage for the new SSO and reveal-trigger behavior.
  • Verified Slack first-load on the post-fix(cef): popup paint dies after first frame — skip blank-page guard for popups (#1079) #1182 build: Slack rendered on first reveal, so no compositor-wake mitigation commit was added.

Problem

  • Slack workspaces that use "Sign in with Google" could send the OAuth popup to the system browser instead of the per-account CEF profile, so the auth cookies landed outside the embedded Slack session.
  • popup_should_navigate_parent only enabled Google auth popup parent-navigation for google-meet; Slack had an existing Google auth detector but never reached it.
  • Slack's allowed-host list only covered Slack-owned hosts, so Google OAuth/resource hosts were not considered in-app for the Slack provider.
  • The Slack first-load blank-tab symptom needed verification on current main before adding any compositor workaround.

Solution

  • Added provider_supports_google_sso(provider) and enabled it for google-meet and slack.
  • Generalized popup_should_navigate_parent to use that helper, while keeping the meet.google.com room rewrite scoped to google-meet only.
  • Added Slack allowlist entries for accounts.google.com, accounts.googleusercontent.com, ssl.gstatic.com, fonts.gstatic.com, lh3.googleusercontent.com, oauth2.googleapis.com, and www.googleapis.com.
  • Threaded reveal trigger metadata through Rust load events and the frontend reveal IPC, then logged reveal timing from webview_account_reveal.
  • Manual verify-then-decide result: Slack rendered normally on first reveal with log reveal trigger=load elapsed_ms=2271; no geometry move, JS injection, or Commit E mitigation needed.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) per docs/TESTING-STRATEGY.md
  • Diff coverage ≥ 80% — covered by the CI diff-cover gate for this PR; local full coverage was not run.
  • N/A: Coverage matrix updated — no new/removed/renamed feature row; existing feature ID 10.1.4 Slack Connection remains the affected row.
  • All affected feature IDs from the matrix are listed in the PR description under ## Related
  • No new external network dependencies introduced (mock backend used per docs/TESTING-STRATEGY.md)
  • N/A: Manual smoke checklist updated — this is not a release-cut checklist change; manual smoke result is documented in this PR body.
  • Linked issue closed via Closes #NNN in the ## Related section

Impact

  • Desktop CEF webview behavior only; no mobile/web/CLI impact.
  • Slack Google OAuth should now complete in the embedded Slack account profile instead of the system browser profile.
  • Google Meet popup behavior is preserved with regression tests for room navigation.
  • Added diagnostic logging is low-volume and only fires on account reveal.
  • No new JS injection and no changes to Slack origin media/notification permission grants.

Related

Summary by CodeRabbit

  • New Features

    • Broader "Sign in with Google" support for Slack SSO flows, including in-app navigation and popup handling.
  • Improvements

    • Webview load events now include explicit reveal triggers (load vs watchdog) and per-account spawn→reveal timing for improved diagnostics and latency logging.
    • Reveal requests now carry trigger context to ensure correct reveal behavior and telemetry.
  • Tests

    • Added/updated tests covering Google SSO allowlist, popup/navigation, and load-trigger propagation.

@oxoxDev oxoxDev requested a review from a team May 5, 2026 20:01
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 5, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Threads a RevealTrigger through webview load signaling, records per-account provider and spawn timestamps, expands Slack allowlist for Google/OAuth hosts, updates popup navigation for Google-SSO-capable providers, and surfaces trigger in emit_load_finished and webview_account_reveal (now using RevealArgs).

Changes

Webview Load Instrumentation & Slack Google OAuth Support

Layer / File(s) Summary
Data Shape
app/src-tauri/src/webview_accounts/mod.rs
Adds RevealTrigger enum; adds RevealArgs { account_id: String, bounds: Bounds, trigger: Option<String> }; WebviewAccountsState gains account_providers: Mutex<HashMap<String,String>> and spawn_started_at: Mutex<HashMap<String, Instant>>.
Core Load Signaling
app/src-tauri/src/webview_accounts/mod.rs
emit_load_finished signature extended to accept trigger: RevealTrigger; emitted webview-account:load payload now includes "trigger" and logging includes trigger.as_str().
CDP Session Wiring
app/src-tauri/src/cdp/session.rs
Watchdog timeout and Page.loadEventFired handlers updated to call emit_load_finished(..., RevealTrigger::Watchdog) or RevealTrigger::Load.
Spawn / Lifecycle Instrumentation
app/src-tauri/src/webview_accounts/mod.rs
On spawn, record spawn_started_at and account_providers; clear them on shutdown/purge paths.
Reveal Command & Metrics
app/src-tauri/src/webview_accounts/mod.rs
webview_account_reveal now accepts RevealArgs; resolves provider from account_providers, computes elapsed ms from spawn_started_at, logs provider+latency+trigger, restores bounds/show, and clears spawn timestamp.
Slack Allowlist & Popup Rules
app/src-tauri/src/webview_accounts/mod.rs
Expanded Slack host allowlist to include Google/OAuth domains; adds provider_supports_google_sso and allows popup→parent navigation for supported providers (e.g., Slack).
Frontend Service Layer
app/src/services/webviewAccountService.ts
WebviewAccountLoadPayload adds optional trigger; handleWebviewAccountLoad maps payload.trigger === 'watchdog''watchdog' else 'load' and passes that trigger to webview_account_reveal.
Tests & Assertions
app/src/services/__tests__/webviewAccountService.loadListener.test.ts, app/src-tauri/src/webview_accounts/mod.rs
Tests updated to send/expect trigger in synthetic webview-account:load events; added Slack Google SSO allowlist and popup/navigation tests; updated reveal-related assertions to include trigger.

Sequence Diagram

sequenceDiagram
    participant Client as Frontend
    participant Service as WebviewAccountService
    participant Tauri as Tauri/WebviewAccountsState
    participant CDP as CDP Session
    participant Webview as Embedded Webview

    rect rgba(200, 220, 255, 0.5)
    Note over Client,Tauri: Cold spawn records provider & spawn time
    Client->>Service: webview_account_open(...)
    Service->>Tauri: webview_account_open command
    Tauri->>Tauri: account_providers[account_id] = provider
    Tauri->>Tauri: spawn_started_at[account_id] = Instant::now()
    Tauri->>Webview: create & navigate webview
    end

    par Load completion
        rect rgba(144, 238, 144, 0.5)
        Webview->>CDP: Page.loadEventFired
        CDP->>Tauri: emit_load_finished(..., state="finished", trigger=Load)
        Tauri->>Service: emit webview-account:load { account_id, url, trigger: "load" }
        end
    and Watchdog fallback
        rect rgba(255, 200, 200, 0.5)
        CDP->>CDP: timeout elapsed
        CDP->>Tauri: emit_load_finished(..., state="timeout", trigger=Watchdog)
        Tauri->>Service: emit webview-account:load { account_id, url, trigger: "watchdog" }
        end
    end

    rect rgba(220, 200, 255, 0.5)
    Service->>Service: handleWebviewAccountLoad(payload)
    Service->>Tauri: invoke webview_account_reveal(RevealArgs{..., trigger})
    Tauri->>Tauri: provider = account_providers[account_id] || "unknown"
    Tauri->>Tauri: elapsed_ms = now - spawn_started_at[account_id]
    Tauri->>Tauri: log(provider, elapsed_ms, trigger)
    Tauri->>Webview: restore bounds & show
    Tauri->>Tauri: remove spawn_started_at[account_id]
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • graycyrus
  • senamakel

Poem

🐰 I tracked each spawn and whispered "now",
When load or watchdog gave a vow;
Slack's Google doors I let pass through,
Bounds restored and signals true —
Hooray, the tiny rabbit says, we grew!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the fix addressing Slack's first-load UI issue and Google authentication, matching the main objectives of the changeset.
Linked Issues check ✅ Passed The PR implements key requirements from #1036: enables Google SSO support for Slack, adds reveal-trigger diagnostics for load debugging, extends Slack host allowlist for OAuth flows, and includes comprehensive tests for the new behavior.
Out of Scope Changes check ✅ Passed All changes are directly scoped to issue #1036: updates to session load-signal emission, Google SSO provider support, reveal-trigger metadata threading, and related test coverage. No unrelated modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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


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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
app/src/services/__tests__/webviewAccountService.loadListener.test.ts (1)

184-195: 💤 Low value

Consider adding a test case for watchdog trigger propagation.

The tests cover trigger: 'load' (the default), but there's no explicit test verifying that trigger: 'watchdog' from the payload propagates correctly to the reveal call. This would lock the behavior for the timeout-recovery-then-late-load scenario.

💡 Optional test case for watchdog trigger
it('propagates watchdog trigger to reveal when payload specifies watchdog', async () => {
  const bounds = { x: 0, y: 0, width: 800, height: 600 };
  await openWebviewAccount({ accountId: ACCOUNT_ID, provider: 'telegram', bounds });
  vi.mocked(invoke).mockClear();

  await fireLoadEvent({ state: 'finished', trigger: 'watchdog', url: 'https://web.telegram.org/' });

  expect(vi.mocked(invoke)).toHaveBeenCalledWith('webview_account_reveal', {
    args: { account_id: ACCOUNT_ID, bounds, trigger: 'watchdog' },
  });
});
🤖 Prompt for 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.

In `@app/src/services/__tests__/webviewAccountService.loadListener.test.ts` around
lines 184 - 195, Add a test that verifies the `trigger: 'watchdog'` from the
load payload is propagated to the reveal call: use openWebviewAccount to open
the account (referencing ACCOUNT_ID and bounds), clear vi.mocked(invoke), call
fireLoadEvent with { state: 'finished', trigger: 'watchdog', url:
'https://web.telegram.org/' }, and assert vi.mocked(invoke) was called with
'webview_account_reveal' and args { account_id: ACCOUNT_ID, bounds, trigger:
'watchdog' } (mirroring the existing tests that use openWebviewAccount,
fireLoadEvent and invoke).
🤖 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.

Nitpick comments:
In `@app/src/services/__tests__/webviewAccountService.loadListener.test.ts`:
- Around line 184-195: Add a test that verifies the `trigger: 'watchdog'` from
the load payload is propagated to the reveal call: use openWebviewAccount to
open the account (referencing ACCOUNT_ID and bounds), clear vi.mocked(invoke),
call fireLoadEvent with { state: 'finished', trigger: 'watchdog', url:
'https://web.telegram.org/' }, and assert vi.mocked(invoke) was called with
'webview_account_reveal' and args { account_id: ACCOUNT_ID, bounds, trigger:
'watchdog' } (mirroring the existing tests that use openWebviewAccount,
fireLoadEvent and invoke).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b7905dcd-60cf-450d-8229-3fdf5860a2f0

📥 Commits

Reviewing files that changed from the base of the PR and between ec4d3de and 48c3476.

📒 Files selected for processing (4)
  • app/src-tauri/src/cdp/session.rs
  • app/src-tauri/src/webview_accounts/mod.rs
  • app/src/services/__tests__/webviewAccountService.loadListener.test.ts
  • app/src/services/webviewAccountService.ts

coderabbitai[bot]
coderabbitai Bot previously approved these changes May 5, 2026
@oxoxDev
Copy link
Copy Markdown
Contributor Author

oxoxDev commented May 5, 2026

Addressed the CodeRabbit watchdog-trigger test nit in df18b80. Added explicit coverage that a load payload with trigger='watchdog' propagates to webview_account_reveal; targeted Vitest passes 11/11.

coderabbitai[bot]
coderabbitai Bot previously approved these changes May 5, 2026
Copy link
Copy Markdown
Member

@senamakel senamakel left a comment

Choose a reason for hiding this comment

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

resolve the merge conflicts and push again

@oxoxDev
Copy link
Copy Markdown
Contributor Author

oxoxDev commented May 6, 2026

Resolved the merge conflicts against upstream/main in signed merge 20d34c5, then cleaned the final diff back to the four #1036 files in 8f3fc56. Local focused validation passed: webview_accounts 69/69, cdp::session 10/10, agent::prompts 35/35, and targeted Vitest load listener 11/11. CI is re-running on head 8f3fc56.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
app/src-tauri/src/webview_accounts/mod.rs (1)

2721-2735: 💤 Low value

Inconsistent mutex handling for diagnostic lookups.

account_providers uses .lock().unwrap() (panics on poison) while spawn_started_at uses .lock().ok() (graceful fallback). Since both are for diagnostic logging only, consider using consistent handling. Given the codebase pattern uses .unwrap() elsewhere, using .unwrap() for spawn_started_at as well would be consistent.

♻️ Suggested consistency fix
     let elapsed_ms = state
         .spawn_started_at
         .lock()
-        .ok()
+        .unwrap()
-        .and_then(|mut g| g.remove(&args.account_id))
+        .remove(&args.account_id)
         .map(|started| started.elapsed().as_millis())
         .map(|ms| ms.to_string())
         .unwrap_or_else(|| "unknown".to_string());
🤖 Prompt for 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.

In `@app/src-tauri/src/webview_accounts/mod.rs` around lines 2721 - 2735, The
diagnostic lookup for spawn_started_at should match the established
panic-on-poison pattern used for account_providers: replace the current graceful
.lock().ok() path with a direct .lock().unwrap() usage so both mutexes behave
consistently; locate the block that reads spawn_started_at (using
state.spawn_started_at and args.account_id) and change the locking + removal
sequence to use .lock().unwrap() before removing the entry and computing
elapsed, keeping the same map.remove/started.elapsed()/as_millis()->to_string
flow as the surrounding code.
🤖 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.

Nitpick comments:
In `@app/src-tauri/src/webview_accounts/mod.rs`:
- Around line 2721-2735: The diagnostic lookup for spawn_started_at should match
the established panic-on-poison pattern used for account_providers: replace the
current graceful .lock().ok() path with a direct .lock().unwrap() usage so both
mutexes behave consistently; locate the block that reads spawn_started_at (using
state.spawn_started_at and args.account_id) and change the locking + removal
sequence to use .lock().unwrap() before removing the entry and computing
elapsed, keeping the same map.remove/started.elapsed()/as_millis()->to_string
flow as the surrounding code.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7fbc3eb0-5d02-4155-9b66-18607c69c31d

📥 Commits

Reviewing files that changed from the base of the PR and between df18b80 and 8f3fc56.

📒 Files selected for processing (1)
  • app/src-tauri/src/webview_accounts/mod.rs

coderabbitai[bot]
coderabbitai Bot previously approved these changes May 6, 2026
@oxoxDev
Copy link
Copy Markdown
Contributor Author

oxoxDev commented May 6, 2026

Addressed the latest CodeRabbit mutex-consistency nit in signed commit d452231 by aligning the reveal diagnostic spawn_started_at lock handling with the existing account_providers unwrap pattern. Local validation passed: cargo fmt --manifest-path app/src-tauri/Cargo.toml --all --check and cargo test --manifest-path app/src-tauri/Cargo.toml --lib webview_accounts (69/69).

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/src-tauri/src/webview_accounts/mod.rs (1)

2228-2238: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Start the reveal timer before add_child.

elapsed_ms is supposed to capture cold-spawn → reveal time, but the clock starts only after add_child returns, so browser creation time is missing from the new diagnostic.

Proposed fix
+    let spawn_started = Instant::now();
     let webview = parent_window
         .add_child(builder, initial_position, initial_size)
         .map_err(|e| format!("add_child failed: {e}"))?;
@@
     state
         .spawn_started_at
         .lock()
         .unwrap()
-        .insert(args.account_id.clone(), Instant::now());
+        .insert(args.account_id.clone(), spawn_started);

As per coding guidelines, "**/*.rs: Default to verbose diagnostics on new/changed flows with entry/exit logging, branches, external calls, retries/timeouts, state transitions, and errors`.

🤖 Prompt for 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.

In `@app/src-tauri/src/webview_accounts/mod.rs` around lines 2228 - 2238, Move the
cold-spawn timer start to before the call to parent_window.add_child so the
measured elapsed_ms includes browser creation time: acquire the spawn_started_at
lock and insert args.account_id -> Instant::now() before invoking
parent_window.add_child (the code that currently assigns webview), keeping the
same data structure and error handling around add_child and preserving the
existing webview variable assignment and logging paths.
🧹 Nitpick comments (1)
app/src-tauri/src/webview_accounts/mod.rs (1)

265-317: 🏗️ Heavy lift

Consider splitting the new Google-SSO policy and reveal telemetry out of mod.rs.

This file is already carrying too many responsibilities, and these additions make navigation/reveal regressions harder to reason about. Pulling the new provider-policy helpers and reveal-trigger/state plumbing into small submodules would make future fixes safer.

As per coding guidelines, "**/*.rs: Prefer modules ≤ ~500 lines; split growing modules`.

Also applies to: 617-655, 1337-1585

🤖 Prompt for 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.

In `@app/src-tauri/src/webview_accounts/mod.rs` around lines 265 - 317, The module
mod.rs is getting large and mixing concerns: extract the Google-SSO popup policy
helpers (provider_supports_google_sso, popup_should_navigate_parent, and any
helpers like is_google_auth_popup) into a small submodule (e.g.,
webview_accounts/google_sso.rs) and move the reveal/telemetry trigger and state
plumbing mentioned elsewhere into a separate submodule (e.g.,
webview_accounts/reveal_telemetry.rs); update mod.rs to re-export the functions
or call them via the new submodules, keep public APIs unchanged, and ensure unit
tests/imports are updated to reference the new module paths so mod.rs stays
under ~500 lines and responsibilities are separated.
🤖 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/webview_accounts/mod.rs`:
- Around line 1359-1363: The current from_ipc(raw: Option<&str>) silently maps
any unknown trigger to Self::Load; change it to surface unexpected IPC values by
either (A) adding an explicit Unknown(String) variant to the RevealTrigger enum
and returning Unknown(raw.unwrap_or_default().to_string()) for anything not
matching "watchdog" or "load" (and add a tracing::warn or log entry with the raw
value), or (B) change from_ipc to return a Result<RevealTrigger, String> and
return Err(format!("unknown reveal trigger: {:?}", raw)) for unexpected inputs
while logging the value; update all call sites of from_ipc (e.g., where
RevealTrigger is constructed) to handle the new Unknown/Result case so unknown
IPC inputs are logged and not silently remapped to Load.

---

Outside diff comments:
In `@app/src-tauri/src/webview_accounts/mod.rs`:
- Around line 2228-2238: Move the cold-spawn timer start to before the call to
parent_window.add_child so the measured elapsed_ms includes browser creation
time: acquire the spawn_started_at lock and insert args.account_id ->
Instant::now() before invoking parent_window.add_child (the code that currently
assigns webview), keeping the same data structure and error handling around
add_child and preserving the existing webview variable assignment and logging
paths.

---

Nitpick comments:
In `@app/src-tauri/src/webview_accounts/mod.rs`:
- Around line 265-317: The module mod.rs is getting large and mixing concerns:
extract the Google-SSO popup policy helpers (provider_supports_google_sso,
popup_should_navigate_parent, and any helpers like is_google_auth_popup) into a
small submodule (e.g., webview_accounts/google_sso.rs) and move the
reveal/telemetry trigger and state plumbing mentioned elsewhere into a separate
submodule (e.g., webview_accounts/reveal_telemetry.rs); update mod.rs to
re-export the functions or call them via the new submodules, keep public APIs
unchanged, and ensure unit tests/imports are updated to reference the new module
paths so mod.rs stays under ~500 lines and responsibilities are separated.
🪄 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: d370c450-4b2b-4a52-8c01-d6ef717c53fe

📥 Commits

Reviewing files that changed from the base of the PR and between 8f3fc56 and d452231.

📒 Files selected for processing (1)
  • app/src-tauri/src/webview_accounts/mod.rs

Comment thread app/src-tauri/src/webview_accounts/mod.rs
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/src-tauri/src/webview_accounts/mod.rs (1)

292-300: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Handle direct Google OAuth authorize popups, not just signin/account-chooser URLs.

This new Slack path only stays in-app when is_google_auth_popup(url) returns true, but that helper currently looks for signin / ServiceLogin / chooser / SetSID markers. A plain Google authorize URL such as accounts.google.com/o/oauth2/... would still miss this branch and fall through to the system-browser handoff, which is exactly the Slack SSO breakage this PR is trying to close.

Suggested fix
 fn is_google_auth_popup(url: &Url) -> bool {
     let Some(host) = url.host_str() else {
         return false;
     };
     if !is_google_sso_host(host) {
         return false;
     }

     let path = url.path().to_ascii_lowercase();
     if path.contains("signin")
         || path.contains("servicelogin")
         || path.contains("accountchooser")
         || path.contains("chooseaccount")
+        || path.contains("oauth")
         || path.contains("setsid")
     {
         return true;
     }

     url.query_pairs().any(|(key, value)| {
         let k = key.to_ascii_lowercase();
         let v = value.to_ascii_lowercase();
         matches!(k.as_str(), "flowname" | "service" | "continue")
             && (v.contains("signin")
                 || v.contains("servicelogin")
                 || v.contains("accountchooser")
                 || v.contains("chooseaccount")
+                || v.contains("oauth")
                 || v.contains("meet.google.com")
                 || v.contains("mail.google.com"))
     })
 }
🤖 Prompt for 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.

In `@app/src-tauri/src/webview_accounts/mod.rs` around lines 292 - 300,
popup_should_navigate_parent currently only returns the popup URL for Google SSO
when is_google_auth_popup matches signin/chooser markers, missing plain OAuth
authorize endpoints (e.g., accounts.google.com/o/oauth2/...); update
is_google_auth_popup (or add a new check used by popup_should_navigate_parent)
to also detect Google OAuth authorize URLs by checking the host
(accounts.google.com) and the path prefix "/o/oauth2" (and common variants like
"/o/oauth2/v2/auth"), or by detecting OAuth-specific query params such as
"client_id" and "redirect_uri"; keep provider_supports_google_sso and the
existing about-scheme guard and return Some(url.clone()) when this new
OAuth-authorize detection matches.
🤖 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.

Outside diff comments:
In `@app/src-tauri/src/webview_accounts/mod.rs`:
- Around line 292-300: popup_should_navigate_parent currently only returns the
popup URL for Google SSO when is_google_auth_popup matches signin/chooser
markers, missing plain OAuth authorize endpoints (e.g.,
accounts.google.com/o/oauth2/...); update is_google_auth_popup (or add a new
check used by popup_should_navigate_parent) to also detect Google OAuth
authorize URLs by checking the host (accounts.google.com) and the path prefix
"/o/oauth2" (and common variants like "/o/oauth2/v2/auth"), or by detecting
OAuth-specific query params such as "client_id" and "redirect_uri"; keep
provider_supports_google_sso and the existing about-scheme guard and return
Some(url.clone()) when this new OAuth-authorize detection matches.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 95458fdc-32e3-4537-9dab-d4136b11a0e7

📥 Commits

Reviewing files that changed from the base of the PR and between d452231 and 1772d68.

📒 Files selected for processing (1)
  • app/src-tauri/src/webview_accounts/mod.rs

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix Slack webview first-load UI and Google auth failures

2 participants