From 4d96b4a52e0aac1032efc0cf951139839301e5b9 Mon Sep 17 00:00:00 2001 From: kevinkim-ogp Date: Thu, 19 Dec 2024 14:29:45 +0800 Subject: [PATCH] PLU-388: Postman Max 50 recipients (#825) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Problem Postman limits each email to have a maximum of 50 recipients (including the primary recipient, CC recipients, and BCC recipients), but Plumber does not implement this check. ## Solution * Add validation on the list of CC recipient emails **Improvements**: - Add validation on the list of CC recipient emails and throw error before attempting to call the Postman API. ## Before & After Screenshots **BEFORE**: NA **AFTER**: Screenshot 2024-12-18 at 5 30 00 PM ## Tests - [x] Existing emails can be sent correctly - [x] Step error thrown when more than 49 recipients included in the CC field --- .../__tests__/common/parameters.test.ts | 22 +++++++++++++++++++ .../src/apps/postman/common/parameters.ts | 8 +++++++ 2 files changed, 30 insertions(+) diff --git a/packages/backend/src/apps/postman/__tests__/common/parameters.test.ts b/packages/backend/src/apps/postman/__tests__/common/parameters.test.ts index 0158e214d..cab5374cd 100644 --- a/packages/backend/src/apps/postman/__tests__/common/parameters.test.ts +++ b/packages/backend/src/apps/postman/__tests__/common/parameters.test.ts @@ -2,6 +2,10 @@ import { assert, beforeEach, describe, expect, it } from 'vitest' import { transactionalEmailSchema } from '../../common/parameters' +function generateEmails(length: number) { + return Array.from({ length }, (_, i) => `user${i + 1}@example.com`).join(',') +} + describe('postman transactional email schema zod validation', () => { let validPayload: Record @@ -155,4 +159,22 @@ describe('postman transactional email schema zod validation', () => { expect(result.error?.errors[0].message).toEqual('Invalid CC emails') }, ) + + it.each([ + { recipient: 10, cc: 50 }, + { recipient: 41, cc: 51 }, + { recipient: 50, cc: 52 }, + { recipient: 1, cc: 50 }, + ])( + 'should fail if total number of emails in Recipient email(s) and CC recipient email(s) exceeds 50', + ({ recipient, cc }) => { + validPayload.destinationEmail = generateEmails(recipient) + validPayload.destinationEmailCc = generateEmails(cc) + const result = transactionalEmailSchema.safeParse(validPayload) + assert(result.success === false) + expect(result.error?.errors[0].message).toEqual( + 'The total number of CC recipient emails must not exceed 49', + ) + }, + ) }) diff --git a/packages/backend/src/apps/postman/common/parameters.ts b/packages/backend/src/apps/postman/common/parameters.ts index 78b99d8ed..d6b6aa19e 100644 --- a/packages/backend/src/apps/postman/common/parameters.ts +++ b/packages/backend/src/apps/postman/common/parameters.ts @@ -102,6 +102,14 @@ export const transactionalEmailSchema = z.object({ destinationEmailCc: z .string() .transform((value, ctx) => validateEmails(value, ctx, 'Invalid CC emails')) + /** + * NOTE: Postman limits a maximum of 50 recipients (including primary recipient and CC recipients) + * Currently, Plumber sends emails to the main recipient individually, + * hence a limit of 49 CC recipients is enforced. + */ + .refine((value) => value.length <= 49, { + message: 'The total number of CC recipient emails must not exceed 49', + }) .optional(), replyTo: z.preprocess((value) => { if (typeof value !== 'string') {