"""Admin Configuration page API: read/edit the DB-overridable operational settings defined in app.sysconfig. Secret values (e.g. SMTP password) are write-only — never returned.""" from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from app import email as email_mod from app import sysconfig from app.db import get_db from app.models import User from app.routes.admin import admin_user router = APIRouter(prefix="/api/admin/config", tags=["admin"]) @router.get("") def get_config(_: User = Depends(admin_user), db: Session = Depends(get_db)) -> dict: return sysconfig.describe(db) @router.patch("/{key}") def set_config( key: str, payload: dict, _: User = Depends(admin_user), db: Session = Depends(get_db), ) -> dict: s = sysconfig.spec(key) if s is None: raise HTTPException(status_code=404, detail="Unknown config key") if "value" not in payload: raise HTTPException(status_code=400, detail="Missing 'value'") if s.secret and not sysconfig.secrets_manageable(): raise HTTPException( status_code=400, detail="Set TOKEN_ENCRYPTION_KEY to store secrets in the database.", ) try: sysconfig.set_value(db, key, payload["value"]) except (TypeError, ValueError) as exc: raise HTTPException(status_code=400, detail=str(exc) or "Invalid value") return sysconfig.describe(db) @router.delete("/{key}") def reset_config( key: str, _: User = Depends(admin_user), db: Session = Depends(get_db), ) -> dict: if sysconfig.spec(key) is None: raise HTTPException(status_code=404, detail="Unknown config key") sysconfig.reset(db, key) return sysconfig.describe(db) @router.post("/test-email") def send_test_email( user: User = Depends(admin_user), db: Session = Depends(get_db), ) -> dict: """Send a test email to the requesting admin using the current (DB or env) SMTP config — lets the admin verify the settings actually work.""" if not email_mod.email_enabled(): raise HTTPException(status_code=400, detail="SMTP is not configured.") sent = email_mod.send_test(user.email) if not sent: raise HTTPException(status_code=422, detail="SMTP send failed — check the settings.") return {"sent": True, "to": user.email}