Skip to content

Commit aeaf6d9

Browse files
author
Niranjan Jayakar
committed
fix(cognito): user pool - link style email verification fails to deploy
A couple of things happen with this change - - `emailVerificationMessage`, `emailVerificationSubject` and `smsVerificationMessage` properties are not set when link-style verification is used. This is root cause for the error message reported by the user. - The defaults `emailBody` and `emailSubject` are modified when link-style verification is used. They will now correctly contian the template placeholder '{##Verify Email##}'. fixes #6811
1 parent 4501b8b commit aeaf6d9

File tree

2 files changed

+114
-24
lines changed

2 files changed

+114
-24
lines changed

packages/@aws-cdk/aws-cognito/lib/user-pool.ts

+51-20
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,9 @@ export interface UserVerificationConfig {
144144
* The email body template for the verification email sent to the user upon sign up.
145145
* See https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-settings-message-templates.html to
146146
* learn more about message templates.
147-
* @default 'Hello {username}, Your verification code is {####}'
147+
*
148+
* @default - 'Hello {username}, Your verification code is {####}' if VerificationEmailStyle.CODE is chosen,
149+
* 'Hello {username}, Verify your account by clicking on {##Verify Email##}' if VerificationEmailStyle.LINK is chosen.
148150
*/
149151
readonly emailBody?: string;
150152

@@ -159,7 +161,9 @@ export interface UserVerificationConfig {
159161
* The message template for the verification SMS sent to the user upon sign up.
160162
* See https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-settings-message-templates.html to
161163
* learn more about message templates.
162-
* @default 'The verification code to your new account is {####}'
164+
*
165+
* @default - 'The verification code to your new account is {####}' if VerificationEmailStyle.CODE is chosen,
166+
* not configured if VerificationEmailStyle.LINK is chosen
163167
*/
164168
readonly smsMessage?: string;
165169
}
@@ -486,24 +490,15 @@ export class UserPool extends Resource implements IUserPool {
486490
}
487491
}
488492

489-
const emailVerificationSubject = props.userVerification?.emailSubject ?? 'Verify your new account';
490-
const emailVerificationMessage = props.userVerification?.emailBody ?? 'Hello {username}, Your verification code is {####}';
491-
const smsVerificationMessage = props.userVerification?.smsMessage ?? 'The verification code to your new account is {####}';
492-
493-
const defaultEmailOption = props.userVerification?.emailStyle ?? VerificationEmailStyle.CODE;
494-
const verificationMessageTemplate: CfnUserPool.VerificationMessageTemplateProperty =
495-
(defaultEmailOption === VerificationEmailStyle.CODE) ? {
496-
defaultEmailOption,
497-
emailMessage: emailVerificationMessage,
498-
emailSubject: emailVerificationSubject,
499-
smsMessage: smsVerificationMessage,
500-
} : {
501-
defaultEmailOption,
502-
emailMessageByLink: emailVerificationMessage,
503-
emailSubjectByLink: emailVerificationSubject,
504-
smsMessage: smsVerificationMessage
505-
};
506-
493+
const verificationMessageTemplate = this.verificationMessageConfiguration(props);
494+
let emailVerificationMessage;
495+
let emailVerificationSubject;
496+
let smsVerificationMessage;
497+
if (verificationMessageTemplate.defaultEmailOption === VerificationEmailStyle.CODE) {
498+
emailVerificationMessage = verificationMessageTemplate.emailMessage;
499+
emailVerificationSubject = verificationMessageTemplate.emailSubject;
500+
smsVerificationMessage = verificationMessageTemplate.smsMessage;
501+
}
507502
const inviteMessageTemplate: CfnUserPool.InviteMessageTemplateProperty = {
508503
emailMessage: props.userInvitation?.emailBody,
509504
emailSubject: props.userInvitation?.emailSubject,
@@ -664,6 +659,42 @@ export class UserPool extends Resource implements IUserPool {
664659
});
665660
}
666661

