Skip to content

Instantly share code, notes, and snippets.

@realStandal
Last active May 4, 2021 22:26
Show Gist options
  • Save realStandal/ba9645489d4acee6286b4f5c14b1abd0 to your computer and use it in GitHub Desktop.
Save realStandal/ba9645489d4acee6286b4f5c14b1abd0 to your computer and use it in GitHub Desktop.
Updated `RedwoodApolloProvider` providing full custom-`useAuth` pass through.
import {
ApolloProvider,
ApolloClientOptions,
ApolloClient,
ApolloLink,
InMemoryCache,
useQuery,
useMutation,
createHttpLink,
} from '@apollo/client'
import { setContext } from '@apollo/client/link/context'
import { AuthContextInterface, useAuth as useRwAuth } from '@redwoodjs/auth'
import {
FetchConfigProvider,
useFetchConfig,
} from 'src/components/FetchConfigProvider'
import { GraphQLHooksProvider } from 'src/components/GraphQLHooksProvider'
export type GraphQLClientConfig = Omit<ApolloClientOptions<InMemoryCache>, 'cache'>
export type CustomUseAuthHook = () => AuthContextInterface
const ApolloProviderWithFetchConfig: React.FunctionComponent<{
config?: GraphQLClientConfig,
useAuth?: CustomUseAuthHook
}> = ({ config = {}, children, useAuth = useRwAuth }) => {
const { uri, headers } = useFetchConfig()
const { getToken, type: authProviderType, isAuthenticated } = useAuth()
const withToken = setContext(async () => {
if (isAuthenticated && getToken) {
const token = await getToken()
return { token }
}
return { token: null }
})
const authMiddleware = new ApolloLink((operation, forward) => {
const { token } = operation.getContext()
// Only add auth headers when token is present
// Token is null, when !isAuthenticated
const authHeaders = token
? {
'auth-provider': authProviderType,
authorization: `Bearer ${token}`,
}
: {}
operation.setContext(() => ({
headers: {
...headers,
// Duped auth headers, because we may remove FetchContext at a later date
...authHeaders,
},
}))
return forward(operation)
})
const httpLink = createHttpLink({ uri })
const client = new ApolloClient({
cache: new InMemoryCache(),
...config,
link: ApolloLink.from([withToken, authMiddleware.concat(httpLink)]),
})
return <ApolloProvider client={client}>{children}</ApolloProvider>
}
export const RedwoodApolloProvider: React.FunctionComponent<{
graphQLClientConfig?: GraphQLClientConfig
useAuth?: CustomUseAuthHook
}> = ({ graphQLClientConfig, useAuth, children }) => {
return (
<FetchConfigProvider useAuth={useAuth}>
<ApolloProviderWithFetchConfig config={graphQLClientConfig}>
<GraphQLHooksProvider useQuery={useQuery} useMutation={useMutation}>
{children}
</GraphQLHooksProvider>
</ApolloProviderWithFetchConfig>
</FetchConfigProvider>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment