Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ TELEGRAM_WEBHOOK_URL=https://yourdomain.com/api/telegram/webhook

# Development Settings (Optional)
SKIP_TELEGRAM_VALIDATION=false
# Set to true to disable all rate limiting (use with caution)
SKIP_RATE_LIMITING=false

# Frontend Configuration (VITE_ prefix required for client access)
Expand Down
1 change: 1 addition & 0 deletions server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ const newUser = await db.insert(users).values(validatedUserData);
- `DATABASE_URL`: PostgreSQL connection string
- `SESSION_SECRET`: Session encryption secret
- `PORT`: Server port (default: 3000)
- `SKIP_RATE_LIMITING`: Disable all rate limiting when set to `true` (defaults to enabled in development)

### Middleware Stack

Expand Down
27 changes: 0 additions & 27 deletions server/rateLimiter.simple.ts

This file was deleted.

52 changes: 3 additions & 49 deletions server/rateLimiter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,6 @@ export const generalLimiter = rateLimit({
},
});

// Strict limiter for authentication attempts - 5 requests per 15 minutes
export const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 5, // Limit each IP to 5 auth attempts per windowMs
message: {
error: 'Too many authentication attempts',
message: 'Too many authentication attempts, please try again later.',
retryAfter: '15 minutes',
},
standardHeaders: true,
legacyHeaders: false,
skipSuccessfulRequests: true, // Don't count successful requests
});

// Tournament creation limiter - 10 requests per hour
export const tournamentCreationLimiter = rateLimit({
windowMs: 60 * 60 * 1000, // 1 hour
Expand All @@ -74,6 +60,7 @@ export const tournamentCreationLimiter = rateLimit({
standardHeaders: true,
legacyHeaders: false,
keyGenerator: (req: Request) => safeKeyGenerator(req),
skip: () => shouldSkipRateLimit(),
});

// Tournament registration limiter - 20 requests per 10 minutes
Expand All @@ -88,6 +75,7 @@ export const tournamentRegistrationLimiter = rateLimit({
standardHeaders: true,
legacyHeaders: false,
keyGenerator: (req: Request) => safeKeyGenerator(req),
skip: () => shouldSkipRateLimit(),
});

// Admin operations limiter - 50 requests per 15 minutes
Expand All @@ -102,19 +90,7 @@ export const adminLimiter = rateLimit({
standardHeaders: true,
legacyHeaders: false,
keyGenerator: (req: Request) => safeKeyGenerator(req, 'admin_'),
});

// WebSocket connection limiter - 10 connections per minute
export const websocketLimiter = rateLimit({
windowMs: 60 * 1000, // 1 minute
max: 10, // Limit WebSocket connections
message: {
error: 'WebSocket connection limit exceeded',
message: 'Too many WebSocket connection attempts.',
retryAfter: '1 minute',
},
standardHeaders: true,
legacyHeaders: false,
skip: () => shouldSkipRateLimit(),
});

/**
Expand Down Expand Up @@ -143,32 +119,10 @@ export function createCustomLimiter(options: {
});
}

/**
* Rate limiter for file uploads
*/
export const uploadLimiter = createCustomLimiter({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 20, // 20 uploads per 15 minutes
message: 'Too many file uploads. Please try again later.',
});

/**
* Rate limiter for search operations
*/
export const searchLimiter = createCustomLimiter({
windowMs: 60 * 1000, // 1 minute
max: 30, // 30 searches per minute
message: 'Too many search requests. Please slow down.',
});

export default {
general: generalLimiter,
Copy link

Copilot AI Aug 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The generalLimiter is missing the skip functionality that was added to other limiters. Consider adding skip: () => shouldSkipRateLimit() to ensure consistent behavior across all rate limiters.

Copilot uses AI. Check for mistakes.
auth: authLimiter,
tournamentCreation: tournamentCreationLimiter,
tournamentRegistration: tournamentRegistrationLimiter,
admin: adminLimiter,
websocket: websocketLimiter,
upload: uploadLimiter,
search: searchLimiter,
createCustom: createCustomLimiter,
};
2 changes: 1 addition & 1 deletion server/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { z } from 'zod';

import { telegramAuthMiddleware } from './auth';
import { telegramConfig, isDevelopment } from './config';
import * as rateLimiters from './rateLimiter.simple';
import * as rateLimiters from './rateLimiter';
import { storage } from './storage';

export async function registerRoutes(app: Express): Promise<Server> {
Expand Down
Loading