Fix/desktop oauth connect opener#270
Merged
Merged
Conversation
…ct buttons)
The integration connect buttons (Gmail/Calendar/GitHub/…) did nothing on
desktop. The frontend is a remote-origin webview (http://localhost:8788), and
Tauri v2's ACL rejects custom app commands from remote origins ("not allowed by
ACL" — same failure as the removed Switch-to-CLI button). So invoke("open_url")
threw, the error was swallowed in openExternalUrl, and the window.open fallback
is a no-op inside the webview → nothing happened.
Fix: use the official tauri-plugin-opener, whose opener:allow-open-url permission
is designed to work from remote webviews. Register the plugin, grant the
permission (scoped to http/https) in capabilities/default.json, and point
openExternalUrl at plugin:opener|open_url. This is the single chokepoint for all
connect buttons + cloud links, so it fixes every caller.
The custom open_url command is left in place (harmless) but is now unused.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014t8Ukp4NPWtqJ55X261wMZ
…n/workspace)
The opener plugin fixed URL-opening (integration connect buttons), but the cloud
sign-in + workspace + cloud-dashboard buttons invoke CUSTOM app commands
(sign_in_google_loopback, verify_orcabot_account, download_cloud_workspace, …),
which Tauri v2 also rejects from the remote-origin frontend ("not allowed by
ACL") — there was no app ACL manifest, so no permission existed to grant them.
Declare all 20 registered commands in build.rs (AppManifest::commands) to
generate their allow-<command> permissions, and grant every one in
capabilities/default.json. Because declaring a manifest makes ALL app commands
ACL-gated (including the local loading screen's get_ports/get_surface_token/…),
the full set is granted so both the local loading screen and the remote frontend
keep working. Keep build.rs's list in sync with generate_handler! in main.rs.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014t8Ukp4NPWtqJ55X261wMZ
…ct handlers
All of WorkspaceBlock's connect buttons (Drive/GitHub/Box/OneDrive) and the file
picker were dead on desktop: they guarded on the reactive `user` from
`const { user } = useAuthStore()`, but WorkspaceBlock is a React Flow node that
can render before the desktop auth bootstrap sets the user and may not re-render
afterward — leaving `user` a stale null, so `if (!user) return` silently
dead-ended every handler. (TeamsBlock works because it guards on dashboardId and
gets identity from getAuthHeaders, which reads useAuthStore.getState() — always
current.)
Read the user via useAuthStore.getState() at click time in each handler, matching
how getAuthHeaders already works, so a stale render-time value can't block the
buttons.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014t8Ukp4NPWtqJ55X261wMZ
… is dead Temporary diagnostic: the Workspace connect buttons fail silently on desktop even after the getState fix, and the webview console isn't visible in release builds. Toast the click + user/desktop/base state so the next test names the cause (no click = onClick not firing / stale frontend; user=NULL = auth not resolved; state-ok-but-no-browser = openExternalUrl). Revert once verified. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014t8Ukp4NPWtqJ55X261wMZ
…disabled
The real cause of the dead Workspace connect buttons: they're `disabled={!user}`
(8 of them) bound to the reactive `const { user } = useAuthStore()`. WorkspaceBlock
is a React Flow node that can render before desktop auth resolves and hold a stale
null, so every button stayed disabled — no click, no handler, no toast (which is
why instrumenting the handler showed nothing).
Read the user via a selector with a getState() fallback so `user` is always the
current store value. This un-disables the supportable connect buttons (Google
Drive/Gmail/Calendar via PKCE, GitHub device flow, Microsoft PKCE) at once.
(Box/Slack/Discord/X — confidential-secret providers desktop can't support — are
already hidden behind !DESKTOP_MODE from the #250 PKCE work.)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014t8Ukp4NPWtqJ55X261wMZ
WKWebView keeps its HTTP cache across app launches, so a rebuilt/updated frontend can serve stale JS chunks — which is why fixes that were verified in the staged bundle never appeared in the running app (dead buttons, old UI, Box still shown). On startup, before the loading screen redirects to the frontend, clear the webview's browsing data when the frontend may have changed: on an app-version change (a shipped frontend update) or ORCABOT_CLEAR_CACHE=1 (local iteration). Gated via a version marker so it fires once per update, not every launch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014t8Ukp4NPWtqJ55X261wMZ
…cache-clear Root cause of the dead workspace buttons + visible Box + Calendar "access revoked": DESKTOP_MODE was computed false in the packaged webview. getDesktopMode() checked window.__TAURI__ (not reliably injected for a remote-origin webview) and window.__TAURI_IPC__ (a Tauri v1 global, absent in v2), so isTauri was false and DESKTOP_MODE fell back to a cookie/localStorage marker. The startup log proves the webview works via __TAURI_INTERNALS__ (get_surface_token succeeded), so detect via that always-present v2 global. With DESKTOP_MODE false, Box rendered (!DESKTOP_MODE), every connect handler took the window.open web path (a no-op in the webview), and dev-auth degraded → the Calendar revoked error. The earlier clear_all_browsing_data() cache-bust made it worse by wiping the very cookie/localStorage DESKTOP_MODE relied on. Remove that cache-clear entirely (the frontend loads fresh regardless — the log shows the current chunks) and rely on robust Tauri detection instead. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014t8Ukp4NPWtqJ55X261wMZ
…indow.open The dead workspace "Connect" buttons were in WorkspaceSidebar (the left WORKSPACE panel's STORAGE INTEGRATIONS list) — a DIFFERENT component from WorkspaceBlock, which is what I'd been fixing. Its handlers called openPopup → window.open unconditionally, and window.open is a no-op inside the Tauri webview, so Drive/ GitHub/Box/OneDrive Connect did nothing on desktop (with a console "blocked" the user never sees). Branch openPopup on DESKTOP_MODE: on desktop, open the OS browser via connectViaBrowser (opener plugin) and poll the provider status until connected (each handler passes its checkConnected/onConnected); on web, keep the existing popup + postMessage flow. Also drop the leftover diagnostic console.logs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014t8Ukp4NPWtqJ55X261wMZ
Strip the temporary "Drive connect clicked" toast (and its now-unused sonner import) — it was a debugging aid and would pop for anyone using the canvas Workspace block. The connect path itself is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014t8Ukp4NPWtqJ55X261wMZ
Box OAuth needs a confidential client secret we can't ship safely in a desktop binary (no PKCE/device public-client flow), so hide it on desktop — both the icon-row button and the STORAGE INTEGRATIONS list entry are gated behind !DESKTOP_MODE. Drive (Google PKCE), GitHub (device flow), and OneDrive (Microsoft PKCE) remain — they're public-client and shippable. The Box folder-picker dialog is unreachable on desktop once its openers are hidden, so it's left as-is. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014t8Ukp4NPWtqJ55X261wMZ
GitHub via the web-redirect connect (/integrations/github/connect) needs the confidential GITHUB_CLIENT_SECRET, which we don't ship on desktop — so it errored "GitHub OAuth is not configured." Desktop is a public client and must use the device flow (like WorkspaceBlock): route handleGithubConnect to a GithubDeviceDialog when DESKTOP_MODE, keep the redirect popup on web. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014t8Ukp4NPWtqJ55X261wMZ
Release payload = the desktop OAuth connect-button fixes on this branch: DESKTOP_MODE detection via __TAURI_INTERNALS__, WorkspaceSidebar connect buttons through the opener plugin (not window.open), GitHub device flow, Box hidden. VM image unchanged (fetched on-demand via vm-image.json). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014t8Ukp4NPWtqJ55X261wMZ
- security: drop the custom `open_url` command grant from the remote-frontend
capability. The frontend now opens URLs via the safer opener plugin; the custom
command shells out (`cmd /C start` on Windows) on a merely prefix-validated URL,
so granting it to the remote origin was an unnecessary injection vector. Matches
the existing main.rs comment ("the custom open_url command which the ACL rejects
from remote"). The command + its permission defs remain, just un-granted.
- ux: on desktop the connectViaBrowser onConnected callbacks now advance into the
storage picker (Drive/OneDrive/GitHub), mirroring the web postMessage handlers,
so users don't have to click the integration a second time to finish linking.
- leak: capture connectViaBrowser's cancel fn; cancel the prior in-flight poll on
repeated clicks and on unmount, so the interval + focus listeners don't linger
for the full 5-minute timeout.
- bump the mandated revision markers on both workspace components.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014t8Ukp4NPWtqJ55X261wMZ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the component sign in buttons on desktop