courrier preview
This commit is contained in:
parent
2b02742bc4
commit
1f6032941a
@ -91,6 +91,9 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
|
||||
console.log('Setting initial content in editor', {
|
||||
length: initialContent.length,
|
||||
startsWithHtml: initialContent.trim().startsWith('<'),
|
||||
containsForwardedMessage: initialContent.includes('---------- Forwarded message ----------'),
|
||||
containsReplyIndicator: initialContent.includes('wrote:'),
|
||||
hasBlockquote: initialContent.includes('<blockquote')
|
||||
});
|
||||
|
||||
// Detect text direction
|
||||
@ -99,6 +102,18 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
|
||||
// Process HTML content using centralized utility
|
||||
const sanitizedContent = processHtmlContent(initialContent);
|
||||
|
||||
// Log sanitized content details for debugging
|
||||
console.log('Sanitized content details:', {
|
||||
length: sanitizedContent.length,
|
||||
isEmpty: sanitizedContent.trim().length === 0,
|
||||
startsWithDiv: sanitizedContent.trim().startsWith('<div'),
|
||||
containsForwardedMessage: sanitizedContent.includes('---------- Forwarded message ----------'),
|
||||
containsQuoteHeader: sanitizedContent.includes('wrote:'),
|
||||
hasTable: sanitizedContent.includes('<table'),
|
||||
hasBlockquote: sanitizedContent.includes('<blockquote'),
|
||||
firstNChars: sanitizedContent.substring(0, 100).replace(/\n/g, '\\n')
|
||||
});
|
||||
|
||||
// Check if sanitized content is valid
|
||||
if (sanitizedContent.trim().length === 0) {
|
||||
console.warn('Sanitized content is empty after processing, using fallback approach');
|
||||
@ -213,7 +228,12 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
|
||||
try {
|
||||
console.log('Updating content in editor:', {
|
||||
contentLength: initialContent.length,
|
||||
startsWithHtml: initialContent.trim().startsWith('<')
|
||||
startsWithHtml: initialContent.trim().startsWith('<'),
|
||||
containsForwardedMessage: initialContent.includes('---------- Forwarded message ----------'),
|
||||
containsQuoteHeader: initialContent.includes('wrote:'),
|
||||
hasBlockquote: initialContent.includes('<blockquote'),
|
||||
hasTable: initialContent.includes('<table'),
|
||||
firstNChars: initialContent.substring(0, 100).replace(/\n/g, '\\n')
|
||||
});
|
||||
|
||||
// Detect text direction
|
||||
@ -222,6 +242,18 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
|
||||
// Process HTML content using centralized utility
|
||||
const sanitizedContent = processHtmlContent(initialContent);
|
||||
|
||||
// Log sanitized content details for debugging
|
||||
console.log('Sanitized content details:', {
|
||||
length: sanitizedContent.length,
|
||||
isEmpty: sanitizedContent.trim().length === 0,
|
||||
startsWithDiv: sanitizedContent.trim().startsWith('<div'),
|
||||
containsForwardedMessage: sanitizedContent.includes('---------- Forwarded message ----------'),
|
||||
containsQuoteHeader: sanitizedContent.includes('wrote:'),
|
||||
hasTable: sanitizedContent.includes('<table'),
|
||||
hasBlockquote: sanitizedContent.includes('<blockquote'),
|
||||
firstNChars: sanitizedContent.substring(0, 100).replace(/\n/g, '\\n')
|
||||
});
|
||||
|
||||
// Check if content is valid HTML
|
||||
if (sanitizedContent.trim().length === 0) {
|
||||
console.warn('Sanitized content is empty, using original content');
|
||||
|
||||
@ -19,14 +19,16 @@ DOMPurify.setConfig({
|
||||
'div', 'span', 'img', 'br', 'hr', 'section', 'article', 'header', 'footer',
|
||||
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'blockquote', 'pre', 'code',
|
||||
'ul', 'ol', 'li', 'dl', 'dt', 'dd', 'a', 'b', 'i', 'u', 'em',
|
||||
'strong', 'del', 'ins', 'mark', 'small', 'sub', 'sup', 'q', 'abbr'
|
||||
'strong', 'del', 'ins', 'mark', 'small', 'sub', 'sup', 'q', 'abbr',
|
||||
'font' // Allow legacy font tag often found in emails
|
||||
],
|
||||
ADD_ATTR: [
|
||||
'style', 'class', 'id', 'name', 'href', 'src', 'alt', 'title', 'width', 'height',
|
||||
'border', 'cellspacing', 'cellpadding', 'bgcolor', 'background', 'color',
|
||||
'align', 'valign', 'dir', 'lang', 'target', 'rel', 'charset', 'media',
|
||||
'colspan', 'rowspan', 'scope', 'span', 'size', 'face', 'hspace', 'vspace',
|
||||
'data-*'
|
||||
'data-*',
|
||||
'start', 'type', 'value', 'cite', 'datetime', 'wrap', 'summary'
|
||||
],
|
||||
KEEP_CONTENT: true,
|
||||
WHOLE_DOCUMENT: false,
|
||||
@ -34,7 +36,8 @@ DOMPurify.setConfig({
|
||||
ALLOW_UNKNOWN_PROTOCOLS: true, // Needed for some email clients
|
||||
FORBID_TAGS: ['script', 'iframe', 'object', 'embed', 'form', 'input', 'button', 'select', 'textarea'],
|
||||
FORBID_ATTR: ['onerror', 'onload', 'onclick', 'onmouseover', 'onmouseout'],
|
||||
FORCE_BODY: false
|
||||
FORCE_BODY: false,
|
||||
USE_PROFILES: { html: true } // Use HTML profile for more permissive sanitization for emails
|
||||
});
|
||||
|
||||
/**
|
||||
@ -47,7 +50,9 @@ export function sanitizeHtml(html: string): string {
|
||||
|
||||
try {
|
||||
// Use DOMPurify with our central configuration
|
||||
const clean = DOMPurify.sanitize(html);
|
||||
const clean = DOMPurify.sanitize(html, {
|
||||
ADD_ATTR: ['style', 'class', 'id', 'align', 'valign', 'colspan', 'rowspan', 'cellspacing', 'cellpadding', 'bgcolor']
|
||||
});
|
||||
|
||||
// Fix common email rendering issues
|
||||
const fixedHtml = clean
|
||||
|
||||
@ -204,10 +204,24 @@ export function processHtmlContent(htmlContent: string, textContent?: string): s
|
||||
if (!htmlContent) return '';
|
||||
|
||||
try {
|
||||
console.log('processHtmlContent input:', {
|
||||
length: htmlContent.length,
|
||||
startsWithHtml: htmlContent.trim().startsWith('<html'),
|
||||
startsWithDiv: htmlContent.trim().startsWith('<div'),
|
||||
hasBody: htmlContent.includes('<body'),
|
||||
containsForwardedMessage: htmlContent.includes('---------- Forwarded message ----------'),
|
||||
containsQuoteHeader: htmlContent.includes('wrote:'),
|
||||
hasBlockquote: htmlContent.includes('<blockquote'),
|
||||
hasTable: htmlContent.includes('<table')
|
||||
});
|
||||
|
||||
// Check for browser environment (DOMParser is browser-only)
|
||||
const hasHtmlTag = htmlContent.includes('<html');
|
||||
const hasBodyTag = htmlContent.includes('<body');
|
||||
|
||||
// Preserve original HTML for debugging
|
||||
let originalHtml = htmlContent;
|
||||
|
||||
// Extract body content if we have a complete HTML document and in browser environment
|
||||
if (hasHtmlTag && hasBodyTag && typeof window !== 'undefined' && typeof DOMParser !== 'undefined') {
|
||||
try {
|
||||
@ -217,6 +231,7 @@ export function processHtmlContent(htmlContent: string, textContent?: string): s
|
||||
const bodyContent = doc.body.innerHTML;
|
||||
|
||||
if (bodyContent) {
|
||||
console.log('Extracted body content from HTML document, length:', bodyContent.length);
|
||||
htmlContent = bodyContent;
|
||||
}
|
||||
} catch (error) {
|
||||
@ -227,6 +242,16 @@ export function processHtmlContent(htmlContent: string, textContent?: string): s
|
||||
// Use the centralized sanitizeHtml function
|
||||
let sanitizedContent = sanitizeHtml(htmlContent);
|
||||
|
||||
console.log('After sanitizeHtml:', {
|
||||
originalLength: originalHtml.length,
|
||||
sanitizedLength: sanitizedContent.length,
|
||||
difference: originalHtml.length - sanitizedContent.length,
|
||||
percentRemoved: ((originalHtml.length - sanitizedContent.length) / originalHtml.length * 100).toFixed(2) + '%',
|
||||
containsForwardedMessage: sanitizedContent.includes('---------- Forwarded message ----------'),
|
||||
hasTable: sanitizedContent.includes('<table'),
|
||||
hasBlockquote: sanitizedContent.includes('<blockquote')
|
||||
});
|
||||
|
||||
// Fix URL encoding issues and clean up content
|
||||
try {
|
||||
if (typeof window !== 'undefined' && typeof document !== 'undefined') {
|
||||
|
||||
@ -456,40 +456,53 @@ export function formatForwardedEmail(originalEmail: EmailMessage | LegacyEmailMe
|
||||
// Create the forwarded email HTML content
|
||||
if (htmlContent) {
|
||||
console.log('Formatting HTML forward, original content length:', htmlContent.length);
|
||||
htmlContent = `
|
||||
|
||||
// Important: First sanitize the content portion only
|
||||
const sanitizedOriginalContent = sanitizeHtml(htmlContent);
|
||||
console.log('Sanitized original content length:', sanitizedOriginalContent.length);
|
||||
|
||||
// Create the complete forwarded email with header info
|
||||
const fullForwardedEmail = `
|
||||
<div style="margin: 20px 0 10px 0; color: #666; font-family: Arial, sans-serif;">
|
||||
---------- Forwarded message ----------<br>
|
||||
<table style="margin: 10px 0 15px 0; border-collapse: collapse; font-size: 13px; color: #333;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="padding: 3px 10px 3px 0; font-weight: bold; text-align: right; vertical-align: top;">From:</td>
|
||||
<td style="padding: 3px 0;">${fromStr}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 3px 10px 3px 0; font-weight: bold; text-align: right; vertical-align: top;">Date:</td>
|
||||
<td style="padding: 3px 0;">${date}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 3px 10px 3px 0; font-weight: bold; text-align: right; vertical-align: top;">Subject:</td>
|
||||
<td style="padding: 3px 0;">${email.subject || ''}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 3px 10px 3px 0; font-weight: bold; text-align: right; vertical-align: top;">To:</td>
|
||||
<td style="padding: 3px 0;">${toStr}</td>
|
||||
</tr>
|
||||
${ccStr ? `
|
||||
<tr>
|
||||
<td style="padding: 3px 10px 3px 0; font-weight: bold; text-align: right; vertical-align: top;">Cc:</td>
|
||||
<td style="padding: 3px 0;">${ccStr}</td>
|
||||
</tr>
|
||||
` : ''}
|
||||
<tr>
|
||||
<td style="padding: 3px 10px 3px 0; font-weight: bold; text-align: right; vertical-align: top;">From:</td>
|
||||
<td style="padding: 3px 0;">${fromStr}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 3px 10px 3px 0; font-weight: bold; text-align: right; vertical-align: top;">Date:</td>
|
||||
<td style="padding: 3px 0;">${date}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 3px 10px 3px 0; font-weight: bold; text-align: right; vertical-align: top;">Subject:</td>
|
||||
<td style="padding: 3px 0;">${email.subject || ''}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 3px 10px 3px 0; font-weight: bold; text-align: right; vertical-align: top;">To:</td>
|
||||
<td style="padding: 3px 0;">${toStr}</td>
|
||||
</tr>
|
||||
${ccStr ? `
|
||||
<tr>
|
||||
<td style="padding: 3px 10px 3px 0; font-weight: bold; text-align: right; vertical-align: top;">Cc:</td>
|
||||
<td style="padding: 3px 0;">${ccStr}</td>
|
||||
</tr>
|
||||
` : ''}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div style="padding: 10px 0; border-top: 1px solid #ddd;">
|
||||
${sanitizeHtml(htmlContent)}
|
||||
${sanitizedOriginalContent}
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Now we have the full forwarded email structure without sanitizing it again
|
||||
htmlContent = fullForwardedEmail;
|
||||
|
||||
console.log('Final forward HTML content length:', htmlContent.length,
|
||||
'contains table:', htmlContent.includes('<table'),
|
||||
'contains forwarded message:', htmlContent.includes('---------- Forwarded message ----------'));
|
||||
}
|
||||
|
||||
// Format the plain text version
|
||||
|
||||
Loading…
Reference in New Issue
Block a user