59 lines
1.3 KiB
TypeScript
59 lines
1.3 KiB
TypeScript
const CH = 'smart-auth';
|
|
const LS_KEY = 'smart_logout_ping';
|
|
|
|
/** 当前标签页主动登出时通知其它标签 */
|
|
export function broadcastLogout(): void {
|
|
if (typeof window === 'undefined') {
|
|
return;
|
|
}
|
|
try {
|
|
if (typeof BroadcastChannel !== 'undefined') {
|
|
const bc = new BroadcastChannel(CH);
|
|
bc.postMessage({ type: 'logout', t: Date.now() });
|
|
bc.close();
|
|
}
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
try {
|
|
localStorage.setItem(LS_KEY, String(Date.now()));
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
}
|
|
|
|
export type LogoutListener = () => void;
|
|
|
|
/** 其它标签登出时回调(需在客户端挂载一次) */
|
|
export function subscribeRemoteLogout(onLogout: LogoutListener): () => void {
|
|
if (typeof window === 'undefined') {
|
|
return () => {};
|
|
}
|
|
|
|
let bc: BroadcastChannel | null = null;
|
|
try {
|
|
if (typeof BroadcastChannel !== 'undefined') {
|
|
bc = new BroadcastChannel(CH);
|
|
bc.onmessage = (ev: MessageEvent<{ type?: string }>) => {
|
|
if (ev.data?.type === 'logout') {
|
|
onLogout();
|
|
}
|
|
};
|
|
}
|
|
} catch {
|
|
bc = null;
|
|
}
|
|
|
|
const onStorage = (e: StorageEvent) => {
|
|
if (e.key === LS_KEY && e.newValue) {
|
|
onLogout();
|
|
}
|
|
};
|
|
window.addEventListener('storage', onStorage);
|
|
|
|
return () => {
|
|
window.removeEventListener('storage', onStorage);
|
|
bc?.close();
|
|
};
|
|
}
|