import { useContext, useEffect, useState } from 'react'; import { Redirect, useLocation, useParams } from 'react-router-dom'; import AuthenticationContext from './AuthenticationContext'; import { createSession } from './createSession'; function useCodeAndError() { const location = useLocation(); const query = new URLSearchParams(location.search); const code = query.get('code'); const error = query.get('error'); return [code, error]; } function inferRedirectUrl() { // Strip query parameters const { protocol, host, pathname } = window.location; const redirectUrl = `${protocol}//${host}${pathname}`; return redirectUrl; } export default function Authenticator() { const { provider } = useParams<{ provider: string }>(); const [code, error] = useCodeAndError(); const { refresh } = useContext(AuthenticationContext); const [pending, setPending] = useState(true); const [token, setToken] = useState(null); useEffect(() => { if (token) { localStorage.setItem('session_token', token); } else { localStorage.removeItem('session_token'); } }, [token]); useEffect(() => { if (code) { setPending(true); createSession(code, inferRedirectUrl()) .then(({ token }) => { setToken(token ?? null); }) .finally(() => setPending(false)); } }, [code, provider]); useEffect(() => { // Refresh when the token changes refresh(); }, [token, refresh]); let children: JSX.Element; if (error != null) { switch (error) { case 'access_denied': children = ( <>

Sign In Error

We couldn't use your Ion account to log in.

Home ); break; default: console.error('Unhandled OAuth error case:', error); children =

Sign In Error

; } } else if (pending) { children =

Signing In

; } else if (token) { children = ; } else { // If we aren't pending anymore, but don't have a token, we must have errored children = ( <>

Sign In Error



Home ); } return (
{children}
); }