feat: 调度表单重构、登录门控、批量任务与页面缓存对齐
调度页执行周期可视化/单次执行/分类选机/推送源对齐;登录 IP 门控与无缝导航; 服务器批量后台任务、执行记录、凭据合并、各页激活刷新与错误提示修复。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -111,6 +111,18 @@ class WebsshTokenRequest(BaseModel):
|
||||
|
||||
# ── Public Routes (no JWT required) ──
|
||||
|
||||
@router.get("/login-access")
|
||||
async def login_access(request: Request):
|
||||
"""Precheck login form visibility. Blocked IPs get 403 with empty body (no IP leak)."""
|
||||
from server.utils.login_allowlist import check_login_ip
|
||||
|
||||
client_ip = get_client_ip(request)
|
||||
allowlist_enabled, allowed, _message = check_login_ip(client_ip)
|
||||
if allowlist_enabled and not allowed:
|
||||
return Response(status_code=403)
|
||||
return {"allowed": True}
|
||||
|
||||
|
||||
@router.post("/login")
|
||||
async def login(
|
||||
request: Request,
|
||||
@@ -136,6 +148,8 @@ async def login(
|
||||
status_code = 429
|
||||
elif result.get("reason") == "totp_required":
|
||||
status_code = 202 # Accepted but needs TOTP
|
||||
elif result.get("reason") == "ip_blocked":
|
||||
return Response(status_code=403)
|
||||
raise HTTPException(status_code=status_code, detail=result.get("message", "Login failed"))
|
||||
|
||||
# Set refresh token as HttpOnly cookie (not accessible from JS)
|
||||
|
||||
Reference in New Issue
Block a user