UNPKG

wkr-util

Version:
54 lines (49 loc) 1.88 kB
import {compose, split, map, trim, pick} from '@cullylarson/f' import rateLimit from 'express-rate-limit' import {messageObj} from '@cullylarson/validate' import {formatIpv4, responseError} from './' import {logLevels} from './log' export const RateLimit = ({ tooManyErrorMessage = 'You have made too many requests to this resource. Please try again later.', tooManyErrorKey = 'too-many-requests', tooManyErrorStatus = 429, rateLimitIpsWhitelistStr = null, rateLimitIpsWhitelist = [], logRepo = null, ...rateLimitParams }) => { if(rateLimitIpsWhitelistStr && (!rateLimitIpsWhitelist || !rateLimitIpsWhitelist.length)) { rateLimitIpsWhitelist = compose( map(trim), split(','), )(rateLimitIpsWhitelistStr) } return rateLimit({ windowMs: 5 * 60 * 1000, // 5 minutes max: 300, // limit each IP to this many requests per windowMs skipSuccessfulRequests: true, skip: (req) => { const ip = formatIpv4(req.ip) return ip === '127.0.0.1' || rateLimitIpsWhitelist.includes(ip) }, handler: (req, res) => { return res.status(tooManyErrorStatus).json(responseError(messageObj(tooManyErrorKey, tooManyErrorMessage))) }, onLimitReached: (req, res, options) => { if(!logRepo) return logRepo.add( 'too-many-requests', logLevels.NOTICE, 'This IP address has made too many requests and has been rate-limited.', { data: { ...pick(['windowMs', 'max'], options), ...pick(['limit', 'current', 'remaining', 'resetTime'], req.rateLimit), }, }, req, ) }, ...rateLimitParams, }) }