From dcf230aa5760545a547c0feae05d5044f0257077 Mon Sep 17 00:00:00 2001 From: limes Date: Sat, 15 Nov 2025 21:19:13 +0100 Subject: [PATCH] fix(mailer): escape pnid --- package-lock.json | 18 ++++++++++++++++++ package.json | 4 +++- src/mailer.ts | 7 +++++-- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4fa9eb6..3b598d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "fs-extra": "^8.1.0", "got": "^11.8.2", "hcaptcha": "^0.1.0", + "he": "^1.2.0", "image-pixels": "^1.1.1", "ip2location-nodejs": "^9.6.3", "is-valid-hostname": "^1.0.2", @@ -58,6 +59,7 @@ "@types/dicer": "^0.2.2", "@types/express": "^4.17.17", "@types/fs-extra": "^11.0.1", + "@types/he": "^1.2.3", "@types/morgan": "^1.9.4", "@types/ndarray": "^1.0.11", "@types/node": "^18.14.4", @@ -3345,6 +3347,13 @@ "@types/node": "*" } }, + "node_modules/@types/he": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/he/-/he-1.2.3.tgz", + "integrity": "sha512-q67/qwlxblDzEDvzHhVkwc1gzVWxaNxeyHUBF4xElrvjL11O+Ytze+1fGpBHlr/H9myiBUaUXNnNPmBHxxfAcA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/http-cache-semantics": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", @@ -7122,6 +7131,15 @@ "integrity": "sha512-iMrDmH2VpIEKOrcKWidVjI89FdDKTEdZ7PfPWkP27sTazIIkob8YfdY2ezaufAnWBiUUcvzsn0qF+dyXtBH2Vw==", "license": "MIT" }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, "node_modules/http-cache-semantics": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", diff --git a/package.json b/package.json index 7d0c32b..8e844b4 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "fs-extra": "^8.1.0", "got": "^11.8.2", "hcaptcha": "^0.1.0", + "he": "^1.2.0", "image-pixels": "^1.1.1", "ip2location-nodejs": "^9.6.3", "is-valid-hostname": "^1.0.2", @@ -74,6 +75,7 @@ "@types/dicer": "^0.2.2", "@types/express": "^4.17.17", "@types/fs-extra": "^11.0.1", + "@types/he": "^1.2.3", "@types/morgan": "^1.9.4", "@types/ndarray": "^1.0.11", "@types/node": "^18.14.4", @@ -88,4 +90,4 @@ "ndarray": "^1.0.19", "typescript": "^4.9.5" } -} \ No newline at end of file +} diff --git a/src/mailer.ts b/src/mailer.ts index 68d1646..61cedc4 100644 --- a/src/mailer.ts +++ b/src/mailer.ts @@ -2,6 +2,7 @@ import path from 'node:path'; import fs from 'node:fs'; import nodemailer from 'nodemailer'; import * as aws from '@aws-sdk/client-ses'; +import { encode } from 'he'; import { config, disabledFeatures } from '@/config-manager'; import type { MailerOptions } from '@/types/common/mailer-options'; @@ -105,11 +106,13 @@ export class CreateEmail { // for now only replaces the pnid for shoutouts. could easily be expanded to add more. if (c?.replacements) { Object.entries(c.replacements).forEach(([key, value]) => { + const safeValue = encode(value); + if (key === 'pnid') { if (plainText) { - tempText = tempText.replace(/{{pnid}}/g, value); + tempText = tempText.replace(/{{pnid}}/g, safeValue); } else { - tempText = tempText.replace(/{{pnid}}/g, `${value}`); + tempText = tempText.replace(/{{pnid}}/g, `${safeValue}`); } } });