diff --git a/packages/bitcore-node/src/config.ts b/packages/bitcore-node/src/config.ts index 23d71fa3146..b52dc02077d 100644 --- a/packages/bitcore-node/src/config.ts +++ b/packages/bitcore-node/src/config.ts @@ -77,7 +77,8 @@ const Config = function(): ConfigType { }; let foundConfig = findConfig(); - config = _.merge(config, foundConfig, {}); + const mergeCopyArray = (objVal, srcVal) => (objVal instanceof Array ? srcVal : undefined); + config = _.mergeWith(config, foundConfig, mergeCopyArray); if (!Object.keys(config.chains).length) { Object.assign(config.chains, { BTC: { diff --git a/packages/bitcore-node/src/models/rateLimit.ts b/packages/bitcore-node/src/models/rateLimit.ts index 6ec018338ac..36d08a112e0 100644 --- a/packages/bitcore-node/src/models/rateLimit.ts +++ b/packages/bitcore-node/src/models/rateLimit.ts @@ -12,6 +12,16 @@ export type IRateLimit = { expireAt?: Date; }; +export enum RateLimitTimes { + None = 0, + Second = 1000, + Minute = RateLimitTimes.Second * 60, + Hour = RateLimitTimes.Minute * 60, + Day = RateLimitTimes.Hour * 24, + Month = RateLimitTimes.Day * 30, + Year = RateLimitTimes.Day * 365 +} + export class RateLimitModel extends BaseModel { constructor(storage?: StorageService) { super('ratelimits', storage); @@ -26,25 +36,25 @@ export class RateLimitModel extends BaseModel { incrementAndCheck(identifier: string, method: string) { return Promise.all([ this.collection.findOneAndUpdate( - { identifier, method, period: 'second', time: { $gt: new Date(Date.now() - 1000) } }, + { identifier, method, period: 'second', time: { $gte: new Date(Date.now() - RateLimitTimes.Second) } }, { - $setOnInsert: { time: new Date(), expireAt: new Date(Date.now() + 10 * 1000) }, + $setOnInsert: { time: new Date(), expireAt: new Date(Date.now() + 2 * RateLimitTimes.Second) }, $inc: { count: 1 } }, { upsert: true, returnOriginal: false } ), this.collection.findOneAndUpdate( - { identifier, method, period: 'minute', time: { $gt: new Date(Date.now() - 60 * 1000) } }, + { identifier, method, period: 'minute', time: { $gte: new Date(Date.now() - RateLimitTimes.Minute) } }, { - $setOnInsert: { time: new Date(), expireAt: new Date(Date.now() + 2 * 60 * 1000) }, + $setOnInsert: { time: new Date(), expireAt: new Date(Date.now() + 2 * RateLimitTimes.Minute) }, $inc: { count: 1 } }, { upsert: true, returnOriginal: false } ), this.collection.findOneAndUpdate( - { identifier, method, period: 'hour', time: { $gt: new Date(Date.now() - 60 * 60 * 1000) } }, + { identifier, method, period: 'hour', time: { $gte: new Date(Date.now() - RateLimitTimes.Hour) } }, { - $setOnInsert: { time: new Date(), expireAt: new Date(Date.now() + 62 * 60 * 1000) }, + $setOnInsert: { time: new Date(), expireAt: new Date(Date.now() + 2 * RateLimitTimes.Hour) }, $inc: { count: 1 } }, { upsert: true, returnOriginal: false } diff --git a/packages/bitcore-node/src/routes/index.ts b/packages/bitcore-node/src/routes/index.ts index 059c83aa4e6..0d326b7974e 100644 --- a/packages/bitcore-node/src/routes/index.ts +++ b/packages/bitcore-node/src/routes/index.ts @@ -7,7 +7,6 @@ import { Web3Proxy } from "./web3"; const app = express(); const bodyParser = require('body-parser'); -app.use(RateLimiter('GLOBAL', 10, 200, 4000)); app.use( bodyParser.json({ limit: 100000000 @@ -58,6 +57,7 @@ function getRouterFromFile(path) { app.use(cors()); app.use(LogMiddleware()); app.use(CacheMiddleware(CacheTimes.Second)); +app.use(RateLimiter('GLOBAL', 10, 200, 4000)); app.use('/api', getRouterFromFile('status')); app.use('/api/:chain/:network', (req: Request, resp: Response, next: any) => {