Skip to content

Commit f2506a2

Browse files
authored
chore: change postman credentials (#812)
## Problem Right now, email is sent from `[email protected]` but we want to change it to `[email protected]` ## Solution Introduce a flag on LD to toggle between the old and new credentials - Turn on to use new credentials - This is in case the new credentials don't work, can easily use back the old credentials Created a new group email: [email protected], and ensured that two API keys are created for staging and prod respectively, with the rate limit of 250 applied to the user. ## TODO - [x] Add to parameter store for staging and prod ## Tests - [x] Check that email can be sent through test step - [x] Check that OTP email can be sent - [x] Check that blacklist and error emails can be sent **New environment variables**: - `POSTMAN_OLD_FROM_ADDRESS` : [email protected] (this is the old from address) - `POSTMAN_OLD_API_KEY`: for staging and prod
1 parent 0d63f5e commit f2506a2

File tree

6 files changed

+58
-6
lines changed

6 files changed

+58
-6
lines changed

ecs/env.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@
3434
},
3535
{
3636
"name": "POSTMAN_FROM_ADDRESS",
37+
"value": "[email protected]"
38+
},
39+
{
40+
"name": "POSTMAN_OLD_FROM_ADDRESS",
3741
"value": "[email protected]"
3842
},
3943
{
@@ -110,6 +114,10 @@
110114
"name": "POSTMAN_API_KEY",
111115
"valueFrom": "plumber-<ENVIRONMENT>-postman-api-key"
112116
},
117+
{
118+
"name": "POSTMAN_OLD_API_KEY",
119+
"valueFrom": "plumber-<ENVIRONMENT>-postman-old-api-key"
120+
},
113121
{
114122
"name": "FORMSG_API_KEY",
115123
"valueFrom": "plumber-formsg-api-key"

packages/backend/.env-example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ REDIS_CLUSTER_MODE=false
2020
ENABLE_BULLMQ_DASHBOARD=false
2121
2222
POSTMAN_API_KEY=api_key
23+
POSTMAN_OLD_API_KEY=api_key
2324
FORMSG_API_KEY=sample-formsg-api-key
2425
FORMSG_STAGING_API_KEY=sample-formsg-api-key
2526
FORMSG_UAT_API_KEY=sample-formsg-api-key

packages/backend/src/apps/postman/__tests__/actions/send-transactional-email.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const mocks = vi.hoisted(() => ({
1414
getObjectFromS3Id: vi.fn(),
1515
getDefaultReplyTo: vi.fn(() => '[email protected]'),
1616
sendBlacklistEmail: vi.fn(),
17+
getLdFlagValue: vi.fn(),
1718
}))
1819

1920
vi.mock('@/helpers/s3', async () => {
@@ -36,6 +37,10 @@ vi.mock('../../common/send-blacklist-email', () => ({
3637
createRequestBlacklistFormLink: vi.fn(),
3738
}))
3839

40+
vi.mock('@/helpers/launch-darkly', () => ({
41+
getLdFlagValue: mocks.getLdFlagValue,
42+
}))
43+
3944
describe('send transactional email', () => {
4045
let $: IGlobalVariable
4146

packages/backend/src/apps/postman/common/email-helper.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { sortBy } from 'lodash'
55

66
import appConfig from '@/config/app'
77
import HttpError from '@/errors/http'
8+
import { getLdFlagValue } from '@/helpers/launch-darkly'
89

910
import {
1011
PostmanEmailDataOut,
@@ -79,14 +80,24 @@ export async function sendTransactionalEmails(
7980
errorStatus?: PostmanEmailSendStatus
8081
error?: HttpError
8182
}> {
83+
const shouldUseNewCredentials = await getLdFlagValue<boolean>(
84+
'new_postman_credentials',
85+
'[email protected]', // mock email
86+
false,
87+
)
88+
8289
const promises = recipients.map(async (recipientEmail) => {
8390
const requestData = new FormData()
8491
requestData.append('subject', email.subject)
8592
requestData.append('body', email.body)
8693
requestData.append('recipient', recipientEmail)
8794
requestData.append(
8895
'from',
89-
`${email.senderName} <${appConfig.postman.fromAddress}>`,
96+
`${email.senderName} <${
97+
shouldUseNewCredentials
98+
? appConfig.postman.fromAddress
99+
: appConfig.postman.oldFromAddress
100+
}>`,
90101
)
91102
requestData.append('disable_tracking', 'true')
92103
if (email.ccList?.length > 0) {
@@ -112,7 +123,11 @@ export async function sendTransactionalEmails(
112123
{
113124
headers: {
114125
...requestData.getHeaders(),
115-
Authorization: `Bearer ${appConfig.postman.apiKey}`,
126+
Authorization: `Bearer ${
127+
shouldUseNewCredentials
128+
? appConfig.postman.apiKey
129+
: appConfig.postman.oldApiKey
130+
}`,
116131
},
117132
},
118133
)

packages/backend/src/config/app.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ type AppConfig = {
3636
apiKey: string
3737
fromAddress: string
3838
rateLimit: number
39+
oldApiKey: string
40+
oldFromAddress: string
3941
}
4042
isWorker: boolean
4143
workerActionConcurrency: number
@@ -100,9 +102,11 @@ const appConfig: AppConfig = {
100102
},
101103
postman: {
102104
apiKey: process.env.POSTMAN_API_KEY,
103-
fromAddress:
104-
process.env.POSTMAN_FROM_ADDRESS || '[email protected]',
105+
fromAddress: process.env.POSTMAN_FROM_ADDRESS || '[email protected]',
105106
rateLimit: parseInt(process.env.POSTMAN_RATE_LIMIT) || 169,
107+
oldApiKey: process.env.POSTMAN_OLD_API_KEY,
108+
oldFromAddress:
109+
process.env.POSTMAN_OLD_FROM_ADDRESS || '[email protected]',
106110
},
107111
launchDarklySdkKey: process.env.LAUNCH_DARKLY_SDK_KEY,
108112
maxJobAttempts: Number(process.env.MAX_JOB_ATTEMPTS ?? '10'),
@@ -124,6 +128,10 @@ if (!appConfig.postman.apiKey) {
124128
throw new Error('POSTMAN_API_KEY environment variable needs to be set!')
125129
}
126130

131+
if (!appConfig.postman.oldApiKey) {
132+
throw new Error('POSTMAN_OLD_API_KEY environment variable needs to be set!')
133+
}
134+
127135
if (
128136
!appConfig.sgid ||
129137
!appConfig.sgid.clientId ||

packages/backend/src/helpers/send-email.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import axios from 'axios'
33
import appConfig from '@/config/app'
44
import HttpError from '@/errors/http'
55

6+
import { getLdFlagValue } from './launch-darkly'
67
import logger from './logger'
78

89
export interface PostmanEmailRequestBody {
@@ -19,20 +20,34 @@ export async function sendEmail({
1920
replyTo,
2021
}: PostmanEmailRequestBody): Promise<void> {
2122
try {
23+
const shouldUseNewCredentials = await getLdFlagValue<boolean>(
24+
'new_postman_credentials',
25+
'[email protected]', // mock email
26+
false,
27+
)
28+
2229
await axios.post(
2330
'https://api.postman.gov.sg/v1/transactional/email/send',
2431
{
2532
subject,
2633
body,
2734
recipient,
28-
from: `Plumber <${appConfig.postman.fromAddress}>`,
35+
from: `Plumber <${
36+
shouldUseNewCredentials
37+
? appConfig.postman.fromAddress
38+
: appConfig.postman.oldFromAddress
39+
}>`,
2940
...(replyTo && { reply_to: replyTo }),
3041
disable_tracking: true,
3142
},
3243
{
3344
headers: {
3445
'Content-Type': 'application/json',
35-
Authorization: `Bearer ${appConfig.postman.apiKey}`,
46+
Authorization: `Bearer ${
47+
shouldUseNewCredentials
48+
? appConfig.postman.apiKey
49+
: appConfig.postman.oldApiKey
50+
}`,
3651
},
3752
},
3853
)

0 commit comments

Comments
 (0)