This commit is contained in:
@@ -5,6 +5,7 @@ import { cn } from '@/lib/utils';
|
||||
import { KROW_LOGO_URL } from '@/assets/brand';
|
||||
import { Checkbox } from '@/components/ds';
|
||||
import { useAuth } from '@/lib/AuthContext';
|
||||
import { safeReturnTo } from '@/lib/authReturnTo';
|
||||
|
||||
const DEMO_EMAIL = 'demo@krow.app';
|
||||
|
||||
@@ -26,6 +27,24 @@ export default function AdminLogin() {
|
||||
const location = useLocation();
|
||||
const { login } = useAuth();
|
||||
|
||||
/* Two kinds of "where was I going", and they are not interchangeable.
|
||||
|
||||
A ?returnTo= in the QUERY is put there by the API, not by this app. The
|
||||
OAuth authorization endpoint redirects here when nobody is signed in,
|
||||
carrying its own path and query so the authorization request survives the
|
||||
round trip. It names a route on the BACKEND (/oauth/authorize), which React
|
||||
Router does not have and must not be given — routing to it client-side
|
||||
renders the not-found page and the connector never finishes. So it is
|
||||
followed with a real navigation, which safeReturnTo reports as `browser`.
|
||||
|
||||
`location.state.from` is the in-app case: a guard bounced someone off a
|
||||
page in this bundle (ProtectedRoute and AdminRoute both set it). That is a
|
||||
router destination and stays one, unchanged.
|
||||
|
||||
The query wins when both exist. It is the more specific instruction, and it
|
||||
is the one the person is actually in the middle of. */
|
||||
const fromQuery = safeReturnTo(location.search);
|
||||
|
||||
const from = location.state?.from;
|
||||
const returnTo = typeof from === 'string' && from.startsWith('/admin') && from !== '/admin/login'
|
||||
? from
|
||||
@@ -79,7 +98,13 @@ export default function AdminLogin() {
|
||||
}
|
||||
|
||||
setStatus('success');
|
||||
setTimeout(() => navigate(returnTo, { replace: true }), 320);
|
||||
setTimeout(() => {
|
||||
// `replace`, not `assign`: the login should not sit in history between
|
||||
// the authorization request and the consent screen, or Back from consent
|
||||
// returns to a login the person has already completed.
|
||||
if (fromQuery?.via === 'browser') window.location.replace(fromQuery.path);
|
||||
else navigate(fromQuery?.path ?? returnTo, { replace: true });
|
||||
}, 320);
|
||||
};
|
||||
|
||||
const busy = status !== 'idle';
|
||||
|
||||
Reference in New Issue
Block a user