diff --git a/CHANGELOG.md b/CHANGELOG.md index 8533a4d393..440e2e21e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ - デフォルト値は「ローカルのコンテンツだけ公開」になっています - Feat: ロールでアップロード可能なファイル種別を設定可能になりました - デフォルトは**テキスト、JSON、画像、動画、音声ファイル**になっています。zipなど、その他の種別のファイルは含まれていないため、必要に応じて設定を変更してください。 + - 場合によってはファイル種別を正しく検出できないことがあります(特にテキストフォーマット)。その場合、ファイル種別は application/octet-stream と見做されます。 + - したがって、それらの種別不明ファイルを許可したい場合は application/octet-stream を指定に追加してください。 - Enhance: UIのアイコンデータの読み込みを軽量化 ### Client diff --git a/locales/index.d.ts b/locales/index.d.ts index b3f5ff4938..b6b69f3ebe 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -7753,6 +7753,10 @@ export interface Locale extends ILocale { * MIMEタイプを指定します。改行で区切って複数指定できるほか、アスタリスク(*)でワイルドカード指定できます。(例: image/*) */ "uploadableFileTypes_caption": string; + /** + * ファイルによっては種別を判定できないことがあります。そのようなファイルを許可する場合は {x} を指定に追加してください。 + */ + "uploadableFileTypes_caption2": ParameterizedString<"x">; }; "_condition": { /** diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 44e6af61c7..a4081b1bf9 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -2007,6 +2007,7 @@ _role: chatAvailability: "チャットを許可" uploadableFileTypes: "アップロード可能なファイル種別" uploadableFileTypes_caption: "MIMEタイプを指定します。改行で区切って複数指定できるほか、アスタリスク(*)でワイルドカード指定できます。(例: image/*)" + uploadableFileTypes_caption2: "ファイルによっては種別を判定できないことがあります。そのようなファイルを許可する場合は {x} を指定に追加してください。" _condition: roleAssignedTo: "マニュアルロールにアサイン済み" isLocal: "ローカルユーザー" diff --git a/package.json b/package.json index 50c2542ffb..6c852b76d3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "misskey", - "version": "2025.5.1-beta.0", + "version": "2025.5.1-beta.2", "codename": "nasubi", "repository": { "type": "git", diff --git a/packages/backend/src/core/DriveService.ts b/packages/backend/src/core/DriveService.ts index 0c7c06d92f..54d2f26538 100644 --- a/packages/backend/src/core/DriveService.ts +++ b/packages/backend/src/core/DriveService.ts @@ -469,13 +469,14 @@ export class DriveService { if (user && this.meta.sensitiveMediaDetection === 'remote' && this.userEntityService.isLocalUser(user)) skipNsfwCheck = true; const info = await this.fileInfoService.getFileInfo(path, { + fileName: name, skipSensitiveDetection: skipNsfwCheck, sensitiveThreshold: // 感度が高いほどしきい値は低くすることになる - this.meta.sensitiveMediaDetectionSensitivity === 'veryHigh' ? 0.1 : - this.meta.sensitiveMediaDetectionSensitivity === 'high' ? 0.3 : - this.meta.sensitiveMediaDetectionSensitivity === 'low' ? 0.7 : - this.meta.sensitiveMediaDetectionSensitivity === 'veryLow' ? 0.9 : - 0.5, + this.meta.sensitiveMediaDetectionSensitivity === 'veryHigh' ? 0.1 : + this.meta.sensitiveMediaDetectionSensitivity === 'high' ? 0.3 : + this.meta.sensitiveMediaDetectionSensitivity === 'low' ? 0.7 : + this.meta.sensitiveMediaDetectionSensitivity === 'veryLow' ? 0.9 : + 0.5, sensitiveThresholdForPorn: 0.75, enableSensitiveMediaDetectionForVideos: this.meta.enableSensitiveMediaDetectionForVideos, }); diff --git a/packages/backend/src/core/FileInfoService.ts b/packages/backend/src/core/FileInfoService.ts index a295e81920..6250d4d3a1 100644 --- a/packages/backend/src/core/FileInfoService.ts +++ b/packages/backend/src/core/FileInfoService.ts @@ -64,6 +64,7 @@ export class FileInfoService { */ @bindThis public async getFileInfo(path: string, opts: { + fileName?: string | null; skipSensitiveDetection: boolean; sensitiveThreshold?: number; sensitiveThresholdForPorn?: number; @@ -76,6 +77,26 @@ export class FileInfoService { let type = await this.detectType(path); + if (type.mime === TYPE_OCTET_STREAM.mime && opts.fileName != null) { + const ext = opts.fileName.split('.').pop(); + if (ext === 'txt') { + type = { + mime: 'text/plain', + ext: 'txt', + }; + } else if (ext === 'csv') { + type = { + mime: 'text/csv', + ext: 'csv', + }; + } else if (ext === 'json') { + type = { + mime: 'application/json', + ext: 'json', + }; + } + } + // image dimensions let width: number | undefined; let height: number | undefined; @@ -438,12 +459,12 @@ export class FileInfoService { */ @bindThis private async detectImageSize(path: string): Promise<{ - width: number; - height: number; - wUnits: string; - hUnits: string; - orientation?: number; -}> { + width: number; + height: number; + wUnits: string; + hUnits: string; + orientation?: number; + }> { const readable = fs.createReadStream(path); const imageSize = await probeImageSize(readable); readable.destroy(); diff --git a/packages/backend/src/server/api/endpoints/drive/files/create.ts b/packages/backend/src/server/api/endpoints/drive/files/create.ts index 11c255a361..7d5c0ccd4d 100644 --- a/packages/backend/src/server/api/endpoints/drive/files/create.ts +++ b/packages/backend/src/server/api/endpoints/drive/files/create.ts @@ -63,6 +63,12 @@ export const meta = { id: 'b9d8c348-33f0-4673-b9a9-5d4da058977a', httpStatusCode: 413, }, + + unallowedFileType: { + message: 'Cannot upload the file because it is an unallowed file type.', + code: 'UNALLOWED_FILE_TYPE', + id: '4becd248-7f2c-48c4-a9f0-75edc4f9a1ea', + }, }, } as const; @@ -123,6 +129,7 @@ export default class extends Endpoint { // eslint- if (err.id === '282f77bf-5816-4f72-9264-aa14d8261a21') throw new ApiError(meta.errors.inappropriate); if (err.id === 'c6244ed2-a39a-4e1c-bf93-f0fbd7764fa6') throw new ApiError(meta.errors.noFreeSpace); if (err.id === 'f9e4e5f3-4df4-40b5-b400-f236945f7073') throw new ApiError(meta.errors.maxFileSizeExceeded); + if (err.id === 'bd71c601-f9b0-4808-9137-a330647ced9b') throw new ApiError(meta.errors.unallowedFileType); } throw new ApiError(); } finally { diff --git a/packages/backend/src/server/api/endpoints/notes/show-partial-bulk.ts b/packages/backend/src/server/api/endpoints/notes/show-partial-bulk.ts index 87b368e17e..e102bc1d4a 100644 --- a/packages/backend/src/server/api/endpoints/notes/show-partial-bulk.ts +++ b/packages/backend/src/server/api/endpoints/notes/show-partial-bulk.ts @@ -19,7 +19,26 @@ export const meta = { optional: false, nullable: false, items: { type: 'object', - optional: false, nullable: false, + properties: { + id: { + type: 'string', + optional: false, nullable: false, + }, + reactions: { + type: 'object', + optional: false, nullable: false, + additionalProperties: { + type: 'number', + }, + }, + reactionEmojis: { + type: 'object', + optional: false, nullable: false, + additionalProperties: { + type: 'string', + }, + }, + }, }, }, diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue index ee8a470b0e..4a78d00665 100644 --- a/packages/frontend/src/components/MkNote.vue +++ b/packages/frontend/src/components/MkNote.vue @@ -193,7 +193,7 @@ SPDX-License-Identifier: AGPL-3.0-only