diff --git a/packages/emails/lib/sanitizeDisplayName.ts b/packages/emails/lib/sanitizeDisplayName.ts new file mode 100644 index 0000000000..04950b9b6b --- /dev/null +++ b/packages/emails/lib/sanitizeDisplayName.ts @@ -0,0 +1,16 @@ +export const sanitizeDisplayName = (nameAndEmail: string) => { + const match = nameAndEmail.match(/^(.*?)\s<(.*)>$/); + + if (match) { + const sanitizedName = sanitize(match[1]); + return `${sanitizedName} <${match[2]}>`; + } + + return nameAndEmail; +}; + +const sanitize = (name: string) => { + const charsToReplace = /[;,"<>()]/g; + + return name.replace(charsToReplace, " "); +}; diff --git a/packages/emails/templates/_base-email.ts b/packages/emails/templates/_base-email.ts index 0e432b8fcf..d5574f1e54 100644 --- a/packages/emails/templates/_base-email.ts +++ b/packages/emails/templates/_base-email.ts @@ -9,6 +9,8 @@ import { serverConfig } from "@calcom/lib/serverConfig"; import { setTestEmail } from "@calcom/lib/testEmails"; import prisma from "@calcom/prisma"; +import { sanitizeDisplayName } from "../lib/sanitizeDisplayName"; + export default class BaseEmail { name = ""; @@ -46,10 +48,21 @@ export default class BaseEmail { } const payload = await this.getNodeMailerPayload(); + + const from = "from" in payload ? (payload.from as string) : ""; + const to = "to" in payload ? (payload.to as string) : ""; + + const sanitizedFrom = sanitizeDisplayName(from); + const sanitizedTo = sanitizeDisplayName(to); + const parseSubject = z.string().safeParse(payload?.subject); const payloadWithUnEscapedSubject = { headers: this.getMailerOptions().headers, ...payload, + ...{ + from: sanitizedFrom, + to: sanitizedTo, + }, ...(parseSubject.success && { subject: decodeHTML(parseSubject.data) }), }; await new Promise((resolve, reject) => diff --git a/packages/emails/templates/disabled-app-email.ts b/packages/emails/templates/disabled-app-email.ts index 724bed66e1..cd85295448 100644 --- a/packages/emails/templates/disabled-app-email.ts +++ b/packages/emails/templates/disabled-app-email.ts @@ -1,5 +1,7 @@ import type { TFunction } from "next-i18next"; +import { APP_NAME } from "@calcom/lib/constants"; + import { renderEmail } from ".."; import BaseEmail from "./_base-email"; @@ -30,7 +32,7 @@ export default class DisabledAppEmail extends BaseEmail { protected async getNodeMailerPayload(): Promise> { return { - from: `Cal.com <${this.getMailerOptions().from}>`, + from: `${APP_NAME} <${this.getMailerOptions().from}>`, to: this.email, subject: this.title && this.eventTypeId diff --git a/packages/emails/templates/slug-replacement-email.ts b/packages/emails/templates/slug-replacement-email.ts index 2a2655718d..e7943300db 100644 --- a/packages/emails/templates/slug-replacement-email.ts +++ b/packages/emails/templates/slug-replacement-email.ts @@ -1,5 +1,7 @@ import type { TFunction } from "next-i18next"; +import { APP_NAME } from "@calcom/lib/constants"; + import { renderEmail } from ".."; import BaseEmail from "./_base-email"; @@ -21,7 +23,7 @@ export default class SlugReplacementEmail extends BaseEmail { protected async getNodeMailerPayload(): Promise> { return { - from: `Cal.com <${this.getMailerOptions().from}>`, + from: `${APP_NAME} <${this.getMailerOptions().from}>`, to: this.email, subject: this.t("email_subject_slug_replacement", { slug: this.slug }), html: await renderEmail("SlugReplacementEmail", {