/** 同源多标签页会话同步:监听 jwt/clear 变更,退出时将当前受保护页面替换为登录页。 */ import { defineNuxtPlugin } from "#app"; import { useAuth, isValidJwt } from "~/lib/auth.js"; import { r as safeRedirect } from "~/lib/auth-redirect.js"; import { isPublicRoute } from "~/utils/access.js"; export default defineNuxtPlugin({ name: "console-session-sync", dependsOn: ["console-ui"], setup(app) { const auth = useAuth(); const router = app.$router; // 只处理 localStorage 会话事件;读取最新值而非 event.newValue,避免积压事件倒退状态。 function reconcileSession(event) { if ( event.storageArea !== localStorage || (event.key !== null && event.key !== "jwt") ) return; // Read the latest value: several storage events may already be queued. const persisted = localStorage.getItem("jwt"); if (persisted === auth.token) return; if (isValidJwt(persisted)) auth.prepareLogin().commit(persisted); else auth.clear(); const route = router.currentRoute.value; if (!auth.isLoggedIn && !isPublicRoute(route)) { const redirect = safeRedirect(route.fullPath); void router.replace({ path: "/login", query: redirect === "/" ? {} : { redirect }, }); } } window.addEventListener("storage", reconcileSession); // 应用销毁时解绑,避免热重载或重新挂载后叠加处理同一 storage 事件。 app.vueApp.onUnmount(() => window.removeEventListener("storage", reconcileSession), ); }, });