forked from jghaines/lambda-auth0-authorizer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlib.js
129 lines (105 loc) · 4.25 KB
/
lib.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
'use strict';
// static setup that can be done at load-time
var ACCESS_TOKEN_LENGTH = 16; // (aparent) length of an Autho0 access_token
// since AWS Lambda doesn't (yet) provide environment varibles, load them from .env
require('dotenv').config();
var fs = require('fs');
var Promise = require('bluebird');
Promise.longStackTraces();
var AWS = require('aws-sdk');
AWS.config.apiVersions = { dynamodb: '2012-08-10' };
if ( process.env.AWS_REGION ) {
AWS.config.update( { region: process.env.AWS_REGION } );
}
var dynamo = new AWS.DynamoDB.DocumentClient();
Promise.promisifyAll( Object.getPrototypeOf( dynamo ));
var policyDocumentFilename = 'policyDocument.json';
var policyDocument;
try {
policyDocument = JSON.parse(fs.readFileSync( __dirname + '/' + policyDocumentFilename, 'utf8'));
} catch (e) {
if (e.code === 'ENOENT') {
console.error('Expected ' + policyDocumentFilename + ' to be included in Lambda deployment package');
// fallthrough
}
throw e;
}
var dynamoParametersFilename = 'dynamo.json';
var dynamoParameters = null;
try {
dynamoParameters = JSON.parse(fs.readFileSync( __dirname + '/' + dynamoParametersFilename, 'utf8'));
} catch (e) {
if (e.code !== 'ENOENT') {
throw e;
}
// otherwise fallthrough
}
var AuthenticationClient = require('auth0').AuthenticationClient;
if ( typeof process.env.AUTH0_DOMAIN === "undefined" || ! process.env.AUTH0_DOMAIN.match( /\.auth0\.com$/ ) ) {
throw new Error( "Expected AUTHO_DOMAIN environment variable to be set in .env file. See https://manage.auth0.com/#/applications" )
}
if ( typeof process.env.AUTH0_CLIENTID === "undefined" || process.env.AUTH0_CLIENTID.length === 0 ) {
throw new Error( "Expected AUTH0_CLIENTID environment variable to be set in .env file. See https://manage.auth0.com/#/applications" )
}
var auth0 = new AuthenticationClient( {
domain : process.env.AUTH0_DOMAIN,
clientId : process.env.AUTH0_CLIENTID
} );
// extract and return the Bearer Token from the Lambda event parameters
var getToken = function( params ) {
var token;
if ( ! params.type || params.type !== 'TOKEN' ) {
throw new Error( "Expected 'event.type' parameter to have value TOKEN" );
}
var tokenString = params.authorizationToken;
if ( !tokenString ) {
throw new Error( "Expected 'event.authorizationToken' parameter to be set" );
}
var match = tokenString.match( /^Bearer (.*)$/ );
if ( ! match || match.length < 2 ) {
throw new Error( "Invalid Authorization token - '" + tokenString + "' does not match 'Bearer .*'" );
}
return match[1];
}
// if dynamo.json is included in the package, save the userInfo to DynamoDB
var saveUserInfo = function( userInfo ) {
if ( dynamoParameters ) {
var putParams = Object.assign({}, dynamoParameters);
var hashkeyName = Object.keys( putParams.Item )[0];
putParams.Item = userInfo;
putParams.Item[ hashkeyName ] = userInfo.user_id;
return dynamo.putAsync( putParams ).then( () => userInfo );
} else {
return userInfo;
}
}
// extract user_id from the autho0 userInfo and return it for AWS principalId
var getPrincipalId = function( userInfo ) {
if ( ! userInfo || ! userInfo.user_id ) {
throw new Error( "No user_id returned from Auth0" );
}
console.log( 'Auth0 authentication successful for user_id ' + userInfo.user_id );
return userInfo.user_id;
}
// return the expected Custom Authorizaer JSON object
var getAuthentication = function( principalId ) {
return {
principalId : principalId,
policyDocument : policyDocument
}
}
module.exports.authenticate = function (params) {
var token = getToken(params);
var getTokenDataPromise;
if ( token.length === ACCESS_TOKEN_LENGTH ) { // Auth0 v1 access_token (deprecated)
getTokenDataPromise = auth0.users.getInfo( token );
} else if ( token.length > ACCESS_TOKEN_LENGTH ) { // (probably) Auth0 id_token
getTokenDataPromise = auth0.tokens.getInfo( token );
} else {
throw new TypeError( "Bearer token too short - expected >= 16 charaters" );
}
return getTokenDataPromise
.then( saveUserInfo )
.then( getPrincipalId )
.then( getAuthentication );
}