mirror of
https://github.com/immich-app/immich.git
synced 2025-12-18 17:23:16 +03:00
fix(server): follow symlinks when zipping assets (#11685)
* follow symlinks when zipping assets fixes #9335 * chore: clean up --------- Co-authored-by: Jason Rasmussen <jason@rasm.me>
This commit is contained in:
@@ -2,12 +2,14 @@ import { BadRequestException } from '@nestjs/common';
|
||||
import { DownloadResponseDto } from 'src/dtos/download.dto';
|
||||
import { AssetEntity } from 'src/entities/asset.entity';
|
||||
import { IAssetRepository } from 'src/interfaces/asset.interface';
|
||||
import { ILoggerRepository } from 'src/interfaces/logger.interface';
|
||||
import { IStorageRepository } from 'src/interfaces/storage.interface';
|
||||
import { DownloadService } from 'src/services/download.service';
|
||||
import { assetStub } from 'test/fixtures/asset.stub';
|
||||
import { authStub } from 'test/fixtures/auth.stub';
|
||||
import { IAccessRepositoryMock, newAccessRepositoryMock } from 'test/repositories/access.repository.mock';
|
||||
import { newAssetRepositoryMock } from 'test/repositories/asset.repository.mock';
|
||||
import { newLoggerRepositoryMock } from 'test/repositories/logger.repository.mock';
|
||||
import { newStorageRepositoryMock } from 'test/repositories/storage.repository.mock';
|
||||
import { Readable } from 'typeorm/platform/PlatformTools.js';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
@@ -26,6 +28,7 @@ describe(DownloadService.name, () => {
|
||||
let sut: DownloadService;
|
||||
let accessMock: IAccessRepositoryMock;
|
||||
let assetMock: Mocked<IAssetRepository>;
|
||||
let loggerMock: Mocked<ILoggerRepository>;
|
||||
let storageMock: Mocked<IStorageRepository>;
|
||||
|
||||
it('should work', () => {
|
||||
@@ -35,9 +38,10 @@ describe(DownloadService.name, () => {
|
||||
beforeEach(() => {
|
||||
accessMock = newAccessRepositoryMock();
|
||||
assetMock = newAssetRepositoryMock();
|
||||
loggerMock = newLoggerRepositoryMock();
|
||||
storageMock = newStorageRepositoryMock();
|
||||
|
||||
sut = new DownloadService(accessMock, assetMock, storageMock);
|
||||
sut = new DownloadService(accessMock, assetMock, loggerMock, storageMock);
|
||||
});
|
||||
|
||||
describe('downloadArchive', () => {
|
||||
@@ -109,6 +113,27 @@ describe(DownloadService.name, () => {
|
||||
expect(archiveMock.addFile).toHaveBeenNthCalledWith(1, 'upload/library/IMG_123.jpg', 'IMG_123.jpg');
|
||||
expect(archiveMock.addFile).toHaveBeenNthCalledWith(2, 'upload/library/IMG_123.jpg', 'IMG_123+1.jpg');
|
||||
});
|
||||
|
||||
it('should resolve symlinks', async () => {
|
||||
const archiveMock = {
|
||||
addFile: vitest.fn(),
|
||||
finalize: vitest.fn(),
|
||||
stream: new Readable(),
|
||||
};
|
||||
|
||||
accessMock.asset.checkOwnerAccess.mockResolvedValue(new Set(['asset-1']));
|
||||
assetMock.getByIds.mockResolvedValue([
|
||||
{ ...assetStub.noResizePath, id: 'asset-1', originalPath: '/path/to/symlink.jpg' },
|
||||
]);
|
||||
storageMock.realpath.mockResolvedValue('/path/to/realpath.jpg');
|
||||
storageMock.createZipStream.mockReturnValue(archiveMock);
|
||||
|
||||
await expect(sut.downloadArchive(authStub.admin, { assetIds: ['asset-1'] })).resolves.toEqual({
|
||||
stream: archiveMock.stream,
|
||||
});
|
||||
|
||||
expect(archiveMock.addFile).toHaveBeenCalledWith('/path/to/realpath.jpg', 'IMG_123.jpg');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getDownloadInfo', () => {
|
||||
|
||||
Reference in New Issue
Block a user