import html import smtplib import ssl from email.message import EmailMessage from email.utils import formataddr from .models import AppSettings, User def _settings_ready(settings: AppSettings | None) -> bool: return bool(settings and settings.smtp_host and settings.smtp_from_email) def send_html_email(settings: AppSettings, recipient: str, subject: str, body_html: str, body_text: str): if not _settings_ready(settings): raise ValueError("SMTP settings are incomplete") message = EmailMessage() message["Subject"] = subject message["From"] = formataddr((settings.smtp_from_name or "Cluedo HP", settings.smtp_from_email)) message["To"] = recipient message.set_content(body_text) message.add_alternative(body_html, subtype="html") context = ssl.create_default_context() with smtplib.SMTP(settings.smtp_host, settings.smtp_port or 587, timeout=20) as server: server.ehlo() if settings.smtp_use_tls: server.starttls(context=context) server.ehlo() if settings.smtp_username: server.login(settings.smtp_username, settings.smtp_password) server.send_message(message) def send_user_invite(settings: AppSettings, user: User, invite_url: str): name = html.escape(user.display_name or user.email) safe_url = html.escape(invite_url, quote=True) from_name = html.escape(settings.smtp_from_name or "Cluedo HP") body_html = f"""