Harden auth risk controls and admin reauth

This commit is contained in:
2025-12-26 21:07:47 +08:00
parent f90b0a4f11
commit e3b0c35da6
32 changed files with 741 additions and 92 deletions

View File

@@ -80,6 +80,7 @@ EMAIL_TYPE_REGISTER = 'register' # 注册验证
EMAIL_TYPE_RESET = 'reset' # 密码重置
EMAIL_TYPE_BIND = 'bind' # 邮箱绑定
EMAIL_TYPE_TASK_COMPLETE = 'task_complete' # 任务完成通知
EMAIL_TYPE_SECURITY_ALERT = 'security_alert' # 安全告警
# Token有效期
TOKEN_EXPIRE_REGISTER = 24 * 60 * 60 # 注册验证: 24小时
@@ -1620,6 +1621,67 @@ def verify_bind_email_token(token: str) -> Optional[Dict[str, Any]]:
return verify_email_token(token, EMAIL_TYPE_BIND)
def send_security_alert_email(
email: str,
username: str,
ip_address: str,
user_agent: str,
new_ip: bool,
new_device: bool,
user_id: int = None,
) -> Dict[str, Any]:
"""发送登录安全提醒邮件(低侵入,不影响登录)。"""
settings = get_email_settings()
if not settings.get("enabled", False):
return {"success": False, "error": "邮件功能未启用"}
reason_parts = []
if new_ip:
reason_parts.append("新的登录IP")
if new_device:
reason_parts.append("新的登录设备")
reason_text = "".join(reason_parts) if reason_parts else "异常登录"
subject = "账号安全提醒"
now_str = get_beijing_now_str()
ip_text = ip_address or "未知"
ua_text = user_agent or "未知"
text_body = (
f"您好,{username}\n\n"
f"我们检测到 {reason_text}\n"
f"时间:{now_str}\n"
f"IP{ip_text}\n"
f"设备信息:{ua_text}\n\n"
"如果这不是您本人操作,请尽快修改密码并联系管理员。\n"
)
html_body = f"""
<html>
<body>
<h2>账号安全提醒</h2>
<p>您好,{username}</p>
<p>我们检测到 <strong>{reason_text}</strong>。</p>
<ul>
<li>时间:{now_str}</li>
<li>IP{ip_text}</li>
<li>设备信息:{ua_text}</li>
</ul>
<p>如果这不是您本人操作,请尽快修改密码并联系管理员。</p>
</body>
</html>
"""
return send_email(
to_email=email,
subject=subject,
body=text_body,
html_body=html_body,
email_type=EMAIL_TYPE_SECURITY_ALERT,
user_id=user_id,
)
# ============ 异步发送队列 ============
class EmailQueue: