Commit Graph

2 Commits

Author SHA1 Message Date
MHSanaei 46cac582ab fix(frontend): refetch a fresh CSRF token on 403 instead of reusing the stale meta tag
On a 403 to an unsafe method the client cleared its cached CSRF token and
called ensureCsrfToken to retry. But ensureCsrfToken prefers the
<meta name="csrf-token"> tag baked into the page, which the production
panel always injects, so the "refresh" re-read the same stale token and the
/csrf-token refetch was never reached — the retry re-sent the token that had
just been rejected and the save failed with an error toast.

The token lives in the session and rotates when the session is regenerated
(for example re-login in another tab), leaving the tab's baked-in meta token
stale. Fetch the current token straight from /csrf-token in the 403 branch so
the retry uses the authoritative server value. The existing tests only passed
because they strip the meta tag; the new test keeps a stale tag present.
2026-07-15 05:08:00 +02:00
MHSanaei bc309ed9f8 refactor(frontend): replace axios with the native Fetch API
Drop the axios (and qs) dependencies in favor of a native fetch wrapper.
axios only ever handled same-origin JSON/form calls, a CSRF header, a 401
redirect, and a 403-retry, all of which the platform now provides directly.

- New src/api/http-init.ts (replaces axios-init.ts) reimplements the
  request/response interceptors on fetch: base-path prefixing,
  X-Requested-With, same-origin credentials, the CSRF token on unsafe
  methods, a single 403 retry with token refresh, and the 401
  redirect-and-latch. A small encodeForm() reproduces qs's
  arrayFormat:'repeat' encoding, so the request wire format is unchanged.
- HttpUtil (src/utils/index.ts) keeps its public signatures and the Msg
  envelope, so the ~49 API call sites are untouched. HttpOptions is now
  hand-rolled instead of extending AxiosRequestConfig.
- PanelUpdateModal drops its lone direct axios.get in favor of HttpUtil.get
  with { silent, timeout }.
- Add tests for the fetch core (CSRF header, form/JSON/FormData bodies,
  base-path prefix, 403 retry, 401 redirect, tolerant body parse) and for
  HttpUtil's envelope unwrap / toast / error mapping; this logic was
  previously untested.
- Remove the vendor-axios manualChunks branch and the qs type shim, and
  reword stale "axios" mentions in docs and route comments.
2026-07-08 01:09:18 +02:00