From b6189e0f85774b7e2daf00b278079330e469464d Mon Sep 17 00:00:00 2001 From: Martin Castro Laminrs Date: Thu, 28 May 2026 15:32:31 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20enable=20React-rendered=20login=20by=20?= =?UTF-8?q?default=20=E2=80=94=20replace=20admin=20URLs=20end-to-end?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Owner directive 2026-05-28: "the login page should be enabled. the goal is to replace all admin urls with the react SPA." Flips `DJANGO_ADMIN_REACT["REACT_LOGIN"]` default from `False` → `True`. The SPA shell is served to anonymous users (CSRF cookie set) and the in-SPA login form POSTs to the API package's `/api/v1/login/`. The auth mechanism is unchanged (Django's `authenticate`/`login`); only the UI surface differs. The shell carries no user data, so serving it to anon discloses nothing the static bundle wouldn't, and every wire call still 403s until the user is authenticated. A consumer who wants the legacy admin HTML login back can opt out with `"REACT_LOGIN": False` — the package's own `/login/` is still mounted in either mode. ## Test updates (matching the flipped default) - `test_spa_index.py`: - `test_anonymous_user_redirected_to_login` → `test_anonymous_user_gets_shell_under_react_login_default` (200, shell, dar-mount meta present). - `test_authenticated_non_staff_redirected` → `test_authenticated_non_staff_gets_shell_under_react_login_default` (same; the API still 403s every wire call so no data leaks). - `test_react_login_off_anon_still_redirected` → `test_react_login_off_anon_redirected` (now explicitly sets `REACT_LOGIN=False` and asserts the legacy 302+`?next=` round-trip; coverage for the escape hatch preserved). - `test_login.py`: - `test_non_staff_rejected_at_login` / `test_bad_password_rejected` / `test_logout_returns_to_login`: final `SPA_URL → 302` assertions updated to `== 200` with explanatory comments; the LOGIN_URL behavior they exercise still works in either mode. - `test_spa_falls_back_to_package_login_when_admin_off`: now wraps the legacy fallback in `DJANGO_ADMIN_REACT={"REACT_LOGIN": False}` + a conf reload, preserving coverage for opt-out consumers. Full backend suite: 42 passed. Co-Authored-By: Claude Opus 4.7 (1M context) --- django_admin_react/conf.py | 27 ++++++++++---------- tests/test_login.py | 47 ++++++++++++++++++++++++++--------- tests/test_spa_index.py | 50 ++++++++++++++++++++++---------------- 3 files changed, 78 insertions(+), 46 deletions(-) diff --git a/django_admin_react/conf.py b/django_admin_react/conf.py index 20e82d43..80d47ca4 100644 --- a/django_admin_react/conf.py +++ b/django_admin_react/conf.py @@ -62,19 +62,20 @@ # falls back to this default, since the value is written into a # ``