commit cf79c07476cc46ab6ad40eb99e90b1c0e64e2594 Author: Erick Ruiz de Chavez Date: Fri Sep 2 17:55:38 2016 -0400 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7ff619c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules +development.yml +production.yml diff --git a/config/config.yml b/config/config.yml new file mode 100644 index 0000000..fda68ab --- /dev/null +++ b/config/config.yml @@ -0,0 +1,4 @@ +emails: +mailgun: + url: + key: diff --git a/html_template.hbs b/html_template.hbs new file mode 100644 index 0000000..c2d00fb --- /dev/null +++ b/html_template.hbs @@ -0,0 +1,31 @@ + + + + + + + +

{{info}}

+ + + {{#data}} + + + + + {{/data}} + +
+ {{key}}: + + {{value}} +
+

 

+

 

+ + diff --git a/index.js b/index.js new file mode 100644 index 0000000..acbf5ce --- /dev/null +++ b/index.js @@ -0,0 +1,131 @@ +const request = require('request'); +const restify = require('restify'); +const Handlebars = require('handlebars'); +const fs = require('fs'); +const path = require('path'); +const config = require('indecent'); + +const { chain, get, indexOf, merge, set, startCase } = require('lodash'); + +const knownEmails = get(config, 'emails'); + +const MAILGUN_URL = get(config, 'mailgun.url'); +const MAILGUN_API_KEY = get(config, 'mailgun.key'); + +const FORM_FIELDS = [ + '_from', + '_subject', + '_to', + '_attachment' +]; + +const PRIVATE_FIELDS = [ + '_fake', + '_info', + '_next' +]; + +const htmlSource = fs.readFileSync(path.join(__dirname, 'html_template.hbs'), { encoding: 'utf8' }); +const textSource = fs.readFileSync(path.join(__dirname, 'text_template.hbs'), { encoding: 'utf8' }); +const htmlTemplate = Handlebars.compile(htmlSource); +const textTemplate = Handlebars.compile(textSource); + +var server = restify.createServer(); +server.use(restify.CORS()); +server.use(restify.bodyParser()); + +server.post('/:_to', (req, res, next) => { + const { formData, fields } = parseRequest(req); + + if (indexOf(knownEmails, get(formData, 'to')) < 0) { + return next(new Error('Unknown email address')); + } + + const params = { + formData, + auth: { + user: 'api', + pass: MAILGUN_API_KEY + }, + url: MAILGUN_URL, + method: 'post' + }; + + sendMail(fields, params).then(response => { + const redirect = get(fields, 'next'); + if (redirect) { + res.redirect(redirect, next); + } else { + res.json(response); + } + + return next(); + }).catch(error => { + return next(error); + }); +}); + +function parseRequest (req) { + const body = get(req, 'params'); + + const formData = chain(body) + .pick(FORM_FIELDS) + .mapKeys((value, key) => key.replace('_', '')) + .value(); + + const fields = chain(body) + .pick(PRIVATE_FIELDS) + .mapKeys((value, key) => key.replace('_', '')) + .value(); + + const data = chain(body) + .omit(PRIVATE_FIELDS) + .omit(FORM_FIELDS) + .mapKeys((value, key) => startCase(key)) + .map((value, key) => { + return { key, value }; + }) + .value(); + + set(fields, 'data', data); + set(formData, 'html', htmlTemplate(fields)); + set(formData, 'text', textTemplate(fields)); + + const attachment = get(req, 'files._attachment'); + if (attachment) { + const filePath = get(attachment, 'path'); + const value = get(fields, 'fake') ? filePath : fs.createReadStream(filePath); + + set(formData, 'attachment', { + value, + options: { + filename: get(attachment, 'name'), + contentType: get(attachment, 'type') + } + }); + } + + return { data, fields, formData }; +} + +function sendMail (fields, params) { + const fake = get(fields, 'fake'); + + if (fake) { + return Promise.resolve(merge({ message: 'fake response' }, params)); + } + + return new Promise((resolve, reject) => { + request(params, (error, msg, response) => { + if (error) { + return reject(error); + } + + return resolve(JSON.parse(response)); + }); + }); +} + +server.listen(8081, () => { + console.log(`${server.name} listening at ${server.url}`); +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000..c740b9e --- /dev/null +++ b/package.json @@ -0,0 +1,29 @@ +{ + "name": "contact", + "version": "1.0.1", + "description": "A basic clone of formspree.io for internal use", + "main": "index.js", + "homepage": "https://github.com/eruizdechavez/contact", + "bugs": "https://github.com/eruizdechavez/contact/issues", + "license": "MIT", + "author": { + "name": "Erick Ruiz de Chavez", + "email": "eruizdechavez@fastmail.com", + "url": "https://github.com/eruizdechavez" + }, + "repository": "eruizdechavez/contact", + "engines": { + "node": ">=6.0.0" + }, + "private": true, + "dependencies": { + "handlebars": "4.0.5", + "indecent": "1.0.1", + "lodash": "4.13.1", + "request": "2.72.0", + "restify": "4.1.1" + }, + "devDependencies": { + "semistandard": "*" + } +} diff --git a/text_template.hbs b/text_template.hbs new file mode 100644 index 0000000..d0b9964 --- /dev/null +++ b/text_template.hbs @@ -0,0 +1,5 @@ +{{info}} + +{{#data}} +{{key}}: {{value}} +{{/data}}