Skip to content

Instantly share code, notes, and snippets.

@luisrudge
Created August 2, 2019 17:21
Show Gist options
  • Save luisrudge/28e591869dcdee10afdfd878bf20b006 to your computer and use it in GitHub Desktop.
Save luisrudge/28e591869dcdee10afdfd878bf20b006 to your computer and use it in GitHub Desktop.
[WIP / non-official] typescript version of the react wrapper for auth0-spa-js
import React, { useState, useEffect, useContext } from "react";
import createAuth0Client from "@auth0/auth0-spa-js";
import Auth0Client from "@auth0/auth0-spa-js/dist/typings/Auth0Client";
interface Auth0Context {
isAuthenticated: boolean;
user: any;
loading: boolean;
popupOpen: boolean;
loginWithPopup(options: PopupLoginOptions): Promise<void>;
handleRedirectCallback(): Promise<RedirectLoginResult>;
getIdTokenClaims(o?: getIdTokenClaimsOptions): Promise<IdToken>;
loginWithRedirect(o: RedirectLoginOptions): Promise<void>;
getTokenSilently(o?: GetTokenSilentlyOptions): Promise<string | undefined>;
getTokenWithPopup(o?: GetTokenWithPopupOptions): Promise<string | undefined>;
logout(o?: LogoutOptions): void;
}
interface Auth0ProviderOptions {
children: React.ReactElement;
onRedirectCallback?(result: RedirectLoginResult): void;
}
const DEFAULT_REDIRECT_CALLBACK = () =>
window.history.replaceState({}, document.title, window.location.pathname);
export const Auth0Context = React.createContext<Auth0Context | null>(null);
export const useAuth0 = () => useContext(Auth0Context)!;
export const Auth0Provider = ({
children,
onRedirectCallback = DEFAULT_REDIRECT_CALLBACK,
...initOptions
}: Auth0ProviderOptions & Auth0ClientOptions) => {
const [isAuthenticated, setIsAuthenticated] = useState(false);
const [user, setUser] = useState();
const [auth0Client, setAuth0] = useState<Auth0Client>();
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 (
<Auth0Context.Provider
value={{
isAuthenticated,
user,
loading,
popupOpen,
loginWithPopup,
handleRedirectCallback,
getIdTokenClaims: (o: getIdTokenClaimsOptions | undefined) =>
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}
</Auth0Context.Provider>
);
};
@jagwire16
Copy link

Wow. You just saved the day. Thanks for tackling this ahead of me. I was about to abandon the Auth0 in Typescript for React approach because of the terrible example they provided and I think I might be able to stick with it now. <3

@christopherhill
Copy link

Just a note for anyone reading this, depending on your tsconfig.json and overall Typescript setup, you may need to ensure that you use a .tsx extension for proper evaluation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment