From 0066061a7b30918209e4cf3513a8ea1c396cfb7b Mon Sep 17 00:00:00 2001 From: Raven Scott Date: Thu, 19 Sep 2024 08:30:19 -0400 Subject: [PATCH] Add captcha to contact --- app.js | 104 ++++++++++++++++++++++++++-------------------- package.json | 1 + views/contact.ejs | 6 +++ 3 files changed, 67 insertions(+), 44 deletions(-) diff --git a/app.js b/app.js index 787ecd1..2e028f9 100644 --- a/app.js +++ b/app.js @@ -6,6 +6,7 @@ const { marked } = require('marked'); const nodemailer = require('nodemailer'); const hljs = require('highlight.js'); const { format } = require('date-fns'); // To format dates in a proper XML format +const axios = require('axios'); // Add axios for reCAPTCHA verification const app = express(); @@ -134,59 +135,74 @@ app.get('/contact', (req, res) => { }); // Handle contact form submission -app.post('/contact', (req, res) => { - const { name, email, subject, message } = req.body; +app.post('/contact', async (req, res) => { + const { name, email, subject, message, 'g-recaptcha-response': captchaToken } = req.body; // Validate form inputs (basic example) if (!name || !email || !subject || !message) { return res.render('contact', { title: 'Contact Raven Scott', msg: 'All fields are required.' }); } - // Create email content - const output = ` -

You have a new contact request from ${name}.

-

Contact Details

- -

Message

-

${message}

- `; + // Verify the reCAPTCHA token + const captchaSecret = process.env.CAPTCHA_SECRET_KEY; // Your reCAPTCHA secret key + const captchaVerifyUrl = `https://www.google.com/recaptcha/api/siteverify?secret=${captchaSecret}&response=${captchaToken}`; - // Set up Nodemailer transporter - let transporter = nodemailer.createTransport({ - host: process.env.SMTP_HOST, - port: process.env.SMTP_PORT, - secure: false, // true for 465, false for other ports - auth: { - user: process.env.EMAIL_USER, // Email user from environment variables - pass: process.env.EMAIL_PASS, // Email password from environment variables - }, - tls: { - rejectUnauthorized: false, - }, - }); + try { + const captchaResponse = await axios.post(captchaVerifyUrl); - // Set up email options - let mailOptions = { - from: `"${name}" `, - to: process.env.RECEIVER_EMAIL, // Your email address to receive contact form submissions - subject: subject, - html: output, - }; - - // Send email - transporter.sendMail(mailOptions, (error, info) => { - if (error) { - console.error(error); - return res.render('contact', { title: 'Contact Raven Scott', msg: 'An error occurred. Please try again.' }); - } else { - console.log('Email sent: ' + info.response); - return res.render('contact', { title: 'Contact Raven Scott', msg: 'Your message has been sent successfully!' }); + if (!captchaResponse.data.success) { + return res.render('contact', { title: 'Contact Raven Scott', msg: 'Captcha verification failed. Please try again.' }); } - }); + + // CAPTCHA passed, proceed with sending email + const output = ` +

You have a new contact request from ${name}.

+

Contact Details

+ +

Message

+

${message}

+ `; + + // Set up Nodemailer transporter + let transporter = nodemailer.createTransport({ + host: process.env.SMTP_HOST, + port: process.env.SMTP_PORT, + secure: false, // true for 465, false for other ports + auth: { + user: process.env.EMAIL_USER, // Email user from environment variables + pass: process.env.EMAIL_PASS, // Email password from environment variables + }, + tls: { + rejectUnauthorized: false, + }, + }); + + // Set up email options + let mailOptions = { + from: `"${name}" `, + to: process.env.RECEIVER_EMAIL, // Your email address to receive contact form submissions + subject: subject, + html: output, + }; + + // Send email + transporter.sendMail(mailOptions, (error, info) => { + if (error) { + console.error(error); + return res.render('contact', { title: 'Contact Raven Scott', msg: 'An error occurred. Please try again.' }); + } else { + console.log('Email sent: ' + info.response); + return res.render('contact', { title: 'Contact Raven Scott', msg: 'Your message has been sent successfully!' }); + } + }); + } catch (error) { + console.error('Error verifying CAPTCHA:', error); + return res.render('contact', { title: 'Contact Raven Scott', msg: 'An error occurred while verifying CAPTCHA. Please try again.' }); + } }); // Blog Post Route diff --git a/package.json b/package.json index 626ad6c..bddd736 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "author": "", "license": "ISC", "dependencies": { + "axios": "^1.7.7", "body-parser": "^1.20.3", "bootstrap": "^5.3.3", "date-fns": "^4.0.0", diff --git a/views/contact.ejs b/views/contact.ejs index d0d46ef..59b4242 100644 --- a/views/contact.ejs +++ b/views/contact.ejs @@ -12,6 +12,8 @@ + + @@ -70,6 +72,10 @@ + + +
+