"use client"; import { useEffect, useRef, useState } from "react"; import { useRouter } from "next/navigation"; import { useSwissOIDAuth } from "swissoid-front"; import useTranslation from "@/src/hooks/useTranslation"; /** * SessionMonitor component * * Monitors session expiry and shows a warning modal when session is about to expire. * - Shows modal 5 minutes before expiry * - User can click "Stay logged in" to refresh the session * - If session expires (authenticated: false), redirects to homepage * * SwissOID polls /auth/status every 30 seconds by default. */ export default function SessionMonitor() { const router = useRouter(); const { locale, t } = useTranslation(); const { authenticated, loading, user, refreshSession } = useSwissOIDAuth(); const [showModal, setShowModal] = useState(false); const [timeRemaining, setTimeRemaining] = useState(null); const [isRefreshing, setIsRefreshing] = useState(false); const wasAuthenticatedRef = useRef(false); const hasRedirectedRef = useRef(false); // Monitor session expiry and show warning modal useEffect(() => { if (!authenticated || !user || loading) { setShowModal(false); return; } const checkExpiry = () => { const exp = (user as any)?.exp; if (!exp) return; const expiryTime = exp * 1000; // Convert to milliseconds const now = Date.now(); const remaining = expiryTime - now; setTimeRemaining(remaining); // Show modal if less than 5 minutes remaining const fiveMinutes = 5 * 60 * 1000; if (remaining > 0 && remaining < fiveMinutes && !showModal) { setShowModal(true); } // Hide modal if session was refreshed (more than 5 minutes now) if (remaining >= fiveMinutes && showModal) { setShowModal(false); } }; // Check immediately checkExpiry(); // Check every 10 seconds const interval = setInterval(checkExpiry, 10000); return () => clearInterval(interval); }, [authenticated, user, loading, showModal]); // Handle logout when authenticated becomes false useEffect(() => { // Track if user was authenticated if (authenticated && !loading) { wasAuthenticatedRef.current = true; } // If user was authenticated and now is not (session expired), redirect to homepage if (wasAuthenticatedRef.current && !authenticated && !loading && !hasRedirectedRef.current) { console.log('[SessionMonitor] Session expired, redirecting to homepage'); hasRedirectedRef.current = true; setShowModal(false); // Redirect to homepage router.push(`/${locale}`); } }, [authenticated, loading, router, locale]); const handleRefresh = async () => { setIsRefreshing(true); try { await refreshSession(); setShowModal(false); } catch (error) { console.error('[SessionMonitor] Failed to refresh session:', error); } finally { setIsRefreshing(false); } }; if (!showModal || timeRemaining === null) { return null; } const minutes = Math.ceil(timeRemaining / 60000); return (

{t('Session Expiring')}

{minutes > 1 ? t('Your session will expire in {minutes} minutes.', { minutes }) : t('Your session will expire in less than a minute.')}

); }