'use client'; import { useEffect, useRef, useState } from 'react'; import { useSession } from 'next-auth/react'; interface ResponsiveIframeProps { src: string; className?: string; allow?: string; style?: React.CSSProperties; } export function ResponsiveIframe({ src, className = '', allow, style }: ResponsiveIframeProps) { const iframeRef = useRef(null); const { data: session } = useSession(); const [isRefreshing, setIsRefreshing] = useState(false); const [iframeSrc, setIframeSrc] = useState(''); const [hasTriedRefresh, setHasTriedRefresh] = useState(false); // Refresh NextAuth session (which will also refresh Keycloak tokens) before loading iframe useEffect(() => { // If no src, nothing to do if (!src) { return; } // If no session yet, wait for it (don't set src yet) if (!session) { return; } // If already tried refresh for this src, just set it if (hasTriedRefresh) { if (!iframeSrc) { setIframeSrc(src); } return; } // Ensure session has required tokens before proceeding if (!session.accessToken || !session.refreshToken) { console.warn('Session missing required tokens, redirecting to sign-in'); window.location.href = '/signin'; return; } const refreshSession = async () => { setIsRefreshing(true); setHasTriedRefresh(true); try { // Wait a bit to ensure NextAuth session is fully established await new Promise(resolve => setTimeout(resolve, 100)); // Call our API to refresh the Keycloak session // This ensures tokens are fresh and may help refresh Keycloak session cookies const response = await fetch('/api/auth/refresh-keycloak-session', { method: 'GET', credentials: 'include', // Include cookies }); if (response.ok) { console.log('Session refreshed before loading iframe'); setIframeSrc(src); } else { const errorData = await response.json().catch(() => ({})); // If session was invalidated, redirect to sign-in if (response.status === 401 && errorData.error === 'SessionInvalidated') { console.warn('Keycloak session invalidated, redirecting to sign-in'); window.location.href = '/signin'; return; } console.warn('Failed to refresh session, loading iframe anyway (may require login)'); // Still load iframe, but it may prompt for login setIframeSrc(src); } } catch (error) { console.error('Error refreshing session:', error); // On error, still try to load iframe setIframeSrc(src); } finally { setIsRefreshing(false); } }; refreshSession(); }, [session, src, hasTriedRefresh, iframeSrc]); useEffect(() => { const iframe = iframeRef.current; if (!iframe || !iframeSrc) return; const calculateHeight = () => { const pageY = (elem: HTMLElement): number => { return elem.offsetParent ? (elem.offsetTop + pageY(elem.offsetParent as HTMLElement)) : elem.offsetTop; }; const height = document.documentElement.clientHeight; const iframeY = pageY(iframe); const newHeight = Math.max(0, height - iframeY); iframe.style.height = `${newHeight}px`; }; const handleHashChange = () => { if (window.location.hash && window.location.hash.length && iframe.src) { const iframeURL = new URL(iframe.src); iframeURL.hash = window.location.hash; iframe.src = iframeURL.toString(); } }; // Initial setup calculateHeight(); handleHashChange(); // Event listeners window.addEventListener('resize', calculateHeight); window.addEventListener('hashchange', handleHashChange); iframe.addEventListener('load', calculateHeight); // Cleanup return () => { window.removeEventListener('resize', calculateHeight); window.removeEventListener('hashchange', handleHashChange); iframe.removeEventListener('load', calculateHeight); }; }, []); return ( <> {isRefreshing && (

Actualisation de la session...

)}