diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json new file mode 100644 index 0000000000000..8bbe077289ad2 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json @@ -0,0 +1,19 @@ +{ + "version": "38.0.1", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "IntegTestDefaultTestDeployAssertE3E7D2A4.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/cdk.out new file mode 100644 index 0000000000000..c6e612584e352 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"38.0.1"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/integ-user-pool-feature-plans.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/integ-user-pool-feature-plans.assets.json new file mode 100644 index 0000000000000..97e4aa852388a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/integ-user-pool-feature-plans.assets.json @@ -0,0 +1,19 @@ +{ + "version": "38.0.1", + "files": { + "a72b902838ee34a1865ddc6b3df03a50523b0fd57ac3fcca7e9265397b960308": { + "source": { + "path": "integ-user-pool-feature-plans.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "a72b902838ee34a1865ddc6b3df03a50523b0fd57ac3fcca7e9265397b960308.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/integ-user-pool-feature-plans.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/integ-user-pool-feature-plans.template.json new file mode 100644 index 0000000000000..511db0f2f3a32 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/integ-user-pool-feature-plans.template.json @@ -0,0 +1,134 @@ +{ + "Resources": { + "userpoolliteplanA197F128": { + "Type": "AWS::Cognito::UserPool", + "Properties": { + "AccountRecoverySetting": { + "RecoveryMechanisms": [ + { + "Name": "verified_phone_number", + "Priority": 1 + }, + { + "Name": "verified_email", + "Priority": 2 + } + ] + }, + "AdminCreateUserConfig": { + "AllowAdminCreateUserOnly": true + }, + "EmailVerificationMessage": "The verification code to your new account is {####}", + "EmailVerificationSubject": "Verify your new account", + "SmsVerificationMessage": "The verification code to your new account is {####}", + "UserPoolTier": "LITE", + "VerificationMessageTemplate": { + "DefaultEmailOption": "CONFIRM_WITH_CODE", + "EmailMessage": "The verification code to your new account is {####}", + "EmailSubject": "Verify your new account", + "SmsMessage": "The verification code to your new account is {####}" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "userpoolessentialsplan605F6755": { + "Type": "AWS::Cognito::UserPool", + "Properties": { + "AccountRecoverySetting": { + "RecoveryMechanisms": [ + { + "Name": "verified_phone_number", + "Priority": 1 + }, + { + "Name": "verified_email", + "Priority": 2 + } + ] + }, + "AdminCreateUserConfig": { + "AllowAdminCreateUserOnly": true + }, + "EmailVerificationMessage": "The verification code to your new account is {####}", + "EmailVerificationSubject": "Verify your new account", + "SmsVerificationMessage": "The verification code to your new account is {####}", + "UserPoolTier": "ESSENTIALS", + "VerificationMessageTemplate": { + "DefaultEmailOption": "CONFIRM_WITH_CODE", + "EmailMessage": "The verification code to your new account is {####}", + "EmailSubject": "Verify your new account", + "SmsMessage": "The verification code to your new account is {####}" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "userpoolplusplan01FBD006": { + "Type": "AWS::Cognito::UserPool", + "Properties": { + "AccountRecoverySetting": { + "RecoveryMechanisms": [ + { + "Name": "verified_phone_number", + "Priority": 1 + }, + { + "Name": "verified_email", + "Priority": 2 + } + ] + }, + "AdminCreateUserConfig": { + "AllowAdminCreateUserOnly": true + }, + "EmailVerificationMessage": "The verification code to your new account is {####}", + "EmailVerificationSubject": "Verify your new account", + "SmsVerificationMessage": "The verification code to your new account is {####}", + "UserPoolTier": "PLUS", + "VerificationMessageTemplate": { + "DefaultEmailOption": "CONFIRM_WITH_CODE", + "EmailMessage": "The verification code to your new account is {####}", + "EmailSubject": "Verify your new account", + "SmsMessage": "The verification code to your new account is {####}" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/integ.json new file mode 100644 index 0000000000000..ef203138b4071 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "38.0.1", + "testCases": { + "IntegTest/DefaultTest": { + "stacks": [ + "integ-user-pool-feature-plans" + ], + "assertionStack": "IntegTest/DefaultTest/DeployAssert", + "assertionStackName": "IntegTestDefaultTestDeployAssertE3E7D2A4" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/manifest.json new file mode 100644 index 0000000000000..3f81c5b9f2b6f --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/manifest.json @@ -0,0 +1,125 @@ +{ + "version": "38.0.1", + "artifacts": { + "integ-user-pool-feature-plans.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "integ-user-pool-feature-plans.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "integ-user-pool-feature-plans": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "integ-user-pool-feature-plans.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/a72b902838ee34a1865ddc6b3df03a50523b0fd57ac3fcca7e9265397b960308.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "integ-user-pool-feature-plans.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "integ-user-pool-feature-plans.assets" + ], + "metadata": { + "/integ-user-pool-feature-plans/userpool-lite-plan/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "userpoolliteplanA197F128" + } + ], + "/integ-user-pool-feature-plans/userpool-essentials-plan/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "userpoolessentialsplan605F6755" + } + ], + "/integ-user-pool-feature-plans/userpool-plus-plan/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "userpoolplusplan01FBD006" + } + ], + "/integ-user-pool-feature-plans/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/integ-user-pool-feature-plans/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "integ-user-pool-feature-plans" + }, + "IntegTestDefaultTestDeployAssertE3E7D2A4.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "IntegTestDefaultTestDeployAssertE3E7D2A4": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "IntegTestDefaultTestDeployAssertE3E7D2A4.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "IntegTestDefaultTestDeployAssertE3E7D2A4.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "IntegTestDefaultTestDeployAssertE3E7D2A4.assets" + ], + "metadata": { + "/IntegTest/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/IntegTest/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "IntegTest/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/tree.json new file mode 100644 index 0000000000000..ef933888ff246 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.js.snapshot/tree.json @@ -0,0 +1,245 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "integ-user-pool-feature-plans": { + "id": "integ-user-pool-feature-plans", + "path": "integ-user-pool-feature-plans", + "children": { + "userpool-lite-plan": { + "id": "userpool-lite-plan", + "path": "integ-user-pool-feature-plans/userpool-lite-plan", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-user-pool-feature-plans/userpool-lite-plan/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Cognito::UserPool", + "aws:cdk:cloudformation:props": { + "accountRecoverySetting": { + "recoveryMechanisms": [ + { + "name": "verified_phone_number", + "priority": 1 + }, + { + "name": "verified_email", + "priority": 2 + } + ] + }, + "adminCreateUserConfig": { + "allowAdminCreateUserOnly": true + }, + "emailVerificationMessage": "The verification code to your new account is {####}", + "emailVerificationSubject": "Verify your new account", + "smsVerificationMessage": "The verification code to your new account is {####}", + "userPoolTier": "LITE", + "verificationMessageTemplate": { + "defaultEmailOption": "CONFIRM_WITH_CODE", + "emailMessage": "The verification code to your new account is {####}", + "emailSubject": "Verify your new account", + "smsMessage": "The verification code to your new account is {####}" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_cognito.CfnUserPool", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_cognito.UserPool", + "version": "0.0.0" + } + }, + "userpool-essentials-plan": { + "id": "userpool-essentials-plan", + "path": "integ-user-pool-feature-plans/userpool-essentials-plan", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-user-pool-feature-plans/userpool-essentials-plan/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Cognito::UserPool", + "aws:cdk:cloudformation:props": { + "accountRecoverySetting": { + "recoveryMechanisms": [ + { + "name": "verified_phone_number", + "priority": 1 + }, + { + "name": "verified_email", + "priority": 2 + } + ] + }, + "adminCreateUserConfig": { + "allowAdminCreateUserOnly": true + }, + "emailVerificationMessage": "The verification code to your new account is {####}", + "emailVerificationSubject": "Verify your new account", + "smsVerificationMessage": "The verification code to your new account is {####}", + "userPoolTier": "ESSENTIALS", + "verificationMessageTemplate": { + "defaultEmailOption": "CONFIRM_WITH_CODE", + "emailMessage": "The verification code to your new account is {####}", + "emailSubject": "Verify your new account", + "smsMessage": "The verification code to your new account is {####}" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_cognito.CfnUserPool", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_cognito.UserPool", + "version": "0.0.0" + } + }, + "userpool-plus-plan": { + "id": "userpool-plus-plan", + "path": "integ-user-pool-feature-plans/userpool-plus-plan", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-user-pool-feature-plans/userpool-plus-plan/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Cognito::UserPool", + "aws:cdk:cloudformation:props": { + "accountRecoverySetting": { + "recoveryMechanisms": [ + { + "name": "verified_phone_number", + "priority": 1 + }, + { + "name": "verified_email", + "priority": 2 + } + ] + }, + "adminCreateUserConfig": { + "allowAdminCreateUserOnly": true + }, + "emailVerificationMessage": "The verification code to your new account is {####}", + "emailVerificationSubject": "Verify your new account", + "smsVerificationMessage": "The verification code to your new account is {####}", + "userPoolTier": "PLUS", + "verificationMessageTemplate": { + "defaultEmailOption": "CONFIRM_WITH_CODE", + "emailMessage": "The verification code to your new account is {####}", + "emailSubject": "Verify your new account", + "smsMessage": "The verification code to your new account is {####}" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_cognito.CfnUserPool", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_cognito.UserPool", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "integ-user-pool-feature-plans/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "integ-user-pool-feature-plans/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "IntegTest": { + "id": "IntegTest", + "path": "IntegTest", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "IntegTest/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "IntegTest/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "IntegTest/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "IntegTest/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "IntegTest/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.ts new file mode 100644 index 0000000000000..62504d12a8447 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cognito/test/integ.user-pool-feature-plans.ts @@ -0,0 +1,23 @@ +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import { App, RemovalPolicy, Stack } from 'aws-cdk-lib'; +import { UserPool, FeaturePlan } from 'aws-cdk-lib/aws-cognito'; + +const app = new App(); +const stack = new Stack(app, 'integ-user-pool-feature-plans'); + +new UserPool(stack, 'userpool-lite-plan', { + featurePlan: FeaturePlan.LITE, + removalPolicy: RemovalPolicy.DESTROY, +}); + +new UserPool(stack, 'userpool-essentials-plan', { + featurePlan: FeaturePlan.ESSENTIALS, + removalPolicy: RemovalPolicy.DESTROY, +}); + +new UserPool(stack, 'userpool-plus-plan', { + featurePlan: FeaturePlan.PLUS, + removalPolicy: RemovalPolicy.DESTROY, +}); + +new IntegTest(app, 'IntegTest', { testCases: [stack] }); diff --git a/packages/aws-cdk-lib/aws-cognito/README.md b/packages/aws-cdk-lib/aws-cognito/README.md index e59370ef2d7cd..72bd51cb4ae94 100644 --- a/packages/aws-cdk-lib/aws-cognito/README.md +++ b/packages/aws-cdk-lib/aws-cognito/README.md @@ -18,6 +18,7 @@ This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aw - [Amazon Cognito Construct Library](#amazon-cognito-construct-library) - [Table of Contents](#table-of-contents) - [User Pools](#user-pools) + - [User pool feature plans](#user-pool-feature-plans) - [Sign Up](#sign-up) - [Code Verification](#code-verification) - [Link Verification](#link-verification) @@ -75,6 +76,20 @@ const role = new iam.Role(this, 'role', { userPool.grant(role, 'cognito-idp:AdminCreateUser'); ``` +### User pool feature plans + +Amazon Cognito has feature plans for user pools. Each plan has a set of features and a monthly cost per active user. Each feature plan unlocks access to more features than the one before it. +Lean more aboug [feature plans here](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-sign-in-feature-plans.html). + +- *Lite* - a low-cost feature plan for user pools with lower numbers of monthly active users. +- *Essentials* - all of the latest user pool authentication features. +- *Plus* - includes everything in the Essentials plan and adds advanced security features that protect your users. + +The default feature plan is Essentials for newly create user pools. +For the existing user pools, Lite plan is automatically set. + +Previously, some user pool features were included in [an advanced security features](#advanced-security-mode) pricing structure. The features that were included in this structure are now under either the Essentials or Plus plan. + ### Sign Up Users can either be signed up by the app's administrators or can sign themselves up. Once a user has signed up, their @@ -308,8 +323,8 @@ configure an MFA token and use it for sign in. It also allows for the users to u [time-based one time password (TOTP)](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-mfa-totp.html). -If you want to enable email-based MFA, set `email` propety to the Amazon SES email-sending configuration and set `advancedSecurityMode` to `AdvancedSecurity.ENFORCED` or `AdvancedSecurity.AUDIT`. -For more information, see [Email MFA](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-settings-advanced-security-email-mfa.html). +If you want to enable email-based MFA, set `email` propety to the Amazon SES email-sending configuration and set `featurePlan` to `FeaturePlan.ESSENTIALS` or `FeaturePlan.PLUS`. +For more information, see [SMS and email message MFA](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-mfa-sms-email-message.html). ```ts new cognito.UserPool(this, 'myuserpool', { @@ -365,6 +380,8 @@ A user will not be allowed to reset their password via phone if they are also us #### Advanced Security Mode +⚠️ Advanced Security Mode is deprecated in favor of [user pool feature plans](#user-pool-feature-plans). + User pools can be configured to use Advanced security. You can turn the user pool advanced security features on, and customize the actions that are taken in response to different risks. Or you can use audit mode to gather metrics on detected risks without taking action. In audit mode, the advanced security features publish metrics to Amazon CloudWatch. See the [documentation on Advanced security](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-settings-advanced-security.html) to learn more. ```ts diff --git a/packages/aws-cdk-lib/aws-cognito/lib/user-pool.ts b/packages/aws-cdk-lib/aws-cognito/lib/user-pool.ts index 9ba99724cdb6e..03f3c3ff15f10 100644 --- a/packages/aws-cdk-lib/aws-cognito/lib/user-pool.ts +++ b/packages/aws-cdk-lib/aws-cognito/lib/user-pool.ts @@ -408,7 +408,7 @@ export interface MfaSecondFactor { * The MFA token is sent to the user via EMAIL * * To enable email-based MFA, set `email` property to the Amazon SES email-sending configuration - * and set `advancedSecurityMode` to `AdvancedSecurity.ENFORCED` or `AdvancedSecurity.AUDIT` + * and set `feturePlan` to `FeaturePlan.ESSENTIALS` or `FeaturePlan.PLUS` * * @see https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-mfa-sms-email-message.html * @default false @@ -540,6 +540,7 @@ export interface DeviceTracking { /** * The different ways in which a user pool's Advanced Security Mode can be configured. + * @deprecated Advanced Security Mode is deprecated in favor of user pool feature plans. * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cognito-userpool-userpooladdons.html#cfn-cognito-userpool-userpooladdons-advancedsecuritymode */ export enum AdvancedSecurityMode { @@ -551,6 +552,19 @@ export enum AdvancedSecurityMode { OFF = 'OFF', } +/** + * The user pool feature plan, or tier. + * @see https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-sign-in-feature-plans.html + */ +export enum FeaturePlan { + /** Lite feature plan */ + LITE = 'LITE', + /** Essentials feature plan */ + ESSENTIALS = 'ESSENTIALS', + /** Plus feature plan */ + PLUS = 'PLUS', +}; + /** * Props for the UserPool construct */ @@ -758,9 +772,18 @@ export interface UserPoolProps { /** * The user pool's Advanced Security Mode + * @deprecated Advanced Security Mode is deprecated in favor of user pool feature plans. * @default - no value */ readonly advancedSecurityMode?: AdvancedSecurityMode; + + /** + * The user pool feature plan, or tier. + * This parameter determines the eligibility of the user pool for features like managed login, access-token customization, and threat protection. + * @see https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-sign-in-feature-plans.html + * @default - FeaturePlan.ESSENTIALS for a newly created user pool; FeaturePlan.LITE otherwise + */ + readonly featurePlan?: FeaturePlan; } /** @@ -1017,6 +1040,13 @@ export class UserPool extends UserPoolBase { }); this.emailConfiguration = emailConfiguration; + if ( + props.featurePlan && props.featurePlan !== FeaturePlan.LITE && + props.advancedSecurityMode && props.advancedSecurityMode !== AdvancedSecurityMode.OFF + ) { + throw new Error('you cannot enable Advanced Security Mode when feature plan is Essentials or higher.'); + } + const userPool = new CfnUserPool(this, 'Resource', { userPoolName: props.userPoolName, usernameAttributes: signIn.usernameAttrs, @@ -1044,6 +1074,7 @@ export class UserPool extends UserPoolBase { accountRecoverySetting: this.accountRecovery(props), deviceConfiguration: props.deviceTracking, userAttributeUpdateSettings: this.configureUserAttributeChanges(props), + userPoolTier: props.featurePlan, deletionProtection: defaultDeletionProtection(props.deletionProtection), }); userPool.applyRemovalPolicy(props.removalPolicy); @@ -1400,8 +1431,8 @@ export class UserPool extends UserPoolBase { throw new Error('To enable email-based MFA, set `email` property to the Amazon SES email-sending configuration.'); } - if (props.advancedSecurityMode === AdvancedSecurityMode.OFF) { - throw new Error('To enable email-based MFA, set `advancedSecurityMode` to `AdvancedSecurity.ENFORCED` or `AdvancedSecurity.AUDIT`.'); + if (props.featurePlan === FeaturePlan.LITE && (!props.advancedSecurityMode || props.advancedSecurityMode === AdvancedSecurityMode.OFF)) { + throw new Error('To enable email-based MFA, set `featurePlan` to `FeaturePlan.ESSENTIALS` or `FeaturePlan.PLUS`.'); } } } diff --git a/packages/aws-cdk-lib/aws-cognito/test/user-pool.test.ts b/packages/aws-cdk-lib/aws-cognito/test/user-pool.test.ts index bcf69ec7948e9..64fda04f7dd2b 100644 --- a/packages/aws-cdk-lib/aws-cognito/test/user-pool.test.ts +++ b/packages/aws-cdk-lib/aws-cognito/test/user-pool.test.ts @@ -5,7 +5,7 @@ import { Role, ServicePrincipal } from '../../aws-iam'; import * as kms from '../../aws-kms'; import * as lambda from '../../aws-lambda'; import { CfnParameter, Duration, Stack, Tags } from '../../core'; -import { AccountRecovery, Mfa, NumberAttribute, StringAttribute, UserPool, UserPoolIdentityProvider, UserPoolOperation, VerificationEmailStyle, UserPoolEmail, AdvancedSecurityMode, LambdaVersion } from '../lib'; +import { AccountRecovery, Mfa, NumberAttribute, StringAttribute, UserPool, UserPoolIdentityProvider, UserPoolOperation, VerificationEmailStyle, UserPoolEmail, AdvancedSecurityMode, LambdaVersion, FeaturePlan } from '../lib'; describe('User Pool', () => { test('default setup', () => { @@ -2188,6 +2188,36 @@ test('deletion protection', () => { }); }); +test.each([ + [FeaturePlan.LITE, 'LITE'], + [FeaturePlan.ESSENTIALS, 'ESSENTIALS'], + [FeaturePlan.PLUS, 'PLUS'], +])('feature plan is configured correctly when set to (%s)', (featurePlan, compareString) => { + // GIVEN + const stack = new Stack(); + + // WHEN + new UserPool(stack, 'Pool', { featurePlan }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + UserPoolTier: compareString, + }); +}); + +test('feature plan is not present if option is not provided', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + new UserPool(stack, 'Pool', {}); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + UserPoolTier: Match.absent(), + }); +}); + test.each( [ [AdvancedSecurityMode.ENFORCED, 'ENFORCED'], @@ -2223,6 +2253,21 @@ test('advanced security is not present if option is not provided', () => { }); }); +test.each([ + [FeaturePlan.ESSENTIALS, AdvancedSecurityMode.AUDIT], + [FeaturePlan.ESSENTIALS, AdvancedSecurityMode.ENFORCED], + [FeaturePlan.PLUS, AdvancedSecurityMode.AUDIT], + [FeaturePlan.PLUS, AdvancedSecurityMode.ENFORCED], +])('throws when feature plan is %s and advanced security mode is %s', (featurePlan, advancedSecurityMode) => { + // GIVEN + const stack = new Stack(); + + // WHEN + expect(() => { + new UserPool(stack, 'Pool', { featurePlan, advancedSecurityMode }); + }).toThrow('you cannot enable Advanced Security Mode when feature plan is Essentials or higher.'); +}); + describe('email MFA test', () => { test('email MFA enabled', () => { // GIVEN @@ -2243,7 +2288,7 @@ describe('email MFA test', () => { otp: false, email: true, }, - advancedSecurityMode: AdvancedSecurityMode.ENFORCED, + featurePlan: FeaturePlan.ESSENTIALS, }); // THEN @@ -2262,7 +2307,7 @@ describe('email MFA test', () => { otp: false, email: true, }, - advancedSecurityMode: AdvancedSecurityMode.ENFORCED, + featurePlan: FeaturePlan.ESSENTIALS, })).toThrow('To enable email-based MFA, set `email` property to the Amazon SES email-sending configuration.'); }); @@ -2277,11 +2322,36 @@ describe('email MFA test', () => { otp: false, email: true, }, - advancedSecurityMode: AdvancedSecurityMode.ENFORCED, + featurePlan: FeaturePlan.ESSENTIALS, })).toThrow('To enable email-based MFA, set `email` property to the Amazon SES email-sending configuration.'); }); - test('set Email MFA', () => { + test.each([ + AdvancedSecurityMode.AUDIT, + AdvancedSecurityMode.ENFORCED, + ])('email MFA with Lite feature plan and %s Advanced Security Mode', (advancedSecurityMode) => { + const stack = new Stack(); + + expect(() => new UserPool(stack, 'Pool1', { + email: UserPoolEmail.withSES({ + sesRegion: 'us-east-1', + fromEmail: 'noreply@example.com', + fromName: 'myname@mycompany.com', + replyTo: 'support@example.com', + sesVerifiedDomain: 'example.com', + }), + mfa: Mfa.REQUIRED, + mfaSecondFactor: { + sms: true, + otp: false, + email: true, + }, + featurePlan: FeaturePlan.LITE, + advancedSecurityMode, + })).not.toThrow(); + }); + + test('throws when email MFA is enabled with Lite feature plan', () => { const stack = new Stack(); expect(() => new UserPool(stack, 'Pool1', { @@ -2298,8 +2368,8 @@ describe('email MFA test', () => { otp: false, email: true, }, - advancedSecurityMode: AdvancedSecurityMode.OFF, - })).toThrow('To enable email-based MFA, set `advancedSecurityMode` to `AdvancedSecurity.ENFORCED` or `AdvancedSecurity.AUDIT`.'); + featurePlan: FeaturePlan.LITE, + })).toThrow('To enable email-based MFA, set `featurePlan` to `FeaturePlan.ESSENTIALS` or `FeaturePlan.PLUS`.'); }); });