Files
float-users/src/app/modules/auth/core/Auth.tsx
T
2023-04-15 16:06:57 +01:00

116 lines
3.1 KiB
TypeScript

import {
FC,
useState,
useEffect,
createContext,
useContext,
useRef,
Dispatch,
SetStateAction,
} from 'react'
import {useLocation} from 'react-router-dom'
import {LayoutSplashScreen} from '../../../../_res/layout/core'
import {AuthModel, UserModel} from './_models'
import * as authHelper from './AuthHelpers'
import {getUserByToken} from './_requests'
import {WithChildren} from '../../../../_res/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 saveAuth = (auth: AuthModel | undefined) => {
setAuth(auth)
if (auth) {
authHelper.setAuth(auth)
} else {
authHelper.removeAuth()
}
}
const logout = () => {
saveAuth(undefined)
setCurrentUser(undefined)
}
return (
<AuthContext.Provider value={{auth, saveAuth, currentUser, setCurrentUser, logout}}>
{children}
</AuthContext.Provider>
)
}
const AuthInit: FC<WithChildren> = ({children}) => {
const pathname = useLocation().pathname
const {auth, logout, setCurrentUser} = useAuth()
const didRequest = useRef(false)
const [showSplashScreen, setShowSplashScreen] = useState(true)
// We should request user by authToken (IN OUR EXAMPLE IT'S API_TOKEN) before rendering the application
useEffect(() => {
// function to expire session after 5 mins
let logoutSession = setTimeout(()=>{ //expire session after 5 mins
logout()
}, Number(process.env.REACT_APP_SESSION_TIMEOUT))
const requestUser = async (apiToken: string) => {
try {
if (!didRequest.current) {
// const {data} = await getUserByToken(apiToken)
// if (data) {
// setCurrentUser(data)
// }
if (localStorage.getItem('kt-auth-react-v')) {
setCurrentUser(auth.profile)
}
}
} catch (error) {
console.error(error)
if (!didRequest.current) {
logout()
}
} finally {
setShowSplashScreen(false)
}
return () => (didRequest.current = true)
}
if (auth && auth.session_token) {
requestUser(auth.session_token)
} else {
logout()
setShowSplashScreen(false)
}
// eslint-disable-next-line
return ()=>{ // clears session timeout side effect
clearInterval(logoutSession)
}
}, [pathname])
return showSplashScreen ? <LayoutSplashScreen /> : <>{children}</>
}
export {AuthProvider, AuthInit, useAuth}