import React, { createContext, useContext, useEffect } from "react" import { getInMemoryAuthToken, getRefreshToken, isLoggedOut, isTokenExpired, LOGGED_OUT_KEY, logout, setAuthToken, } from "../services/auth" import { gql, useMutation } from "@apollo/client" import useNetwork from "./useNetwork" import { navigate } from "gatsby" import uuid from "uuid" const AuthContext = createContext(null) export const AuthProvider = ({ children }) => ( <AuthContext.Provider value={useProvideAuth()}> {children} </AuthContext.Provider> ) export const useAuth = () => useContext(AuthContext) const syncLoginStatus = (event) => { if (event.key === LOGGED_OUT_KEY && isLoggedOut()) { logout(navigate("/dashboard/")) } } const REFRESH_TOKEN = gql` mutation LoginUser($input: RefreshJwtAuthTokenInput!) { refreshJwtAuthToken(input: $input) { authToken } } ` const useProvideAuth = () => { const [refreshToken, { data }] = useMutation(REFRESH_TOKEN) const isOnline = useNetwork() // const isAuthTokenExpired = () => // getInMemoryAuthToken().authToken && isTokenExpired(getInMemoryAuthToken().authToken) const isLoggedIn = () => getInMemoryAuthToken() && !isTokenExpired(getInMemoryAuthToken()) useEffect(() => { // TODO: This should only happen in one place. Either we implement an // interval here, or we use the apollo-link-token-refresh in client.js if (isOnline && getRefreshToken()) { refreshToken({ variables: { input: { clientMutationId: uuid(), jwtRefreshToken: getRefreshToken(), }, }, }).then((response) => { console.log("silentRefresh", response) const token = response.data.refreshJwtAuthToken ? response.data.refreshJwtAuthToken.authToken : null if (token) { setAuthToken(response.data.refreshJwtAuthToken.authToken) } }) } }, [refreshToken]) /** * Make sure, User is logged out on all Tabs */ useEffect(() => { window.addEventListener("storage", syncLoginStatus) return () => { window.removeEventListener("storage", syncLoginStatus) } }) // TODO: this still needs to be implemented properly // useEffect(() => { // console.log("useEffect called") // if (isAuthTokenExpired() && isOnline) { // console.log("Triggered Token Refresh") // /** // * Execute an arbitrary query to trigger auth token refresh, // * then sync local storage with auth context. // */ // client // .query({ // query: gql` // { // generalSettings { // title // } // } // `, // }) // } // }) return { isLoggedIn, // user: token ? token.user : null, } }