diff --git a/app/api/parse-email/route.ts b/app/api/parse-email/route.ts index abc18c4c..5b524c6c 100644 --- a/app/api/parse-email/route.ts +++ b/app/api/parse-email/route.ts @@ -1,27 +1,5 @@ import { NextResponse } from 'next/server'; -import { simpleParser } from 'mailparser'; -import DOMPurify from 'isomorphic-dompurify'; - -function cleanHtml(html: string): string { - try { - return DOMPurify.sanitize(html, { - ALLOWED_TAGS: ['p', 'br', 'div', 'span', 'a', 'img', 'strong', 'em', 'u', 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'], - ALLOWED_ATTR: ['href', 'src', 'alt', 'title', 'class', 'style'], - ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|tel):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i - }); - } catch (error) { - console.error('Error cleaning HTML:', error); - return html; - } -} - -function getAddressText(address: any): string | null { - if (!address) return null; - if (Array.isArray(address)) { - return address.map(addr => addr.value?.[0]?.address || '').filter(Boolean).join(', '); - } - return address.value?.[0]?.address || null; -} +import { parseEmail } from '@/lib/server/email-parser'; export async function POST(request: Request) { try { @@ -34,20 +12,8 @@ export async function POST(request: Request) { ); } - const parsed = await simpleParser(emailContent); - - return NextResponse.json({ - subject: parsed.subject || null, - from: getAddressText(parsed.from), - to: getAddressText(parsed.to), - cc: getAddressText(parsed.cc), - bcc: getAddressText(parsed.bcc), - date: parsed.date || null, - html: parsed.html ? cleanHtml(parsed.html) : null, - text: parsed.text || null, - attachments: parsed.attachments || [], - headers: Object.fromEntries(parsed.headers) - }); + const parsed = await parseEmail(emailContent); + return NextResponse.json(parsed); } catch (error) { console.error('Error parsing email:', error); return NextResponse.json( diff --git a/lib/server/email-parser.ts b/lib/server/email-parser.ts new file mode 100644 index 00000000..85b20e54 --- /dev/null +++ b/lib/server/email-parser.ts @@ -0,0 +1,45 @@ +import { simpleParser } from 'mailparser'; +import DOMPurify from 'isomorphic-dompurify'; + +function cleanHtml(html: string): string { + try { + return DOMPurify.sanitize(html, { + ALLOWED_TAGS: ['p', 'br', 'div', 'span', 'a', 'img', 'strong', 'em', 'u', 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'], + ALLOWED_ATTR: ['href', 'src', 'alt', 'title', 'class', 'style'], + ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|tel):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i + }); + } catch (error) { + console.error('Error cleaning HTML:', error); + return html; + } +} + +function getAddressText(address: any): string | null { + if (!address) return null; + if (Array.isArray(address)) { + return address.map(addr => addr.value?.[0]?.address || '').filter(Boolean).join(', '); + } + return address.value?.[0]?.address || null; +} + +export async function parseEmail(emailContent: string) { + try { + const parsed = await simpleParser(emailContent); + + return { + subject: parsed.subject || null, + from: getAddressText(parsed.from), + to: getAddressText(parsed.to), + cc: getAddressText(parsed.cc), + bcc: getAddressText(parsed.bcc), + date: parsed.date || null, + html: parsed.html ? cleanHtml(parsed.html) : null, + text: parsed.text || null, + attachments: parsed.attachments || [], + headers: Object.fromEntries(parsed.headers) + }; + } catch (error) { + console.error('Error parsing email:', error); + throw error; + } +} \ No newline at end of file diff --git a/next.config.js b/next.config.js new file mode 100644 index 00000000..93c15381 --- /dev/null +++ b/next.config.js @@ -0,0 +1,20 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + webpack: (config, { isServer }) => { + if (!isServer) { + config.resolve.fallback = { + ...config.resolve.fallback, + net: false, + tls: false, + fs: false, + dns: false, + child_process: false, + http2: false, + module: false, + }; + } + return config; + }, +}; + +module.exports = nextConfig; \ No newline at end of file