Skip to content

Commit 00d0547

Browse files
committed
feat(graphql-api): allow whitelisted IPs to bypass rate limits
1 parent b52b4c4 commit 00d0547

File tree

3 files changed

+31
-0
lines changed

3 files changed

+31
-0
lines changed

graphql-api/src/app.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import { client as esClient } from './elasticsearch'
88
import graphQLApi from './graphql/graphql-api'
99
import logger from './logger'
1010

11+
import { loadWhitelist } from './whitelist'
12+
1113
process.on('uncaughtException', (error) => {
1214
logger.error(error)
1315
process.exit(1)
@@ -75,6 +77,8 @@ app.use(function requestLogMiddleware(request: any, response: any, next: any) {
7577
next()
7678
})
7779

80+
loadWhitelist()
81+
7882
const context = { esClient }
7983

8084
app.use('/api/', graphQLApi({ context }))

graphql-api/src/graphql/rate-limiting.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Redis } from 'ioredis'
22
import config from '../config'
33
import { UserVisibleError } from '../errors'
44
import logger from '../logger'
5+
import { isWhitelistedIP } from '../whitelist'
56

67
let rateLimitDb: Redis
78

@@ -47,6 +48,10 @@ export const applyRateLimits = async (request: any) => {
4748

4849
const clientId = request.ip
4950

51+
if (isWhitelistedIP(clientId)) {
52+
return
53+
}
54+
5055
try {
5156
const totalRequestsInWindow = await increaseRateLimitCounter(
5257
`rate_limit:1m:requests:${clientId}:${rateLimitWindow}`,

graphql-api/src/whitelist.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Storage } from '@google-cloud/storage'
2+
3+
const storage = new Storage()
4+
let whitelistedIPs: Set<string> = new Set()
5+
6+
export async function loadWhitelist() {
7+
try {
8+
const bucket = storage.bucket('gnomad-configs')
9+
const file = bucket.file('whitelist.json')
10+
const [contents] = await file.download()
11+
const data = JSON.parse(contents.toString())
12+
whitelistedIPs = new Set(data.whitelisted_ips)
13+
// TODO: REMOVEME
14+
console.log(`Loaded ${whitelistedIPs.size} whitelisted IPs`)
15+
} catch (err) {
16+
console.error('Failed to load IP whitelist: ', err)
17+
}
18+
}
19+
20+
export function isWhitelistedIP(ip: string): boolean {
21+
return whitelistedIPs.has(ip)
22+
}

0 commit comments

Comments
 (0)