mirror of
https://github.com/KevinMidboe/immich.git
synced 2025-10-29 17:40:28 +00:00
fix(server): more asset upload validation and docs (#1720)
* fix(server): more asset upload validation and docs * remove unused DTO * changed Object.keys() to Object.values() * apply patch to openapi generator for web * revert CreateAssetDto assetType enum * resolve merge conflict * Revert "resolve merge conflict" This reverts commit 0e0080518759a05d029f2f7a761537c58cb586d0.
This commit is contained in:
@@ -16,6 +16,7 @@ import {
|
||||
UploadedFiles,
|
||||
Patch,
|
||||
StreamableFile,
|
||||
ParseFilePipe,
|
||||
} from '@nestjs/common';
|
||||
import { Authenticated } from '../../decorators/authenticated.decorator';
|
||||
import { AssetService } from './asset.service';
|
||||
@@ -31,7 +32,6 @@ import { CuratedObjectsResponseDto } from './response-dto/curated-objects-respon
|
||||
import { CuratedLocationsResponseDto } from './response-dto/curated-locations-response.dto';
|
||||
import { AssetResponseDto, ImmichReadStream } from '@app/domain';
|
||||
import { CheckDuplicateAssetResponseDto } from './response-dto/check-duplicate-asset-response.dto';
|
||||
import { AssetFileUploadDto } from './dto/asset-file-upload.dto';
|
||||
import { CreateAssetDto, mapToUploadFile } from './dto/create-asset.dto';
|
||||
import { AssetFileUploadResponseDto } from './response-dto/asset-file-upload-response.dto';
|
||||
import { DeleteAssetResponseDto } from './response-dto/delete-asset-response.dto';
|
||||
@@ -55,6 +55,7 @@ import { SharedLinkResponseDto } from '@app/domain';
|
||||
import { UpdateAssetsToSharedLinkDto } from './dto/add-assets-to-shared-link.dto';
|
||||
import { AssetSearchDto } from './dto/asset-search.dto';
|
||||
import { assetUploadOption, ImmichFile } from '../../config/asset-upload.config';
|
||||
import FileNotEmptyValidator from '../validation/file-not-empty-validator';
|
||||
|
||||
function asStreamableFile({ stream, type, length }: ImmichReadStream) {
|
||||
return new StreamableFile(stream, { type, length });
|
||||
@@ -80,12 +81,13 @@ export class AssetController {
|
||||
@ApiConsumes('multipart/form-data')
|
||||
@ApiBody({
|
||||
description: 'Asset Upload Information',
|
||||
type: AssetFileUploadDto,
|
||||
type: CreateAssetDto,
|
||||
})
|
||||
async uploadFile(
|
||||
@GetAuthUser() authUser: AuthUserDto,
|
||||
@UploadedFiles() files: { assetData: ImmichFile[]; livePhotoData?: ImmichFile[] },
|
||||
@Body(ValidationPipe) dto: CreateAssetDto,
|
||||
@UploadedFiles(new ParseFilePipe({ validators: [new FileNotEmptyValidator(['assetData'])] }))
|
||||
files: { assetData: ImmichFile[]; livePhotoData?: ImmichFile[] },
|
||||
@Body(new ValidationPipe()) dto: CreateAssetDto,
|
||||
@Response({ passthrough: true }) res: Res,
|
||||
): Promise<AssetFileUploadResponseDto> {
|
||||
const file = mapToUploadFile(files.assetData[0]);
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsNotEmpty } from 'class-validator';
|
||||
|
||||
export class AssetFileUploadDto {
|
||||
@IsNotEmpty()
|
||||
@ApiProperty({ type: 'string', format: 'binary' })
|
||||
assetData!: any;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AssetType } from '@app/infra';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsBoolean, IsNotEmpty, IsOptional } from 'class-validator';
|
||||
import { IsBoolean, IsEnum, IsNotEmpty, IsOptional } from 'class-validator';
|
||||
import { ImmichFile } from '../../../config/asset-upload.config';
|
||||
|
||||
export class CreateAssetDto {
|
||||
@@ -11,6 +11,7 @@ export class CreateAssetDto {
|
||||
deviceId!: string;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsEnum(AssetType)
|
||||
@ApiProperty({ enumName: 'AssetTypeEnum', enum: AssetType })
|
||||
assetType!: AssetType;
|
||||
|
||||
@@ -32,6 +33,14 @@ export class CreateAssetDto {
|
||||
|
||||
@IsOptional()
|
||||
duration?: string;
|
||||
|
||||
// The properties below are added to correctly generate the API docs
|
||||
// and client SDKs. Validation should be handled in the controller.
|
||||
@ApiProperty({ type: 'string', format: 'binary' })
|
||||
assetData!: any;
|
||||
|
||||
@ApiProperty({ type: 'string', format: 'binary' })
|
||||
livePhotoData?: any;
|
||||
}
|
||||
|
||||
export interface UploadFile {
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import { FileValidator, Injectable } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
export default class FileNotEmptyValidator extends FileValidator {
|
||||
requiredFields: string[];
|
||||
|
||||
constructor(requiredFields: string[]) {
|
||||
super({});
|
||||
this.requiredFields = requiredFields;
|
||||
}
|
||||
|
||||
isValid(files?: any): boolean {
|
||||
if (!files) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.requiredFields.every((field) => {
|
||||
return files[field];
|
||||
});
|
||||
}
|
||||
|
||||
buildErrorMessage(): string {
|
||||
return `Field(s) ${this.requiredFields.join(', ')} should not be empty`;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user