import html import os import smtplib import ssl from datetime import datetime from email.message import EmailMessage from api.utils.email_verification import EMAIL_VERIFICATION_CODE_TTL_MINUTES def _env_bool(name: str, default: str = "false") -> bool: return os.getenv(name, default).strip().lower() in {"1", "true", "yes", "on"} def _build_verification_plain(username: str, code: str) -> str: ttl = EMAIL_VERIFICATION_CODE_TTL_MINUTES return "\n".join( [ f"Hola {username},", "", "Tu código de verificación para Deck of Cards es:", "", code, "", f"Este código caduca en {ttl} minutos.", "Si no has creado esta cuenta, puedes ignorar este correo.", "", "— Deck of Cards", "Plataforma web para la elicitación de escalas de valor (DoC-MF).", ] ) def _build_verification_html(username: str, code: str) -> str: safe_username = html.escape(username) frontend_url = os.getenv("FRONTEND_URL", "http://localhost:5173").rstrip("/") logo_url = f"{frontend_url}/favicon.svg" ttl = EMAIL_VERIFICATION_CODE_TTL_MINUTES year = datetime.utcnow().year return f""" Verificación — Deck of Cards
Deck of Cards Deck of Cards

Verificación de cuenta

Hola, {safe_username}

Gracias por registrarte. Introduce el siguiente código en la pantalla de registro para confirmar tu correo electrónico.

Tu código

{code}

El código caduca en {ttl} minutos.

Si no has creado esta cuenta, ignora este mensaje. Nadie más podrá usar tu correo sin el código.

Deck of Cards Software Científico

Plataforma web para la elicitación de escalas de valor y construcción de conjuntos difusos interpretables (DoC-MF).

© {year} Deck of Cards App.

Basado en la metodología DoC-MF (D. García-Zamora, B. Dutta, J.R. Figueira y L. Martínez, EJOR, 2024).

""" def send_verification_email(recipient_email: str, username: str, code: str) -> bool: smtp_host = os.getenv("SMTP_HOST") if not smtp_host: print( "[email-verification] SMTP_HOST no configurado. " f"Código para {recipient_email}: {code}" ) return False smtp_port = int(os.getenv("SMTP_PORT", "587")) smtp_username = os.getenv("SMTP_USERNAME") smtp_password = os.getenv("SMTP_PASSWORD") smtp_from_email = os.getenv("SMTP_FROM_EMAIL") or smtp_username smtp_from_name = os.getenv("SMTP_FROM_NAME", "Deck of Cards") use_tls = _env_bool("SMTP_USE_TLS", "true") use_ssl = _env_bool("SMTP_USE_SSL", "false") if not smtp_from_email: raise RuntimeError("SMTP_FROM_EMAIL o SMTP_USERNAME debe estar configurado") message = EmailMessage() message["Subject"] = "Código de verificación — Deck of Cards" message["From"] = f"{smtp_from_name} <{smtp_from_email}>" message["To"] = recipient_email message.set_content(_build_verification_plain(username, code)) message.add_alternative(_build_verification_html(username, code), subtype="html") context = ssl.create_default_context() if use_ssl: with smtplib.SMTP_SSL(smtp_host, smtp_port, context=context) as server: if smtp_username and smtp_password: server.login(smtp_username, smtp_password) server.send_message(message) else: with smtplib.SMTP(smtp_host, smtp_port) as server: if use_tls: server.starttls(context=context) if smtp_username and smtp_password: server.login(smtp_username, smtp_password) server.send_message(message) return True