"""YakPanel - Email notifications""" import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from app.core.config import get_runtime_config def send_email(subject: str, body: str, to: str | None = None) -> tuple[bool, str]: """Send email via SMTP. Returns (success, message).""" cfg = get_runtime_config() email_to = to or cfg.get("email_to", "").strip() smtp_server = cfg.get("smtp_server", "").strip() smtp_port = int(cfg.get("smtp_port") or 587) smtp_user = cfg.get("smtp_user", "").strip() smtp_password = cfg.get("smtp_password", "").strip() if not email_to: return False, "Email recipient not configured" if not smtp_server: return False, "SMTP server not configured" try: msg = MIMEMultipart() msg["Subject"] = subject msg["From"] = smtp_user or "YakPanel-server@localhost" msg["To"] = email_to msg.attach(MIMEText(body, "plain", "utf-8")) with smtplib.SMTP(smtp_server, smtp_port, timeout=15) as server: if smtp_user and smtp_password: server.starttls() server.login(smtp_user, smtp_password) server.sendmail(msg["From"], [email_to], msg.as_string()) return True, "Sent" except smtplib.SMTPAuthenticationError as e: return False, f"SMTP auth failed: {e}" except smtplib.SMTPException as e: return False, str(e) except Exception as e: return False, str(e)