feat(web): soft-redirect to login on 401 via a navigate bridge (#48)
This commit is contained in:
@@ -1,7 +1,23 @@
|
||||
/** Hard-navigate to login. Isolated so it can be spied/mocked in tests and swapped
|
||||
* for a router navigation if needed. */
|
||||
type NavigateFn = (to: string, opts?: { replace?: boolean }) => void;
|
||||
|
||||
let navigateFn: NavigateFn | null = null;
|
||||
|
||||
/** Register (or clear) the router's navigate fn. Called by NavigationBridge. */
|
||||
export function setNavigate(fn: NavigateFn | null): void {
|
||||
navigateFn = fn;
|
||||
}
|
||||
|
||||
/** Soft-redirect to login on a 401, preserving SPA state and the return path.
|
||||
* Falls back to a hard navigation when no router navigate is registered yet
|
||||
* (e.g. a 401 during the very first load). No-op when already on /login. */
|
||||
export function redirectToLogin(): void {
|
||||
if (window.location.pathname !== "/login") {
|
||||
window.location.assign("/login");
|
||||
const { pathname, search } = window.location;
|
||||
if (pathname === "/login") return;
|
||||
const from = encodeURIComponent(pathname + search);
|
||||
const target = `/login?reason=expired&from=${from}`;
|
||||
if (navigateFn) {
|
||||
navigateFn(target, { replace: true });
|
||||
} else {
|
||||
window.location.assign(target);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user