mirror of
https://github.com/jcreek/SvelteKitSaasBoilerplate.git
synced 2026-07-14 19:43:55 +00:00
feat(#79): Add rate limiting to contact page form
This commit is contained in:
@@ -0,0 +1,30 @@
|
|||||||
|
type RateLimitStore = {
|
||||||
|
[key: string]: { count: number; lastRequest: number };
|
||||||
|
};
|
||||||
|
|
||||||
|
const rateLimitStore: RateLimitStore = {};
|
||||||
|
const RATE_LIMIT_WINDOW = 60 * 5000; // 5 minutes
|
||||||
|
const MAX_REQUESTS = 5;
|
||||||
|
|
||||||
|
export function isRateLimited(ip: string): boolean {
|
||||||
|
const currentTime = Date.now();
|
||||||
|
const requestInfo = rateLimitStore[ip];
|
||||||
|
|
||||||
|
if (!requestInfo) {
|
||||||
|
rateLimitStore[ip] = { count: 1, lastRequest: currentTime };
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentTime - requestInfo.lastRequest > RATE_LIMIT_WINDOW) {
|
||||||
|
rateLimitStore[ip] = { count: 1, lastRequest: currentTime };
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestInfo.count >= MAX_REQUESTS) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
rateLimitStore[ip].count += 1;
|
||||||
|
rateLimitStore[ip].lastRequest = currentTime;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
@@ -3,9 +3,17 @@ import { fail } from '@sveltejs/kit';
|
|||||||
import { sendEmail } from '$lib/utils/brevo/email';
|
import { sendEmail } from '$lib/utils/brevo/email';
|
||||||
import { VITE_CONTACT_EMAIL } from '$env/static/private';
|
import { VITE_CONTACT_EMAIL } from '$env/static/private';
|
||||||
import logger from '$lib/utils/logger/logger';
|
import logger from '$lib/utils/logger/logger';
|
||||||
|
import { isRateLimited } from '$lib/utils/rateLimiter';
|
||||||
|
|
||||||
export const actions: Actions = {
|
export const actions: Actions = {
|
||||||
default: async ({ request }) => {
|
default: async ({ request }) => {
|
||||||
|
const ip =
|
||||||
|
request.headers.get('x-forwarded-for') ?? request.headers.get('remote-addr') ?? 'unknown';
|
||||||
|
|
||||||
|
if (isRateLimited(ip)) {
|
||||||
|
return fail(429, { error: 'Too many requests. Please try again later.' });
|
||||||
|
}
|
||||||
|
|
||||||
const formData = await request.formData();
|
const formData = await request.formData();
|
||||||
const name = formData.get('name') as string;
|
const name = formData.get('name') as string;
|
||||||
const email = formData.get('email') as string;
|
const email = formData.get('email') as string;
|
||||||
|
|||||||
Reference in New Issue
Block a user