Skip to content

feat: Auth and session reliability overhaul with refresh token support#132

Open
Meganugger wants to merge 3 commits intoOpenCloudGaming:devfrom
OpenCloudFork:feat/auth-session-reliability
Open

feat: Auth and session reliability overhaul with refresh token support#132
Meganugger wants to merge 3 commits intoOpenCloudGaming:devfrom
OpenCloudFork:feat/auth-session-reliability

Conversation

@Meganugger
Copy link

Summary

Comprehensive overhaul of the authentication and session management systems, adding refresh token support with mutex-protected token exchange, 401 retry logic, session expired events, improved launch polling to prevent premature timeouts, and session clock auto-hide/reveal behavior.

Added

  • offline_access scope in OAuth PKCE flow for refresh tokens
  • Centralized 401 interceptor with lockedRefresh() mutex (prevents parallel refresh attempts)
  • withRetryOn401() wrapper — retries failed API calls exactly once after token refresh
  • client_token exchange fallback when standard refresh fails
  • auth:session-expired IPC event for unrecoverable auth failures with auto-logout
  • Session clock settings: sessionClockShowEveryMinutes, sessionClockShowDurationSeconds
  • Session clock auto-hide/periodic reveal logic in StreamView
  • Navbar modal back-button support via pushState/popstate
  • session-polling.test.ts — unit tests for session launch polling

Updated

  • auth.ts — rewritten with refresh mutex, retry logic, and token validation
  • cloudmatch.ts — improved session status polling with grace periods
  • types.ts — extended session status types
  • App.tsx — session launch polling with configurable timeouts and grace periods
  • StreamLoading.tsx — provisioning-aware timeout display
  • StreamView.tsx — session clock auto-hide/reveal intervals
  • SettingsPage.tsx — session clock configuration UI
  • Navbar.tsx — modal history state management
  • CI matrix upgraded to blacksmith-4vcpu-* instances

Fixed

  • False "Session did not become ready in time" errors during provisioning
  • Premature session timeouts during long queue waits
  • Parallel token refresh race conditions
  • Session expired state not properly communicated to renderer

Validation Notes

Recommended smoke checks:

  • Log in and verify token refresh works after extended idle
  • Start a session during peak hours (long queue) and verify no premature timeout
  • Verify session clock appears, hides after configured duration, and re-reveals periodically
  • Force a 401 error and verify auto-logout with error message on login screen
  • Run npm test and verify session-polling tests pass

Meganugger and others added 3 commits February 22, 2026 14:38
…oning

Replace fixed 30-attempt polling loop with resilient session provisioning:

- Exponential backoff polling (1s initial, 1.5x growth, 5s cap) instead of
  fixed 2s intervals
- Hard timeout of 180s instead of 60s (30×2s), with clear user messaging
- status=1 (provisioning) treated as normal — keeps polling, never throws
- status=6 (cleaning up) treated as terminal failure
- Unknown statuses continue polling with warning logs
- AbortController integration: Cancel button / navigation cleanly aborts
  the poll loop without showing a false error
- User abort (DOMException AbortError) distinguished from real errors —
  no error toast shown on user cancellation
- StreamLoading shows 'Still starting… (Xs)' after 30s of provisioning
- provisioningElapsed state resets properly on completion or abort
- Single-flight guard preserved via existing launchInFlightRef

Eliminates the error → wait → Resume click flow: sessions that are still
provisioning automatically proceed to signaling once ready.

Tests: 35 passing assertions covering immediate ready, long provisioning,
status transitions, abort cancellation, hard timeout, and backoff behavior.

Co-authored-by: Capy <capy@capy.ai>
Auth System:
- Add offline_access scope to OAuth PKCE flow for refresh tokens
- Centralized 401 interceptor with Promise-based refresh mutex
  - Single lockedRefresh() prevents parallel refresh attempts
  - withRetryOn401() wrapper retries failed API calls once after refresh
  - No infinite loops: retry limited to exactly once per request
- client_token exchange fallback (token-exchange grant type) when
  standard refresh_token flow fails
- Validate refresh response: reject empty access_token
- Session expired event (auth:session-expired IPC channel) emitted
  on unrecoverable 401 or failed refresh
- Auto-logout: clears session, notifies renderer, shows error on
  login screen

Session Clock:
- New settings: sessionClockShowEveryMinutes (default 60),
  sessionClockShowDurationSeconds (default 30)
- Auto-hide/periodic reveal logic in streaming view
  - Clock shows initially, hides after duration
  - Re-reveals every N minutes for configured duration
  - 0 minutes = always visible
  - Clean interval cleanup on unmount/session end
- Settings UI section with numeric inputs and hints

Navigation:
- Navbar modal pushes history state on open
- popstate listener closes modal on browser back
- No routing breakage: uses pushState/popstate pattern

Build:
- CI matrix upgraded to 4 CPU instances (blacksmith-4vcpu-*)
  for all build and release runners

Zero new type errors. Zero new lint warnings.
Pre-existing TS2367 on keyboardLock permission unchanged.

Co-authored-by: Capy <capy@capy.ai>
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.

1 participant