diff --git a/client/src/App/App.container.jsx b/client/src/App/App.container.jsx index 54ccd8791..bffef01c2 100644 --- a/client/src/App/App.container.jsx +++ b/client/src/App/App.container.jsx @@ -16,6 +16,7 @@ import { ApolloLink } from "apollo-boost"; import { ApolloProvider } from "react-apollo"; import { persistCache } from "apollo-cache-persist"; import initialState from "../graphql/initial-state"; +import { shouldRefreshToken, refreshToken } from "../graphql/middleware"; class AppContainer extends Component { state = { @@ -71,6 +72,11 @@ class AppContainer extends Component { const token = localStorage.getItem("token"); // return the headers to the context so httpLink can read them if (token) { + console.log("checking if token should refresh."); + if (shouldRefreshToken) { + refreshToken(); + } + return { headers: { ...headers, diff --git a/client/src/App/App.js b/client/src/App/App.js index 2c2c8eeb7..5f000622c 100644 --- a/client/src/App/App.js +++ b/client/src/App/App.js @@ -50,6 +50,8 @@ export default () => { //add the bearer token to the headers. localStorage.setItem("token", token); + const now = new Date(); + window.sessionStorage.setItem(`lastTokenRefreshTime`, now); apolloClient .mutate({ @@ -61,23 +63,6 @@ export default () => { console.log("User login upsert error.", error); }); - // apolloClient - // .query({ - // query: QUERY_BODYSHOP, - // fetchPolicy: "network-only" - // }) - // .then(r => { - // const bodyShopData = r.data.bodyshops[0]; - // apolloClient.writeData({ - // data: { - // bodyShopData: { ...bodyShopData, __typename: "bodyShopData" } - // } - // }); - // }) - // .catch(error => { - // console.log("Error getting bodyshop data.", error); - // }); - apolloClient.writeData({ data: { currentUser: { diff --git a/client/src/components/job-tombstone/job-tombstone.component.jsx b/client/src/components/job-tombstone/job-tombstone.component.jsx index 96c6725ed..368591854 100644 --- a/client/src/components/job-tombstone/job-tombstone.component.jsx +++ b/client/src/components/job-tombstone/job-tombstone.component.jsx @@ -14,6 +14,7 @@ import { import { UPDATE_JOB } from "../../graphql/jobs.queries"; import { useMutation } from "@apollo/react-hooks"; import FormItemPhone from "../form-items-formatted/phone-form-item.component"; +import { useTranslation } from "react-i18next"; const formItemLayout = { labelCol: { @@ -29,6 +30,7 @@ const formItemLayout = { function JobTombstone({ job, ...otherProps }) { const [jobContext, setJobContext] = useState(job); const [mutationUpdateJob] = useMutation(UPDATE_JOB); + const { t } = useTranslation(); if (!job) { return ( @@ -66,9 +68,10 @@ function JobTombstone({ job, ...otherProps }) { title={"RO " + jobContext.ro_number ?? "0"} subTitle={ jobContext.owner - ? jobContext.owner?.first_name ?? - +" " + jobContext.owner?.first_name - : "No owner" + ? (jobContext.owner?.first_name ?? "") + + " " + + (jobContext.owner?.last_name ?? "") + : t("jobs.labels.no_owner") } tags={{jobContext?.job_status?.name}} extra={[ diff --git a/client/src/graphql/middleware.js b/client/src/graphql/middleware.js new file mode 100644 index 000000000..b3a8ff7be --- /dev/null +++ b/client/src/graphql/middleware.js @@ -0,0 +1,38 @@ +import { auth } from "../firebase/firebase.utils"; + +//used to ensure that there is always a fresh token. +function minutesSince(date) { + const now = new Date(); + const millisecondsSince = now - date; + // Divide milliseconds by 1000 to get seconds + // Divide seconds by 60 to get minutes + return millisecondsSince / 1000 / 60; +} + +// Pass a different argument number to set a sooner/longer refresh time +export function shouldRefreshToken(minutesBeforeShouldRefresh = 45) { + const stringifiedRefreshTime = window.sessionStorage.getItem( + `lastTokenRefreshTime` + ); + const lastRefreshAt = new Date(stringifiedRefreshTime); + const aboutToExpire = + minutesSince(lastRefreshAt) >= minutesBeforeShouldRefresh; + return aboutToExpire; +} + +export async function refreshToken() { + console.log("Refreshing token.") + try { + if (auth.user) { + const idToken = await auth().currentUser.getIdToken( + /* force refresh */ true + ); + const now = new Date(); + window.localStorage.setItem(`lastTokenRefreshTime`, now); + localStorage.setItem("token", idToken); + console.log("Token refreshed.") + } + } catch (err) { + console.error(err); + } +} diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json index 699e2963c..caf984bc5 100644 --- a/client/src/translations/en_us/common.json +++ b/client/src/translations/en_us/common.json @@ -9,11 +9,18 @@ "labels": { "in": "In", "out": "Out" - }, - "title": "Welcome to {{framework}}", - "greetings": "Hello2!", - "intro": "To get started, edit <1><0> and save to reload." + } }, + + "jobs": { + "labels": { + "no_owner": "No Owner" + }, + "fields": { + "ro_number": "RO #" + } + }, + "whiteboard": { "viewJobImages": "View Job Images", "printCenter": "Print Center",