hamptonbrown/app/api/contact/route.ts

92 lines
2.9 KiB
TypeScript
Executable File

import { NextRequest, NextResponse } from 'next/server';
import { contactFormSchema } from '@/lib/validations';
import { Resend } from 'resend';
// Simple in-memory rate limiting (in production, use Redis or similar)
const rateLimitMap = new Map<string, { count: number; resetTime: number }>();
const RATE_LIMIT_WINDOW = 60 * 1000; // 1 minute
const RATE_LIMIT_MAX = 5; // 5 requests per minute
function checkRateLimit(ip: string): boolean {
const now = Date.now();
const record = rateLimitMap.get(ip);
if (!record || now > record.resetTime) {
rateLimitMap.set(ip, { count: 1, resetTime: now + RATE_LIMIT_WINDOW });
return true;
}
if (record.count >= RATE_LIMIT_MAX) {
return false;
}
record.count++;
return true;
}
export async function POST(request: NextRequest) {
try {
// Rate limiting
const ip = request.ip || request.headers.get('x-forwarded-for') || 'unknown';
if (!checkRateLimit(ip)) {
return NextResponse.json(
{ error: 'Too many requests. Please try again later.' },
{ status: 429 }
);
}
// Parse and validate request body
const body = await request.json();
const validatedData = contactFormSchema.parse(body);
// Log in development
if (process.env.NODE_ENV === 'development') {
console.log('Contact form submission:', validatedData);
}
// Send email in production if Resend is configured
if (process.env.NODE_ENV === 'production' && process.env.RESEND_API_KEY && process.env.CONTACT_TO_EMAIL) {
try {
const resend = new Resend(process.env.RESEND_API_KEY);
await resend.emails.send({
from: 'Hamton Brown CPA <noreply@hamtonbrown.com>',
to: process.env.CONTACT_TO_EMAIL,
subject: `New Contact Form Submission from ${validatedData.name}`,
html: `
<h2>New Contact Form Submission</h2>
<p><strong>Name:</strong> ${validatedData.name}</p>
<p><strong>Email:</strong> ${validatedData.email}</p>
${validatedData.phone ? `<p><strong>Phone:</strong> ${validatedData.phone}</p>` : ''}
<p><strong>Message:</strong></p>
<p>${validatedData.message}</p>
`,
});
} catch (emailError) {
console.error('Failed to send email:', emailError);
// Don't fail the request if email fails
}
}
return NextResponse.json(
{ message: 'Thank you for your message. We will get back to you soon.' },
{ status: 200 }
);
} catch (error) {
console.error('Contact form error:', error);
if (error instanceof Error && error.name === 'ZodError') {
return NextResponse.json(
{ error: 'Invalid form data. Please check your inputs.' },
{ status: 400 }
);
}
return NextResponse.json(
{ error: 'Internal server error. Please try again later.' },
{ status: 500 }
);
}
}