UNPKG

mcp-quiz-server

Version:

🧠 AI-Powered Quiz Management via Model Context Protocol (MCP) - Create, manage, and take quizzes directly from VS Code, Claude, and other AI agents.

168 lines (167 loc) 5.98 kB
"use strict"; /** * @fileoverview Centralized Authentication Configuration * @version 1.0.0 * @since 2025-08-05 * @lastUpdated 2025-08-05 * @module AuthConfig * @description Centralized configuration for JWT authentication across all services. * Ensures consistent JWT secrets, issuers, and audiences between main server and SSE server. * @contributors GitHub Copilot * @dependencies Environment variables, AuthConfiguration interface * @requirements REQ-AUTH-001 (JWT Authentication), SECURITY_003 (SSE Transport Authentication) * @testCoverage Configuration validation, environment variable handling */ Object.defineProperty(exports, "__esModule", { value: true }); exports.getAuthConfig = getAuthConfig; exports.getSSEAuthConfig = getSSEAuthConfig; exports.getDevAuthConfig = getDevAuthConfig; exports.logAuthConfig = logAuthConfig; /** * Centralized Authentication Configuration * * @description Provides consistent JWT authentication configuration across all services. * Prevents JWT signature validation failures by ensuring all services * use the same secrets, issuers, and audiences. * * @example * ```typescript * import { getAuthConfig } from './config/auth-config'; * * const authService = new JWTAuthService(getAuthConfig()); * ``` * * @since 2025-08-05 * @author GitHub Copilot * @requirements Consistent JWT configuration across main server and SSE server */ /** * Default JWT secret for development environments * @private */ const DEFAULT_JWT_SECRET = 'dev-secret-change-in-production-4a8f9b2e1c7d3e6f8a1b4c7e2d5f8b3a6c9e1f4a7b2e5d8c1f4a7b2e5d8c1f4a7b'; /** * Get centralized authentication configuration * * @description Returns consistent authentication configuration for all services. * Uses environment variables with sensible fallbacks. * * @returns {AuthConfiguration} Authentication configuration object * * @since 2025-08-05 * @author GitHub Copilot */ function getAuthConfig() { const config = { jwtSecret: process.env.JWT_SECRET || DEFAULT_JWT_SECRET, jwtIssuer: process.env.JWT_ISSUER || 'mcp-quiz-server-dev', jwtAudience: process.env.JWT_AUDIENCE || 'mcp-clients-dev', accessTokenExpiryMinutes: parseInt(process.env.ACCESS_TOKEN_EXPIRY_MINUTES || '15'), refreshTokenExpiryDays: parseInt(process.env.REFRESH_TOKEN_EXPIRY_DAYS || '7'), sessionTimeoutMinutes: parseInt(process.env.SESSION_TIMEOUT_MINUTES || '120'), maxSessionsPerUser: parseInt(process.env.MAX_SESSIONS_PER_USER || '3'), enableRefreshTokenRotation: process.env.ENABLE_REFRESH_TOKEN_ROTATION === 'true', }; // Validate configuration validateAuthConfig(config); return config; } /** * Validate authentication configuration * * @description Ensures configuration values are valid and secure. * * @param {AuthConfiguration} config - Configuration to validate * @throws {Error} If configuration is invalid * * @since 2025-08-05 * @author GitHub Copilot */ function validateAuthConfig(config) { if (!config.jwtSecret) { throw new Error('JWT secret is required'); } if (config.jwtSecret.length < 32) { console.warn('⚠️ JWT secret is shorter than recommended 32 characters'); } if (!config.jwtIssuer) { throw new Error('JWT issuer is required'); } if (!config.jwtAudience) { throw new Error('JWT audience is required'); } if (config.accessTokenExpiryMinutes <= 0) { throw new Error('Access token expiry must be positive'); } if (config.refreshTokenExpiryDays <= 0) { throw new Error('Refresh token expiry must be positive'); } if (config.sessionTimeoutMinutes <= 0) { throw new Error('Session timeout must be positive'); } if (config.maxSessionsPerUser <= 0) { throw new Error('Max sessions per user must be positive'); } } /** * Get auth configuration for SSE server * * @description Returns auth configuration optimized for SSE server usage. * Uses longer token expiry for persistent connections. * * @returns {AuthConfiguration} SSE-optimized authentication configuration * * @since 2025-08-05 * @author GitHub Copilot */ function getSSEAuthConfig() { const baseConfig = getAuthConfig(); return { ...baseConfig, // Longer token expiry for SSE connections to reduce re-authentication accessTokenExpiryMinutes: parseInt(process.env.SSE_TOKEN_EXPIRY_MINUTES || '60'), }; } /** * Get auth configuration for development/testing * * @description Returns auth configuration optimized for development environments. * Uses shorter expiry times for faster testing cycles. * * @returns {AuthConfiguration} Development-optimized authentication configuration * * @since 2025-08-05 * @author GitHub Copilot */ function getDevAuthConfig() { const baseConfig = getAuthConfig(); return { ...baseConfig, // Shorter expiry for development testing accessTokenExpiryMinutes: 5, refreshTokenExpiryDays: 1, sessionTimeoutMinutes: 30, }; } /** * Log current authentication configuration * * @description Logs current auth configuration for debugging (without sensitive data). * * @since 2025-08-05 * @author GitHub Copilot */ function logAuthConfig() { const config = getAuthConfig(); console.log('🔐 Authentication Configuration:', { issuer: config.jwtIssuer, audience: config.jwtAudience, accessTokenExpiry: `${config.accessTokenExpiryMinutes}min`, refreshTokenExpiry: `${config.refreshTokenExpiryDays}d`, sessionTimeout: `${config.sessionTimeoutMinutes}min`, maxSessions: config.maxSessionsPerUser, refreshTokenRotation: config.enableRefreshTokenRotation, secretLength: config.jwtSecret.length, usingDefaultSecret: config.jwtSecret === DEFAULT_JWT_SECRET, }); }