From c490bf19c8fbcc7575c3a746d97c6be1c4ddd688 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sat, 8 Nov 2025 00:08:11 +0000 Subject: [PATCH] Add rate limiting to company submission functions Implement rate limiting for `submitCompanyCreation` and `submitCompanyUpdate` to prevent abuse and ensure pipeline integrity. This includes adding checks for submission rate limits and recording submission attempts. --- src/lib/companyHelpers.ts | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/lib/companyHelpers.ts b/src/lib/companyHelpers.ts index b558beb0..bb20b747 100644 --- a/src/lib/companyHelpers.ts +++ b/src/lib/companyHelpers.ts @@ -5,14 +5,46 @@ import { CompanyFormData, TempCompanyData } from '@/types/company'; import { handleError } from './errorHandler'; import { withRetry, isRetryableError } from './retryHelpers'; import { logger } from './logger'; +import { checkSubmissionRateLimit, recordSubmissionAttempt } from './submissionRateLimiter'; +import { sanitizeErrorMessage } from './errorSanitizer'; export type { CompanyFormData, TempCompanyData }; +/** + * Rate limiting helper - checks rate limits before allowing submission + */ +function checkRateLimitOrThrow(userId: string, action: string): void { + const rateLimit = checkSubmissionRateLimit(userId); + + if (!rateLimit.allowed) { + const sanitizedMessage = sanitizeErrorMessage(rateLimit.reason || 'Rate limit exceeded'); + + logger.warn('[RateLimit] Company submission blocked', { + userId, + action, + reason: rateLimit.reason, + retryAfter: rateLimit.retryAfter, + }); + + throw new Error(sanitizedMessage); + } + + logger.info('[RateLimit] Company submission allowed', { + userId, + action, + remaining: rateLimit.remaining, + }); +} + export async function submitCompanyCreation( data: CompanyFormData, companyType: 'manufacturer' | 'designer' | 'operator' | 'property_owner', userId: string ) { + // Phase 3: Rate limiting check + checkRateLimitOrThrow(userId, 'company_creation'); + recordSubmissionAttempt(userId); + // Check if user is banned (with quick retry for read operation) const profile = await withRetry( async () => { @@ -145,6 +177,10 @@ export async function submitCompanyUpdate( data: CompanyFormData, userId: string ) { + // Phase 3: Rate limiting check + checkRateLimitOrThrow(userId, 'company_update'); + recordSubmissionAttempt(userId); + // Check if user is banned (with quick retry for read operation) const profile = await withRetry( async () => {