import React, { useState, useEffect, useContext, FC } from "react"; import createAuth0Client from "@auth0/auth0-spa-js"; import Auth0Client from "@auth0/auth0-spa-js/dist/typings/Auth0Client"; interface IAuth0Context { isAuthenticated: boolean; user: any; loading: boolean; popupOpen: boolean; loginWithPopup(options: PopupLoginOptions): Promise; handleRedirectCallback(): Promise; getIdTokenClaims(o?: getIdTokenClaimsOptions): Promise; loginWithRedirect(o: RedirectLoginOptions): Promise; getTokenSilently(o?: GetTokenSilentlyOptions): Promise; getTokenWithPopup(o?: GetTokenWithPopupOptions): Promise; logout(o?: LogoutOptions): void; } export interface IAuth0ProviderOptions { children: React.ReactElement; onRedirectCallback?(result: RedirectLoginResult): void; } const DEFAULT_REDIRECT_CALLBACK: () => void = () => window.history.replaceState({}, document.title, window.location.pathname); export const Auth0Context: React.Context = React.createContext( null ); export const useAuth0: () => IAuth0Context = () => useContext(Auth0Context)!; export const Auth0Provider = ({ children, onRedirectCallback = DEFAULT_REDIRECT_CALLBACK, ...initOptions }: IAuth0ProviderOptions & Auth0ClientOptions) => { const [isAuthenticated, setIsAuthenticated] = useState(false); const [user, setUser] = useState(); const [auth0Client, setAuth0] = useState(); const [loading, setLoading] = useState(true); const [popupOpen, setPopupOpen] = useState(false); useEffect(() => { const initAuth0 = async () => { const auth0FromHook = await createAuth0Client(initOptions); setAuth0(auth0FromHook); if (window.location.search.includes("code=")) { const { appState } = await auth0FromHook.handleRedirectCallback(); onRedirectCallback(appState); } const isAuthenticated = await auth0FromHook.isAuthenticated(); setIsAuthenticated(isAuthenticated); if (isAuthenticated) { const user = await auth0FromHook.getUser(); setUser(user); } setLoading(false); }; initAuth0(); // eslint-disable-next-line }, []); const loginWithPopup = async (o: PopupLoginOptions) => { setPopupOpen(true); try { await auth0Client!.loginWithPopup(o); } catch (error) { console.error(error); } finally { setPopupOpen(false); } const user = await auth0Client!.getUser(); setUser(user); setIsAuthenticated(true); }; const handleRedirectCallback = async () => { setLoading(true); const result = await auth0Client!.handleRedirectCallback(); const user = await auth0Client!.getUser(); setLoading(false); setIsAuthenticated(true); setUser(user); return result; }; return ( auth0Client!.getIdTokenClaims(o), loginWithRedirect: (o: RedirectLoginOptions) => auth0Client!.loginWithRedirect(o), getTokenSilently: (o: GetTokenSilentlyOptions | undefined) => auth0Client!.getTokenSilently(o), getTokenWithPopup: (o: GetTokenWithPopupOptions | undefined) => auth0Client!.getTokenWithPopup(o), logout: (o: LogoutOptions | undefined) => auth0Client!.logout(o) }} > {children} ); };