Skip to content

Commit

Permalink
fix: ratelimiting using 'username' as key instead of the actual username
Browse files Browse the repository at this point in the history
  • Loading branch information
naftis committed Oct 30, 2024
1 parent 7229165 commit 5e245f2
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 4 deletions.
55 changes: 54 additions & 1 deletion packages/gateway/src/rate-limit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ import { resolvers as locationRootResolvers } from '@gateway/features/location/r
import * as fetchAny from 'jest-fetch-mock'
import * as jwt from 'jsonwebtoken'
import { readFileSync } from 'fs'
// eslint-disable-next-line import/no-relative-parent-imports
import {
startContainer,
stopContainer,
flushAll
} from './utils/redis-test-utils'
import { StartedTestContainer } from 'testcontainers'
import { savedAdministrativeLocation } from '@opencrvs/commons/fixtures'
import { createServer } from '@gateway/server'

const fetch = fetchAny as any
const resolvers = rootResolvers as any
Expand Down Expand Up @@ -239,4 +239,57 @@ describe('Rate limit', () => {

return expect(() => Promise.all(resolverCalls)).not.toThrowError()
})

it.only('handles multiple users authenticating with different usernames', async () => {
const server = await createServer()

// okay to go through 10 times
for (let i = 1; i <= 10; i++) {
const res = await server.app.inject({
method: 'POST',
url: '/auth/authenticate',
payload: {
username: 'test.user',
password: 'test'
}
})

expect((res.result as any).statusCode).not.toBe(402)
}

// should return 402 Forbidden
const res = await server.app.inject({
method: 'POST',
url: '/auth/authenticate',
payload: {
username: 'test.user',
password: 'test'
}
})
expect((res.result as any).statusCode).toBe(402)

// okay to go through 10 times with a different username
for (let i = 1; i <= 10; i++) {
const res = await server.app.inject({
method: 'POST',
url: '/auth/authenticate',
payload: {
username: 'test.user2',
password: 'test'
}
})
expect((res.result as any).statusCode).not.toBe(402)
}

// should return 402 Forbidden
const res2 = await server.app.inject({
method: 'POST',
url: '/auth/authenticate',
payload: {
username: 'test.user2',
password: 'test'
}
})
expect((res2.result as any).statusCode).toBe(402)
})
})
9 changes: 6 additions & 3 deletions packages/gateway/src/rate-limit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,17 @@ export const rateLimitedRoute =
const key = pathOptionsForKey!.find(
(path) => get(payload, path) !== undefined
)
const value = payload[key!]

if (!key) {
throw new Error("Couldn't find a rate limiting key in payload")
if (!value) {
throw new Error(
"Couldn't find the value for a rate limiting key in payload"
)
}

return withRateLimit(
{
key: `${key}:${route}`,
key: `${value}:${route}`,
requestsPerMinute
},
fn
Expand Down

0 comments on commit 5e245f2

Please sign in to comment.