import { logger } from "@/logger.js" /** * 环境变量验证配置 * required: 必需的环境变量 * optional: 可选的环境变量(提供默认值) */ const ENV_CONFIG = { required: [ "SESSION_SECRET", "JWT_SECRET" ], optional: { "NODE_ENV": "development", "PORT": "3000", "LOG_DIR": "logs", "HTTPS_ENABLE": "off" } } /** * 验证必需的环境变量 * @returns {Object} 验证结果 */ function validateRequiredEnv() { const missing = [] const valid = {} for (const key of ENV_CONFIG.required) { const value = process.env[key] if (!value || value.trim() === '') { missing.push(key) } else { valid[key] = value } } return { missing, valid } } /** * 设置可选环境变量的默认值 * @returns {Object} 设置的默认值 */ function setOptionalDefaults() { const defaults = {} for (const [key, defaultValue] of Object.entries(ENV_CONFIG.optional)) { if (!process.env[key]) { process.env[key] = defaultValue defaults[key] = defaultValue } } return defaults } /** * 验证环境变量的格式和有效性 * @param {Object} env 环境变量对象 * @returns {Array} 错误列表 */ function validateEnvFormat(env) { const errors = [] // 验证 PORT 是数字 if (env.PORT && isNaN(parseInt(env.PORT))) { errors.push("PORT must be a valid number") } // 验证 NODE_ENV 的值 const validNodeEnvs = ['development', 'production', 'test'] if (env.NODE_ENV && !validNodeEnvs.includes(env.NODE_ENV)) { errors.push(`NODE_ENV must be one of: ${validNodeEnvs.join(', ')}`) } // 验证 SESSION_SECRET 至少包含一个密钥 if (env.SESSION_SECRET) { const secrets = env.SESSION_SECRET.split(',').filter(s => s.trim()) if (secrets.length === 0) { errors.push("SESSION_SECRET must contain at least one non-empty secret") } } // 验证 JWT_SECRET 长度 if (env.JWT_SECRET && env.JWT_SECRET.length < 32) { errors.push("JWT_SECRET must be at least 32 characters long for security") } return errors } /** * 初始化和验证所有环境变量 * @returns {boolean} 验证是否成功 */ export function validateEnvironment() { logger.info("🔍 开始验证环境变量...") // 1. 验证必需的环境变量 const { missing, valid } = validateRequiredEnv() if (missing.length > 0) { logger.error("❌ 缺少必需的环境变量:") missing.forEach(key => { logger.error(` - ${key}`) }) logger.error("请设置这些环境变量后重新启动应用") return false } // 2. 设置可选环境变量的默认值 const defaults = setOptionalDefaults() if (Object.keys(defaults).length > 0) { logger.info("⚙️ 设置默认环境变量:") Object.entries(defaults).forEach(([key, value]) => { logger.info(` - ${key}=${value}`) }) } // 3. 验证环境变量格式 const formatErrors = validateEnvFormat(process.env) if (formatErrors.length > 0) { logger.error("❌ 环境变量格式错误:") formatErrors.forEach(error => { logger.error(` - ${error}`) }) return false } // 4. 记录有效的环境变量(敏感信息脱敏) logger.info("✅ 环境变量验证成功:") logger.info(` - NODE_ENV=${process.env.NODE_ENV}`) logger.info(` - PORT=${process.env.PORT}`) logger.info(` - LOG_DIR=${process.env.LOG_DIR}`) logger.info(` - SESSION_SECRET=${maskSecret(process.env.SESSION_SECRET)}`) logger.info(` - JWT_SECRET=${maskSecret(process.env.JWT_SECRET)}`) return true } /** * 脱敏显示敏感信息 * @param {string} secret 敏感字符串 * @returns {string} 脱敏后的字符串 */ export function maskSecret(secret) { if (!secret) return "未设置" if (secret.length <= 8) return "*".repeat(secret.length) return secret.substring(0, 4) + "*".repeat(secret.length - 8) + secret.substring(secret.length - 4) } /** * 获取环境变量配置(用于生成 .env.example) * @returns {Object} 环境变量配置 */ export function getEnvConfig() { return ENV_CONFIG } export default { validateEnvironment, getEnvConfig, maskSecret }