/** * File which sends emails to me from * a captcha protected form on the contact * page. * * @author Jeffery Russell 8-19-18 */ //used for file IO const utils = require('../utils/utils.js'); //used for static files const includes = require('../includes/includes'); //for parsing post data const qs = require('querystring'); //cleans form submission const sanitizer = require('sanitizer'); //used to send post data for the captcha const Request = require('request'); //sends the email using a throw away gmail account const nodemailer = require("nodemailer"); //agent for sending the email const smtpTransport = require('nodemailer-smtp-transport'); //captcha secret const CAPTCHA_SECRET = utils.getFileLine("../captcha_secret"); //password to gmail account const EMAIL_PASSWORD = utils.getFileLine("../email_password"); /** * Verifies if the captcha response recieved from the post data was * valid, or are bots trying to get around the captcha * * @param data captcha data from post request * @returns {Promise} resolves whether the captcha is valid */ const verifyCapcha = function(data) { const recaptcha_url = "https://www.google.com/recaptcha/api/siteverify?" + "secret=" + CAPTCHA_SECRET + "&" + "response=" + data; return sync = new Promise(function(resolve, reject) { Request(recaptcha_url, function (error, response, body) { if (!error && response.statusCode == 200) { const googleAnswer = JSON.parse(body); if(googleAnswer.success == true) { resolve(true); } else { resolve(false); } } else { resolve(false); } } ); }); }; /** * Sends a email to my personal emaail address using a throw away * gmail account * * @param name from contact form * @param email from contact form * @param message from contact form */ const sendEmail = function(name, email, message) { const transporter = nodemailer.createTransport(smtpTransport({ service: 'gmail', host: 'smtp.gmail.com', auth: { user: 'jrtechswebsite@gmail.com', pass: EMAIL_PASSWORD } })); const mailOptions = { to: "jeffery@jrtechs.net", // list of receivers subject: "Jrtechs.net form submission", // Subject line text: message, // plaintext body html: message }; // send mail with defined transport object transporter.sendMail(mailOptions, function(error, response) { if(error) { console.log(error); } else { console.log("Message sent: " + response); } transporter.close(); // shut down the connection pool, no more messages }); }; /** * If there was post data on the contact page, it processes it to see * if it was a valid captcha request and sends an email. If no post data was sent, * the normal form is displayed * * @param request -- main express request * @returns {Promise} renders the html of the contact widget */ const processContactPage = function(request) { return new Promise(function(resolve, reject) { utils.getPostData(request).then(function(postData) { const data = qs.parse(postData); if(data.name && data.email && data["g-recaptcha-response"] && data.message) { verifyCapcha(sanitizer.sanitize(data["g-recaptcha-response"])) .then(function(valid) { if(valid) { resolve(utils.include("includes/html/messageSent.html")); sendEmail(data.name, data.email, data.message); } else { resolve(utils.include("includes/html/invalidCaptcha.html")); } }); } else { resolve(utils.include("includes/html/contact.html")); } }).catch(function(err) { reject(err); }) }); }; module.exports = { /** * Displays the contact page along with the header, sidebar, and footer. * This uses the admin header because it doesn't need any minified css * which has been purged of some css classes which are not used in any * of the blog posts. * * @param request -- main express request * @param result -- renders the html of the contact page */ main: function(request, result) { result.writeHead(200, {'Content-Type': 'text/html'}); Promise.all([includes.printAdminHeader(), processContactPage(request), require("../sidebar/sidebar.js").main(), includes.printFooter()]).then(function(content) { result.write(content.join('')); result.end(); }).catch(function(err) { console.log(err); }); } };