mirror of
https://github.com/KevinMidboe/immich.git
synced 2025-12-29 21:21:16 +00:00
refactor(server): upload config (#3148)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { BadRequestException } from '@nestjs/common';
|
||||
import { BadRequestException, UnauthorizedException } from '@nestjs/common';
|
||||
import { AuthUserDto } from '../auth';
|
||||
import { IAccessRepository } from './access.repository';
|
||||
|
||||
@@ -25,6 +25,13 @@ export enum Permission {
|
||||
export class AccessCore {
|
||||
constructor(private repository: IAccessRepository) {}
|
||||
|
||||
requireUploadAccess(authUser: AuthUserDto | null): AuthUserDto {
|
||||
if (!authUser || (authUser.isPublicUser && !authUser.isAllowUpload)) {
|
||||
throw new UnauthorizedException();
|
||||
}
|
||||
return authUser;
|
||||
}
|
||||
|
||||
async requirePermission(authUser: AuthUserDto, permission: Permission, ids: string[] | string) {
|
||||
const hasAccess = await this.hasPermission(authUser, permission, ids);
|
||||
if (!hasAccess) {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { AssetEntity } from '@app/infra/entities';
|
||||
import { BadRequestException, Inject } from '@nestjs/common';
|
||||
import { DateTime } from 'luxon';
|
||||
import { extname } from 'path';
|
||||
import { AssetEntity } from '../../infra/entities/asset.entity';
|
||||
import { AccessCore, IAccessRepository, Permission } from '../access';
|
||||
import { AuthUserDto } from '../auth';
|
||||
import { HumanReadableSize, usePagination } from '../domain.util';
|
||||
import { AccessCore, IAccessRepository, Permission } from '../index';
|
||||
import { ImmichReadStream, IStorageRepository } from '../storage';
|
||||
import { IAssetRepository } from './asset.repository';
|
||||
import { AssetIdsDto, DownloadArchiveInfo, DownloadDto, DownloadResponseDto, MemoryLaneDto } from './dto';
|
||||
@@ -12,6 +12,20 @@ import { MapMarkerDto } from './dto/map-marker.dto';
|
||||
import { mapAsset, MapMarkerResponseDto } from './response-dto';
|
||||
import { MemoryLaneResponseDto } from './response-dto/memory-lane-response.dto';
|
||||
|
||||
export enum UploadFieldName {
|
||||
ASSET_DATA = 'assetData',
|
||||
LIVE_PHOTO_DATA = 'livePhotoData',
|
||||
SIDECAR_DATA = 'sidecarData',
|
||||
PROFILE_DATA = 'file',
|
||||
}
|
||||
|
||||
export interface UploadFile {
|
||||
mimeType: string;
|
||||
checksum: Buffer;
|
||||
originalPath: string;
|
||||
originalName: string;
|
||||
}
|
||||
|
||||
export class AssetService {
|
||||
private access: AccessCore;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ export const ICryptoRepository = 'ICryptoRepository';
|
||||
|
||||
export interface ICryptoRepository {
|
||||
randomBytes(size: number): Buffer;
|
||||
randomUUID(): string;
|
||||
hashFile(filePath: string): Promise<Buffer>;
|
||||
hashSha256(data: string): string;
|
||||
hashBcrypt(data: string | Buffer, saltOrRounds: string | number): Promise<string>;
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import { validMimeTypes } from './domain.constant';
|
||||
|
||||
describe('valid mime types', () => {
|
||||
it('should be a sorted list', () => {
|
||||
expect(validMimeTypes).toEqual(validMimeTypes.sort());
|
||||
});
|
||||
|
||||
it('should contain only unique values', () => {
|
||||
expect(validMimeTypes).toEqual([...new Set(validMimeTypes)]);
|
||||
});
|
||||
|
||||
it('should contain only image or video mime types', () => {
|
||||
expect(validMimeTypes).toEqual(
|
||||
validMimeTypes.filter((mimeType) => mimeType.startsWith('image/') || mimeType.startsWith('video/')),
|
||||
);
|
||||
});
|
||||
|
||||
it('should contain only lowercase mime types', () => {
|
||||
expect(validMimeTypes).toEqual(validMimeTypes.map((mimeType) => mimeType.toLowerCase()));
|
||||
});
|
||||
});
|
||||
@@ -28,7 +28,7 @@ export function assertMachineLearningEnabled() {
|
||||
}
|
||||
}
|
||||
|
||||
export const validMimeTypes = [
|
||||
export const ASSET_MIME_TYPES = [
|
||||
'image/3fr',
|
||||
'image/ari',
|
||||
'image/arw',
|
||||
@@ -106,11 +106,14 @@ export const validMimeTypes = [
|
||||
'video/x-ms-wmv',
|
||||
'video/x-msvideo',
|
||||
];
|
||||
|
||||
export function isSupportedFileType(mimetype: string): boolean {
|
||||
return validMimeTypes.includes(mimetype);
|
||||
}
|
||||
|
||||
export function isSidecarFileType(mimeType: string): boolean {
|
||||
return ['application/xml', 'text/xml'].includes(mimeType);
|
||||
}
|
||||
export const LIVE_PHOTO_MIME_TYPES = ASSET_MIME_TYPES;
|
||||
export const SIDECAR_MIME_TYPES = ['application/xml', 'text/xml'];
|
||||
export const PROFILE_MIME_TYPES = [
|
||||
'image/jpeg',
|
||||
'image/png',
|
||||
'image/heic',
|
||||
'image/heif',
|
||||
'image/dng',
|
||||
'image/webp',
|
||||
'image/avif',
|
||||
];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Express } from 'express';
|
||||
import { UploadFieldName } from '../../asset/asset.service';
|
||||
|
||||
export class CreateProfileImageDto {
|
||||
@ApiProperty({ type: 'string', format: 'binary' })
|
||||
file!: Express.Multer.File;
|
||||
[UploadFieldName.PROFILE_DATA]!: Express.Multer.File;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user