Created
May 11, 2020 12:01
-
-
Save bzhr/531e1c25a4960fcd06ec06d8b21f143b to your computer and use it in GitHub Desktop.
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 characters
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(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
how did you define "getToken, getRefreshToken, getNewToken"?