_create_forward_message fixed for multipart messages

This commit is contained in:
Andreas Knuth 2026-01-25 17:23:08 -06:00
parent 046111e267
commit 406cce6270
1 changed files with 54 additions and 45 deletions

View File

@ -231,54 +231,63 @@ class RulesProcessor:
msg.attach(body_part)
return msg
@staticmethod
def _create_forward_message(original_parsed, recipient: str, forward_to: str, original_from: str):
"""Create Forward message as complete MIME message"""
original_subject = original_parsed.get('Subject', '(no subject)')
original_date = original_parsed.get('Date', 'unknown')
@staticmethod
def _create_forward_message(original_parsed, recipient: str, forward_to: str, original_from: str):
"""Create Forward message as complete MIME message"""
original_subject = original_parsed.get('Subject', '(no subject)')
original_date = original_parsed.get('Date', 'unknown')
msg = MIMEMultipart('mixed')
msg['From'] = recipient
msg['To'] = forward_to
msg['Subject'] = f"FWD: {original_subject}"
msg['Date'] = formatdate(localtime=True)
msg['Message-ID'] = make_msgid(domain=recipient.split('@')[1])
msg['Reply-To'] = original_from
msg['X-SES-Worker-Processed'] = 'forwarded'
msg = MIMEMultipart('mixed')
msg['From'] = recipient
msg['To'] = forward_to
msg['Subject'] = f"FWD: {original_subject}"
msg['Date'] = formatdate(localtime=True)
msg['Message-ID'] = make_msgid(domain=recipient.split('@')[1])
msg['Reply-To'] = original_from
msg['X-SES-Worker-Processed'] = 'forwarded'
text_body, html_body = EmailParser.extract_body_parts(original_parsed)
body_part = MIMEMultipart('alternative')
# Text version
fwd_text = "---------- Forwarded message ---------\n"
fwd_text += f"From: {original_from}\n"
fwd_text += f"Date: {original_date}\n"
fwd_text += f"Subject: {original_subject}\n"
fwd_text += f"To: {recipient}\n\n"
fwd_text += text_body
body_part.attach(MIMEText(fwd_text, 'plain', 'utf-8'))
text_body, html_body = EmailParser.extract_body_parts(original_parsed)
body_part = MIMEMultipart('alternative')
# Text version
fwd_text = "---------- Forwarded message ---------\n"
fwd_text += f"From: {original_from}\n"
fwd_text += f"Date: {original_date}\n"
fwd_text += f"Subject: {original_subject}\n"
fwd_text += f"To: {recipient}\n\n"
fwd_text += text_body
body_part.attach(MIMEText(fwd_text, 'plain', 'utf-8'))
# HTML version
if html_body:
fwd_html = "<div style='border-left:3px solid #ccc;padding-left:10px;'>"
fwd_html += "<strong>---------- Forwarded message ---------</strong><br>"
fwd_html += f"<strong>From:</strong> {original_from}<br>"
fwd_html += f"<strong>Date:</strong> {original_date}<br>"
fwd_html += f"<strong>Subject:</strong> {original_subject}<br>"
fwd_html += f"<strong>To:</strong> {recipient}<br><br>"
fwd_html += html_body
fwd_html += "</div>"
body_part.attach(MIMEText(fwd_html, 'html', 'utf-8'))
# HTML version
if html_body:
fwd_html = "<div style='border-left:3px solid #ccc;padding-left:10px;'>"
fwd_html += "<strong>---------- Forwarded message ---------</strong><br>"
fwd_html += f"<strong>From:</strong> {original_from}<br>"
fwd_html += f"<strong>Date:</strong> {original_date}<br>"
fwd_html += f"<strong>Subject:</strong> {original_subject}<br>"
fwd_html += f"<strong>To:</strong> {recipient}<br><br>"
fwd_html += html_body
fwd_html += "</div>"
body_part.attach(MIMEText(fwd_html, 'html', 'utf-8'))
msg.attach(body_part)
msg.attach(body_part)
# Copy attachments
if original_parsed.is_multipart():
for part in original_parsed.walk():
if part.get_content_maintype() == 'multipart':
continue
if part.get_content_type() in ['text/plain', 'text/html']:
continue
msg.attach(part)
# Copy attachments - FIX FILENAMES
if original_parsed.is_multipart():
for part in original_parsed.walk():
if part.get_content_maintype() == 'multipart':
continue
if part.get_content_type() in ['text/plain', 'text/html']:
continue
# Fix malformed filename in Content-Disposition
content_disp = part.get('Content-Disposition', '')
if 'filename=' in content_disp and '"' not in content_disp:
# Add quotes around filename with spaces
import re
fixed_disp = re.sub(r'filename=([^;"\s]+(?:\s+[^;"\s]+)*)', r'filename="\1"', content_disp)
part.replace_header('Content-Disposition', fixed_disp)
msg.attach(part)
return msg
return msg