""" E-Mail-Versand via SMTP (smtplib + asyncio.to_thread). Konfiguration pro Firma in smtp_configs. Kein externer Mail-Dienst nötig. """ import asyncio import smtplib import ssl from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from typing import TYPE_CHECKING from uuid import UUID from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.core.config import settings from app.models.smtp_config import SmtpConfig if TYPE_CHECKING: from app.models.user import User def _html_wrapper(title: str, body: str) -> str: return f"""
Dein Firmen-Account wurde erfolgreich erstellt. Du kannst dich ab sofort anmelden.
Zum Login """ await self._send(user.email, f"Willkommen bei {settings.app_name}", _html_wrapper("Willkommen", body), cfg) async def send_invite(self, user: "User", invited_by: "User", raw_token: str, db: AsyncSession) -> None: cfg = await self._load_smtp(user.company_id, db) invite_url = f"{settings.frontend_url}/invite/accept?token={raw_token}" body = f"""{invited_by.full_name} hat dich zu {settings.app_name} eingeladen.
Klicke auf den Button, um dein Konto zu aktivieren und ein Passwort festzulegen.
Der Link ist 7 Tage gültig.
Oder kopiere diesen Link: {invite_url}
""" await self._send( user.email, f"{invited_by.full_name} hat dich zu {settings.app_name} eingeladen", _html_wrapper("Einladung", body), cfg, ) async def send_password_reset(self, user: "User", raw_token: str, db: AsyncSession) -> None: cfg = await self._load_smtp(user.company_id, db) reset_url = f"{settings.frontend_url}/auth/reset-password?token={raw_token}" body = f"""Hallo {user.first_name},
du hast eine Anfrage zum Zurücksetzen deines Passworts gestellt.
Klicke auf den Button – der Link ist 1 Stunde gültig.
Falls du diese Anfrage nicht gestellt hast, kannst du diese E-Mail ignorieren.
""" await self._send(user.email, "Passwort zurücksetzen", _html_wrapper("Passwort zurücksetzen", body), cfg) async def send_test(self, cfg: SmtpConfig, to: str) -> None: """Test-E-Mail direkt mit übergebenem Konfigurationsobjekt.""" body = f"""Deine SMTP-Konfiguration für {settings.app_name} funktioniert korrekt.
Server: {cfg.host}:{cfg.port}
""" await self._send(to, f"{settings.app_name} – SMTP-Test", _html_wrapper("SMTP-Test", body), cfg) email_service = EmailService()