diff --git a/src/routers/feedback.py b/src/routers/feedback.py index e064d14..18a9a7f 100644 --- a/src/routers/feedback.py +++ b/src/routers/feedback.py @@ -39,7 +39,6 @@ _user_timestamps: dict[int, list[float]] = defaultdict(list) _MAX_PER_HOUR = 3 _WINDOW = 3600 - _ALLOWED_TYPES = {"image/jpeg", "image/png"} _MAX_FILE_SIZE = 5 * 1024 * 1024 # 5 MB _MAX_FILES = 3 @@ -105,16 +104,32 @@ async def send_feedback( """ - msg = MIMEMultipart("alternative") + msg = MIMEMultipart("mixed") msg["From"] = f"{SMTP_FROM_NAME} <{SMTP_FROM_EMAIL}>" msg["To"] = FEEDBACK_EMAIL msg["Subject"] = subject if email: msg["Reply-To"] = email + # Text-Teil (alternative: plain + html) + text_part = MIMEMultipart("alternative") text_fallback = f"Feedback von {display_name} ({category_label}):\n\n{message}" - msg.attach(MIMEText(text_fallback, "plain", "utf-8")) - msg.attach(MIMEText(html_body, "html", "utf-8")) + text_part.attach(MIMEText(text_fallback, "plain", "utf-8")) + text_part.attach(MIMEText(html_body, "html", "utf-8")) + msg.attach(text_part) + + # Bild-Anhaenge + for f in files: + file_data = await f.read() + if len(file_data) > _MAX_FILE_SIZE: + raise HTTPException(status_code=422, detail=f"Datei {f.filename} ist groesser als 5 MB.") + sub_type = (f.content_type or "image/jpeg").split("/")[1] + attachment = MIMEBase("image", sub_type) + attachment.set_payload(file_data) + encoders.encode_base64(attachment) + attachment.add_header("Content-Disposition", "attachment", filename=f.filename or "bild.jpg") + msg.attach(attachment) + logger.debug(f"Anhang: {f.filename} ({len(file_data)} Bytes, {f.content_type})") try: await aiosmtplib.send( @@ -126,7 +141,7 @@ async def send_feedback( start_tls=SMTP_USE_TLS, ) _user_timestamps[user_id].append(now) - logger.info(f"Feedback von {display_name} ({category_label}) gesendet") + logger.info(f"Feedback von {display_name} ({category_label}) gesendet, {len(files)} Anhaenge") except Exception as e: logger.error(f"Feedback-E-Mail fehlgeschlagen: {e}") raise HTTPException(