Created
May 11, 2020 12:01
-
-
Save bzhr/531e1c25a4960fcd06ec06d8b21f143b to your computer and use it in GitHub Desktop.
Revisions
-
bzhr created this gist
May 11, 2020 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,142 @@ import React from "react"; import ReactDOM from "react-dom"; import ApolloClient from "apollo-client"; import { ApolloProvider } from "@apollo/react-hooks"; import { ApolloLink, fromPromise, Observable } from "apollo-link"; import { onError } from "apollo-link-error"; // import "./index.css"; import App from "./App"; import * as serviceWorker from "./serviceWorker"; import { createUploadLink } from "apollo-upload-client"; import { setContext } from "apollo-link-context"; import { InMemoryCache } from "apollo-cache-inmemory"; import "./assets/main.css"; // import { signOut } from "./components/Auth"; import { getToken, getRefreshToken, getNewToken } from "./constants/token"; const API_URL = process.env.REACT_APP_API_URL; const httpLink = createUploadLink({ uri: API_URL ? API_URL : "/graphql", credentials: "omit", }); const authLink = setContext((_, { headers }) => { // get the authentication token from local storage if it exists const token = localStorage.getItem("token"); console.log("Token in auth link: ", token); return { headers: { ...headers, authorization: token ? `JWT ${token}` : "", }, }; }); let isRefreshing = false; let pendingRequests = []; const resolvePendingRequests = () => { pendingRequests.map((callback) => callback()); pendingRequests = []; }; // const getAndStoreToken = () => new Promise const errorLink = onError( ({ graphQLErrors, networkError, operation, forward, location, ...other }) => { console.log("On error"); console.log(graphQLErrors, networkError, other); // TODO --- On error message invalid token clear local storage if (graphQLErrors && graphQLErrors.filter((e) => e).length > 0) { console.log("Errors: ", graphQLErrors); graphQLErrors.map(({ message, status }) => { console.log("Message: ", message); console.log("Status: ", status); console.log("Location: ", location); if (message.includes("You do not have permission")) { const token = getToken(); const refreshToken = getRefreshToken(); console.log("Token, refresh", token, refreshToken); if (token && refreshToken) { console.log("In if condition"); // error code is set to UNAUTHENTICATED // when AuthenticationError thrown in resolver let forward$; if (!isRefreshing) { isRefreshing = true; forward$ = fromPromise( getNewToken(client) .then(({ data: { refreshToken } }) => { console.log("Promise data: ", refreshToken); // localStorage.setItem("token", refreshToken.token); // localStorage.setItem( // "refreshToken", // refreshToken.refreshToken // ); resolvePendingRequests(); return refreshToken.token; }) .catch((error) => { // Handle token refresh errors e.g clear stored tokens, redirect to login, ... console.log("Error after setting token: ", error); pendingRequests = []; return; }) .finally(() => { console.log("Finally"); isRefreshing = false; }) ).filter((value) => { console.log("In Filter: ", value); return Boolean(value); }); } else { // Will only emit once the Promise is resolved forward$ = fromPromise( new Promise((resolve) => { pendingRequests.push(() => resolve()); }) ); } return forward$.flatMap(() => { console.log("Forwarding!"); return forward(operation); }); } // else { // // If there's no token, then sign out user // console.log("There's no token, sign out the user", signOut); // signOut(); // } } }); } if (networkError) { console.log("Network error: ", networkError); } } ); const links = [errorLink, authLink, httpLink]; const link = ApolloLink.from(links); export const client = new ApolloClient({ link, cache: new InMemoryCache(), fetchOptions: { mode: "no-cors", }, }); ReactDOM.render( <ApolloProvider client={client}> <App /> </ApolloProvider>, document.getElementById("root") ); // If you want your app to work offline and load faster, you can change // unregister() to register() below. Note this comes with some pitfalls. // Learn more about service workers: https://bit.ly/CRA-PWA serviceWorker.unregister();