Skip to content

Commit 829bbf9

Browse files
committed
fix: Skip reCAPTCHA if no valid key, with a console warning
This change prevents developers from being blocked during hackathons due to a missing reCAPTCHA key. If the RECAPTCHA_KEY in .env.example or the environment variables is left blank, reCAPTCHA rendering and validation are skipped. Instead, a console warning is displayed.
1 parent 9548777 commit 829bbf9

File tree

4 files changed

+39
-15
lines changed

4 files changed

+39
-15
lines changed

.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ SMTP_PASSWORD=hdgfadsfahg--i.e.Sendgrid-apikey---hdgfadsfahg
1818
SMTP_HOST=smtp.sendgrid.net
1919

2020
# Needed for proper rendering of the Contact Form
21-
RECAPTCHA_SITE_KEY=JKHGxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxJG
21+
RECAPTCHA_SITE_KEY=
2222
RECAPTCHA_SECRET_KEY=87ehxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx3298
2323

2424
#

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,10 @@ _What to get and configure:_
153153
- For user workflows for reset password and verify email
154154
- For contact form processing
155155
- reCAPTCHA
156-
- For contact form submission
156+
- For contact form submission, but you can skip it during your development
157157
- OAuth for social logins (Sign in with / Login with)
158158
- Depending on your application need, obtain keys from Google, Facebook, X (Twitter), LinkedIn, Twitch, GitHub. You don't have to obtain valid keys for any provider that you don't need. Just remove the buttons and links in the login and account pug views before your demo.
159-
- API keys for service providers in the API Examples if you are planning to use them.
159+
- API keys for service providers that you need in the API Examples if you are planning to use them.
160160

161161
- MongoDB Atlas
162162

controllers/contact.js

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,13 @@ async function validateReCAPTCHA(token) {
1818
exports.getContact = (req, res) => {
1919
const unknownUser = !req.user;
2020

21+
if (!process.env.RECAPTCHA_SITE_KEY) {
22+
console.warn('\x1b[33mWARNING: RECAPTCHA_SITE_KEY is missing or invalid. The reCAPTCHA widget will not be rendered or validated. Make sure to add a key to your .env or environment variables before going to production.\x1b[0m');
23+
}
24+
2125
res.render('contact', {
2226
title: 'Contact',
23-
sitekey: process.env.RECAPTCHA_SITE_KEY,
27+
sitekey: process.env.RECAPTCHA_SITE_KEY || null, // Pass null if the key is missing
2428
unknownUser,
2529
});
2630
};
@@ -39,14 +43,21 @@ exports.postContact = async (req, res, next) => {
3943
}
4044
if (validator.isEmpty(req.body.message)) validationErrors.push({ msg: 'Please enter your message.' });
4145

42-
try {
43-
const reCAPTCHAResponse = await validateReCAPTCHA(req.body['g-recaptcha-response']);
44-
if (!reCAPTCHAResponse.data.success) {
45-
validationErrors.push({ msg: 'reCAPTCHA validation failed.' });
46+
if (!process.env.RECAPTCHA_SITE_KEY) {
47+
console.warn('\x1b[33mWARNING: RECAPTCHA_SITE_KEY is missing. Add a key to your .env or use a WebApp Firewall for CAPTCHA validation before going to production.\x1b[0m');
48+
validationErrors.push({ msg: 'Server configuration error. Please try again later.' });
49+
} else if (!validator.isEmpty(req.body['g-recaptcha-response'])) {
50+
try {
51+
const reCAPTCHAResponse = await validateReCAPTCHA(req.body['g-recaptcha-response']);
52+
if (!reCAPTCHAResponse.success) {
53+
validationErrors.push({ msg: 'reCAPTCHA validation failed.' });
54+
}
55+
} catch (error) {
56+
console.error('Error validating reCAPTCHA:', error);
57+
validationErrors.push({ msg: 'Error validating reCAPTCHA. Please try again.' });
4658
}
47-
} catch (error) {
48-
console.error('Error validating reCAPTCHA:', error);
49-
validationErrors.push({ msg: 'Error validating reCAPTCHA. Please try again.' });
59+
} else {
60+
validationErrors.push({ msg: 'reCAPTCHA response was missing.' });
5061
}
5162

5263
if (validationErrors.length) {

views/contact.pug

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
extends layout
22

33
block head
4-
script(src='https://www.google.com/recaptcha/api.js', async='', defer='')
4+
if sitekey
5+
script(src='https://www.google.com/recaptcha/api.js', async='', defer='')
56

67
block content
78
.pb-2.mt-2.mb-4.border-bottom
89
h3 Contact Form
910

10-
form(method='POST')
11+
form#contactForm(method='POST')
1112
input(type='hidden', name='_csrf', value=_csrf)
1213
if (unknownUser)
1314
.form-group.row.mb-3
@@ -24,8 +25,20 @@ block content
2425
textarea#message.form-control(name='message', rows='7', autofocus=(!unknownUser).toString(), required)
2526
.form-group
2627
.offset-md-2.col-md-8.p-1
27-
.g-recaptcha(data-sitekey=sitekey)
28+
if sitekey
29+
#recaptchaWidget.g-recaptcha(data-sitekey=sitekey)
30+
span#recaptchaError.text-danger.d-none.mt-2 Please complete the reCAPTCHA before submitting the form.
2831
br
29-
button.col-md-2.btn.btn-primary(type='submit')
32+
button#submitBtn.col-md-2.btn.btn-primary(type='submit')
3033
i.far.fa-envelope.fa-sm.iconpadding
3134
| Send
35+
script.
36+
document.getElementById('contactForm').addEventListener('submit', function (event) {
37+
const recaptchaError = document.getElementById('recaptchaError');
38+
if (typeof grecaptcha !== 'undefined' && !grecaptcha.getResponse()) {
39+
event.preventDefault(); // Prevent form submission
40+
recaptchaError.classList.remove('d-none'); // Show error message
41+
} else {
42+
recaptchaError.classList.add('d-none'); // Hide error message if resolved
43+
}
44+
});

0 commit comments

Comments
 (0)