import { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react"; import { changeExternalPassword, getExternalSession, loginExternal, logoutExternal } from "../api/auth.js"; import { ExternalApiError, setExternalUnauthorizedHandler } from "../api/client.js"; const ExternalAuthContext = createContext(null); export function ExternalAuthProvider({ children }) { const [session, setSession] = useState(null); const [initializing, setInitializing] = useState(true); const [initializationError, setInitializationError] = useState(null); const refresh = useCallback(async () => { setInitializationError(null); try { const nextSession = await getExternalSession(); setSession(nextSession); return nextSession; } catch (error) { setSession(null); if (!(error instanceof ExternalApiError && error.status === 401)) { // Preserve the stable API status/code for the UI translation layer; never surface a backend-language message directly. setInitializationError(error); } return null; } finally { setInitializing(false); } }, []); useEffect(() => { refresh(); }, [refresh]); useEffect(() => { // Any protected request returning 401 invalidates the entire external session; it never mutates the main-admin session. return setExternalUnauthorizedHandler(() => setSession(null)); }, []); const login = useCallback(async (credentials) => { const nextSession = await loginExternal(credentials); setSession(nextSession); return nextSession; }, []); const logout = useCallback(async () => { try { await logoutExternal(); } finally { setSession(null); } }, []); const changePassword = useCallback(async (payload) => { const responseSession = await changeExternalPassword(payload); const nextSession = responseSession?.appCode ? responseSession : await getExternalSession(); setSession({ ...nextSession, passwordChangeRequired: false }); return nextSession; }, []); const value = useMemo( () => ({ changePassword, initializationError, initializing, login, logout, refresh, session }), [changePassword, initializationError, initializing, login, logout, refresh, session] ); return {children}; } export function useExternalAuth() { const context = useContext(ExternalAuthContext); if (!context) { throw new Error("useExternalAuth must be used inside ExternalAuthProvider"); } return context; }