From 1bbcae611976acc62f8cdf46bce8a0cf8d1391fc Mon Sep 17 00:00:00 2001 From: Carlo Morgenstern Date: Sun, 24 Oct 2021 15:51:02 +0200 Subject: [PATCH] Added rate limiter to all XIV API requests --- index.js | 16 ++++++++++++---- package.json | 1 + yarn.lock | 5 +++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index b34aaad..2366d64 100644 --- a/index.js +++ b/index.js @@ -2,6 +2,7 @@ const cacheManager = require('cache-manager'); const express = require('express'); const fetch = require('node-fetch'); const fsStore = require('cache-manager-fs-binary'); +const rateLimit = require("express-rate-limit"); const { CardCreator } = require('./create-card'); @@ -25,6 +26,13 @@ const diskCache = cacheManager.caching({ } }); +// Rate limit all requests that result in XIV API calls +const limiter = rateLimit({ + windowMs: 1000, // ms = 1s + max: 20, // default XIV API request limit + keyGenerator: () => 'global', +}); + async function getCharacterIdByName(world, name, retries = 1) { if (retries === -1) return undefined; @@ -61,7 +69,7 @@ function getOriginalQueryString(req) { return url.search; } -app.get('/prepare/id/:characterId', (req, res, next) => { +app.get('/prepare/id/:characterId', limiter, (req, res, next) => { const language = typeof req.query.lang === 'string' && supportedLanguages.includes(req.query.lang) ? req.query.lang : supportedLanguages[0]; cacheCreateCard(req.params.characterId, null, language) @@ -74,7 +82,7 @@ app.get('/prepare/id/:characterId', (req, res, next) => { .catch(next); }); -app.get('/prepare/name/:world/:characterName', (req, res, next) => { +app.get('/prepare/name/:world/:characterName', limiter, (req, res, next) => { getCharacterIdByName(req.params.world, req.params.characterName) .then(characterId => { if (characterId == null) { @@ -86,7 +94,7 @@ app.get('/prepare/name/:world/:characterName', (req, res, next) => { .catch(next); }); -app.get('/characters/id/:characterId.png', (req, res, next) => { +app.get('/characters/id/:characterId.png', limiter, (req, res, next) => { const language = typeof req.query.lang === 'string' && supportedLanguages.includes(req.query.lang) ? req.query.lang : supportedLanguages[0]; cacheCreateCard(req.params.characterId, null, language) @@ -108,7 +116,7 @@ app.get('/characters/id/:characterId', (req, res) => { res.redirect(`/characters/id/${req.params.characterId}.png${getOriginalQueryString(req)}`); }); -app.get('/characters/name/:world/:characterName.png', (req, res, next) => { +app.get('/characters/name/:world/:characterName.png', limiter, (req, res, next) => { getCharacterIdByName(req.params.world, req.params.characterName) .then(characterId => { if (characterId == null) { diff --git a/package.json b/package.json index 0cdfe74..fdd65f6 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "cache-manager-fs-binary": "^1.0.4", "canvas": "^2.8.0", "express": "^4.17.1", + "express-rate-limit": "^5.5.0", "node-fetch": "^2.6.5" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index 614c006..3ddac65 100644 --- a/yarn.lock +++ b/yarn.lock @@ -534,6 +534,11 @@ etag@~1.8.1: resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= +express-rate-limit@^5.5.0: + version "5.5.0" + resolved "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-5.5.0.tgz" + integrity sha512-/1mrKggjXMxd1/ghPub5N3d36u5VlK8KjbQFQLxYub09BWSSgSXMQbXgFiIW0BYxjM49YCj8bkihONZR2U4+mQ== + express@^4.17.1: version "4.17.1" resolved "https://registry.npmjs.org/express/-/express-4.17.1.tgz"