feat: Add email settings management and templates functionality
All checks were successful
CI / test (3.11) (push) Successful in 1m36s
CI / build-image (push) Successful in 1m27s

- Implemented email settings configuration in the admin panel, allowing for SMTP settings and notification preferences.
- Created a new template for email settings with fields for SMTP host, port, username, password, sender address, and recipients.
- Added JavaScript functionality to handle loading, saving, and validating email settings.
- Introduced email templates management, enabling the listing, editing, and saving of email templates.
- Updated navigation to include links to email settings and templates.
- Added tests for email settings and templates to ensure proper functionality and validation.
This commit is contained in:
2025-11-15 11:12:23 +01:00
parent 2629f6b25f
commit e192086833
19 changed files with 1537 additions and 192 deletions

View File

@@ -6,12 +6,12 @@ import smtplib
from dataclasses import dataclass
from datetime import datetime, timezone
from email.message import EmailMessage
from typing import Any, Dict, Tuple
from typing import Any, Dict, Tuple, cast
from .. import settings
from ..database import save_contact
from ..metrics import record_submission
from ..utils import is_valid_email
from .email_settings import load_effective_smtp_settings
@dataclass
@@ -70,12 +70,22 @@ def persist_submission(submission: ContactSubmission) -> int:
def send_notification(submission: ContactSubmission) -> bool:
"""Send an email notification for the submission if SMTP is configured."""
if not settings.SMTP_SETTINGS["host"] or not settings.SMTP_SETTINGS["recipients"]:
smtp_config = load_effective_smtp_settings()
if not smtp_config.get("notify_contact_form"):
logging.info("Contact notifications disabled; skipping email dispatch")
return False
if not smtp_config.get("host") or not smtp_config.get("recipients"):
logging.info("SMTP not configured; skipping email notification")
return False
sender = settings.SMTP_SETTINGS["sender"] or "no-reply@example.com"
recipients = settings.SMTP_SETTINGS["recipients"]
sender = smtp_config.get("sender") or "no-reply@example.com"
recipients = smtp_config.get("recipients", [])
host = cast(str, smtp_config.get("host"))
port = int(smtp_config.get("port") or 0)
username = smtp_config.get("username") or None
password = smtp_config.get("password") or ""
msg = EmailMessage()
msg["Subject"] = f"Neue Kontaktanfrage von {submission.name}"
@@ -98,12 +108,11 @@ def send_notification(submission: ContactSubmission) -> bool:
)
try:
with smtplib.SMTP(settings.SMTP_SETTINGS["host"], settings.SMTP_SETTINGS["port"], timeout=15) as server:
if settings.SMTP_SETTINGS["use_tls"]:
with smtplib.SMTP(host, port, timeout=15) as server:
if smtp_config.get("use_tls"):
server.starttls()
if settings.SMTP_SETTINGS["username"]:
server.login(
settings.SMTP_SETTINGS["username"], settings.SMTP_SETTINGS["password"] or "")
if username:
server.login(username, password)
server.send_message(msg)
logging.info("Notification email dispatched to %s", recipients)
return True