import { createContext, useCallback, useContext, useEffect, useState, } from 'react'; import { forgetCredentials } from '#/lib/credential.js'; import { canWrite, currentSession, onSessionEnded, signOut as revoke, } from '#/lib/oauth.js'; /** * @typedef {Object} SessionContextValue * @property {import('#/lib/oauth.js').Session|null} session * @property {(value: import('#/lib/oauth.js').Session|null) => void} setSession * @property {() => Promise} endSession * @property {boolean} writable - whether the granted scope permits a write */ const SessionContext = createContext( /** @type {SessionContextValue} */ (/** @type {unknown} */ ({})), ); export function SessionProvider({ children }) { const [session, setSession] = useState(() => currentSession()); const endSession = useCallback(async () => { await revoke(session); forgetCredentials(); setSession(null); }, [session]); // A refusal from the server, rather than a sign-out the reader asked for. The // credentials go with it: each one was issued against this session. useEffect(() => { onSessionEnded(() => { forgetCredentials(); setSession(null); }); }, []); return ( {children} ); } export function useSession() { return useContext(SessionContext); }