From 59a235ebc4cb1210bea951ab62f71d36b4246ff2 Mon Sep 17 00:00:00 2001 From: David Mehren Date: Sat, 5 Mar 2022 12:02:13 +0100 Subject: [PATCH] fix: ensure nested objects are properly validated & transformed To validate nested objects, class-transformer requires the `@ValidateNested` annotation. For arrays, class-transfomer requires setting `each: true`. To correctly transform nested objects from JSON to instances, class-transformer requires the `@Type` annotation. References: https://github.com/typestack/class-validator#validating-nested-objects https://github.com/typestack/class-validator#validating-arrays https://github.com/typestack/class-transformer#working-with-nested-objects Signed-off-by: David Mehren --- src/notes/note-metadata.dto.ts | 8 +++++--- src/notes/note-permissions.dto.ts | 13 +++++++++---- src/notes/note.dto.ts | 2 ++ 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/notes/note-metadata.dto.ts b/src/notes/note-metadata.dto.ts index f76859e43..622bf0984 100644 --- a/src/notes/note-metadata.dto.ts +++ b/src/notes/note-metadata.dto.ts @@ -4,6 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; import { IsArray, IsDate, @@ -104,14 +105,15 @@ export class NoteMetadataDto extends BaseDto { * @example "['john.smith', 'jane.smith']" */ @IsArray() - @ValidateNested() + @IsString({ each: true }) @ApiProperty() - editedBy: UserInfoDto['username'][]; + editedBy: string[]; /** * Permissions currently in effect for the note */ - @ValidateNested() + @ValidateNested({ each: true }) + @Type(() => NotePermissionsDto) @ApiProperty({ type: NotePermissionsDto }) permissions: NotePermissionsDto; } diff --git a/src/notes/note-permissions.dto.ts b/src/notes/note-permissions.dto.ts index 4626d2ddb..56424f68a 100644 --- a/src/notes/note-permissions.dto.ts +++ b/src/notes/note-permissions.dto.ts @@ -4,6 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; import { IsArray, IsBoolean, @@ -96,16 +97,18 @@ export class NotePermissionsDto { /** * List of users the note is shared with */ - @ValidateNested() + @ValidateNested({ each: true }) @IsArray() + @Type(() => NoteUserPermissionEntryDto) @ApiProperty({ isArray: true, type: NoteUserPermissionEntryDto }) sharedToUsers: NoteUserPermissionEntryDto[]; /** * List of groups the note is shared with */ - @ValidateNested() + @ValidateNested({ each: true }) @IsArray() + @Type(() => NoteGroupPermissionEntryDto) @ApiProperty({ isArray: true, type: NoteGroupPermissionEntryDto }) sharedToGroups: NoteGroupPermissionEntryDto[]; } @@ -115,7 +118,8 @@ export class NotePermissionsUpdateDto { * List of users the note should be shared with */ @IsArray() - @ValidateNested() + @ValidateNested({ each: true }) + @Type(() => NoteUserPermissionUpdateDto) @ApiProperty({ isArray: true, type: NoteUserPermissionUpdateDto }) sharedToUsers: NoteUserPermissionUpdateDto[]; @@ -123,7 +127,8 @@ export class NotePermissionsUpdateDto { * List of groups the note should be shared with */ @IsArray() - @ValidateNested() + @ValidateNested({ each: true }) + @Type(() => NoteGroupPermissionUpdateDto) @ApiProperty({ isArray: true, type: NoteGroupPermissionUpdateDto }) sharedToGroups: NoteGroupPermissionUpdateDto[]; } diff --git a/src/notes/note.dto.ts b/src/notes/note.dto.ts index 2a988e93c..ddba4d72e 100644 --- a/src/notes/note.dto.ts +++ b/src/notes/note.dto.ts @@ -4,6 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { ApiProperty } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; import { IsArray, IsString, ValidateNested } from 'class-validator'; import { EditDto } from '../revisions/edit.dto'; @@ -31,6 +32,7 @@ export class NoteDto extends BaseDto { */ @IsArray() @ValidateNested({ each: true }) + @Type(() => EditDto) @ApiProperty({ isArray: true, type: EditDto }) editedByAtPosition: EditDto[]; }