mirror of
https://github.com/immich-app/immich.git
synced 2025-01-04 02:46:47 +01:00
fix: only check external path once (#4419)
This commit is contained in:
parent
f57acc0802
commit
83b63ca12e
2 changed files with 1 additions and 69 deletions
|
@ -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 () => {
|
it('should set a missing asset to offline', async () => {
|
||||||
storageMock.stat.mockRejectedValue(new Error());
|
storageMock.stat.mockRejectedValue(new Error());
|
||||||
|
|
||||||
|
|
|
@ -156,17 +156,6 @@ export class LibraryService {
|
||||||
async handleAssetRefresh(job: ILibraryFileJob) {
|
async handleAssetRefresh(job: ILibraryFileJob) {
|
||||||
const assetPath = path.normalize(job.assetPath);
|
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);
|
const existingAssetEntity = await this.assetRepository.getByLibraryIdAndOriginalPath(job.id, assetPath);
|
||||||
|
|
||||||
let stats: Stats;
|
let stats: Stats;
|
||||||
|
@ -367,8 +356,6 @@ export class LibraryService {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const normalizedExternalPath = path.normalize(user.externalPath);
|
|
||||||
|
|
||||||
this.logger.verbose(`Refreshing library: ${job.id}`);
|
this.logger.verbose(`Refreshing library: ${job.id}`);
|
||||||
const crawledAssetPaths = (
|
const crawledAssetPaths = (
|
||||||
await this.storageRepository.crawl({
|
await this.storageRepository.crawl({
|
||||||
|
@ -379,7 +366,7 @@ export class LibraryService {
|
||||||
.map(path.normalize)
|
.map(path.normalize)
|
||||||
.filter((assetPath) =>
|
.filter((assetPath) =>
|
||||||
// Filter out paths that are not within the user's external path
|
// 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}`);
|
this.logger.debug(`Found ${crawledAssetPaths.length} assets when crawling import paths ${library.importPaths}`);
|
||||||
|
|
Loading…
Reference in a new issue