Skip to content

fix: WebSocket reconnection fails after idle due to token expiration #350

@juniorcammel

Description

@juniorcammel

Problem

In web mode, the application periodically disconnects and shows:

"Authentication Required - Enter the API key shown in the server console to continue."

This happens after the browser tab is idle for ~5 minutes or after any WebSocket disconnection.

Root Cause Analysis

The WebSocket authentication system has a design issue:

1. WS Token is Single-Use

File: apps/server/src/lib/auth.ts:218-219

// Always delete the token (single-use)
wsConnectionTokens.delete(token);

2. WS Token Expires in 5 Minutes

File: apps/server/src/lib/auth.ts:21

const WS_TOKEN_MAX_AGE_MS = 5 * 60 * 1000; // 5 minutes

3. No Automatic Token Refresh

File: apps/ui/src/lib/http-api-client.ts:478

  • fetchWsToken() is only called once during initial connection
  • No heartbeat/ping mechanism to keep the connection alive

4. Reconnection Cascade Failure

File: apps/ui/src/lib/http-api-client.ts:536-541

  • When WebSocket disconnects (idle, network issues, tab backgrounded), client tries to reconnect after 5s
  • If the HTTP session also expired or there's an issue, /api/auth/token fails
  • User gets redirected to login

Scenarios That Trigger This

  • Tab idle for more than 5 minutes
  • Long-running operations (>5min) without WebSocket activity
  • Temporary network interruptions
  • Browser backgrounding the tab (suspends WebSocket)

Proposed Solution

Option A: Keep WebSocket Connection Alive (Recommended)

  1. Increase WS token expiration (apps/server/src/lib/auth.ts:21)

    const WS_TOKEN_MAX_AGE_MS = 15 * 60 * 1000; // 15 minutes
  2. Add heartbeat in client (apps/ui/src/lib/http-api-client.ts)

    • Send ping every 30 seconds to keep connection alive
    • Stop heartbeat on close, restart on open
  3. Improve reconnection

    • Reduce reconnect delay from 5s to 2s
    • connectWebSocket() already fetches new token internally
  4. Handle ping on server (optional)

    • Respond to ping messages with pong

Environment

  • Mode: Web browser (not Electron)
  • Version: v0.7.3 (commit 2bbc811)

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    StaleNo recent activity. Please update, reopen, or reach out on Discord if the issue still occurs.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions