-
Notifications
You must be signed in to change notification settings - Fork 276
/
add-cognito-user-pool-trigger.js
113 lines (111 loc) · 3.91 KB
/
add-cognito-user-pool-trigger.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
const loadConfig = require('../util/loadconfig'),
iamNameSanitize = require('../util/iam-name-sanitize'),
aws = require('aws-sdk'),
getOwnerInfo = require('../tasks/get-owner-info');
module.exports = function addCognitoUserPoolTrigger(options, optionalLogger) {
'use strict';
let lambdaConfig,
lambda,
cognito;
const initServices = function () {
lambda = new aws.Lambda({region: lambdaConfig.region});
cognito = new aws.CognitoIdentityServiceProvider({region: lambdaConfig.region});
},
readConfig = function () {
return loadConfig(options, {lambda: {name: true, region: true}})
.then(config => lambdaConfig = config.lambda)
.then(initServices)
.then(() => lambda.getFunctionConfiguration({FunctionName: lambdaConfig.name, Qualifier: options.version}).promise())
.then(result => {
lambdaConfig.arn = result.FunctionArn;
lambdaConfig.version = result.Version;
});
},
addInvokePermission = function (poolArn) {
const result = {
statementId: iamNameSanitize('lambda_' + Date.now()),
poolArn: poolArn
};
return lambda.addPermission({
Action: 'lambda:InvokeFunction',
FunctionName: lambdaConfig.name,
Principal: 'cognito-idp.amazonaws.com',
SourceArn: poolArn,
Qualifier: options.version,
StatementId: result.statementId
}).promise().then(() => result);
},
getPoolArn = function () {
return getOwnerInfo(options.region, optionalLogger)
.then(ownerInfo => `arn:${ownerInfo.partition}:cognito-idp:${lambdaConfig.region}:${ownerInfo.account}:userpool/${options['user-pool-id']}`);
},
cleanUpPoolConfig = function (data) {
/* cognito update requires the full config, not just a patch, but some attributes returned
* from describeUserPool are not accepted back into the configuration, so they have to be removed
*/
['Id', 'Name', 'LastModifiedDate', 'CreationDate', 'SchemaAttributes', 'EstimatedNumberOfUsers', 'AliasAttributes', 'UsernameAttributes', 'Arn', 'Domain'].forEach(n => delete data[n]);
if (data.AdminCreateUserConfig && data.AdminCreateUserConfig.UnusedAccountValidityDays) {
delete data.AdminCreateUserConfig.UnusedAccountValidityDays;
}
if (Object.keys(data.UserPoolAddOns || {}).length === 0) {
delete data.UserPoolAddOns;
}
},
patchPool = function () {
return cognito.describeUserPool({
UserPoolId: options['user-pool-id']
}).promise().then(result => {
const data = result.UserPool;
data.UserPoolId = data.Id;
data.LambdaConfig = data.LambdaConfig || {};
options.events.split(',').forEach(name => data.LambdaConfig[name] = lambdaConfig.arn);
cleanUpPoolConfig(data);
return cognito.updateUserPool(data).promise();
});
};
if (!options.events) {
return Promise.reject('events not specified. provide with --events');
}
if (!options['user-pool-id']) {
return Promise.reject('user pool id not specified. provide with --user-pool-id');
}
return readConfig()
.then(patchPool)
.then(getPoolArn)
.then(addInvokePermission);
};
module.exports.doc = {
description: 'Configures the Lambda to run on a Cognito User Pool trigger',
priority: 5,
args: [
{
argument: 'user-pool-id',
description: 'the Cognito User Pool ID',
example: 'us-east-1_2abcDEFG'
},
{
argument: 'events',
description: 'Names of triggers to set up (use comma to separate multiple events). See http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CognitoIdentityServiceProvider.html#updateUserPool-property for valid names',
example: 'PreSignUp,PreAuthentication'
},
{
argument: 'version',
optional: true,
description: 'Bind to a particular version',
example: 'production',
default: 'latest version'
},
{
argument: 'source',
optional: true,
description: 'Directory with project files',
default: 'current directory'
},
{
argument: 'config',
optional: true,
description: 'Config file containing the resource names',
default: 'claudia.json'
}
]
};