From e750c9171e5f70878bd1fdb5a63effdad77c58ed Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Thu, 22 May 2025 23:01:31 +0900 Subject: feat: ロールでアップロード可能なファイル種別を設定可能に (#16081) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * wip * Update RoleService.ts * wip * Update RoleService.ts * Update CHANGELOG.md --- packages/backend/src/core/DriveService.ts | 22 +++++++++++++++++----- packages/backend/src/core/RoleService.ts | 18 ++++++++++++++++++ 2 files changed, 35 insertions(+), 5 deletions(-) (limited to 'packages/backend/src/core') diff --git a/packages/backend/src/core/DriveService.ts b/packages/backend/src/core/DriveService.ts index 0d5ac022aa..0c7c06d92f 100644 --- a/packages/backend/src/core/DriveService.ts +++ b/packages/backend/src/core/DriveService.ts @@ -515,16 +515,23 @@ export class DriveService { this.registerLogger.debug(`ADD DRIVE FILE: user ${user?.id ?? 'not set'}, name ${detectedName}, tmp ${path}`); - //#region Check drive usage + //#region Check drive usage and mime type if (user && !isLink) { - const usage = await this.driveFileEntityService.calcDriveUsageOf(user); const isLocalUser = this.userEntityService.isLocalUser(user); - const policies = await this.roleService.getUserPolicies(user.id); + + const allowedMimeTypes = policies.uploadableFileTypes; + const isAllowed = allowedMimeTypes.some((mimeType) => { + if (mimeType === '*' || mimeType === '*/*') return true; + if (mimeType.endsWith('/*')) return info.type.mime.startsWith(mimeType.slice(0, -1)); + return info.type.mime === mimeType; + }); + if (!isAllowed) { + throw new IdentifiableError('bd71c601-f9b0-4808-9137-a330647ced9b', 'Unallowed file type.'); + } + const driveCapacity = 1024 * 1024 * policies.driveCapacityMb; const maxFileSize = 1024 * 1024 * policies.maxFileSizeMb; - this.registerLogger.debug('drive capacity override applied'); - this.registerLogger.debug(`overrideCap: ${driveCapacity}bytes, usage: ${usage}bytes, u+s: ${usage + info.size}bytes`); if (maxFileSize < info.size) { if (isLocalUser) { @@ -532,6 +539,11 @@ export class DriveService { } } + const usage = await this.driveFileEntityService.calcDriveUsageOf(user); + + this.registerLogger.debug('drive capacity override applied'); + this.registerLogger.debug(`overrideCap: ${driveCapacity}bytes, usage: ${usage}bytes, u+s: ${usage + info.size}bytes`); + // If usage limit exceeded if (driveCapacity < usage + info.size) { if (isLocalUser) { diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts index fc97780ba3..2669104f7e 100644 --- a/packages/backend/src/core/RoleService.ts +++ b/packages/backend/src/core/RoleService.ts @@ -65,6 +65,7 @@ export type RolePolicies = { canImportMuting: boolean; canImportUserLists: boolean; chatAvailability: 'available' | 'readonly' | 'unavailable'; + uploadableFileTypes: string[]; }; export const DEFAULT_POLICIES: RolePolicies = { @@ -101,6 +102,13 @@ export const DEFAULT_POLICIES: RolePolicies = { canImportMuting: true, canImportUserLists: true, chatAvailability: 'available', + uploadableFileTypes: [ + 'text/plain', + 'application/json', + 'image/*', + 'video/*', + 'audio/*', + ], }; @Injectable() @@ -412,6 +420,16 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit { canImportMuting: calc('canImportMuting', vs => vs.some(v => v === true)), canImportUserLists: calc('canImportUserLists', vs => vs.some(v => v === true)), chatAvailability: calc('chatAvailability', aggregateChatAvailability), + uploadableFileTypes: calc('uploadableFileTypes', vs => { + const set = new Set(); + for (const v of vs) { + for (const type of v) { + if (type.trim() === '') continue; + set.add(type.trim()); + } + } + return [...set]; + }), }; } -- cgit v1.2.3-freya