v1.22: Verwaltung sendet Direkt-E-Mails an Mieter mit CC an die Verwaltung

This commit is contained in:
2026-10-04 14:17:12 +02:00
parent 497abfcd4b
commit f15fc6ee0c
10 changed files with 410 additions and 8 deletions
Binary file not shown.
+19 -2
View File
@@ -12,7 +12,8 @@ Endpunkte:
GET /healthz → {"ok": true}
GET /outbox → aktuelle Outbox (Demo/Debug)
POST /send → {"ok": true, "id": ..., "versandt": true/false}
Body: {"to": "...", "subject": "...", "text": "...", "html": "..."}
Body: {"to": "...", "subject": "...", "text": "...", "html": "...",
optional "cc": "a@b.de, c@d.de", "from_address"/"from_name" (nur @hocks.eu)}
Auth: Header X-Api-Token oder Body-Feld "token" == MAIL_API_TOKEN
"""
@@ -78,8 +79,10 @@ def rate_limit_ok() -> bool:
def versenden(e: dict) -> bool:
msg = EmailMessage()
msg["From"] = f"{SENDER_NAME} <{SENDER_ADDRESS}>"
msg["From"] = f"{e.get('from_name') or SENDER_NAME} <{e.get('from_address') or SENDER_ADDRESS}>"
msg["To"] = e["to"]
if e.get("cc"):
msg["Cc"] = e["cc"] # Komma-getrennte CC-Empfaenger (v1.22)
msg["Subject"] = e["subject"]
msg.set_content(e.get("text") or "")
if e.get("html"):
@@ -172,12 +175,26 @@ class Handler(BaseHTTPRequestHandler):
if not rate_limit_ok():
self._antwort(429, {"fehler": "Rate-Limit erreicht"})
return
# Optionaler eigener Absender (nur hocks.eu-Domain, sonst Fallback)
absender = str(body.get("from_address", "")).strip().lower()
absender_name = str(body.get("from_name", "")).strip()
if (not EMAIL_RE.match(absender) or not absender.endswith("@hocks.eu")
or len(absender_name) > 60 or any(c in absender_name for c in "<>\r\n")):
absender, absender_name = SENDER_ADDRESS, SENDER_NAME
# Optional CC (Komma-getrennt, einzeln validiert) – v1.22
cc = ','.join(
a for a in (x.strip() for x in str(body.get("cc", "")).split(","))
if a and EMAIL_RE.match(a)
)
eintrag = {
"id": uuid.uuid4().hex[:12],
"to": an,
"subject": betreff,
"text": str(body.get("text", "")),
"html": str(body.get("html", "")),
"cc": cc,
"from_address": absender,
"from_name": absender_name,
"versuche": 0,
"versandt": False,
"angenommenAm": time.strftime("%d.%m.%Y %H:%M:%S"),