diff --git a/app/courrier/page.tsx b/app/courrier/page.tsx
index 1bf92b5c..65658a44 100644
--- a/app/courrier/page.tsx
+++ b/app/courrier/page.tsx
@@ -331,15 +331,24 @@ const initialSidebarItems = [
function getReplyBody(email: Email, type: 'reply' | 'reply-all' | 'forward'): string {
if (!email.body) return '';
- const { headers, body } = splitEmailHeadersAndBody(email.body);
- const { contentType, encoding, charset } = parseEmailHeaders(headers);
-
- let content = '';
-
- if (contentType.includes('multipart/')) {
- const boundary = contentType.match(/boundary="([^"]+)"/)?.[1];
+ try {
+ // Split email into headers and body
+ const [headersPart, ...bodyParts] = email.body.split('\r\n\r\n');
+ if (!headersPart || bodyParts.length === 0) {
+ throw new Error('Invalid email format: missing headers or body');
+ }
+
+ const body = bodyParts.join('\r\n\r\n');
+
+ // Parse headers using Infomaniak MIME decoder
+ const headerInfo = parseEmailHeaders(headersPart);
+ const boundary = extractBoundary(headersPart);
+
+ let content = '';
+
+ // If it's a multipart email
if (boundary) {
- const parts = body.split('--' + boundary).filter(part => part.trim());
+ const parts = body.split(`--${boundary}`);
// Find HTML part first, fallback to text part
const htmlPart = parts.find(part => part.toLowerCase().includes('content-type: text/html'));
@@ -347,84 +356,64 @@ function getReplyBody(email: Email, type: 'reply' | 'reply-all' | 'forward'): st
const selectedPart = htmlPart || textPart;
if (selectedPart) {
- const partHeaders = selectedPart.split('\r\n\r\n')[0];
- const partBody = selectedPart.split('\r\n\r\n').slice(1).join('\r\n\r\n');
- const { encoding: partEncoding } = parseEmailHeaders(partHeaders);
+ const [partHeaders, ...partBodyParts] = selectedPart.split('\r\n\r\n');
+ const partBody = partBodyParts.join('\r\n\r\n');
+ const partHeaderInfo = parseEmailHeaders(partHeaders);
- content = partEncoding === 'quoted-printable'
- ? decodeQuotedPrintable(partBody, charset)
+ content = partHeaderInfo.encoding === 'quoted-printable'
+ ? decodeQuotedPrintable(partBody, partHeaderInfo.charset)
: partBody;
}
+ } else {
+ content = headerInfo.encoding === 'quoted-printable'
+ ? decodeQuotedPrintable(body, headerInfo.charset)
+ : body;
}
- } else {
- content = encoding === 'quoted-printable'
- ? decodeQuotedPrintable(body, charset)
- : body;
- }
-
- // Convert plain text to HTML if needed, preserving line breaks
- if (!contentType.includes('text/html')) {
- content = content
- .split('\n')
- .map(line => {
- // Preserve empty lines
- if (!line.trim()) return '
';
- // Handle quoted text
- if (line.startsWith('>')) {
- return `
${line}
`; - } - return `${line}
`; - }) - .join(''); - } - - // Clean HTML content while preserving formatting - content = content - .replace(/