├── .gitignore
├── README.md
├── lambda-functions
├── retrieve-subscribers.js
└── subscribe-newsletter.js
├── package.json
└── public
├── admin
└── index.html
├── assets
├── amazon-cognito-identity.min.js
├── app.js
├── aws-cognito-sdk.min.js
├── aws-sdk.min.js
├── gateway
│ ├── apigClient.js
│ └── lib
│ │ ├── CryptoJS
│ │ ├── components
│ │ │ ├── enc-base64.js
│ │ │ └── hmac.js
│ │ └── rollups
│ │ │ ├── hmac-sha256.js
│ │ │ └── sha256.js
│ │ ├── apiGatewayCore
│ │ ├── apiGatewayClient.js
│ │ ├── sigV4Client.js
│ │ ├── simpleHttpClient.js
│ │ └── utils.js
│ │ ├── axios
│ │ └── dist
│ │ │ └── axios.standalone.js
│ │ └── url-template
│ │ └── url-template.js
├── jsbn.js
├── jsbn2.js
├── moment.min.js
└── sjcl.js
├── index.html
├── login.html
└── post
├── function-as-a-service
└── index.html
├── serverless-computing-takes-over-the-world
└── index.html
└── welcome-to-serverless-stories
└── index.html
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # nyc test coverage
18 | .nyc_output
19 |
20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
21 | .grunt
22 |
23 | # node-waf configuration
24 | .lock-wscript
25 |
26 | # Compiled binary addons (http://nodejs.org/api/addons.html)
27 | build/Release
28 |
29 | # Dependency directories
30 | node_modules
31 | jspm_packages
32 |
33 | # Optional npm cache directory
34 | .npm
35 |
36 | # Optional REPL history
37 | .node_repl_history
38 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Serverless Stories (Lambda Implementation)
2 |
3 | Serverless Stories is a static blog that is enhanced with AWS Lambda. It is a sample application showing you can build serverless applications with AWS Lambda. Check out the blog post [here](https://auth0.com/blog/building-serverless-apps-with-aws-lambda/) and a comparison to Webtask [here](https://auth0.com/blog/2016/06/28/building-serverless-apps-with-webtask/).
4 |
5 | 
6 |
7 | ## Running the App
8 |
9 | 1. Clone the repo
10 | 2. Install the http-server by running `npm install http-server -g` (you will need Node and NPM)
11 | 3. Run `http-server` and navigate to `localhost:8080` to see the blog.
12 | 4. Read the blog post located [here](https://auth0.com/blog/building-serverless-apps-with-aws-lambda/) to learn how to work with AWS Lambda and get it implemented in the app.
13 |
14 | ## What is Auth0?
15 |
16 | Auth0 helps you to:
17 |
18 | * Add authentication with [multiple authentication sources](https://docs.auth0.com/identityproviders), either social like **Google, Facebook, Microsoft Account, LinkedIn, GitHub, Twitter, Box, Salesforce, amont others**, or enterprise identity systems like **Windows Azure AD, Google Apps, Active Directory, ADFS or any SAML Identity Provider**.
19 | * Add authentication through more traditional **[username/password databases](https://docs.auth0.com/mysql-connection-tutorial)**.
20 | * Add support for **[linking different user accounts](https://docs.auth0.com/link-accounts)** with the same user.
21 | * Support for generating signed [Json Web Tokens](https://docs.auth0.com/jwt) to call your APIs and **flow the user identity** securely.
22 | * Analytics of how, when and where users are logging in.
23 | * Pull data from other sources and add it to the user profile, through [JavaScript rules](https://docs.auth0.com/rules).
24 |
25 | ## Create a free Auth0 account
26 |
27 | 1. Go to [Auth0](https://auth0.com/signup) and click Sign Up.
28 | 2. Use Google, GitHub or Microsoft Account to login.
29 |
30 | ## Issue Reporting
31 |
32 | If you have found a bug or if you have a feature request, please report them at this repository issues section. Please do not report security vulnerabilities on the public GitHub issue tracker. The [Responsible Disclosure Program](https://auth0.com/whitehat) details the procedure for disclosing security issues.
33 |
34 | ## Author
35 |
36 | [Auth0](auth0.com)
37 |
38 | ## License
39 |
40 | This project is licensed under the MIT license. See the [LICENSE](LICENSE) file for more info.
41 |
42 |
--------------------------------------------------------------------------------
/lambda-functions/retrieve-subscribers.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // We'll again use the AWS SDK to get an instance of our database
4 | var aws = require('aws-sdk');
5 | var db = new aws.DynamoDB();
6 |
7 | exports.handler = (event, context, callback) => {
8 | // We'll modify our response code a little bit so that when the response
9 | // is ok, we'll return the list of emails in the message
10 | const RESPONSE = {
11 | OK : {
12 | statusCode : 200,
13 | message: [],
14 | },
15 | ERROR : {
16 | status : 400,
17 | message: "Something went wrong. Please try again."
18 | }
19 | };
20 |
21 | // We'll use the scan method to get all the data from our database
22 | db.scan({
23 | TableName: "Emails"
24 | }, function(err, data) {
25 | if (err) {
26 | callback(null, RESPONSE.ERROR);
27 | }
28 | else {
29 | // If we get data back, we'll do some modifications to make it easier to read
30 | for(var i = 0; i < data.Items.length; i++){
31 | RESPONSE.OK.message.push({'email': data.Items[i].email.S});
32 | }
33 | callback(null, RESPONSE.OK);
34 | }
35 | });
36 | };
--------------------------------------------------------------------------------
/lambda-functions/subscribe-newsletter.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // Require the AWS SDK and get the instance of our DynamoDB
4 | var aws = require('aws-sdk');
5 | var db = new aws.DynamoDB();
6 |
7 | // We'll use the same response we used in our Webtask module
8 | const RESPONSE = {
9 | OK : {
10 | statusCode : 200,
11 | message: "You have successfully subscribed to the newsletter!",
12 | },
13 | DUPLICATE : {
14 | status : 400,
15 | message : "You are already subscribed."
16 | },
17 | ERROR : {
18 | status : 400,
19 | message: "Something went wrong. Please try again."
20 | }
21 | };
22 |
23 |
24 | // Set up the model for our the email
25 | var model = {
26 | email: {"S" : ""},
27 | };
28 |
29 | exports.handler = (event, context, callback) => {
30 | // Capture the email from our POST request
31 | var email = event.body.email;
32 |
33 | if(!email){
34 | // If we don't get an email, we'll end our execution and send an error
35 | return callback(null, RESPONSE.ERROR);
36 | }
37 |
38 | // If we do have an email, we'll set it to our model
39 | model.email.S = email;
40 |
41 | // Insert the email into the database, but only if the email does not already exist.
42 | db.putItem({
43 | TableName: 'Emails',
44 | Item: model,
45 | Expected: {
46 | email: { Exists: false }
47 | }
48 | }, function (err, data) {
49 | if (err) {
50 | // If we get an err, we'll assume it's a duplicate email and send an
51 | // appropriate message
52 | return callback(null, RESPONSE.DUPLICATE);
53 | }
54 | // If the data was stored succesfully, we'll respond accordingly
55 | callback(null, RESPONSE.OK);
56 | });
57 | };
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "serverless-stories-lambda",
3 | "version" : "1.0.0",
4 | "dependencies" : {
5 | "http-server" : "latest"
6 | }
7 | }
--------------------------------------------------------------------------------
/public/admin/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/public/assets/amazon-cognito-identity.min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2016 Amazon.com,
3 | * Inc. or its affiliates. All Rights Reserved.
4 | *
5 | * Licensed under the Amazon Software License (the "License").
6 | * You may not use this file except in compliance with the
7 | * License. A copy of the License is located at
8 | *
9 | * http://aws.amazon.com/asl/
10 | *
11 | * or in the "license" file accompanying this file. This file is
12 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
13 | * CONDITIONS OF ANY KIND, express or implied. See the License
14 | * for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 |
19 | AWSCognito.CognitoIdentityServiceProvider.CognitoUser=function(){var a=function b(a){if(!(this instanceof b))throw new Error("CognitoUser constructor was not called with new.");if(null==a||null==a.Username||null==a.Pool)throw new Error("Username and pool information are required.");this.username=a.Username||"",this.pool=a.Pool,this.AuthState=null,this.client=new AWSCognito.CognitoIdentityServiceProvider({apiVersion:"2016-04-19"}),this.signInUserSession=null};return a.prototype.getSignInUserSession=function(){return this.signInUserSession},a.prototype.getUsername=function(){return this.username},a.prototype.authenticateUser=function(a,b){var c,d,e=new AWSCognito.CognitoIdentityServiceProvider.AuthenticationHelper(this.pool.getUserPoolId().split("_")[1],this.pool.getParanoia()),f=this;this.client.getAuthenticationDetails({ClientId:this.pool.getClientId(),Username:this.username,SrpA:e.getLargeAValue().toString(16),ValidationData:a.getValidationData()},function(g,h){if(g)return b.onFailure(g);f.username=h.Username,c=new BigInteger(h.SrpB,16),d=new BigInteger(h.Salt,16);var i=e.getPasswordAuthenticationKey(f.username,a.getPassword(),c,d),j=sjcl.codec.bytes.toBits(h.SecretBlock),k=new sjcl.misc.hmac(i,sjcl.hash.sha256);k.update(sjcl.codec.utf8String.toBits(f.pool.getUserPoolId().split("_")[1])),k.update(sjcl.codec.utf8String.toBits(f.username)),k.update(j);var l=moment().utc(),m=l.format("ddd MMM D HH:mm:ss UTC YYYY");k.update(sjcl.codec.utf8String.toBits(m));for(var n=k.digest(),o=sjcl.codec.bytes.fromBits(n),p=new ArrayBuffer(32),q=new Uint8Array(p),r=0;rLog out');
24 | $('#login').hide();
25 | } else {
26 | $('#login').show().append('Log in');
27 | $('#user').hide();
28 | }
29 | }
30 |
31 | function loadAdmin(){
32 | if(window.location.pathname == '/admin/'){
33 | if(localStorage.getItem('token')){
34 | AWS.config.credentials.get(function (err) {
35 | var client = apigClientFactory.newClient({
36 | accessKey: AWS.config.credentials.accessKeyId,
37 | secretKey: AWS.config.credentials.secretAccessKey,
38 | sessionToken: AWS.config.credentials.sessionToken,
39 | region: 'us-east-1'
40 | });
41 | client.subscribersGet().then(function(data){
42 | for(var i = 0; i < data.data.message.length; i++){
43 | $('#subscribers').append('
Lorem ipsum dolor sit amet, dolor eu nec, a etiam elit sed, iaculis vehicula nam suspendisse orci arcu, pellentesque est sit fringilla. Vehicula et ut. Elit felis fusce in in sollicitudin, a ac venenatis fermentum egestas scelerisque sit, morbi vehicula ultricies, fusce sit feugiat primis amet, lobortis lacinia curabitur integer. Pretium dignissim enim eget, nostra vulputate ipsum proin dui, arcu ad ut et augue nulla vel. Fermentum ante, ea et ornare amet in dolor, vestibulum quis erat, pulvinar mollis, in mollis eget ut auctor nunc mollis. Hendrerit a adipiscing pede nulla quisque donec, nec nulla vitae quisque. In sagittis donec accumsan dolor massa in.
52 |
53 |
Convallis sodales in mi mollis maecenas massa, sed id, aenean eum sodales a varius proin vero, sit magna massa. Nec rhoncus duis, velit sed nulla lobortis a vestibulum condimentum, consectetuer auctor justo nibh odio felis turpis. Turpis eos, aliquet metus fringilla eleifend tincidunt felis nulla. Turpis molestie tellus ante vestibulum, turpis vestibulum, eget urna arcu scelerisque et, nonummy sapien vivamus ac, quis libero. Donec ac consequat accumsan ipsum neque, lorem at mi fermentum quis. Leo in aliquam nam erat, vitae amet, montes aliquet urna lacus. Placerat ullamcorper, placerat ut et quam est. Aenean adipiscing arcu dicta varius ante massa, nunc arcu quisque mi eget libero, elit non, suscipit suscipit ullamcorper sem risus.
54 |
55 |
Sodales proin montes condimentum vitae dignissimos sollicitudin, scelerisque eu aenean quis eros eget quisque, vel amet sem enim dolor, massa in et sollicitudin tincidunt non phasellus, facilisis mollis senectus urna. Facilisis vel dapibus eu purus habitasse, ac eget arcu dui libero hymenaeos aliquam, justo quis eu mus consequat vitae sed, elit posuere. Ultricies aliquam adipiscing purus morbi mollis. Tortor laoreet sit ut et praesent, fringilla cras, tortor amet volutpat nec est ut vestibulum. Varius diam in nunc, rhoncus sit et amet non etiam amet, sit vehicula praesent. Ridiculus maecenas, praesent dolorum molestie ipsum molestie, tristique accumsan nec tincidunt ullamcorper nullam pede, ultrices fusce sit ante nulla. Sollicitudin quia risus vehicula sed a nunc, aliquet suspendisse et. Neque nam molestie vehicula vel, lacus sollicitudin est erat arcu. Elit cras quis blandit vestibulum interdum pulvinar, turpis viverra tellus eu, nam semper neque sit ligula. Quis quis nulla gravida eget vestibulum luctus, fusce integer vitae elit enim suspendisse ut, nec pellentesque etiam eu turpis congue libero, augue eget scelerisque sed donec mi. Fermentum ut amet massa, sapien senectus hac, vehicula sed vivamus. Integer commodo dui vel euismod vivamus, lacus ornare, phasellus mi donec maecenas, nam et vestibulum euismod.
56 |
57 |
A eget, ultricies ultricies metus congue quis, faucibus arcu. Libero sapien, vel risus lectus nec nibh diam sem, tellus sagittis, mus taciti sed et in. Sed sed est vitae sed tincidunt. Dictum tempus, velit et nunc, et ridiculus mollis curabitur risus praesent. Volutpat elit sequi pellentesque enim blandit, diam dignissim lorem id id, in sapien molestie elit morbi vestibulum est. Elit vitae donec libero magna ut ipsum, scelerisque ut phasellus eget sed id vulputate, wisi phasellus sed sit, fames lacus a integer non ultricies, facilisis nullam ligula amet ante etiam. Duis montes, velit lectus, mattis nunc eget odio sed faucibus, augue dolor ante amet lacus, eleifend luctus volutpat a natoque luctus penatibus. Nam dui aliquet arcu ligula libero, et adipiscing mauris at urna nec, pede neque nullam arcu in morbi tempus, turpis eget et vitae lacinia mattis. Vitae nunc leo sed non, non dolor nibh amet bibendum ut, quis sit et, felis ligula, suscipit libero non elit cras.
Lorem ipsum dolor sit amet, dolor eu nec, a etiam elit sed, iaculis vehicula nam suspendisse orci arcu, pellentesque est sit fringilla. Vehicula et ut. Elit felis fusce in in sollicitudin, a ac venenatis fermentum egestas scelerisque sit, morbi vehicula ultricies, fusce sit feugiat primis amet, lobortis lacinia curabitur integer. Pretium dignissim enim eget, nostra vulputate ipsum proin dui, arcu ad ut et augue nulla vel. Fermentum ante, ea et ornare amet in dolor, vestibulum quis erat, pulvinar mollis, in mollis eget ut auctor nunc mollis. Hendrerit a adipiscing pede nulla quisque donec, nec nulla vitae quisque. In sagittis donec accumsan dolor massa in.
52 |
53 |
Convallis sodales in mi mollis maecenas massa, sed id, aenean eum sodales a varius proin vero, sit magna massa. Nec rhoncus duis, velit sed nulla lobortis a vestibulum condimentum, consectetuer auctor justo nibh odio felis turpis. Turpis eos, aliquet metus fringilla eleifend tincidunt felis nulla. Turpis molestie tellus ante vestibulum, turpis vestibulum, eget urna arcu scelerisque et, nonummy sapien vivamus ac, quis libero. Donec ac consequat accumsan ipsum neque, lorem at mi fermentum quis. Leo in aliquam nam erat, vitae amet, montes aliquet urna lacus. Placerat ullamcorper, placerat ut et quam est. Aenean adipiscing arcu dicta varius ante massa, nunc arcu quisque mi eget libero, elit non, suscipit suscipit ullamcorper sem risus.
54 |
55 |
Sodales proin montes condimentum vitae dignissimos sollicitudin, scelerisque eu aenean quis eros eget quisque, vel amet sem enim dolor, massa in et sollicitudin tincidunt non phasellus, facilisis mollis senectus urna. Facilisis vel dapibus eu purus habitasse, ac eget arcu dui libero hymenaeos aliquam, justo quis eu mus consequat vitae sed, elit posuere. Ultricies aliquam adipiscing purus morbi mollis. Tortor laoreet sit ut et praesent, fringilla cras, tortor amet volutpat nec est ut vestibulum. Varius diam in nunc, rhoncus sit et amet non etiam amet, sit vehicula praesent. Ridiculus maecenas, praesent dolorum molestie ipsum molestie, tristique accumsan nec tincidunt ullamcorper nullam pede, ultrices fusce sit ante nulla. Sollicitudin quia risus vehicula sed a nunc, aliquet suspendisse et. Neque nam molestie vehicula vel, lacus sollicitudin est erat arcu. Elit cras quis blandit vestibulum interdum pulvinar, turpis viverra tellus eu, nam semper neque sit ligula. Quis quis nulla gravida eget vestibulum luctus, fusce integer vitae elit enim suspendisse ut, nec pellentesque etiam eu turpis congue libero, augue eget scelerisque sed donec mi. Fermentum ut amet massa, sapien senectus hac, vehicula sed vivamus. Integer commodo dui vel euismod vivamus, lacus ornare, phasellus mi donec maecenas, nam et vestibulum euismod.
56 |
57 |
A eget, ultricies ultricies metus congue quis, faucibus arcu. Libero sapien, vel risus lectus nec nibh diam sem, tellus sagittis, mus taciti sed et in. Sed sed est vitae sed tincidunt. Dictum tempus, velit et nunc, et ridiculus mollis curabitur risus praesent. Volutpat elit sequi pellentesque enim blandit, diam dignissim lorem id id, in sapien molestie elit morbi vestibulum est. Elit vitae donec libero magna ut ipsum, scelerisque ut phasellus eget sed id vulputate, wisi phasellus sed sit, fames lacus a integer non ultricies, facilisis nullam ligula amet ante etiam. Duis montes, velit lectus, mattis nunc eget odio sed faucibus, augue dolor ante amet lacus, eleifend luctus volutpat a natoque luctus penatibus. Nam dui aliquet arcu ligula libero, et adipiscing mauris at urna nec, pede neque nullam arcu in morbi tempus, turpis eget et vitae lacinia mattis. Vitae nunc leo sed non, non dolor nibh amet bibendum ut, quis sit et, felis ligula, suscipit libero non elit cras.
Lorem ipsum dolor sit amet, dolor eu nec, a etiam elit sed, iaculis vehicula nam suspendisse orci arcu, pellentesque est sit fringilla. Vehicula et ut. Elit felis fusce in in sollicitudin, a ac venenatis fermentum egestas scelerisque sit, morbi vehicula ultricies, fusce sit feugiat primis amet, lobortis lacinia curabitur integer. Pretium dignissim enim eget, nostra vulputate ipsum proin dui, arcu ad ut et augue nulla vel. Fermentum ante, ea et ornare amet in dolor, vestibulum quis erat, pulvinar mollis, in mollis eget ut auctor nunc mollis. Hendrerit a adipiscing pede nulla quisque donec, nec nulla vitae quisque. In sagittis donec accumsan dolor massa in.
52 |
53 |
Convallis sodales in mi mollis maecenas massa, sed id, aenean eum sodales a varius proin vero, sit magna massa. Nec rhoncus duis, velit sed nulla lobortis a vestibulum condimentum, consectetuer auctor justo nibh odio felis turpis. Turpis eos, aliquet metus fringilla eleifend tincidunt felis nulla. Turpis molestie tellus ante vestibulum, turpis vestibulum, eget urna arcu scelerisque et, nonummy sapien vivamus ac, quis libero. Donec ac consequat accumsan ipsum neque, lorem at mi fermentum quis. Leo in aliquam nam erat, vitae amet, montes aliquet urna lacus. Placerat ullamcorper, placerat ut et quam est. Aenean adipiscing arcu dicta varius ante massa, nunc arcu quisque mi eget libero, elit non, suscipit suscipit ullamcorper sem risus.
54 |
55 |
Sodales proin montes condimentum vitae dignissimos sollicitudin, scelerisque eu aenean quis eros eget quisque, vel amet sem enim dolor, massa in et sollicitudin tincidunt non phasellus, facilisis mollis senectus urna. Facilisis vel dapibus eu purus habitasse, ac eget arcu dui libero hymenaeos aliquam, justo quis eu mus consequat vitae sed, elit posuere. Ultricies aliquam adipiscing purus morbi mollis. Tortor laoreet sit ut et praesent, fringilla cras, tortor amet volutpat nec est ut vestibulum. Varius diam in nunc, rhoncus sit et amet non etiam amet, sit vehicula praesent. Ridiculus maecenas, praesent dolorum molestie ipsum molestie, tristique accumsan nec tincidunt ullamcorper nullam pede, ultrices fusce sit ante nulla. Sollicitudin quia risus vehicula sed a nunc, aliquet suspendisse et. Neque nam molestie vehicula vel, lacus sollicitudin est erat arcu. Elit cras quis blandit vestibulum interdum pulvinar, turpis viverra tellus eu, nam semper neque sit ligula. Quis quis nulla gravida eget vestibulum luctus, fusce integer vitae elit enim suspendisse ut, nec pellentesque etiam eu turpis congue libero, augue eget scelerisque sed donec mi. Fermentum ut amet massa, sapien senectus hac, vehicula sed vivamus. Integer commodo dui vel euismod vivamus, lacus ornare, phasellus mi donec maecenas, nam et vestibulum euismod.
56 |
57 |
A eget, ultricies ultricies metus congue quis, faucibus arcu. Libero sapien, vel risus lectus nec nibh diam sem, tellus sagittis, mus taciti sed et in. Sed sed est vitae sed tincidunt. Dictum tempus, velit et nunc, et ridiculus mollis curabitur risus praesent. Volutpat elit sequi pellentesque enim blandit, diam dignissim lorem id id, in sapien molestie elit morbi vestibulum est. Elit vitae donec libero magna ut ipsum, scelerisque ut phasellus eget sed id vulputate, wisi phasellus sed sit, fames lacus a integer non ultricies, facilisis nullam ligula amet ante etiam. Duis montes, velit lectus, mattis nunc eget odio sed faucibus, augue dolor ante amet lacus, eleifend luctus volutpat a natoque luctus penatibus. Nam dui aliquet arcu ligula libero, et adipiscing mauris at urna nec, pede neque nullam arcu in morbi tempus, turpis eget et vitae lacinia mattis. Vitae nunc leo sed non, non dolor nibh amet bibendum ut, quis sit et, felis ligula, suscipit libero non elit cras.