feat(server): harden move file (#4361)

Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
This commit is contained in:
Daniel Dietzler
2023-10-11 04:14:44 +02:00
committed by GitHub
parent 332a8d80f2
commit 09bf1c9175
31 changed files with 564 additions and 190 deletions

View File

@@ -6,6 +6,7 @@ import {
IStorageRepository,
mimeTypes,
} from '@app/domain';
import { Logger } from '@nestjs/common';
import archiver from 'archiver';
import { constants, createReadStream, existsSync, mkdirSync } from 'fs';
import fs, { readdir, writeFile } from 'fs/promises';
@@ -17,6 +18,8 @@ import path from 'path';
const moveFile = promisify<string, string, mv.Options>(mv);
export class FilesystemProvider implements IStorageRepository {
private logger = new Logger(FilesystemProvider.name);
createZipStream(): ImmichZipStream {
const archive = archiver('zip', { store: true });
@@ -52,6 +55,8 @@ export class FilesystemProvider implements IStorageRepository {
writeFile = writeFile;
async moveFile(source: string, destination: string): Promise<void> {
this.logger.verbose(`Moving ${source} to ${destination}`);
if (await this.checkFileExists(destination)) {
throw new Error(`Destination file already exists: ${destination}`);
}

View File

@@ -11,6 +11,7 @@ export * from './library.repository';
export * from './machine-learning.repository';
export * from './media.repository';
export * from './metadata.repository';
export * from './move.repository';
export * from './partner.repository';
export * from './person.repository';
export * from './shared-link.repository';

View File

@@ -70,6 +70,8 @@ export class JobRepository implements IJobRepository {
private getJobOptions(item: JobItem): JobsOptions | null {
switch (item.name) {
case JobName.STORAGE_TEMPLATE_MIGRATION_SINGLE:
return { jobId: item.data.id };
case JobName.GENERATE_PERSON_THUMBNAIL:
return { priority: 1 };

View File

@@ -0,0 +1,26 @@
import { IMoveRepository, MoveCreate } from '@app/domain';
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { MoveEntity, PathType } from '../entities';
@Injectable()
export class MoveRepository implements IMoveRepository {
constructor(@InjectRepository(MoveEntity) private repository: Repository<MoveEntity>) {}
create(entity: MoveCreate): Promise<MoveEntity> {
return this.repository.save(entity);
}
getByEntity(entityId: string, pathType: PathType): Promise<MoveEntity | null> {
return this.repository.findOne({ where: { entityId, pathType } });
}
update(entity: Partial<MoveEntity>): Promise<MoveEntity> {
return this.repository.save(entity);
}
delete(move: MoveEntity): Promise<MoveEntity> {
return this.repository.remove(move);
}
}