1+ import type { RequestHandler } from 'express'
2+ import type { Options } from 'express-rate-limit'
13import * as process from 'node:process'
24import * as dotenv from 'dotenv'
35import { rateLimit } from 'express-rate-limit'
@@ -9,15 +11,38 @@ dotenv.config()
911const MAX_REQUEST_PER_HOUR = process . env . MAX_REQUEST_PER_HOUR
1012const AUTH_MAX_REQUEST_PER_MINUTE = process . env . AUTH_MAX_REQUEST_PER_MINUTE
1113
12- const maxCount = ( isNotEmptyString ( MAX_REQUEST_PER_HOUR ) && ! Number . isNaN ( Number ( MAX_REQUEST_PER_HOUR ) ) )
13- ? Number . parseInt ( MAX_REQUEST_PER_HOUR )
14- : 0 // 0 means unlimited
15- const authMaxCount = ( isNotEmptyString ( AUTH_MAX_REQUEST_PER_MINUTE ) && ! Number . isNaN ( Number ( AUTH_MAX_REQUEST_PER_MINUTE ) ) )
16- ? Number . parseInt ( AUTH_MAX_REQUEST_PER_MINUTE )
17- : 0 // 0 means unlimited
18- const limiter = rateLimit ( {
14+ function parsePositiveInt ( value ?: string | null ) : number | null {
15+ if ( ! isNotEmptyString ( value ) ) {
16+ return null
17+ }
18+
19+ const parsedValue = Number . parseInt ( value , 10 )
20+
21+ return Number . isNaN ( parsedValue ) || parsedValue <= 0 ? null : parsedValue
22+ }
23+
24+ const noopLimiter : RequestHandler = ( _req , _res , next ) => {
25+ next ( )
26+ }
27+
28+ type LimiterOptions = Partial < Omit < Options , 'limit' | 'max' > >
29+
30+ function buildLimiter (
31+ count : number | null ,
32+ options : LimiterOptions ,
33+ ) : RequestHandler {
34+ if ( ! count ) {
35+ return noopLimiter
36+ }
37+
38+ return rateLimit ( {
39+ ...options ,
40+ limit : count ,
41+ } )
42+ }
43+
44+ const limiter = buildLimiter ( parsePositiveInt ( MAX_REQUEST_PER_HOUR ) , {
1945 windowMs : 60 * 60 * 1000 , // Maximum number of accesses within an hour
20- max : maxCount ,
2146 statusCode : 200 , // 200 means success,but the message is 'Too many request from this IP in 1 hour'
2247 keyGenerator : ( req , _ ) => {
2348 return requestIp . getClientIp ( req ) // IP address from requestIp.mw(), as opposed to req.ip
@@ -26,9 +51,9 @@ const limiter = rateLimit({
2651 res . send ( { status : 'Fail' , message : 'Too many request from this IP in 1 hour' , data : null } )
2752 } ,
2853} )
29- const authLimiter = rateLimit ( {
54+
55+ const authLimiter = buildLimiter ( parsePositiveInt ( AUTH_MAX_REQUEST_PER_MINUTE ) , {
3056 windowMs : 60 * 1000 , // Maximum number of accesses within a minute
31- max : authMaxCount ,
3257 statusCode : 200 , // 200 means success,but the message is 'Too many request from this IP in 1 minute'
3358 keyGenerator : ( req , _ ) => {
3459 return requestIp . getClientIp ( req ) // IP address from requestIp.mw(), as opposed to req.ip
0 commit comments