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 () => {