From 6edcb636c8b6001f23a8a068c080f1fbfbb2d4a6 Mon Sep 17 00:00:00 2001 From: alma Date: Sat, 26 Apr 2025 11:04:22 +0200 Subject: [PATCH] panel 2 courier api restore --- components/email/ComposeEmail.tsx | 95 ++++++++++++++++++++++--------- 1 file changed, 69 insertions(+), 26 deletions(-) diff --git a/components/email/ComposeEmail.tsx b/components/email/ComposeEmail.tsx index 368c0a31..dbc4bdd0 100644 --- a/components/email/ComposeEmail.tsx +++ b/components/email/ComposeEmail.tsx @@ -180,6 +180,7 @@ export default function ComposeEmail({ : new Date().toLocaleString(); // Create a clean wrapper that won't interfere with the original email's styling + // Use inline styles for the header to avoid CSS conflicts const headerHtml = `
@@ -192,38 +193,80 @@ export default function ComposeEmail({
`; - // Get the content with proper fallbacks + // Process the original content let originalContent = ''; - // First try the html field which should contain the raw HTML - if (initialEmail.html && initialEmail.html.trim()) { - console.log('Using HTML content for forward'); - // Preserve the HTML exactly as-is without any wrapper divs that could break styles - originalContent = initialEmail.html; - } - // Then try the content field - else if (initialEmail.content && initialEmail.content.trim()) { - console.log('Using content field for forward'); - // Preserve the content exactly as-is - originalContent = initialEmail.content; - } - // Fall back to text with styling if available - else if (initialEmail.text && initialEmail.text.trim()) { - console.log('Using text content for forward'); - originalContent = `
${initialEmail.text}
`; - } - // Last resort - no content available - else { - console.log('No content available for forward'); - originalContent = '
No content available
'; + // First try to use the API to parse and sanitize the email content + try { + // Use server-side parsing via fetch API to properly handle complex emails + const response = await fetch('/api/parse-email', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + email: initialEmail.content || initialEmail.html || initialEmail.text || '' + }), + }); + + if (response.ok) { + const parsedEmail = await response.json(); + + if (parsedEmail.html && parsedEmail.html.trim()) { + console.log('Using parsed HTML content for forward'); + + // Create an iframe-like containment for the email content + // This prevents CSS from the original email leaking into our compose view + originalContent = ` + + `; + } else if (parsedEmail.text && parsedEmail.text.trim()) { + console.log('Using parsed text content for forward'); + originalContent = `
${parsedEmail.text}
`; + } else { + console.log('No content available from parser'); + originalContent = '
No content available
'; + } + } else { + throw new Error('Failed to parse email content'); + } + } catch (parseError) { + console.error('Error parsing email content:', parseError); + + // Fall back to direct content handling if API parsing fails + if (initialEmail.html && initialEmail.html.trim()) { + console.log('Falling back to HTML content for forward'); + // Use DOMPurify to sanitize HTML and remove dangerous elements + originalContent = DOMPurify.sanitize(initialEmail.html, { + ADD_TAGS: ['style', 'div', 'span', 'p', 'br', 'hr', 'h1', 'h2', 'h3', 'img', 'table', 'tr', 'td', 'th'], + ADD_ATTR: ['style', 'class', 'id', 'src', 'alt', 'href', 'target'], + FORBID_TAGS: ['script', 'iframe', 'object', 'embed'], + FORBID_ATTR: ['onerror', 'onload', 'onclick', 'onmouseover'] + }); + } else if (initialEmail.content && initialEmail.content.trim()) { + console.log('Falling back to content field for forward'); + originalContent = DOMPurify.sanitize(initialEmail.content); + } else if (initialEmail.text && initialEmail.text.trim()) { + console.log('Falling back to text content for forward'); + originalContent = `
${initialEmail.text}
`; + } else { + console.log('No content available for forward'); + originalContent = '
No content available
'; + } } // Preserve all original structure by wrapping, not modifying the original content + // Important: We add a style scope to prevent CSS leakage const forwardedContent = ` ${headerHtml} `; @@ -234,15 +277,15 @@ export default function ComposeEmail({ } catch (error) { console.error('Error initializing forwarded email:', error); - // Even in error case, provide a usable template + // Even in error case, provide a usable template with empty values setBody(`
---------- Forwarded message ---------
-
From: ${initialEmail.from ? JSON.stringify(initialEmail.from) : 'Unknown'}
+
From: ${initialEmail.from ? formatSender(initialEmail.from) : 'Unknown'}
Date: ${new Date().toLocaleString()}
Subject: ${initialEmail.subject || '(No subject)'}
-
To: ${initialEmail.to ? JSON.stringify(initialEmail.to) : ''}
+
To: ${initialEmail.to ? formatRecipients(initialEmail.to) : ''}