From e37eb7c9e1a261ed9ef6195fb389d6eef25de683 Mon Sep 17 00:00:00 2001 From: ChaituVR Date: Sat, 5 Aug 2023 01:20:33 +0530 Subject: [PATCH 1/4] Return limits and remaining count in headers --- src/helpers/keycard.ts | 17 ++++++++++------- src/helpers/rateLimit.ts | 11 +++++++---- src/index.ts | 6 +++--- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/helpers/keycard.ts b/src/helpers/keycard.ts index 3c419441..3e0171ef 100644 --- a/src/helpers/keycard.ts +++ b/src/helpers/keycard.ts @@ -7,15 +7,18 @@ const keycard = new Keycard({ URL: process.env.KEYCARD_URL || 'https://keycard.snapshot.org' }); -const verifyKeyCard = async (req, res, next) => { - const key = req.headers['x-api-key'] || req.query.apiKey; - if (key && keycard.configured) { - const { valid, rateLimited } = keycard.logReq(key); +const checkKeycard = async (req, res, next) => { + const apiKey = req.headers['x-api-key'] || req.query.apiKey; + if (apiKey && keycard.configured) { + const keycardData = keycard.logReq(apiKey); + if (!keycardData.valid) return sendError(res, 'invalid api key', 401); - if (!valid) return sendError(res, 'invalid api key', 401); - if (rateLimited) return sendError(res, 'too many requests', 429); + res.locals.keycardData = keycardData; + res.set('X-Api-Key-Limit', keycardData.limit); + res.set('X-Api-Key-Remaining', keycardData.remaining); + res.set('X-Api-Key-Reset', keycardData.reset); } return next(); }; -export { keycard, verifyKeyCard }; +export { keycard, checkKeycard }; diff --git a/src/helpers/rateLimit.ts b/src/helpers/rateLimit.ts index 9a7f26d9..93d549ea 100644 --- a/src/helpers/rateLimit.ts +++ b/src/helpers/rateLimit.ts @@ -1,16 +1,19 @@ import rateLimit from 'express-rate-limit'; import { getIp, sendError } from './utils'; import log from './log'; -import { keycard } from './keycard'; export default rateLimit({ windowMs: 20 * 1e3, max: 60, keyGenerator: req => getIp(req), standardHeaders: true, - skip: req => { - const key = req.headers['x-api-key'] || req.query.apiKey; - return key && keycard.configured; + skip: (req, res) => { + const keycardData = res.locals.keycardData; + if (keycardData?.valid && !keycardData.rateLimited) { + return true; + } + + return false; }, handler: (req, res) => { log.info(`too many requests ${getIp(req).slice(0, 7)}`); diff --git a/src/index.ts b/src/index.ts index 9987f9d7..23e505f3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,7 +6,7 @@ import graphql from './graphql'; import rateLimit from './helpers/rateLimit'; import log from './helpers/log'; import './helpers/strategies'; -import { verifyKeyCard } from './helpers/keycard'; +import { checkKeycard } from './helpers/keycard'; import './helpers/moderation'; import { initLogger, fallbackLogger } from '@snapshot-labs/snapshot-sentry'; @@ -19,9 +19,9 @@ app.use(express.json({ limit: '20mb' })); app.use(express.urlencoded({ limit: '20mb', extended: false })); app.use(cors({ maxAge: 86400 })); app.set('trust proxy', 1); -app.use(rateLimit); +app.use(checkKeycard, rateLimit); app.use('/api', api); -app.use('/graphql', verifyKeyCard, graphql); +app.use('/graphql', graphql); fallbackLogger(app); app.get('/*', (req, res) => res.redirect('/api')); From f0c4ef1f62cc3333b10b8fcbc382c4d37c883860 Mon Sep 17 00:00:00 2001 From: ChaituVR Date: Sun, 6 Aug 2023 20:42:00 +0530 Subject: [PATCH 2/4] Use keycard.js from github --- package.json | 2 +- yarn.lock | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index acedd9b0..2c436f39 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "@ethersproject/hash": "^5.5.0", "@ethersproject/providers": "^5.6.8", "@ethersproject/wallet": "^5.6.2", - "@snapshot-labs/keycard": "^0.1.0", + "@snapshot-labs/keycard": "https://github.com/snapshot-labs/keycard.js#update-log-request", "@snapshot-labs/pineapple": "^0.1.0-beta.1", "@snapshot-labs/snapshot-sentry": "^1.1.0", "@snapshot-labs/snapshot.js": "^0.4.107", diff --git a/yarn.lock b/yarn.lock index 09668aa6..404f26ee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1286,10 +1286,9 @@ dependencies: "@snapshot-labs/eslint-config-base" "^0.1.0-beta.7" -"@snapshot-labs/keycard@^0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@snapshot-labs/keycard/-/keycard-0.1.0.tgz#4904a43a61b48f7b0d0db02246f8a104d1daa536" - integrity sha512-CSbioDWmR5nqxYpEAJBzEbLXn8ucsg3arCLI2tgdhDIskH8n19Pzo21jELjql+/zUM8sPMQKnhmv1xTAIq9I4w== +"@snapshot-labs/keycard@https://github.com/snapshot-labs/keycard.js#update-log-request": + version "0.2.0" + resolved "https://github.com/snapshot-labs/keycard.js#2b91cf1eec0ab0bd2272c89d53a895a4c974c033" dependencies: cross-fetch "^3.1.5" From 8ccf98e89dff663687e7228abccfc3345e845e2f Mon Sep 17 00:00:00 2001 From: ChaituVR Date: Sun, 6 Aug 2023 21:30:04 +0530 Subject: [PATCH 3/4] Update keycard.js --- yarn.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 404f26ee..79a8cbce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1288,7 +1288,7 @@ "@snapshot-labs/keycard@https://github.com/snapshot-labs/keycard.js#update-log-request": version "0.2.0" - resolved "https://github.com/snapshot-labs/keycard.js#2b91cf1eec0ab0bd2272c89d53a895a4c974c033" + resolved "https://github.com/snapshot-labs/keycard.js#7e576b15374573d20179f161e7685e67163917ae" dependencies: cross-fetch "^3.1.5" From 5346755b293d472dd9e8a934c9268b9c9248ef8b Mon Sep 17 00:00:00 2001 From: ChaituVR Date: Mon, 7 Aug 2023 12:43:26 +0530 Subject: [PATCH 4/4] Update keycard.js package --- package.json | 2 +- yarn.lock | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 2c436f39..b8a65eb6 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "@ethersproject/hash": "^5.5.0", "@ethersproject/providers": "^5.6.8", "@ethersproject/wallet": "^5.6.2", - "@snapshot-labs/keycard": "https://github.com/snapshot-labs/keycard.js#update-log-request", + "@snapshot-labs/keycard": "^0.2.0", "@snapshot-labs/pineapple": "^0.1.0-beta.1", "@snapshot-labs/snapshot-sentry": "^1.1.0", "@snapshot-labs/snapshot.js": "^0.4.107", diff --git a/yarn.lock b/yarn.lock index 79a8cbce..49d9f5e8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1286,9 +1286,10 @@ dependencies: "@snapshot-labs/eslint-config-base" "^0.1.0-beta.7" -"@snapshot-labs/keycard@https://github.com/snapshot-labs/keycard.js#update-log-request": +"@snapshot-labs/keycard@^0.2.0": version "0.2.0" - resolved "https://github.com/snapshot-labs/keycard.js#7e576b15374573d20179f161e7685e67163917ae" + resolved "https://registry.yarnpkg.com/@snapshot-labs/keycard/-/keycard-0.2.0.tgz#7a9e4dd2224089fd291fe63ada738a70a5407d46" + integrity sha512-cfA2/fNy9MhChl0MR/rF0AY+Dzj9sQPd/jcZbIxsx7p4Dd8ZmSo6ufHz60H7pHBM5r4KgozHTlscN7sQVShZYg== dependencies: cross-fetch "^3.1.5"