mirror of
https://github.com/myfatemi04/wheelshare-frontend.git
synced 2025-04-21 11:20:17 -04:00
clean up authentication code
This commit is contained in:
parent
557d554db3
commit
dde3edee04
|
@ -14,10 +14,10 @@ const ION_AUTHORIZATION_ENDPOINT = dev
|
|||
: 'https://ion.tjhsst.edu/oauth/authorize?response_type=code&client_id=rNa6n9YSg8ftINdyVPpUsaMuxNbHLo9dh1OsOktR&scope=read&redirect_uri=https%3A%2F%2Fwheelshare.space%2Fauth%2Fion%2Fcallback';
|
||||
|
||||
export default function App() {
|
||||
const { isLoggedIn, user } = useContext(AuthenticationContext);
|
||||
const { user } = useContext(AuthenticationContext);
|
||||
return (
|
||||
<div style={{ padding: '1rem' }}>
|
||||
{isLoggedIn ? (
|
||||
{user ? (
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
|
@ -28,7 +28,7 @@ export default function App() {
|
|||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
{user!.name}{' '}
|
||||
{user.name}{' '}
|
||||
<UIButton style={{ marginTop: 0 }} onClick={logout}>
|
||||
Log out
|
||||
</UIButton>
|
||||
|
|
|
@ -6,20 +6,19 @@ export type User = {
|
|||
email?: string;
|
||||
};
|
||||
|
||||
export type AuthState = {
|
||||
isLoggedIn: boolean | null;
|
||||
export type AuthenticationContextProps = {
|
||||
user: User | null;
|
||||
|
||||
/**
|
||||
* Function that can be used to trigger an auth state refresh.
|
||||
*/
|
||||
refreshAuthState: (() => void) | null;
|
||||
refresh: () => void;
|
||||
};
|
||||
|
||||
const AuthenticationContext = createContext<AuthState>({
|
||||
isLoggedIn: false,
|
||||
const AuthenticationContext = createContext<AuthenticationContextProps>({
|
||||
user: null,
|
||||
refreshAuthState: null,
|
||||
refresh: () =>
|
||||
console.warn('calling refresh on default AuthenticationContext'),
|
||||
});
|
||||
|
||||
export default AuthenticationContext;
|
||||
|
|
|
@ -1,45 +1,30 @@
|
|||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { getMe } from '../api';
|
||||
import AuthenticationContext, { AuthState } from './AuthenticationContext';
|
||||
import AuthenticationContext, { User } from './AuthenticationContext';
|
||||
|
||||
export default function AuthenticationWrapper({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const sessionToken = localStorage.getItem('session_token');
|
||||
// Prevent race conditions
|
||||
const [authState, setAuthState] = useState<AuthState>({
|
||||
isLoggedIn: null,
|
||||
user: null,
|
||||
refreshAuthState: null,
|
||||
});
|
||||
const [user, setUser] = useState<User | null>(null);
|
||||
|
||||
const refreshAuthState = useCallback(() => {
|
||||
const loggedOut = () =>
|
||||
setAuthState({ isLoggedIn: false, user: null, refreshAuthState });
|
||||
const refresh = useCallback(() => {
|
||||
const none = () => setUser(null);
|
||||
const sessionToken = localStorage.getItem('session_token');
|
||||
|
||||
if (sessionToken) {
|
||||
getMe()
|
||||
.then((user) => {
|
||||
if (user) {
|
||||
setAuthState({ isLoggedIn: true, user, refreshAuthState });
|
||||
getMe().then(setUser).catch(none);
|
||||
} else {
|
||||
loggedOut();
|
||||
none();
|
||||
}
|
||||
})
|
||||
.catch(loggedOut);
|
||||
} else {
|
||||
loggedOut();
|
||||
}
|
||||
}, [sessionToken]);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
refreshAuthState();
|
||||
}, [refreshAuthState]);
|
||||
useEffect(refresh, [refresh]);
|
||||
|
||||
return (
|
||||
<AuthenticationContext.Provider value={authState}>
|
||||
<AuthenticationContext.Provider value={{ user, refresh }}>
|
||||
{children}
|
||||
</AuthenticationContext.Provider>
|
||||
);
|
||||
|
|
|
@ -3,45 +3,51 @@ import { Redirect, useLocation, useParams } from 'react-router-dom';
|
|||
import AuthenticationContext from './AuthenticationContext';
|
||||
import { createSession } from './createSession';
|
||||
|
||||
function useCode() {
|
||||
const location = useLocation();
|
||||
const query = new URLSearchParams(location.search);
|
||||
const code = query.get('code');
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
export default function Authenticator() {
|
||||
const { provider } = useParams<{ provider: string }>();
|
||||
const query = new URLSearchParams(useLocation().search);
|
||||
const code = query.get('code');
|
||||
const { refreshAuthState } = useContext(AuthenticationContext);
|
||||
const [status, setStatus] =
|
||||
useState<'pending' | 'errored' | 'authenticated'>('pending');
|
||||
const code = useCode();
|
||||
const { refresh } = useContext(AuthenticationContext);
|
||||
|
||||
const [pending, setPending] = useState(true);
|
||||
const [token, setToken] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
createSession(code!)
|
||||
.then((data) => {
|
||||
if (data.status === 'success') {
|
||||
console.log('Success! Token:', data.token);
|
||||
setToken(data.token);
|
||||
localStorage.setItem('session_token', data.token);
|
||||
setStatus('authenticated');
|
||||
if (token) {
|
||||
localStorage.setItem('session_token', token);
|
||||
} else {
|
||||
console.log('Authentication failure.');
|
||||
setToken(null);
|
||||
localStorage.removeItem('session_token');
|
||||
setStatus('errored');
|
||||
}
|
||||
}, [token]);
|
||||
|
||||
useEffect(() => {
|
||||
setPending(true);
|
||||
createSession(code!)
|
||||
.then(({ token }) => {
|
||||
setToken(token ?? null);
|
||||
})
|
||||
.catch(() => {
|
||||
setStatus('errored');
|
||||
});
|
||||
.finally(() => setPending(false));
|
||||
}, [code, provider]);
|
||||
|
||||
useEffect(() => {
|
||||
refreshAuthState && refreshAuthState();
|
||||
}, [token, refreshAuthState]);
|
||||
refresh();
|
||||
}, [token, refresh]);
|
||||
|
||||
switch (status) {
|
||||
case 'authenticated':
|
||||
return <Redirect to="/" />;
|
||||
case 'errored':
|
||||
return <h1>Sign In Error</h1>;
|
||||
case 'pending':
|
||||
if (pending) {
|
||||
return <h1>Signing In</h1>;
|
||||
}
|
||||
|
||||
if (token) {
|
||||
return <Redirect to="/" />;
|
||||
}
|
||||
|
||||
// If we aren't pending anymore, but don't have a token, we must have errored
|
||||
return <h1>Sign In Error</h1>;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user