diff --git a/app/api/parse-email/route.ts b/app/api/parse-email/route.ts index 1db100fc..abc18c4c 100644 --- a/app/api/parse-email/route.ts +++ b/app/api/parse-email/route.ts @@ -1,15 +1,10 @@ import { NextResponse } from 'next/server'; import { simpleParser } from 'mailparser'; -import DOMPurify from 'dompurify'; -import { JSDOM } from 'jsdom'; - -// Create a window object for DOMPurify -const window = new JSDOM('').window; -const purify = DOMPurify(window); +import DOMPurify from 'isomorphic-dompurify'; function cleanHtml(html: string): string { try { - return purify.sanitize(html, { + 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 @@ -20,6 +15,14 @@ function cleanHtml(html: string): string { } } +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 POST(request: Request) { try { const { emailContent } = await request.json(); @@ -35,10 +38,10 @@ export async function POST(request: Request) { return NextResponse.json({ subject: parsed.subject || null, - from: parsed.from?.text || null, - to: parsed.to?.text || null, - cc: parsed.cc?.text || null, - bcc: parsed.bcc?.text || 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, diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json index c3bda15c..7146163c 100644 --- a/node_modules/.package-lock.json +++ b/node_modules/.package-lock.json @@ -3812,13 +3812,13 @@ "dev": true }, "node_modules/isomorphic-dompurify": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/isomorphic-dompurify/-/isomorphic-dompurify-2.23.0.tgz", - "integrity": "sha512-f9w5fPJwlu+VK1uowFy4eWYgd7uxl0nQJbtorGp1OAs6JeY1qPkBQKNee1RXrnr68GqZ86PwQ6LF/5rW1TrOZQ==", + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/isomorphic-dompurify/-/isomorphic-dompurify-2.24.0.tgz", + "integrity": "sha512-SgKoDBCQveodymGMBPpzs9MOTCk4Luq0bTfwoPrUKa7q0FnCLZMtqR25Rnq228zJfMTsX1ZItiJbDtjb2lyv4A==", "license": "MIT", "dependencies": { "dompurify": "^3.2.5", - "jsdom": "^26.0.0" + "jsdom": "^26.1.0" }, "engines": { "node": ">=18" diff --git a/node_modules/isomorphic-dompurify/package.json b/node_modules/isomorphic-dompurify/package.json index 4512b450..d321547e 100644 --- a/node_modules/isomorphic-dompurify/package.json +++ b/node_modules/isomorphic-dompurify/package.json @@ -1,6 +1,6 @@ { "name": "isomorphic-dompurify", - "version": "2.23.0", + "version": "2.24.0", "description": "Makes it possible to use DOMPurify on server and client in the same way.", "keywords": [ "security", @@ -31,11 +31,11 @@ "types": "index.d.ts", "dependencies": { "dompurify": "^3.2.5", - "jsdom": "^26.0.0" + "jsdom": "^26.1.0" }, "devDependencies": { "terser": "^5.39.0", - "vitest": "^3.1.1" + "vitest": "^3.1.2" }, "engines": { "node": ">=18" diff --git a/package-lock.json b/package-lock.json index b97bfe49..3622f6be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -59,7 +59,7 @@ "imap": "^0.8.19", "imapflow": "^1.0.184", "input-otp": "1.4.1", - "isomorphic-dompurify": "^2.23.0", + "isomorphic-dompurify": "^2.24.0", "jwt-decode": "^4.0.0", "libmime": "^5.3.6", "lucide-react": "^0.454.0", @@ -4440,13 +4440,13 @@ "dev": true }, "node_modules/isomorphic-dompurify": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/isomorphic-dompurify/-/isomorphic-dompurify-2.23.0.tgz", - "integrity": "sha512-f9w5fPJwlu+VK1uowFy4eWYgd7uxl0nQJbtorGp1OAs6JeY1qPkBQKNee1RXrnr68GqZ86PwQ6LF/5rW1TrOZQ==", + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/isomorphic-dompurify/-/isomorphic-dompurify-2.24.0.tgz", + "integrity": "sha512-SgKoDBCQveodymGMBPpzs9MOTCk4Luq0bTfwoPrUKa7q0FnCLZMtqR25Rnq228zJfMTsX1ZItiJbDtjb2lyv4A==", "license": "MIT", "dependencies": { "dompurify": "^3.2.5", - "jsdom": "^26.0.0" + "jsdom": "^26.1.0" }, "engines": { "node": ">=18" diff --git a/package.json b/package.json index f06ccb09..08aba9c8 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "imap": "^0.8.19", "imapflow": "^1.0.184", "input-otp": "1.4.1", - "isomorphic-dompurify": "^2.23.0", + "isomorphic-dompurify": "^2.24.0", "jwt-decode": "^4.0.0", "libmime": "^5.3.6", "lucide-react": "^0.454.0", diff --git a/yarn.lock b/yarn.lock index 5be071e3..8ad4c084 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1961,13 +1961,13 @@ isexe@^2.0.0: resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -isomorphic-dompurify@^2.23.0: - version "2.23.0" - resolved "https://registry.npmjs.org/isomorphic-dompurify/-/isomorphic-dompurify-2.23.0.tgz" - integrity sha512-f9w5fPJwlu+VK1uowFy4eWYgd7uxl0nQJbtorGp1OAs6JeY1qPkBQKNee1RXrnr68GqZ86PwQ6LF/5rW1TrOZQ== +isomorphic-dompurify@^2.24.0: + version "2.24.0" + resolved "https://registry.npmjs.org/isomorphic-dompurify/-/isomorphic-dompurify-2.24.0.tgz" + integrity sha512-SgKoDBCQveodymGMBPpzs9MOTCk4Luq0bTfwoPrUKa7q0FnCLZMtqR25Rnq228zJfMTsX1ZItiJbDtjb2lyv4A== dependencies: dompurify "^3.2.5" - jsdom "^26.0.0" + jsdom "^26.1.0" jackspeak@^3.1.2: version "3.4.3" @@ -1998,7 +1998,7 @@ jsbn@1.1.0: resolved "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz" integrity sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A== -jsdom@^26.0.0: +jsdom@^26.1.0: version "26.1.0" resolved "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz" integrity sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==