diff --git a/client/package.json b/client/package.json index 80f871cdb..4eefe5e0e 100644 --- a/client/package.json +++ b/client/package.json @@ -13,6 +13,7 @@ "apollo-link-context": "^1.0.19", "apollo-link-error": "^1.1.12", "apollo-link-logger": "^1.2.3", + "apollo-link-retry": "^2.2.15", "apollo-link-ws": "^1.0.19", "axios": "^0.19.2", "chart.js": "^2.9.3", diff --git a/client/src/App/App.container.jsx b/client/src/App/App.container.jsx index a860694be..62d7e7b1c 100644 --- a/client/src/App/App.container.jsx +++ b/client/src/App/App.container.jsx @@ -13,9 +13,13 @@ import GlobalLoadingBar from "../components/global-loading-bar/global-loading-ba import SpinnerComponent from "../components/loading-spinner/loading-spinner.component"; import errorLink from "../graphql/apollo-error-handling"; import App from "./App"; - - +import { RetryLink } from "apollo-link-retry"; +import { auth } from "../firebase/firebase.utils"; export default class AppContainer extends Component { + // constructor() { + // super(); + // } + state = { client: null, loaded: false @@ -29,7 +33,7 @@ export default class AppContainer extends Component { const wsLink = new WebSocketLink({ uri: process.env.REACT_APP_GRAPHQL_ENDPOINT_WS, options: { - lazy: true, + //lazy: true, reconnect: true, connectionParams: () => { const token = localStorage.getItem("token"); @@ -44,6 +48,24 @@ export default class AppContainer extends Component { } }); + // const wsLink = new WebSocketLink({ + // uri: websocketUrl, + // options: { + // reconnect: true + // }, + // webSocketImpl: ws + // }); + + const subscriptionMiddleware = { + applyMiddleware: async (options, next) => { + options.authToken = await auth.currentUser.getIdToken(true); + next(); + } + }; + + // add the middleware to the web socket link via the Subscription Transport client + wsLink.subscriptionClient.use([subscriptionMiddleware]); + const link = split( // split based on operation type ({ query }) => { @@ -65,26 +87,84 @@ export default class AppContainer extends Component { httpLink ); + // const authLink = setContext((_, { headers }) => { + // const token = localStorage.getItem("token"); + // console.log("In the auth link"); + // //Check to see if the token has expired. If it has, then + // if (token) { + // return { + // headers: { + // ...headers, + // authorization: token ? `Bearer ${token}` : "" + // } + // }; + // } else { + // return { headers }; + // } + // }); + const authLink = setContext((_, { headers }) => { - const token = localStorage.getItem("token"); - if (token) { - return { - headers: { - ...headers, - authorization: token ? `Bearer ${token}` : "" - } - }; - } else { - return { headers }; - } + // return AsyncTokenLookup() + // .then((userToken) => { + // token = userToken; + // return { token }; + // }) + return auth.currentUser.getIdToken().then(token => { + if (token) { + return { + headers: { + ...headers, + authorization: token ? `Bearer ${token}` : "" + } + }; + } else { + return { headers }; + } + }); }); + // const authLink = new ApolloLink((operation, forward) => { + // console.log("The new auth link"); + // const token = localStorage.getItem("token"); + // auth.currentUser. + // auth.currentUser.getIdToken().then(t => { + // console.log("token", token); + // if (token) { + // operation.setContext({ + // headers: { + // Authorization: `Bearer ${token}` + // } + // }); + + // operation.setContext({ + // headers: { + // Authorization: `Bearer ${token}` + // } + // }); + // return forward(operation); + // } + // }); + // return forward(operation); + // }); + const middlewares = []; if (process.env.NODE_ENV === "development") { middlewares.push(apolloLogger); } - middlewares.push(errorLink.concat(authLink.concat(link))); + const retryLink = new RetryLink({ + delay: { + initial: 300, + max: 5, + jitter: true + }, + attempts: { + max: 5, + retryIf: (error, _operation) => !!error + } + }); + + middlewares.push(retryLink.concat(errorLink.concat(authLink.concat(link)))); const cache = new InMemoryCache(); @@ -100,8 +180,6 @@ export default class AppContainer extends Component { }); } - componentWillUnmount() {} - render() { const { client, loaded } = this.state; if (!loaded) { diff --git a/client/src/graphql/apollo-error-handling.js b/client/src/graphql/apollo-error-handling.js index d6fdb1b7d..ea2d7fb62 100644 --- a/client/src/graphql/apollo-error-handling.js +++ b/client/src/graphql/apollo-error-handling.js @@ -41,59 +41,9 @@ const errorLink = onError( } }); console.log(operation.getContext()); - // console.log("forward", forward); - // console.log("operation", operation); return forward(operation); - - // return new Observable(observer => { - // const subscriber = { - // next: observer.next.bind(observer), - // error: observer.error.bind(observer), - // complete: observer.complete.bind(observer) - // }; - // console.log("About to resend the request."); - // // Retry last failed request - // forward(operation).subscribe(subscriber); - // }); } }); - - // return new Observable(observer => { - // auth.currentUser - // .getIdToken(true) - // .then(function(idToken) { - // if (!idToken) { - // window.localStorage.removeItem("token"); - // return console.log("Refresh token has expired"); - // } - // console.log("Got a new token", idToken); - // window.localStorage.setItem("token", idToken); - - // // reset the headers - // operation.setContext(({ headers = {} }) => ({ - // headers: { - // // Re-add old headers - // ...headers, - // // Switch out old access token for new one - // authorization: idToken ? `Bearer ${idToken}` : "" - // } - // })); - - // const subscriber = { - // next: observer.next.bind(observer), - // error: observer.error.bind(observer), - // complete: observer.complete.bind(observer) - // }; - // console.log("About to resend the request."); - // // Retry last failed request - // forward(operation).subscribe(subscriber); - // }) - // .catch(error => { - // // No refresh or client token available, we force user to login - // console.log("Hit an error."); - // observer.error(error); - // }); - // }); } } ); diff --git a/client/yarn.lock b/client/yarn.lock index 42a0848ed..4fbf9a330 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -2317,7 +2317,7 @@ dependencies: "@types/yargs-parser" "*" -"@types/zen-observable@^0.8.0": +"@types/zen-observable@0.8.0", "@types/zen-observable@^0.8.0": version "0.8.0" resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.0.tgz#8b63ab7f1aa5321248aad5ac890a485656dcea4d" integrity sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg== @@ -2893,6 +2893,15 @@ apollo-link-logger@^1.2.3: resolved "https://registry.yarnpkg.com/apollo-link-logger/-/apollo-link-logger-1.2.3.tgz#1f3e6f7849ce7a7e3aa822141fe062cfa278b1e1" integrity sha512-GaVwdHyXmawfvBlHfZkFkBHH3+YH7wibzSCc4/YpIbPVtbtZqi0Qop18w++jgpw385W083DMOdYe2eJsKkZdag== +apollo-link-retry@^2.2.15: + version "2.2.15" + resolved "https://registry.yarnpkg.com/apollo-link-retry/-/apollo-link-retry-2.2.15.tgz#4cc3202fcb6251fed6f6b57ade99b4b1ad05c619" + integrity sha512-ltwXGxm+2NXzskrk+GTofj66LQtcc9OGCjIxAPbjlvtHanpKJn8CviWq8dIsMiYGS9T9rGG/kPPx/VdJfcFb6w== + dependencies: + "@types/zen-observable" "0.8.0" + apollo-link "^1.2.13" + tslib "^1.9.3" + apollo-link-ws@^1.0.19: version "1.0.19" resolved "https://registry.yarnpkg.com/apollo-link-ws/-/apollo-link-ws-1.0.19.tgz#dfa871d4df883a8777c9556c872fc892e103daa5"