This repository has been archived on 2025-03-28. You can view files and clone it, but cannot push or open issues or pull requests.
coryd.dev-eleventy/workers/contact/index.js

76 lines
No EOL
2.7 KiB
JavaScript

import { createClient } from '@supabase/supabase-js'
const RATE_LIMIT = 5
const TIME_FRAME = 60 * 60 * 1000
const ipSubmissions = new Map()
export default {
async fetch(request, env) {
if (request.method === 'POST') {
const ip = request.headers.get('CF-Connecting-IP') || request.headers.get('X-Forwarded-For') || request.headers.get('Remote-Addr')
const currentTime = Date.now()
if (!ipSubmissions.has(ip)) ipSubmissions.set(ip, [])
const submissions = ipSubmissions.get(ip).filter(time => currentTime - time < TIME_FRAME)
if (submissions.length >= RATE_LIMIT) return Response.redirect('https://coryd.dev/rate-limit', 301)
submissions.push(currentTime)
ipSubmissions.set(ip, submissions)
try {
const formData = await request.formData()
const name = formData.get('name')
const email = formData.get('email')
const message = formData.get('message')
const hpName = formData.get('hp_name')
if (hpName) return new Response('Spam detected', { status: 400 })
if (!name || !email || !message) return new Response('Invalid input', { status: 400 })
const supabaseUrl = env.SUPABASE_URL
const supabaseKey = env.SUPABASE_KEY
const supabase = createClient(supabaseUrl, supabaseKey)
const { error } = await supabase.from('contacts').insert([
{ name, email, message, replied: false }
])
if (error) throw error
const forwardEmailApiKey = env.FORWARDEMAIL_API_KEY
const authHeader = 'Basic ' + btoa(`${forwardEmailApiKey}:`)
const emailData = new URLSearchParams({
from: 'hi@admin.coryd.dev',
to: 'hi@coryd.dev',
subject: 'New contact form submission',
text: `Name: ${name}\nEmail: ${email}\nMessage: ${message}`,
replyTo: email
}).toString()
const response = await fetch('https://api.forwardemail.net/v1/emails', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': authHeader
},
body: emailData
})
if (!response.ok) {
const errorText = await response.text()
console.error('Email API response error:', response.status, errorText)
throw new Error(`Failed to send email: ${errorText}`)
}
return Response.redirect('https://coryd.dev/contact/success', 301)
} catch (error) {
console.error('Error:', error.message)
return Response.redirect('https://coryd.dev/broken', 301)
}
} else {
return Response.redirect('https://coryd.dev/not-allowed', 301)
}
}
}