diff --git a/lib/partner-listener/routers/product-price.js b/lib/partner-listener/routers/product-price.js index 8168ac2..c63f146 100644 --- a/lib/partner-listener/routers/product-price.js +++ b/lib/partner-listener/routers/product-price.js @@ -1,8 +1,13 @@ const MODULE_NAME = 'PARTNER-LISTENER.ROUTERS.PRODUCT-PRICE'; +const RATE_LIMIT_MESSAGE = 'Rate limited. Cobalah satu menit lagi!\n'; +const RATE_LIMIT_MAX = 2; +const RATE_LIMIT_WINDOW_MS = 60 * 1000; + const axios = require('axios').default; const express = require('express'); const urlJoin = require('join-path'); +const expressRateLimit = require('express-rate-limit'); const coreUrl = require('komodo-sdk/core-url'); const logger = require('tektrans-logger'); @@ -16,6 +21,16 @@ const CORE_ENDPOINT = urlJoin(coreUrl, '/product-tree'); const router = express.Router(); module.exports = router; +const rateLimit = expressRateLimit({ + windowMs: RATE_LIMIT_WINDOW_MS, + max: RATE_LIMIT_MAX, + message: RATE_LIMIT_MESSAGE, + keyGenerator: (req, res) => res.locals && res.locals.terminalName, + // handler: (req, res, next, opts) => { + // onRateLimited(req, res, 'ip', opts); + // }, +}); + const traverse = (data, productType) => { const products = []; @@ -47,11 +62,16 @@ const traverse = (data, productType) => { return products; }; +const extractTerminalName = (req, res, next) => { + const terminalNameWithoutIp = (getFromBodyQsParams(req, 'terminal_name') || '').toString().trim(); + res.locals.terminalName = `${terminalNameWithoutIp}@${ipv6ToIpv4(req.ip)}`; + next(); +}; + const mainHandler = async (req, res) => { const { xid } = res.locals; - const terminalNameWithoutIp = (getFromBodyQsParams(req, 'terminal_name') || '').toString().trim(); - const terminalName = `${terminalNameWithoutIp}@${ipv6ToIpv4(req.ip)}`; + const { terminalName } = res.locals; const password = getFromBodyQsParams(req, 'password'); try { @@ -96,4 +116,4 @@ const mainHandler = async (req, res) => { } }; -router.get('/', mainHandler); +router.get('/', extractTerminalName, rateLimit, mainHandler); diff --git a/package-lock.json b/package-lock.json index 236a393..11fde53 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "axios": "^0.19.2", "express": "^4.17.1", + "express-rate-limit": "^6.6.0", "join-path": "^1.1.1", "komodo-sdk": "^1.45.6", "mkdirp": "^1.0.4", @@ -1173,6 +1174,17 @@ "node": ">= 0.10.0" } }, + "node_modules/express-rate-limit": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-6.6.0.tgz", + "integrity": "sha512-HFN2+4ZGdkQOS8Qli4z6knmJFnw6lZed67o6b7RGplWeb1Z0s8VXaj3dUgPIdm9hrhZXTRpCTHXA0/2Eqex0vA==", + "engines": { + "node": ">= 12.9.0" + }, + "peerDependencies": { + "express": "^4 || ^5" + } + }, "node_modules/express-session": { "version": "1.17.2", "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.2.tgz", @@ -5600,6 +5612,12 @@ } } }, + "express-rate-limit": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-6.6.0.tgz", + "integrity": "sha512-HFN2+4ZGdkQOS8Qli4z6knmJFnw6lZed67o6b7RGplWeb1Z0s8VXaj3dUgPIdm9hrhZXTRpCTHXA0/2Eqex0vA==", + "requires": {} + }, "express-session": { "version": "1.17.2", "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.2.tgz", diff --git a/package.json b/package.json index 392374b..33096de 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "dependencies": { "axios": "^0.19.2", "express": "^4.17.1", + "express-rate-limit": "^6.6.0", "join-path": "^1.1.1", "komodo-sdk": "^1.45.6", "mkdirp": "^1.0.4",