This commit is contained in:
alma 2026-01-10 12:47:44 +01:00
parent ab1bc1faae
commit 8cfe4069eb

View File

@ -42,7 +42,7 @@ export function ResponsiveIframe({
style, style,
}: ResponsiveIframeProps) { }: ResponsiveIframeProps) {
const iframeRef = useRef<HTMLIFrameElement>(null); const iframeRef = useRef<HTMLIFrameElement>(null);
const { data: session } = useSession(); const { data: session, status: sessionStatus } = useSession();
const [isRefreshing, setIsRefreshing] = useState(false); const [isRefreshing, setIsRefreshing] = useState(false);
const [iframeSrc, setIframeSrc] = useState<string>(''); const [iframeSrc, setIframeSrc] = useState<string>('');
const [hasTriedRefresh, setHasTriedRefresh] = useState(false); const [hasTriedRefresh, setHasTriedRefresh] = useState(false);
@ -50,10 +50,32 @@ export function ResponsiveIframe({
// Detect service name from URL for postMessage auth // Detect service name from URL for postMessage auth
const serviceName = detectServiceFromUrl(src); const serviceName = detectServiceFromUrl(src);
// Debug logging on mount and state changes
useEffect(() => {
console.log('[ResponsiveIframe] State:', {
src: src || '(empty)',
iframeSrc: iframeSrc || '(empty)',
sessionStatus,
hasSession: !!session,
hasAccessToken: !!session?.accessToken,
hasRefreshToken: !!session?.refreshToken,
hasTriedRefresh,
isRefreshing,
serviceName: serviceName || '(unknown)',
});
}, [src, iframeSrc, session, sessionStatus, hasTriedRefresh, isRefreshing, serviceName]);
// Refresh NextAuth session before loading iframe // Refresh NextAuth session before loading iframe
useEffect(() => { useEffect(() => {
console.log('[ResponsiveIframe] Effect triggered:', {
src: src || '(empty)',
sessionStatus,
hasTriedRefresh,
});
// If no src, nothing to do // If no src, nothing to do
if (!src) { if (!src) {
console.warn('[ResponsiveIframe] No src provided, cannot load iframe');
return; return;
} }
@ -62,19 +84,27 @@ export function ResponsiveIframe({
const logoutCookie = document.cookie.split(';').some(c => c.trim().startsWith('logout_in_progress=true')); const logoutCookie = document.cookie.split(';').some(c => c.trim().startsWith('logout_in_progress=true'));
if (justLoggedOut || logoutCookie) { if (justLoggedOut || logoutCookie) {
console.warn('Logout in progress, redirecting to sign-in instead of refreshing session'); console.warn('[ResponsiveIframe] Logout in progress, redirecting to sign-in');
window.location.href = '/signin'; window.location.href = '/signin';
return; return;
} }
// If session is loading, wait
if (sessionStatus === 'loading') {
console.log('[ResponsiveIframe] Session still loading, waiting...');
return;
}
// If no session yet, wait for it (don't set src yet) // If no session yet, wait for it (don't set src yet)
if (!session) { if (!session) {
console.log('[ResponsiveIframe] No session yet, waiting...');
return; return;
} }
// If already tried refresh for this src, just set it // If already tried refresh for this src, just set it
if (hasTriedRefresh) { if (hasTriedRefresh) {
if (!iframeSrc) { if (!iframeSrc) {
console.log('[ResponsiveIframe] Already tried refresh, setting src directly:', src);
setIframeSrc(src); setIframeSrc(src);
} }
return; return;
@ -82,12 +112,17 @@ export function ResponsiveIframe({
// Ensure session has required tokens before proceeding // Ensure session has required tokens before proceeding
if (!session.accessToken || !session.refreshToken) { if (!session.accessToken || !session.refreshToken) {
console.warn('Session missing required tokens, redirecting to sign-in'); console.warn('[ResponsiveIframe] Session missing tokens:', {
hasAccessToken: !!session.accessToken,
hasRefreshToken: !!session.refreshToken,
});
console.warn('[ResponsiveIframe] Redirecting to sign-in');
window.location.href = '/signin'; window.location.href = '/signin';
return; return;
} }
const refreshSession = async () => { const refreshSession = async () => {
console.log('[ResponsiveIframe] Starting session refresh...');
setIsRefreshing(true); setIsRefreshing(true);
setHasTriedRefresh(true); setHasTriedRefresh(true);
@ -98,45 +133,53 @@ export function ResponsiveIframe({
// Double-check logout flag before making the request // Double-check logout flag before making the request
const stillLoggedOut = sessionStorage.getItem('just_logged_out') === 'true'; const stillLoggedOut = sessionStorage.getItem('just_logged_out') === 'true';
if (stillLoggedOut) { if (stillLoggedOut) {
console.warn('Logout detected during refresh, aborting'); console.warn('[ResponsiveIframe] Logout detected during refresh, aborting');
window.location.href = '/signin'; window.location.href = '/signin';
return; return;
} }
// Call our API to refresh the Keycloak session // Call our API to refresh the Keycloak session
// This ensures tokens are fresh and may help refresh Keycloak session cookies console.log('[ResponsiveIframe] Calling refresh-keycloak-session API...');
const response = await fetch('/api/auth/refresh-keycloak-session', { const response = await fetch('/api/auth/refresh-keycloak-session', {
method: 'GET', method: 'GET',
credentials: 'include', // Include cookies credentials: 'include',
});
console.log('[ResponsiveIframe] Refresh API response:', {
ok: response.ok,
status: response.status,
}); });
if (response.ok) { if (response.ok) {
console.log('Session refreshed before loading iframe'); console.log('[ResponsiveIframe] Session refreshed, setting iframe src:', src);
setIframeSrc(src); setIframeSrc(src);
} else { } else {
const errorData = await response.json().catch(() => ({})); const errorData = await response.json().catch(() => ({}));
console.warn('[ResponsiveIframe] Refresh failed:', errorData);
// If session was invalidated, redirect to sign-in // If session was invalidated, redirect to sign-in
if (response.status === 401 && errorData.error === 'SessionInvalidated') { if (response.status === 401 && errorData.error === 'SessionInvalidated') {
console.warn('Keycloak session invalidated, redirecting to sign-in'); console.warn('[ResponsiveIframe] Session invalidated, redirecting to sign-in');
window.location.href = '/signin'; window.location.href = '/signin';
return; return;
} }
console.warn('Failed to refresh session, loading iframe anyway (may require login)'); console.warn('[ResponsiveIframe] Loading iframe anyway (may require login)');
setIframeSrc(src); setIframeSrc(src);
} }
} catch (error) { } catch (error) {
console.error('Error refreshing session:', error); console.error('[ResponsiveIframe] Error during refresh:', error);
// On error, still try to load iframe with original URL // On error, still try to load iframe with original URL
console.log('[ResponsiveIframe] Setting src despite error:', src);
setIframeSrc(src); setIframeSrc(src);
} finally { } finally {
setIsRefreshing(false); setIsRefreshing(false);
console.log('[ResponsiveIframe] Refresh complete, isRefreshing:', false);
} }
}; };
refreshSession(); refreshSession();
}, [session, src, hasTriedRefresh, iframeSrc]); }, [session, sessionStatus, src, hasTriedRefresh, iframeSrc]);
// Listen for messages from iframe applications (logout, auth requests) // Listen for messages from iframe applications (logout, auth requests)
useEffect(() => { useEffect(() => {
@ -291,13 +334,15 @@ export function ResponsiveIframe({
</div> </div>
)} )}
{/* Only render iframe when we have a src to avoid browser warning */}
{iframeSrc && (
<iframe <iframe
ref={iframeRef} ref={iframeRef}
id="myFrame" id="myFrame"
src={iframeSrc || ''} src={iframeSrc}
className={`w-full border-none ${className}`} className={`w-full border-none ${className}`}
style={{ style={{
display: iframeSrc ? 'block' : 'none', display: 'block',
width: '100%', width: '100%',
height: '100%', height: '100%',
...style ...style
@ -306,6 +351,7 @@ export function ResponsiveIframe({
allowFullScreen allowFullScreen
onLoad={handleIframeLoad} onLoad={handleIframeLoad}
/> />
)}
{/* Show placeholder while waiting for session */} {/* Show placeholder while waiting for session */}
{!iframeSrc && !isRefreshing && ( {!iframeSrc && !isRefreshing && (