@nestjs/throttler 5.1.2 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +5 -5
- package/dist/hash.js +1 -2
- package/dist/hash.js.map +1 -1
- package/dist/throttler-module-options.interface.d.ts +3 -1
- package/dist/throttler-storage-options.interface.d.ts +3 -1
- package/dist/throttler-storage-options.interface.js.map +1 -1
- package/dist/throttler-storage-record.interface.d.ts +2 -0
- package/dist/throttler-storage-record.interface.js.map +1 -1
- package/dist/throttler-storage.interface.d.ts +1 -1
- package/dist/throttler-storage.interface.js.map +1 -1
- package/dist/throttler.constants.d.ts +1 -0
- package/dist/throttler.constants.js +2 -1
- package/dist/throttler.constants.js.map +1 -1
- package/dist/throttler.decorator.d.ts +1 -0
- package/dist/throttler.decorator.js +1 -0
- package/dist/throttler.decorator.js.map +1 -1
- package/dist/throttler.guard.d.ts +4 -4
- package/dist/throttler.guard.interface.d.ts +11 -0
- package/dist/throttler.guard.js +24 -7
- package/dist/throttler.guard.js.map +1 -1
- package/dist/throttler.providers.js +2 -2
- package/dist/throttler.providers.js.map +1 -1
- package/dist/throttler.service.d.ts +6 -2
- package/dist/throttler.service.js +55 -15
- package/dist/throttler.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +35 -35
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# The MIT License
|
|
2
2
|
|
|
3
|
-
Copyright 2019-
|
|
3
|
+
Copyright 2019-2024 Jay McDoniel, contributors
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
6
|
|
package/README.md
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
<p align="center">
|
|
2
2
|
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo-small.svg" width="120" alt="Nest Logo" /></a>
|
|
3
3
|
</p>
|
|
4
|
-
[travis-image]: https://api.travis-ci.org/nestjs/nest.svg?branch=master
|
|
5
|
-
[travis-url]: https://travis-ci.org/nestjs/nest
|
|
6
|
-
[linux-image]: https://img.shields.io/travis/nestjs/nest/master.svg?label=linux
|
|
7
|
-
[linux-url]: https://travis-ci.org/nestjs/nest
|
|
8
4
|
|
|
9
5
|
<p align="center">A progressive <a href="http://nodejs.org" target="blank">Node.js</a> framework for building efficient and scalable server-side applications.</p>
|
|
10
6
|
<p align="center">
|
|
@@ -272,6 +268,10 @@ The following options are valid for the object passed to the array of the `Throt
|
|
|
272
268
|
<td><code>limit</code></td>
|
|
273
269
|
<td>the maximum number of requests within the TTL limit</td>
|
|
274
270
|
</tr>
|
|
271
|
+
<tr>
|
|
272
|
+
<td><code>blockDuration</code></td>
|
|
273
|
+
<td>the number of milliseconds that request will be blocked for that time</td>
|
|
274
|
+
</tr>
|
|
275
275
|
<tr>
|
|
276
276
|
<td><code>ignoreUserAgents</code></td>
|
|
277
277
|
<td>an array of regular expressions of user-agents to ignore when it comes to throttling requests</td>
|
|
@@ -311,7 +311,7 @@ If you need to set up storages instead, or want to use a some of the above optio
|
|
|
311
311
|
</tr>
|
|
312
312
|
<tr>
|
|
313
313
|
<td><code>errorMessage</code></td>
|
|
314
|
-
<td>a <code>string</code> which overrides the default throttler error message</td>
|
|
314
|
+
<td>a <code>string</code> OR a function that takes in the <code>ExecutionContext</code> and the <code>ThrottlerLimitDetail</code> and returns a <code>string</code> which overrides the default throttler error message</td>
|
|
315
315
|
</tr>
|
|
316
316
|
<tr>
|
|
317
317
|
<td><code>getTracker</code></td>
|
package/dist/hash.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.md5 =
|
|
3
|
+
exports.md5 = md5;
|
|
4
4
|
const crypto = require("node:crypto");
|
|
5
5
|
function md5(text) {
|
|
6
6
|
return crypto.createHash('md5').update(text).digest('hex');
|
|
7
7
|
}
|
|
8
|
-
exports.md5 = md5;
|
|
9
8
|
//# sourceMappingURL=hash.js.map
|
package/dist/hash.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":";;AAEA,kBAEC;AAJD,sCAAsC;AAEtC,SAAgB,GAAG,CAAC,IAAY;IAC9B,OAAO,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC7D,CAAC"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { ExecutionContext, ModuleMetadata, Type } from '@nestjs/common/interfaces';
|
|
2
2
|
import { ThrottlerStorage } from './throttler-storage.interface';
|
|
3
|
+
import { ThrottlerLimitDetail } from './throttler.guard.interface';
|
|
3
4
|
export type Resolvable<T extends number | string | boolean> = T | ((context: ExecutionContext) => T | Promise<T>);
|
|
4
5
|
export interface ThrottlerOptions {
|
|
5
6
|
name?: string;
|
|
6
7
|
limit: Resolvable<number>;
|
|
7
8
|
ttl: Resolvable<number>;
|
|
9
|
+
blockDuration?: Resolvable<number>;
|
|
8
10
|
ignoreUserAgents?: RegExp[];
|
|
9
11
|
skipIf?: (context: ExecutionContext) => boolean;
|
|
10
12
|
getTracker?: ThrottlerGetTrackerFunction;
|
|
@@ -15,7 +17,7 @@ export type ThrottlerModuleOptions = Array<ThrottlerOptions> | {
|
|
|
15
17
|
ignoreUserAgents?: RegExp[];
|
|
16
18
|
getTracker?: ThrottlerGetTrackerFunction;
|
|
17
19
|
generateKey?: ThrottlerGenerateKeyFunction;
|
|
18
|
-
errorMessage?: string;
|
|
20
|
+
errorMessage?: string | ((context: ExecutionContext, throttlerLimitDetail: ThrottlerLimitDetail) => string);
|
|
19
21
|
storage?: ThrottlerStorage;
|
|
20
22
|
throttlers: Array<ThrottlerOptions>;
|
|
21
23
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"throttler-storage-options.interface.js","sourceRoot":"","sources":["../src/throttler-storage-options.interface.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"throttler-storage-options.interface.js","sourceRoot":"","sources":["../src/throttler-storage-options.interface.ts"],"names":[],"mappings":";;;AAsBa,QAAA,uBAAuB,GAAG,MAAM,CAAC,yBAAyB,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"throttler-storage-record.interface.js","sourceRoot":"","sources":["../src/throttler-storage-record.interface.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"throttler-storage-record.interface.js","sourceRoot":"","sources":["../src/throttler-storage-record.interface.ts"],"names":[],"mappings":";;;AAsBa,QAAA,sBAAsB,GAAG,MAAM,CAAC,wBAAwB,CAAC,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ThrottlerStorageRecord } from './throttler-storage-record.interface';
|
|
2
2
|
export interface ThrottlerStorage {
|
|
3
|
-
increment(key: string, ttl: number): Promise<ThrottlerStorageRecord>;
|
|
3
|
+
increment(key: string, ttl: number, limit: number, blockDuration: number, throttlerName: string): Promise<ThrottlerStorageRecord>;
|
|
4
4
|
}
|
|
5
5
|
export declare const ThrottlerStorage: unique symbol;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"throttler-storage.interface.js","sourceRoot":"","sources":["../src/throttler-storage.interface.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"throttler-storage.interface.js","sourceRoot":"","sources":["../src/throttler-storage.interface.ts"],"names":[],"mappings":";;;AAgBa,QAAA,gBAAgB,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export declare const THROTTLER_LIMIT = "THROTTLER:LIMIT";
|
|
2
2
|
export declare const THROTTLER_TTL = "THROTTLER:TTL";
|
|
3
3
|
export declare const THROTTLER_TRACKER = "THROTTLER:TRACKER";
|
|
4
|
+
export declare const THROTTLER_BLOCK_DURATION = "THROTTLER:BLOCK_DURATION";
|
|
4
5
|
export declare const THROTTLER_KEY_GENERATOR = "THROTTLER:KEY_GENERATOR";
|
|
5
6
|
export declare const THROTTLER_OPTIONS = "THROTTLER:MODULE_OPTIONS";
|
|
6
7
|
export declare const THROTTLER_SKIP = "THROTTLER:SKIP";
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.THROTTLER_SKIP = exports.THROTTLER_OPTIONS = exports.THROTTLER_KEY_GENERATOR = exports.THROTTLER_TRACKER = exports.THROTTLER_TTL = exports.THROTTLER_LIMIT = void 0;
|
|
3
|
+
exports.THROTTLER_SKIP = exports.THROTTLER_OPTIONS = exports.THROTTLER_KEY_GENERATOR = exports.THROTTLER_BLOCK_DURATION = exports.THROTTLER_TRACKER = exports.THROTTLER_TTL = exports.THROTTLER_LIMIT = void 0;
|
|
4
4
|
exports.THROTTLER_LIMIT = 'THROTTLER:LIMIT';
|
|
5
5
|
exports.THROTTLER_TTL = 'THROTTLER:TTL';
|
|
6
6
|
exports.THROTTLER_TRACKER = 'THROTTLER:TRACKER';
|
|
7
|
+
exports.THROTTLER_BLOCK_DURATION = 'THROTTLER:BLOCK_DURATION';
|
|
7
8
|
exports.THROTTLER_KEY_GENERATOR = 'THROTTLER:KEY_GENERATOR';
|
|
8
9
|
exports.THROTTLER_OPTIONS = 'THROTTLER:MODULE_OPTIONS';
|
|
9
10
|
exports.THROTTLER_SKIP = 'THROTTLER:SKIP';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"throttler.constants.js","sourceRoot":"","sources":["../src/throttler.constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,eAAe,GAAG,iBAAiB,CAAC;AACpC,QAAA,aAAa,GAAG,eAAe,CAAC;AAChC,QAAA,iBAAiB,GAAG,mBAAmB,CAAC;AACxC,QAAA,uBAAuB,GAAG,yBAAyB,CAAC;AACpD,QAAA,iBAAiB,GAAG,0BAA0B,CAAC;AAC/C,QAAA,cAAc,GAAG,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"throttler.constants.js","sourceRoot":"","sources":["../src/throttler.constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,eAAe,GAAG,iBAAiB,CAAC;AACpC,QAAA,aAAa,GAAG,eAAe,CAAC;AAChC,QAAA,iBAAiB,GAAG,mBAAmB,CAAC;AACxC,QAAA,wBAAwB,GAAG,0BAA0B,CAAC;AACtD,QAAA,uBAAuB,GAAG,yBAAyB,CAAC;AACpD,QAAA,iBAAiB,GAAG,0BAA0B,CAAC;AAC/C,QAAA,cAAc,GAAG,gBAAgB,CAAC"}
|
|
@@ -2,6 +2,7 @@ import { Resolvable, ThrottlerGenerateKeyFunction, ThrottlerGetTrackerFunction }
|
|
|
2
2
|
interface ThrottlerMethodOrControllerOptions {
|
|
3
3
|
limit?: Resolvable<number>;
|
|
4
4
|
ttl?: Resolvable<number>;
|
|
5
|
+
blockDuration?: Resolvable<number>;
|
|
5
6
|
getTracker?: ThrottlerGetTrackerFunction;
|
|
6
7
|
generateKey?: ThrottlerGenerateKeyFunction;
|
|
7
8
|
}
|
|
@@ -8,6 +8,7 @@ function setThrottlerMetadata(target, options) {
|
|
|
8
8
|
for (const name in options) {
|
|
9
9
|
Reflect.defineMetadata(throttler_constants_1.THROTTLER_TTL + name, options[name].ttl, target);
|
|
10
10
|
Reflect.defineMetadata(throttler_constants_1.THROTTLER_LIMIT + name, options[name].limit, target);
|
|
11
|
+
Reflect.defineMetadata(throttler_constants_1.THROTTLER_BLOCK_DURATION + name, options[name].blockDuration, target);
|
|
11
12
|
Reflect.defineMetadata(throttler_constants_1.THROTTLER_TRACKER + name, options[name].getTracker, target);
|
|
12
13
|
Reflect.defineMetadata(throttler_constants_1.THROTTLER_KEY_GENERATOR + name, options[name].generateKey, target);
|
|
13
14
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"throttler.decorator.js","sourceRoot":"","sources":["../src/throttler.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AAMxC,+
|
|
1
|
+
{"version":3,"file":"throttler.decorator.js","sourceRoot":"","sources":["../src/throttler.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AAMxC,+DAO+B;AAC/B,+DAAyE;AAUzE,SAAS,oBAAoB,CAC3B,MAAW,EACX,OAA2D;IAE3D,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,OAAO,CAAC,cAAc,CAAC,mCAAa,GAAG,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACxE,OAAO,CAAC,cAAc,CAAC,qCAAe,GAAG,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC5E,OAAO,CAAC,cAAc,CAAC,8CAAwB,GAAG,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QAC7F,OAAO,CAAC,cAAc,CAAC,uCAAiB,GAAG,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QACnF,OAAO,CAAC,cAAc,CAAC,6CAAuB,GAAG,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAC5F,CAAC;AACH,CAAC;AASM,MAAM,QAAQ,GAAG,CACtB,OAA2D,EACzB,EAAE;IACpC,OAAO,CACL,MAAW,EACX,WAA6B,EAC7B,UAAyC,EACzC,EAAE;QACF,IAAI,UAAU,EAAE,CAAC;YACf,oBAAoB,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAChD,OAAO,UAAU,CAAC;QACpB,CAAC;QACD,oBAAoB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACtC,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC,CAAC;AAfW,QAAA,QAAQ,YAenB;AASK,MAAM,YAAY,GAAG,CAC1B,OAAgC,EAAE,OAAO,EAAE,IAAI,EAAE,EACf,EAAE;IACpC,OAAO,CACL,MAAW,EACX,WAA6B,EAC7B,UAAyC,EACzC,EAAE;;QACF,MAAM,gBAAgB,GAAG,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,KAAK,mCAAI,MAAM,CAAC;QACrD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,OAAO,CAAC,cAAc,CAAC,oCAAc,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,gBAAgB,CAAC,CAAC;QAC5E,CAAC;QACD,OAAO,UAAU,aAAV,UAAU,cAAV,UAAU,GAAI,MAAM,CAAC;IAC9B,CAAC,CAAC;AACJ,CAAC,CAAC;AAdW,QAAA,YAAY,gBAcvB;AAOK,MAAM,sBAAsB,GAAG,GAAG,EAAE,CAAC,IAAA,eAAM,EAAC,IAAA,qCAAe,GAAE,CAAC,CAAC;AAAzD,QAAA,sBAAsB,0BAAmC;AAO/D,MAAM,sBAAsB,GAAG,GAAG,EAAE,CAAC,IAAA,eAAM,EAAC,IAAA,qCAAe,GAAE,CAAC,CAAC;AAAzD,QAAA,sBAAsB,0BAAmC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
|
2
2
|
import { Reflector } from '@nestjs/core';
|
|
3
|
-
import {
|
|
3
|
+
import { ThrottlerModuleOptions, ThrottlerOptions } from './throttler-module-options.interface';
|
|
4
4
|
import { ThrottlerStorage } from './throttler-storage.interface';
|
|
5
|
-
import { ThrottlerLimitDetail } from './throttler.guard.interface';
|
|
5
|
+
import { ThrottlerLimitDetail, ThrottlerRequest } from './throttler.guard.interface';
|
|
6
6
|
export declare class ThrottlerGuard implements CanActivate {
|
|
7
7
|
protected readonly options: ThrottlerModuleOptions;
|
|
8
8
|
protected readonly storageService: ThrottlerStorage;
|
|
@@ -15,7 +15,7 @@ export declare class ThrottlerGuard implements CanActivate {
|
|
|
15
15
|
onModuleInit(): Promise<void>;
|
|
16
16
|
canActivate(context: ExecutionContext): Promise<boolean>;
|
|
17
17
|
protected shouldSkip(_context: ExecutionContext): Promise<boolean>;
|
|
18
|
-
protected handleRequest(
|
|
18
|
+
protected handleRequest(requestProps: ThrottlerRequest): Promise<boolean>;
|
|
19
19
|
protected getTracker(req: Record<string, any>): Promise<string>;
|
|
20
20
|
protected getRequestResponse(context: ExecutionContext): {
|
|
21
21
|
req: Record<string, any>;
|
|
@@ -23,6 +23,6 @@ export declare class ThrottlerGuard implements CanActivate {
|
|
|
23
23
|
};
|
|
24
24
|
protected generateKey(context: ExecutionContext, suffix: string, name: string): string;
|
|
25
25
|
protected throwThrottlingException(context: ExecutionContext, throttlerLimitDetail: ThrottlerLimitDetail): Promise<void>;
|
|
26
|
-
protected getErrorMessage(
|
|
26
|
+
protected getErrorMessage(context: ExecutionContext, throttlerLimitDetail: ThrottlerLimitDetail): Promise<string>;
|
|
27
27
|
private resolveValue;
|
|
28
28
|
}
|
|
@@ -1,7 +1,18 @@
|
|
|
1
|
+
import { ExecutionContext } from '@nestjs/common';
|
|
1
2
|
import { ThrottlerStorageRecord } from './throttler-storage-record.interface';
|
|
3
|
+
import { ThrottlerGenerateKeyFunction, ThrottlerGetTrackerFunction, ThrottlerOptions } from './throttler-module-options.interface';
|
|
2
4
|
export interface ThrottlerLimitDetail extends ThrottlerStorageRecord {
|
|
3
5
|
ttl: number;
|
|
4
6
|
limit: number;
|
|
5
7
|
key: string;
|
|
6
8
|
tracker: string;
|
|
7
9
|
}
|
|
10
|
+
export interface ThrottlerRequest {
|
|
11
|
+
context: ExecutionContext;
|
|
12
|
+
limit: number;
|
|
13
|
+
ttl: number;
|
|
14
|
+
throttler: ThrottlerOptions;
|
|
15
|
+
blockDuration: number;
|
|
16
|
+
getTracker: ThrottlerGetTrackerFunction;
|
|
17
|
+
generateKey: ThrottlerGenerateKeyFunction;
|
|
18
|
+
}
|
package/dist/throttler.guard.js
CHANGED
|
@@ -75,21 +75,32 @@ let ThrottlerGuard = class ThrottlerGuard {
|
|
|
75
75
|
}
|
|
76
76
|
const routeOrClassLimit = this.reflector.getAllAndOverride(throttler_constants_1.THROTTLER_LIMIT + namedThrottler.name, [handler, classRef]);
|
|
77
77
|
const routeOrClassTtl = this.reflector.getAllAndOverride(throttler_constants_1.THROTTLER_TTL + namedThrottler.name, [handler, classRef]);
|
|
78
|
+
const routeOrClassBlockDuration = this.reflector.getAllAndOverride(throttler_constants_1.THROTTLER_BLOCK_DURATION + namedThrottler.name, [handler, classRef]);
|
|
78
79
|
const routeOrClassGetTracker = this.reflector.getAllAndOverride(throttler_constants_1.THROTTLER_TRACKER + namedThrottler.name, [handler, classRef]);
|
|
79
80
|
const routeOrClassGetKeyGenerator = this.reflector.getAllAndOverride(throttler_constants_1.THROTTLER_KEY_GENERATOR + namedThrottler.name, [handler, classRef]);
|
|
80
81
|
const limit = await this.resolveValue(context, routeOrClassLimit || namedThrottler.limit);
|
|
81
82
|
const ttl = await this.resolveValue(context, routeOrClassTtl || namedThrottler.ttl);
|
|
83
|
+
const blockDuration = await this.resolveValue(context, routeOrClassBlockDuration || namedThrottler.blockDuration || ttl);
|
|
82
84
|
const getTracker = routeOrClassGetTracker || namedThrottler.getTracker || this.commonOptions.getTracker;
|
|
83
85
|
const generateKey = routeOrClassGetKeyGenerator || namedThrottler.generateKey || this.commonOptions.generateKey;
|
|
84
|
-
continues.push(await this.handleRequest(
|
|
86
|
+
continues.push(await this.handleRequest({
|
|
87
|
+
context,
|
|
88
|
+
limit,
|
|
89
|
+
ttl,
|
|
90
|
+
throttler: namedThrottler,
|
|
91
|
+
blockDuration,
|
|
92
|
+
getTracker,
|
|
93
|
+
generateKey,
|
|
94
|
+
}));
|
|
85
95
|
}
|
|
86
96
|
return continues.every((cont) => cont);
|
|
87
97
|
}
|
|
88
98
|
async shouldSkip(_context) {
|
|
89
99
|
return false;
|
|
90
100
|
}
|
|
91
|
-
async handleRequest(
|
|
101
|
+
async handleRequest(requestProps) {
|
|
92
102
|
var _a;
|
|
103
|
+
const { context, limit, ttl, throttler, blockDuration, getTracker, generateKey } = requestProps;
|
|
93
104
|
const { req, res } = this.getRequestResponse(context);
|
|
94
105
|
const ignoreUserAgents = (_a = throttler.ignoreUserAgents) !== null && _a !== void 0 ? _a : this.commonOptions.ignoreUserAgents;
|
|
95
106
|
if (Array.isArray(ignoreUserAgents)) {
|
|
@@ -101,10 +112,10 @@ let ThrottlerGuard = class ThrottlerGuard {
|
|
|
101
112
|
}
|
|
102
113
|
const tracker = await getTracker(req);
|
|
103
114
|
const key = generateKey(context, tracker, throttler.name);
|
|
104
|
-
const { totalHits, timeToExpire } = await this.storageService.increment(key, ttl);
|
|
115
|
+
const { totalHits, timeToExpire, isBlocked, timeToBlockExpire } = await this.storageService.increment(key, ttl, limit, blockDuration, throttler.name);
|
|
105
116
|
const getThrottlerSuffix = (name) => (name === 'default' ? '' : `-${name}`);
|
|
106
|
-
if (
|
|
107
|
-
res.header(`Retry-After${getThrottlerSuffix(throttler.name)}`,
|
|
117
|
+
if (isBlocked) {
|
|
118
|
+
res.header(`Retry-After${getThrottlerSuffix(throttler.name)}`, timeToBlockExpire);
|
|
108
119
|
await this.throwThrottlingException(context, {
|
|
109
120
|
limit,
|
|
110
121
|
ttl,
|
|
@@ -112,6 +123,8 @@ let ThrottlerGuard = class ThrottlerGuard {
|
|
|
112
123
|
tracker,
|
|
113
124
|
totalHits,
|
|
114
125
|
timeToExpire,
|
|
126
|
+
isBlocked,
|
|
127
|
+
timeToBlockExpire,
|
|
115
128
|
});
|
|
116
129
|
}
|
|
117
130
|
res.header(`${this.headerPrefix}-Limit${getThrottlerSuffix(throttler.name)}`, limit);
|
|
@@ -133,9 +146,13 @@ let ThrottlerGuard = class ThrottlerGuard {
|
|
|
133
146
|
async throwThrottlingException(context, throttlerLimitDetail) {
|
|
134
147
|
throw new throttler_exception_1.ThrottlerException(await this.getErrorMessage(context, throttlerLimitDetail));
|
|
135
148
|
}
|
|
136
|
-
async getErrorMessage(
|
|
149
|
+
async getErrorMessage(context, throttlerLimitDetail) {
|
|
137
150
|
if (!Array.isArray(this.options)) {
|
|
138
|
-
|
|
151
|
+
if (!this.options.errorMessage)
|
|
152
|
+
return this.errorMessage;
|
|
153
|
+
return typeof this.options.errorMessage === 'function'
|
|
154
|
+
? this.options.errorMessage(context, throttlerLimitDetail)
|
|
155
|
+
: this.options.errorMessage;
|
|
139
156
|
}
|
|
140
157
|
return this.errorMessage;
|
|
141
158
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"throttler.guard.js","sourceRoot":"","sources":["../src/throttler.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA2E;AAC3E,uCAAyC;AACzC,iCAA6B;AAQ7B,+EAAiE;AACjE,+
|
|
1
|
+
{"version":3,"file":"throttler.guard.js","sourceRoot":"","sources":["../src/throttler.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA2E;AAC3E,uCAAyC;AACzC,iCAA6B;AAQ7B,+EAAiE;AACjE,+DAO+B;AAC/B,+DAAuF;AACvF,+DAA6E;AAOtE,IAAM,cAAc,GAApB,MAAM,cAAc;IASzB,YAC4B,OAAkD,EAClD,cAAmD,EAC1D,SAAoB;QAFM,YAAO,GAAP,OAAO,CAAwB;QAC/B,mBAAc,GAAd,cAAc,CAAkB;QAC1D,cAAS,GAAT,SAAS,CAAW;QAX/B,iBAAY,GAAG,aAAa,CAAC;QAC7B,iBAAY,GAAG,sCAAgB,CAAC;IAWvC,CAAC;IAEJ,KAAK,CAAC,YAAY;;;QAChB,IAAI,CAAC,UAAU,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;aACrF,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YACtB,IAAI,OAAO,KAAK,CAAC,GAAG,KAAK,UAAU,EAAE,CAAC;gBACpC,OAAO,CAAC,CAAC;YACX,CAAC;YACD,IAAI,OAAO,MAAM,CAAC,GAAG,KAAK,UAAU,EAAE,CAAC;gBACrC,OAAO,CAAC,CAAC;YACX,CAAC;YACD,OAAO,KAAK,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;QAChC,CAAC,CAAC;aACD,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,WAAC,OAAA,iCAAM,GAAG,KAAE,IAAI,EAAE,MAAA,GAAG,CAAC,IAAI,mCAAI,SAAS,IAAG,CAAA,EAAA,CAAC,CAAC;QAC3D,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,aAAa,GAAG;gBACnB,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM;gBAC3B,gBAAgB,EAAE,IAAI,CAAC,OAAO,CAAC,gBAAgB;gBAC/C,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU;gBACnC,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW;aACtC,CAAC;QACJ,CAAC;QACD,YAAA,IAAI,CAAC,aAAa,EAAC,UAAU,uCAAV,UAAU,GAAK,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAC;QAC7D,YAAA,IAAI,CAAC,aAAa,EAAC,WAAW,uCAAX,WAAW,GAAK,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAC;IACjE,CAAC;IAOD,KAAK,CAAC,WAAW,CAAC,OAAyB;QACzC,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;QAEpC,IAAI,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACnC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,SAAS,GAAc,EAAE,CAAC;QAEhC,KAAK,MAAM,cAAc,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAE7C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAU,oCAAc,GAAG,cAAc,CAAC,IAAI,EAAE;gBAC3F,OAAO;gBACP,QAAQ;aACT,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;YAClE,IAAI,IAAI,KAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAG,OAAO,CAAC,CAAA,EAAE,CAAC;gBAC9B,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACrB,SAAS;YACX,CAAC;YAGD,MAAM,iBAAiB,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CACxD,qCAAe,GAAG,cAAc,CAAC,IAAI,EACrC,CAAC,OAAO,EAAE,QAAQ,CAAC,CACpB,CAAC;YACF,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CACtD,mCAAa,GAAG,cAAc,CAAC,IAAI,EACnC,CAAC,OAAO,EAAE,QAAQ,CAAC,CACpB,CAAC;YACF,MAAM,yBAAyB,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAChE,8CAAwB,GAAG,cAAc,CAAC,IAAI,EAC9C,CAAC,OAAO,EAAE,QAAQ,CAAC,CACpB,CAAC;YACF,MAAM,sBAAsB,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAC7D,uCAAiB,GAAG,cAAc,CAAC,IAAI,EACvC,CAAC,OAAO,EAAE,QAAQ,CAAC,CACpB,CAAC;YACF,MAAM,2BAA2B,GAC/B,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAC9B,6CAAuB,GAAG,cAAc,CAAC,IAAI,EAC7C,CAAC,OAAO,EAAE,QAAQ,CAAC,CACpB,CAAC;YAGJ,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,iBAAiB,IAAI,cAAc,CAAC,KAAK,CAAC,CAAC;YAC1F,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,eAAe,IAAI,cAAc,CAAC,GAAG,CAAC,CAAC;YACpF,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,YAAY,CAC3C,OAAO,EACP,yBAAyB,IAAI,cAAc,CAAC,aAAa,IAAI,GAAG,CACjE,CAAC;YACF,MAAM,UAAU,GACd,sBAAsB,IAAI,cAAc,CAAC,UAAU,IAAI,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC;YACvF,MAAM,WAAW,GACf,2BAA2B,IAAI,cAAc,CAAC,WAAW,IAAI,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC;YAC9F,SAAS,CAAC,IAAI,CACZ,MAAM,IAAI,CAAC,aAAa,CAAC;gBACvB,OAAO;gBACP,KAAK;gBACL,GAAG;gBACH,SAAS,EAAE,cAAc;gBACzB,aAAa;gBACb,UAAU;gBACV,WAAW;aACZ,CAAC,CACH,CAAC;QACJ,CAAC;QACD,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;IAES,KAAK,CAAC,UAAU,CAAC,QAA0B;QACnD,OAAO,KAAK,CAAC;IACf,CAAC;IAQS,KAAK,CAAC,aAAa,CAAC,YAA8B;;QAC1D,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,YAAY,CAAC;QAGhG,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;QACtD,MAAM,gBAAgB,GAAG,MAAA,SAAS,CAAC,gBAAgB,mCAAI,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC;QAE3F,IAAI,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACpC,KAAK,MAAM,OAAO,IAAI,gBAAgB,EAAE,CAAC;gBACvC,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;oBAC5C,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;QACH,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QAC1D,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,iBAAiB,EAAE,GAC7D,MAAM,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,aAAa,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QAEtF,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QAGpF,IAAI,SAAS,EAAE,CAAC;YACd,GAAG,CAAC,MAAM,CAAC,cAAc,kBAAkB,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,iBAAiB,CAAC,CAAC;YAClF,MAAM,IAAI,CAAC,wBAAwB,CAAC,OAAO,EAAE;gBAC3C,KAAK;gBACL,GAAG;gBACH,GAAG;gBACH,OAAO;gBACP,SAAS;gBACT,YAAY;gBACZ,SAAS;gBACT,iBAAiB;aAClB,CAAC,CAAC;QACL,CAAC;QAED,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,YAAY,SAAS,kBAAkB,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAGrF,GAAG,CAAC,MAAM,CACR,GAAG,IAAI,CAAC,YAAY,aAAa,kBAAkB,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EACrE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC,CAC/B,CAAC;QACF,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,YAAY,SAAS,kBAAkB,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;QAE5F,OAAO,IAAI,CAAC;IACd,CAAC;IAES,KAAK,CAAC,UAAU,CAAC,GAAwB;QACjD,OAAO,GAAG,CAAC,EAAE,CAAC;IAChB,CAAC;IAES,kBAAkB,CAAC,OAAyB;QAIpD,MAAM,IAAI,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;QACpC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;IAC7D,CAAC;IAMS,WAAW,CAAC,OAAyB,EAAE,MAAc,EAAE,IAAY;QAC3E,MAAM,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,IAAI,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC;QACjF,OAAO,IAAA,UAAG,EAAC,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC,CAAC;IACpC,CAAC;IASS,KAAK,CAAC,wBAAwB,CACtC,OAAyB,EACzB,oBAA0C;QAE1C,MAAM,IAAI,wCAAkB,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC;IAC1F,CAAC;IAES,KAAK,CAAC,eAAe,CAC7B,OAAyB,EACzB,oBAA0C;QAE1C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY;gBAAE,OAAO,IAAI,CAAC,YAAY,CAAC;YAEzD,OAAO,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,KAAK,UAAU;gBACpD,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,EAAE,oBAAoB,CAAC;gBAC1D,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC;QAChC,CAAC;QACD,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAEO,KAAK,CAAC,YAAY,CACxB,OAAyB,EACzB,eAA8B;QAE9B,OAAO,OAAO,eAAe,KAAK,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC;IAC5F,CAAC;CACF,CAAA;AArOY,wCAAc;yBAAd,cAAc;IAD1B,IAAA,mBAAU,GAAE;IAWR,WAAA,IAAA,4CAAsB,GAAE,CAAA;IACxB,WAAA,IAAA,4CAAsB,GAAE,CAAA;qDACK,gBAAS;GAZ9B,cAAc,CAqO1B"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getStorageToken = exports.getOptionsToken = exports.ThrottlerStorageProvider =
|
|
3
|
+
exports.getStorageToken = exports.getOptionsToken = exports.ThrottlerStorageProvider = void 0;
|
|
4
|
+
exports.createThrottlerProviders = createThrottlerProviders;
|
|
4
5
|
const throttler_storage_interface_1 = require("./throttler-storage.interface");
|
|
5
6
|
const throttler_constants_1 = require("./throttler.constants");
|
|
6
7
|
const throttler_service_1 = require("./throttler.service");
|
|
@@ -12,7 +13,6 @@ function createThrottlerProviders(options) {
|
|
|
12
13
|
},
|
|
13
14
|
];
|
|
14
15
|
}
|
|
15
|
-
exports.createThrottlerProviders = createThrottlerProviders;
|
|
16
16
|
exports.ThrottlerStorageProvider = {
|
|
17
17
|
provide: throttler_storage_interface_1.ThrottlerStorage,
|
|
18
18
|
useFactory: (options) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"throttler.providers.js","sourceRoot":"","sources":["../src/throttler.providers.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"throttler.providers.js","sourceRoot":"","sources":["../src/throttler.providers.ts"],"names":[],"mappings":";;;AAMA,4DAOC;AAXD,+EAAiE;AACjE,+DAA0D;AAC1D,2DAA8D;AAE9D,SAAgB,wBAAwB,CAAC,OAA+B;IACtE,OAAO;QACL;YACE,OAAO,EAAE,uCAAiB;YAC1B,QAAQ,EAAE,OAAO;SAClB;KACF,CAAC;AACJ,CAAC;AAEY,QAAA,wBAAwB,GAAG;IACtC,OAAO,EAAE,8CAAgB;IACzB,UAAU,EAAE,CAAC,OAA+B,EAAE,EAAE;QAC9C,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,OAAO;YAC/C,CAAC,CAAC,OAAO,CAAC,OAAO;YACjB,CAAC,CAAC,IAAI,2CAAuB,EAAE,CAAC;IACpC,CAAC;IACD,MAAM,EAAE,CAAC,uCAAiB,CAAC;CAC5B,CAAC;AAMK,MAAM,eAAe,GAAG,GAAG,EAAE,CAAC,uCAAiB,CAAC;AAA1C,QAAA,eAAe,mBAA2B;AAMhD,MAAM,eAAe,GAAG,GAAG,EAAE,CAAC,8CAAgB,CAAC;AAAzC,QAAA,eAAe,mBAA0B"}
|
|
@@ -5,9 +5,13 @@ import { ThrottlerStorage } from './throttler-storage.interface';
|
|
|
5
5
|
export declare class ThrottlerStorageService implements ThrottlerStorage, OnApplicationShutdown {
|
|
6
6
|
private _storage;
|
|
7
7
|
private timeoutIds;
|
|
8
|
-
get storage():
|
|
8
|
+
get storage(): Map<string, ThrottlerStorageOptions>;
|
|
9
9
|
private getExpirationTime;
|
|
10
|
+
private getBlockExpirationTime;
|
|
10
11
|
private setExpirationTime;
|
|
11
|
-
|
|
12
|
+
private clearExpirationTimes;
|
|
13
|
+
private resetBlockdRequest;
|
|
14
|
+
private fireHitCount;
|
|
15
|
+
increment(key: string, ttl: number, limit: number, blockDuration: number, throttlerName: string): Promise<ThrottlerStorageRecord>;
|
|
12
16
|
onApplicationShutdown(): void;
|
|
13
17
|
}
|
|
@@ -10,42 +10,82 @@ exports.ThrottlerStorageService = void 0;
|
|
|
10
10
|
const common_1 = require("@nestjs/common");
|
|
11
11
|
let ThrottlerStorageService = class ThrottlerStorageService {
|
|
12
12
|
constructor() {
|
|
13
|
-
this._storage =
|
|
14
|
-
this.timeoutIds =
|
|
13
|
+
this._storage = new Map();
|
|
14
|
+
this.timeoutIds = new Map();
|
|
15
15
|
}
|
|
16
16
|
get storage() {
|
|
17
17
|
return this._storage;
|
|
18
18
|
}
|
|
19
19
|
getExpirationTime(key) {
|
|
20
|
-
return Math.floor((this.storage
|
|
20
|
+
return Math.floor((this.storage.get(key).expiresAt - Date.now()) / 1000);
|
|
21
21
|
}
|
|
22
|
-
|
|
22
|
+
getBlockExpirationTime(key) {
|
|
23
|
+
return Math.floor((this.storage.get(key).blockExpiresAt - Date.now()) / 1000);
|
|
24
|
+
}
|
|
25
|
+
setExpirationTime(key, ttlMilliseconds, throttlerName) {
|
|
23
26
|
const timeoutId = setTimeout(() => {
|
|
24
|
-
this.storage
|
|
27
|
+
const { totalHits } = this.storage.get(key);
|
|
28
|
+
totalHits.set(throttlerName, totalHits.get(throttlerName) - 1);
|
|
25
29
|
clearTimeout(timeoutId);
|
|
26
|
-
this.timeoutIds
|
|
30
|
+
this.timeoutIds.set(throttlerName, this.timeoutIds.get(throttlerName).filter((id) => id !== timeoutId));
|
|
27
31
|
}, ttlMilliseconds);
|
|
28
|
-
this.timeoutIds.push(timeoutId);
|
|
32
|
+
this.timeoutIds.get(throttlerName).push(timeoutId);
|
|
33
|
+
}
|
|
34
|
+
clearExpirationTimes(throttlerName) {
|
|
35
|
+
this.timeoutIds.get(throttlerName).forEach(clearTimeout);
|
|
36
|
+
this.timeoutIds.set(throttlerName, []);
|
|
37
|
+
}
|
|
38
|
+
resetBlockdRequest(key, throttlerName) {
|
|
39
|
+
this.storage.get(key).isBlocked = false;
|
|
40
|
+
this.storage.get(key).totalHits.set(throttlerName, 0);
|
|
41
|
+
this.clearExpirationTimes(throttlerName);
|
|
42
|
+
}
|
|
43
|
+
fireHitCount(key, throttlerName, ttl) {
|
|
44
|
+
const { totalHits } = this.storage.get(key);
|
|
45
|
+
totalHits.set(throttlerName, totalHits.get(throttlerName) + 1);
|
|
46
|
+
this.setExpirationTime(key, ttl, throttlerName);
|
|
29
47
|
}
|
|
30
|
-
async increment(key, ttl) {
|
|
48
|
+
async increment(key, ttl, limit, blockDuration, throttlerName) {
|
|
31
49
|
const ttlMilliseconds = ttl;
|
|
32
|
-
|
|
33
|
-
|
|
50
|
+
const blockDurationMilliseconds = blockDuration;
|
|
51
|
+
if (!this.timeoutIds.has(throttlerName)) {
|
|
52
|
+
this.timeoutIds.set(throttlerName, []);
|
|
53
|
+
}
|
|
54
|
+
if (!this.storage.has(key)) {
|
|
55
|
+
this.storage.set(key, {
|
|
56
|
+
totalHits: new Map([[throttlerName, 0]]),
|
|
57
|
+
expiresAt: Date.now() + ttlMilliseconds,
|
|
58
|
+
blockExpiresAt: 0,
|
|
59
|
+
isBlocked: false,
|
|
60
|
+
});
|
|
34
61
|
}
|
|
35
62
|
let timeToExpire = this.getExpirationTime(key);
|
|
36
63
|
if (timeToExpire <= 0) {
|
|
37
|
-
this.storage
|
|
64
|
+
this.storage.get(key).expiresAt = Date.now() + ttlMilliseconds;
|
|
38
65
|
timeToExpire = this.getExpirationTime(key);
|
|
39
66
|
}
|
|
40
|
-
this.storage
|
|
41
|
-
|
|
67
|
+
if (!this.storage.get(key).isBlocked) {
|
|
68
|
+
this.fireHitCount(key, throttlerName, ttlMilliseconds);
|
|
69
|
+
}
|
|
70
|
+
if (this.storage.get(key).totalHits.get(throttlerName) > limit &&
|
|
71
|
+
!this.storage.get(key).isBlocked) {
|
|
72
|
+
this.storage.get(key).isBlocked = true;
|
|
73
|
+
this.storage.get(key).blockExpiresAt = Date.now() + blockDurationMilliseconds;
|
|
74
|
+
}
|
|
75
|
+
const timeToBlockExpire = this.getBlockExpirationTime(key);
|
|
76
|
+
if (timeToBlockExpire <= 0 && this.storage.get(key).isBlocked) {
|
|
77
|
+
this.resetBlockdRequest(key, throttlerName);
|
|
78
|
+
this.fireHitCount(key, throttlerName, ttlMilliseconds);
|
|
79
|
+
}
|
|
42
80
|
return {
|
|
43
|
-
totalHits: this.storage
|
|
81
|
+
totalHits: this.storage.get(key).totalHits.get(throttlerName),
|
|
44
82
|
timeToExpire,
|
|
83
|
+
isBlocked: this.storage.get(key).isBlocked,
|
|
84
|
+
timeToBlockExpire: timeToBlockExpire,
|
|
45
85
|
};
|
|
46
86
|
}
|
|
47
87
|
onApplicationShutdown() {
|
|
48
|
-
this.timeoutIds.forEach(clearTimeout);
|
|
88
|
+
this.timeoutIds.forEach((timeouts) => timeouts.forEach(clearTimeout));
|
|
49
89
|
}
|
|
50
90
|
};
|
|
51
91
|
exports.ThrottlerStorageService = ThrottlerStorageService;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"throttler.service.js","sourceRoot":"","sources":["../src/throttler.service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAmE;AAS5D,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;IAA7B;QACG,aAAQ,
|
|
1
|
+
{"version":3,"file":"throttler.service.js","sourceRoot":"","sources":["../src/throttler.service.ts"],"names":[],"mappings":"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"}
|