Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/llms-txt-hub / apps/web/__tests__/lib/security-rate-limiting.test.ts |
| Date | Not specified in source |
| Repository | Janady13/llms-txt-hub |
| Revision | e0f4bf978d4df168369c7601d9c5f5ea89e84377 |
| Branch | main |
| Path or archive member | apps/web/__tests__/lib/security-rate-limiting.test.ts |
| Original SHA-256 | 9eca4b0cc22192354f9f540600cdb8b40364ec563c19460b1be1427ab7f61f04 |
| Git blob SHA | 26e7845d0c1945e19e836534e38084e240cd3868 |
| Reading-copy SHA-256 | 9eca4b0cc22192354f9f540600cdb8b40364ec563c19460b1be1427ab7f61f04 |
Recovered source transcript
Download complete source text ↓174 lines · 5.1 KB
/**
* Tests for rate limiting functionality in security-utils
*
* Critical rate limiting functions that protect against abuse.
*/
import './security-utils-setup'
import { checkRateLimit, getRateLimitKey } from '@/lib/security-utils'
import { createMockRequest } from './security-utils-setup'
describe('Rate Limiting', () => {
beforeEach(() => {
jest.useFakeTimers()
})
afterEach(() => {
jest.useRealTimers()
})
describe('checkRateLimit', () => {
it('allows first request', () => {
const result = checkRateLimit({ identifier: 'test-key' })
expect(result.allowed).toBe(true)
expect(result.resetTime).toBeDefined()
expect(typeof result.resetTime).toBe('number')
})
it('allows requests within limit', () => {
const identifier = 'test-key-within-limit'
const options = { windowMs: 60000, maxRequests: 3 }
for (let i = 0; i < 3; i++) {
const result = checkRateLimit({ identifier, ...options })
expect(result.allowed).toBe(true)
}
})
it('blocks requests exceeding limit', () => {
const identifier = 'test-key-exceeding-limit'
const options = { windowMs: 60000, maxRequests: 2 }
checkRateLimit({ identifier, ...options }) // 1st request
checkRateLimit({ identifier, ...options }) // 2nd request
const result = checkRateLimit({ identifier, ...options }) // 3rd request (should be blocked)
expect(result.allowed).toBe(false)
expect(result.resetTime).toBeDefined()
})
it('resets limit after time window', () => {
const identifier = 'test-key-reset'
const options = { windowMs: 1000, maxRequests: 1 }
checkRateLimit({ identifier, ...options }) // 1st request
const blockedResult = checkRateLimit({ identifier, ...options }) // 2nd request (blocked)
expect(blockedResult.allowed).toBe(false)
// Advance time past the window
jest.advanceTimersByTime(1001)
const allowedResult = checkRateLimit({ identifier, ...options }) // Should be allowed now
expect(allowedResult.allowed).toBe(true)
})
it('handles different keys independently', () => {
const options = { windowMs: 60000, maxRequests: 1 }
const result1 = checkRateLimit({ identifier: 'key1', ...options })
const result2 = checkRateLimit({ identifier: 'key2', ...options })
expect(result1.allowed).toBe(true)
expect(result2.allowed).toBe(true)
})
it('uses correct default options', () => {
const identifier = 'test-defaults'
// Should allow default number of requests (10)
for (let i = 0; i < 10; i++) {
const result = checkRateLimit({ identifier })
expect(result.allowed).toBe(true)
}
// 11th request should be blocked
const result = checkRateLimit({ identifier })
expect(result.allowed).toBe(false)
})
it('handles concurrent requests correctly', () => {
const identifier = 'test-concurrent'
const options = { windowMs: 60000, maxRequests: 2 }
// Simulate concurrent requests
const results = Array.from({ length: 5 }, () => checkRateLimit({ identifier, ...options }))
const allowedCount = results.filter(r => r.allowed).length
const blockedCount = results.filter(r => !r.allowed).length
expect(allowedCount).toBe(2)
expect(blockedCount).toBe(3)
})
})
describe('getRateLimitKey', () => {
it('creates key from IP address', () => {
const request = createMockRequest({
url: 'https://example.com',
headers: {
'x-forwarded-for': '192.168.1.1'
}
})
const key = getRateLimitKey(request)
expect(key).toBe('ratelimit:192.168.1.1')
})
it('falls back to x-real-ip header', () => {
const request = createMockRequest({
url: 'https://example.com',
headers: {
'x-real-ip': '10.0.0.1'
}
})
const key = getRateLimitKey(request)
expect(key).toBe('ratelimit:10.0.0.1')
})
it('uses default IP when headers missing', () => {
const request = createMockRequest({ url: 'https://example.com' })
const key = getRateLimitKey(request)
expect(key).toBe('ratelimit:unknown')
})
it('prefers x-forwarded-for over x-real-ip', () => {
const request = createMockRequest({
url: 'https://example.com',
headers: {
'x-forwarded-for': '192.168.1.1',
'x-real-ip': '10.0.0.1'
}
})
const key = getRateLimitKey(request)
expect(key).toBe('ratelimit:192.168.1.1')
})
it('handles multiple IPs in x-forwarded-for', () => {
const request = createMockRequest({
url: 'https://example.com',
headers: {
'x-forwarded-for': '192.168.1.1, 10.0.0.1, 127.0.0.1'
}
})
const key = getRateLimitKey(request)
expect(key).toBe('ratelimit:192.168.1.1')
})
it('trims whitespace from IP addresses', () => {
const request = createMockRequest({
url: 'https://example.com',
headers: {
'x-forwarded-for': ' 192.168.1.1 '
}
})
const key = getRateLimitKey(request)
expect(key).toBe('ratelimit:192.168.1.1')
})
})
})