Skip to content

fix(desktop): preserve OAuth sessions in sidebar - #67578

Closed
TheAngryPit wants to merge 1 commit into
NousResearch:mainfrom
TheAngryPit:codex/fix-desktop-session-auth-routing
Closed

fix(desktop): preserve OAuth sessions in sidebar#67578
TheAngryPit wants to merge 1 commit into
NousResearch:mainfrom
TheAngryPit:codex/fix-desktop-session-auth-routing

Conversation

@TheAngryPit

Copy link
Copy Markdown
Contributor

Summary

Fixes #41529 and supersedes the stale implementation in #41530.

Hermes Desktop's primary/global session list bypassed its existing auth-aware request helper in two places:

Both paths called the token transport directly. For an OAuth-backed primary gateway, the token is null, so the request failed and the existing fallback silently returned an empty list. Sessions remained in the backend and could still be opened by ID, but disappeared from the sidebar.

Change

  • Route primary session reads through the existing fetchJsonForProfile(null, ...) path, which already selects OAuth-session or token transport from the resolved connection.
  • Share that behavior between the legacy merged list and the batched sidebar list.
  • Preserve the existing empty-list fallback when a remote is unavailable.
  • Add focused regression coverage for the profile-aware primary request path and fallback.

Proof

  • vitest run --project electron: 460 passed, 1 skipped.
  • tsc -p tsconfig.electron.json --noEmit: passed.
  • ESLint on the three changed files: passed.
  • Prettier check on the three changed files: passed.
  • git diff --check: passed.

Runtime reproduction

On current main, with a global OAuth backend plus named remote profile overrides:

  • /api/profiles/sessions/sidebar returned zero recent sessions;
  • the direct authenticated /api/profiles/sessions?profile=default path returned the persisted sessions.

The difference is the primary fetch transport selected by Electron's remote-profile interception path.

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused fix. The premise is present on current main: apps/desktop/electron/main.ts:8236 and :8256 directly use the primary token transport, while requestJsonForProfile() selects the OAuth-session transport for OAuth connections at apps/desktop/electron/main.ts:6380-6384.

The PR replaces both affected call sites through one extracted helper and covers that helper's primary-route and fallback behavior in apps/desktop/electron/profile-session-routing.test.ts. Its parent is current main (36f2a966c7f9f69987494b867c3dcf96b69a5766), so salvage should be a clean cherry-pick.

This is an automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 19, 2026
@alt-glitch alt-glitch added type/bug Something isn't working comp/desktop Electron desktop app (apps/desktop/*) area/auth Authentication, OAuth, credential pools area/sessions Session lifecycle, resume, persistence, history P2 Medium — degraded but workaround exists needs-decision Awaiting maintainer decision before any implementation sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Jul 19, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related to #41529 and the stale-path implementation #41530. This patch ports the OAuth-aware primary-session fetch to current main.ts; it is not a duplicate of the older implementation.

@OutThisLife
OutThisLife force-pushed the codex/fix-desktop-session-auth-routing branch from 0db6a32 to 6404ee0 Compare July 27, 2026 18:01

@OutThisLife OutThisLife left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Rebased onto current main (import-order conflict only, 6404ee0) and kicked CI, which had never run on this branch.

Premise confirmed independently. On main both fetchProfilesSessionSlice (main.ts:9780) and mergeRemoteProfileSessions (main.ts:9800) call fetchJson(url, primary.token, …). For an OAuth-gated primary primary.token is null, the call 401s, and the .catch(() => ({ sessions: [], total: 0, profile_totals: {} })) immediately below turns that into an empty sidebar. Rows stay in the backend and stay openable by id, which is exactly the reported "my sessions disappeared" shape.

Routing through fetchJsonForProfile is the right fix rather than re-deriving transport selection at the call site — that helper already picks native-bearer vs cookie-partition, and the decision itself is pinned by resolveOauthRestAuth in native-auth-decisions.ts.

Verified locally on 2b0fb72ac, stacked with #72740: 799 electron tests pass, npm run typecheck green.

This closes the fourth of the four defects listed in the #58108 sweeper review.

On the adversarial audit above: the first two points don't hold. "Contains zero references to OAuth" is the point of the change — OAuth transport selection lives inside fetchJsonForProfile, and duplicating it at the call site is what #68169 does wrong (it drops the native-bearer branch and leaves cookieless native sessions 401ing). The third point is fair as far as it goes: the new test injects a fake and proves the extraction seam, not the transport choice. That choice is covered separately by native-auth-decisions.test.ts, so the contract is pinned — just in two files rather than one.

Credit where this started: @sealca reported #41529 and wrote the original fix in #41530 against the pre-TypeScript main.cjs. Squash body on merge should carry Co-authored-by: for @sealca and @rod-nxtlevel (#58108), Closes #41529, Supersedes #41530, #68169.

@OutThisLife

Copy link
Copy Markdown
Collaborator

Superseded by #72835 — not because anything was wrong with this, but because it turned out to be one of four parts of the same subsystem fix, and landing them separately would have left three overlapping routing predicates in connection-config.ts.

Your commit is cherry-picked verbatim into that PR, so authorship stays with you in git history, and #41529 closes with it. Sorry for the churn after approving and rebasing this one — the consolidation call came after.

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

Labels

area/auth Authentication, OAuth, credential pools area/sessions Session lifecycle, resume, persistence, history comp/desktop Electron desktop app (apps/desktop/*) needs-decision Awaiting maintainer decision before any implementation P2 Medium — degraded but workaround exists sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Desktop hides global OAuth sessions when a token-auth remote profile is configured

4 participants