"""Magic-link delivery. SMTP when configured, dev log fallback otherwise.""" from __future__ import annotations import logging import smtplib from email.message import EmailMessage from app.settings import settings logger = logging.getLogger(__name__) def magic_link(token: str) -> str: return f"{settings.frontend_url.rstrip('/')}/login?token={token}" def send_magic_link(to_email: str, link: str) -> bool: """Mail the login link. Returns False (logs instead) when SMTP is unset. The plaintext link only ever appears here: service/api logging must never include tokens or session ids (see test_auth no-leak test). """ if not settings.smtp_host: logger.info("SMTP not configured; magic link for %s: %s", to_email, link) return False message = EmailMessage() message["Subject"] = "Your kirche-einfach login link" message["To"] = to_email message["From"] = settings.mail_from or settings.contact_to or to_email if settings.contact_to: message["Reply-To"] = settings.contact_to message.set_content( f"Hello,\n\nUse this link to log in (valid 15 minutes, single use):\n{link}\n" ) with smtplib.SMTP(settings.smtp_host, settings.smtp_port, timeout=10) as smtp: smtp.starttls() if settings.smtp_username: smtp.login(settings.smtp_username, settings.smtp_password) smtp.send_message(message) logger.info("magic link mailed to %s", to_email) return True def send_access_notification(request_id: str, name: str, email: str) -> bool: """Notify CONTACT_TO about a new access request (best effort).""" if not settings.smtp_host or not settings.contact_to: logger.info("new access request %s from %s <%s>", request_id, name, email) return False message = EmailMessage() message["Subject"] = f"New access request: {name}" message["To"] = settings.contact_to message["From"] = settings.mail_from or settings.contact_to message.set_content( f"Name: {name}\nEmail: {email}\nRequest: {request_id}\n" ) try: with smtplib.SMTP(settings.smtp_host, settings.smtp_port, timeout=10) as smtp: smtp.starttls() if settings.smtp_username: smtp.login(settings.smtp_username, settings.smtp_password) smtp.send_message(message) except OSError: logger.warning("access-request notification failed for %s", request_id) return False return True