Enhance platform security and monitoring with rate limiting and caching
Adds security middleware, rate limiting, Redis caching, and monitoring services for improved security, performance, and analytics. Replit-Commit-Author: Agent Replit-Commit-Session-Id: c5f0c281-8dd8-4846-b452-4a07bcd21062 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/9777c70b-fc38-4831-8d6b-78dfffe041b0/c9b78723-c2e4-4754-83c6-8d40e8eb250e.jpg
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
import rateLimit from 'express-rate-limit';
|
||||
import helmet from 'helmet';
|
||||
import compression from 'compression';
|
||||
import type { Request, Response, NextFunction } from 'express';
|
||||
|
||||
// Rate limiting configurations
|
||||
export const generalRateLimit = rateLimit({
|
||||
windowMs: 15 * 60 * 1000, // 15 minutes
|
||||
max: 100, // 100 requests per window
|
||||
message: {
|
||||
error: 'Too many requests from this IP, please try again later.',
|
||||
retryAfter: '15 minutes'
|
||||
},
|
||||
standardHeaders: true,
|
||||
legacyHeaders: false
|
||||
});
|
||||
|
||||
export const authRateLimit = rateLimit({
|
||||
windowMs: 15 * 60 * 1000, // 15 minutes
|
||||
max: 5, // 5 login attempts per window
|
||||
skipSuccessfulRequests: true,
|
||||
message: {
|
||||
error: 'Too many authentication attempts, please try again later.',
|
||||
retryAfter: '15 minutes'
|
||||
}
|
||||
});
|
||||
|
||||
export const voiceRateLimit = rateLimit({
|
||||
windowMs: 60 * 1000, // 1 minute
|
||||
max: 30, // 30 voice commands per minute
|
||||
message: {
|
||||
error: 'Voice command rate limit exceeded, please wait before trying again.',
|
||||
retryAfter: '1 minute'
|
||||
}
|
||||
});
|
||||
|
||||
export const aiRateLimit = rateLimit({
|
||||
windowMs: 60 * 1000, // 1 minute
|
||||
max: 10, // 10 AI requests per minute
|
||||
message: {
|
||||
error: 'AI service rate limit exceeded, please wait before trying again.',
|
||||
retryAfter: '1 minute'
|
||||
}
|
||||
});
|
||||
|
||||
// Security middleware
|
||||
export const securityMiddleware = helmet({
|
||||
contentSecurityPolicy: {
|
||||
directives: {
|
||||
defaultSrc: ["'self'"],
|
||||
styleSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"],
|
||||
fontSrc: ["'self'", "https://fonts.gstatic.com"],
|
||||
scriptSrc: ["'self'"],
|
||||
imgSrc: ["'self'", "data:", "https:"],
|
||||
connectSrc: ["'self'", "ws:", "wss:"]
|
||||
}
|
||||
},
|
||||
crossOriginEmbedderPolicy: false
|
||||
});
|
||||
|
||||
// Compression middleware
|
||||
export const compressionMiddleware = compression({
|
||||
filter: (req: Request, res: Response) => {
|
||||
if (req.headers['x-no-compression']) {
|
||||
return false;
|
||||
}
|
||||
return compression.filter(req, res);
|
||||
},
|
||||
threshold: 1024 // Only compress responses larger than 1KB
|
||||
});
|
||||
|
||||
// Error tracking middleware
|
||||
export const errorTrackingMiddleware = (
|
||||
error: any,
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
) => {
|
||||
// Log error details
|
||||
console.error('Error:', {
|
||||
message: error.message,
|
||||
stack: error.stack,
|
||||
url: req.url,
|
||||
method: req.method,
|
||||
ip: req.ip,
|
||||
userAgent: req.get('User-Agent'),
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
|
||||
// Don't expose internal errors in production
|
||||
const isDevelopment = process.env.NODE_ENV === 'development';
|
||||
|
||||
if (error.status && error.status < 500) {
|
||||
// Client errors (4xx)
|
||||
res.status(error.status).json({
|
||||
error: error.message,
|
||||
...(isDevelopment && { stack: error.stack })
|
||||
});
|
||||
} else {
|
||||
// Server errors (5xx)
|
||||
res.status(500).json({
|
||||
error: isDevelopment ? error.message : 'Internal server error',
|
||||
...(isDevelopment && { stack: error.stack })
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Request logging middleware
|
||||
export const requestLoggingMiddleware = (req: Request, res: Response, next: NextFunction) => {
|
||||
const start = Date.now();
|
||||
|
||||
res.on('finish', () => {
|
||||
const duration = Date.now() - start;
|
||||
console.log(`${req.method} ${req.url} ${res.statusCode} ${duration}ms`);
|
||||
});
|
||||
|
||||
next();
|
||||
};
|
||||
Reference in New Issue
Block a user