""" Email utility for sending password reset codes via Gmail SMTP. """ import smtplib import ssl import logging from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from ..core.config import Config logger = logging.getLogger(__name__) SMTP_SERVER = "smtp.gmail.com" SMTP_PORT = 465 def send_reset_code_email(to_email: str, code: str) -> bool: """ Send a password reset code email via Gmail SMTP. Args: to_email: Recipient email address. code: The 6-digit reset code (plaintext, for display in email). Returns: True if sent successfully, False otherwise. """ sender = Config.GMAIL_USER password = Config.GMAIL_APP_PASSWORD if not sender or not password: logger.error("Gmail credentials not configured. Set GMAIL_USER and GMAIL_APP_PASSWORD.") return False subject = "AniCove — Password Reset Code" html_body = f"""\

AniCove

Your password reset code is:

{code}

This code expires in 5 minutes.

If you didn't request this, you can safely ignore this email.

""" msg = MIMEMultipart("alternative") msg["Subject"] = subject msg["From"] = sender msg["To"] = to_email # Plain-text fallback text_body = ( f"AniCove — Password Reset\n\n" f"Your reset code is: {code}\n\n" f"This code expires in 5 minutes.\n" f"If you didn't request this, ignore this email." ) msg.attach(MIMEText(text_body, "plain")) msg.attach(MIMEText(html_body, "html")) try: context = ssl.create_default_context() with smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT, context=context) as server: server.login(sender, password) server.sendmail(sender, to_email, msg.as_string()) logger.info(f"Reset code email sent to {to_email}") return True except smtplib.SMTPAuthenticationError: logger.error("Gmail SMTP authentication failed. Check GMAIL_USER / GMAIL_APP_PASSWORD.") return False except Exception as e: logger.error(f"Failed to send reset code email to {to_email}: {e}") return False