diff --git a/config/env/sample.js b/config/env/sample.js index 6b3f955..f1bf2a7 100644 --- a/config/env/sample.js +++ b/config/env/sample.js @@ -31,4 +31,8 @@ module.exports = { // Google maps API key googleMapsAPI: 'XXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXX' + // reCaptcha API key + recaptchaSitekey: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', + recaptchaSecret: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', + }; diff --git a/config/mail.js b/config/mail.js index fe4a578..9270a66 100644 --- a/config/mail.js +++ b/config/mail.js @@ -34,7 +34,7 @@ module.exports = { return `

+Tracman

${text}

Do not reply to this email. For information about why you recieved this email, see our privacy policy.

`; }, - from: `"Tracman" `, + noReply: `"Tracman" `, to: (user)=>{ return `"${user.name}" <${user.email}>`; diff --git a/config/routes/auth.js b/config/routes/auth.js index 2ccbe37..c7dffe0 100644 --- a/config/routes/auth.js +++ b/config/routes/auth.js @@ -80,7 +80,7 @@ module.exports = (app, passport) => { // Email the instructions to continue mail.send({ - from: mail.from, + from: mail.noReply, to: `<${user.email}>`, subject: 'Complete your Tracman registration', text: mail.text(`Welcome to Tracman! \n\nTo complete your registration, follow this link and set your password:\n${env.url}/settings/password/${token}\n\nThis link will expire at ${expirationTimeString}. `), @@ -238,7 +238,7 @@ module.exports = (app, passport) => { // Email reset link mail.send({ - from: mail.from, + from: mail.noReply, to: mail.to(user), subject: 'Reset your Tracman password', text: mail.text(`Hi, \n\nDid you request to reset your Tracman password? If so, follow this link to do so:\n${env.url}/settings/password/${token}\n\nIf you didn't initiate this request, just ignore this email. `), diff --git a/config/routes/index.js b/config/routes/index.js index 44fa002..d3e81ac 100644 --- a/config/routes/index.js +++ b/config/routes/index.js @@ -1,10 +1,13 @@ 'use strict'; const mw = require('../middleware.js'), + env = require('../env/env.js'), + mail = require('../mail.js'), router = require('express').Router(), + request = require('request'), slug = require('slug'), xss = require('xss'), - User = require('../models.js').user; + User = require('../models.js').user; module.exports = router @@ -18,6 +21,68 @@ module.exports = router res.render('help'); }) + // Contact + .get('/contact', (req,res)=>{ + res.render('contact',{ + sitekey: env.recaptchaSitekey + }); + }) + .post('/contact', (req,res,next)=>{ + + // Confirm captcha + request.post( 'https://www.google.com/recaptcha/api/siteverify', {form:{ + secret: env.recaptchaSecret, + response: req.body['g-recaptcha-response'], + remoteip: req.ip + }}, (err, response, body)=>{ + + // Check for errors + if (err){ + mw.throwErr(err,req); + res.redirect('/contact'); + } + if (response.statusCode!==200) { + let err = new Error('Bad response from reCaptcha service'); + mw.throwErr(err,req); + res.redirect('/contact'); + } + else { + + // Captcha succeeded + if (JSON.parse(body).success){ + mail.send({ + from: `${req.body.name} <${req.body.email}>`, + to: `Tracman Contact `, + subject: req.body.subject||'A message', + text: req.body.message + }) + .then(()=>{ + req.flash('success', `Your message has been sent. `); + res.redirect(req.session.next || '/'); + }) + .catch((err)=>{ + mw.throwErr(err,req); + res.redirect('/contact'); + }); + } + + // Captcha failed + else { + let err = new Error('Failed reCaptcha'); + mw.throwErr(err,req); + res.redirect('/contact'); + } + + } + } +); + + //TODO: Check req.body.g-recaptcha-response + + + + }) + // Terms of Service and Privacy Policy .get('/terms', (req,res)=>{ res.render('terms'); diff --git a/config/routes/settings.js b/config/routes/settings.js index 1ab18e0..ff9bdc5 100644 --- a/config/routes/settings.js +++ b/config/routes/settings.js @@ -71,7 +71,7 @@ router.route('/') debug(`Mailing new email token to ${req.body.email}...`); mail.send({ to: `"${req.user.name}" <${req.body.email}>`, - from: mail.from, + from: mail.noReply, subject: 'Confirm your new email address for Tracman', text: mail.text(`A request has been made to change your Tracman email address. If you did not initiate this request, please disregard it. \n\nTo confirm your email, follow this link:\n${env.url}/settings/email/${token}. `), html: mail.html(`

A request has been made to change your Tracman email address. If you did not initiate this request, please disregard it.

To confirm your email, follow this link:
${env.url}/settings/email/${token}.

`) @@ -241,7 +241,7 @@ router.route('/password') // Confirm password change request by email. mail.send({ to: mail.to(req.user), - from: mail.from, + from: mail.noReply, subject: 'Request to change your Tracman password', text: mail.text(`A request has been made to change your tracman password. If you did not initiate this request, please contact support at keith@tracman.org. \n\nTo change your password, follow this link:\n${env.url}/settings/password/${token}. \n\nThis request will expire at ${expirationTimeString}. `), html: mail.html(`

A request has been made to change your tracman password. If you did not initiate this request, please contact support at keith@tracman.org.

To change your password, follow this link:
${env.url}/settings/password/${token}.

This request will expire at ${expirationTimeString}.

`) diff --git a/config/routes/test.js b/config/routes/test.js index bbb4d18..5f8066c 100644 --- a/config/routes/test.js +++ b/config/routes/test.js @@ -10,7 +10,7 @@ router .get('/mail', (req,res,next)=>{ mail.send({ to: `"Keith Irwin" `, - from: mail.from, + from: mail.noReply, subject: 'Test email', text: mail.text("Looks like everything's working! "), html: mail.html("

Looks like everything's working!

") diff --git a/package.json b/package.json index b981674..99d7c84 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "passport-local": "^1.0.0", "passport-twitter": "^1.0.4", "passport-twitter-token": "^1.3.0", + "request": "^2.81.0", "slug": "^0.9.1", "socket.io": "^1.4.4", "xss": "^0.3.3" diff --git a/static/css/contact.css b/static/css/contact.css new file mode 100644 index 0000000..6fcb4c8 --- /dev/null +++ b/static/css/contact.css @@ -0,0 +1,31 @@ +input, textarea { + margin-bottom: 3%; +} + +#subject, #message { + width: 100%; +} + +@media (max-width:600px) { + #name, #email { + width: 100%; + } +} +@media (min-width:600px) { + #name, #email { + min-width: 45%; + } + #name { + float: left; + } + #email { + float: right; + } +} + +button.btn { + display: block; + margin: auto; + min-width: 60%; + min-height: 12vh; +} \ No newline at end of file diff --git a/views/contact.html b/views/contact.html new file mode 100644 index 0000000..5a69bf4 --- /dev/null +++ b/views/contact.html @@ -0,0 +1,38 @@ +{% extends 'templates/base.html' %} +{% block title %}{{super()}} | Contact{% endblock %} + +{% block head %} +{{super()}} + + + +{% endblock %} + +{% block main %} +
+ +

Contact

+ +
+ + + + + + + + +
+ +
+{% endblock %} + +{% block javascript %} +{{super()}} + +{% endblock %} diff --git a/views/templates/header.html b/views/templates/header.html index 1164e80..d446915 100644 --- a/views/templates/header.html +++ b/views/templates/header.html @@ -13,6 +13,7 @@