Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ffcfd9766d | |||
| 3501a52f0e |
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "picpeak-backend",
|
||||
"version": "1.0.59",
|
||||
"version": "1.0.60",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "picpeak-backend",
|
||||
"version": "1.0.59",
|
||||
"version": "1.0.60",
|
||||
"dependencies": {
|
||||
"adm-zip": "^0.5.16",
|
||||
"archiver": "^5.3.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "picpeak-backend",
|
||||
"version": "1.0.59",
|
||||
"version": "1.0.60",
|
||||
"description": "Backend for PicPeak event photo sharing platform",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
|
||||
+72
-1
@@ -97,6 +97,38 @@ app.use(cors(corsOptions));
|
||||
const limiter = rateLimit({
|
||||
windowMs: 15 * 60 * 1000, // 15 minutes
|
||||
max: process.env.NODE_ENV === 'development' ? 1000 : 100, // More lenient in development
|
||||
// Use correct client IP when behind proxy
|
||||
keyGenerator: (req) => {
|
||||
// Get the real client IP from proxy headers
|
||||
const clientIp = req.headers['x-forwarded-for']?.split(',')[0]?.trim() ||
|
||||
req.headers['x-real-ip'] ||
|
||||
req.connection.remoteAddress ||
|
||||
req.ip;
|
||||
|
||||
// Log rate limit key for debugging (only in development)
|
||||
if (process.env.NODE_ENV === 'development' && req.path.includes('/api/')) {
|
||||
logger.debug('Rate limit key generated', {
|
||||
path: req.path,
|
||||
clientIp,
|
||||
headers: {
|
||||
'x-forwarded-for': req.headers['x-forwarded-for'],
|
||||
'x-real-ip': req.headers['x-real-ip']
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return clientIp;
|
||||
},
|
||||
handler: (req, res) => {
|
||||
logger.warn('Rate limit exceeded', {
|
||||
ip: req.headers['x-forwarded-for']?.split(',')[0]?.trim() || req.ip,
|
||||
path: req.path,
|
||||
method: req.method
|
||||
});
|
||||
res.status(429).json({
|
||||
error: 'Too many requests, please try again later.'
|
||||
});
|
||||
},
|
||||
skip: (req) => {
|
||||
// Skip rate limiting for authenticated admin users
|
||||
if (req.path.startsWith('/api/admin/') && req.headers.authorization) {
|
||||
@@ -118,7 +150,24 @@ const limiter = rateLimit({
|
||||
|
||||
const authLimiter = rateLimit({
|
||||
windowMs: 15 * 60 * 1000,
|
||||
max: 5 // limit auth attempts
|
||||
max: 5, // limit auth attempts
|
||||
// Use correct client IP when behind proxy
|
||||
keyGenerator: (req) => {
|
||||
// Get the real client IP from proxy headers
|
||||
return req.headers['x-forwarded-for']?.split(',')[0]?.trim() ||
|
||||
req.headers['x-real-ip'] ||
|
||||
req.connection.remoteAddress ||
|
||||
req.ip;
|
||||
},
|
||||
handler: (req, res) => {
|
||||
logger.warn('Auth rate limit exceeded', {
|
||||
ip: req.headers['x-forwarded-for']?.split(',')[0]?.trim() || req.ip,
|
||||
path: req.path
|
||||
});
|
||||
res.status(429).json({
|
||||
error: 'Too many authentication attempts, please try again later.'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Apply rate limiting - admin routes check will skip for valid admin tokens
|
||||
@@ -158,6 +207,28 @@ app.use('/thumbnails', require('./src/middleware/photoAuth'), setCorsHeaders, se
|
||||
// Static file serving for uploads (public - logos, favicons)
|
||||
app.use('/uploads', setCorsHeaders, secureStatic(path.join(storagePath, 'uploads')));
|
||||
|
||||
// Debug endpoint to check IP detection (only in development)
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
app.get('/api/debug/ip', (req, res) => {
|
||||
const clientIp = req.headers['x-forwarded-for']?.split(',')[0]?.trim() ||
|
||||
req.headers['x-real-ip'] ||
|
||||
req.connection.remoteAddress ||
|
||||
req.ip;
|
||||
|
||||
res.json({
|
||||
detectedIp: clientIp,
|
||||
reqIp: req.ip,
|
||||
headers: {
|
||||
'x-forwarded-for': req.headers['x-forwarded-for'],
|
||||
'x-real-ip': req.headers['x-real-ip'],
|
||||
'x-forwarded-proto': req.headers['x-forwarded-proto'],
|
||||
'x-forwarded-host': req.headers['x-forwarded-host']
|
||||
},
|
||||
trustProxy: app.get('trust proxy')
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Health check endpoint
|
||||
app.get('/health', async (req, res) => {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user