/** * @fileoverview Authentication mocking utilities for Laravel Healthcare MCP Server tests * Provides comprehensive mocking for authentication tokens and Sanctum authentication */ import { jest } from "@jest/globals"; /** * Authentication Mock Manager for handling authentication-related mocks */ export class AuthMockManager { constructor() { this.tokens = new Map(); this.credentials = new Map(); this.authHistory = []; this.authenticationCleared = false; } /** * Create a mock AuthManager instance * @returns {Object} Mock AuthManager instance */ createMockAuthManager() { const mockAuthManager = { authenticate: jest.fn(), getToken: jest.fn(), validateToken: jest.fn(), refreshToken: jest.fn(), logout: jest.fn(), validateAllCredentials: jest.fn(), getCacheStats: jest.fn(), credentials: {}, tokenCache: new Map(), }; // Setup method implementations mockAuthManager.authenticate.mockImplementation( async (authType, credentials) => { this.authHistory.push({ action: "authenticate", authType, credentials: { ...credentials, password: "[REDACTED]" }, timestamp: new Date().toISOString(), }); if (this.shouldAuthenticationSucceed(authType, credentials)) { const token = this.generateMockToken(authType); this.tokens.set(authType, token); return { success: true, token }; } else { throw new Error(`Authentication failed for ${authType}`); } } ); mockAuthManager.getToken.mockImplementation((authType) => { return this.tokens.get(authType) || null; }); mockAuthManager.validateToken.mockImplementation( async (token, authType) => { const storedToken = this.tokens.get(authType); return storedToken === token; } ); mockAuthManager.refreshToken.mockImplementation(async (authType) => { if (this.tokens.has(authType)) { const newToken = this.generateMockToken(authType); this.tokens.set(authType, newToken); return { success: true, token: newToken }; } throw new Error(`No token found for ${authType}`); }); mockAuthManager.logout.mockImplementation(async (authType) => { this.tokens.delete(authType); this.authHistory.push({ action: "logout", authType, timestamp: new Date().toISOString(), }); return { success: true }; }); mockAuthManager.validateAllCredentials.mockImplementation(async () => { const results = {}; for (const authType of Object.values(global.testConstants.AUTH_TYPES)) { if (authType === "public") continue; results[authType] = { valid: this.hasValidCredentials(authType), error: this.hasValidCredentials(authType) ? null : `Invalid credentials for ${authType}`, }; } return results; }); mockAuthManager.getCacheStats.mockImplementation(() => ({ size: this.tokens.size, keys: Array.from(this.tokens.keys()), lastAccess: new Date().toISOString(), })); return mockAuthManager; } /** * Generate a mock authentication token * @param {string} authType - Authentication type * @returns {string} Mock token */ generateMockToken(authType) { const timestamp = Date.now(); const random = Math.random().toString(36).substring(2); return `${authType}_token_${timestamp}_${random}`; } /** * Set mock credentials for an authentication type * @param {string} authType - Authentication type * @param {Object} credentials - Mock credentials */ setMockCredentials(authType, credentials) { this.credentials.set(authType, credentials); this.authenticationCleared = false; // Authentication is now available } /** * Check if authentication should succeed * @param {string} authType - Authentication type * @param {Object} credentials - Provided credentials * @returns {boolean} Whether authentication should succeed */ shouldAuthenticationSucceed(authType, credentials) { const mockCredentials = this.credentials.get(authType); if (!mockCredentials) { // Default success for test credentials return ( credentials.username === `test_${authType}` && credentials.password === "test_password" ); } return ( credentials.username === mockCredentials.username && credentials.password === mockCredentials.password ); } /** * Check if valid credentials exist for auth type * @param {string} authType - Authentication type * @returns {boolean} Whether valid credentials exist */ hasValidCredentials(authType) { return ( this.credentials.has(authType) || process.env[`${authType.toUpperCase()}_USERNAME`] ); } /** * Setup default mock credentials for all auth types */ setupDefaultCredentials() { const authTypes = [ "provider", "patient", "partner", "affiliate", "network", ]; authTypes.forEach((authType) => { this.setMockCredentials(authType, { username: `test_${authType}`, password: "test_password", email: `test@${authType}.example.com`, }); }); } /** * Mock Sanctum token authentication * @param {string} token - Bearer token * @returns {Object} Mock user data */ mockSanctumAuth(token) { if (!token || !token.startsWith("Bearer ")) { throw new Error("Invalid token format"); } const actualToken = token.replace("Bearer ", ""); // Find auth type from token let authType = "provider"; for (const [type, storedToken] of this.tokens.entries()) { if (storedToken === actualToken) { authType = type; break; } } return { id: `mock_${authType}_user_123`, email: `test@${authType}.example.com`, role: authType, permissions: this.getMockPermissions(authType), tokenType: "Bearer", expiresAt: new Date(Date.now() + 3600000).toISOString(), // 1 hour from now }; } /** * Get mock permissions for auth type * @param {string} authType - Authentication type * @returns {Array} Array of permissions */ getMockPermissions(authType) { const permissions = { provider: [ "read:patients", "write:patients", "read:prescriptions", "write:prescriptions", ], patient: ["read:own_data", "write:own_data"], partner: ["read:business_data", "write:business_data"], affiliate: ["read:affiliate_data", "write:affiliate_data"], network: ["read:network_data", "write:network_data"], }; return permissions[authType] || []; } /** * Create mock HIPAA-compliant authentication context * @param {string} authType - Authentication type * @returns {Object} HIPAA-compliant auth context */ createHIPAAAuthContext(authType) { return { userId: `mock_${authType}_user_123`, role: authType, permissions: this.getMockPermissions(authType), sessionId: `session_${Date.now()}`, ipAddress: "127.0.0.1", userAgent: "Jest Test Suite", loginTime: new Date().toISOString(), lastActivity: new Date().toISOString(), hipaaCompliant: true, auditTrail: { enabled: true, logLevel: "detailed", }, }; } /** * Get authentication history * @returns {Array} Array of authentication events */ getAuthHistory() { return [...this.authHistory]; } /** * Clear authentication history */ clearHistory() { this.authHistory = []; } /** * Reset all authentication mocks */ reset() { this.tokens.clear(); this.credentials.clear(); this.authHistory = []; this.authenticationCleared = true; } /** * Check if authentication has been cleared */ isAuthenticationCleared() { return this.authenticationCleared; } /** * Simulate token expiration * @param {string} authType - Authentication type */ expireToken(authType) { this.tokens.delete(authType); this.authHistory.push({ action: "token_expired", authType, timestamp: new Date().toISOString(), }); } } // Export singleton instance export const authMockManager = new AuthMockManager();