1
0
mirror of https://github.com/immich-app/immich.git synced 2024-11-24 08:52:28 +02:00

feat(server): server-side checking of duplicate import paths and exclusion patterns (#6993)

validate path and pattern
This commit is contained in:
Jonathan Jogenfors 2024-02-09 19:02:11 +01:00 committed by GitHub
parent 2ee9044b6a
commit 954c1c2ef4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 57 additions and 3 deletions

View File

@ -98,6 +98,36 @@ describe(`${LibraryController.name} (e2e)`, () => {
);
});
it('should not create an external library with duplicate import paths', async () => {
const { status, body } = await request(server)
.post('/library')
.set('Authorization', `Bearer ${admin.accessToken}`)
.send({
type: LibraryType.EXTERNAL,
name: 'My Awesome Library',
importPaths: ['/path', '/path'],
exclusionPatterns: ['**/Raw/**'],
});
expect(status).toBe(400);
expect(body).toEqual(errorStub.badRequest(["All importPaths's elements must be unique"]));
});
it('should not create an external library with duplicate exclusion patterns', async () => {
const { status, body } = await request(server)
.post('/library')
.set('Authorization', `Bearer ${admin.accessToken}`)
.send({
type: LibraryType.EXTERNAL,
name: 'My Awesome Library',
importPaths: ['/path/to/import'],
exclusionPatterns: ['**/Raw/**', '**/Raw/**'],
});
expect(status).toBe(400);
expect(body).toEqual(errorStub.badRequest(["All exclusionPatterns's elements must be unique"]));
});
it('should create an upload library with defaults', async () => {
const { status, body } = await request(server)
.post('/library')
@ -229,7 +259,7 @@ describe(`${LibraryController.name} (e2e)`, () => {
);
});
it('should not allow an empty import path', async () => {
it('should reject an empty import path', async () => {
const { status, body } = await request(server)
.put(`/library/${library.id}`)
.set('Authorization', `Bearer ${admin.accessToken}`)
@ -239,6 +269,16 @@ describe(`${LibraryController.name} (e2e)`, () => {
expect(body).toEqual(errorStub.badRequest(['each value in importPaths should not be empty']));
});
it('should reject duplicate import paths', async () => {
const { status, body } = await request(server)
.put(`/library/${library.id}`)
.set('Authorization', `Bearer ${admin.accessToken}`)
.send({ importPaths: ['/path', '/path'] });
expect(status).toBe(400);
expect(body).toEqual(errorStub.badRequest(["All importPaths's elements must be unique"]));
});
it('should change the exclusion pattern', async () => {
const { status, body } = await request(server)
.put(`/library/${library.id}`)
@ -253,7 +293,17 @@ describe(`${LibraryController.name} (e2e)`, () => {
);
});
it('should not allow an empty exclusion pattern', async () => {
it('should reject duplicate exclusion patterns', async () => {
const { status, body } = await request(server)
.put(`/library/${library.id}`)
.set('Authorization', `Bearer ${admin.accessToken}`)
.send({ exclusionPatterns: ['**/*.jpg', '**/*.jpg'] });
expect(status).toBe(400);
expect(body).toEqual(errorStub.badRequest(["All exclusionPatterns's elements must be unique"]));
});
it('should reject an empty exclusion pattern', async () => {
const { status, body } = await request(server)
.put(`/library/${library.id}`)
.set('Authorization', `Bearer ${admin.accessToken}`)

View File

@ -1,6 +1,6 @@
import { LibraryEntity, LibraryType } from '@app/infra/entities';
import { ApiProperty } from '@nestjs/swagger';
import { IsBoolean, IsEnum, IsNotEmpty, IsOptional, IsString } from 'class-validator';
import { ArrayUnique, IsBoolean, IsEnum, IsNotEmpty, IsOptional, IsString } from 'class-validator';
import { ValidateUUID } from '../domain.util';
export class CreateLibraryDto {
@ -20,11 +20,13 @@ export class CreateLibraryDto {
@IsOptional()
@IsString({ each: true })
@IsNotEmpty({ each: true })
@ArrayUnique()
importPaths?: string[];
@IsOptional()
@IsString({ each: true })
@IsNotEmpty({ each: true })
@ArrayUnique()
exclusionPatterns?: string[];
@IsOptional()
@ -45,11 +47,13 @@ export class UpdateLibraryDto {
@IsOptional()
@IsString({ each: true })
@IsNotEmpty({ each: true })
@ArrayUnique()
importPaths?: string[];
@IsOptional()
@IsNotEmpty({ each: true })
@IsString({ each: true })
@ArrayUnique()
exclusionPatterns?: string[];
}