panel 2 courier api restore

This commit is contained in:
alma 2025-04-26 10:06:39 +02:00
parent fb36344577
commit 4405dcc18b
3 changed files with 58 additions and 42 deletions

View File

@ -11,7 +11,7 @@ const menuItems = {
}
export default async function SectionPage({ params }: { params: { section: string } }) {
const { section } = await Promise.resolve(params);
const { section } = params;
const iframeUrl = menuItems[section as keyof typeof menuItems]
if (!iframeUrl) {

View File

@ -39,8 +39,8 @@ export async function POST(
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
// Properly await the params object before accessing its properties
const { id: emailId } = await Promise.resolve(params);
// No need to await Promise.resolve(), params is already an object
const { id: emailId } = params;
if (!emailId) {
return NextResponse.json({ error: 'Email ID is required' }, { status: 400 });
}

View File

@ -93,6 +93,45 @@ export default function ComposeEmail({
}
}, [initialEmail, type]);
// Helper functions for formatting the forwarded message - moved outside try block
// Format date for the forwarded message header
const formatDate = (date: Date | null): string => {
if (!date) return '';
try {
return date.toLocaleString('en-US', {
weekday: 'short',
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
} catch (e) {
return date.toString();
}
};
// Format sender address in a readable format
const formatSender = (from: Array<{name?: string, address: string}> | undefined): string => {
if (!from || from.length === 0) return 'Unknown';
return from.map(sender =>
sender.name && sender.name !== sender.address
? `${sender.name} <${sender.address}>`
: sender.address
).join(', ');
};
// Format recipient addresses in a readable format
const formatRecipients = (recipients: Array<{name?: string, address: string}> | undefined): string => {
if (!recipients || recipients.length === 0) return '';
return recipients.map(recipient =>
recipient.name && recipient.name !== recipient.address
? `${recipient.name} <${recipient.address}>`
: recipient.address
).join(', ');
};
// New function to initialize forwarded email using same approach as Panel 3
const initializeForwardedEmail = async () => {
if (!initialEmail) {
@ -112,68 +151,45 @@ export default function ComposeEmail({
setSubject(formattedSubject);
// Format date for the forwarded message header
const formatDate = (date: Date | null): string => {
if (!date) return '';
try {
return date.toLocaleString('en-US', {
weekday: 'short',
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
} catch (e) {
return date.toString();
}
};
// Create a forwarded message header with proper formatting
const headerContent = `
<div style="border-bottom: 1px solid #e2e2e2; margin-bottom: 15px; padding-bottom: 15px; font-family: Arial, sans-serif; color: #333;">
<p style="margin: 5px 0; font-size: 14px;">---------- Forwarded message ---------</p>
<p style="margin: 5px 0; font-size: 14px;"><b>From:</b> ${initialEmail.from || ''}</p>
<p style="margin: 5px 0; font-size: 14px;"><b>From:</b> ${formatSender(initialEmail.from)}</p>
<p style="margin: 5px 0; font-size: 14px;"><b>Date:</b> ${formatDate(initialEmail.date)}</p>
<p style="margin: 5px 0; font-size: 14px;"><b>Subject:</b> ${initialEmail.subject || ''}</p>
<p style="margin: 5px 0; font-size: 14px;"><b>To:</b> ${initialEmail.to || ''}</p>
<p style="margin: 5px 0; font-size: 14px;"><b>To:</b> ${formatRecipients(initialEmail.to)}</p>
</div>`;
// Process content based on its type
// Use enhanced DOMPurify sanitization options similar to EmailPreview component
// This will preserve more styles and formatting from the original email
let contentBody = '';
// Check if email content exists
if (!initialEmail.content || initialEmail.content.trim() === '') {
contentBody = '<div style="color: #666; font-style: italic; margin-top: 10px;">No content available</div>';
} else if (initialEmail.content.trim().startsWith('<') && initialEmail.content.includes('</')) {
// It's probably HTML, sanitize it before using
} else {
try {
// Use DOMPurify to sanitize HTML content
// Use enhanced DOMPurify sanitization options directly from Panel 3
const sanitizedContent = DOMPurify.sanitize(initialEmail.content, {
ADD_TAGS: ['style', 'meta', 'link', 'table', 'thead', 'tbody', 'tr', 'td', 'th', 'hr', 'font', 'div', 'span', 'a', 'img', 'b', 'strong', 'i', 'em', 'u', 'br', 'p', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'pre', 'code', 'center', 'section', 'header', 'footer', 'article', 'nav'],
ADD_ATTR: ['colspan', 'rowspan', 'cellpadding', 'cellspacing', 'border', 'bgcolor', 'width', 'height', 'align', 'valign', 'class', 'style', 'color', 'face', 'size', 'background', 'src', 'href', 'target', 'rel', 'alt', 'title'],
ADD_TAGS: ['style', 'meta', 'link', 'table', 'thead', 'tbody', 'tr', 'td', 'th', 'hr', 'font', 'div', 'span', 'a', 'img', 'b', 'strong', 'i', 'em', 'u', 'br', 'p', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'pre', 'code', 'center', 'section', 'header', 'footer', 'article', 'nav', 'keyframes'],
ADD_ATTR: ['*', 'colspan', 'rowspan', 'cellpadding', 'cellspacing', 'border', 'bgcolor', 'width', 'height', 'align', 'valign', 'class', 'id', 'style', 'color', 'face', 'size', 'background', 'src', 'href', 'target', 'rel', 'alt', 'title', 'name', 'animation', 'animation-name', 'animation-duration', 'animation-fill-mode'],
ALLOW_UNKNOWN_PROTOCOLS: true,
WHOLE_DOCUMENT: false,
RETURN_DOM: false,
WHOLE_DOCUMENT: true,
KEEP_CONTENT: true,
FORBID_TAGS: ['script', 'iframe', 'object', 'embed', 'form', 'input', 'button', 'select', 'option', 'textarea', 'canvas', 'video', 'audio'],
FORBID_ATTR: ['onerror', 'onload', 'onclick', 'onmouseover', 'onmouseout', 'onchange', 'onsubmit'],
USE_PROFILES: { html: true, svg: false, svgFilters: false, mathMl: false },
FORCE_BODY: true
});
contentBody = sanitizedContent;
} catch (e) {
console.error('Error sanitizing HTML content:', e);
contentBody = '<div style="color: #666; font-style: italic; margin-top: 10px;">Error processing original content</div>';
}
} else {
// It's plain text, convert newlines to <br> tags and wrap in a div
contentBody = `<div style="font-family: Arial, sans-serif; white-space: pre-wrap;">${initialEmail.content.replace(/\n/g, '<br>')}</div>`;
}
// If content seems empty or invalid after processing, provide a fallback
if (!contentBody.trim() || contentBody.trim() === '<div></div>') {
contentBody = '<div style="color: #666; font-style: italic; margin-top: 10px;">No content available</div>';
}
// Set the complete forwarded email
// Set the complete forwarded email with enhanced preservation of styles
setBody(headerContent + contentBody);
} catch (error) {
console.error('Error initializing forwarded email:', error);
@ -181,10 +197,10 @@ export default function ComposeEmail({
const errorHeaderContent = `
<div style="border-bottom: 1px solid #e2e2e2; margin-bottom: 15px; padding-bottom: 15px; font-family: Arial, sans-serif; color: #333;">
<p style="margin: 5px 0; font-size: 14px;">---------- Forwarded message ---------</p>
<p style="margin: 5px 0; font-size: 14px;"><b>From:</b> ${initialEmail.from || ''}</p>
<p style="margin: 5px 0; font-size: 14px;"><b>Date:</b> ${formatDate(initialEmail.date)}</p>
<p style="margin: 5px 0; font-size: 14px;"><b>From:</b> ${initialEmail.from ? formatSender(initialEmail.from) : 'Unknown'}</p>
<p style="margin: 5px 0; font-size: 14px;"><b>Date:</b> ${initialEmail.date ? formatDate(initialEmail.date) : ''}</p>
<p style="margin: 5px 0; font-size: 14px;"><b>Subject:</b> ${initialEmail.subject || ''}</p>
<p style="margin: 5px 0; font-size: 14px;"><b>To:</b> ${initialEmail.to || ''}</p>
<p style="margin: 5px 0; font-size: 14px;"><b>To:</b> ${initialEmail.to ? formatRecipients(initialEmail.to) : ''}</p>
</div>
<div style="color: #ef4444; font-style: italic; margin-top: 10px;">Error loading forwarded content</div>`;
setBody(errorHeaderContent);