Add one-time password recovery flow
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
"""SMTP delivery for one-time account recovery messages."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import smtplib
|
||||
import ssl
|
||||
from email.message import EmailMessage
|
||||
|
||||
|
||||
def smtp_configured() -> bool:
|
||||
return bool(
|
||||
os.getenv("SOVEREIGNAI_SMTP_HOST", "").strip()
|
||||
and os.getenv("SOVEREIGNAI_SMTP_FROM", "").strip()
|
||||
)
|
||||
|
||||
|
||||
def send_password_reset_email(address: str, token: str | None) -> None:
|
||||
host = os.getenv("SOVEREIGNAI_SMTP_HOST", "").strip()
|
||||
sender = os.getenv("SOVEREIGNAI_SMTP_FROM", "").strip()
|
||||
if not host or not sender:
|
||||
raise RuntimeError("SMTP recovery email is not configured")
|
||||
security = os.getenv("SOVEREIGNAI_SMTP_SECURITY", "starttls").strip().casefold()
|
||||
if security not in {"starttls", "ssl"}:
|
||||
raise RuntimeError("SOVEREIGNAI_SMTP_SECURITY must be starttls or ssl")
|
||||
port = int(os.getenv("SOVEREIGNAI_SMTP_PORT", "465" if security == "ssl" else "587"))
|
||||
username = os.getenv("SOVEREIGNAI_SMTP_USERNAME", "")
|
||||
password = os.getenv("SOVEREIGNAI_SMTP_PASSWORD", "")
|
||||
|
||||
message = EmailMessage()
|
||||
message["Subject"] = "استعادة كلمة مرور SovereignAI"
|
||||
message["From"] = sender
|
||||
message["To"] = address
|
||||
message.set_content(
|
||||
"إذا كان لهذا البريد حساب في SovereignAI، استخدم رمز الاستعادة التالي خلال 30 دقيقة.\n\n"
|
||||
f"{token if token is not None else 'لا يوجد رمز صالح لهذا الطلب.'}\n\n"
|
||||
"إذا لم تطلب الاستعادة، تجاهل هذه الرسالة."
|
||||
)
|
||||
|
||||
smtp_type = smtplib.SMTP_SSL if security == "ssl" else smtplib.SMTP
|
||||
client = (
|
||||
smtp_type(host, port, timeout=10, context=ssl.create_default_context())
|
||||
if security == "ssl"
|
||||
else smtp_type(host, port, timeout=10)
|
||||
)
|
||||
with client:
|
||||
if security == "starttls":
|
||||
client.starttls(context=ssl.create_default_context())
|
||||
if username:
|
||||
client.login(username, password)
|
||||
client.send_message(message)
|
||||
Reference in New Issue
Block a user