92 lines
2.8 KiB
JavaScript
92 lines
2.8 KiB
JavaScript
const rateLimit = require('express-rate-limit');
|
|
const logger = require('../utils/logger');
|
|
|
|
// General API rate limiter
|
|
const apiLimiter = rateLimit({
|
|
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
max: 100, // Limit each IP to 100 requests per windowMs
|
|
message: {
|
|
success: false,
|
|
message: 'Zu viele Anfragen von dieser IP, bitte versuchen Sie es später erneut.'
|
|
},
|
|
standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers
|
|
legacyHeaders: false, // Disable the `X-RateLimit-*` headers
|
|
handler: (req, res) => {
|
|
logger.warn(`Rate limit exceeded for IP: ${req.ip} on ${req.path}`);
|
|
res.status(429).json({
|
|
success: false,
|
|
message: 'Zu viele Anfragen von dieser IP, bitte versuchen Sie es später erneut.'
|
|
});
|
|
}
|
|
});
|
|
|
|
// Strict rate limiter for authentication endpoints
|
|
const authLimiter = rateLimit({
|
|
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
max: 5, // Limit each IP to 5 login attempts per windowMs
|
|
skipSuccessfulRequests: true, // Don't count successful requests
|
|
message: {
|
|
success: false,
|
|
message: 'Zu viele Login-Versuche. Bitte warten Sie 15 Minuten und versuchen Sie es erneut.'
|
|
},
|
|
standardHeaders: true,
|
|
legacyHeaders: false,
|
|
handler: (req, res) => {
|
|
logger.warn(`Auth rate limit exceeded for IP: ${req.ip}`);
|
|
res.status(429).json({
|
|
success: false,
|
|
message: 'Zu viele Login-Versuche. Bitte warten Sie 15 Minuten und versuchen Sie es erneut.'
|
|
});
|
|
}
|
|
});
|
|
|
|
// Strict rate limiter for invite / set-password endpoints
|
|
const inviteLimiter = rateLimit({
|
|
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
max: 10,
|
|
skipSuccessfulRequests: true,
|
|
message: {
|
|
success: false,
|
|
message: 'Zu viele Versuche. Bitte warten Sie 15 Minuten.'
|
|
},
|
|
standardHeaders: true,
|
|
legacyHeaders: false,
|
|
handler: (req, res) => {
|
|
logger.warn(`Invite rate limit exceeded for IP: ${req.ip}`);
|
|
res.status(429).json({
|
|
success: false,
|
|
message: 'Zu viele Versuche. Bitte warten Sie 15 Minuten.'
|
|
});
|
|
}
|
|
});
|
|
|
|
// Limiter für die öffentliche PLZ-Suche.
|
|
// Der Endpunkt stößt ausgehende Anfragen an Nominatim an und teilt sich mit dem
|
|
// Geocoding im Admin-Bereich die globale Mindestwartezeit von geocodeMinDelayMs.
|
|
// Ohne eigenes Limit können anonyme Aufrufe das Anlegen von Führern ausbremsen
|
|
// und die Nominatim-Nutzungsregeln verletzen.
|
|
const geocodeLimiter = rateLimit({
|
|
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
max: 20,
|
|
message: {
|
|
success: false,
|
|
message: 'Zu viele PLZ-Abfragen. Bitte warten Sie einen Moment.'
|
|
},
|
|
standardHeaders: true,
|
|
legacyHeaders: false,
|
|
handler: (req, res) => {
|
|
logger.warn(`Geocode rate limit exceeded for IP: ${req.ip}`);
|
|
res.status(429).json({
|
|
success: false,
|
|
message: 'Zu viele PLZ-Abfragen. Bitte warten Sie einen Moment.'
|
|
});
|
|
}
|
|
});
|
|
|
|
module.exports = {
|
|
apiLimiter,
|
|
authLimiter,
|
|
inviteLimiter,
|
|
geocodeLimiter
|
|
};
|