UNPKG

@pagamio/frontend-commons-lib

Version:

Pagamio library for Frontend reusable components like the form engine and table container

99 lines (98 loc) 3.73 kB
/** * @fileoverview Logout service that handles cleanup operations during user logout */ import { removeLocalStorageItems } from '../../shared'; import { TokenManager } from '../utils'; const defaultLogoutOptions = { clearStorage: true, invalidateSession: true, logoutEndpoint: '/api/auth/logout', storageKeys: ['user', 'rememberMe'], }; export class LogoutService { tokenManager; options; baseUrl; constructor(config) { this.baseUrl = config.baseUrl; this.tokenManager = new TokenManager({ baseUrl: this.baseUrl, refreshEndpoint: '/auth/refresh', // Default refresh endpoint }); this.options = { ...defaultLogoutOptions, logoutEndpoint: config.logoutEndpoint ?? defaultLogoutOptions.logoutEndpoint, storageKeys: config.storageKeys ?? defaultLogoutOptions.storageKeys, }; } async logout(options) { const currentOptions = { ...this.options, ...options }; const { clearStorage, invalidateSession, logoutEndpoint, storageKeys, onLogoutSuccess, onLogoutError, customCleanup, } = currentOptions; try { const cleanupTasks = []; // Clear tokens this.tokenManager.clearAllTokens(); // Clear localStorage if (clearStorage && storageKeys?.length) { removeLocalStorageItems(storageKeys); } // Invalidate server session if (invalidateSession && logoutEndpoint) { const { token } = this.tokenManager.getAccessToken(); if (token) { cleanupTasks.push(this.invalidateServerSession(logoutEndpoint, token)); } } // Run custom cleanup if provided if (customCleanup) { const cleanup = customCleanup(); if (cleanup instanceof Promise) { cleanupTasks.push(cleanup); } } // Clear browser cache cleanupTasks.push(this.clearBrowserCache()); await Promise.all(cleanupTasks); onLogoutSuccess?.(); return true; } catch (error) { const logoutError = error instanceof Error ? error : new Error('Logout failed'); onLogoutError?.(logoutError); throw logoutError; } } async invalidateServerSession(endpoint, token) { const fullEndpoint = endpoint.startsWith('http') ? endpoint : `${this.baseUrl}${endpoint}`; const response = await fetch(fullEndpoint, { method: 'POST', headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', }, }); if (!response.ok) { throw new Error(`Failed to invalidate session: ${response.statusText}`); } } async clearBrowserCache() { if (typeof window === 'undefined') return; // Clear service worker registrations if ('serviceWorker' in navigator) { const registrations = await navigator.serviceWorker.getRegistrations(); await Promise.all(registrations.map((registration) => registration.unregister())); } // Clear browser cache if ('caches' in window) { const keys = await caches.keys(); await Promise.all(keys.map((key) => caches.delete(key))); } } } // Create default instance with baseUrl from window.location.origin const createLogoutService = (config) => { return new LogoutService(config); }; // Export the create function and types export { createLogoutService };