mirror of
				https://github.com/immich-app/immich.git
				synced 2025-10-31 10:37:11 -04:00 
			
		
		
		
	feat(server): improve validation in controllers (#2149)
* feat(server): improve validation in controllers * set ValidationPipe config with decorator
This commit is contained in:
		
							parent
							
								
									ed551500e7
								
							
						
					
					
						commit
						c584791b65
					
				| @ -1,14 +1,15 @@ | ||||
| import { AlbumService, AuthUserDto } from '@app/domain'; | ||||
| import { GetAlbumsDto } from '@app/domain/album/dto/get-albums.dto'; | ||||
| import { Controller, Get, Query, UsePipes, ValidationPipe } from '@nestjs/common'; | ||||
| import { Controller, Get, Query } from '@nestjs/common'; | ||||
| import { ApiTags } from '@nestjs/swagger'; | ||||
| import { GetAuthUser } from '../decorators/auth-user.decorator'; | ||||
| import { Authenticated } from '../decorators/authenticated.decorator'; | ||||
| import { UseValidation } from '../decorators/use-validation.decorator'; | ||||
| 
 | ||||
| @ApiTags('Album') | ||||
| @Controller('album') | ||||
| @Authenticated() | ||||
| @UsePipes(new ValidationPipe({ transform: true })) | ||||
| @UseValidation() | ||||
| export class AlbumController { | ||||
|   constructor(private service: AlbumService) {} | ||||
| 
 | ||||
|  | ||||
| @ -6,15 +6,16 @@ import { | ||||
|   APIKeyUpdateDto, | ||||
|   AuthUserDto, | ||||
| } from '@app/domain'; | ||||
| import { Body, Controller, Delete, Get, Param, Post, Put, UsePipes, ValidationPipe } from '@nestjs/common'; | ||||
| import { Body, Controller, Delete, Get, Param, Post, Put } from '@nestjs/common'; | ||||
| import { ApiTags } from '@nestjs/swagger'; | ||||
| import { GetAuthUser } from '../decorators/auth-user.decorator'; | ||||
| import { Authenticated } from '../decorators/authenticated.decorator'; | ||||
| import { UseValidation } from '../decorators/use-validation.decorator'; | ||||
| 
 | ||||
| @ApiTags('API Key') | ||||
| @Controller('api-key') | ||||
| @Authenticated() | ||||
| @UsePipes(new ValidationPipe({ transform: true })) | ||||
| @UseValidation() | ||||
| export class APIKeyController { | ||||
|   constructor(private service: APIKeyService) {} | ||||
| 
 | ||||
|  | ||||
| @ -13,15 +13,16 @@ import { | ||||
|   UserResponseDto, | ||||
|   ValidateAccessTokenResponseDto, | ||||
| } from '@app/domain'; | ||||
| import { Body, Controller, Ip, Post, Req, Res, UsePipes, ValidationPipe } from '@nestjs/common'; | ||||
| import { Body, Controller, Ip, Post, Req, Res } from '@nestjs/common'; | ||||
| import { ApiBadRequestResponse, ApiTags } from '@nestjs/swagger'; | ||||
| import { Request, Response } from 'express'; | ||||
| import { GetAuthUser } from '../decorators/auth-user.decorator'; | ||||
| import { Authenticated } from '../decorators/authenticated.decorator'; | ||||
| import { UseValidation } from '../decorators/use-validation.decorator'; | ||||
| 
 | ||||
| @ApiTags('Authentication') | ||||
| @Controller('auth') | ||||
| @UsePipes(new ValidationPipe({ transform: true })) | ||||
| @UseValidation() | ||||
| export class AuthController { | ||||
|   constructor(private readonly service: AuthService) {} | ||||
| 
 | ||||
|  | ||||
| @ -4,15 +4,16 @@ import { | ||||
|   DeviceInfoService, | ||||
|   UpsertDeviceInfoDto as UpsertDto, | ||||
| } from '@app/domain'; | ||||
| import { Body, Controller, Put, UsePipes, ValidationPipe } from '@nestjs/common'; | ||||
| import { Body, Controller, Put } from '@nestjs/common'; | ||||
| import { ApiTags } from '@nestjs/swagger'; | ||||
| import { GetAuthUser } from '../decorators/auth-user.decorator'; | ||||
| import { Authenticated } from '../decorators/authenticated.decorator'; | ||||
| import { UseValidation } from '../decorators/use-validation.decorator'; | ||||
| 
 | ||||
| @ApiTags('Device Info') | ||||
| @Controller('device-info') | ||||
| @Authenticated() | ||||
| @UsePipes(new ValidationPipe({ transform: true })) | ||||
| @UseValidation() | ||||
| export class DeviceInfoController { | ||||
|   constructor(private readonly service: DeviceInfoService) {} | ||||
| 
 | ||||
|  | ||||
| @ -1,12 +1,13 @@ | ||||
| import { AllJobStatusResponseDto, JobCommandDto, JobStatusDto, JobIdDto, JobService } from '@app/domain'; | ||||
| import { Body, Controller, Get, Param, Put, UsePipes, ValidationPipe } from '@nestjs/common'; | ||||
| import { Body, Controller, Get, Param, Put } from '@nestjs/common'; | ||||
| import { ApiTags } from '@nestjs/swagger'; | ||||
| import { Authenticated } from '../decorators/authenticated.decorator'; | ||||
| import { UseValidation } from '../decorators/use-validation.decorator'; | ||||
| 
 | ||||
| @ApiTags('Job') | ||||
| @Controller('jobs') | ||||
| @Authenticated({ admin: true }) | ||||
| @UsePipes(new ValidationPipe({ transform: true })) | ||||
| @UseValidation() | ||||
| export class JobController { | ||||
|   constructor(private service: JobService) {} | ||||
| 
 | ||||
|  | ||||
| @ -7,15 +7,16 @@ import { | ||||
|   OAuthService, | ||||
|   UserResponseDto, | ||||
| } from '@app/domain'; | ||||
| import { Body, Controller, Get, HttpStatus, Post, Redirect, Req, Res, UsePipes, ValidationPipe } from '@nestjs/common'; | ||||
| import { Body, Controller, Get, HttpStatus, Post, Redirect, Req, Res } from '@nestjs/common'; | ||||
| import { ApiTags } from '@nestjs/swagger'; | ||||
| import { Request, Response } from 'express'; | ||||
| import { GetAuthUser } from '../decorators/auth-user.decorator'; | ||||
| import { Authenticated } from '../decorators/authenticated.decorator'; | ||||
| import { UseValidation } from '../decorators/use-validation.decorator'; | ||||
| 
 | ||||
| @ApiTags('OAuth') | ||||
| @Controller('oauth') | ||||
| @UsePipes(new ValidationPipe({ transform: true })) | ||||
| @UseValidation() | ||||
| export class OAuthController { | ||||
|   constructor(private service: OAuthService) {} | ||||
| 
 | ||||
|  | ||||
| @ -6,15 +6,16 @@ import { | ||||
|   SearchResponseDto, | ||||
|   SearchService, | ||||
| } from '@app/domain'; | ||||
| import { Controller, Get, Query, UsePipes, ValidationPipe } from '@nestjs/common'; | ||||
| import { Controller, Get, Query } from '@nestjs/common'; | ||||
| import { ApiTags } from '@nestjs/swagger'; | ||||
| import { GetAuthUser } from '../decorators/auth-user.decorator'; | ||||
| import { Authenticated } from '../decorators/authenticated.decorator'; | ||||
| import { UseValidation } from '../decorators/use-validation.decorator'; | ||||
| 
 | ||||
| @ApiTags('Search') | ||||
| @Controller('search') | ||||
| @Authenticated() | ||||
| @UsePipes(new ValidationPipe({ transform: true })) | ||||
| @UseValidation() | ||||
| export class SearchController { | ||||
|   constructor(private service: SearchService) {} | ||||
| 
 | ||||
|  | ||||
| @ -5,13 +5,14 @@ import { | ||||
|   ServerStatsResponseDto, | ||||
|   ServerVersionReponseDto, | ||||
| } from '@app/domain'; | ||||
| import { Controller, Get, UsePipes, ValidationPipe } from '@nestjs/common'; | ||||
| import { Controller, Get } from '@nestjs/common'; | ||||
| import { ApiTags } from '@nestjs/swagger'; | ||||
| import { Authenticated } from '../decorators/authenticated.decorator'; | ||||
| import { UseValidation } from '../decorators/use-validation.decorator'; | ||||
| 
 | ||||
| @ApiTags('Server Info') | ||||
| @Controller('server-info') | ||||
| @UsePipes(new ValidationPipe({ transform: true })) | ||||
| @UseValidation() | ||||
| export class ServerInfoController { | ||||
|   constructor(private service: ServerInfoService) {} | ||||
| 
 | ||||
|  | ||||
| @ -1,12 +1,13 @@ | ||||
| import { AuthUserDto, EditSharedLinkDto, SharedLinkResponseDto, ShareService } from '@app/domain'; | ||||
| import { Body, Controller, Delete, Get, Param, Patch, UsePipes, ValidationPipe } from '@nestjs/common'; | ||||
| import { Body, Controller, Delete, Get, Param, Patch } from '@nestjs/common'; | ||||
| import { ApiTags } from '@nestjs/swagger'; | ||||
| import { GetAuthUser } from '../decorators/auth-user.decorator'; | ||||
| import { Authenticated } from '../decorators/authenticated.decorator'; | ||||
| import { UseValidation } from '../decorators/use-validation.decorator'; | ||||
| 
 | ||||
| @ApiTags('share') | ||||
| @Controller('share') | ||||
| @UsePipes(new ValidationPipe({ transform: true })) | ||||
| @UseValidation() | ||||
| export class ShareController { | ||||
|   constructor(private readonly service: ShareService) {} | ||||
| 
 | ||||
|  | ||||
| @ -1,12 +1,13 @@ | ||||
| import { SystemConfigDto, SystemConfigService, SystemConfigTemplateStorageOptionDto } from '@app/domain'; | ||||
| import { Body, Controller, Get, Put, UsePipes, ValidationPipe } from '@nestjs/common'; | ||||
| import { Body, Controller, Get, Put } from '@nestjs/common'; | ||||
| import { ApiTags } from '@nestjs/swagger'; | ||||
| import { Authenticated } from '../decorators/authenticated.decorator'; | ||||
| import { UseValidation } from '../decorators/use-validation.decorator'; | ||||
| 
 | ||||
| @ApiTags('System Config') | ||||
| @Controller('system-config') | ||||
| @Authenticated({ admin: true }) | ||||
| @UsePipes(new ValidationPipe({ transform: true })) | ||||
| @UseValidation() | ||||
| export class SystemConfigController { | ||||
|   constructor(private readonly service: SystemConfigService) {} | ||||
| 
 | ||||
|  | ||||
| @ -5,7 +5,6 @@ import { | ||||
|   Delete, | ||||
|   Body, | ||||
|   Param, | ||||
|   ValidationPipe, | ||||
|   Put, | ||||
|   Query, | ||||
|   UseInterceptors, | ||||
| @ -13,7 +12,6 @@ import { | ||||
|   Response, | ||||
|   StreamableFile, | ||||
|   Header, | ||||
|   UsePipes, | ||||
| } from '@nestjs/common'; | ||||
| import { UserService } from '@app/domain'; | ||||
| import { Authenticated } from '../decorators/authenticated.decorator'; | ||||
| @ -29,10 +27,11 @@ import { UserCountResponseDto } from '@app/domain'; | ||||
| import { CreateProfileImageDto } from '@app/domain'; | ||||
| import { CreateProfileImageResponseDto } from '@app/domain'; | ||||
| import { UserCountDto } from '@app/domain'; | ||||
| import { UseValidation } from '../decorators/use-validation.decorator'; | ||||
| 
 | ||||
| @ApiTags('User') | ||||
| @Controller('user') | ||||
| @UsePipes(new ValidationPipe({ transform: true, whitelist: true })) | ||||
| @UseValidation() | ||||
| export class UserController { | ||||
|   constructor(private service: UserService) {} | ||||
| 
 | ||||
|  | ||||
| @ -0,0 +1,12 @@ | ||||
| import { applyDecorators, UsePipes, ValidationPipe } from '@nestjs/common'; | ||||
| 
 | ||||
| export function UseValidation() { | ||||
|   return applyDecorators( | ||||
|     UsePipes( | ||||
|       new ValidationPipe({ | ||||
|         transform: true, | ||||
|         whitelist: true, | ||||
|       }), | ||||
|     ), | ||||
|   ); | ||||
| } | ||||
| @ -1,21 +1,30 @@ | ||||
| import { SystemConfig } from '@app/infra/entities'; | ||||
| import { ValidateNested } from 'class-validator'; | ||||
| import { Type } from 'class-transformer'; | ||||
| import { IsObject, ValidateNested } from 'class-validator'; | ||||
| import { SystemConfigFFmpegDto } from './system-config-ffmpeg.dto'; | ||||
| import { SystemConfigOAuthDto } from './system-config-oauth.dto'; | ||||
| import { SystemConfigPasswordLoginDto } from './system-config-password-login.dto'; | ||||
| import { SystemConfigStorageTemplateDto } from './system-config-storage-template.dto'; | ||||
| 
 | ||||
| export class SystemConfigDto { | ||||
|   @Type(() => SystemConfigFFmpegDto) | ||||
|   @ValidateNested() | ||||
|   @IsObject() | ||||
|   ffmpeg!: SystemConfigFFmpegDto; | ||||
| 
 | ||||
|   @Type(() => SystemConfigOAuthDto) | ||||
|   @ValidateNested() | ||||
|   @IsObject() | ||||
|   oauth!: SystemConfigOAuthDto; | ||||
| 
 | ||||
|   @Type(() => SystemConfigPasswordLoginDto) | ||||
|   @ValidateNested() | ||||
|   @IsObject() | ||||
|   passwordLogin!: SystemConfigPasswordLoginDto; | ||||
| 
 | ||||
|   @Type(() => SystemConfigStorageTemplateDto) | ||||
|   @ValidateNested() | ||||
|   @IsObject() | ||||
|   storageTemplate!: SystemConfigStorageTemplateDto; | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user