feat: add sanitize-html for improved email content sanitization
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
"mailparser": "^3.9.8",
|
||||
"morgan": "^1.10.0",
|
||||
"multer": "^2.1.1",
|
||||
"sanitize-html": "^2.17.3",
|
||||
"signale": "^1.4.0",
|
||||
"stripe": "^20.0.0"
|
||||
},
|
||||
@@ -52,6 +53,7 @@
|
||||
"@types/mailparser": "^3.4.6",
|
||||
"@types/morgan": "^1.9.9",
|
||||
"@types/multer": "^2.0.0",
|
||||
"@types/sanitize-html": "^2.16.1",
|
||||
"@types/signale": "^1.4.7",
|
||||
"concurrently": "^9.2.1",
|
||||
"tsx": "^4.20.6"
|
||||
|
||||
@@ -3,6 +3,7 @@ import type {Prisma} from '@plunk/db';
|
||||
import {EmailSourceType, EmailStatus} from '@plunk/db';
|
||||
import type {Request, Response} from 'express';
|
||||
import {simpleParser} from 'mailparser';
|
||||
import sanitizeHtml from 'sanitize-html';
|
||||
import signale from 'signale';
|
||||
import type Stripe from 'stripe';
|
||||
|
||||
@@ -157,19 +158,31 @@ export class Webhooks {
|
||||
// Parse email content if available
|
||||
let htmlBody: string | undefined;
|
||||
|
||||
if (body.content) {
|
||||
if (body.content && typeof body.content === 'string') {
|
||||
try {
|
||||
const isBase64 = body.receipt?.action?.encoding === 'BASE64';
|
||||
const emailBuffer = isBase64
|
||||
? Buffer.from(body.content as string, 'base64')
|
||||
: Buffer.from(body.content as string);
|
||||
? Buffer.from(body.content, 'base64')
|
||||
: Buffer.from(body.content);
|
||||
|
||||
const parsed = await simpleParser(emailBuffer);
|
||||
htmlBody =
|
||||
const raw =
|
||||
(parsed.html ? String(parsed.html) : undefined) ??
|
||||
parsed.textAsHtml ??
|
||||
parsed.text ??
|
||||
undefined;
|
||||
|
||||
if (raw) {
|
||||
htmlBody = sanitizeHtml(raw, {
|
||||
allowedTags: sanitizeHtml.defaults.allowedTags.concat(['img']),
|
||||
allowedAttributes: {
|
||||
...sanitizeHtml.defaults.allowedAttributes,
|
||||
img: ['src', 'alt', 'width', 'height'],
|
||||
'*': ['style'],
|
||||
},
|
||||
allowedSchemes: ['http', 'https', 'mailto'],
|
||||
});
|
||||
}
|
||||
} catch (parseError) {
|
||||
signale.error('[WEBHOOK] Failed to parse email content:', parseError);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user