Skip to main content
Glama
auth-manager.js6.1 kB
export class AuthManager { constructor(logger) { this.logger = logger; this.sessions = new Map(); this.clients = new Map(); this.tempTokens = new Map(); // For OAuth flow this.sessionTimeout = parseInt(process.env.SESSION_TIMEOUT) || 86400000; // 24 hours default this.tempTokenTimeout = parseInt(process.env.TEMP_TOKEN_TIMEOUT) || 300000; // 5 minutes default // Clean up expired sessions every hour setInterval(() => this.cleanupExpiredSessions(), 60 * 60 * 1000); // Clean up expired temp tokens every minute setInterval(() => this.cleanupExpiredTempTokens(), 60 * 1000); } async authenticateWithToken(bearerToken, sessionId) { try { // Import here to avoid circular dependency const { RezoomexApiClient } = await import('./rezoomex-client.js'); const client = new RezoomexApiClient(bearerToken, this.logger); // Test authentication const isValid = await client.validateSession(); if (isValid) { this.clients.set(sessionId, client); this.sessions.set(sessionId, { createdAt: Date.now() }); this.logger.info('Client authenticated successfully', { sessionId, userInfo: client.userInfo?.email || 'unknown' }); return client; } else { this.logger.warn('Authentication failed - invalid token', { sessionId }); return null; } } catch (error) { this.logger.error('Authentication error', { sessionId, error: error.message, stack: error.stack }); return null; } } getClient(sessionId) { if (!sessionId) { this.logger.warn('No session ID provided'); return null; } const client = this.clients.get(sessionId); if (!client) { this.logger.warn('Client not found for session', { sessionId }); return null; } // Refresh session timeout this.sessions.set(sessionId, { createdAt: Date.now() }); return client; } clearSession(sessionId) { if (this.clients.has(sessionId)) { this.clients.delete(sessionId); this.logger.info('Session cleared', { sessionId }); } if (this.sessions.has(sessionId)) { this.sessions.delete(sessionId); } } cleanupExpiredSessions() { const now = Date.now(); let cleanedCount = 0; for (const [sessionId, session] of this.sessions.entries()) { if (now - session.createdAt > this.sessionTimeout) { this.sessions.delete(sessionId); this.clients.delete(sessionId); cleanedCount++; } } if (cleanedCount > 0) { this.logger.info(`Cleaned up ${cleanedCount} expired sessions`); } } cleanupExpiredTempTokens() { const now = Date.now(); let cleanedCount = 0; for (const [tokenId, tokenData] of this.tempTokens.entries()) { if (now - tokenData.createdAt > this.tempTokenTimeout) { this.tempTokens.delete(tokenId); cleanedCount++; } } if (cleanedCount > 0) { this.logger.info(`Cleaned up ${cleanedCount} expired temp tokens`); } } // Temporary token management for OAuth flow storeTempToken(tokenId, bearerToken) { this.tempTokens.set(tokenId, { token: bearerToken, createdAt: Date.now() }); this.logger.info('Temporary token stored', { tokenId }); } getTempToken(tokenId) { const tokenData = this.tempTokens.get(tokenId); if (!tokenData) { return null; } // Check if expired if (Date.now() - tokenData.createdAt > this.tempTokenTimeout) { this.tempTokens.delete(tokenId); return null; } return tokenData.token; } removeTempToken(tokenId) { const removed = this.tempTokens.delete(tokenId); if (removed) { this.logger.info('Temporary token removed', { tokenId }); } return removed; } getAllSessions() { return Array.from(this.clients.keys()); } getSessionCount() { return this.sessions.size; } getTempTokenCount() { return this.tempTokens.size; } async validateAllSessions() { const sessions = Array.from(this.clients.entries()); const results = []; for (const [sessionId, client] of sessions) { try { const isValid = await client.validateSession(); if (!isValid) { this.clearSession(sessionId); results.push({ sessionId, valid: false, action: 'cleared' }); } else { results.push({ sessionId, valid: true, action: 'kept' }); } } catch (error) { this.logger.error('Session validation error', { sessionId, error: error.message }); this.clearSession(sessionId); results.push({ sessionId, valid: false, action: 'cleared', error: error.message }); } } return results; } // Cleanup method for graceful shutdown cleanup() { this.logger.info('Cleaning up auth manager', { sessionCount: this.clients.size, tempTokenCount: this.tempTokens.size }); // Clear all sessions and temp tokens this.clients.clear(); this.sessions.clear(); this.tempTokens.clear(); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Pratik-911/Rmx-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server