diff --git a/src/index.ts b/src/index.ts index 468c39b..1e66584 100644 --- a/src/index.ts +++ b/src/index.ts @@ -26,6 +26,8 @@ export { processEmails, retryFailedEmails, parseAndValidateEmails, + sanitizeDisplayName, + sanitizeFromName, } from './utils/helpers.js' // Email processing utilities diff --git a/src/sendEmail.ts b/src/sendEmail.ts index 881759d..e31e83d 100644 --- a/src/sendEmail.ts +++ b/src/sendEmail.ts @@ -1,5 +1,5 @@ import { Payload } from 'payload' -import { getMailing, renderTemplate, parseAndValidateEmails } from './utils/helpers.js' +import { getMailing, renderTemplate, parseAndValidateEmails, sanitizeFromName } from './utils/helpers.js' import { BaseEmailDocument } from './types/index.js' import { processJobById } from './utils/emailProcessor.js' @@ -104,15 +104,7 @@ export const sendEmail = async { + if (!displayName) return displayName + + let sanitized = displayName + .trim() + // Remove/replace newlines and carriage returns to prevent header injection + .replace(/[\r\n]/g, ' ') + // Remove control characters (except space and printable characters) + .replace(/[\x00-\x1F\x7F-\x9F]/g, '') + + // Escape quotes if needed (for email headers) + if (escapeQuotes) { + sanitized = sanitized.replace(/"/g, '\\"') + } + + return sanitized +} + +/** + * Sanitize and validate fromName for emails + * Wrapper around sanitizeDisplayName for consistent fromName handling + * @param fromName - The fromName to sanitize + * @returns Sanitized fromName or undefined if empty after sanitization + */ +export const sanitizeFromName = (fromName: string | null | undefined): string | undefined => { + if (!fromName) return undefined + + const sanitized = sanitizeDisplayName(fromName, false) + return sanitized.length > 0 ? sanitized : undefined +} + export const getMailing = (payload: Payload) => { const mailing = (payload as any).mailing if (!mailing) {