Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serverless #1

Merged
merged 27 commits into from
Apr 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
node_modules/
dist
dist/
build/
npm-debug.log
*.swp
.env
.DS_Store
.npmignore
.serverless/
secrets.*.yml
yarn-error.log
22 changes: 0 additions & 22 deletions gulpfile.js

This file was deleted.

82 changes: 0 additions & 82 deletions index.js

This file was deleted.

44 changes: 0 additions & 44 deletions package.json

This file was deleted.

87 changes: 87 additions & 0 deletions serverless/handler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
'use strict';
const AWS = require('aws-sdk');
const fetch = require('node-fetch');

const EMAIL_REGEX = /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;

module.exports.sendMail = (event, context, callback) => {
console.log(event);

const body = JSON.parse(event.body);

validateResponse(body)
.then(checkRecaptcha)
.then(sendEmail)
.then(() => {
callback(null, generateResponse('OK', 200, 'Sent Email'));
})
.catch(err => {
console.log(err);
callback(null, generateResponse('FAILED', 400, err.message));
});
};

function validateResponse(body) {
return new Promise((resolve, reject) => {
if (!body) reject(new Error('Need to provide a body with the request'));

const { name, email, message, recaptcha_response } = body;
if (!name || !email || !message || !recaptcha_response)
reject(new Error('Need to provide name, email, message, and valid captcha response'));

if (!EMAIL_REGEX.test(email))
reject(new Error('Email needs to be in the correct email format'));

if (message.length > 1000)
reject(new Error('Message needs to be less than 1000 characters'));

resolve(body);
});
}

function checkRecaptcha(body) {
const { recaptcha_response } = body;
const url ="https://www.google.com/recaptcha/api/siteverify?response=" + recaptcha_response + "&secret=" + process.env.RECAPTCHA_SECRET;

return fetch(url, { method: 'post' })
.then(response => response.json())
.then(response => {
if (!response.success) throw new Error('Invalid recaptcha response');
return body;
})
}

function sendEmail(body) {
const { name, email, message } = body;
const emailMessage = 'From: ' + name + '\n' +
'Email: ' + email + '\n' +
'Message: ' + message;

const ses = new AWS.SES();


return ses.sendEmail({
Destination: {
ToAddresses: [ process.env.EMAIL_TO ]
},
Message: {
Body: {
Text: { Data: emailMessage }
},
Subject: {
Data: 'Message from ' + name + ' on your website'
}
},
Source: process.env.EMAIL_FROM
}).promise();
}

function generateResponse(status, statusCode, message) {
return {
statusCode: statusCode,
body: JSON.stringify({
status,
message
})
};
}
16 changes: 16 additions & 0 deletions serverless/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "cvbackend",
"version": "1.0.0",
"description": "",
"main": "handler.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"aws-sdk": "^2.31.0",
"node-fetch": "^1.6.3",
"serverless-secrets-plugin": "^0.0.1"
}
}
1 change: 1 addition & 0 deletions serverless/secrets.dev.yml.encrypted
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
m�{'��H�,FwH+M�Y�Ik��+����� ;�l�C��w�<�H��kS�IV\40�(��dF��2���B2�1�b&�(�K6<��uH#�ˆ�O��u;\��z��k��� �T���������"8�e��)=��e{� z�g��6��j�j/����w���C��y�u����#�˒x1A�9"���Uq�)=�ld��O֌V�(���� X.ښ�M�7�:����ŋ<`�ۣL���Z�)v>S"� R���Fw)�S�
Expand Down
Binary file added serverless/secrets.prod.yml.encrypted
Binary file not shown.
33 changes: 33 additions & 0 deletions serverless/serverless.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
service: cv-backend

plugins:
- serverless-secrets-plugin

provider:
name: aws
runtime: nodejs6.10
stage: dev
region: us-west-2
environment:
EMAIL_FROM: ${self:custom.secrets.EMAIL_FROM}
EMAIL_TO: ${self:custom.secrets.EMAIL_TO}
RECAPTCHA_SECRET: ${self:custom.secrets.RECAPTCHA_SECRET}
iamRoleStatements:
- Effect: "Allow"
Action:
- "ses:SendEmail"
- "ses:SendEmailRaw"
Resource:
- "*"

custom:
secrets: ${file(secrets.${opt:stage, self:provider.stage}.yml)}

functions:
sendMail:
handler: handler.sendMail
events:
- http:
path: mail
method: post
cors: true
Loading