1
0
mirror of https://github.com/immich-app/immich.git synced 2024-11-28 09:33:27 +02:00

fix: only check external path once (#4419)

This commit is contained in:
Jonathan Jogenfors 2023-10-10 15:44:43 +02:00 committed by GitHub
parent f57acc0802
commit 83b63ca12e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 1 additions and 69 deletions

View File

@ -415,61 +415,6 @@ describe(LibraryService.name, () => {
});
});
it('should skip an asset if the user cannot be found', async () => {
userMock.get.mockResolvedValue(null);
const mockLibraryJob: ILibraryFileJob = {
id: libraryStub.externalLibrary1.id,
ownerId: mockUser.id,
assetPath: '/data/user1/photo.jpg',
force: false,
};
expect(sut.handleAssetRefresh(mockLibraryJob)).resolves.toBe(false);
});
it('should skip an asset if external path is not set', async () => {
mockUser = userStub.admin;
userMock.get.mockResolvedValue(mockUser);
const mockLibraryJob: ILibraryFileJob = {
id: libraryStub.externalLibrary1.id,
ownerId: mockUser.id,
assetPath: '/data/user1/photo.jpg',
force: false,
};
expect(sut.handleAssetRefresh(mockLibraryJob)).resolves.toBe(false);
});
it("should skip an asset if it isn't in the external path", async () => {
mockUser = userStub.externalPath1;
userMock.get.mockResolvedValue(mockUser);
const mockLibraryJob: ILibraryFileJob = {
id: libraryStub.externalLibrary1.id,
ownerId: mockUser.id,
assetPath: '/etc/rootpassword.jpg',
force: false,
};
expect(sut.handleAssetRefresh(mockLibraryJob)).resolves.toBe(false);
});
it('should skip an asset if directory traversal is attempted', async () => {
mockUser = userStub.externalPath1;
userMock.get.mockResolvedValue(mockUser);
const mockLibraryJob: ILibraryFileJob = {
id: libraryStub.externalLibrary1.id,
ownerId: mockUser.id,
assetPath: '/data/user1/../../etc/rootpassword.jpg',
force: false,
};
expect(sut.handleAssetRefresh(mockLibraryJob)).resolves.toBe(false);
});
it('should set a missing asset to offline', async () => {
storageMock.stat.mockRejectedValue(new Error());

View File

@ -156,17 +156,6 @@ export class LibraryService {
async handleAssetRefresh(job: ILibraryFileJob) {
const assetPath = path.normalize(job.assetPath);
const user = await this.userRepository.get(job.ownerId);
if (!user?.externalPath) {
this.logger.warn('User has no external path set, cannot import asset');
return false;
}
if (!path.normalize(assetPath).match(new RegExp(`^${path.normalize(user.externalPath)}`))) {
this.logger.error("Asset must be within the user's external path");
return false;
}
const existingAssetEntity = await this.assetRepository.getByLibraryIdAndOriginalPath(job.id, assetPath);
let stats: Stats;
@ -367,8 +356,6 @@ export class LibraryService {
return false;
}
const normalizedExternalPath = path.normalize(user.externalPath);
this.logger.verbose(`Refreshing library: ${job.id}`);
const crawledAssetPaths = (
await this.storageRepository.crawl({
@ -379,7 +366,7 @@ export class LibraryService {
.map(path.normalize)
.filter((assetPath) =>
// Filter out paths that are not within the user's external path
assetPath.match(new RegExp(`^${normalizedExternalPath}`)),
assetPath.match(new RegExp(`^${user.externalPath}`)),
);
this.logger.debug(`Found ${crawledAssetPaths.length} assets when crawling import paths ${library.importPaths}`);