diff --git a/backend/.env.example b/backend/.env.example index 05d6fcf..e06416d 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -18,6 +18,10 @@ PORT=40001 # 运行环境(production 或 development) NODE_ENV=production +# 强制HTTPS访问(生产环境建议开启) +# 设置为 true 时,仅接受 HTTPS 访问 +ENFORCE_HTTPS=false + # 公开访问端口(nginx监听的端口,用于生成分享链接) # 标准端口(80/443)可不配置 PUBLIC_PORT=80 diff --git a/backend/server.js b/backend/server.js index 2b7c265..098ce8d 100644 --- a/backend/server.js +++ b/backend/server.js @@ -3062,7 +3062,13 @@ app.get('/api/admin/storage-stats', authMiddleware, adminMiddleware, async (req, try { // 获取本地存储目录所在的驱动器号 const driveLetter = localStorageDir.charAt(0); - const { stdout: wmicOutput } = await execAsync(`wmic logicaldisk where "DeviceID='' + driveLetter + '':''" get Size,FreeSpace /value`, { encoding: 'utf8' }); + if (!/^[A-Za-z]$/.test(driveLetter)) { + throw new Error('Invalid drive letter'); + } + const { stdout: wmicOutput } = await execAsync( + `wmic logicaldisk where "DeviceID='${driveLetter}:'" get Size,FreeSpace /value`, + { encoding: 'utf8' } + ); const freeMatch = wmicOutput.match(/FreeSpace=(\d+)/); const sizeMatch = wmicOutput.match(/Size=(\d+)/); diff --git a/install.sh b/install.sh index cf95bbc..32b24c1 100644 --- a/install.sh +++ b/install.sh @@ -2121,11 +2121,13 @@ create_env_file() { PROTOCOL="http" COOKIE_SECURE_VALUE="false" PORT_VALUE=${HTTP_PORT:-80} + ENFORCE_HTTPS_VALUE="false" else # HTTPS 模式 PROTOCOL="https" COOKIE_SECURE_VALUE="true" PORT_VALUE=${HTTPS_PORT:-443} + ENFORCE_HTTPS_VALUE="true" fi # 生成 ALLOWED_ORIGINS (标准端口不需要显示端口号) @@ -2141,6 +2143,7 @@ create_env_file() { # 留空,后端默认允许所有来源(适合开发环境) ALLOWED_ORIGINS_VALUE="" COOKIE_SECURE_VALUE="false" + ENFORCE_HTTPS_VALUE="false" print_warning "IP 模式下 CORS 将允许所有来源(仅适合开发环境)" print_info "生产环境建议使用域名模式" fi @@ -2165,6 +2168,9 @@ PORT=${BACKEND_PORT} # 环境 NODE_ENV=production +# 强制HTTPS(生产环境建议开启) +ENFORCE_HTTPS=${ENFORCE_HTTPS_VALUE} + # CORS 跨域配置 # 允许访问的前端域名(多个用逗号分隔) # 生产环境必须配置具体域名,开发环境可留空 @@ -3809,6 +3815,33 @@ print_update_completion() { echo "" } +update_patch_env() { + print_step "检查 .env 新增配置..." + if [[ -f "${PROJECT_DIR}/backend/.env" ]]; then + if ! grep -q "^ENFORCE_HTTPS=" "${PROJECT_DIR}/backend/.env"; then + # 基于现有配置做一个合理的默认值:如果已启用安全Cookie或公开端口为443,优先设为true + COOKIE_SECURE_CUR=$(grep "^COOKIE_SECURE=" "${PROJECT_DIR}/backend/.env" | cut -d'=' -f2- | tr '[:upper:]' '[:lower:]') + PUBLIC_PORT_CUR=$(grep "^PUBLIC_PORT=" "${PROJECT_DIR}/backend/.env" | cut -d'=' -f2-) + ALLOWED_CUR=$(grep "^ALLOWED_ORIGINS=" "${PROJECT_DIR}/backend/.env" | cut -d'=' -f2-) + + ENFORCE_DEFAULT="false" + if [[ "$COOKIE_SECURE_CUR" == "true" ]] || [[ "$PUBLIC_PORT_CUR" == "443" ]]; then + ENFORCE_DEFAULT="true" + elif echo "$ALLOWED_CUR" | grep -qi "https://"; then + ENFORCE_DEFAULT="true" + fi + + echo "ENFORCE_HTTPS=${ENFORCE_DEFAULT}" >> "${PROJECT_DIR}/backend/.env" + print_warning "已为现有 .env 补充 ENFORCE_HTTPS=${ENFORCE_DEFAULT}(如生产请确认设为 true 并重启)" + else + print_info ".env 已包含 ENFORCE_HTTPS,保持不变" + fi + else + print_warning "未找到 ${PROJECT_DIR}/backend/.env,请手动确认配置" + fi + echo "" +} + update_main() { # 检查root权限 check_root @@ -3849,6 +3882,8 @@ update_main() { # 迁移数据库配置 update_migrate_database + # 补充新配置项 + update_patch_env # 重启服务 update_restart_services