From ad63f55a0f3d5cf3ad166847fc70edf1a8b8a211 Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Thu, 19 Dec 2024 11:22:26 -0500 Subject: [PATCH 1/2] add file extension to locally-stored media --- packages/backend/src/core/DriveService.ts | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/packages/backend/src/core/DriveService.ts b/packages/backend/src/core/DriveService.ts index 086f2f94d5..99e0ea98dd 100644 --- a/packages/backend/src/core/DriveService.ts +++ b/packages/backend/src/core/DriveService.ts @@ -37,6 +37,7 @@ import { InternalStorageService } from '@/core/InternalStorageService.js'; import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { FileInfoService } from '@/core/FileInfoService.js'; +import type { FileInfo } from '@/core/FileInfoService.js'; import { bindThis } from '@/decorators.js'; import { RoleService } from '@/core/RoleService.js'; import { correctFilename } from '@/misc/correct-filename.js'; @@ -139,15 +140,19 @@ export class DriveService { /*** * Save file + * @param file * @param path Path for original * @param name Name for original (should be extention corrected) - * @param type Content-Type for original - * @param hash Hash for original - * @param size Size for original + * @param info File metadata */ @bindThis - private async save(file: MiDriveFile, path: string, name: string, type: string, hash: string, size: number): Promise { - // thunbnail, webpublic を必要なら生成 + private async save(file: MiDriveFile, path: string, name: string, info: FileInfo): Promise { + const type = info.type.mime; + const ext = info.type.ext; + const hash = info.md5; + const size = info.size; + + // thunbnail, webpublic を必要なら生成 const alts = await this.generateAlts(path, type, !file.uri); if (this.meta.useObjectStorage) { @@ -223,9 +228,9 @@ export class DriveService { return await this.driveFilesRepository.insertOne(file); } else { // use internal storage - const accessKey = randomUUID(); - const thumbnailAccessKey = 'thumbnail-' + randomUUID(); - const webpublicAccessKey = 'webpublic-' + randomUUID(); + const accessKey = `${randomUUID()}.${ext}`; + const thumbnailAccessKey = `thumbnail-${randomUUID()}.${ext}`; + const webpublicAccessKey = `webpublic-${randomUUID()}.${ext}`; // Ugly type is just to help TS figure out that 2nd / 3rd promises are optional. const promises: [Promise, ...(Promise | undefined)[]] = [ @@ -616,7 +621,7 @@ export class DriveService { } } } else { - file = await (this.save(file, path, detectedName, info.type.mime, info.md5, info.size)); + file = await (this.save(file, path, detectedName, info)); } this.registerLogger.succ(`drive file has been created ${file.id}`); From 0de93c2bde78bd4c4c7aed87d42cd7054955b4b2 Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Thu, 19 Dec 2024 12:33:11 -0500 Subject: [PATCH 2/2] only attach file extension for browser-safe file types --- packages/backend/src/core/DriveService.ts | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/backend/src/core/DriveService.ts b/packages/backend/src/core/DriveService.ts index 99e0ea98dd..734ce6b88f 100644 --- a/packages/backend/src/core/DriveService.ts +++ b/packages/backend/src/core/DriveService.ts @@ -148,7 +148,6 @@ export class DriveService { @bindThis private async save(file: MiDriveFile, path: string, name: string, info: FileInfo): Promise { const type = info.type.mime; - const ext = info.type.ext; const hash = info.md5; const size = info.size; @@ -228,9 +227,11 @@ export class DriveService { return await this.driveFilesRepository.insertOne(file); } else { // use internal storage - const accessKey = `${randomUUID()}.${ext}`; - const thumbnailAccessKey = `thumbnail-${randomUUID()}.${ext}`; - const webpublicAccessKey = `webpublic-${randomUUID()}.${ext}`; + const ext = FILE_TYPE_BROWSERSAFE.includes(type) ? info.type.ext : null; + + const accessKey = makeFileKey(ext); + const thumbnailAccessKey = makeFileKey(ext, 'thumbnail'); + const webpublicAccessKey = makeFileKey(ext, 'webpublic'); // Ugly type is just to help TS figure out that 2nd / 3rd promises are optional. const promises: [Promise, ...(Promise | undefined)[]] = [ @@ -867,3 +868,16 @@ export class DriveService { } } } + +function makeFileKey(ext: string | null, prefix?: string): string { + const parts: string[] = [randomUUID()]; + + if (prefix) { + parts.unshift(prefix, '-'); + } + if (ext) { + parts.push('.', ext); + } + + return parts.join(''); +}