Files

133 lines
4.3 KiB
JavaScript

import express from 'express';
import multer from 'multer';
import { saveLead, getLeads } from '../db.js';
import { sendContactEmail, sendCareersEmail, sendStrategyEmail } from '../services/mailService.js';
const router = express.Router();
const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 10 * 1024 * 1024 } });
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, Careers, and Strategy Call form submissions via SMTP
router.post('/', upload.single('resume'), async (req, res) => {
try {
const { name, email, phone, mobile, subject, message, interests, type, designation, dateTime, resumeName, turnstileToken } = req.body;
const contactName = name?.trim();
const contactEmail = email?.trim();
const contactPhone = (phone || mobile || '').trim();
const contactSubject = (subject || interests || type || 'General Inquiry').trim();
const contactMessage = (message || req.body.comments || '').trim();
if (!contactName || !contactEmail) {
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,
email: contactEmail,
phone: contactPhone,
subject: contactSubject,
message: contactMessage,
designation,
dateTime,
resumeName,
type: type || 'contact'
});
// Attempt sending email via SMTP service based on form type
let mailResult = { success: false };
if (type === 'careers') {
mailResult = await sendCareersEmail({
name: contactName,
email: contactEmail,
phone: contactPhone,
resumeName: req.file ? req.file.originalname : (resumeName || 'Resume Uploaded'),
message: contactMessage,
file: req.file
});
} else if (type === 'strategy') {
mailResult = await sendStrategyEmail({
name: contactName,
email: contactEmail,
phone: contactPhone,
designation: designation || 'N/A',
dateTime: dateTime || 'N/A',
interests: interests || 'General Strategy Consultation',
message: contactMessage
});
} else {
mailResult = await sendContactEmail({
name: contactName,
email: contactEmail,
phone: contactPhone,
subject: contactSubject,
message: contactMessage
});
}
if (!mailResult.success) {
// If SMTP is not yet configured or fails, return 200 with lead saved & warning
return res.status(200).json({
success: true,
saved: true,
leadId: lead.id,
smtpError: mailResult.error,
message: 'Your request was saved successfully. Note: SMTP email dispatch requires SMTP credentials in .env.'
});
}
return res.status(200).json({
success: true,
saved: true,
leadId: lead.id,
messageId: mailResult.messageId,
message: 'Request sent successfully via SMTP!'
});
} catch (error) {
console.error('[Contact Route Error]', error);
return res.status(500).json({ error: error.message || 'Internal Server Error' });
}
});
// GET /api/contact/leads - Retrieve saved contact leads
router.get('/leads', (_req, res) => {
try {
const leads = getLeads();
return res.json({ success: true, leads });
} catch (error) {
return res.status(500).json({ error: error.message });
}
});
export default router;