fix(auth): deliver OAuth JWT to remote core in cloud mode#2453
Conversation
Two failure paths prevented the openhuman://auth deep link from reaching a Docker-hosted remote core: 1. oauthAuthReadiness.ts pinged the core with a stale local-core bearer token (resolved from cache). Fix: explicitly pass the stored cloud token to testCoreRpcConnection in cloud mode. 2. CoreStateProvider's auth-expired cascade cleared the session while auth_store_session was in flight. Fix: dispatch a 15 s suppress- reauth window around storeSession; CoreStateProvider skips clearSession while the window is active. Also busts stale RPC URL/token caches before auth_store_session in cloud mode, and improves the core_unreachable error message to name the cloud core specifically. Closes tinyhumansai#2377
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAuth readiness and deep-link handling gain cloud-mode awareness: readiness passes cloud bearer token to RPC checks and shows cloud-specific unreachable messaging; deep-link delivery clears RPC caches, dispatches suppression events while delivering the token, CoreStateProvider respects suppression, and RPC client logs token source. ChangesCloud-mode OAuth flow for remote runtime token delivery
Sequence Diagram(s)sequenceDiagram
participant DesktopApp
participant DeepLinkHandler
participant ConfigPersistence
participant CoreRpcClient
participant CoreStateProvider
DesktopApp->>DeepLinkHandler: openhuman://auth?token=JWT
DeepLinkHandler->>ConfigPersistence: getStoredCoreMode()
ConfigPersistence-->>DeepLinkHandler: 'cloud'
DeepLinkHandler->>CoreRpcClient: clearCoreRpcUrlCache(), clearCoreRpcTokenCache()
DeepLinkHandler->>CoreStateProvider: dispatch core-state:suppress-reauth(until)
DeepLinkHandler->>CoreRpcClient: call openhuman.auth_store_session(token)
CoreRpcClient-->>DeepLinkHandler: RPC response
DeepLinkHandler->>CoreStateProvider: dispatch core-state:suppress-reauth(until:0)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
|
@M3gA-Mind CI is failing on changes in this PR — please fix before review. |
…livery (tinyhumansai#2377) Add two targeted tests that exercise the `core-state:suppress-reauth` custom-event handler introduced for issue tinyhumansai#2377: - verifies auth-expired clearSession is blocked while the suppress window is active - verifies clearSession resumes after the window is explicitly cleared (until=0)
|
Two CI failures, both pre-existing infrastructure flakes unrelated to these TypeScript-only changes:
|
|
@graycyrus @senamakel Follow-up after the earlier CI-failure note: the latest effective checks are now green, CodeRabbit approved, and the PR is mergeable. This fixes remote-core OAuth token delivery (#2377), so it is part of the same sign-in/deep-link reliability cluster. Please review/merge when available. |
|
@M3gA-Mind this PR has merge conflicts with main — please rebase/resolve before review. |
# Conflicts: # app/src/utils/__tests__/desktopDeepLinkListener.test.ts # app/src/utils/desktopDeepLinkListener.ts
Trivial cleanup: the suppress-reauth check called Date.now() a second time instead of reusing the 'now' value computed on the line above. Functionally identical, but consistent with the debounce check below.
Summary
oauthAuthReadiness.ts: in cloud mode, pass the stored cloud bearer token directly totestCoreRpcConnection()so the readiness-gate ping doesn't fail with a stale local-core token from cache.desktopDeepLinkListener.ts: bust stale RPC URL/token caches beforeauth_store_sessionin cloud mode; wrap the call in acore-state:suppress-reauth15 s window to prevent a concurrent auth-expired cascade from clearing the session mid-flight.CoreStateProvider.tsx: honour thesuppress-reauthwindow — skipclearSessionwhile a deep-link auth delivery is in progress.coreRpcClient.ts: add diagnostic logging forauth_store_sessionrouting (token source:cloud-storedvslocal-resolved).core_unreachableerror message to name the cloud core URL/token settings when mode is cloud.Problem
When a user runs in remote/cloud mode (Docker-hosted core), completing Google/GitHub OAuth left the app in an infinite onboarding loop. Two concurrent failures prevented the JWT from reaching the remote core:
Wrong ping token:
oauthAuthReadiness.tscalledtestCoreRpcConnectionwithout a token override.getCoreRpcToken()could resolve the local in-process core's bearer from a primed cache — the remote core rejected it with 401, the readiness gate timed out, and the deep link was dropped.Auth-expired cascade:
CoreStateProviderran periodicfetchCoreAppSnapshotRPCs against the remote core while the session was not yet stored. Those returned "no backend session token; run auth_store_session first", whichclassifyRpcErrorclassified asauth_expired, triggeringclearSession→auth_clear_session→ Welcome screen. If this fired afterstoreSession, the session was immediately undone.Solution
Two targeted guards, no new dependencies:
CoreStateProviderto delay auth-expired resets whilestoreSessionis in flight; the window clears in afinallyblock regardless of outcome.Submission Checklist
desktopDeepLinkListener.test.ts, 3 new inoauthAuthReadiness.test.tsCloses #2377Impact
getStoredCoreMode() === 'cloud'.Related
AI Authored PR Metadata
Linear Issue
Commit & Branch
Validation Run
pnpm --filter openhuman-app format:check— cleanpnpm --filter openhuman-app compile— 0 errorspnpm --filter openhuman-app lint— 0 new errors (existing warnings on main are pre-existing)pnpm debug unit desktopDeepLinkListenerandoauthAuthReadiness— all passValidation Blocked
command:N/Aerror:N/Aimpact:N/ABehavior Changes
Parity Contract
cloudmode checkauth_store_sessionsignature unchangedDuplicate / Superseded PR Handling
Summary by CodeRabbit
New Features
Bug Fixes
Tests