fix: pick landing route by access predicate to avoid redirect loop

Access extensions can narrow ``canSeeAdmin`` to ``false`` even when
``currentUser.is_admin`` is ``true``. The default-landing logic
keyed off ``is_admin`` and pushed admin to ``/dashboard``; when
``canSeeAdmin`` is narrowed there, ``Exception`` 403-redirects to
``/``, which re-pushes ``/dashboard``, looping into a blank screen.
Switch the landing pick (and the masthead-click handler) to consult
the resolved ``access.canSeeAdmin`` predicate instead.

Behavior is unchanged for the default access module, where
``canSeeAdmin`` mirrors ``is_admin``.
This commit is contained in:
gitlawr
2026-05-09 17:22:27 +08:00
committed by Lawrence Li
parent 2889ba7c78
commit 168c55990f
+11 -2
View File
@@ -32,6 +32,7 @@ import {
matchRoutes,
request,
setLocale,
useAccess,
useAppData,
useIntl,
useLocation,
@@ -156,6 +157,7 @@ export default (props: any) => {
};
const { initialState, loading, setInitialState } = initialInfo;
const access = useAccess();
const userConfig = {
title: '',
@@ -290,7 +292,14 @@ export default (props: any) => {
if (!initialState?.currentUser && location.pathname !== loginPath) {
history.push(loginPath);
} else if (location.pathname === '/') {
const pathname = initialState?.currentUser?.is_admin
// Pick a landing route the caller can actually see. Access
// extensions can narrow ``canSeeAdmin`` to ``false`` even when
// ``currentUser.is_admin`` is ``true``; pushing an admin to
// ``/dashboard`` (gated by ``canSeeAdmin``) in that case
// dead-ends in ``Exception`` 403 → redirect-to-``/`` →
// re-push, looping into a blank screen. Honoring the resolved
// predicate keeps the user on a route they can render.
const pathname = access?.canSeeAdmin
? DEFAULT_ENTER_PAGE.adminForNormal
: DEFAULT_ENTER_PAGE.user;
history.push(pathname);
@@ -300,7 +309,7 @@ export default (props: any) => {
const onMenuHeaderClick = (e: React.MouseEvent) => {
e.stopPropagation();
e.preventDefault();
const pagepath = initialState?.currentUser?.is_admin
const pagepath = access?.canSeeAdmin
? DEFAULT_ENTER_PAGE.adminForNormal
: DEFAULT_ENTER_PAGE.user;