Last active
May 19, 2022 06:05
-
-
Save kratam/0cba026ce2d59be2d7a32610ec910161 to your computer and use it in GitHub Desktop.
nhost multitab token fix
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
/* eslint-disable no-console */ | |
import Cookies from 'js-cookie' | |
import { NhostClient } from '@nhost/nextjs' | |
import React from 'react' | |
import { ApolloProvider } from '@apollo/client' | |
import { TokenRefreshLink } from 'apollo-link-token-refresh' | |
import jwtDecode from 'jwt-decode' | |
import { createApolloClient } from './providers/nhost-apollo-provider' | |
const nhostClient = new NhostClient({ | |
backendUrl: process.env.NEXT_PUBLIC_BACKEND_ENDPOINT, | |
autoSignIn: true, | |
autoRefreshToken: false, | |
}) | |
const publicNhostClient = new NhostClient({ | |
backendUrl: process.env.NEXT_PUBLIC_BACKEND_ENDPOINT, | |
autoSignIn: false, | |
autoRefreshToken: false, | |
}) | |
nhostClient.auth.onAuthStateChanged((opts) => { | |
console.log('state changed', opts) | |
console.log('token in session', nhostClient.auth.getSession()?.refreshToken) | |
}) | |
if (typeof window !== 'undefined') window.nhost = nhostClient | |
const fetchAccessToken = () => { | |
const refreshToken = Cookies.get('nhostRefreshToken') || undefined | |
return nhostClient.auth | |
.refreshSession(refreshToken) | |
.then((r) => | |
console.log(`invalidated ${refreshToken}, new: ${r.session.refreshToken}`) | |
) | |
} | |
const tokenRefreshLink = new TokenRefreshLink({ | |
accessTokenField: 'accessToken', | |
isTokenValidOrUndefined: () => { | |
try { | |
const token = nhostClient.auth.getAccessToken() | |
const accessTokenDecrypted = jwtDecode(token) | |
return Date.now() < accessTokenDecrypted.exp * 1000 | |
} catch (error) { | |
return false | |
} | |
}, | |
fetchAccessToken, | |
/** | |
* fetchAccessToken is not really a fetch, so we're just mocking handleFetch | |
* and handleResponse. | |
* The business logic will happen inside nhostClient.auth.refreshSession. | |
*/ | |
handleFetch: () => {}, | |
handleResponse: () => (r) => ({ accessToken: 'foo', ...r }), | |
handleError: (err) => { | |
console.error(`tokenrefresh error`, err) | |
}, | |
}) | |
// eslint-disable-next-line react/prop-types | |
const NhostApolloProvider = ({ children, ...options }) => { | |
const client = React.useMemo( | |
() => createApolloClient({ ...options, onError: tokenRefreshLink }), | |
// eslint-disable-next-line react-hooks/exhaustive-deps | |
[options.nhost, options.cache, options.connectToDevTools] | |
) | |
if (client) return <ApolloProvider client={client}>{children}</ApolloProvider> | |
return <div>no Apollo client</div> | |
} | |
export { nhostClient, publicNhostClient, NhostApolloProvider } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment