import { useContext , useEffect , useState } from 'react' ; import UserContext from '../context/user-context' ; import { IAccessTokenContext } from '../context/access-token-context' ; import { getAccessTokenFromCache , ensureClient } from '../utils/auth0' ; import Auth0Context , { LoginOptions , AccessTokenRequestOptions } from '../context/auth0-context' ; export interface UseAuthResult { /**
     * The current user.
     */ user : any ; /**
     * The access token.
     */ accessToken ? : string | null ; /**
     * If the transaction failed, this will contain the error.
     */ error : Error | null ; /**
     * Is the transaction still ongoing.
     */ isLoading : boolean ; /**
     * Is the user authenticated.
     */ isAuthenticated : boolean ; /**
     * Sign in.
     */ login : ( options : LoginOptions ) => Promise < void > ; /**
     * Sign out.
     */ logout : ( options : LogoutOptions ) => void ; } function initialState ( ) { return { accessToken : null , error : null , isLoading : false } ; } export default function useAuth ( accessTokenRequest ? ) { const { isAuthenticated , isLoading , error , user } = useContext ( UserContext ) ; const { client , login , logout , handlers } = useContext ( Auth0Context ) ; if ( ! accessTokenRequest ) { return { user , error , isAuthenticated , isLoading , login , logout } ; } const [ state , setState ] = useState < IAccessTokenContext > ( ( ) : IAccessTokenContext => ( { ... initialState ( ) , accessToken : client && getAccessTokenFromCache ( client , accessTokenRequest . audience , accessTokenRequest . scope ) , isLoading : ! ! accessTokenRequest } ) ) ; useEffect ( ( ) => { if ( ! client || isLoading || ! isAuthenticated ) { return ; } if ( state . accessToken ) { return ; } const cachedAccessToken = getAccessTokenFromCache ( client , accessTokenRequest . audience , accessTokenRequest . scope ) ; if ( cachedAccessToken ) { setState ( { ... initialState ( ) , accessToken : cachedAccessToken } ) ; return ; } const getToken = async ( ) : Promise < void > => { try { setState ( { ... initialState ( ) , isLoading : true } ) ; setState ( { ... initialState ( ) , accessToken : await ensureClient ( client ) . getTokenSilently ( { audience : accessTokenRequest . audience , scope : accessTokenRequest . scope } ) } ) ; } catch ( e ) { if ( handlers . onAccessTokenError ) { handlers . onAccessTokenError ( e , accessTokenRequest ) ; } setState ( { ... initialState ( ) , error : e } ) ; } } ; getToken ( ) ; } , [ isAuthenticated , isLoading ] ) ; return { user , error : error || state . error , isAuthenticated , isLoading : isLoading || state . isLoading , accessToken : state . accessToken , login , logout } ; }