mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 06:11:11 -05:00
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.
This commit is contained in:
@@ -5,14 +5,46 @@ import { CompanyFormData, TempCompanyData } from '@/types/company';
|
|||||||
import { handleError } from './errorHandler';
|
import { handleError } from './errorHandler';
|
||||||
import { withRetry, isRetryableError } from './retryHelpers';
|
import { withRetry, isRetryableError } from './retryHelpers';
|
||||||
import { logger } from './logger';
|
import { logger } from './logger';
|
||||||
|
import { checkSubmissionRateLimit, recordSubmissionAttempt } from './submissionRateLimiter';
|
||||||
|
import { sanitizeErrorMessage } from './errorSanitizer';
|
||||||
|
|
||||||
export type { CompanyFormData, TempCompanyData };
|
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(
|
export async function submitCompanyCreation(
|
||||||
data: CompanyFormData,
|
data: CompanyFormData,
|
||||||
companyType: 'manufacturer' | 'designer' | 'operator' | 'property_owner',
|
companyType: 'manufacturer' | 'designer' | 'operator' | 'property_owner',
|
||||||
userId: string
|
userId: string
|
||||||
) {
|
) {
|
||||||
|
// Phase 3: Rate limiting check
|
||||||
|
checkRateLimitOrThrow(userId, 'company_creation');
|
||||||
|
recordSubmissionAttempt(userId);
|
||||||
|
|
||||||
// Check if user is banned (with quick retry for read operation)
|
// Check if user is banned (with quick retry for read operation)
|
||||||
const profile = await withRetry(
|
const profile = await withRetry(
|
||||||
async () => {
|
async () => {
|
||||||
@@ -145,6 +177,10 @@ export async function submitCompanyUpdate(
|
|||||||
data: CompanyFormData,
|
data: CompanyFormData,
|
||||||
userId: string
|
userId: string
|
||||||
) {
|
) {
|
||||||
|
// Phase 3: Rate limiting check
|
||||||
|
checkRateLimitOrThrow(userId, 'company_update');
|
||||||
|
recordSubmissionAttempt(userId);
|
||||||
|
|
||||||
// Check if user is banned (with quick retry for read operation)
|
// Check if user is banned (with quick retry for read operation)
|
||||||
const profile = await withRetry(
|
const profile = await withRetry(
|
||||||
async () => {
|
async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user