148 lines
3.8 KiB
TypeScript
148 lines
3.8 KiB
TypeScript
/* eslint-disable react-refresh/only-export-components */
|
|
import {
|
|
FC,
|
|
useState,
|
|
useEffect,
|
|
useCallback,
|
|
createContext,
|
|
useContext,
|
|
Dispatch,
|
|
SetStateAction,
|
|
} from "react";
|
|
import { LayoutSplashScreen } from "../../../../_metronic/layout/core";
|
|
import { AuthModel, UserModel } from "./_models";
|
|
import * as authHelper from "./AuthHelpers";
|
|
import { getUserByToken } from "./_requests";
|
|
import { WithChildren } from "../../../../_metronic/helpers";
|
|
|
|
type AuthContextProps = {
|
|
auth: AuthModel | undefined;
|
|
saveAuth: (auth: AuthModel | undefined) => void;
|
|
currentUser: UserModel | undefined;
|
|
setCurrentUser: Dispatch<SetStateAction<UserModel | undefined>>;
|
|
logout: () => void;
|
|
};
|
|
|
|
const initAuthContextPropsState = {
|
|
auth: authHelper.getAuth(),
|
|
saveAuth: () => {},
|
|
currentUser: undefined,
|
|
setCurrentUser: () => {},
|
|
logout: () => {},
|
|
};
|
|
|
|
const AuthContext = createContext<AuthContextProps>(initAuthContextPropsState);
|
|
|
|
const useAuth = () => {
|
|
return useContext(AuthContext);
|
|
};
|
|
|
|
const AuthProvider: FC<WithChildren> = ({ children }) => {
|
|
const [auth, setAuth] = useState<AuthModel | undefined>(authHelper.getAuth());
|
|
const [currentUser, setCurrentUser] = useState<UserModel | undefined>();
|
|
const [lastActivityTime, setLastActivityTime] = useState(Date.now());
|
|
|
|
let checkExpirationInMinutes: number = Number(
|
|
import.meta.env.VITE_APP_SESSION_EXPIRE_MINUTES
|
|
);
|
|
let expirationChecker: number = Number(
|
|
import.meta.env.VITE_APP_SESSION_EXPIRE_CHECKER
|
|
);
|
|
|
|
const saveAuth = (auth: AuthModel | undefined) => {
|
|
setAuth(auth);
|
|
if (auth) {
|
|
authHelper.setAuth(auth);
|
|
} else {
|
|
authHelper.removeAuth();
|
|
}
|
|
};
|
|
|
|
const logout = () => {
|
|
saveAuth(undefined);
|
|
setCurrentUser(undefined);
|
|
};
|
|
|
|
useEffect((): any => {
|
|
const expireSession = () => {
|
|
localStorage.removeItem("wrenchboard-agent-auth-details");
|
|
logout();
|
|
};
|
|
|
|
const checkInactivity = setInterval(() => {
|
|
let currentTime: number = Date.now();
|
|
let checkLastActivityTime: number = lastActivityTime;
|
|
|
|
if (currentTime - checkLastActivityTime > checkExpirationInMinutes) {
|
|
expireSession();
|
|
}
|
|
}, expirationChecker);
|
|
|
|
// cleaning up listeners
|
|
return () => {
|
|
clearInterval(checkInactivity);
|
|
};
|
|
}, [lastActivityTime]);
|
|
|
|
// Reset last activity time on user input
|
|
const resetTime = useCallback(() => {
|
|
setLastActivityTime(Date.now());
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
window.addEventListener("mousemove", resetTime);
|
|
window.addEventListener("keydown", resetTime);
|
|
|
|
return () => {
|
|
window.removeEventListener("mousemove", resetTime);
|
|
window.removeEventListener("keydown", resetTime);
|
|
};
|
|
}, [resetTime]);
|
|
|
|
return (
|
|
<AuthContext.Provider
|
|
value={{ auth, saveAuth, currentUser, setCurrentUser, logout }}
|
|
>
|
|
{children}
|
|
</AuthContext.Provider>
|
|
);
|
|
};
|
|
|
|
const AuthInit: FC<WithChildren> = ({ children }) => {
|
|
const { auth, currentUser, logout, setCurrentUser } = useAuth();
|
|
const [showSplashScreen, setShowSplashScreen] = useState(true);
|
|
|
|
// We should request user by authToken (IN OUR EXAMPLE IT'S API_TOKEN) before rendering the application
|
|
useEffect(() => {
|
|
const requestUser = async (apiToken: string) => {
|
|
try {
|
|
if (!currentUser) {
|
|
const { data } = await getUserByToken(apiToken);
|
|
if (data) {
|
|
setCurrentUser(data);
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error(error);
|
|
if (currentUser) {
|
|
logout();
|
|
}
|
|
} finally {
|
|
setShowSplashScreen(false);
|
|
}
|
|
};
|
|
|
|
if (auth && auth.api_token) {
|
|
requestUser(auth.api_token);
|
|
} else {
|
|
logout();
|
|
setShowSplashScreen(false);
|
|
}
|
|
// eslint-disable-next-line
|
|
}, []);
|
|
|
|
return showSplashScreen ? <LayoutSplashScreen /> : <>{children}</>;
|
|
};
|
|
|
|
export { AuthProvider, AuthInit, useAuth };
|