import { useCallback, useEffect, useState } from "react"; import type { AuthState, UserSession } from "./types.js"; /** * useAuth - 会话状态管理 * * 用途:管理用户登录状态、token、用户信息。 * P2 阶段:token 存储在 localStorage(F12 裁决),P6 评估迁移 httpOnly Cookie。 * * 注意:本 hook 提供"状态管理"骨架,具体的登录/登出 API 调用 * 由 apps/* 注入(通过 AuthProvider Context 或 props 传入 fetcher)。 * * @example * const { user, isAuthenticated, login, logout } = useAuth(); */ const TOKEN_KEY = "edu_auth_token"; const USER_KEY = "edu_auth_user"; export interface UseAuthReturn extends AuthState { /** 登录(由调用方注入 fetcher) */ login: (token: string, user: UserSession) => void; /** 登出 */ logout: () => void; /** 刷新用户信息 */ refreshUser: (user: UserSession) => void; } export function useAuth(): UseAuthReturn { const [state, setState] = useState({ user: null, token: null, isAuthenticated: false, isLoading: true, }); // 初始化:从 localStorage 读取 token + user(F12 裁决 P2 用 localStorage) useEffect(() => { try { const token = localStorage.getItem(TOKEN_KEY); const userJson = localStorage.getItem(USER_KEY); const user = userJson ? (JSON.parse(userJson) as UserSession) : null; setState({ user, token, isAuthenticated: Boolean(token && user), isLoading: false, }); } catch { setState({ user: null, token: null, isAuthenticated: false, isLoading: false, }); } }, []); const login = useCallback((token: string, user: UserSession): void => { localStorage.setItem(TOKEN_KEY, token); localStorage.setItem(USER_KEY, JSON.stringify(user)); setState({ user, token, isAuthenticated: true, isLoading: false, }); }, []); const logout = useCallback((): void => { localStorage.removeItem(TOKEN_KEY); localStorage.removeItem(USER_KEY); setState({ user: null, token: null, isAuthenticated: false, isLoading: false, }); }, []); const refreshUser = useCallback((user: UserSession): void => { localStorage.setItem(USER_KEY, JSON.stringify(user)); setState((prev) => ({ ...prev, user })); }, []); return { ...state, login, logout, refreshUser, }; }