// Garde la session Authentik VIVANTE pour éviter la coupure « il faut recharger pour que les données/recherche reviennent ». // Cause : la SPA + /api + /hub sont derrière Authentik ; la session (cookie) expire après une durée d'inactivité. // Les appels /api (authFetch) se rechargent seuls (_reauth), MAIS les appels /hub (fetch nu) échouent en silence → données absentes. // Solution : un battement régulier qui (a) RAFRAÎCHIT la session (fenêtre glissante) et (b) recharge proprement si elle est morte. import { authFetch } from 'src/api/auth' import { BASE_URL } from 'src/config/erpnext' let _timer = null let _started = false // Ping léger à travers la porte Authentik. authFetch gère _reauth (recharge 1×/20 s si 401/redirection IdP/HTML). async function ping () { try { await authFetch(BASE_URL + '/auth/whoami') } catch (e) { /* réseau transitoire → on réessaie au prochain tick */ } } // Démarre le battement (prod uniquement — pas d'Authentik en dev local). Idempotent. export function startSessionKeepAlive ({ minutes = 4 } = {}) { if (_started) return const host = window.location.hostname if (host === 'localhost' || host === '127.0.0.1') return // dev : pas de front Authentik → inutile + éviterait les reloads _started = true _timer = setInterval(ping, Math.max(1, minutes) * 60 * 1000) // < timeout Authentik → la session ne meurt jamais tant que l'onglet est ouvert // Retour sur l'onglet après une pause → vérifie/rafraîchit TOUT DE SUITE (le cas le plus courant de « c'est figé »). document.addEventListener('visibilitychange', () => { if (document.visibilityState === 'visible') ping() }) ping() // amorçage immédiat } export function stopSessionKeepAlive () { if (_timer) { clearInterval(_timer); _timer = null } _started = false }