Files
hms/crates/erp-server/src/config.rs
iven 945ccd64ba
Some checks failed
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / frontend-build (push) Has been cancelled
CI / security-audit (push) Has been cancelled
fix: 全面 QA 审计修复 — 安全加固/代码质量/跨平台一致性/测试覆盖
Phase 0 安全热修复 (CRITICAL):
- 外部化微信 appid/secret 到 ERP__WECHAT__APPID/SECRET 环境变量
- 正确连接 HealthCrypto 到 ERP__HEALTH__AES_KEY/HMAC_KEY 环境变量
- 外部化小程序加密密钥到 TARO_APP_ENCRYPTION_KEY 环境变量
- 移除小程序 auth store 中的敏感信息 console.log

Phase 1 安全加固:
- 微信自动注册 display_name 添加 sanitize 防止 XSS
- 测试数据库凭据改为从 TEST_DB_URL 环境变量读取

Phase 2 代码质量:
- 提取 useThemeMode hook 消除 22 处重复暗色模式检测
- 提取共享健康常量到 constants/health.ts
- 拆分 patient_service.rs 脱敏函数到 masking.rs
- 移除未使用的 i18next/react-i18next 依赖
- 移除未使用的 api/errors.ts 和 erp-auth/anyhow 依赖

Phase 3 测试覆盖:
- 新增 5 个患者模块集成测试 (CRUD/租户隔离/验证/软删除)

Phase 4 跨平台一致性:
- 统一小程序 Patient.birthday → birth_date 匹配后端
- 统一小程序 Appointment.time_slot → start_time/end_time 匹配后端

Phase 5 架构:
- 微信登录添加多租户 TODO 注释
- 更新 wiki/infrastructure.md 环境变量文档
2026-04-25 10:00:49 +08:00

88 lines
2.2 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
use serde::Deserialize;
#[derive(Debug, Clone, Deserialize)]
pub struct AppConfig {
pub server: ServerConfig,
pub database: DatabaseConfig,
pub redis: RedisConfig,
pub jwt: JwtConfig,
pub auth: AuthConfig,
pub log: LogConfig,
pub cors: CorsConfig,
pub wechat: WechatConfig,
pub health: HealthConfig,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ServerConfig {
pub host: String,
pub port: u16,
}
#[derive(Debug, Clone, Deserialize)]
pub struct DatabaseConfig {
pub url: String,
pub max_connections: u32,
pub min_connections: u32,
}
#[derive(Debug, Clone, Deserialize)]
pub struct RedisConfig {
pub url: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct JwtConfig {
pub secret: String,
pub access_token_ttl: String,
pub refresh_token_ttl: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct LogConfig {
pub level: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct AuthConfig {
pub super_admin_password: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct CorsConfig {
/// Comma-separated list of allowed origins.
/// Use "*" to allow all origins (development only).
pub allowed_origins: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct WechatConfig {
pub appid: String,
pub secret: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct HealthConfig {
/// AES-256 密钥 (64 字符 hex 编码32 字节)
pub aes_key: String,
/// HMAC-SHA256 密钥 (64 字符 hex 编码32 字节)
pub hmac_key: String,
}
impl AppConfig {
pub fn load() -> anyhow::Result<Self> {
let config = config::Config::builder()
.add_source(config::File::with_name("config/default"))
.add_source(config::Environment::with_prefix("ERP").separator("__"))
.build()?;
let app_config: Self = config.try_deserialize()?;
// 安全检查:禁止在生产使用默认 JWT 密钥
if app_config.jwt.secret == "change-me-in-production" {
tracing::warn!("⚠️ JWT 密钥使用默认值,请通过 ERP__JWT__SECRET 环境变量设置安全密钥");
}
Ok(app_config)
}
}