UNPKG

msexchange-mcp

Version:

MCP server for Microsoft Exchange/Outlook email operations via Microsoft Graph API

93 lines 4.03 kB
import { AuthService } from '../auth/authService.js'; import { AuthService as AuthServiceKeyVault } from '../auth/authService-keyvault.js'; import { loadConfig } from '../config/config.js'; // Singleton AuthService instance let authServiceInstance = null; function getAuthService() { if (!authServiceInstance) { const config = loadConfig(); // Use Key Vault auth service if enabled and configured if (config.keyVault.enabled && config.keyVault.vaultUri) { console.error('🔐 Using AuthService with Azure Key Vault integration'); authServiceInstance = new AuthServiceKeyVault(config); } else { console.error('📁 Using standard AuthService (no Key Vault)'); authServiceInstance = new AuthService(config); // Start proactive token refresh for non-Key Vault version if ('startProactiveRefresh' in authServiceInstance) { authServiceInstance.startProactiveRefresh(); } } console.error('🔧 Created new AuthService instance'); } return authServiceInstance; } // Helper function to check if an error is token-related function isTokenError(error) { return (error?.status === 401 || error?.code === 'InvalidAuthenticationToken' || error?.code === 'Unauthenticated' || error?.message?.includes('authentication') || error?.message?.includes('token') || error?.message?.includes('unauthorized')); } // Enhanced Graph client with automatic token refresh retry export async function getGraphClientWithRetry(userEmail) { const maxAttempts = 2; let lastError; for (let attempt = 1; attempt <= maxAttempts; attempt++) { try { const auth = getAuthService(); console.error(`🔑 Getting token for ${userEmail} (attempt ${attempt}/${maxAttempts})`); // Force token refresh on retry attempts const token = attempt > 1 ? await auth.forceTokenRefresh(userEmail) : await auth.getTokenForUser(userEmail); console.error(`✅ Token acquired successfully`); return auth.getGraphClient(token); } catch (error) { lastError = error; console.error(`❌ Token acquisition failed on attempt ${attempt}:`, error.message); // Only retry if it's a token-related error and we have attempts left if (isTokenError(error) && attempt < maxAttempts) { console.error(`🔄 Token error detected, retrying with fresh token...`); continue; } // If not a token error or no attempts left, throw immediately throw error; } } throw lastError; } // Original function maintained for backward compatibility export async function getGraphClient(userEmail) { return getGraphClientWithRetry(userEmail); } // Function to execute Graph API operations with automatic retry on token errors export async function executeWithTokenRetry(userEmail, operation) { const maxAttempts = 2; let lastError; for (let attempt = 1; attempt <= maxAttempts; attempt++) { try { const client = await getGraphClientWithRetry(userEmail); return await operation(client); } catch (error) { lastError = error; console.error(`❌ Graph operation failed on attempt ${attempt}:`, error.message); // Only retry if it's a token-related error and we have attempts left if (isTokenError(error) && attempt < maxAttempts) { console.error(`🔄 Token error detected during operation, retrying...`); // Clear any cached tokens to force refresh const auth = getAuthService(); await auth.clearTokenCache(userEmail); continue; } throw error; } } throw lastError; } //# sourceMappingURL=graphClient.js.map