78 lines
2.3 KiB
TypeScript
78 lines
2.3 KiB
TypeScript
import { attemptRefreshingSession } from 'supertokens-web-js/recipe/session';
|
|
import { logger } from './index';
|
|
|
|
class SessionRefreshManager {
|
|
private refreshPromise: Promise<boolean> | null = null;
|
|
private redirectPromise: Promise<void> | null = null;
|
|
private lastRefreshTime: number = 0;
|
|
private readonly MIN_REFRESH_INTERVAL = 1000;
|
|
|
|
async refresh(): Promise<boolean> {
|
|
if (this.refreshPromise) {
|
|
logger.info('RefreshManager: Reusing existing refresh promise');
|
|
return this.refreshPromise;
|
|
}
|
|
|
|
const timeSinceLastRefresh = Date.now() - this.lastRefreshTime;
|
|
if (timeSinceLastRefresh < this.MIN_REFRESH_INTERVAL) {
|
|
logger.info(`RefreshManager: Skipping refresh (last refresh ${timeSinceLastRefresh}ms ago)`);
|
|
return true;
|
|
}
|
|
|
|
logger.info('RefreshManager: Starting new session refresh');
|
|
this.refreshPromise = attemptRefreshingSession()
|
|
.then((result) => {
|
|
logger.info('RefreshManager: Refresh completed successfully:', result);
|
|
this.lastRefreshTime = Date.now();
|
|
return result;
|
|
})
|
|
.catch((error) => {
|
|
logger.error('RefreshManager: Refresh failed:', error);
|
|
throw error;
|
|
})
|
|
.finally(() => {
|
|
setTimeout(() => {
|
|
this.refreshPromise = null;
|
|
}, 500);
|
|
});
|
|
|
|
return this.refreshPromise;
|
|
}
|
|
|
|
async redirectToRefresh(currentPath: string): Promise<void> {
|
|
if (this.redirectPromise) {
|
|
logger.info('RefreshManager: Redirect already in progress, waiting...');
|
|
return this.redirectPromise;
|
|
}
|
|
|
|
logger.info('RefreshManager: Initiating refresh redirect to:', currentPath);
|
|
this.redirectPromise = new Promise<void>((resolve) => {
|
|
setTimeout(() => {
|
|
window.location.href = `/refresh-session?redirect=${encodeURIComponent(currentPath)}`;
|
|
resolve();
|
|
}, 100);
|
|
});
|
|
|
|
this.redirectPromise.finally(() => {
|
|
setTimeout(() => {
|
|
this.redirectPromise = null;
|
|
}, 1000);
|
|
});
|
|
|
|
return this.redirectPromise;
|
|
}
|
|
|
|
reset(): void {
|
|
logger.info('RefreshManager: Resetting state');
|
|
this.refreshPromise = null;
|
|
this.redirectPromise = null;
|
|
this.lastRefreshTime = 0;
|
|
}
|
|
|
|
getTimeSinceLastRefresh(): number {
|
|
return Date.now() - this.lastRefreshTime;
|
|
}
|
|
}
|
|
|
|
export const refreshManager = new SessionRefreshManager();
|