aethercall
Version:
A scalable WebRTC video calling API built with Node.js and OpenVidu
214 lines (177 loc) • 6.29 kB
JavaScript
/**
* Centralized Configuration Loader
* Loads configuration from environment variables with defaults
*/
const path = require('path');
// Load environment variables from .env file
require('dotenv').config();
const config = {
// Environment
nodeEnv: process.env.NODE_ENV || 'development',
// Server Configuration
port: parseInt(process.env.PORT) || 3000,
host: process.env.HOST || 'localhost',
// OpenVidu Configuration
openviduUrl: process.env.OPENVIDU_URL || 'http://localhost:4443',
openviduSecret: process.env.OPENVIDU_SECRET || 'MY_SECRET',
// TURN Server Configuration
turnServerUrl: process.env.TURN_SERVER_URL || '',
turnUsername: process.env.TURN_USERNAME || '',
turnPassword: process.env.TURN_PASSWORD || '',
// Database Configuration
dbType: process.env.DB_TYPE || 'memory',
dbConnectionString: process.env.DB_CONNECTION_STRING || '',
// JWT Configuration
jwtSecret: process.env.JWT_SECRET || 'your-super-secret-jwt-key',
jwtExpiresIn: process.env.JWT_EXPIRES_IN || '24h',
// CORS Configuration
corsOrigin: process.env.CORS_ORIGIN || '*',
corsMethods: process.env.CORS_METHODS || 'GET,POST,PUT,DELETE,OPTIONS',
// Rate Limiting
rateLimitWindowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS) || 900000, // 15 minutes
rateLimitMaxRequests: parseInt(process.env.RATE_LIMIT_MAX_REQUESTS) || 100,
// Logging
logLevel: process.env.LOG_LEVEL || 'info',
// File Storage (if using filesystem adapter)
dataPath: process.env.DATA_PATH || path.join(process.cwd(), 'data'),
// Recording Configuration
recordingsPath: process.env.RECORDINGS_PATH || path.join(process.cwd(), 'recordings'),
maxRecordingSize: parseInt(process.env.MAX_RECORDING_SIZE) || 1024 * 1024 * 1024, // 1GB
// Session Configuration
maxSessionDuration: parseInt(process.env.MAX_SESSION_DURATION) || 4 * 60 * 60 * 1000, // 4 hours
maxParticipantsPerSession: parseInt(process.env.MAX_PARTICIPANTS_PER_SESSION) || 50,
// Security Configuration
enableHttps: process.env.ENABLE_HTTPS === 'true',
sslKeyPath: process.env.SSL_KEY_PATH || '',
sslCertPath: process.env.SSL_CERT_PATH || '',
// Analytics
enableAnalytics: process.env.ENABLE_ANALYTICS === 'true',
analyticsRetentionDays: parseInt(process.env.ANALYTICS_RETENTION_DAYS) || 30,
// WebSocket Configuration (for future use)
wsPort: parseInt(process.env.WS_PORT) || 3001,
enableWebSocket: process.env.ENABLE_WEBSOCKET === 'true',
// gRPC Configuration (for future use)
grpcPort: parseInt(process.env.GRPC_PORT) || 50051,
enableGrpc: process.env.ENABLE_GRPC === 'true',
// Health Check Configuration
healthCheckInterval: parseInt(process.env.HEALTH_CHECK_INTERVAL) || 30000, // 30 seconds
// Development Configuration
enableSwagger: process.env.ENABLE_SWAGGER === 'true' || process.env.NODE_ENV === 'development',
enableCors: process.env.ENABLE_CORS !== 'false',
// Performance Configuration
enableCompression: process.env.ENABLE_COMPRESSION !== 'false',
enableCaching: process.env.ENABLE_CACHING === 'true',
cacheMaxAge: parseInt(process.env.CACHE_MAX_AGE) || 300, // 5 minutes
};
/**
* Validate required configuration
*/
function validateConfig() {
const required = {
openviduUrl: 'OPENVIDU_URL',
openviduSecret: 'OPENVIDU_SECRET',
jwtSecret: 'JWT_SECRET'
};
const missing = [];
for (const [key, envVar] of Object.entries(required)) {
if (!config[key] || config[key] === envVar.replace('_', '-').toLowerCase()) {
missing.push(envVar);
}
}
if (missing.length > 0) {
throw new Error(`Missing required environment variables: ${missing.join(', ')}`);
}
}
/**
* Get database configuration object
* @returns {Object} Database configuration
*/
function getDatabaseConfig() {
const dbConfig = {
type: config.dbType
};
switch (config.dbType.toLowerCase()) {
case 'postgres':
case 'postgresql':
dbConfig.connectionString = config.dbConnectionString;
break;
case 'mongodb':
case 'mongo':
dbConfig.connectionString = config.dbConnectionString;
dbConfig.database = process.env.DB_NAME || 'aethercall';
break;
case 'filesystem':
case 'fs':
dbConfig.basePath = config.dataPath;
break;
case 'memory':
default:
// No additional configuration needed
break;
}
return dbConfig;
}
/**
* Get OpenVidu configuration object
* @returns {Object} OpenVidu configuration
*/
function getOpenViduConfig() {
return {
url: config.openviduUrl,
secret: config.openviduSecret
};
}
/**
* Get TURN server configuration
* @returns {Object|null} TURN server configuration or null if not configured
*/
function getTurnConfig() {
if (!config.turnServerUrl) {
return null;
}
return {
urls: config.turnServerUrl,
username: config.turnUsername,
password: config.turnPassword
};
}
/**
* Check if running in development mode
* @returns {boolean}
*/
function isDevelopment() {
return config.nodeEnv === 'development';
}
/**
* Check if running in production mode
* @returns {boolean}
*/
function isProduction() {
return config.nodeEnv === 'production';
}
/**
* Check if running in test mode
* @returns {boolean}
*/
function isTest() {
return config.nodeEnv === 'test';
}
// Validate configuration on module load (except in test environment)
if (!isTest()) {
try {
validateConfig();
} catch (error) {
console.error('Configuration Error:', error.message);
process.exit(1);
}
}
module.exports = {
...config,
validateConfig,
getDatabaseConfig,
getOpenViduConfig,
getTurnConfig,
isDevelopment,
isProduction,
isTest
};