diff --git a/lib/utils/email-formatter.ts b/lib/utils/email-formatter.ts index ab3b5627..2fbf2d07 100644 --- a/lib/utils/email-formatter.ts +++ b/lib/utils/email-formatter.ts @@ -25,6 +25,63 @@ DOMPurify.addHook('afterSanitizeAttributes', function(node) { } }); +// Configure DOMPurify to enforce LTR for English-only content +DOMPurify.addHook('afterSanitizeAttributes', function(node) { + // Always set direction to LTR for all elements + if (node.hasAttribute('dir')) { + node.setAttribute('dir', 'ltr'); + } + + // Ensure text alignment is left-aligned for all elements + if (node.hasAttribute('style')) { + let style = node.getAttribute('style') || ''; + + // Remove any right-to-left text alignment + if (style.includes('text-align: right') || style.includes('text-align:right')) { + style = style.replace(/text-align:\s*right\s*;?/gi, ''); + style = style.trim(); + // Add semicolon if needed + if (style && !style.endsWith(';')) { + style += ';'; + } + } + + // Add left alignment if not already specified + if (!style.includes('text-align:')) { + style += (style ? ' ' : '') + 'text-align: left;'; + } + + node.setAttribute('style', style); + } +}); + +// Clear existing hooks first +DOMPurify.removeHook('afterSanitizeAttributes'); + +// Configure DOMPurify for English-only content (always LTR) +DOMPurify.addHook('afterSanitizeAttributes', function(node) { + // Always set direction to LTR for all elements + node.setAttribute('dir', 'ltr'); + + // Ensure text alignment is left-aligned for all elements + if (node.hasAttribute('style')) { + let style = node.getAttribute('style') || ''; + + // Remove any right-to-left text alignment + if (style.includes('text-align: right') || style.includes('text-align:right')) { + style = style.replace(/text-align:\s*right\s*;?/gi, ''); + style = style.trim(); + } + + // Add left alignment + style = (style ? style + '; ' : '') + 'text-align: left;'; + node.setAttribute('style', style); + } else { + // If no style exists, add default left alignment + node.setAttribute('style', 'text-align: left;'); + } +}); + // Interface definitions export interface EmailAddress { name: string; @@ -134,26 +191,26 @@ export function formatForwardedEmail(email: EmailMessage): { // Just wrap the content in appropriate styling without adding another header const content = `
-
+
${originalContent}
`; return { subject, content }; } - // Create formatted content with explicit LTR formatting + // Create formatted content for forwarded email const content = `
-
-
-
-
---------- Forwarded message ---------
-
From: ${fromString}
-
Date: ${dateString}
-
Subject: ${email.subject || ''}
-
To: ${toString}
+
+
+
+
---------- Forwarded message ---------
+
From: ${fromString}
+
Date: ${dateString}
+
Subject: ${email.subject || ''}
+
To: ${toString}
- @@ -197,7 +254,7 @@ export function formatReplyEmail(email: EmailMessage, type: 'reply' | 'reply-all }); // Create quote header - const quoteHeader = `
On ${formattedDate}, ${fromText} wrote:
`; + const quoteHeader = `
On ${formattedDate}, ${fromText} wrote:
`; // Get and sanitize original content const quotedContent = sanitizeHtml(email.html || email.content || email.text || ''); @@ -216,13 +273,13 @@ export function formatReplyEmail(email: EmailMessage, type: 'reply' | 'reply-all cc = formatEmailAddresses(allRecipients); } - // Format content with explicit LTR for quoted parts + // Format content for reply const content = `
-
-
${quoteHeader}
-
-
+
+
${quoteHeader}
+
+
${quotedContent}