diff --git a/docs/providers/aws/README.md b/docs/providers/aws/README.md
index d464d02fc..f9dc3ced4 100644
--- a/docs/providers/aws/README.md
+++ b/docs/providers/aws/README.md
@@ -90,6 +90,7 @@ If you have questions, join the [chat in gitter](https://gitter.im/serverless/se
IoT
CloudWatch Event
CloudWatch Log
+ Cognito User Pool
diff --git a/docs/providers/aws/events/cognito-user-pool.md b/docs/providers/aws/events/cognito-user-pool.md
new file mode 100644
index 000000000..0c2b65207
--- /dev/null
+++ b/docs/providers/aws/events/cognito-user-pool.md
@@ -0,0 +1,116 @@
+
+
+
+### [Read this on the main serverless docs site](https://www.serverless.com/framework/docs/providers/aws/events/cognito-user-pool)
+
+
+# Cognito User Pool
+
+## Valid Triggers
+
+Serverless supports all Cognito User Pool Triggers as specified [here][aws-triggers-list].
+
+## Simple event definition
+
+This will create a Cognito User Pool with the specified name. You can reference the same pool multiple times.
+
+```yml
+functions:
+ preSignUp:
+ handler: preSignUp.handler
+ events:
+ - cognitoUserPool:
+ pool: MyUserPool
+ trigger: PreSignUp
+ customMessage:
+ handler: customMessage.handler
+ events:
+ - cognitoUserPool:
+ pool: MyUserPool
+ trigger: CustomMessage
+```
+
+## Multiple pools event definitions
+
+This will create multiple Cognito User Pools with their specified names:
+
+```yml
+functions:
+ preSignUpForPool1:
+ handler: preSignUp.handler
+ events:
+ - cognitoUserPool:
+ pool: MyUserPool1
+ trigger: PreSignUp
+ preSignUpForPool2:
+ handler: preSignUp.handler
+ events:
+ - cognitoUserPool:
+ pool: MyUserPool2
+ trigger: PreSignUp
+```
+
+You can also deploy the same function for different user pools:
+
+```yml
+functions:
+ preSignUp:
+ handler: preSignUp.handler
+ events:
+ - cognitoUserPool:
+ pool: MyUserPool1
+ trigger: PreSignUp
+ - cognitoUserPool:
+ pool: MyUserPool2
+ trigger: PreSignUp
+```
+
+## Custom message trigger handlers
+
+For custom messages, you will need to check `event.triggerSource` type inside your handler function:
+
+```js
+// customMessage.js
+function handler(event, context, callback) {
+ if (event.triggerSource === 'CustomMessage_AdminCreateUser') {
+ // ...
+ }
+ if (event.triggerSource === 'CustomMessage_ResendCode') {
+ // ...
+ }
+}
+```
+
+## Overriding a generated User Pool
+
+A Cognito User Pool created by an event can be overridden by using the [logical resource name][logical-resource-names] in `Resources`:
+
+```yml
+functions:
+ preSignUp:
+ handler: preSignUpForPool1.handler
+ events:
+ - cognitoUserPool:
+ pool: MyUserPool
+ trigger: PreSignUp
+ postConfirmation:
+ handler: postConfirmation.handler
+ events:
+ - cognitoUserPool:
+ pool: MyUserPool
+ trigger: PostConfirmation
+
+resources:
+ Resources:
+ CognitoUserPoolMyUserPool:
+ Type: AWS::Cognito::UserPool
+```
+
+[aws-triggers-list]: http://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html#cognito-user-pools-lambda-trigger-syntax-shared
+[logical-resource-names]: ../guide/resources#aws-cloudformation-resource-reference
diff --git a/docs/providers/aws/guide/resources.md b/docs/providers/aws/guide/resources.md
index aecb4c462..6007cbbc1 100644
--- a/docs/providers/aws/guide/resources.md
+++ b/docs/providers/aws/guide/resources.md
@@ -70,7 +70,7 @@ We're also using the term `normalizedName` or similar terms in this guide. This
|Lambda::Function | {normalizedFunctionName}LambdaFunction | HelloLambdaFunction |
|Lambda::Version | {normalizedFunctionName}LambdaVersion{sha256} | HelloLambdaVersionr3pgoTvv1xT4E4NiCL6JG02fl6vIyi7OS1aW0FwAI |
|Logs::LogGroup | {normalizedFunctionName}LogGroup | HelloLogGroup |
-|Lambda::Permission | - **Schedule**: {normalizedFunctionName}LambdaPermissionEventsRuleSchedule{index}
- **CloudWatch Event**: {normalizedFunctionName}LambdaPermissionEventsRuleCloudWatchEvent{index}
- **CloudWatch Log**: {normalizedFunctionName}LambdaPermissionLogsSubscriptionFilterCloudWatchLog{index}
- **IoT**: {normalizedFunctionName}LambdaPermissionIotTopicRule{index}
- **S3**: {normalizedFunctionName}LambdaPermission{normalizedBucketName}S3
- **APIG**: {normalizedFunctionName}LambdaPermissionApiGateway
- **SNS**: {normalizedFunctionName}LambdaPermission{normalizedTopicName}SNS
- **Alexa Skill**: {normalizedFunctionName}LambdaPermissionAlexaSkill
| - **Schedule**: HelloLambdaPermissionEventsRuleSchedule1
- **CloudWatch Event**: HelloLambdaPermissionEventsRuleCloudWatchEvent1
- **CloudWatch Log**: HelloLambdaPermissionLogsSubscriptionFilterCloudWatchLog1
- **IoT**: HelloLambdaPermissionIotTopicRule1
- **S3**: HelloLambdaPermissionBucketS3
- **APIG**: HelloLambdaPermissionApiGateway
- **SNS**: HelloLambdaPermissionTopicSNS
- **Alexa Skill**: HelloLambdaPermissionAlexaSkill
|
+|Lambda::Permission | - **Schedule**: {normalizedFunctionName}LambdaPermissionEventsRuleSchedule{index}
- **CloudWatch Event**: {normalizedFunctionName}LambdaPermissionEventsRuleCloudWatchEvent{index}
- **CloudWatch Log**: {normalizedFunctionName}LambdaPermissionLogsSubscriptionFilterCloudWatchLog{index}
- **IoT**: {normalizedFunctionName}LambdaPermissionIotTopicRule{index}
- **S3**: {normalizedFunctionName}LambdaPermission{normalizedBucketName}S3
- **APIG**: {normalizedFunctionName}LambdaPermissionApiGateway
- **SNS**: {normalizedFunctionName}LambdaPermission{normalizedTopicName}SNS
- **Alexa Skill**: {normalizedFunctionName}LambdaPermissionAlexaSkill
- **Cognito User Pool Trigger Source**: {normalizedFunctionName}LambdaPermissionCognitoUserPool{normalizedPoolId}TriggerSource{triggerSource}
| - **Schedule**: HelloLambdaPermissionEventsRuleSchedule1
- **CloudWatch Event**: HelloLambdaPermissionEventsRuleCloudWatchEvent1
- **CloudWatch Log**: HelloLambdaPermissionLogsSubscriptionFilterCloudWatchLog1
- **IoT**: HelloLambdaPermissionIotTopicRule1
- **S3**: HelloLambdaPermissionBucketS3
- **APIG**: HelloLambdaPermissionApiGateway
- **SNS**: HelloLambdaPermissionTopicSNS
- **Alexa Skill**: HelloLambdaPermissionAlexaSkill
- **Cognito User Pool Trigger Source**: HelloLambdaPermissionCognitoUserPoolMyPoolTriggerSourceCustomMessage
|
|Events::Rule | - **Schedule**: {normalizedFuntionName}EventsRuleSchedule{SequentialID}
- **CloudWatch Event**: {normalizedFuntionName}EventsRuleCloudWatchEvent{SequentialID}
| - **Schedule**: HelloEventsRuleSchedule1
- **CloudWatch Event**: HelloEventsRuleCloudWatchEvent1
|
|AWS::Logs::SubscriptionFilter | {normalizedFuntionName}LogsSubscriptionFilterCloudWatchLog{SequentialID} | HelloLogsSubscriptionFilterCloudWatchLog1 |
|AWS::IoT::TopicRule | {normalizedFuntionName}IotTopicRule{SequentialID} | HelloIotTopicRule1 |
@@ -83,6 +83,7 @@ We're also using the term `normalizedName` or similar terms in this guide. This
|SNS::Topic | SNSTopic{normalizedTopicName} | SNSTopicSometopic |
|SNS::Subscription | {normalizedFunctionName}SnsSubscription{normalizedTopicName} | HelloSnsSubscriptionSomeTopic |
|AWS::Lambda::EventSourceMapping | - **DynamoDB:** {normalizedFunctionName}EventSourceMappingDynamodb{tableName}
- **Kinesis:** {normalizedFunctionName}EventSourceMappingKinesis{streamName}
| - **DynamoDB:** HelloLambdaEventSourceMappingDynamodbUsers
- **Kinesis:** HelloLambdaEventSourceMappingKinesisMystream
|
+|Cognito::UserPool | CognitoUserPool{normalizedPoolId} | CognitoUserPoolPoolId |
## Override AWS CloudFormation Resource
diff --git a/docs/providers/aws/guide/serverless.yml.md b/docs/providers/aws/guide/serverless.yml.md
index 05c1bf301..2c81c81a4 100644
--- a/docs/providers/aws/guide/serverless.yml.md
+++ b/docs/providers/aws/guide/serverless.yml.md
@@ -137,6 +137,9 @@ functions:
- cloudwatchLog:
logGroup: '/aws/lambda/hello'
filter: '{$.userIdentity.type = Root}'
+ - cognitoUserPool:
+ pool: MyUserPool
+ trigger: PreSignUp
# The "Resources" your "Functions" use. Raw AWS CloudFormation goes in here.
resources:
diff --git a/lib/plugins/Plugins.json b/lib/plugins/Plugins.json
index 48b655570..8149aa451 100644
--- a/lib/plugins/Plugins.json
+++ b/lib/plugins/Plugins.json
@@ -36,6 +36,7 @@
"./aws/package/compile/events/iot/index.js",
"./aws/package/compile/events/cloudWatchEvent/index.js",
"./aws/package/compile/events/cloudWatchLog/index.js",
+ "./aws/package/compile/events/cognitoUserPool/index.js",
"./aws/deployFunction/index.js",
"./aws/deployList/index.js",
"./aws/invokeLocal/index.js"
diff --git a/lib/plugins/aws/lib/naming.js b/lib/plugins/aws/lib/naming.js
index e81d281fe..82fe10abe 100644
--- a/lib/plugins/aws/lib/naming.js
+++ b/lib/plugins/aws/lib/naming.js
@@ -246,6 +246,11 @@ module.exports = {
.getNormalizedFunctionName(functionName)}LogsSubscriptionFilterCloudWatchLog${logsIndex}`;
},
+ // Cognito User Pool
+ getCognitoUserPoolLogicalId(poolId) {
+ return `CognitoUserPool${this.normalizeNameToAlphaNumericOnly(poolId)}`;
+ },
+
// Permissions
getLambdaS3PermissionLogicalId(functionName, bucketName) {
return `${this.getNormalizedFunctionName(functionName)}LambdaPermission${this
@@ -278,4 +283,9 @@ module.exports = {
return `${this.getNormalizedFunctionName(functionName)
}LambdaPermissionLogsSubscriptionFilterCloudWatchLog${logsIndex}`;
},
+ getLambdaCognitoUserPoolPermissionLogicalId(functionName, poolId, triggerSource) {
+ return `${this
+ .getNormalizedFunctionName(functionName)}LambdaPermissionCognitoUserPool${
+ this.normalizeNameToAlphaNumericOnly(poolId)}TriggerSource${triggerSource}`;
+ },
};
diff --git a/lib/plugins/aws/lib/naming.test.js b/lib/plugins/aws/lib/naming.test.js
index 950e92ff0..ae1f77de0 100644
--- a/lib/plugins/aws/lib/naming.test.js
+++ b/lib/plugins/aws/lib/naming.test.js
@@ -388,6 +388,13 @@ describe('#naming()', () => {
});
});
+ describe('#getCognitoUserPoolLogicalId()', () => {
+ it('should normalize the user pool name and add the standard prefix', () => {
+ expect(sdk.naming.getCognitoUserPoolLogicalId('us-east-1_v123sDAS1'))
+ .to.equal('CognitoUserPoolUseast1v123sDAS1');
+ });
+ });
+
describe('#getLambdaS3PermissionLogicalId()', () => {
it('should normalize the function name and add the standard suffix', () => {
expect(sdk.naming.getLambdaS3PermissionLogicalId('functionName', 'bucket'))
@@ -463,4 +470,14 @@ describe('#naming()', () => {
.to.equal('FunctionNameLambdaPermissionLogsSubscriptionFilterCloudWatchLog0');
});
});
+
+ describe('#getLambdaCognitoUserPoolPermissionLogicalId()', () => {
+ it('should normalize the function name and add the standard suffix', () => {
+ expect(sdk.naming.getLambdaCognitoUserPoolPermissionLogicalId(
+ 'functionName',
+ 'Pool1',
+ 'CustomMessage'
+ )).to.equal('FunctionNameLambdaPermissionCognitoUserPoolPool1TriggerSourceCustomMessage');
+ });
+ });
});
diff --git a/lib/plugins/aws/package/compile/events/cognitoUserPool/index.js b/lib/plugins/aws/package/compile/events/cognitoUserPool/index.js
new file mode 100644
index 000000000..d94063701
--- /dev/null
+++ b/lib/plugins/aws/package/compile/events/cognitoUserPool/index.js
@@ -0,0 +1,164 @@
+'use strict';
+
+const _ = require('lodash');
+
+const validTriggerSources = [
+ 'PreSignUp',
+ 'PostConfirmation',
+ 'PreAuthentication',
+ 'PostAuthentication',
+ 'CustomMessage',
+ 'DefineAuthChallenge',
+ 'CreateAuthChallenge',
+ 'VerifyAuthChallengeResponse',
+];
+
+class AwsCompileCognitoUserPoolEvents {
+ constructor(serverless) {
+ this.serverless = serverless;
+ this.provider = this.serverless.getProvider('aws');
+
+ this.hooks = {
+ 'package:compileEvents': this.compileCognitoUserPoolEvents.bind(this),
+ };
+ }
+
+ compileCognitoUserPoolEvents() {
+ const userPools = [];
+ const cognitoUserPoolTriggerFunctions = [];
+
+ // Iterate through all functions declared in `serverless.yml`
+ this.serverless.service.getAllFunctions().forEach((functionName) => {
+ const functionObj = this.serverless.service.getFunction(functionName);
+
+ if (functionObj.events) {
+ functionObj.events.forEach(event => {
+ if (event.cognitoUserPool) {
+ // Check event definition for `cognitoUserPool` object
+ if (typeof event.cognitoUserPool === 'object') {
+ // Check `cognitoUserPool` object has required properties
+ if (!event.cognitoUserPool.pool || !event.cognitoUserPool.trigger) {
+ throw new this.serverless.classes
+ .Error([
+ `Cognito User Pool event of function "${functionName}" is not an object.`,
+ 'The correct syntax is an object with the "pool" and "trigger" properties.',
+ 'Please check the docs for more info.',
+ ].join(' '));
+ }
+
+ // Check `cognitoUserPool` trigger is valid
+ if (!_.includes(validTriggerSources, event.cognitoUserPool.trigger)) {
+ throw new this.serverless.classes
+ .Error([
+ 'Cognito User Pool trigger source is invalid, must be one of:',
+ `${validTriggerSources.join(', ')}.`,
+ 'Please check the docs for more info.',
+ ].join(' '));
+ }
+
+ // Save trigger functions so we can use them to generate
+ // IAM permissions later
+ cognitoUserPoolTriggerFunctions.push({
+ functionName,
+ poolName: event.cognitoUserPool.pool,
+ triggerSource: event.cognitoUserPool.trigger,
+ });
+
+ // Save user pools so we can use them to generate
+ // CloudFormation resources later
+ userPools.push(event.cognitoUserPool.pool);
+ } else {
+ throw new this.serverless.classes
+ .Error([
+ `Cognito User Pool event of function "${functionName}" is not an object.`,
+ 'The correct syntax is an object with the "pool" and "trigger" properties.',
+ 'Please check the docs for more info.',
+ ].join(' '));
+ }
+ }
+ });
+ }
+ });
+
+ // Generate CloudFormation templates for Cognito User Pool changes
+ _.forEach(userPools, (poolName) => {
+ // Create a `LambdaConfig` object for the CloudFormation template
+ const currentPoolTriggerFunctions = _.filter(cognitoUserPoolTriggerFunctions, {
+ poolName,
+ });
+
+ const lambdaConfig = _.reduce(currentPoolTriggerFunctions, (result, value) => {
+ const lambdaLogicalId = this.provider.naming.getLambdaLogicalId(value.functionName);
+
+ // Return a new object to avoid lint errors
+ return Object.assign({}, result, {
+ [value.triggerSource]: {
+ 'Fn::GetAtt': [
+ lambdaLogicalId,
+ 'Arn',
+ ],
+ },
+ });
+ }, {});
+
+ const userPoolLogicalId = this.provider.naming.getCognitoUserPoolLogicalId(poolName);
+
+ const DependsOn = _.map(currentPoolTriggerFunctions, (value) => this
+ .provider.naming.getLambdaLogicalId(value.functionName));
+
+ const userPoolTemplate = {
+ Type: 'AWS::Cognito::UserPool',
+ Properties: {
+ UserPoolName: poolName,
+ LambdaConfig: lambdaConfig,
+ },
+ DependsOn,
+ };
+
+ const userPoolCFResource = {
+ [userPoolLogicalId]: userPoolTemplate,
+ };
+
+ _.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
+ userPoolCFResource);
+ });
+
+ // Generate CloudFormation templates for IAM permissions to allow Cognito to trigger Lambda
+ cognitoUserPoolTriggerFunctions.forEach((cognitoUserPoolTriggerFunction) => {
+ const userPoolLogicalId = this.provider.naming
+ .getCognitoUserPoolLogicalId(cognitoUserPoolTriggerFunction.poolName);
+ const lambdaLogicalId = this.provider.naming
+ .getLambdaLogicalId(cognitoUserPoolTriggerFunction.functionName);
+
+ const permissionTemplate = {
+ Type: 'AWS::Lambda::Permission',
+ Properties: {
+ FunctionName: {
+ 'Fn::GetAtt': [
+ lambdaLogicalId,
+ 'Arn',
+ ],
+ },
+ Action: 'lambda:InvokeFunction',
+ Principal: 'cognito-idp.amazonaws.com',
+ SourceArn: {
+ 'Fn::GetAtt': [
+ userPoolLogicalId,
+ 'Arn',
+ ],
+ },
+ },
+ };
+ const lambdaPermissionLogicalId = this.provider.naming
+ .getLambdaCognitoUserPoolPermissionLogicalId(cognitoUserPoolTriggerFunction.functionName,
+ cognitoUserPoolTriggerFunction.poolName, cognitoUserPoolTriggerFunction.triggerSource);
+ const permissionCFResource = {
+ [lambdaPermissionLogicalId]: permissionTemplate,
+ };
+ _.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
+ permissionCFResource);
+ });
+ }
+}
+
+module.exports = AwsCompileCognitoUserPoolEvents;
diff --git a/lib/plugins/aws/package/compile/events/cognitoUserPool/index.test.js b/lib/plugins/aws/package/compile/events/cognitoUserPool/index.test.js
new file mode 100644
index 000000000..6ec9a6c28
--- /dev/null
+++ b/lib/plugins/aws/package/compile/events/cognitoUserPool/index.test.js
@@ -0,0 +1,282 @@
+'use strict';
+
+const expect = require('chai').expect;
+const AwsProvider = require('../../../../provider/awsProvider');
+const AwsCompileCognitoUserPoolEvents = require('./index');
+const Serverless = require('../../../../../../Serverless');
+
+describe('AwsCompileCognitoUserPoolEvents', () => {
+ let serverless;
+ let awsCompileCognitoUserPoolEvents;
+
+ beforeEach(() => {
+ serverless = new Serverless();
+ serverless.service.provider.compiledCloudFormationTemplate = { Resources: {} };
+ serverless.setProvider('aws', new AwsProvider(serverless));
+ awsCompileCognitoUserPoolEvents = new AwsCompileCognitoUserPoolEvents(serverless);
+ awsCompileCognitoUserPoolEvents.serverless.service.service = 'new-service';
+ });
+
+ describe('#constructor()', () => {
+ it('should set the provider variable to an instance of AwsProvider', () =>
+ expect(awsCompileCognitoUserPoolEvents.provider).to.be.instanceof(AwsProvider));
+ });
+
+ describe('#compileCognitoUserPoolEvents()', () => {
+ it('should throw an error if cognitoUserPool event type is not an object', () => {
+ awsCompileCognitoUserPoolEvents.serverless.service.functions = {
+ first: {
+ events: [
+ {
+ cognitoUserPool: 42,
+ },
+ ],
+ },
+ };
+
+ expect(() => awsCompileCognitoUserPoolEvents.compileCognitoUserPoolEvents()).to.throw(Error);
+ });
+
+ it('should throw an error if the "pool" property is not given', () => {
+ awsCompileCognitoUserPoolEvents.serverless.service.functions = {
+ first: {
+ events: [
+ {
+ cognitoUserPool: {
+ pool: null,
+ },
+ },
+ ],
+ },
+ };
+
+ expect(() => awsCompileCognitoUserPoolEvents.compileCognitoUserPoolEvents()).to.throw(Error);
+ });
+
+ it('should throw an error if the "trigger" property is not given', () => {
+ awsCompileCognitoUserPoolEvents.serverless.service.functions = {
+ first: {
+ events: [
+ {
+ cognitoUserPool: {
+ trigger: null,
+ },
+ },
+ ],
+ },
+ };
+
+ expect(() => awsCompileCognitoUserPoolEvents.compileCognitoUserPoolEvents()).to.throw(Error);
+ });
+
+ it('should throw an error if the "trigger" property is invalid', () => {
+ awsCompileCognitoUserPoolEvents.serverless.service.functions = {
+ first: {
+ events: [
+ {
+ cognitoUserPool: {
+ pool: 'MyUserPool',
+ trigger: 'invalidTrigger',
+ },
+ },
+ ],
+ },
+ };
+
+ expect(() => awsCompileCognitoUserPoolEvents.compileCognitoUserPoolEvents()).to.throw(Error);
+ });
+
+ it('should create resources when CUP events are given as separate functions', () => {
+ awsCompileCognitoUserPoolEvents.serverless.service.functions = {
+ first: {
+ events: [
+ {
+ cognitoUserPool: {
+ pool: 'MyUserPool1',
+ trigger: 'PreSignUp',
+ },
+ },
+ ],
+ },
+ second: {
+ events: [
+ {
+ cognitoUserPool: {
+ pool: 'MyUserPool2',
+ trigger: 'PostConfirmation',
+ },
+ },
+ ],
+ },
+ };
+
+ awsCompileCognitoUserPoolEvents.compileCognitoUserPoolEvents();
+
+ expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
+ .compiledCloudFormationTemplate.Resources.CognitoUserPoolMyUserPool1.Type
+ ).to.equal('AWS::Cognito::UserPool');
+ expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
+ .compiledCloudFormationTemplate.Resources.CognitoUserPoolMyUserPool2.Type
+ ).to.equal('AWS::Cognito::UserPool');
+ expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
+ .compiledCloudFormationTemplate.Resources
+ .FirstLambdaPermissionCognitoUserPoolMyUserPool1TriggerSourcePreSignUp.Type
+ ).to.equal('AWS::Lambda::Permission');
+ expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
+ .compiledCloudFormationTemplate.Resources
+ .SecondLambdaPermissionCognitoUserPoolMyUserPool2TriggerSourcePostConfirmation.Type
+ ).to.equal('AWS::Lambda::Permission');
+ });
+
+ it('should create resources when CUP events are given with the same function', () => {
+ awsCompileCognitoUserPoolEvents.serverless.service.functions = {
+ first: {
+ events: [
+ {
+ cognitoUserPool: {
+ pool: 'MyUserPool1',
+ trigger: 'PreSignUp',
+ },
+ },
+ {
+ cognitoUserPool: {
+ pool: 'MyUserPool2',
+ trigger: 'PostConfirmation',
+ },
+ },
+ ],
+ },
+ };
+
+ awsCompileCognitoUserPoolEvents.compileCognitoUserPoolEvents();
+
+ expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
+ .compiledCloudFormationTemplate.Resources.CognitoUserPoolMyUserPool1.Type
+ ).to.equal('AWS::Cognito::UserPool');
+ expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
+ .compiledCloudFormationTemplate.Resources.CognitoUserPoolMyUserPool2.Type
+ ).to.equal('AWS::Cognito::UserPool');
+ expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
+ .compiledCloudFormationTemplate.Resources
+ .FirstLambdaPermissionCognitoUserPoolMyUserPool1TriggerSourcePreSignUp.Type
+ ).to.equal('AWS::Lambda::Permission');
+ expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
+ .compiledCloudFormationTemplate.Resources
+ .FirstLambdaPermissionCognitoUserPoolMyUserPool2TriggerSourcePostConfirmation.Type
+ ).to.equal('AWS::Lambda::Permission');
+ });
+
+ it('should create resources when CUP events are given with diff funcs and single event', () => {
+ awsCompileCognitoUserPoolEvents.serverless.service.functions = {
+ first: {
+ events: [
+ {
+ cognitoUserPool: {
+ pool: 'MyUserPool1',
+ trigger: 'PreSignUp',
+ },
+ },
+ ],
+ },
+ second: {
+ events: [
+ {
+ cognitoUserPool: {
+ pool: 'MyUserPool2',
+ trigger: 'PreSignUp',
+ },
+ },
+ ],
+ },
+ };
+
+ awsCompileCognitoUserPoolEvents.compileCognitoUserPoolEvents();
+
+ expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
+ .compiledCloudFormationTemplate.Resources.CognitoUserPoolMyUserPool1.Type
+ ).to.equal('AWS::Cognito::UserPool');
+ expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
+ .compiledCloudFormationTemplate.Resources.CognitoUserPoolMyUserPool1
+ .Properties.LambdaConfig.PreSignUp['Fn::GetAtt'][0]
+ ).to.equal(serverless.service.serverless.getProvider('aws')
+ .naming.getLambdaLogicalId('first'));
+
+ expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
+ .compiledCloudFormationTemplate.Resources.CognitoUserPoolMyUserPool2.Type
+ ).to.equal('AWS::Cognito::UserPool');
+ expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
+ .compiledCloudFormationTemplate.Resources.CognitoUserPoolMyUserPool2
+ .Properties.LambdaConfig.PreSignUp['Fn::GetAtt'][0]
+ ).to.equal(serverless.service.serverless.getProvider('aws')
+ .naming.getLambdaLogicalId('second'));
+
+ expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
+ .compiledCloudFormationTemplate.Resources
+ .FirstLambdaPermissionCognitoUserPoolMyUserPool1TriggerSourcePreSignUp.Type
+ ).to.equal('AWS::Lambda::Permission');
+ expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
+ .compiledCloudFormationTemplate.Resources
+ .SecondLambdaPermissionCognitoUserPoolMyUserPool2TriggerSourcePreSignUp.Type
+ ).to.equal('AWS::Lambda::Permission');
+ });
+
+ it('should create single user pool resource when the same pool referenced repeatedly', () => {
+ awsCompileCognitoUserPoolEvents.serverless.service.functions = {
+ first: {
+ events: [
+ {
+ cognitoUserPool: {
+ pool: 'MyUserPool',
+ trigger: 'PreSignUp',
+ },
+ },
+ ],
+ },
+ second: {
+ events: [
+ {
+ cognitoUserPool: {
+ pool: 'MyUserPool',
+ trigger: 'PostConfirmation',
+ },
+ },
+ ],
+ },
+ };
+
+ awsCompileCognitoUserPoolEvents.compileCognitoUserPoolEvents();
+
+ expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
+ .compiledCloudFormationTemplate.Resources
+ .CognitoUserPoolMyUserPool.Type
+ ).to.equal('AWS::Cognito::UserPool');
+ expect(Object.keys(awsCompileCognitoUserPoolEvents.serverless.service.provider
+ .compiledCloudFormationTemplate.Resources
+ .CognitoUserPoolMyUserPool.Properties.LambdaConfig).length
+ ).to.equal(2);
+ expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
+ .compiledCloudFormationTemplate.Resources
+ .FirstLambdaPermissionCognitoUserPoolMyUserPoolTriggerSourcePreSignUp.Type
+ ).to.equal('AWS::Lambda::Permission');
+ expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
+ .compiledCloudFormationTemplate.Resources
+ .SecondLambdaPermissionCognitoUserPoolMyUserPoolTriggerSourcePostConfirmation.Type
+ ).to.equal('AWS::Lambda::Permission');
+ });
+
+ it('should not create resources when CUP events are not given', () => {
+ awsCompileCognitoUserPoolEvents.serverless.service.functions = {
+ first: {
+ events: [],
+ },
+ };
+
+ awsCompileCognitoUserPoolEvents.compileCognitoUserPoolEvents();
+
+ expect(
+ awsCompileCognitoUserPoolEvents.serverless.service.provider
+ .compiledCloudFormationTemplate.Resources
+ ).to.deep.equal({});
+ });
+ });
+});
diff --git a/lib/plugins/create/templates/aws-csharp/serverless.yml b/lib/plugins/create/templates/aws-csharp/serverless.yml
index 57e708604..e1f60bedb 100644
--- a/lib/plugins/create/templates/aws-csharp/serverless.yml
+++ b/lib/plugins/create/templates/aws-csharp/serverless.yml
@@ -79,6 +79,9 @@ functions:
# state:
# - pending
# - cloudwatchLog: '/aws/lambda/hello'
+# - cognitoUserPool:
+# pool: MyUserPool
+# trigger: PreSignUp
# Define function environment variables here
# environment:
diff --git a/lib/plugins/create/templates/aws-groovy-gradle/serverless.yml b/lib/plugins/create/templates/aws-groovy-gradle/serverless.yml
index ca9c60b82..9ef210f6b 100644
--- a/lib/plugins/create/templates/aws-groovy-gradle/serverless.yml
+++ b/lib/plugins/create/templates/aws-groovy-gradle/serverless.yml
@@ -77,6 +77,9 @@ functions:
# state:
# - pending
# - cloudwatchLog: '/aws/lambda/hello'
+# - cognitoUserPool:
+# pool: MyUserPool
+# trigger: PreSignUp
# Define function environment variables here
# environment:
diff --git a/lib/plugins/create/templates/aws-java-gradle/serverless.yml b/lib/plugins/create/templates/aws-java-gradle/serverless.yml
index 53a22f47c..d421ab1d5 100644
--- a/lib/plugins/create/templates/aws-java-gradle/serverless.yml
+++ b/lib/plugins/create/templates/aws-java-gradle/serverless.yml
@@ -77,6 +77,9 @@ functions:
# state:
# - pending
# - cloudwatchLog: '/aws/lambda/hello'
+# - cognitoUserPool:
+# pool: MyUserPool
+# trigger: PreSignUp
# Define function environment variables here
# environment:
diff --git a/lib/plugins/create/templates/aws-java-maven/serverless.yml b/lib/plugins/create/templates/aws-java-maven/serverless.yml
index a677a2212..d6fe45620 100644
--- a/lib/plugins/create/templates/aws-java-maven/serverless.yml
+++ b/lib/plugins/create/templates/aws-java-maven/serverless.yml
@@ -77,6 +77,9 @@ functions:
# state:
# - pending
# - cloudwatchLog: '/aws/lambda/hello'
+# - cognitoUserPool:
+# pool: MyUserPool
+# trigger: PreSignUp
# Define function environment variables here
# environment:
diff --git a/lib/plugins/create/templates/aws-nodejs/serverless.yml b/lib/plugins/create/templates/aws-nodejs/serverless.yml
index 6cdb54b2c..059b386d4 100644
--- a/lib/plugins/create/templates/aws-nodejs/serverless.yml
+++ b/lib/plugins/create/templates/aws-nodejs/serverless.yml
@@ -82,6 +82,9 @@ functions:
# state:
# - pending
# - cloudwatchLog: '/aws/lambda/hello'
+# - cognitoUserPool:
+# pool: MyUserPool
+# trigger: PreSignUp
# Define function environment variables here
# environment:
diff --git a/lib/plugins/create/templates/aws-python/serverless.yml b/lib/plugins/create/templates/aws-python/serverless.yml
index d3d0b6285..110ae584f 100644
--- a/lib/plugins/create/templates/aws-python/serverless.yml
+++ b/lib/plugins/create/templates/aws-python/serverless.yml
@@ -82,6 +82,9 @@ functions:
# state:
# - pending
# - cloudwatchLog: '/aws/lambda/hello'
+# - cognitoUserPool:
+# pool: MyUserPool
+# trigger: PreSignUp
# Define function environment variables here
# environment:
diff --git a/lib/plugins/create/templates/aws-python3/serverless.yml b/lib/plugins/create/templates/aws-python3/serverless.yml
index 156d8608a..73cce39e6 100644
--- a/lib/plugins/create/templates/aws-python3/serverless.yml
+++ b/lib/plugins/create/templates/aws-python3/serverless.yml
@@ -82,6 +82,9 @@ functions:
# state:
# - pending
# - cloudwatchLog: '/aws/lambda/hello'
+# - cognitoUserPool:
+# pool: MyUserPool
+# trigger: PreSignUp
# Define function environment variables here
# environment:
diff --git a/lib/plugins/create/templates/aws-scala-sbt/serverless.yml b/lib/plugins/create/templates/aws-scala-sbt/serverless.yml
index 309390a97..c7ce81f69 100644
--- a/lib/plugins/create/templates/aws-scala-sbt/serverless.yml
+++ b/lib/plugins/create/templates/aws-scala-sbt/serverless.yml
@@ -79,6 +79,9 @@ functions:
# state:
# - pending
# - cloudwatchLog: '/aws/lambda/hello'
+# - cognitoUserPool:
+# pool: MyUserPool
+# trigger: PreSignUp
# Define function environment variables here
# environment:
diff --git a/tests/integration/aws/cognito-user-pool/multiple-pools-multiple-events-multiple-functions/service/handler.js b/tests/integration/aws/cognito-user-pool/multiple-pools-multiple-events-multiple-functions/service/handler.js
new file mode 100644
index 000000000..a1e2afe62
--- /dev/null
+++ b/tests/integration/aws/cognito-user-pool/multiple-pools-multiple-events-multiple-functions/service/handler.js
@@ -0,0 +1,27 @@
+'use strict';
+
+const preSignUp = (event, context, callback) => {
+ const nextEvent = Object.assign({}, event);
+ nextEvent.response.autoConfirmUser = true;
+
+ process.stdout.write(JSON.stringify(nextEvent));
+ callback(null, nextEvent);
+};
+
+const customMessage = (event, context, callback) => {
+ const nextEvent = Object.assign({}, event);
+ if (event.triggerSource === 'CustomMessage_SignUp') {
+ nextEvent.response.smsMessage = `Welcome to the service. Your confirmation code is ${
+ event.request.codeParameter}`;
+ nextEvent.response.emailSubject = 'Welcome to the service';
+ nextEvent.response.emailMessage = `Thank you for signing up. ${
+ event.request.codeParameter} is your verification code`;
+ }
+ process.stdout.write(JSON.stringify(nextEvent));
+ callback(null, nextEvent);
+};
+
+module.exports.preSignUp1 = preSignUp;
+module.exports.preSignUp2 = preSignUp;
+module.exports.customMessage1 = customMessage;
+module.exports.customMessage2 = customMessage;
diff --git a/tests/integration/aws/cognito-user-pool/multiple-pools-multiple-events-multiple-functions/service/serverless.yml b/tests/integration/aws/cognito-user-pool/multiple-pools-multiple-events-multiple-functions/service/serverless.yml
new file mode 100644
index 000000000..7dc6f310a
--- /dev/null
+++ b/tests/integration/aws/cognito-user-pool/multiple-pools-multiple-events-multiple-functions/service/serverless.yml
@@ -0,0 +1,31 @@
+service: aws-nodejs
+
+provider:
+ name: aws
+ runtime: nodejs6.10
+
+functions:
+ preSignUp1:
+ handler: handler.preSignUp1
+ events:
+ - cognitoUserPool:
+ pool: ${env:COGNITO_USER_POOL_1}
+ trigger: PreSignUp
+ customMessage1:
+ handler: handler.customMessage1
+ events:
+ - cognitoUserPool:
+ pool: ${env:COGNITO_USER_POOL_1}
+ trigger: CustomMessage
+ preSignUp2:
+ handler: handler.preSignUp2
+ events:
+ - cognitoUserPool:
+ pool: ${env:COGNITO_USER_POOL_2}
+ trigger: PreSignUp
+ customMessage2:
+ handler: handler.customMessage2
+ events:
+ - cognitoUserPool:
+ pool: ${env:COGNITO_USER_POOL_2}
+ trigger: CustomMessage
diff --git a/tests/integration/aws/cognito-user-pool/multiple-pools-multiple-events-multiple-functions/tests.js b/tests/integration/aws/cognito-user-pool/multiple-pools-multiple-events-multiple-functions/tests.js
new file mode 100644
index 000000000..df2ba5d40
--- /dev/null
+++ b/tests/integration/aws/cognito-user-pool/multiple-pools-multiple-events-multiple-functions/tests.js
@@ -0,0 +1,77 @@
+'use strict';
+
+const path = require('path');
+const expect = require('chai').expect;
+const Utils = require('../../../../utils/index');
+
+describe('AWS - Cognito User Pool: Multiple User Pools with multiple ' +
+ 'events with multiple functions', () => {
+ beforeAll(() => {
+ Utils.createTestService('aws-nodejs', path.join(__dirname, 'service'));
+ Utils.deployService();
+ });
+
+ it('should call the specified function on the first User Pool when PreSignUp ' +
+ 'event is triggered', () => Utils
+ .getCognitoUserPoolId(process.env.COGNITO_USER_POOL_1)
+ .then((poolId) =>
+ Promise.all([
+ poolId,
+ Utils.createCognitoUser(poolId, 'test@test.com', 'Password123!'),
+ ])
+ )
+ .delay(60000)
+ .then((promiseResponse) => {
+ const poolId = promiseResponse[0];
+ const logs = Utils.getFunctionLogs('preSignUp1');
+
+ expect(RegExp(`"userPoolId":"${poolId}"`, 'g').test(logs)).to.equal(true);
+ expect(/"triggerSource":"PreSignUp_\w+"/g.test(logs)).to.equal(true);
+ })
+ );
+
+ it('should call the specified function on the first User Pool when CustomMessage ' +
+ 'event is triggered', () => Utils
+ .getCognitoUserPoolId(process.env.COGNITO_USER_POOL_1)
+ .then((poolId) => {
+ const logs = Utils.getFunctionLogs('customMessage1');
+
+ expect(RegExp(`"userPoolId":"${poolId}"`, 'g').test(logs)).to.equal(true);
+ expect(/"triggerSource":"CustomMessage_AdminCreateUser"/g.test(logs)).to.equal(true);
+ })
+ );
+
+ it('should call the specified function on the second User Pool when PreSignUp ' +
+ 'event is triggered', () => Utils
+ .getCognitoUserPoolId(process.env.COGNITO_USER_POOL_2)
+ .then((poolId) =>
+ Promise.all([
+ poolId,
+ Utils.createCognitoUser(poolId, 'test@test.com', 'Password123!'),
+ ])
+ )
+ .delay(60000)
+ .then((promiseResponse) => {
+ const poolId = promiseResponse[0];
+ const logs = Utils.getFunctionLogs('preSignUp2');
+
+ expect(RegExp(`"userPoolId":"${poolId}"`, 'g').test(logs)).to.equal(true);
+ expect(/"triggerSource":"PreSignUp_\w+"/g.test(logs)).to.equal(true);
+ })
+ );
+
+ it('should call the specified function on the second User Pool when CustomMessage ' +
+ 'event is triggered', () => Utils
+ .getCognitoUserPoolId(process.env.COGNITO_USER_POOL_2)
+ .then((poolId) => {
+ const logs = Utils.getFunctionLogs('customMessage2');
+
+ expect(RegExp(`"userPoolId":"${poolId}"`, 'g').test(logs)).to.equal(true);
+ expect(/"triggerSource":"CustomMessage_AdminCreateUser"/g.test(logs)).to.equal(true);
+ })
+ );
+
+ afterAll(() => {
+ Utils.removeService();
+ });
+});
diff --git a/tests/integration/aws/cognito-user-pool/multiple-pools-single-event-single-function/service/handler.js b/tests/integration/aws/cognito-user-pool/multiple-pools-single-event-single-function/service/handler.js
new file mode 100644
index 000000000..b7f044321
--- /dev/null
+++ b/tests/integration/aws/cognito-user-pool/multiple-pools-single-event-single-function/service/handler.js
@@ -0,0 +1,9 @@
+'use strict';
+
+module.exports.preSignUp = (event, context, callback) => {
+ const nextEvent = Object.assign({}, event);
+ nextEvent.response.autoConfirmUser = true;
+
+ process.stdout.write(JSON.stringify(nextEvent));
+ callback(null, nextEvent);
+};
diff --git a/tests/integration/aws/cognito-user-pool/multiple-pools-single-event-single-function/service/serverless.yml b/tests/integration/aws/cognito-user-pool/multiple-pools-single-event-single-function/service/serverless.yml
new file mode 100644
index 000000000..121de6025
--- /dev/null
+++ b/tests/integration/aws/cognito-user-pool/multiple-pools-single-event-single-function/service/serverless.yml
@@ -0,0 +1,16 @@
+service: aws-nodejs
+
+provider:
+ name: aws
+ runtime: nodejs6.10
+
+functions:
+ preSignUp:
+ handler: handler.preSignUp
+ events:
+ - cognitoUserPool:
+ pool: ${env:COGNITO_USER_POOL_1}
+ trigger: PreSignUp
+ - cognitoUserPool:
+ pool: ${env:COGNITO_USER_POOL_2}
+ trigger: PreSignUp
diff --git a/tests/integration/aws/cognito-user-pool/multiple-pools-single-event-single-function/tests.js b/tests/integration/aws/cognito-user-pool/multiple-pools-single-event-single-function/tests.js
new file mode 100644
index 000000000..9a9477545
--- /dev/null
+++ b/tests/integration/aws/cognito-user-pool/multiple-pools-single-event-single-function/tests.js
@@ -0,0 +1,53 @@
+'use strict';
+
+const path = require('path');
+const expect = require('chai').expect;
+const Utils = require('../../../../utils/index');
+
+describe('AWS - Cognito User Pool: Multiple User Pools with single ' +
+ 'event with single function', () => {
+ beforeAll(() => {
+ Utils.createTestService('aws-nodejs', path.join(__dirname, 'service'));
+ Utils.deployService();
+ });
+
+ it('should call the specified function on the first User Pool when PreSignUp ' +
+ 'event is triggered', () => Utils
+ .getCognitoUserPoolId(process.env.COGNITO_USER_POOL_1)
+ .then((poolId) =>
+ Promise.all([
+ poolId,
+ Utils.createCognitoUser(poolId, 'test@test.com', 'Password123!'),
+ ])
+ )
+ .delay(60000)
+ .then((promiseResponse) => {
+ const poolId = promiseResponse[0];
+ const logs = Utils.getFunctionLogs('preSignUp');
+ expect(RegExp(`"userPoolId":"${poolId}"`, 'g').test(logs)).to.equal(true);
+ expect(/"triggerSource":"PreSignUp_\w+"/g.test(logs)).to.equal(true);
+ })
+ );
+
+ it('should call the specified function on the second User Pool when PreSignUp ' +
+ 'event is triggered', () => Utils
+ .getCognitoUserPoolId(process.env.COGNITO_USER_POOL_2)
+ .then((poolId) =>
+ Promise.all([
+ poolId,
+ Utils.createCognitoUser(poolId, 'test@test.com', 'Password123!'),
+ ])
+ )
+ .delay(60000)
+ .then((promiseResponse) => {
+ const poolId = promiseResponse[0];
+ const logs = Utils.getFunctionLogs('preSignUp');
+ expect(RegExp(`"userPoolId":"${poolId}"`, 'g').test(logs)).to.equal(true);
+ expect(/"triggerSource":"PreSignUp_\w+"/g.test(logs)).to.equal(true);
+ })
+ );
+
+ afterAll(() => {
+ Utils.removeService();
+ });
+});
diff --git a/tests/integration/aws/cognito-user-pool/single-pool-multiple-events-multiple-functions/service/handler.js b/tests/integration/aws/cognito-user-pool/single-pool-multiple-events-multiple-functions/service/handler.js
new file mode 100644
index 000000000..2801cf8c5
--- /dev/null
+++ b/tests/integration/aws/cognito-user-pool/single-pool-multiple-events-multiple-functions/service/handler.js
@@ -0,0 +1,22 @@
+'use strict';
+
+module.exports.preSignUp = (event, context, callback) => {
+ const nextEvent = Object.assign({}, event);
+ nextEvent.response.autoConfirmUser = true;
+
+ process.stdout.write(JSON.stringify(nextEvent));
+ callback(null, nextEvent);
+};
+
+module.exports.customMessage = (event, context, callback) => {
+ const nextEvent = Object.assign({}, event);
+ if (event.triggerSource === 'CustomMessage_SignUp') {
+ nextEvent.response.smsMessage = `Welcome to the service. Your confirmation code is ${
+ event.request.codeParameter}`;
+ nextEvent.response.emailSubject = 'Welcome to the service';
+ nextEvent.response.emailMessage = `Thank you for signing up. ${
+ event.request.codeParameter} is your verification code`;
+ }
+ process.stdout.write(JSON.stringify(nextEvent));
+ callback(null, nextEvent);
+};
diff --git a/tests/integration/aws/cognito-user-pool/single-pool-multiple-events-multiple-functions/service/serverless.yml b/tests/integration/aws/cognito-user-pool/single-pool-multiple-events-multiple-functions/service/serverless.yml
new file mode 100644
index 000000000..9ecaf3f5f
--- /dev/null
+++ b/tests/integration/aws/cognito-user-pool/single-pool-multiple-events-multiple-functions/service/serverless.yml
@@ -0,0 +1,19 @@
+service: aws-nodejs
+
+provider:
+ name: aws
+ runtime: nodejs6.10
+
+functions:
+ preSignUp:
+ handler: handler.preSignUp
+ events:
+ - cognitoUserPool:
+ pool: ${env:COGNITO_USER_POOL_1}
+ trigger: PreSignUp
+ customMessage:
+ handler: handler.customMessage
+ events:
+ - cognitoUserPool:
+ pool: ${env:COGNITO_USER_POOL_1}
+ trigger: CustomMessage
diff --git a/tests/integration/aws/cognito-user-pool/single-pool-multiple-events-multiple-functions/tests.js b/tests/integration/aws/cognito-user-pool/single-pool-multiple-events-multiple-functions/tests.js
new file mode 100644
index 000000000..96d25c39b
--- /dev/null
+++ b/tests/integration/aws/cognito-user-pool/single-pool-multiple-events-multiple-functions/tests.js
@@ -0,0 +1,39 @@
+'use strict';
+
+const path = require('path');
+const expect = require('chai').expect;
+const Utils = require('../../../../utils/index');
+
+describe('AWS - Cognito User Pool: Single User Pool with multiple ' +
+ 'events with multiple functions', () => {
+ beforeAll(() => {
+ Utils.createTestService('aws-nodejs', path.join(__dirname, 'service'));
+ Utils.deployService();
+ });
+
+ it('should call the specified function when PreSignUp event is triggered', () => Utils
+ .getCognitoUserPoolId(process.env.COGNITO_USER_POOL_1)
+ .then((poolId) =>
+ Utils.createCognitoUser(poolId, 'test@test.com', 'Password123!')
+ )
+ .delay(60000)
+ .then(() => {
+ const logs = Utils.getFunctionLogs('preSignUp');
+ expect(/"triggerSource":"PreSignUp_\w+"/g.test(logs)).to.equal(true);
+ })
+ );
+
+ it('should call the specified function when CustomMessage event is triggered', () => Utils
+ .getCognitoUserPoolId(process.env.COGNITO_USER_POOL_1)
+ .then((poolId) => {
+ const logs = Utils.getFunctionLogs('customMessage');
+
+ expect(RegExp(`"userPoolId":"${poolId}"`, 'g').test(logs)).to.equal(true);
+ expect(/"triggerSource":"CustomMessage_AdminCreateUser"/g.test(logs)).to.equal(true);
+ })
+ );
+
+ afterAll(() => {
+ Utils.removeService();
+ });
+});
diff --git a/tests/integration/aws/cognito-user-pool/single-pool-single-event-single-function/service/handler.js b/tests/integration/aws/cognito-user-pool/single-pool-single-event-single-function/service/handler.js
new file mode 100644
index 000000000..b7f044321
--- /dev/null
+++ b/tests/integration/aws/cognito-user-pool/single-pool-single-event-single-function/service/handler.js
@@ -0,0 +1,9 @@
+'use strict';
+
+module.exports.preSignUp = (event, context, callback) => {
+ const nextEvent = Object.assign({}, event);
+ nextEvent.response.autoConfirmUser = true;
+
+ process.stdout.write(JSON.stringify(nextEvent));
+ callback(null, nextEvent);
+};
diff --git a/tests/integration/aws/cognito-user-pool/single-pool-single-event-single-function/service/serverless.yml b/tests/integration/aws/cognito-user-pool/single-pool-single-event-single-function/service/serverless.yml
new file mode 100644
index 000000000..97167e310
--- /dev/null
+++ b/tests/integration/aws/cognito-user-pool/single-pool-single-event-single-function/service/serverless.yml
@@ -0,0 +1,13 @@
+service: aws-nodejs
+
+provider:
+ name: aws
+ runtime: nodejs6.10
+
+functions:
+ preSignUp:
+ handler: handler.preSignUp
+ events:
+ - cognitoUserPool:
+ pool: ${env:COGNITO_USER_POOL_1}
+ trigger: PreSignUp
diff --git a/tests/integration/aws/cognito-user-pool/single-pool-single-event-single-function/tests.js b/tests/integration/aws/cognito-user-pool/single-pool-single-event-single-function/tests.js
new file mode 100644
index 000000000..b77837821
--- /dev/null
+++ b/tests/integration/aws/cognito-user-pool/single-pool-single-event-single-function/tests.js
@@ -0,0 +1,29 @@
+'use strict';
+
+const path = require('path');
+const expect = require('chai').expect;
+const Utils = require('../../../../utils/index');
+
+describe('AWS - Cognito User Pool: Single User Pool with single ' +
+ 'event with single function', () => {
+ beforeAll(() => {
+ Utils.createTestService('aws-nodejs', path.join(__dirname, 'service'));
+ Utils.deployService();
+ });
+
+ it('should call the specified function when PreSignUp event is triggered', () => Utils
+ .getCognitoUserPoolId(process.env.COGNITO_USER_POOL_1)
+ .then((poolId) =>
+ Utils.createCognitoUser(poolId, 'test@test.com', 'Password123!')
+ )
+ .delay(60000)
+ .then(() => {
+ const logs = Utils.getFunctionLogs('preSignUp');
+ expect(/"triggerSource":"PreSignUp_\w+"/g.test(logs)).to.equal(true);
+ })
+ );
+
+ afterAll(() => {
+ Utils.removeService();
+ });
+});
diff --git a/tests/utils/index.js b/tests/utils/index.js
index a6d6cd5a3..358f6a1bd 100644
--- a/tests/utils/index.js
+++ b/tests/utils/index.js
@@ -51,6 +51,8 @@ module.exports = {
process.env.TOPIC_2 = `${serviceName}-1`;
process.env.BUCKET_1 = `${serviceName}-1`;
process.env.BUCKET_2 = `${serviceName}-2`;
+ process.env.COGNITO_USER_POOL_1 = `${serviceName}-1`;
+ process.env.COGNITO_USER_POOL_2 = `${serviceName}-2`;
// return the name of the CloudFormation stack
return `${serviceName}-dev`;
@@ -163,6 +165,32 @@ module.exports = {
return cwe.putEventsPromised(params);
},
+ getCognitoUserPoolId(userPoolName) {
+ const cisp = new AWS.CognitoIdentityServiceProvider({ region: 'us-east-1' });
+ BbPromise.promisifyAll(cisp, { suffix: 'Promised' });
+
+ const params = {
+ MaxResults: 50,
+ };
+
+ return cisp.listUserPoolsPromised(params)
+ .then((data) => data.UserPools.find((userPool) =>
+ RegExp(userPoolName, 'g').test(userPool.Name)).Id
+ );
+ },
+
+ createCognitoUser(userPoolId, username, password) {
+ const cisp = new AWS.CognitoIdentityServiceProvider({ region: 'us-east-1' });
+ BbPromise.promisifyAll(cisp, { suffix: 'Promised' });
+
+ const params = {
+ UserPoolId: userPoolId,
+ Username: username,
+ TemporaryPassword: password,
+ };
+ return cisp.adminCreateUserPromised(params);
+ },
+
getFunctionLogs(functionName) {
const logs = execSync(`${serverlessExec} logs --function ${functionName} --noGreeting true`);
const logsString = new Buffer(logs, 'base64').toString();