feat: update throttler (#7957)

This commit is contained in:
darkskygit
2024-08-23 13:52:47 +00:00
parent 49c8a25fce
commit 0b3c7d1407
4 changed files with 31 additions and 26 deletions

View File

@@ -34,7 +34,7 @@
"@nestjs/platform-express": "^10.3.7",
"@nestjs/platform-socket.io": "^10.3.7",
"@nestjs/schedule": "^4.0.1",
"@nestjs/throttler": "5.2.0",
"@nestjs/throttler": "6.2.1",
"@nestjs/websockets": "^10.3.7",
"@node-rs/argon2": "^1.8.0",
"@node-rs/crc32": "^1.10.0",
@@ -76,7 +76,7 @@
"mustache": "^4.2.0",
"nanoid": "^5.0.7",
"nest-commander": "^3.12.5",
"nestjs-throttler-storage-redis": "^0.4.4",
"nestjs-throttler-storage-redis": "^0.5.0",
"nodemailer": "^6.9.13",
"on-headers": "^1.0.2",
"openai": "^4.33.0",

View File

@@ -8,8 +8,8 @@ import {
ThrottlerGuard,
ThrottlerModule,
type ThrottlerModuleOptions,
ThrottlerOptions,
ThrottlerOptionsFactory,
ThrottlerRequest,
ThrottlerStorageService,
} from '@nestjs/throttler';
import type { Request } from 'express';
@@ -74,12 +74,15 @@ export class CloudThrottlerGuard extends ThrottlerGuard {
return `${tracker};${throttler}`;
}
override async handleRequest(
context: ExecutionContext,
limit: number,
ttl: number,
throttlerOptions: ThrottlerOptions
) {
override async handleRequest(request: ThrottlerRequest) {
const {
context,
throttler: throttlerOptions,
ttl,
blockDuration,
} = request;
let limit = request.limit;
// give it 'default' if no throttler is specified,
// so the unauthenticated users visits will always hit default throttler
// authenticated users will directly bypass unprotected APIs in [CloudThrottlerGuard.canActivate]
@@ -118,13 +121,11 @@ export class CloudThrottlerGuard extends ThrottlerGuard {
tracker,
throttlerOptions.name ?? 'default'
);
const { timeToExpire, totalHits } = await this.storageService.increment(
key,
ttl
);
const { timeToExpire, totalHits, isBlocked, timeToBlockExpire } =
await this.storageService.increment(key, ttl, limit, blockDuration, key);
if (totalHits > limit) {
res.header('Retry-After', timeToExpire.toString());
if (isBlocked) {
res.header('Retry-After', timeToBlockExpire.toString());
await this.throwThrottlingException(context, {
limit,
ttl,
@@ -132,6 +133,8 @@ export class CloudThrottlerGuard extends ThrottlerGuard {
tracker,
totalHits,
timeToExpire,
isBlocked,
timeToBlockExpire,
});
}

View File

@@ -137,6 +137,8 @@ test('should be able to prevent requests if limit is reached', async t => {
const stub = Sinon.stub(app.get(ThrottlerStorage), 'increment').resolves({
timeToExpire: 10,
totalHits: 21,
isBlocked: true,
timeToBlockExpire: 10,
});
const res = await request(app.getHttpServer())
.get('/nonthrottled/strict')