From ffc77768c097dbf7d820be0577bcb600c03ddf4d Mon Sep 17 00:00:00 2001 From: Salim Ben Dakhlia Date: Fri, 13 Sep 2024 12:25:08 +0200 Subject: [PATCH 1/2] feat: add an option to disable header masking for a route --- .../logging-interceptor/src/log.decorator.ts | 4 ++++ .../src/logging.interceptor.ts | 3 ++- .../test/logging.interceptor.test.ts | 11 +++++++++++ .../test/test-app/cats/cats.controller.ts | 16 ++++++++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/packages/logging-interceptor/src/log.decorator.ts b/packages/logging-interceptor/src/log.decorator.ts index 0030aa32..020a2bba 100644 --- a/packages/logging-interceptor/src/log.decorator.ts +++ b/packages/logging-interceptor/src/log.decorator.ts @@ -28,6 +28,10 @@ export interface MaskingOptions { * If it is an array of strings, it will mask only the specified fields. */ response?: string[] | boolean; + /** + * If true, it will disable the header masking. + */ + disableHeaderMask?: boolean; } /** diff --git a/packages/logging-interceptor/src/logging.interceptor.ts b/packages/logging-interceptor/src/logging.interceptor.ts index 32112747..e28d96d0 100644 --- a/packages/logging-interceptor/src/logging.interceptor.ts +++ b/packages/logging-interceptor/src/logging.interceptor.ts @@ -150,7 +150,8 @@ export class LoggingInterceptor implements NestInterceptor { // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions const maskedBody = options?.mask?.request ? this.maskData(body, options.mask.request) : body; - const maskedHeaders = this.maskHeaders(headers); + // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions + const maskedHeaders = options?.mask?.disableHeaderMask ? headers : this.maskHeaders(headers); this.logger.log( { diff --git a/packages/logging-interceptor/test/logging.interceptor.test.ts b/packages/logging-interceptor/test/logging.interceptor.test.ts index b6114079..3758a691 100644 --- a/packages/logging-interceptor/test/logging.interceptor.test.ts +++ b/packages/logging-interceptor/test/logging.interceptor.test.ts @@ -483,6 +483,17 @@ describe('Logging interceptor', () => { expect(logSpy.mock.calls[0][0].headers.authorization).toBe('Bearer JWT'); }); + it('should not mask a request header is disableHeaderMasking is true', async () => { + const interceptor = app.get(ApplicationConfig).getGlobalInterceptors()[0] as LoggingInterceptor; + interceptor.setMask({ requestHeader: {} }); + const logSpy: jest.SpyInstance = jest.spyOn(Logger.prototype, 'log'); + const url: string = `/cats/header`; + + await request(app.getHttpServer()).post(url).set('authorization', 'Bearer JWT').expect(HttpStatus.CREATED); + + expect(logSpy.mock.calls[0][0].headers.authorization).toBe('Bearer JWT'); + }); + it('should not mask a request header if the corresponding mask is false', async () => { const interceptor = app.get(ApplicationConfig).getGlobalInterceptors()[0] as LoggingInterceptor; interceptor.setMask({ requestHeader: { authorization: false } }); diff --git a/packages/logging-interceptor/test/test-app/cats/cats.controller.ts b/packages/logging-interceptor/test/test-app/cats/cats.controller.ts index 7dcc5244..2017bb20 100644 --- a/packages/logging-interceptor/test/test-app/cats/cats.controller.ts +++ b/packages/logging-interceptor/test/test-app/cats/cats.controller.ts @@ -48,6 +48,22 @@ export class CatsController { return { id: 1, ...payload }; } + @Post('header') + @Log({ + mask: { + request: ['birthdate', 'interests.description', 'address', 'enemies'], + response: ['id', 'birthdate', 'interests.description', 'address', 'enemies'], + disableHeaderMask: true, + }, + }) + public createCatUnmaskedHeader(@Body() payload: CreateCatDto) { + if (payload.name === 'dog') { + throw new BadRequestException({ message: 'You cannot name a cat dog' }); + } + + return { id: 1, ...payload }; + } + @Get() @Log({ mask: { From 1703c91c97d28efcf643c6005052dfcd26be478d Mon Sep 17 00:00:00 2001 From: Salim Ben Dakhlia Date: Fri, 13 Sep 2024 16:48:34 +0200 Subject: [PATCH 2/2] chore: change new option variable name --- packages/logging-interceptor/src/log.decorator.ts | 2 +- packages/logging-interceptor/src/logging.interceptor.ts | 2 +- .../logging-interceptor/test/test-app/cats/cats.controller.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/logging-interceptor/src/log.decorator.ts b/packages/logging-interceptor/src/log.decorator.ts index 020a2bba..234682ed 100644 --- a/packages/logging-interceptor/src/log.decorator.ts +++ b/packages/logging-interceptor/src/log.decorator.ts @@ -31,7 +31,7 @@ export interface MaskingOptions { /** * If true, it will disable the header masking. */ - disableHeaderMask?: boolean; + disableHeaderMasking?: boolean; } /** diff --git a/packages/logging-interceptor/src/logging.interceptor.ts b/packages/logging-interceptor/src/logging.interceptor.ts index e28d96d0..e8bca0d2 100644 --- a/packages/logging-interceptor/src/logging.interceptor.ts +++ b/packages/logging-interceptor/src/logging.interceptor.ts @@ -151,7 +151,7 @@ export class LoggingInterceptor implements NestInterceptor { // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions const maskedBody = options?.mask?.request ? this.maskData(body, options.mask.request) : body; // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions - const maskedHeaders = options?.mask?.disableHeaderMask ? headers : this.maskHeaders(headers); + const maskedHeaders = options?.mask?.disableHeaderMasking ? headers : this.maskHeaders(headers); this.logger.log( { diff --git a/packages/logging-interceptor/test/test-app/cats/cats.controller.ts b/packages/logging-interceptor/test/test-app/cats/cats.controller.ts index 2017bb20..3131852b 100644 --- a/packages/logging-interceptor/test/test-app/cats/cats.controller.ts +++ b/packages/logging-interceptor/test/test-app/cats/cats.controller.ts @@ -53,7 +53,7 @@ export class CatsController { mask: { request: ['birthdate', 'interests.description', 'address', 'enemies'], response: ['id', 'birthdate', 'interests.description', 'address', 'enemies'], - disableHeaderMask: true, + disableHeaderMasking: true, }, }) public createCatUnmaskedHeader(@Body() payload: CreateCatDto) {