Skip to content

Instantly share code, notes, and snippets.

@kratam
Last active May 19, 2022 06:05
Show Gist options
  • Save kratam/0cba026ce2d59be2d7a32610ec910161 to your computer and use it in GitHub Desktop.
Save kratam/0cba026ce2d59be2d7a32610ec910161 to your computer and use it in GitHub Desktop.
nhost multitab token fix
/* 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