• fix(auth): stop mobile logins failing with "Cannot read properties of undefined"
    Release / version (push) Canceled after 0s
    Release / frontend (push) Canceled after 0s
    Release / linux (amd64) (push) Canceled after 0s
    Release / linux (arm64) (push) Canceled after 0s
    Release / windows (push) Canceled after 0s
    Release / macos (push) Canceled after 0s
    Release / release (push) Canceled after 0s
    Build and Push Docker Image / build-and-push (push) Canceled after 0s

    LastSkywalker released this 2026-08-30 16:20:02 +03:00

    A sign-in that got a 2xx whose body was not the {"data": …} envelope walked
    straight into payload.user in the user store, so the login form printed
    Cannot read properties of undefined (reading 'user') — no hint of what the
    browser actually received. It reproduces on one device and not another (a
    phone on mobile data vs. a desktop) because the cause is on the path, not in
    the credentials.

    Two fixes:

    • unwrapEnvelope() in the api client validates the envelope and, when it is
      missing, throws with the status, the content type and a body preview logged
      to the console — a proxy, VPN, ad blocker or stale cached page answering
      instead of node-stats now says so. Applied to login, register, refresh and
      /users/me; the auth payload is additionally checked for a user. The login
      form also shows the server's own message ("Invalid email or password")
      rather than axios' "Request failed with status code 401".

    • CacheControl middleware: no-store for /api/* (per-user, cookie-bound
      responses must never be cached by a proxy in front), immutable for the
      content-hashed /assets/*, and no-cache for the SPA shell. The shell had no
      cache headers at all, so it fell under browser heuristic caching and a
      device that visited weeks ago could keep booting a stale bundle against a
      current API. Handlers that set their own value (the wallpaper proxy) still
      win.

    Co-Authored-By: Claude Opus 5 noreply@anthropic.com
    Claude-Session: https://claude.ai/code/session_01QotjVPhLcTfCvFf5ZEVFUk

    Downloads