From 51785a1ead3e93211e01336feb35cb9fbff3d841 Mon Sep 17 00:00:00 2001 From: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> Date: Fri, 31 Mar 2023 17:14:01 +0200 Subject: [PATCH] feat(server): apply ValidationPipe on controllers (#2137) --- .../immich/src/controllers/album.controller.ts | 8 +++----- .../src/controllers/api-key.controller.ts | 10 ++++------ .../immich/src/controllers/auth.controller.ts | 9 ++++----- .../src/controllers/device-info.controller.ts | 5 +++-- .../immich/src/controllers/job.controller.ts | 5 +++-- .../immich/src/controllers/oauth.controller.ts | 9 +++++---- .../immich/src/controllers/search.controller.ts | 8 +++----- .../src/controllers/server-info.controller.ts | 3 ++- .../immich/src/controllers/share.controller.ts | 5 +++-- .../src/controllers/system-config.controller.ts | 5 +++-- .../immich/src/controllers/user.controller.ts | 17 ++++++----------- 11 files changed, 39 insertions(+), 45 deletions(-) diff --git a/server/apps/immich/src/controllers/album.controller.ts b/server/apps/immich/src/controllers/album.controller.ts index 01a1ebee7d..0680fd318c 100644 --- a/server/apps/immich/src/controllers/album.controller.ts +++ b/server/apps/immich/src/controllers/album.controller.ts @@ -1,6 +1,6 @@ import { AlbumService, AuthUserDto } from '@app/domain'; import { GetAlbumsDto } from '@app/domain/album/dto/get-albums.dto'; -import { Controller, Get, Query, ValidationPipe } from '@nestjs/common'; +import { Controller, Get, Query, UsePipes, ValidationPipe } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; import { GetAuthUser } from '../decorators/auth-user.decorator'; import { Authenticated } from '../decorators/authenticated.decorator'; @@ -8,14 +8,12 @@ import { Authenticated } from '../decorators/authenticated.decorator'; @ApiTags('Album') @Controller('album') @Authenticated() +@UsePipes(new ValidationPipe({ transform: true })) export class AlbumController { constructor(private service: AlbumService) {} @Get() - async getAllAlbums( - @GetAuthUser() authUser: AuthUserDto, - @Query(new ValidationPipe({ transform: true })) query: GetAlbumsDto, - ) { + async getAllAlbums(@GetAuthUser() authUser: AuthUserDto, @Query() query: GetAlbumsDto) { return this.service.getAllAlbums(authUser, query); } } diff --git a/server/apps/immich/src/controllers/api-key.controller.ts b/server/apps/immich/src/controllers/api-key.controller.ts index 5f8e59a7ba..9804a72029 100644 --- a/server/apps/immich/src/controllers/api-key.controller.ts +++ b/server/apps/immich/src/controllers/api-key.controller.ts @@ -6,7 +6,7 @@ import { APIKeyUpdateDto, AuthUserDto, } from '@app/domain'; -import { Body, Controller, Delete, Get, Param, Post, Put, ValidationPipe } from '@nestjs/common'; +import { Body, Controller, Delete, Get, Param, Post, Put, UsePipes, ValidationPipe } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; import { GetAuthUser } from '../decorators/auth-user.decorator'; import { Authenticated } from '../decorators/authenticated.decorator'; @@ -14,14 +14,12 @@ import { Authenticated } from '../decorators/authenticated.decorator'; @ApiTags('API Key') @Controller('api-key') @Authenticated() +@UsePipes(new ValidationPipe({ transform: true })) export class APIKeyController { constructor(private service: APIKeyService) {} @Post() - createKey( - @GetAuthUser() authUser: AuthUserDto, - @Body(ValidationPipe) dto: APIKeyCreateDto, - ): Promise { + createKey(@GetAuthUser() authUser: AuthUserDto, @Body() dto: APIKeyCreateDto): Promise { return this.service.create(authUser, dto); } @@ -39,7 +37,7 @@ export class APIKeyController { updateKey( @GetAuthUser() authUser: AuthUserDto, @Param('id') id: string, - @Body(ValidationPipe) dto: APIKeyUpdateDto, + @Body() dto: APIKeyUpdateDto, ): Promise { return this.service.update(authUser, id, dto); } diff --git a/server/apps/immich/src/controllers/auth.controller.ts b/server/apps/immich/src/controllers/auth.controller.ts index 7a6389242e..55659b2def 100644 --- a/server/apps/immich/src/controllers/auth.controller.ts +++ b/server/apps/immich/src/controllers/auth.controller.ts @@ -13,7 +13,7 @@ import { UserResponseDto, ValidateAccessTokenResponseDto, } from '@app/domain'; -import { Body, Controller, Ip, Post, Req, Res, ValidationPipe } from '@nestjs/common'; +import { Body, Controller, Ip, Post, Req, Res, UsePipes, ValidationPipe } from '@nestjs/common'; import { ApiBadRequestResponse, ApiTags } from '@nestjs/swagger'; import { Request, Response } from 'express'; import { GetAuthUser } from '../decorators/auth-user.decorator'; @@ -21,12 +21,13 @@ import { Authenticated } from '../decorators/authenticated.decorator'; @ApiTags('Authentication') @Controller('auth') +@UsePipes(new ValidationPipe({ transform: true })) export class AuthController { constructor(private readonly service: AuthService) {} @Post('login') async login( - @Body(new ValidationPipe({ transform: true })) loginCredential: LoginCredentialDto, + @Body() loginCredential: LoginCredentialDto, @Ip() clientIp: string, @Req() req: Request, @Res({ passthrough: true }) res: Response, @@ -38,9 +39,7 @@ export class AuthController { @Post('admin-sign-up') @ApiBadRequestResponse({ description: 'The server already has an admin' }) - adminSignUp( - @Body(new ValidationPipe({ transform: true })) signUpCredential: SignUpDto, - ): Promise { + adminSignUp(@Body() signUpCredential: SignUpDto): Promise { return this.service.adminSignUp(signUpCredential); } diff --git a/server/apps/immich/src/controllers/device-info.controller.ts b/server/apps/immich/src/controllers/device-info.controller.ts index 10feea3c2e..755300aab3 100644 --- a/server/apps/immich/src/controllers/device-info.controller.ts +++ b/server/apps/immich/src/controllers/device-info.controller.ts @@ -4,7 +4,7 @@ import { DeviceInfoService, UpsertDeviceInfoDto as UpsertDto, } from '@app/domain'; -import { Body, Controller, Put, ValidationPipe } from '@nestjs/common'; +import { Body, Controller, Put, UsePipes, ValidationPipe } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; import { GetAuthUser } from '../decorators/auth-user.decorator'; import { Authenticated } from '../decorators/authenticated.decorator'; @@ -12,11 +12,12 @@ import { Authenticated } from '../decorators/authenticated.decorator'; @ApiTags('Device Info') @Controller('device-info') @Authenticated() +@UsePipes(new ValidationPipe({ transform: true })) export class DeviceInfoController { constructor(private readonly service: DeviceInfoService) {} @Put() - upsertDeviceInfo(@GetAuthUser() authUser: AuthUserDto, @Body(ValidationPipe) dto: UpsertDto): Promise { + upsertDeviceInfo(@GetAuthUser() authUser: AuthUserDto, @Body() dto: UpsertDto): Promise { return this.service.upsert(authUser, dto); } } diff --git a/server/apps/immich/src/controllers/job.controller.ts b/server/apps/immich/src/controllers/job.controller.ts index b756d6570c..a22f110d9a 100644 --- a/server/apps/immich/src/controllers/job.controller.ts +++ b/server/apps/immich/src/controllers/job.controller.ts @@ -1,11 +1,12 @@ import { AllJobStatusResponseDto, JobCommandDto, JobIdDto, JobService } from '@app/domain'; -import { Body, Controller, Get, Param, Put, ValidationPipe } from '@nestjs/common'; +import { Body, Controller, Get, Param, Put, UsePipes, ValidationPipe } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; import { Authenticated } from '../decorators/authenticated.decorator'; @ApiTags('Job') @Controller('jobs') @Authenticated({ admin: true }) +@UsePipes(new ValidationPipe({ transform: true })) export class JobController { constructor(private service: JobService) {} @@ -15,7 +16,7 @@ export class JobController { } @Put('/:jobId') - sendJobCommand(@Param(ValidationPipe) { jobId }: JobIdDto, @Body(ValidationPipe) dto: JobCommandDto): Promise { + sendJobCommand(@Param() { jobId }: JobIdDto, @Body() dto: JobCommandDto): Promise { return this.service.handleCommand(jobId, dto); } } diff --git a/server/apps/immich/src/controllers/oauth.controller.ts b/server/apps/immich/src/controllers/oauth.controller.ts index a88e8ce0f8..16e0a3b53d 100644 --- a/server/apps/immich/src/controllers/oauth.controller.ts +++ b/server/apps/immich/src/controllers/oauth.controller.ts @@ -7,7 +7,7 @@ import { OAuthService, UserResponseDto, } from '@app/domain'; -import { Body, Controller, Get, HttpStatus, Post, Redirect, Req, Res, ValidationPipe } from '@nestjs/common'; +import { Body, Controller, Get, HttpStatus, Post, Redirect, Req, Res, UsePipes, ValidationPipe } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; import { Request, Response } from 'express'; import { GetAuthUser } from '../decorators/auth-user.decorator'; @@ -15,6 +15,7 @@ import { Authenticated } from '../decorators/authenticated.decorator'; @ApiTags('OAuth') @Controller('oauth') +@UsePipes(new ValidationPipe({ transform: true })) export class OAuthController { constructor(private service: OAuthService) {} @@ -28,14 +29,14 @@ export class OAuthController { } @Post('config') - generateConfig(@Body(ValidationPipe) dto: OAuthConfigDto): Promise { + generateConfig(@Body() dto: OAuthConfigDto): Promise { return this.service.generateConfig(dto); } @Post('callback') async callback( @Res({ passthrough: true }) res: Response, - @Body(ValidationPipe) dto: OAuthCallbackDto, + @Body() dto: OAuthCallbackDto, @Req() req: Request, ): Promise { const { response, cookie } = await this.service.login(dto, req.secure); @@ -45,7 +46,7 @@ export class OAuthController { @Authenticated() @Post('link') - link(@GetAuthUser() authUser: AuthUserDto, @Body(ValidationPipe) dto: OAuthCallbackDto): Promise { + link(@GetAuthUser() authUser: AuthUserDto, @Body() dto: OAuthCallbackDto): Promise { return this.service.link(authUser, dto); } diff --git a/server/apps/immich/src/controllers/search.controller.ts b/server/apps/immich/src/controllers/search.controller.ts index 430f37941c..c9a5cb046d 100644 --- a/server/apps/immich/src/controllers/search.controller.ts +++ b/server/apps/immich/src/controllers/search.controller.ts @@ -6,7 +6,7 @@ import { SearchResponseDto, SearchService, } from '@app/domain'; -import { Controller, Get, Query, ValidationPipe } from '@nestjs/common'; +import { Controller, Get, Query, UsePipes, ValidationPipe } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; import { GetAuthUser } from '../decorators/auth-user.decorator'; import { Authenticated } from '../decorators/authenticated.decorator'; @@ -14,14 +14,12 @@ import { Authenticated } from '../decorators/authenticated.decorator'; @ApiTags('Search') @Controller('search') @Authenticated() +@UsePipes(new ValidationPipe({ transform: true })) export class SearchController { constructor(private service: SearchService) {} @Get() - search( - @GetAuthUser() authUser: AuthUserDto, - @Query(new ValidationPipe({ transform: true })) dto: SearchDto, - ): Promise { + search(@GetAuthUser() authUser: AuthUserDto, @Query() dto: SearchDto): Promise { return this.service.search(authUser, dto); } diff --git a/server/apps/immich/src/controllers/server-info.controller.ts b/server/apps/immich/src/controllers/server-info.controller.ts index 18d364ad66..97c6e30f92 100644 --- a/server/apps/immich/src/controllers/server-info.controller.ts +++ b/server/apps/immich/src/controllers/server-info.controller.ts @@ -5,12 +5,13 @@ import { ServerStatsResponseDto, ServerVersionReponseDto, } from '@app/domain'; -import { Controller, Get } from '@nestjs/common'; +import { Controller, Get, UsePipes, ValidationPipe } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; import { Authenticated } from '../decorators/authenticated.decorator'; @ApiTags('Server Info') @Controller('server-info') +@UsePipes(new ValidationPipe({ transform: true })) export class ServerInfoController { constructor(private service: ServerInfoService) {} diff --git a/server/apps/immich/src/controllers/share.controller.ts b/server/apps/immich/src/controllers/share.controller.ts index 17124b16fc..d6d460a779 100644 --- a/server/apps/immich/src/controllers/share.controller.ts +++ b/server/apps/immich/src/controllers/share.controller.ts @@ -1,11 +1,12 @@ import { AuthUserDto, EditSharedLinkDto, SharedLinkResponseDto, ShareService } from '@app/domain'; -import { Body, Controller, Delete, Get, Param, Patch, ValidationPipe } from '@nestjs/common'; +import { Body, Controller, Delete, Get, Param, Patch, UsePipes, ValidationPipe } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; import { GetAuthUser } from '../decorators/auth-user.decorator'; import { Authenticated } from '../decorators/authenticated.decorator'; @ApiTags('share') @Controller('share') +@UsePipes(new ValidationPipe({ transform: true })) export class ShareController { constructor(private readonly service: ShareService) {} @@ -38,7 +39,7 @@ export class ShareController { editSharedLink( @GetAuthUser() authUser: AuthUserDto, @Param('id') id: string, - @Body(ValidationPipe) dto: EditSharedLinkDto, + @Body() dto: EditSharedLinkDto, ): Promise { return this.service.edit(authUser, id, dto); } diff --git a/server/apps/immich/src/controllers/system-config.controller.ts b/server/apps/immich/src/controllers/system-config.controller.ts index b37587500b..4a5debe40d 100644 --- a/server/apps/immich/src/controllers/system-config.controller.ts +++ b/server/apps/immich/src/controllers/system-config.controller.ts @@ -1,11 +1,12 @@ import { SystemConfigDto, SystemConfigService, SystemConfigTemplateStorageOptionDto } from '@app/domain'; -import { Body, Controller, Get, Put, ValidationPipe } from '@nestjs/common'; +import { Body, Controller, Get, Put, UsePipes, ValidationPipe } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; import { Authenticated } from '../decorators/authenticated.decorator'; @ApiTags('System Config') @Controller('system-config') @Authenticated({ admin: true }) +@UsePipes(new ValidationPipe({ transform: true })) export class SystemConfigController { constructor(private readonly service: SystemConfigService) {} @@ -20,7 +21,7 @@ export class SystemConfigController { } @Put() - updateConfig(@Body(ValidationPipe) dto: SystemConfigDto): Promise { + updateConfig(@Body() dto: SystemConfigDto): Promise { return this.service.updateConfig(dto); } diff --git a/server/apps/immich/src/controllers/user.controller.ts b/server/apps/immich/src/controllers/user.controller.ts index dc749ecaef..d426dff78a 100644 --- a/server/apps/immich/src/controllers/user.controller.ts +++ b/server/apps/immich/src/controllers/user.controller.ts @@ -11,9 +11,9 @@ import { UseInterceptors, UploadedFile, Response, - ParseBoolPipe, StreamableFile, Header, + UsePipes, } from '@nestjs/common'; import { UserService } from '@app/domain'; import { Authenticated } from '../decorators/authenticated.decorator'; @@ -32,15 +32,13 @@ import { UserCountDto } from '@app/domain'; @ApiTags('User') @Controller('user') +@UsePipes(new ValidationPipe({ transform: true })) export class UserController { constructor(private service: UserService) {} @Authenticated() @Get() - getAllUsers( - @GetAuthUser() authUser: AuthUserDto, - @Query('isAll', ParseBoolPipe) isAll: boolean, - ): Promise { + getAllUsers(@GetAuthUser() authUser: AuthUserDto, @Query('isAll') isAll: boolean): Promise { return this.service.getAllUsers(authUser, isAll); } @@ -58,12 +56,12 @@ export class UserController { @Authenticated({ admin: true }) @Post() - createUser(@Body(new ValidationPipe({ transform: true })) createUserDto: CreateUserDto): Promise { + createUser(@Body() createUserDto: CreateUserDto): Promise { return this.service.createUser(createUserDto); } @Get('/count') - getUserCount(@Query(new ValidationPipe({ transform: true })) dto: UserCountDto): Promise { + getUserCount(@Query() dto: UserCountDto): Promise { return this.service.getUserCount(dto); } @@ -81,10 +79,7 @@ export class UserController { @Authenticated() @Put() - updateUser( - @GetAuthUser() authUser: AuthUserDto, - @Body(ValidationPipe) updateUserDto: UpdateUserDto, - ): Promise { + updateUser(@GetAuthUser() authUser: AuthUserDto, @Body() updateUserDto: UpdateUserDto): Promise { return this.service.updateUser(authUser, updateUserDto); }