662+
private verificationMessageConfiguration(props: UserPoolProps): CfnUserPool.VerificationMessageTemplateProperty {
663+
const emailStyle = props.userVerification?.emailStyle ?? VerificationEmailStyle.CODE;
664+
const emailSubject = props.userVerification?.emailSubject ?? 'Verify your new account';
665+
666+
if (emailStyle === VerificationEmailStyle.CODE) {
667+
const emailMessage = props.userVerification?.emailBody ?? 'Hello {username}, Your verification code is {####}';
668+
const smsMessage = props.userVerification?.smsMessage ?? 'The verification code to your new account is {####}';
669+
if (emailMessage.indexOf('{####}') < 0) {
670+
throw new Error(`Verification email body must contain the template string '{####}'`);
671+
}
672+
if (smsMessage.indexOf('{####}') < 0) {
673+
throw new Error(`SMS message must contain the template string '{####}'`);
674+
}
675+
return {
676+
defaultEmailOption: VerificationEmailStyle.CODE,
677+
emailMessage,
678+
emailSubject,
679+
smsMessage,
680+
};
681+
} else {
682+
if (props.userVerification?.smsMessage !== undefined) {
683+
throw new Error('SMS message cannot be configured when emailStyle is configured to CODE');
684+
}
685+
const emailMessage = props.userVerification?.emailBody ?? 'Hello {username}, Verify your account by clicking on {##Verify Email##}';
686+
if (emailMessage.indexOf('{##Verify Email##}') < 0) {
687+
throw new Error(`Verification email body must contain the template string '{##Verify Email##}'`);
688+
}
689+
return {
690+
defaultEmailOption: VerificationEmailStyle.LINK,
691+
emailMessageByLink: emailMessage,
692+
emailSubjectByLink: emailSubject,
693+
smsMessage: props.userVerification?.smsMessage,
694+
};
695+
}
696+
}
697+
667698
private signInConfiguration(props: UserPoolProps) {
668699
let aliasAttrs: string[] | undefined;
669700
let usernameAttrs: string[] | undefined;

packages/@aws-cdk/aws-cognito/test/user-pool.test.ts

+63-4
Original file line numberDiff line numberDiff line change
@@ -96,22 +96,81 @@ describe('User Pool', () => {
9696
// WHEN
9797
new UserPool(stack, 'Pool', {
9898
userVerification: {
99-
emailStyle: VerificationEmailStyle.LINK
99+
emailStyle: VerificationEmailStyle.LINK,
100100
}
101101
});
102102

103103
// THEN
104104
expect(stack).toHaveResourceLike('AWS::Cognito::UserPool', {
105-
EmailVerificationMessage: 'Hello {username}, Your verification code is {####}',
106-
EmailVerificationSubject: 'Verify your new account',
105+
EmailVerificationMessage: ABSENT,
106+
EmailVerificationSubject: ABSENT,
107+
SmsVerificationMessage: ABSENT,
107108
VerificationMessageTemplate: {
108109
DefaultEmailOption: 'CONFIRM_WITH_LINK',
109-
EmailMessageByLink: 'Hello {username}, Your verification code is {####}',
110+
EmailMessageByLink: 'Hello {username}, Verify your account by clicking on {##Verify Email##}',
110111
EmailSubjectByLink: 'Verify your new account',
112+
SmsMessage: ABSENT,
111113
}
112114
});
113115
}),
114116

117+
test('sms message cannot be specified if link-style email verification is configured', () => {
118+
const stack = new Stack();
119+
120+
expect(() => new UserPool(stack, 'Pool', {
121+
userVerification: {
122+
emailStyle: VerificationEmailStyle.LINK,
123+
smsMessage: 'sms message'
124+
}
125+
})).toThrow(/SMS message cannot be configured/);
126+
});
127+
128+
test('email and sms verification messages are validated', () => {
129+
const stack = new Stack();
130+
131+
expect(() => new UserPool(stack, 'Pool1', {
132+
userVerification: {
133+
emailStyle: VerificationEmailStyle.CODE,
134+
emailBody: 'invalid email body',
135+
}
136+
})).toThrow(/Verification email body/);
137+
138+
expect(() => new UserPool(stack, 'Pool2', {
139+
userVerification: {
140+
emailStyle: VerificationEmailStyle.CODE,
141+
emailBody: 'valid email body {####}',
142+
}
143+
})).not.toThrow();
144+
145+
expect(() => new UserPool(stack, 'Pool3', {
146+
userVerification: {
147+
emailStyle: VerificationEmailStyle.CODE,
148+
smsMessage: 'invalid sms message',
149+
}
150+
})).toThrow(/SMS message/);
151+
152+
expect(() => new UserPool(stack, 'Pool4', {
153+
userVerification: {
154+
emailStyle: VerificationEmailStyle.CODE,
155+
smsMessage: 'invalid sms message {####}',
156+
}
157+
})).not.toThrow();
158+
159+
expect(() => new UserPool(stack, 'Pool5', {
160+
userVerification: {
161+
emailStyle: VerificationEmailStyle.LINK,
162+
emailBody: 'invalid email body {####}',
163+
}
164+
})).toThrow(/Verification email body/);
165+
166+
expect(() => new UserPool(stack, 'Pool6', {
167+
userVerification: {
168+
emailStyle: VerificationEmailStyle.LINK,
169+
emailBody: 'invalid email body {##Verify Email##}',
170+
}
171+
})).not.toThrow();
172+
});
173+
115174
test('user invitation messages are configured correctly', () => {
116175
// GIVEN
117176
const stack = new Stack();

0 commit comments

Comments
 (0)