diff --git a/backend/server.js b/backend/server.js index b5b53c2..3d35699 100644 --- a/backend/server.js +++ b/backend/server.js @@ -3,6 +3,7 @@ const express = require('express'); const helmet = require('helmet'); const cors = require('cors'); const rateLimit = require('express-rate-limit'); +const jwt = require('jsonwebtoken'); const path = require('path'); const { initializeDatabase } = require('./src/database/db'); const { startFileWatcher } = require('./src/services/fileWatcher'); @@ -46,10 +47,23 @@ const corsOptions = { app.use(cors(corsOptions)); -// Rate limiting +// Rate limiting with admin bypass const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes - max: 100 // limit each IP to 100 requests per windowMs + max: 100, // limit each IP to 100 requests per windowMs + skip: (req) => { + // Skip rate limiting for authenticated admin users + if (req.path.startsWith('/api/admin/') && req.headers.authorization) { + const token = req.headers.authorization.replace('Bearer ', ''); + try { + const decoded = jwt.verify(token, process.env.JWT_SECRET); + return decoded.type === 'admin'; + } catch (err) { + return false; + } + } + return false; + } }); const authLimiter = rateLimit({ @@ -57,6 +71,7 @@ const authLimiter = rateLimit({ max: 5 // limit auth attempts }); +// Apply rate limiting - admin routes check will skip for valid admin tokens app.use('/api/', limiter); app.use('/api/auth', authLimiter);