Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(api): Add API rate limiting NestJS guard #4910

Merged
merged 191 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from 177 commits
Commits
Show all changes
191 commits
Select commit Hold shift + click to select a range
748b194
feat(dal, shared, api): Add DAL fields for rate limiting
rifont Nov 3, 2023
4b47cce
test(api): Add tests for rate limit fields
rifont Nov 3, 2023
75febc1
test(api): Use enum for apiServiceLevel test assertion
rifont Nov 3, 2023
1e06a6d
Merge branch 'next' into nv-3058-rate-limiting-dtos
rifont Nov 3, 2023
15035d0
fix(dal): Use api prefix for rate limits to differentiate from other …
rifont Nov 3, 2023
81ef5b7
fix(dal): Update category enum to also include api prefix
rifont Nov 3, 2023
d9d86d9
fix(dal): Make apiRateLimits subdocument optional
rifont Nov 3, 2023
05962ea
feat(shared): Add API rate limiting cache key builder
rifont Nov 3, 2023
975df32
fix(dal): Add fallback unlimited tier
rifont Nov 3, 2023
e17ef8e
Merge branch 'nv-3058-rate-limiting-dtos' into nv-3059-get-rate-limit…
rifont Nov 3, 2023
7618b62
feat(shared): Add rate limiting constants
rifont Nov 3, 2023
1d5d7db
feat(api): Add get rate limit use case
rifont Nov 3, 2023
15324a5
fix(api): Fix import path
rifont Nov 6, 2023
642b046
test(application-generic): Refactor mock cache service into separate …
rifont Nov 6, 2023
acab424
test(api): Add unit tests for get-api-rate-limit use-case
rifont Nov 6, 2023
167631f
fix(api): Remove unused LOG_CONTEXT declaration in get-api-rate-limit…
rifont Nov 6, 2023
9cde897
feat(api): Add rate limiting module, add get-default-api-rate-limit u…
rifont Nov 6, 2023
5b8a128
feat(shared): Add types for env var format and platform rate limit map
rifont Nov 6, 2023
9f9cd55
refactor(api): Refactor get-api-rate-limit use-case to use the get-de…
rifont Nov 6, 2023
72cf83b
Merge branch 'next' into nv-3059-get-rate-limit-use-case
rifont Nov 6, 2023
e5e7357
refactor(api, shared): Rename api rate limiting interface for descrip…
rifont Nov 6, 2023
e2a40cd
refactor(api): Rename get-api-rate-limit use-case helper method for c…
rifont Nov 6, 2023
17a3bfb
Merge branch 'nv-3059-get-rate-limit-use-case' of ssh://github.com/no…
rifont Nov 6, 2023
de803e3
feat(api): Add logging to get-api-rate-limit use case
rifont Nov 6, 2023
d8de11e
fix(shared): Add missing newline
rifont Nov 6, 2023
e746b41
fix(api): Typo
rifont Nov 6, 2023
ad7e156
fix(api): Removed unused import in get-api-rate-limit use-case
rifont Nov 10, 2023
06ce24b
refactor(api, application-generic): Rename max api rate limit cache key
rifont Nov 10, 2023
c065cf0
feat(application-generic): Add evaluate api rate limit cache key builder
rifont Nov 10, 2023
310b877
fix(shared): Remove redundant import rename
rifont Nov 10, 2023
7aa9adb
Merge branch 'nv-3059-get-rate-limit-use-case' into nv-3060-token-buc…
rifont Nov 10, 2023
179586b
chore(shared): Remove redundant constant
rifont Nov 10, 2023
d2e6244
Merge branch 'nv-3059-get-rate-limit-use-case' into nv-3060-token-buc…
rifont Nov 10, 2023
bfa1fe2
refactor(shared): Create new rate limiting types folder
rifont Nov 10, 2023
6ec497b
Merge branch 'nv-3059-get-rate-limit-use-case' into nv-3060-token-buc…
rifont Nov 10, 2023
3a47eb4
fix(shared): Remove redundant satisfies operator
rifont Nov 10, 2023
bfcdc75
Merge branch 'nv-3059-get-rate-limit-use-case' into nv-3060-token-buc…
rifont Nov 10, 2023
c4a5120
chore(shared): Remove unused export in organization types
rifont Nov 10, 2023
16703f6
Merge branch 'nv-3059-get-rate-limit-use-case' into nv-3060-token-buc…
rifont Nov 10, 2023
4ea779d
feat(shared): Add api rate limit configuration types and cosntants
rifont Nov 10, 2023
976a36a
feat(api): Add get-api-rate-limit-configuration use-case
rifont Nov 10, 2023
e3fb0c4
refactor(api): Move get-api-rate-limit use case to rate-limiting modu…
rifont Nov 10, 2023
a7d672b
fix(api): Add module import for get-api-rate-limit use case
rifont Nov 10, 2023
32932a6
fix(api): Remove redundant imports
rifont Nov 10, 2023
cd1d75c
Merge branch 'nv-3059-get-rate-limit-use-case' into nv-3060-token-buc…
rifont Nov 10, 2023
ea9f0f6
feat(application-generic): Expose SADD and EVAL redis operations on c…
rifont Nov 10, 2023
40e0470
feat(api): Add evaluate-api-rate-limit use cases
rifont Nov 10, 2023
68a0c79
Merge branch 'next' into nv-3060-token-bucket-rate-limiting-use-case
rifont Nov 13, 2023
34368ba
chore: Run pnpm install to resolve merge conflicts on lockfile
rifont Nov 13, 2023
dc4abd0
fix(api): Add better logging for rate limit evaluation error
rifont Nov 14, 2023
944df01
test(api): Add tests for evaluate-api-rate-limit use-case
rifont Nov 14, 2023
2831766
docs(api): Fix rate limit mock comment
rifont Nov 14, 2023
2b86538
Merge branch 'next' into nv-3060-token-bucket-rate-limiting-use-case
rifont Nov 14, 2023
104a0e7
docs(api): Add further clarification to rate limit evaluation mock
rifont Nov 14, 2023
7fdb361
docs(api): Further mock redis eval clarification
rifont Nov 14, 2023
530ede7
fix(shared): Adjust typing of IApiRateLimitConfiguration to allow arb…
rifont Nov 14, 2023
d6146d4
Merge branch 'next' into nv-3060-token-bucket-rate-limiting-use-case
rifont Nov 14, 2023
bd103e5
fix(shared): Rename refillInterval to windowDuration to align with ra…
rifont Nov 14, 2023
5526b97
feat(api): Expose refillRate, windowDuration, and burstLimit from eva…
rifont Nov 14, 2023
6537b71
fix(api): Remove redundant ICacheService import
rifont Nov 14, 2023
232321e
feat(api): Extract evaluate-api-rate-limit use-case typings
rifont Nov 14, 2023
36fa061
feat(api): Add ApiRateLimitGuard and related ThrottleCategory decorator
rifont Nov 14, 2023
ece2df4
chore(api): Add @nestjs/throttler library
rifont Nov 14, 2023
a7914e7
fix(api): Use enum for rate limit header keys
rifont Nov 14, 2023
37546e8
feat(api): Add runtime feature toggle and fix dependency injection on…
rifont Nov 15, 2023
ad84552
feat(api): Add @nestjs/throttler and rate limit guard to RateLimiting…
rifont Nov 15, 2023
f63ae19
fix(api): Add rate limiting imports
rifont Nov 15, 2023
4acf5e5
feat(api): Extract default reflector metadata for rate limit guard
rifont Nov 15, 2023
9c6f8b0
fix(application-generic): Use correct method params for eval, add moc…
rifont Nov 15, 2023
e8085b0
chore(application-generic): Tidy up cache typings
rifont Nov 16, 2023
c8a241b
feat(api): Return algorithm in rate limit execution
rifont Nov 16, 2023
622f0d6
feat(api): Add support for bulk operation cost in rate limit execution
rifont Nov 16, 2023
dee2a2b
feat(api): Add variable cost rate limiting algorithm
rifont Nov 16, 2023
dc4e664
feat(shared): Add default bulk cost for api rate limiting
rifont Nov 16, 2023
e48b042
feat(shared): Add bulk cost typing for api rate limiting
rifont Nov 16, 2023
106a8d8
refactor(shared): Move rate limit flag from system-critical to featur…
rifont Nov 16, 2023
1a8f58c
refactor(application-generic): Convert rate limit flag from system-cr…
rifont Nov 16, 2023
1d45ece
feat(application-generic): Create custom provider for rate limit feat…
rifont Nov 16, 2023
897119b
chore(api, shared, application-generic): Rename api rate limiting fea…
rifont Nov 16, 2023
1087f5c
Merge branch 'next' into nv-3061-convert-rate-limit-ff-for-launchdarkly
rifont Nov 16, 2023
0ed6fe8
fix(app-generic): Rename api rate limiting file
rifont Nov 16, 2023
9bdaf9b
Merge branch 'nv-3061-convert-rate-limit-ff-for-launchdarkly' of ssh:…
rifont Nov 17, 2023
462f2e5
Merge branch 'next' into nv-3061-convert-rate-limit-ff-for-launchdarkly
rifont Nov 17, 2023
093a000
Merge branch 'nv-3060-token-bucket-rate-limiting-use-case' into nv-30…
rifont Nov 17, 2023
bdf05ca
Merge branch 'nv-3061-convert-rate-limit-ff-for-launchdarkly' into nv…
rifont Nov 17, 2023
ae80b28
feat(api): Add variable request type handling to throttler
rifont Nov 17, 2023
2c609c4
feat(api): Add support use-cases for rate limit evaluation
rifont Nov 17, 2023
137f6f1
chore(api): Revert accidental changes max-rate-limit use case
rifont Nov 17, 2023
d5d9203
feat(api): Add bulk support to evaluate rate limit use case
rifont Nov 17, 2023
7db1dba
chore(api, dal, shared): Rename API Rate Limiting enums and typings f…
rifont Nov 17, 2023
760b6fb
Merge branch 'nv-3060-consistent-rate-limit-naming' into nv-3060-toke…
rifont Nov 17, 2023
30f2b5e
fix(shared): Export rate limit types from index
rifont Nov 17, 2023
b8b72ed
fix(api): Add get-max-rate-limit command back
rifont Nov 17, 2023
c8c5c28
fix(api): Update rate limit use case imports
rifont Nov 17, 2023
10ca9d9
Merge branch 'nv-3060-consistent-rate-limit-naming' into nv-3060-toke…
rifont Nov 17, 2023
7477b17
fix(app-gen): Fix mock cache SADD implementation to match return val …
rifont Nov 17, 2023
d941188
fix(api): Fix import for get max rate limit use-case test
rifont Nov 17, 2023
1c24411
Merge branch 'nv-3060-consistent-rate-limit-naming' into nv-3060-toke…
rifont Nov 17, 2023
7378ce4
Merge branch 'next' into nv-3061-rate-limiting-nestjs-guard
rifont Nov 17, 2023
e51ceca
Merge branch 'nv-3060-token-bucket-rate-limiting-use-case' into nv-30…
rifont Nov 17, 2023
114e26c
fix(api): Remove unused refillRate result
rifont Nov 17, 2023
e6c718f
Merge branch 'next' into nv-3060-consistent-rate-limit-naming
rifont Nov 17, 2023
8e5f87a
fix(api): Use correct cost enum for evaluate rate limit use-case
rifont Nov 17, 2023
5b391e9
Merge branch 'next' into nv-3060-consistent-rate-limit-naming
rifont Nov 20, 2023
20b74e8
fix(api): Tidy up throttler guard
rifont Nov 22, 2023
545aa7e
feat(api): Modify token bucket algorithm to allow for variable cost
rifont Nov 22, 2023
fd9962b
Merge branch 'nv-3060-token-bucket-rate-limiting-use-case' into nv-30…
rifont Nov 22, 2023
7f150f9
chore(api): Tidy up algo logic
rifont Nov 22, 2023
9fd767f
chore(api): Fix comments on algo
rifont Nov 22, 2023
925aefa
feat(api): Add local caching back to rate limit algo
rifont Nov 23, 2023
f6b6098
chore(api): Refactor token bucket algorithm into separate use-case
rifont Nov 24, 2023
3fa6dff
Merge branch 'nv-3060-consistent-rate-limit-naming' into nv-3060-toke…
rifont Nov 24, 2023
f1835b6
Merge branch 'next' into nv-3060-token-bucket-rate-limiting-use-case
rifont Nov 24, 2023
5551104
feat(api): Add modified token bucket rate limiter
rifont Nov 24, 2023
e3b5bf9
fix(api): Make cache client adapter static and add tests
rifont Nov 24, 2023
5e2affb
fix(api): Fix use-case tests
rifont Nov 24, 2023
359fed9
fix(api, shared): Use snake_case enum values for rate limit configura…
rifont Nov 24, 2023
95f2ab6
Merge branch 'nv-3060-token-bucket-rate-limiting-use-case' into nv-30…
rifont Nov 24, 2023
0ac42cc
fix(api): Fix evaluate rate limit import
rifont Nov 24, 2023
8c11c8a
fix(api): Use enum value
rifont Nov 24, 2023
0f9b163
Merge branch 'nv-3060-token-bucket-rate-limiting-use-case' into nv-30…
rifont Nov 24, 2023
03ba15a
Merge branch 'nv-3060-modified-token-bucket-algorithm' into nv-3061-r…
rifont Nov 24, 2023
bc848ef
fix(api): Fix bad enum reference
rifont Nov 24, 2023
5755611
Merge branch 'nv-3060-token-bucket-rate-limiting-use-case' into nv-30…
rifont Nov 24, 2023
c018948
Merge branch 'nv-3060-modified-token-bucket-algorithm' into nv-3061-r…
rifont Nov 24, 2023
dfb6c36
fix(api): Fix test describe naming
rifont Nov 24, 2023
29489c7
Merge branch 'nv-3060-token-bucket-rate-limiting-use-case' into nv-30…
rifont Nov 24, 2023
b83edde
Merge branch 'nv-3060-modified-token-bucket-algorithm' into nv-3061-r…
rifont Nov 24, 2023
c9b89f9
test(api): Add throttler guard test
rifont Nov 24, 2023
5905b2a
test(api): Add more tests
rifont Nov 24, 2023
507a517
feat(api): Add rate limit configuration environment variables
rifont Nov 24, 2023
e1ea93e
Merge branch 'nv-3060-token-bucket-rate-limiting-use-case' into nv-30…
rifont Nov 24, 2023
ede3228
Merge branch 'nv-3060-modified-token-bucket-algorithm' into nv-3061-r…
rifont Nov 24, 2023
a34a946
test(api): Fix burst limit calculation
rifont Nov 24, 2023
d9721ab
fix(api): Make the createLimiter method functional
rifont Nov 24, 2023
8615e7e
Merge branch 'nv-3060-token-bucket-rate-limiting-use-case' into nv-30…
rifont Nov 24, 2023
e3f3d9e
Merge branch 'nv-3060-modified-token-bucket-algorithm' into nv-3061-r…
rifont Nov 24, 2023
0e8257c
fix(api): Invalidate max rate limit cache entities when loading max l…
rifont Nov 26, 2023
be1ca1e
feat(app-gen): Add key builder for service config and tidy up base ke…
rifont Nov 26, 2023
7b2264a
fix(api): Fix get-max-ratelimit usecase CachedEntity builder to use c…
rifont Nov 26, 2023
a505889
Merge branch 'nv-3060-token-bucket-rate-limiting-use-case' into nv-30…
rifont Nov 26, 2023
31de2ff
Merge branch 'nv-3060-modified-token-bucket-algorithm' into nv-3061-r…
rifont Nov 26, 2023
301ca33
fix(api): Specify default limits on max-rate-limit class attribute
rifont Nov 26, 2023
dd8ccd1
feat(api): Add environment and organization repository methods for ap…
rifont Nov 27, 2023
f3c288b
test(api): Add test rate limit controller
rifont Nov 27, 2023
223aee1
feat(api): Add rate limit guard to app module
rifont Nov 27, 2023
97c6c0d
feat(api): Add strong typing to environment variables
rifont Nov 27, 2023
752ade9
feat(api): Convert rate limit guard to interceptor to provide auth co…
rifont Nov 27, 2023
c9c8faf
test(api): Add rate limit guard tests
rifont Nov 27, 2023
6c0bd50
fix(api): Fix env vars in tests
rifont Nov 27, 2023
d3a04e5
Merge branch 'nv-3060-token-bucket-rate-limiting-use-case' of ssh://g…
rifont Nov 27, 2023
8a86a7f
Merge branch 'nv-3060-modified-token-bucket-algorithm' into nv-3060-t…
rifont Nov 27, 2023
a428fe6
fix(api): Consolidate algorithm into use-case
rifont Nov 27, 2023
d5ab65f
Merge branch 'nv-3060-token-bucket-rate-limiting-use-case' into nv-30…
rifont Nov 27, 2023
1d7a289
Merge branch 'next' into nv-3060-token-bucket-rate-limiting-use-case
rifont Nov 27, 2023
0509da9
test(api): Rename rate limit test spec to e2e
rifont Nov 27, 2023
deb01cf
Merge branch 'nv-3060-token-bucket-rate-limiting-use-case' into nv-30…
rifont Nov 27, 2023
34ea4e6
fix(api): remove redundant e2e gitkeep
rifont Nov 27, 2023
ff1955a
test(api): Add tests for variable-cost token bucket rate limiter
rifont Nov 28, 2023
0c18892
fix(api): Revert addition of variable-cost token bucket
rifont Nov 28, 2023
3d83c03
Merge branch 'next' into nv-3060-token-bucket-rate-limiting-use-case
rifont Nov 28, 2023
088cfae
fix(api): Address PR review comments
rifont Nov 28, 2023
8603730
Merge branch 'nv-3060-token-bucket-rate-limiting-use-case' into nv-30…
rifont Nov 28, 2023
5e91dc3
fix(api): Remove e2e tests for rate limiting temporarily
rifont Nov 28, 2023
b8ce7a4
fix(api): Remove unused test case and import
rifont Nov 28, 2023
8255c3e
fix(api): Revert package.json change
rifont Nov 28, 2023
7dc1352
Revert "fix(api): Remove unused test case and import"
rifont Nov 28, 2023
4e84a20
Revert "fix(api): Remove e2e tests for rate limiting temporarily"
rifont Nov 28, 2023
04b99f9
fix(api): Remove failing throttler tests and modify expected reset
rifont Nov 28, 2023
9617a9f
test(api): Add throttled request test
rifont Nov 28, 2023
64d6e4e
fix(api): Add cspell definitions for rate limiting
rifont Nov 28, 2023
b625403
fix(api): Use rate limiter before idempotency interceptor
rifont Nov 28, 2023
ef45dea
fix(api): Add comment on nestjs throttler config
rifont Nov 28, 2023
69360ed
test(api): update test
rifont Nov 28, 2023
ac45a0e
test(api): Add tolerance for throttled count
rifont Nov 28, 2023
3dc6a9d
test(api): Fix tolerance for upstash
rifont Nov 28, 2023
fab4042
fix(api): Typo
rifont Nov 28, 2023
ff165e3
Merge branch 'next' into nv-3061-rate-limiting-nestjs-guard
rifont Nov 29, 2023
7edb9eb
fix(dal): Fix updateApiRateLimits return value
rifont Nov 29, 2023
c9ae745
fix(api): Auto-generate name prefix
rifont Nov 29, 2023
650eb3a
fix(api): Use invalidate by key instead of query
rifont Nov 29, 2023
963a041
fix(api): Remove redundant import
rifont Nov 29, 2023
8781404
fix(api): Fix cache invalidation test
rifont Nov 29, 2023
7d63579
Merge branch 'next' into nv-3061-rate-limiting-nestjs-guard
rifont Nov 29, 2023
6af53c1
fix(api): Fix typo
rifont Nov 29, 2023
fd05a99
fix(api): Add separate before statements for unit and e2e tests
rifont Nov 29, 2023
8d53cf2
test(api): Use regex for variable policy header values
rifont Nov 29, 2023
588933c
fix(api): Toggle launch darkly off to allow test to define FF state
rifont Nov 29, 2023
d987263
fix(api): Fix launch darkly toggle off
rifont Nov 29, 2023
001a40a
Merge branch 'next' into nv-3061-rate-limiting-nestjs-guard
rifont Dec 4, 2023
828b9ad
fix(api): Increase error tolerance on rate limiting to reduce test fl…
rifont Dec 5, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,12 @@
"maildata",
"brevo",
"Getstream",
"getstream"
"getstream",
"upstash",
"Upstash",
"Krakend",
"ratelimit",
"Ratelimit",
],
"flagWords": [],
"patterns": [
Expand Down
2 changes: 2 additions & 0 deletions apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"@nestjs/platform-express": "^10.2.2",
"@nestjs/swagger": "^7.1.8",
"@nestjs/terminus": "^10.0.1",
"@nestjs/throttler": "^5.0.1",
"@novu/application-generic": "^0.21.0",
"@novu/dal": "^0.21.0",
"@novu/node": "^0.21.0",
Expand All @@ -50,6 +51,7 @@
"@sentry/node": "^7.40.0",
"@sentry/tracing": "^7.40.0",
"@types/newrelic": "^9.14.0",
"@upstash/ratelimit": "^0.4.4",
"axios": "^1.3.3",
"bcrypt": "^5.0.0",
"body-parser": "^1.20.0",
Expand Down
16 changes: 15 additions & 1 deletion apps/api/src/.env.development
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ REDIS_CACHE_FAMILY=
REDIS_CACHE_KEY_PREFIX=
REDIS_CACHE_ENABLE_AUTOPIPELINING=true

IS_API_RATE_LIMITING_ENABLED=false
IS_IN_MEMORY_CLUSTER_MODE_ENABLED=false
ELASTICACHE_CLUSTER_SERVICE_HOST=
ELASTICACHE_CLUSTER_SERVICE_PORT=
Expand Down Expand Up @@ -68,3 +67,18 @@ LAUNCH_DARKLY_SDK_KEY=

IS_API_IDEMPOTENCY_ENABLED=false
AUTO_CREATE_INDEXES=true

IS_API_RATE_LIMITING_ENABLED=false
API_RATE_LIMIT_COST_SINGLE=
API_RATE_LIMIT_COST_BULK=
API_RATE_LIMIT_ALGORITHM_BURST_ALLOWANCE=
API_RATE_LIMIT_ALGORITHM_WINDOW_DURATION=
API_RATE_LIMIT_MAXIMUM_BUSINESS_TRIGGER=
API_RATE_LIMIT_MAXIMUM_BUSINESS_CONFIGURATION=
API_RATE_LIMIT_MAXIMUM_BUSINESS_GLOBAL=
API_RATE_LIMIT_MAXIMUM_FREE_TRIGGER=
API_RATE_LIMIT_MAXIMUM_FREE_CONFIGURATION=
API_RATE_LIMIT_MAXIMUM_FREE_GLOBAL=
API_RATE_LIMIT_MAXIMUM_UNLIMITED_TRIGGER=
API_RATE_LIMIT_MAXIMUM_UNLIMITED_CONFIGURATION=
API_RATE_LIMIT_MAXIMUM_UNLIMITED_GLOBAL=
16 changes: 15 additions & 1 deletion apps/api/src/.env.production
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ REDIS_PORT=6379
REDIS_PREFIX=
REDIS_DB_INDEX=2

IS_API_RATE_LIMITING_ENABLED=false
IS_IN_MEMORY_CLUSTER_MODE_ENABLED=false
ELASTICACHE_CLUSTER_SERVICE_HOST=
ELASTICACHE_CLUSTER_SERVICE_PORT=
Expand Down Expand Up @@ -58,3 +57,18 @@ LAUNCH_DARKLY_SDK_KEY=
IS_API_IDEMPOTENCY_ENABLED=false
## This value should be set to true if it is the first time you are running the with the database
AUTO_CREATE_INDEXES=false

IS_API_RATE_LIMITING_ENABLED=false
API_RATE_LIMIT_COST_SINGLE=
API_RATE_LIMIT_COST_BULK=
API_RATE_LIMIT_ALGORITHM_BURST_ALLOWANCE=
API_RATE_LIMIT_ALGORITHM_WINDOW_DURATION=
API_RATE_LIMIT_MAXIMUM_BUSINESS_TRIGGER=
API_RATE_LIMIT_MAXIMUM_BUSINESS_CONFIGURATION=
API_RATE_LIMIT_MAXIMUM_BUSINESS_GLOBAL=
API_RATE_LIMIT_MAXIMUM_FREE_TRIGGER=
API_RATE_LIMIT_MAXIMUM_FREE_CONFIGURATION=
API_RATE_LIMIT_MAXIMUM_FREE_GLOBAL=
API_RATE_LIMIT_MAXIMUM_UNLIMITED_TRIGGER=
API_RATE_LIMIT_MAXIMUM_UNLIMITED_CONFIGURATION=
API_RATE_LIMIT_MAXIMUM_UNLIMITED_GLOBAL=
16 changes: 15 additions & 1 deletion apps/api/src/.env.test
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ REDIS_CACHE_FAMILY=
REDIS_CACHE_KEY_PREFIX=
REDIS_CACHE_ENABLE_AUTOPIPELINING=false

IS_API_RATE_LIMITING_ENABLED=false
IS_IN_MEMORY_CLUSTER_MODE_ENABLED=false
ELASTICACHE_CLUSTER_SERVICE_HOST=
ELASTICACHE_CLUSTER_SERVICE_PORT=
Expand Down Expand Up @@ -93,3 +92,18 @@ NOVU_SMS_INTEGRATION_SENDER=1234567890

IS_API_IDEMPOTENCY_ENABLED=true
AUTO_CREATE_INDEXES=true

IS_API_RATE_LIMITING_ENABLED=false
API_RATE_LIMIT_COST_SINGLE=
API_RATE_LIMIT_COST_BULK=
API_RATE_LIMIT_ALGORITHM_BURST_ALLOWANCE=
API_RATE_LIMIT_ALGORITHM_WINDOW_DURATION=
API_RATE_LIMIT_MAXIMUM_BUSINESS_TRIGGER=
API_RATE_LIMIT_MAXIMUM_BUSINESS_CONFIGURATION=
API_RATE_LIMIT_MAXIMUM_BUSINESS_GLOBAL=
API_RATE_LIMIT_MAXIMUM_FREE_TRIGGER=
API_RATE_LIMIT_MAXIMUM_FREE_CONFIGURATION=
API_RATE_LIMIT_MAXIMUM_FREE_GLOBAL=
API_RATE_LIMIT_MAXIMUM_UNLIMITED_TRIGGER=
API_RATE_LIMIT_MAXIMUM_UNLIMITED_CONFIGURATION=
API_RATE_LIMIT_MAXIMUM_UNLIMITED_GLOBAL=
16 changes: 15 additions & 1 deletion apps/api/src/.example.env
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ REDIS_CACHE_FAMILY=
REDIS_CACHE_KEY_PREFIX=
REDIS_CACHE_ENABLE_AUTOPIPELINING=

IS_API_RATE_LIMITING_ENABLED=false
IS_IN_MEMORY_CLUSTER_MODE_ENABLED=false
REDIS_CLUSTER_SERVICE_HOST=
REDIS_CLUSTER_SERVICE_PORT=
Expand Down Expand Up @@ -63,3 +62,18 @@ INTERCOM_IDENTITY_VERIFICATION_SECRET_KEY=
LOGGING_LEVEL=info

LAUNCH_DARKLY_SDK_KEY=

IS_API_RATE_LIMITING_ENABLED=false
API_RATE_LIMIT_COST_SINGLE=
API_RATE_LIMIT_COST_BULK=
API_RATE_LIMIT_ALGORITHM_BURST_ALLOWANCE=
API_RATE_LIMIT_ALGORITHM_WINDOW_DURATION=
API_RATE_LIMIT_MAXIMUM_BUSINESS_TRIGGER=
API_RATE_LIMIT_MAXIMUM_BUSINESS_CONFIGURATION=
API_RATE_LIMIT_MAXIMUM_BUSINESS_GLOBAL=
API_RATE_LIMIT_MAXIMUM_FREE_TRIGGER=
API_RATE_LIMIT_MAXIMUM_FREE_CONFIGURATION=
API_RATE_LIMIT_MAXIMUM_FREE_GLOBAL=
API_RATE_LIMIT_MAXIMUM_UNLIMITED_TRIGGER=
API_RATE_LIMIT_MAXIMUM_UNLIMITED_CONFIGURATION=
API_RATE_LIMIT_MAXIMUM_UNLIMITED_GLOBAL=
9 changes: 8 additions & 1 deletion apps/api/src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DynamicModule, HttpException, Module, Logger, Provider } from '@nestjs/common';
import { RavenInterceptor, RavenModule } from 'nest-raven';
import { APP_INTERCEPTOR } from '@nestjs/core';
import { APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core';
import { Type } from '@nestjs/common/interfaces/type.interface';
import { ForwardReference } from '@nestjs/common/interfaces/modules/forward-reference.interface';

Expand Down Expand Up @@ -33,6 +33,8 @@ import { BlueprintModule } from './app/blueprint/blueprint.module';
import { TenantModule } from './app/tenant/tenant.module';
import { IdempotencyInterceptor } from './app/shared/framework/idempotency.interceptor';
import { WorkflowOverridesModule } from './app/workflow-overrides/workflow-overrides.module';
import { ApiRateLimitInterceptor } from './app/rate-limiting/guards';
import { RateLimitingModule } from './app/rate-limiting/rate-limiting.module';

const enterpriseImports = (): Array<Type | DynamicModule | Promise<DynamicModule> | ForwardReference> => {
const modules: Array<Type | DynamicModule | Promise<DynamicModule> | ForwardReference> = [];
Expand Down Expand Up @@ -75,13 +77,18 @@ const baseModules: Array<Type | DynamicModule | Promise<DynamicModule> | Forward
BlueprintModule,
TenantModule,
WorkflowOverridesModule,
RateLimitingModule,
];

const enterpriseModules = enterpriseImports();

const modules = baseModules.concat(enterpriseModules);

const providers: Provider[] = [
{
provide: APP_INTERCEPTOR,
useClass: ApiRateLimitInterceptor,
},
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Placing before the idempotency interceptor so that idempotent requests are still subject to rate limiting.

{
provide: APP_INTERCEPTOR,
useClass: IdempotencyInterceptor,
Expand Down
4 changes: 2 additions & 2 deletions apps/api/src/app/organization/e2e/create-organization.e2e.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { MemberRepository, OrganizationRepository } from '@novu/dal';
import { UserSession } from '@novu/testing';
import { ApiServiceLevelTypeEnum, MemberRoleEnum } from '@novu/shared';
import { ApiServiceLevelEnum, MemberRoleEnum } from '@novu/shared';
import { expect } from 'chai';

describe('Create Organization - /organizations (POST)', async () => {
Expand Down Expand Up @@ -53,7 +53,7 @@ describe('Create Organization - /organizations (POST)', async () => {
const { body } = await session.testAgent.post('/v1/organizations').send(testOrganization).expect(201);
const dbOrganization = await organizationRepository.findById(body.data._id);

expect(dbOrganization?.apiServiceLevel).to.eq(ApiServiceLevelTypeEnum.FREE);
expect(dbOrganization?.apiServiceLevel).to.eq(ApiServiceLevelEnum.FREE);
});
});
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Inject, Injectable, Scope } from '@nestjs/common';
import { OrganizationEntity, OrganizationRepository, UserRepository } from '@novu/dal';
import { ApiServiceLevelTypeEnum, MemberRoleEnum } from '@novu/shared';
import { ApiServiceLevelEnum, MemberRoleEnum } from '@novu/shared';
import { AnalyticsService } from '@novu/application-generic';

import { CreateEnvironmentCommand } from '../../../environments/usecases/create-environment/create-environment.command';
Expand Down Expand Up @@ -36,7 +36,7 @@ export class CreateOrganization {
const createdOrganization = await this.organizationRepository.create({
logo: command.logo,
name: command.name,
apiServiceLevel: ApiServiceLevelTypeEnum.FREE,
apiServiceLevel: ApiServiceLevelEnum.FREE,
});

await this.addMemberUsecase.execute(
Expand Down
Empty file.
Empty file.
2 changes: 2 additions & 0 deletions apps/api/src/app/rate-limiting/guards/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './throttler.decorator';
export * from './throttler.guard';
8 changes: 8 additions & 0 deletions apps/api/src/app/rate-limiting/guards/throttler.decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Reflector } from '@nestjs/core';
import { ApiRateLimitCategoryEnum, ApiRateLimitCostEnum } from '@novu/shared';

// eslint-disable-next-line @typescript-eslint/naming-convention
export const ThrottlerCategory = Reflector.createDecorator<ApiRateLimitCategoryEnum>();

// eslint-disable-next-line @typescript-eslint/naming-convention
export const ThrottlerCost = Reflector.createDecorator<ApiRateLimitCostEnum>();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Custom decorators to specify custom costs and categories on both controllers and methods.

Loading
Loading