mirror of
https://github.com/hansjone/netx.git
synced 2026-10-09 04:20:45 +08:00
fix(auth): sync logout across browser tabs
Listen for localStorage token changes so other open pages clear session state when one tab signs out. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
b540ea21c1
commit
a3bdad5be1
2 changed files with 26 additions and 2 deletions
|
|
@ -7,7 +7,14 @@ import {
|
|||
useState,
|
||||
type ReactNode,
|
||||
} from "react";
|
||||
import { apiGet, apiPost, clearAuthToken, getAuthToken, setAuthToken } from "../services/api";
|
||||
import {
|
||||
AUTH_TOKEN_KEY,
|
||||
apiGet,
|
||||
apiPost,
|
||||
clearAuthToken,
|
||||
getAuthToken,
|
||||
setAuthToken,
|
||||
} from "../services/api";
|
||||
|
||||
export type AuthUser = {
|
||||
id: string;
|
||||
|
|
@ -62,6 +69,23 @@ export function AuthProvider({ children }: { children: ReactNode }) {
|
|||
})();
|
||||
}, [refreshMe]);
|
||||
|
||||
// Other tabs keep React auth state until they hear localStorage change.
|
||||
// `storage` fires only in *other* documents — used to sync logout/login.
|
||||
useEffect(() => {
|
||||
const onStorage = (ev: StorageEvent) => {
|
||||
if (ev.storageArea && ev.storageArea !== localStorage) return;
|
||||
if (ev.key !== null && ev.key !== AUTH_TOKEN_KEY) return;
|
||||
if (ev.key === null || ev.newValue == null || ev.newValue === "") {
|
||||
setToken(null);
|
||||
setUser(null);
|
||||
return;
|
||||
}
|
||||
void refreshMe();
|
||||
};
|
||||
window.addEventListener("storage", onStorage);
|
||||
return () => window.removeEventListener("storage", onStorage);
|
||||
}, [refreshMe]);
|
||||
|
||||
const login = useCallback(async (username: string, password: string) => {
|
||||
const data = await apiPost<{ access_token: string; user: AuthUser }>("/v1/auth/login", {
|
||||
username,
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import type {
|
|||
TopologyMapItem,
|
||||
} from "../types";
|
||||
|
||||
const AUTH_TOKEN_KEY = "netx_access_token";
|
||||
export const AUTH_TOKEN_KEY = "netx_access_token";
|
||||
|
||||
export const getAuthToken = (): string | null => {
|
||||
try {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue