diff --git a/app/courrier/page.tsx b/app/courrier/page.tsx index 322450cf..36c2a53d 100644 --- a/app/courrier/page.tsx +++ b/app/courrier/page.tsx @@ -98,115 +98,160 @@ interface ParsedEmailMetadata { } function renderEmailContent(email: Email) { - if (!email.body) return null; + if (!email.body) { + console.warn('No email body provided'); + return null; + } 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 our MIME decoder + // Parse headers using Infomaniak MIME decoder const headerInfo = parseEmailHeaders(headersPart); const boundary = extractBoundary(headersPart); // If it's a multipart email if (boundary) { - const parts = body.split(`--${boundary}`); - let htmlContent = ''; - let textContent = ''; - let attachments: { filename: string; content: string }[] = []; + try { + const parts = body.split(`--${boundary}`); + let htmlContent = ''; + let textContent = ''; + let attachments: { filename: string; content: string }[] = []; - for (const part of parts) { - if (!part.trim()) continue; - - const [partHeaders, ...partBodyParts] = part.split('\r\n\r\n'); - const partBody = partBodyParts.join('\r\n\r\n'); - const partHeaderInfo = parseEmailHeaders(partHeaders); - - if (partHeaderInfo.contentType.includes('text/html')) { - htmlContent = decodeQuotedPrintable(partBody, partHeaderInfo.charset); - } else if (partHeaderInfo.contentType.includes('text/plain')) { - textContent = decodeQuotedPrintable(partBody, partHeaderInfo.charset); - } else if (partHeaderInfo.contentType.includes('attachment')) { - attachments.push({ - filename: extractFilename(partHeaders), - content: decodeBase64(partBody, partHeaderInfo.charset) - }); + for (const part of parts) { + if (!part.trim()) continue; + + const [partHeaders, ...partBodyParts] = part.split('\r\n\r\n'); + if (!partHeaders || partBodyParts.length === 0) continue; + + const partBody = partBodyParts.join('\r\n\r\n'); + const partHeaderInfo = parseEmailHeaders(partHeaders); + const contentType = extractHeader(partHeaders, 'Content-Type').toLowerCase(); + const encoding = extractHeader(partHeaders, 'Content-Transfer-Encoding').toLowerCase(); + const charset = extractHeader(partHeaders, 'charset') || 'utf-8'; + + try { + if (contentType.includes('text/html')) { + const decodedContent = encoding === 'base64' + ? decodeBase64(partBody, charset) + : decodeQuotedPrintable(partBody, charset); + htmlContent = cleanHtml(decodedContent); + } else if (contentType.includes('text/plain')) { + const decodedContent = encoding === 'base64' + ? decodeBase64(partBody, charset) + : decodeQuotedPrintable(partBody, charset); + textContent = decodedContent; + } else if (contentType.includes('attachment') || extractHeader(partHeaders, 'Content-Disposition').includes('attachment')) { + attachments.push({ + filename: extractFilename(partHeaders) || 'unnamed_attachment', + content: encoding === 'base64' + ? decodeBase64(partBody, charset) + : decodeQuotedPrintable(partBody, charset) + }); + } + } catch (partError) { + console.error('Error processing email part:', partError); + continue; + } } - } - // Prefer HTML content if available - if (htmlContent) { - return ( -
{line}
- ))} + // Prefer HTML content if available + if (htmlContent) { + return ( +{line}
+ ))}{line}
- ))} -{line}
+ ))} +{email.body}
+
+ {email.body}
+