Skip to content

Avoid login redirect when auth check fails during network reconnect #413

Description

@0xSolarPunk

Problem

When a previously authenticated laptop wakes before network connectivity is fully ready, Garcon redirects the user to /login. Submitting the login form then reports Failed to fetch. Refreshing after connectivity settles restores the existing session.

The Garcon server and Cloudflare tunnel remain healthy throughout; this is a client auth-state bug, not a server outage.

Reproduction

  1. Log into Garcon and retain the auth token in local storage.
  2. Load a protected route while /api requests are temporarily unavailable, such as immediately after laptop wake or by aborting /api/v1/auth/status.
  3. The service worker supplies the cached app shell.
  4. Observe redirect to /login despite the stored token.
  5. Attempt login while /api remains unavailable.

Actual: redirect to login followed by raw Failed to fetch.

Expected: preserve the existing token, remain in an indeterminate/reconnecting auth state, and retry validation when connectivity returns.

Root cause

  • web/src/service-worker.ts intentionally serves a cached app shell for failed navigation requests while passing /api through to the network.
  • AuthStore.checkAuthStatus() catches a transport failure from /api/v1/auth/status, sets isLoading=false, and leaves user=null.
  • web/src/routes/+layout.svelte treats that indeterminate state as unauthenticated and redirects to /login.
  • Login uses the same unavailable network path, producing TypeError: Failed to fetch.
  • A related broad catch around getUser() clears the stored token for every exception, including transient network failures. Token invalidation should occur only after an authoritative auth response such as 401/403.

Evidence

During investigation:

  • Garcon service remained continuously active with no correlated restart.
  • Cloudflare tunnel remained active with no warnings or restart.
  • Public /api/v1/auth/status returned 20/20 HTTP 200 once reachable.
  • The behavior follows directly from the cached-shell/API-passthrough and auth redirect paths above.

Acceptance criteria

  • A transport failure during initial auth status does not redirect to /login.
  • A stored token is retained on network errors/timeouts.
  • A stored token is cleared only after an authoritative invalid-token response.
  • UI shows a reconnecting/unavailable state with a manual retry action.
  • Auth status and user validation retry with bounded backoff.
  • Login maps transport failures to a useful network message rather than raw Failed to fetch.
  • Tests cover status transport failure, user-validation transport failure, retry recovery, and 401/403 token invalidation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions