feat: add secure invitation and reset links

This commit is contained in:
2026-08-05 11:31:38 +08:00
parent 540b8e0932
commit 8ef0c312ef
14 changed files with 418 additions and 75 deletions
+15 -5
View File
@@ -39,14 +39,24 @@ def verification_code_email(*, code: str, minutes: int, purpose: str) -> str:
return render_transactional_email(title="邮箱验证码", content=content)
def password_reset_notice_email(*, username: str, reset_url: str) -> str:
"""Render an administrator-initiated password reset notification."""
def password_reset_notice_email(*, username: str, reset_url: str, minutes: int) -> str:
"""Render a one-time password reset link email."""
safe_url = escape(reset_url, quote=True)
content = f"""
<p style="margin:0;color:#475569;font-size:15px;line-height:1.8;">{escape(username)}管理员已要求你重置密码。</p>
<p style="margin:16px 0 24px;color:#475569;font-size:15px;line-height:1.8;">请通过下方按钮进入找回密码流程,系统会向本邮箱发送一次性验证码。</p>
<p style="margin:0;color:#475569;font-size:15px;line-height:1.8;">{escape(username)}请通过下方按钮设置新密码。</p>
<p style="margin:16px 0 24px;color:#475569;font-size:15px;line-height:1.8;">该链接仅可使用一次,并将在 {minutes} 分钟后失效。</p>
<p style="margin:0;"><a href="{safe_url}" style="display:inline-block;padding:12px 20px;border-radius:6px;background:#005eb8;color:#ffffff;font-size:14px;font-weight:700;text-decoration:none;">重置密码</a></p>"""
return render_transactional_email(title="重置密码", content=content)
return render_transactional_email(title="重置账户密码", content=content)
def registration_invitation_email(*, invitation_url: str, minutes: int) -> str:
"""Render a one-time invitation link email for an administrator-created account."""
safe_url = escape(invitation_url, quote=True)
content = f"""
<p style="margin:0;color:#475569;font-size:15px;line-height:1.8;">管理员邀请你加入供水管道健康评估系统。</p>
<p style="margin:16px 0 24px;color:#475569;font-size:15px;line-height:1.8;">请通过下方按钮设置显示名和密码。该链接仅可使用一次,并将在 {minutes} 分钟后失效。</p>
<p style="margin:0;"><a href="{safe_url}" style="display:inline-block;padding:12px 20px;border-radius:6px;background:#005eb8;color:#ffffff;font-size:14px;font-weight:700;text-decoration:none;">接受邀请并注册</a></p>"""
return render_transactional_email(title="管理员邀请你注册", content=content)
def send_transactional_email(*, to: str, subject: str, html: str) -> dict[str, Any]: