"""读取并脱敏 .env 配置供 UI 查看(v1.1.18)。 仅显示 .env 文件中的非空 key;命中 (TOKEN|SECRET|KEY|PASSWORD) 的字段自动脱敏为 ***。 """ from __future__ import annotations import re from pathlib import Path from util.runtime_paths import get_env_path # 匹配任一含 TOKEN / SECRET / KEY / PASSWORD 的 key 名(不区分大小写) _SECRET_PATTERN = re.compile(r"(TOKEN|SECRET|KEY|PASSWORD)", re.IGNORECASE) def _parse_env_file(path: Path) -> dict[str, str]: """手动解析 .env(避免依赖 python-dotenv)。 - 跳过空行 / 注释(# 开头) - 支持 KEY=VALUE 格式 - 自动去除包裹的 "..." 或 '...' """ if not path.exists(): return {} result: dict[str, str] = {} with open(path, "r", encoding="utf-8") as f: for line in f: line = line.strip() if not line or line.startswith("#"): continue if "=" not in line: continue k, _, v = line.partition("=") k = k.strip() v = v.strip() # 去掉行尾注释(不处理引号内的 #,简单实现) if " #" in v: v = v.split(" #", 1)[0].strip() if v.startswith('"') and v.endswith('"') and len(v) >= 2: v = v[1:-1] elif v.startswith("'") and v.endswith("'") and len(v) >= 2: v = v[1:-1] result[k] = v return result def _mask_secret(value: str) -> str: if not value: return "" if len(value) <= 4: return "***" return value[:2] + "***" + value[-2:] def read_env_config() -> dict: """读取 .env 中的非空 key,敏感 key 脱敏为 ***。 Returns: { "env_path": str, "exists": bool, "config": {key: value_or_masked_value, ...} } """ path = get_env_path() parsed = _parse_env_file(path) out: dict[str, str] = {} for k, v in sorted(parsed.items()): if not v: continue if _SECRET_PATTERN.search(k): out[k] = _mask_secret(v) else: out[k] = v return {"env_path": str(path), "exists": path.exists(), "config": out}