fix(web): sync auth expiry state
This commit is contained in:
@@ -13,6 +13,7 @@ import { usePathname, useRouter } from "next/navigation"
|
||||
|
||||
import { fetchProfile, logout } from "@/lib/api/auth"
|
||||
import {
|
||||
AUTH_SESSION_EXPIRED_EVENT,
|
||||
clearSession,
|
||||
readSession,
|
||||
writeSession,
|
||||
@@ -68,16 +69,35 @@ export function AuthProvider({ children }: { children: ReactNode }) {
|
||||
}, [requiresAuth, router])
|
||||
|
||||
async function signOut() {
|
||||
await logout()
|
||||
setSession(null)
|
||||
startTransition(() => {
|
||||
router.replace("/dashboard/login")
|
||||
})
|
||||
try {
|
||||
await logout()
|
||||
} finally {
|
||||
setSession(null)
|
||||
startTransition(() => {
|
||||
router.replace("/dashboard/login")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
function handleAuthExpired() {
|
||||
setSession(null)
|
||||
if (requiresAuth) {
|
||||
startTransition(() => {
|
||||
router.replace("/dashboard/login")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener(AUTH_SESSION_EXPIRED_EVENT, handleAuthExpired)
|
||||
return () => {
|
||||
window.removeEventListener(AUTH_SESSION_EXPIRED_EVENT, handleAuthExpired)
|
||||
}
|
||||
}, [requiresAuth, router])
|
||||
|
||||
useEffect(() => {
|
||||
const stored = readSession()
|
||||
setSession(stored)
|
||||
setSession(stored)
|
||||
if (stored) {
|
||||
void refreshProfile()
|
||||
return
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { clearSession, readSession } from "@/lib/auth"
|
||||
import { expireSession, readSession } from "@/lib/auth"
|
||||
|
||||
const API_BASE_URL =
|
||||
process.env.NEXT_PUBLIC_API_BASE_URL?.trim() || ""
|
||||
@@ -20,7 +20,7 @@ async function parseResult<T>(response: Response) {
|
||||
const payload = (await response.json()) as JsonResult<T>
|
||||
if (!response.ok || !payload.success) {
|
||||
if (payload.errorCode === 3000 || payload.errorCode === 3002) {
|
||||
clearSession()
|
||||
expireSession()
|
||||
}
|
||||
const error = new Error(payload.message || "请求失败")
|
||||
;(error as Error & { errorCode?: number }).errorCode = payload.errorCode
|
||||
|
||||
@@ -16,6 +16,7 @@ export type AuthSession = {
|
||||
}
|
||||
|
||||
const SESSION_STORAGE_KEY = "cs-ai-agent-session"
|
||||
export const AUTH_SESSION_EXPIRED_EVENT = "cs-ai-agent-auth-expired"
|
||||
|
||||
function hasWindow() {
|
||||
return typeof window !== "undefined"
|
||||
@@ -52,3 +53,11 @@ export function clearSession() {
|
||||
}
|
||||
window.localStorage.removeItem(SESSION_STORAGE_KEY)
|
||||
}
|
||||
|
||||
export function expireSession() {
|
||||
if (!hasWindow()) {
|
||||
return
|
||||
}
|
||||
clearSession()
|
||||
window.dispatchEvent(new Event(AUTH_SESSION_EXPIRED_EVENT))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user