panel 2 courier api restore

This commit is contained in:
alma 2025-04-26 11:04:22 +02:00
parent 364fc80a4f
commit 6edcb636c8

View File

@ -180,6 +180,7 @@ export default function ComposeEmail({
: new Date().toLocaleString(); : new Date().toLocaleString();
// Create a clean wrapper that won't interfere with the original email's styling // 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 = ` const headerHtml = `
<div style="border-top: 1px solid #e1e1e1; margin-top: 20px; padding-top: 15px; font-family: Arial, sans-serif; color: #333;"> <div style="border-top: 1px solid #e1e1e1; margin-top: 20px; padding-top: 15px; font-family: Arial, sans-serif; color: #333;">
<div style="margin-bottom: 15px;"> <div style="margin-bottom: 15px;">
@ -192,38 +193,80 @@ export default function ComposeEmail({
</div> </div>
`; `;
// Get the content with proper fallbacks // Process the original content
let originalContent = ''; let originalContent = '';
// First try the html field which should contain the raw HTML // First try to use the API to parse and sanitize the email content
if (initialEmail.html && initialEmail.html.trim()) { try {
console.log('Using HTML content for forward'); // Use server-side parsing via fetch API to properly handle complex emails
// Preserve the HTML exactly as-is without any wrapper divs that could break styles const response = await fetch('/api/parse-email', {
originalContent = initialEmail.html; method: 'POST',
} headers: {
// Then try the content field 'Content-Type': 'application/json',
else if (initialEmail.content && initialEmail.content.trim()) { },
console.log('Using content field for forward'); body: JSON.stringify({
// Preserve the content exactly as-is email: initialEmail.content || initialEmail.html || initialEmail.text || ''
originalContent = initialEmail.content; }),
} });
// Fall back to text with styling if available
else if (initialEmail.text && initialEmail.text.trim()) { if (response.ok) {
console.log('Using text content for forward'); const parsedEmail = await response.json();
originalContent = `<div style="white-space: pre-wrap; font-family: monospace;">${initialEmail.text}</div>`;
} if (parsedEmail.html && parsedEmail.html.trim()) {
// Last resort - no content available console.log('Using parsed HTML content for forward');
else {
console.log('No content available for forward'); // Create an iframe-like containment for the email content
originalContent = '<div style="color: #666; font-style: italic; padding: 10px; font-size: 14px; border: 1px dashed #ccc; margin: 10px 0; text-align: center; background-color: #f9f9f9;">No content available</div>'; // This prevents CSS from the original email leaking into our compose view
originalContent = `
<div class="email-content-container">
${parsedEmail.html}
</div>
`;
} else if (parsedEmail.text && parsedEmail.text.trim()) {
console.log('Using parsed text content for forward');
originalContent = `<div style="white-space: pre-wrap; font-family: monospace;">${parsedEmail.text}</div>`;
} else {
console.log('No content available from parser');
originalContent = '<div style="color: #666; font-style: italic; padding: 10px; font-size: 14px; border: 1px dashed #ccc; margin: 10px 0; text-align: center; background-color: #f9f9f9;">No content available</div>';
}
} 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 = `<div style="white-space: pre-wrap; font-family: monospace;">${initialEmail.text}</div>`;
} else {
console.log('No content available for forward');
originalContent = '<div style="color: #666; font-style: italic; padding: 10px; font-size: 14px; border: 1px dashed #ccc; margin: 10px 0; text-align: center; background-color: #f9f9f9;">No content available</div>';
}
} }
// Preserve all original structure by wrapping, not modifying the original content // Preserve all original structure by wrapping, not modifying the original content
// Important: We add a style scope to prevent CSS leakage
const forwardedContent = ` const forwardedContent = `
${headerHtml} ${headerHtml}
<!-- Start original email content - DO NOT MODIFY THIS CONTENT --> <!-- Start original email content - DO NOT MODIFY THIS CONTENT -->
<div class="original-email-content" style="margin-top: 10px; border-left: 2px solid #e1e1e1; padding-left: 15px;"> <div class="original-email-content" style="margin-top: 10px; border-left: 2px solid #e1e1e1; padding-left: 15px;">
${originalContent} <!-- Email content styling isolation container -->
<div style="position: relative; overflow: auto;">
${originalContent}
</div>
</div> </div>
<!-- End original email content --> <!-- End original email content -->
`; `;
@ -234,15 +277,15 @@ export default function ComposeEmail({
} catch (error) { } catch (error) {
console.error('Error initializing forwarded email:', 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(` setBody(`
<div style="border-top: 1px solid #e1e1e1; margin-top: 20px; padding-top: 15px; font-family: Arial, sans-serif; color: #333;"> <div style="border-top: 1px solid #e1e1e1; margin-top: 20px; padding-top: 15px; font-family: Arial, sans-serif; color: #333;">
<div style="margin-bottom: 15px;"> <div style="margin-bottom: 15px;">
<div style="font-weight: normal; margin-bottom: 10px;">---------- Forwarded message ---------</div> <div style="font-weight: normal; margin-bottom: 10px;">---------- Forwarded message ---------</div>
<div><b>From:</b> ${initialEmail.from ? JSON.stringify(initialEmail.from) : 'Unknown'}</div> <div><b>From:</b> ${initialEmail.from ? formatSender(initialEmail.from) : 'Unknown'}</div>
<div><b>Date:</b> ${new Date().toLocaleString()}</div> <div><b>Date:</b> ${new Date().toLocaleString()}</div>
<div><b>Subject:</b> ${initialEmail.subject || '(No subject)'}</div> <div><b>Subject:</b> ${initialEmail.subject || '(No subject)'}</div>
<div><b>To:</b> ${initialEmail.to ? JSON.stringify(initialEmail.to) : ''}</div> <div><b>To:</b> ${initialEmail.to ? formatRecipients(initialEmail.to) : ''}</div>
</div> </div>
</div> </div>
<div style="margin-top: 10px; padding: 10px; color: #d32f2f; font-style: italic; border: 1px dashed #d32f2f; margin: 10px 0; text-align: center; background-color: #fff8f8;"> <div style="margin-top: 10px; padding: 10px; color: #d32f2f; font-style: italic; border: 1px dashed #d32f2f; margin: 10px 0; text-align: center; background-color: #fff8f8;">