64 lines
2.0 KiB
TypeScript
64 lines
2.0 KiB
TypeScript
import { useEffect, useRef } from 'react';
|
|
import { refreshManager } from '@/lib/supertokens/refresh-manager';
|
|
import { logger } from '@/lib/supertokens';
|
|
import { ensureSuperTokensFrontend } from '@/lib/supertokens/client';
|
|
|
|
export function SessionMonitor() {
|
|
const lastRefreshTimeRef = useRef<number>(0);
|
|
const REFRESH_COOLDOWN = 5 * 1000;
|
|
|
|
useEffect(() => {
|
|
if (typeof window === 'undefined') return;
|
|
|
|
const handleVisibilityChange = async () => {
|
|
if (document.visibilityState !== 'visible') return;
|
|
|
|
const publicRoutes = ['/login', '/logout', '/refresh-session'];
|
|
if (publicRoutes.some(route => window.location.pathname === route)) {
|
|
return;
|
|
}
|
|
|
|
const now = Date.now();
|
|
const timeSinceLastRefresh = now - lastRefreshTimeRef.current;
|
|
|
|
if (timeSinceLastRefresh < REFRESH_COOLDOWN) {
|
|
logger.info(`Session monitor: skipping refresh (refreshed ${timeSinceLastRefresh}ms ago)`);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
ensureSuperTokensFrontend();
|
|
|
|
const { doesSessionExist } = await import('supertokens-web-js/recipe/session');
|
|
|
|
const sessionExists = await doesSessionExist();
|
|
if (!sessionExists) {
|
|
logger.info('Session monitor: no session exists, skipping refresh');
|
|
return;
|
|
}
|
|
|
|
logger.info('Session monitor: tab became visible, checking session freshness');
|
|
|
|
const refreshed = await refreshManager.refresh();
|
|
|
|
if (refreshed) {
|
|
lastRefreshTimeRef.current = Date.now();
|
|
logger.info('Session monitor: session refreshed successfully');
|
|
} else {
|
|
logger.warn('Session monitor: refresh returned false');
|
|
}
|
|
} catch (error: any) {
|
|
logger.error('Session monitor: error refreshing session', error?.message);
|
|
}
|
|
};
|
|
|
|
document.addEventListener('visibilitychange', handleVisibilityChange);
|
|
|
|
return () => {
|
|
document.removeEventListener('visibilitychange', handleVisibilityChange);
|
|
};
|
|
}, []);
|
|
|
|
return null;
|
|
}
|