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
JavaScript
;
/**
* @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,
});
}