feat: add system settings page for admin username and password

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-08-02 08:56:54 +08:00
parent 4743f3efdd
commit b5cba83df4
20 changed files with 647 additions and 117 deletions
+60
View File
@@ -0,0 +1,60 @@
"""读写 .env(保留其它键;不记录密钥到日志)。"""
from __future__ import annotations
import os
import re
from pathlib import Path
_KEY_RE = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$")
def read_env_value(path: Path, key: str) -> str | None:
if not path.is_file():
return None
for line in path.read_text(encoding="utf-8").splitlines():
s = line.strip()
if not s or s.startswith("#") or "=" not in s:
continue
k, v = s.split("=", 1)
if k.strip() == key:
return v.strip()
return None
def update_env_file(path: Path, updates: dict[str, str]) -> None:
"""更新或追加键值;已有键覆盖。"""
for key in updates:
if not _KEY_RE.fullmatch(key):
raise ValueError(f"invalid env key: {key!r}")
lines: list[str] = []
if path.is_file():
lines = path.read_text(encoding="utf-8").splitlines()
seen: set[str] = set()
out: list[str] = []
for line in lines:
raw = line
s = line.strip()
if s and not s.startswith("#") and "=" in s:
k, _ = s.split("=", 1)
key = k.strip()
if key in updates:
out.append(f"{key}={updates[key]}")
seen.add(key)
continue
out.append(raw)
for key, val in updates.items():
if key not in seen:
out.append(f"{key}={val}")
path.parent.mkdir(parents=True, exist_ok=True)
text = "\n".join(out)
if text and not text.endswith("\n"):
text += "\n"
path.write_text(text, encoding="utf-8")
for key, val in updates.items():
os.environ[key] = val
+11
View File
@@ -20,7 +20,9 @@ class Settings(BaseSettings):
mi_port: int = Field(default=5170, alias="MI_PORT")
tz: str = Field(default="Asia/Shanghai", alias="TZ")
auth_secret: str = Field(default="change-me", alias="AUTH_SECRET")
admin_username: str = Field(default="admin", alias="ADMIN_USERNAME")
admin_password: str = Field(default="admin123", alias="ADMIN_PASSWORD")
env_file: str = Field(default=".env", alias="ENV_FILE")
# OKX
okx_api_key: str = Field(default="", alias="OKX_API_KEY")
@@ -56,6 +58,15 @@ class Settings(BaseSettings):
def db_path(self) -> Path:
return Path(self.mi_db_path)
@property
def env_file_path(self) -> Path:
return Path(self.env_file)
def reload_settings() -> Settings:
get_settings.cache_clear()
return get_settings()
@lru_cache
def get_settings() -> Settings: