Fix feedback attachments: proper MIME mixed/alternative structure

Rewrite feedback.py with correct MIMEMultipart(mixed) containing
alternative text part + base64-encoded image attachments.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dieser Commit ist enthalten in:
claude-dev
2026-03-10 13:42:10 +01:00
Ursprung 11db52d28b
Commit 5e5267572b

Datei anzeigen

@@ -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(
</div>
</div>"""
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(