Skip to content

Commit

Permalink
Return limits and remaining count in headers
Browse files Browse the repository at this point in the history
  • Loading branch information
ChaituVR committed Aug 4, 2023
1 parent 6f2649f commit e37eb7c
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 14 deletions.
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);

Check failure on line 17 in src/helpers/keycard.ts

View workflow job for this annotation

GitHub Actions / build-test

Property 'limit' does not exist on type '{ valid: boolean; rateLimited?: boolean | undefined; }'.

Check failure on line 17 in src/helpers/keycard.ts

View workflow job for this annotation

GitHub Actions / lint

Property 'limit' does not exist on type '{ valid: boolean; rateLimited?: boolean | undefined; }'.
res.set('X-Api-Key-Remaining', keycardData.remaining);

Check failure on line 18 in src/helpers/keycard.ts

View workflow job for this annotation

GitHub Actions / build-test

Property 'remaining' does not exist on type '{ valid: boolean; rateLimited?: boolean | undefined; }'.

Check failure on line 18 in src/helpers/keycard.ts

View workflow job for this annotation

GitHub Actions / lint

Property 'remaining' does not exist on type '{ valid: boolean; rateLimited?: boolean | undefined; }'.
res.set('X-Api-Key-Reset', keycardData.reset);

Check failure on line 19 in src/helpers/keycard.ts

View workflow job for this annotation

GitHub Actions / build-test

Property 'reset' does not exist on type '{ valid: boolean; rateLimited?: boolean | undefined; }'.

Check failure on line 19 in src/helpers/keycard.ts

View workflow job for this annotation

GitHub Actions / lint

Property 'reset' does not exist on type '{ valid: boolean; rateLimited?: boolean | undefined; }'.
}
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

0 comments on commit e37eb7c

Please sign in to comment.