|
- import { HasChildren } from "@types";
- import { ResultCode } from "api";
- import {
- login as APILogin,
- logout as APILogout,
- changeContract as APIChangeContract,
- me,
- } from "api/auth";
- import { CustomCode } from "codes/custom";
- import { PageID } from "codes/page";
- import { UserRole } from "codes/user";
- import useAPICall from "hooks/useAPICall";
- import {
- createContext,
- memo,
- useCallback,
- useEffect,
- useMemo,
- useState,
- } from "react";
- import { AUTH } from "routes/auth";
-
- type Auth = {
- initialized: boolean;
-
- authenticated: boolean;
-
- role: UserRole;
- contractId: string | null;
- userId: string | null;
- name: string;
- custom: CustomCode[];
- customerName: string;
-
- isChangedContractId: boolean;
-
- login: (email: string, password: string) => Promise<boolean>;
- logout: VoidFunction;
-
- changeContractId: (contractId: string | null) => Promise<boolean>;
-
- checkRole: (role?: UserRole) => boolean;
- canAccess: (pageId: PageID) => boolean;
- };
- export const AuthContext = createContext<Auth>({
- initialized: false,
-
- authenticated: false,
-
- role: UserRole.NONE,
- contractId: null,
- userId: null,
- name: "",
- custom: [],
- customerName: "",
-
- isChangedContractId: false,
-
- login: async (email: string, password: string) => false,
- logout: () => {},
- changeContractId: async (contractId: string | null) => false,
- checkRole: (role?: UserRole) => false,
- canAccess: (pageId: PageID) => false,
- });
-
- type Props = HasChildren;
- function AuthContextProvider({ children }: Props) {
- const [initialized, setInitialized] = useState(false);
- const [role, setRole] = useState<UserRole>(UserRole.NONE);
- const [contractId, setContractId] = useState<string | null>(null);
- const [userId, setUserId] = useState<string | null>(null);
- const [name, setName] = useState("");
- const [custom, setCustom] = useState<CustomCode[]>([]);
- const [customerName, setCustomerName] = useState("");
-
- const isChangedContractId = useMemo(() => {
- return role === UserRole.SUPER_ADMIN && contractId !== null;
- }, [contractId]);
-
- const authenticated = useMemo(() => {
- return role !== UserRole.NONE;
- }, [role]);
-
- const { callAPI: callMe } = useAPICall({
- apiMethod: me,
- backDrop: true,
- onSuccess: (res) => {
- setContractId(res.data.contract_id);
- setUserId(res.data.id);
- setRole(res.data.role);
- setName(res.data.name);
- setCustom(res.data.custom ?? []);
- setCustomerName(res.data.contract_name ?? "");
- setInitialized(true);
- },
- onFailed: () => {
- clear();
- setInitialized(true);
- },
- });
-
- const { callAPI: callLogin } = useAPICall({
- apiMethod: APILogin,
- backDrop: true,
- onSuccess: (res) => {
- setContractId(res.data.contract_id);
- setUserId(res.data.id);
- setRole(res.data.role);
- setName(res.data.name);
- setCustom(res.data.custom ?? []);
- setCustomerName(res.data.contract_name ?? "");
- setInitialized(true);
- },
- });
-
- const { callAPI: callLogout } = useAPICall({
- apiMethod: APILogout,
- onSuccess: () => {
- clear();
- },
- });
- const { callAPI: callChangeContract } = useAPICall({
- apiMethod: APIChangeContract,
- backDrop: true,
- onSuccess: (res) => {
- setContractId(res.data.contract_id);
- setCustom(res.data.custom ?? []);
- setCustomerName(res.data.contract_name ?? "");
- setInitialized(true);
- },
- });
-
- const clear = () => {
- setRole(UserRole.NONE);
- setContractId(null);
- setUserId(null);
- setName("");
- setCustom([]);
- };
-
- const login = async (email: string, password: string) => {
- const res = await callLogin({ email, password });
- if (!res) return false;
-
- return res.result === ResultCode.SUCCESS;
- };
- const logout = () => {
- callLogout({});
- console.info("ログアウト");
- };
- const changeContractId = async (contractId: string | null) => {
- const res = await callChangeContract({ contract_id: contractId });
- return res?.result === ResultCode.SUCCESS;
- };
-
- const checkRole = useCallback(
- (targetRole?: UserRole): boolean => {
- if (targetRole === undefined) return true;
- return targetRole <= role;
- },
- [role]
- );
-
- const canAccess = useCallback(
- (pageId: PageID): boolean => {
- const authorization = AUTH[pageId];
-
- // デバッグ用
- // console.log(
- // "RET",
- // pageId,
- // role,
- // custom,
- // !!authorization &&
- // authorization.role.includes(role) &&
- // (authorization.custom.length === 0 ||
- // !!custom.find((c) => {
- // return authorization.custom.includes(c);
- // })),
- // [
- // !!authorization,
- // authorization.role.includes(role),
- // authorization.custom.length === 0,
- // !!custom.find((c) => {
- // return authorization.custom.includes(c);
- // }),
- // ]
- // );
-
- return (
- !!authorization &&
- // 権限条件
- authorization.role.includes(role) &&
- // カスタム条件
- (authorization.custom.length === 0 ||
- !!custom.find((c) => {
- return authorization.custom.includes(c);
- })) &&
- // 成り代わり条件
- (authorization.allowChangedContract === undefined ||
- role !== UserRole.SUPER_ADMIN ||
- isChangedContractId === authorization.allowChangedContract)
- );
- },
- [initialized, role, custom, isChangedContractId]
- );
-
- useEffect(() => {
- callMe({});
- }, []);
-
- return (
- <AuthContext.Provider
- value={{
- // Value
- initialized,
- authenticated,
- role,
- contractId,
- userId,
- name,
- custom,
- customerName,
- isChangedContractId,
-
- // Func
- login,
- logout,
- changeContractId,
- checkRole,
- canAccess,
- }}
- >
- {children}
- </AuthContext.Provider>
- );
- }
-
- export default memo(AuthContextProvider);
|