From f98350d588e4930a37e36d88cfb283de8d1001f4 Mon Sep 17 00:00:00 2001 From: Martin Castro Laminrs Date: Sun, 31 May 2026 12:37:44 +0200 Subject: [PATCH] fix(spa): smart-route action-handler redirect URLs (#620) + release 1.4.13 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A ModelAdmin action that returns ``HttpResponseRedirect(some_url)`` was looking silently no-op'd to the operator: the click ran, the toast didn't appear, and nothing visible happened. The diagnosis in the issue blamed the API for swallowing the response, but the API correctly extracts ``response["Location"]`` into the JSON envelope's ``redirect`` field (``api/views/actions.py:256``). The actual bug was on the SPA: ``DetailPage`` piped the redirect URL straight into React Router's ``navigate`` — which is scoped to the SPA's ``BrowserRouter`` ``basename``, so any URL outside the SPA mount silently no-op'd: - legacy admin paths (``/admin////change/``) - hijack / impersonate URLs (``/hijack/release-user/?next=…``) - cross-origin downloads (signed S3 URLs) New ``followActionRedirect`` helper (`apps/web/src/action-redirect.ts`) picks the right primitive per URL: ``navigate`` for same-origin paths inside the SPA mount (no full reload), ``window.location.assign`` for everything else. Returns a stripped basename-relative path to the navigate call so BrowserRouter doesn't double-prefix. The helper is dependency-injected (``currentOrigin``, ``assignLocation``) so the test suite can lock the routing logic without touching jsdom's non-configurable ``window.location``. Locks: 6 new vitests in `action-redirect.test.ts` cover the SPA- internal path, search + hash preservation, the legacy-admin path, cross-origin URLs, the hijack pattern, and a malformed-URL fallback. Release 1.4.13 bundles this with the unreleased changes since 1.4.12 (all already merged on main): - #631 / PR #641 — ``PRIMARY_COLOR`` reads ``site_primary_color`` off the configured ``AdminSite`` before falling back to the setting + default. - #626 / PR #642 — ``raw_id_fields`` and ``radio_fields`` now render their intended widgets (plain-pk text input + lookup link, inline radio bank) instead of falling through to autocomplete / ``