Skip to content

Commit

Permalink
Return limits and remaining count in headers (#634)
Browse files Browse the repository at this point in the history
* Return limits and remaining count in headers

* Use keycard.js from github

* Update keycard.js

* Update keycard.js package
  • Loading branch information
ChaituVR authored Aug 7, 2023
1 parent 4948338 commit 617c795
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 19 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "^0.2.0",
"@snapshot-labs/pineapple": "^0.1.0-beta.1",
"@snapshot-labs/snapshot-sentry": "^1.1.0",
"@snapshot-labs/snapshot.js": "^0.4.108",
Expand Down
17 changes: 10 additions & 7 deletions src/helpers/keycard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
11 changes: 7 additions & 4 deletions src/helpers/rateLimit.ts
Original file line number Diff line number Diff line change
@@ -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)}`);
Expand Down
6 changes: 3 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -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'));
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1286,10 +1286,10 @@
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@^0.2.0":
version "0.2.0"
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"

Expand Down

0 comments on commit 617c795

Please sign in to comment.