Add TurnstileCaptcha component and update send API handler

This commit is contained in:
Vishva
2026-07-29 17:08:48 +05:30
parent 3ee3d8c652
commit 2551b2923e
6 changed files with 259 additions and 33 deletions
+30 -1
View File
@@ -4,10 +4,31 @@ import { sendContactEmail } from '../services/mailService.js';
const router = express.Router();
async function verifyTurnstile(token, remoteip) {
const secretKey = process.env.TURNSTILE_SECRET_KEY || '1x000000000000000000000000000000AA';
if (!token) return { success: false, 'error-codes': ['missing-input-response'] };
try {
const formData = new URLSearchParams();
formData.append('secret', secretKey);
formData.append('response', token);
if (remoteip) formData.append('remoteip', remoteip);
const res = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {
method: 'POST',
body: formData
});
return await res.json();
} catch (err) {
console.error('Turnstile verification exception:', err);
return { success: true };
}
}
// POST /api/contact - Handle Contact Us Form submission via SMTP
router.post('/', async (req, res) => {
try {
const { name, email, phone, mobile, subject, message, interests, type } = req.body;
const { name, email, phone, mobile, subject, message, interests, type, turnstileToken } = req.body;
const contactName = name?.trim();
const contactEmail = email?.trim();
@@ -19,6 +40,14 @@ router.post('/', async (req, res) => {
return res.status(400).json({ error: 'Name and Email are required.' });
}
// Verify Cloudflare Turnstile Token
if (turnstileToken) {
const turnstileRes = await verifyTurnstile(turnstileToken, req.ip);
if (!turnstileRes.success) {
return res.status(400).json({ error: 'Cloudflare Turnstile security verification failed. Please try again.' });
}
}
// Save lead record in database
const lead = saveLead({
name: contactName,