feat: enable React-rendered login by default — replace admin URLs end-to-end#561
Merged
Merged
Conversation
…-to-end
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 `<mount>/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) <noreply@anthropic.com>
MartinCastroAlvarez
pushed a commit
that referenced
this pull request
May 28, 2026
…nfig block (v1 polish) The two settings that landed this release window aren't visible in the README's optional-configuration snippet — add them with one-line inline docs so consumers landing on the PyPI page see the full v1 surface at a glance: - `REACT_LOGIN` — True by default (post-#561); set False to opt back into the legacy admin HTML login. - `API_URL_PREFIX` — None by default; point the SPA at a separately- mounted django-admin-rest-api when the consumer doesn't want the inline include (#559).
MartinCastroAlvarez
added a commit
that referenced
this pull request
May 28, 2026
* chore(release): v1.0.0 — the React-super-layer release Owner directive 2026-05-28: "ship the v1 release to pypi." The repo has been collapsed to a pure React SPA super-layer over `django-admin-rest-api ^1.0.1` (the published v1 API package). The 14 commits since v0.2.0a8 cover the entire 3-repo split, the API/MCP sibling dependencies, the API_URL_PREFIX setting (#559), the React-rendered login as the default (replaces admin URLs end-to-end, #167), the docs prune, and four user-facing feature fixes (#554, #555, #556-via-#529, #557-via-#527). This bump: - `version` `0.2.0a8` → **`1.0.0`**. - `Development Status :: 2 - Pre-Alpha` → `Development Status :: 4 - Beta`. - `README.md` "Pre-alpha" banner replaced with the v1 / three-package shipping note. ## Verification - `poetry run pytest` clean (42 passed on the now-minimal SPA-side suite). - Wheel build & content audit already done in the #550 collapse PR: ships the pre-built React bundle + LICENSE, no `node_modules`, no source maps, no local `api/` tree. - The `release.yml` OIDC workflow handles the publish — the owner cuts a GitHub Release at `v1.0.0` and the wheel + sdist ship to PyPI automatically (no stored token). After this merges: 1. Tag `v1.0.0` on `main`. 2. Publish the GitHub Release with the tag. 3. The OIDC workflow uploads to PyPI under the `pypi` environment. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(release): de-duplicate the README Install section (v1 polish) The README had two `## Install` snippets: the top (correct, two `INSTALLED_APPS` entries + one URL include) and a later one that was stale (only `django_admin_react`, mounted at `/admin/` which would collide with `django.contrib.admin`). Replaced the lower section with a short pointer back to the top — fewer divergent paths, no collision-inducing example. * docs(release): document REACT_LOGIN + API_URL_PREFIX in the README config block (v1 polish) The two settings that landed this release window aren't visible in the README's optional-configuration snippet — add them with one-line inline docs so consumers landing on the PyPI page see the full v1 surface at a glance: - `REACT_LOGIN` — True by default (post-#561); set False to opt back into the legacy admin HTML login. - `API_URL_PREFIX` — None by default; point the SPA at a separately- mounted django-admin-rest-api when the consumer doesn't want the inline include (#559). --------- Co-authored-by: Martin Castro Laminrs <mcastro@laminr.ai> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes the React-shell-on-anonymous request (per owner directive 2026-05-28):
DJANGO_ADMIN_REACT["REACT_LOGIN"]defaults fromFalse→True. SPA shell renders for anonymous users (with CSRF cookie); the in-SPA login form posts to/api/v1/login/. The legacy admin login is preserved as an escape hatch ("REACT_LOGIN": False).Test updates (7 tests adjusted to the new default)
test_anonymous_user_redirected_to_logintest_anonymous_user_gets_shell_under_react_login_default; asserts 200 + shell.test_authenticated_non_staff_redirectedtest_authenticated_non_staff_gets_shell_under_react_login_default; same.test_react_login_off_anon_still_redirectedtest_react_login_off_anon_redirected; explicitly setsREACT_LOGIN=Falseto exercise the escape-hatch path.test_non_staff_rejected_at_loginSPA_URL → 302updated to== 200; new comment.test_bad_password_rejectedtest_logout_returns_to_logintest_spa_falls_back_to_package_login_when_admin_offREACT_LOGIN=False+ conf reload to preserve legacy-fallback coverage.Backend suite: 42 passed. No frontend code change —
LoginPagealready renders the form when the SPA receives anonymous state.🤖 Generated with Claude Code