Skip to content

Consolidate onto a single HTTP stack: migrate api/auth.ts off axios #576

Description

@gaidheal1

Summary

The frontend carries two HTTP clients. axios is used by exactly one module; the other nine api/ modules use fetch via apiFetch. Consolidating removes a dependency and eliminates a divergent auth request path.

Part of #569.

Relevant code

  • frontend/src/api/axios.ts — the axios instance (baseURL, withCredentials: true)
  • frontend/src/api/auth.ts — the only consumer
  • All other api/ modules (activities, announcements, appConfig, categories, player, projects, skills, tasks) use apiFetch

Confirmed by grep: axios appears in those two files only.

Proposed fix

Port api/auth.ts to apiFetch and delete api/axios.ts, then drop axios from package.json.

Two differences need care rather than a blind swap:

  1. withCredentials: true — the axios instance sends cookies; apiFetch does not. Establish whether any auth endpoint actually depends on cookie transport, or whether this is vestigial config alongside the JWT-in-header scheme. If it's genuinely needed, apiFetch will need a credentials: 'include' option.
  2. Token handlingapiFetch automatically attaches Authorization and refreshes expiring tokens via getValidAccessToken. Some auth calls (login, register, password reset) are deliberately unauthenticated and must not trigger a refresh attempt. apiFetch already supports passing an explicit token as its third argument, but the genuinely token-free calls need a path that skips getValidAccessToken entirely — otherwise logging in could trip handleUnauthorized and clear storage.

Point 2 is the real substance here; get it wrong and login breaks in a way tests may not catch.

Acceptance criteria

  • api/auth.ts uses apiFetch; api/axios.ts is deleted; axios removed from package.json
  • Login, registration, logout, password reset request, and password reset confirm all still work end to end
  • Unauthenticated auth calls do not trigger a token refresh or invoke handleUnauthorized on failure
  • Whether withCredentials was load-bearing is explicitly determined and documented in the PR
  • Auth-related E2E/Playwright coverage passes

Notes

Not a DOM-coupling issue strictly, but it's in the same layer and halves the surface that needs porting — axios works under React Native, so this is about removing redundancy and a second auth path rather than a hard blocker.

The refresh-on-unauthenticated-call trap is the main risk; worth verifying manually against a real login rather than trusting unit tests alone.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions