From 5921ec9a580d05b111a21faf0aae46d255b35a73 Mon Sep 17 00:00:00 2001 From: Jason Rasmussen Date: Tue, 24 Oct 2023 12:08:18 -0400 Subject: [PATCH] fix(server): dot files (#4625) --- server/src/domain/audit/audit.service.ts | 7 ++++++- server/src/immich/api-v1/asset/asset.service.ts | 10 ++++++++-- server/src/infra/repositories/filesystem.provider.ts | 3 ++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/server/src/domain/audit/audit.service.ts b/server/src/domain/audit/audit.service.ts index 1eaa720815..2b5a304ea1 100644 --- a/server/src/domain/audit/audit.service.ts +++ b/server/src/domain/audit/audit.service.ts @@ -125,7 +125,12 @@ export class AuditService { const fullPath = (filename: string) => resolve(filename); const hasFile = (items: Set, filename: string) => items.has(filename) || items.has(fullPath(filename)); const crawl = async (folder: StorageFolder) => - new Set(await this.storageRepository.crawl({ pathsToCrawl: [StorageCore.getBaseFolder(folder)] })); + new Set( + await this.storageRepository.crawl({ + includeHidden: true, + pathsToCrawl: [StorageCore.getBaseFolder(folder)], + }), + ); const uploadFiles = await crawl(StorageFolder.UPLOAD); const libraryFiles = await crawl(StorageFolder.LIBRARY); diff --git a/server/src/immich/api-v1/asset/asset.service.ts b/server/src/immich/api-v1/asset/asset.service.ts index 1de4edeea6..da0209c086 100644 --- a/server/src/immich/api-v1/asset/asset.service.ts +++ b/server/src/immich/api-v1/asset/asset.service.ts @@ -25,7 +25,7 @@ import { NotFoundException, } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; -import { Response as Res } from 'express'; +import { Response as Res, Response } from 'express'; import { constants } from 'fs'; import fs from 'fs/promises'; import path from 'path'; @@ -52,6 +52,9 @@ import { CheckExistingAssetsResponseDto } from './response-dto/check-existing-as import { CuratedLocationsResponseDto } from './response-dto/curated-locations-response.dto'; import { CuratedObjectsResponseDto } from './response-dto/curated-objects-response.dto'; +type SendFile = Parameters; +type SendFileOptions = SendFile[1]; + @Injectable() export class AssetService { readonly logger = new Logger(AssetService.name); @@ -436,7 +439,10 @@ export class AssetService { private async sendFile(res: Res, filepath: string): Promise { await fs.access(filepath, constants.R_OK); - const options = path.isAbsolute(filepath) ? {} : { root: process.cwd() }; + const options: SendFileOptions = { dotfiles: 'allow' }; + if (!path.isAbsolute(filepath)) { + options.root = process.cwd(); + } res.set('Cache-Control', 'private, max-age=86400, no-transform'); res.header('Content-Type', mimeTypes.lookup(filepath)); diff --git a/server/src/infra/repositories/filesystem.provider.ts b/server/src/infra/repositories/filesystem.provider.ts index 9c85626c0d..7edcede806 100644 --- a/server/src/infra/repositories/filesystem.provider.ts +++ b/server/src/infra/repositories/filesystem.provider.ts @@ -117,7 +117,7 @@ export class FilesystemProvider implements IStorageRepository { } crawl(crawlOptions: CrawlOptionsDto): Promise { - const { pathsToCrawl, exclusionPatterns } = crawlOptions; + const { pathsToCrawl, exclusionPatterns, includeHidden } = crawlOptions; if (!pathsToCrawl) { return Promise.resolve([]); } @@ -129,6 +129,7 @@ export class FilesystemProvider implements IStorageRepository { absolute: true, nocase: true, nodir: true, + dot: includeHidden, ignore: exclusionPatterns, }); }