import { sleep } from "@/lib/utils"; import { PermissionEnum } from "@/types/permission"; import React, { useContext, useEffect, useMemo } from "react"; import { useCallback, useState } from "react"; export interface IAuthContext { isAuthenticated: boolean; setAuthenticated: (value: boolean) => void; logout: () => Promise; login: (username: string) => void; username: string; token: string; name: string; acs: number[]; hasPermission: (permission: PermissionEnum) => boolean; role: { roleName: string; priority: number; }; } const AuthContext = React.createContext(null); const key = "accesscontrol.auth.user"; function getStoredUser() { return localStorage.getItem(key); } function setStoredUser(user: string | null) { if (user) { localStorage.setItem(key, user); } else { localStorage.removeItem(key); } } export function AuthProvider({ children }: { children: React.ReactNode }) { const [user, setUser] = useState(getStoredUser() || ""); const [isAuthenticated, setIsAuthenticated] = useState(!!user); const token = localStorage.getItem("token") || ""; const name = localStorage.getItem("name") || ""; const acsString = localStorage.getItem("acs"); const acs = useMemo(() => (acsString ? acsString.split(",").map(Number) : []), [acsString]); const roleName = localStorage.getItem("role") || ""; const priority = localStorage.getItem("priority") || "-1"; const setAuthenticated = useCallback((value: boolean) => { setIsAuthenticated(value); }, []); const login = useCallback((username: string) => { setStoredUser(username); setUser(username); }, []); const hasPermission = useCallback( (permission: PermissionEnum) => { return acs.some((a) => a === permission); }, [acs] ); const logout = useCallback(async () => { await sleep(250); setAuthenticated(false); setStoredUser(""); setUser(""); localStorage.removeItem("token"); localStorage.removeItem("name"); localStorage.removeItem("acs"); localStorage.removeItem("role"); localStorage.removeItem("priority"); }, [setAuthenticated]); useEffect(() => { setUser(getStoredUser() || ""); }, []); return ( {children} ); } // eslint-disable-next-line react-refresh/only-export-components export function useAuth() { const context = useContext(AuthContext); if (!context) { throw new Error("useAuth must be used within an AuthProvider"); } return context; }