133 lines
4.3 KiB
JavaScript
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;
|