Skip to content

Commit

Permalink
ci(rebase): merge master
Browse files Browse the repository at this point in the history
  • Loading branch information
rudemex committed Nov 6, 2024
2 parents acf889d + c8e4bec commit 245a6a7
Show file tree
Hide file tree
Showing 25 changed files with 548 additions and 48 deletions.
45 changes: 23 additions & 22 deletions README.md

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,12 @@
"minimatch": "^10.0.1",
"mongodb": "^6.10.0",
"mysql": "^2.18.1",
"mysql2": "^3.11.3",
"mysql2": "^3.11.4",
"pg": "^8.13.1",
"redis": "^4.7.0",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.1",
"testcontainers": "^10.13.2",
"testcontainers": "^10.14.0",
"typeorm": "^0.3.20",
"uuid": "^11.0.2"
},
Expand Down Expand Up @@ -160,7 +160,7 @@
"prettier": "^3.3.3",
"rimraf": "^6.0.1",
"supertest": "^7.0.0",
"testcontainers": "^10.13.2",
"testcontainers": "^10.14.0",
"ts-jest": "^29.2.5",
"ts-loader": "^9.5.1",
"ts-node": "^10.9.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tresdoce-nestjs-toolkit/core",
"version": "1.4.3",
"version": "1.4.4-beta.0",
"description": "Tresdoce NestJS Toolkit - Funcionalidades a nivel core",
"author": {
"name": "Maximiliano \"Mex\" Delgado",
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/typings/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { HttpModuleOptions } from '@tresdoce-nestjs-toolkit/http-client';
import { RedactOptions, BcryptOptions } from '@tresdoce-nestjs-toolkit/utils';
import { SnowFlakeOptions } from '@tresdoce-nestjs-toolkit/snowflake-uid';
import { AwsSqsModuleOptions } from '@tresdoce-nestjs-toolkit/aws-sqs';
import { ThrottlerModuleOptions } from '@tresdoce-nestjs-toolkit/rate-limit';
import { DiskHealthIndicatorOptions } from '@nestjs/terminus';
import { AxiosRequestConfig } from 'axios';
import { CsrfCookieOptions } from '../commons/index';
Expand Down Expand Up @@ -94,6 +95,7 @@ export interface IServerConfig {
corsEnabled: boolean;
corsCredentials: boolean;
csrf?: CsrfCookieOptions;
rateLimits?: ThrottlerModuleOptions;
}

export interface IHealthConfig {
Expand Down
4 changes: 2 additions & 2 deletions packages/filters/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tresdoce-nestjs-toolkit/filters",
"version": "1.1.4",
"version": "1.1.5-beta.0",
"description": "Tresdoce NestJS Toolkit - Librería para filtrar y formatear las excepciones",
"author": {
"name": "Maximiliano \"Mex\" Delgado",
Expand Down Expand Up @@ -44,7 +44,7 @@
"rxjs": "^7.8.1"
},
"dependencies": {
"@tresdoce-nestjs-toolkit/core": "^1.4.3"
"@tresdoce-nestjs-toolkit/core": "^1.4.4-beta.0"
},
"devDependencies": {
"@tresdoce-nestjs-toolkit/config": "^0.4.1",
Expand Down
1 change: 1 addition & 0 deletions packages/paas/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ Esta librería contiene de manera centralizada los recursos necesarios para el d
- [`@tresdoce-nestjs-toolkit/core`](../core)
- [`@tresdoce-nestjs-toolkit/filters`](../filters)
- [`@tresdoce-nestjs-toolkit/health`](../health)
- [`@tresdoce-nestjs-toolkit/rate-limit`](../rate-limit)
- [`@tresdoce-nestjs-toolkit/response-parser`](../response-parser)
- [`@tresdoce-nestjs-toolkit/tracing`](../tracing)
- [`@tresdoce-nestjs-toolkit/utils`](../utils)
Expand Down
11 changes: 6 additions & 5 deletions packages/paas/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tresdoce-nestjs-toolkit/paas",
"version": "1.1.4",
"version": "1.2.0-beta.0",
"description": "Tresdoce NestJS Toolkit - Librería centralizada de funcionalidades cross",
"author": {
"name": "Maximiliano \"Mex\" Delgado",
Expand Down Expand Up @@ -44,11 +44,12 @@
"rxjs": "^7.8.1"
},
"dependencies": {
"@tresdoce-nestjs-toolkit/core": "^1.4.3",
"@tresdoce-nestjs-toolkit/filters": "^1.1.4",
"@tresdoce-nestjs-toolkit/core": "^1.4.4-beta.0",
"@tresdoce-nestjs-toolkit/filters": "^1.1.5-beta.0",
"@tresdoce-nestjs-toolkit/health": "^1.1.4",
"@tresdoce-nestjs-toolkit/response-parser": "^1.2.4",
"@tresdoce-nestjs-toolkit/tracing": "^1.2.4",
"@tresdoce-nestjs-toolkit/rate-limit": "^0.1.0-beta.0",
"@tresdoce-nestjs-toolkit/response-parser": "^1.2.5-beta.0",
"@tresdoce-nestjs-toolkit/tracing": "^1.2.5-beta.0",
"@tresdoce-nestjs-toolkit/utils": "^1.2.4"
},
"devDependencies": {
Expand Down
Empty file.
244 changes: 244 additions & 0 deletions packages/rate-limit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
<div align="center">
<img alt="nestjs-logo" width="150" height="auto" src="https://raw.githubusercontent.com/tresdoce/tresdoce-nestjs-toolkit/master/.readme-static/iso-nestjs.svg" />
<h1>Tresdoce NestJS Toolkit<br/>Rate-Limit</h1>
</div>

<div align="center">
<img src="https://img.shields.io/static/v1.svg?style=flat&label=NodeJS&message=v20.18.0&labelColor=339933&color=757575&logoColor=FFFFFF&logo=Node.js" alt="Node.js"/>
<img src="https://img.shields.io/static/v1.svg?style=flat&label=NPM&message=v10.9.0&labelColor=CB3837&logoColor=FFFFFF&color=757575&logo=npm" alt="Npm"/>
<img src="https://img.shields.io/static/v1.svg?style=flat&label=NestJS&message=v10.4.6&labelColor=E0234E&logoColor=FFFFFF&color=757575&logo=Nestjs" alt="NestJS"/><br/>
<img src="https://img.shields.io/github/license/tresdoce/tresdoce-nestjs-toolkit?style=flat" alt="GitHub license" >
<img alt="Release" src="https://img.shields.io/npm/v/@tresdoce-nestjs-toolkit/rate-limit.svg">
<br/>
</div>
<br/>

> ⚠️ Es importante tener en cuenta que este módulo se encuentra implementado en el package `@tresdoce-nestjs-toolkit/paas`, ya que es una funcionalidad core para el starter.
Este módulo está pensado para ser utilizado en [NestJS Starter](https://github.com/rudemex/nestjs-starter), o cualquier
proyecto que utilice una configuración centralizada, siguiendo la misma arquitectura del starter.

## Glosario

- [🥳 Demo](https://nestjs-starter.tresdoce.com.ar/v1/docs)
- [📝 Requerimientos básicos](#basic-requirements)
- [🛠️ Instalar dependencia](#install-dependencies)
- [⚙️ Configuración](#configurations)
- [👨‍💻 Uso](#use)
- [📄 Changelog](./CHANGELOG.md)
- [📜 License MIT](./license.md)

---

<a name="basic-requirements"></a>

## 📝 Requerimientos básicos

- [NestJS Starter](https://github.com/rudemex/nestjs-starter)
- Node.js v20.18.0 or higher ([Download](https://nodejs.org/es/download/))
- YARN v1.22.19 or higher
- NPM v10.9.0 or higher
- NestJS v10.4.6 or higher ([Documentación](https://nestjs.com/))

<a name="install-dependencies"></a>

## 🛠️ Instalar dependencia

```
npm install -S @tresdoce-nestjs-toolkit/rate-limit
```

```
yarn add @tresdoce-nestjs-toolkit/rate-limit
```

<a name="configurations"></a>

## ⚙️ Configuración

Agregar los datos del rate limit en `configuration.ts` utilizando el key `rateLimits` en el key de `server`.
Puedes encontrar más información en la [documentación](https://docs.nestjs.com/security/rate-limiting)

```typescript
//./src/config/configuration.ts
import { Typings } from '@tresdoce-nestjs-toolkit/core';
import { registerAs } from '@nestjs/config';

export default registerAs('config', (): Typings.AppConfig => {
return {
//...
server: {
//...
rateLimits: {
throttlers: [
{
limit: 10,
ttl: 60,
},
],
},
},
//...
};
});
```

`RateLimitModule` utiliza las opciones de `ThrottlerModule` para configurar las restricciones.
Estas opciones se pueden pasar como un objeto `ThrottlerModuleOptions` que contiene:

| Property | Type | Description |
| ------------------ | ----------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| `throttlers` | `Array<ThrottlerOptions>` | Lista de limitadores individuales con sus propias configuraciones de límite de tasa. |
| `skipIf` | `(context: ExecutionContext) => boolean` | Función que omite la limitación si retorna `true. |
| `ignoreUserAgents` | `RegExp[] ` | Lista de expresiones regulares para omitir ciertos `User-Agents`, como bots de motores de búsqueda. |
| `getTracker` | `ThrottlerGetTrackerFunction` | Función para obtener el identificador único del cliente (por ejemplo, dirección IP o ID de usuario) |
| `generateKey` | `ThrottlerGenerateKeyFunction` | Función para personalizar la clave de rastreo única para cada cliente. |
| `errorMessage` | `string` o `((context, limitDetail) => string)` | Mensaje de error personalizado cuando se alcanza el límite de solicitudes. |
| `storage` | `ThrottlerStorage` | Mecanismo de almacenamiento usado para rastrear las solicitudes, por defecto en memoria. |

Cada item (`ThrottlerOptions`) permite configurar un limitador específico:

| Property | Type | Description |
| ------------------ | ---------------------------------------- | ----------------------------------------------------------------------------------------- |
| `name` | `string` | Nombre opcional para identificar el limitador de tasa. |
| `limit` | `Resolvable<number> ` | Número máximo de solicitudes permitidas en el intervalo `ttl`. |
| `ttl` | `Resolvable<number> ` | Intervalo de tiempo en segundos durante el cual se cuentan las solicitudes. |
| `blockDuration` | `Resolvable<number> ` | Duración en segundos durante la cual se bloquea al cliente después de alcanzar el límite. |
| `ignoreUserAgents` | `RegExp[]` | Lista de `User-Agents que serán ignorados para este limitador. |
| `skipIf` | `(context: ExecutionContext) => boolean` | Función para omitir la limitación de tasa si retorna `true. |
| `getTracker` | `ThrottlerGetTrackerFunction` | Función para rastrear el cliente específico. |
| `generateKey` | `ThrottlerGenerateKeyFunction` | Personalización de la clave única que rastrea las solicitudes de cada cliente. |

### Ejemplos de Configuración Avanzada

- La configuración con `generateKey` rastrea las solicitudes por combinación de IP y ruta, permitiendo límites de tasa específicos por ruta.
- El `blockDuration` en la configuración, bloquea al cliente durante 5 minutos si supera el límite de 10 solicitudes en 1 minuto.
- El `skipIf` en la configuración, omite la limitación de tasa para usuarios administradores autenticados.

```typescript
//./src/config/configuration.ts
import { Typings } from '@tresdoce-nestjs-toolkit/core';
import { registerAs } from '@nestjs/config';

export default registerAs('config', (): Typings.AppConfig => {
return {
//...
server: {
//...
rateLimits: {
throttlers: [
{
limit: 10,
ttl: 60,
blockDuration: 300,
},
],
skipIf: (context) => {
const request = context.switchToHttp().getRequest();
return request.user?.isAdmin;
},
generateKey: (context, trackerString) => {
const request = context.switchToHttp().getRequest();
return `${trackerString}-${request.route.path}`;
},
},
},
//...
};
});
```

<a name="use"></a>

## 👨‍💻 Uso

Para aplicar el rate limit, puedes usar `ThrottlerGuard` a nivel global, controlador o ruta específica.

#### Aplicación Global

```typescript
//./src/main.ts
import { ConfigService } from '@nestjs/config';
import { ThrottlerGuard } from '@tresdoce-nestjs-toolkit/rate-limit';

//...

async function bootstrap() {
//...
app.useGlobalGuards(new ThrottlerGuard());
//...
}
```

O bien, se puede configurar como provider en el `app.module.ts`

```typescript
//./src/app.module.ts
import { APP_GUARD } from '@nestjs/core';
import { ThrottlerGuard } from '@tresdoce-nestjs-toolkit/rate-limit';

@Module({
//...
providers: [
//...
{
provide: APP_GUARD,
useClass: ThrottlerGuard,
},
//...
],
//...
})
export class AppModule {}
```

#### Aplicación Nivel de Controlador

```typescript
import { Controller, Get, UseGuards } from '@nestjs/common';
import { ThrottlerGuard } from '@tresdoce-nestjs-toolkit/rate-limit';

@Controller('test')
@UseGuards(ThrottlerGuard)
export class TestController {
@Get()
getTest() {
return 'Esta es una ruta protegida por el rate limit';
}
}
```

#### Saltear rate limit

El decorador `@SkipThrottle()` se usa para omitir temporalmente el rate limit en métodos o controladores específicos que,
de otro modo, estarían protegidos por el `ThrottlerGuard`. Esto permite marcar ciertas rutas o acciones que no deberían
verse afectadas por el límite de solicitudes configurado en `RateLimitModule`.

```typescript
@SkipThrottle()
@Controller('users')
export class UsersController {
// Rate limiting is applied to this route.
@SkipThrottle({ default: false })
dontSkip() {
return 'List users work with Rate limiting.';
}
// This route will skip rate limiting.
doSkip() {
return 'List users work without Rate limiting.';
}
}
```

## 📄 Changelog

Todos los cambios notables de este paquete se documentarán en el archivo [Changelog](./CHANGELOG.md).

---

<div align="center">
<a href="mailto:mdelgado@tresdoce.com.ar" target="_blank" alt="Send an email">
<img src="https://raw.githubusercontent.com/tresdoce/tresdoce-nestjs-toolkit/ab924d5bdd9a9b9acb3ca5721d4ce977c6b7f680/.readme-static/logo-mex-red.svg" width="120" alt="Logo - Mex" />
</a><br/>
<p>Made with ❤</p>
</div>
9 changes: 9 additions & 0 deletions packages/rate-limit/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const config = require('@tresdoce-nestjs-toolkit/config/jest.config');
//const path = require('path');

module.exports = {
...config,
rootDir: __dirname,
//globalSetup: path.resolve(__dirname, './jest.globalSetup.ts'),
//globalTeardown: path.resolve(__dirname, './jest.globalTeardown.ts'),
};
7 changes: 7 additions & 0 deletions packages/rate-limit/jest.globalSetup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { initDockerCompose } from '@tresdoce-nestjs-toolkit/test-utils';
import * as path from 'path';

const services = [];
const composeFilePath = path.resolve(__dirname, '..', '..');

module.exports = initDockerCompose(services, composeFilePath);
3 changes: 3 additions & 0 deletions packages/rate-limit/jest.globalTeardown.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { closeDockerCompose } from '@tresdoce-nestjs-toolkit/test-utils';

module.exports = closeDockerCompose({ removeVolumes: true });
21 changes: 21 additions & 0 deletions packages/rate-limit/license.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2022 - present Tresdoce & Maximiliano "Mex" Delgado <mdelgado@tresdoce.com.ar>

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:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
4 changes: 4 additions & 0 deletions packages/rate-limit/nest-cli.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"collection": "@nestjs/schematics",
"sourceRoot": "src"
}
Loading

0 comments on commit 245a6a7

Please sign in to comment.