All files / src/authentication AuthSessionProvider.jsx

100% Statements 11/11
100% Branches 0/0
100% Functions 5/5
100% Lines 11/11

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45                        2x       1x     23x     21x           21x 12x 10x         10x     21x 10x     21x    
/**
 * AuthSessionProvider — ADR-001 Phase 2 (BFF httpOnly-cookie auth).
 *
 * Probes `GET /v1/auth/me` once on mount to learn whether the httpOnly
 * access-token cookie is valid, and exposes the result to route guards and
 * role-gated UI. `refresh()` re-probes (called right after login).
 *
 * Developer: Allan Ninal
 */
import { createContext, useCallback, useContext, useEffect, useState } from "react";
import { fetchSession, getStoredRole } from "@/authentication/session";
 
const AuthSessionContext = createContext({
    loading: true,
    isAuthenticated: false,
    role: null,
    refresh: async () => ({ isAuthenticated: false, role: null }),
});
 
export const useAuthSession = () => useContext(AuthSessionContext);
 
export default function AuthSessionProvider({ children }) {
    const [state, setState] = useState({
        loading: true,
        isAuthenticated: false,
        role: getStoredRole(),
    });
 
    const refresh = useCallback(async () => {
        const session = await fetchSession();
        setState({
            loading: false,
            isAuthenticated: session.isAuthenticated,
            role: session.role,
        });
        return session;
    }, []);
 
    useEffect(() => {
        refresh();
    }, [refresh]);
 
    return <AuthSessionContext.Provider value={{ ...state, refresh }}>{children}</AuthSessionContext.Provider>;
}