From 470b32ed5ecb682f6edf67136d69851075f94f3c Mon Sep 17 00:00:00 2001 From: Philip Molares Date: Tue, 30 Nov 2021 22:20:49 +0100 Subject: [PATCH] feat: refactor get note pipe to interceptor This is necessary, because of the order of operations in nestjs, the validation pipe is not able to get the note as the noteIdOrAlias will be transformed by the get note pipe after the validation did run. Signed-off-by: Philip Molares --- ...t-note.pipe.ts => get-note.interceptor.ts} | 34 ++++++++++++------- src/api/utils/permissions.guard.ts | 4 +-- 2 files changed, 24 insertions(+), 14 deletions(-) rename src/api/utils/{get-note.pipe.ts => get-note.interceptor.ts} (52%) diff --git a/src/api/utils/get-note.pipe.ts b/src/api/utils/get-note.interceptor.ts similarity index 52% rename from src/api/utils/get-note.pipe.ts rename to src/api/utils/get-note.interceptor.ts index 8790e326a..80d98aa13 100644 --- a/src/api/utils/get-note.pipe.ts +++ b/src/api/utils/get-note.interceptor.ts @@ -4,29 +4,39 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { - ArgumentMetadata, BadRequestException, + CallHandler, + ExecutionContext, Injectable, + NestInterceptor, NotFoundException, - PipeTransform, } from '@nestjs/common'; +import { Request } from 'express'; +import { Observable } from 'rxjs'; import { ForbiddenIdError, NotInDBError } from '../../errors/errors'; -import { ConsoleLoggerService } from '../../logger/console-logger.service'; import { Note } from '../../notes/note.entity'; import { NotesService } from '../../notes/notes.service'; +import { User } from '../../users/user.entity'; +/** + * Saves the note identified by the `noteIdOrAlias` URL parameter + * under the `note` property of the request object. + */ @Injectable() -export class GetNotePipe implements PipeTransform> { - constructor( - private readonly logger: ConsoleLoggerService, - private noteService: NotesService, - ) { - this.logger.setContext(GetNotePipe.name); - } +export class GetNoteInterceptor implements NestInterceptor { + constructor(private noteService: NotesService) {} - async transform(noteIdOrAlias: string, _: ArgumentMetadata): Promise { - return await getNote(this.noteService, noteIdOrAlias); + async intercept( + context: ExecutionContext, + next: CallHandler, + ): Promise> { + const request: Request & { user: User; note: Note } = context + .switchToHttp() + .getRequest(); + const noteIdOrAlias = request.params['noteIdOrAlias']; + request.note = await getNote(this.noteService, noteIdOrAlias); + return next.handle(); } } diff --git a/src/api/utils/permissions.guard.ts b/src/api/utils/permissions.guard.ts index 5206f1c48..bdbe95ee5 100644 --- a/src/api/utils/permissions.guard.ts +++ b/src/api/utils/permissions.guard.ts @@ -12,7 +12,7 @@ import { NotesService } from '../../notes/notes.service'; import { Permission } from '../../permissions/permissions.enum'; import { PermissionsService } from '../../permissions/permissions.service'; import { User } from '../../users/user.entity'; -import { getNote } from './get-note.pipe'; +import { getNote } from './get-note.interceptor'; /** * This guards controller methods from access, if the user has not the appropriate permissions. @@ -50,7 +50,7 @@ export class PermissionsGuard implements CanActivate { return this.permissionsService.mayCreate(user); } // Get the note from the parameter noteIdOrAlias - // Attention: This gets the note an additional time if used in conjunction with GetNotePipe + // Attention: This gets the note an additional time if used in conjunction with GetNoteInterceptor const noteIdOrAlias = request.params['noteIdOrAlias']; const note = await getNote(this.noteService, noteIdOrAlias); switch (permissions[0]) {