122 lines
3.9 KiB
JavaScript
122 lines
3.9 KiB
JavaScript
import React, { useEffect, Suspense, lazy } from "react";
|
|
import { useApolloClient, useQuery } from "@apollo/react-hooks";
|
|
import { Switch, Route, Redirect } from "react-router-dom";
|
|
import firebase from "../firebase/firebase.utils";
|
|
|
|
import "./App.css";
|
|
|
|
//Component Imports
|
|
import LoadingSpinner from "../components/loading-spinner/loading-spinner.component";
|
|
import AlertComponent from "../components/alert/alert.component";
|
|
import ErrorBoundary from "../components/error-boundary/error-boundary.component";
|
|
|
|
import { auth } from "../firebase/firebase.utils";
|
|
import { UPSERT_USER } from "../graphql/user.queries";
|
|
import { GET_CURRENT_USER } from "../graphql/local.queries";
|
|
// import { QUERY_BODYSHOP } from "../graphql/bodyshop.queries";
|
|
|
|
import PrivateRoute from "../utils/private-route";
|
|
|
|
const LandingPage = lazy(() => import("../pages/landing/landing.page"));
|
|
const ManagePage = lazy(() => import("../pages/manage/manage.page"));
|
|
const SignInPage = lazy(() => import("../pages/sign-in/sign-in.page"));
|
|
const Unauthorized = lazy(() =>
|
|
import("../pages/unauthorized/unauthorized.component")
|
|
);
|
|
|
|
export default () => {
|
|
const apolloClient = useApolloClient();
|
|
|
|
useEffect(() => {
|
|
//Run the auth code only on the first render.
|
|
const unsubscribeFromAuth = auth.onAuthStateChanged(async user => {
|
|
if (user) {
|
|
let token;
|
|
token = await user.getIdToken();
|
|
const idTokenResult = await user.getIdTokenResult();
|
|
const hasuraClaim =
|
|
idTokenResult.claims["https://hasura.io/jwt/claims"];
|
|
if (!hasuraClaim) {
|
|
// Check if refresh is required.
|
|
const metadataRef = firebase
|
|
.database()
|
|
.ref("metadata/" + user.uid + "/refreshTime");
|
|
|
|
metadataRef.on("value", async () => {
|
|
// Force refresh to pick up the latest custom claims changes.
|
|
token = await user.getIdToken(true);
|
|
});
|
|
}
|
|
|
|
//add the bearer token to the headers.
|
|
localStorage.setItem("token", token);
|
|
const now = new Date();
|
|
window.sessionStorage.setItem(`lastTokenRefreshTime`, now);
|
|
|
|
apolloClient
|
|
.mutate({
|
|
mutation: UPSERT_USER,
|
|
variables: { authEmail: user.email, authToken: user.uid }
|
|
})
|
|
.then()
|
|
.catch(error => {
|
|
console.log("User login upsert error.", error);
|
|
});
|
|
|
|
apolloClient.writeData({
|
|
data: {
|
|
currentUser: {
|
|
email: user.email,
|
|
displayName: user.displayName,
|
|
token,
|
|
uid: user.uid,
|
|
photoUrl: user.photoURL,
|
|
__typename: "currentUser"
|
|
}
|
|
}
|
|
});
|
|
} else {
|
|
apolloClient.writeData({ data: { currentUser: null } });
|
|
localStorage.removeItem("token");
|
|
}
|
|
});
|
|
|
|
return function cleanup() {
|
|
unsubscribeFromAuth();
|
|
};
|
|
}, [apolloClient]);
|
|
|
|
const HookCurrentUser = useQuery(GET_CURRENT_USER);
|
|
if (HookCurrentUser.loading) return <LoadingSpinner />;
|
|
if (HookCurrentUser.error)
|
|
return <AlertComponent message={HookCurrentUser.error.message} />;
|
|
return (
|
|
<div>
|
|
<Switch>
|
|
<ErrorBoundary>
|
|
<Suspense fallback={<div>TODO: Suspense Loading</div>}>
|
|
<Route exact path='/' component={LandingPage} />
|
|
<Route exact path='/unauthorized' component={Unauthorized} />
|
|
<Route
|
|
exact
|
|
path='/signin'
|
|
render={() =>
|
|
HookCurrentUser.data.currentUser ? (
|
|
<Redirect to='/manage' />
|
|
) : (
|
|
<SignInPage />
|
|
)
|
|
}
|
|
/>
|
|
<PrivateRoute
|
|
isAuthorized={HookCurrentUser.data.currentUser ? true : false}
|
|
path='/manage'
|
|
component={ManagePage}
|
|
/>
|
|
</Suspense>
|
|
</ErrorBoundary>
|
|
</Switch>
|
|
</div>
|
|
);
|
|
};
|