TTMT.ManageWebGUI/src/hooks/useAuth.tsx
2025-12-22 14:53:19 +07:00

107 lines
2.8 KiB
TypeScript

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<void>;
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<IAuthContext | null>(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<string>(getStoredUser() || "");
const [isAuthenticated, setIsAuthenticated] = useState<boolean>(!!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 (
<AuthContext.Provider
value={{
isAuthenticated,
setAuthenticated,
login,
logout,
username: user,
token,
name,
acs,
role: { roleName, priority: Number(priority) },
hasPermission
}}>
{children}
</AuthContext.Provider>
);
}
// 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;
}