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 <philip.molares@udo.edu>
This commit is contained in:
Philip Molares 2021-11-30 22:20:49 +01:00 committed by David Mehren
parent 0cb3b65998
commit 470b32ed5e
No known key found for this signature in database
GPG key ID: 185982BA4C42B7C3
2 changed files with 24 additions and 14 deletions

View file

@ -4,29 +4,39 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
import { import {
ArgumentMetadata,
BadRequestException, BadRequestException,
CallHandler,
ExecutionContext,
Injectable, Injectable,
NestInterceptor,
NotFoundException, NotFoundException,
PipeTransform,
} from '@nestjs/common'; } from '@nestjs/common';
import { Request } from 'express';
import { Observable } from 'rxjs';
import { ForbiddenIdError, NotInDBError } from '../../errors/errors'; import { ForbiddenIdError, NotInDBError } from '../../errors/errors';
import { ConsoleLoggerService } from '../../logger/console-logger.service';
import { Note } from '../../notes/note.entity'; import { Note } from '../../notes/note.entity';
import { NotesService } from '../../notes/notes.service'; 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() @Injectable()
export class GetNotePipe implements PipeTransform<string, Promise<Note>> { export class GetNoteInterceptor implements NestInterceptor {
constructor( constructor(private noteService: NotesService) {}
private readonly logger: ConsoleLoggerService,
private noteService: NotesService,
) {
this.logger.setContext(GetNotePipe.name);
}
async transform(noteIdOrAlias: string, _: ArgumentMetadata): Promise<Note> { async intercept<T>(
return await getNote(this.noteService, noteIdOrAlias); context: ExecutionContext,
next: CallHandler,
): Promise<Observable<T>> {
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();
} }
} }

View file

@ -12,7 +12,7 @@ import { NotesService } from '../../notes/notes.service';
import { Permission } from '../../permissions/permissions.enum'; import { Permission } from '../../permissions/permissions.enum';
import { PermissionsService } from '../../permissions/permissions.service'; import { PermissionsService } from '../../permissions/permissions.service';
import { User } from '../../users/user.entity'; 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. * 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); return this.permissionsService.mayCreate(user);
} }
// Get the note from the parameter noteIdOrAlias // 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 noteIdOrAlias = request.params['noteIdOrAlias'];
const note = await getNote(this.noteService, noteIdOrAlias); const note = await getNote(this.noteService, noteIdOrAlias);
switch (permissions[0]) { switch (permissions[0]) {