diff --git a/apps/files/src/services/DropService.ts b/apps/files/src/services/DropService.ts index 6d1fbc524c046..91f6e78e974b9 100644 --- a/apps/files/src/services/DropService.ts +++ b/apps/files/src/services/DropService.ts @@ -62,7 +62,9 @@ export async function dataTransferToFileTree(items: DataTransferItem[]): Promise // Warn the user that the browser does not support the Filesystem API // we therefore cannot upload directories recursively. - if (file.type === 'httpd/unix-directory' || !file.type) { + // Note: files with an unknown type are kept on purpose, the server + // detects their mime type on upload (content sniffing + extension map). + if (file.type === 'httpd/unix-directory' || (!file.type && file.size === 0)) { if (!warned) { logger.warn('Browser does not support Filesystem API. Directories will not be uploaded') showWarning(t('files', 'Your browser does not support the Filesystem API. Directories will not be uploaded')) diff --git a/apps/files/src/services/DropServiceUtils.spec.ts b/apps/files/src/services/DropServiceUtils.spec.ts index e8d2e2ad33d69..3fc76656bca0c 100644 --- a/apps/files/src/services/DropServiceUtils.spec.ts +++ b/apps/files/src/services/DropServiceUtils.spec.ts @@ -219,4 +219,35 @@ describe('DropService dataTransferToFileTree', () => { expect(logger.warn).toHaveBeenNthCalledWith(4, 'Could not get FilesystemEntry of item, falling back to file') expect(logger.warn).toHaveBeenCalledTimes(4) }) + + it('Should keep files with an unknown mime type for server-side detection', async () => { + const { showWarning } = await import('@nextcloud/dialogs') + const file = new File(['data'], 'notes.unknown-ext', { type: '' }) + const item = Object.create(DataTransferItemMock.prototype) + Object.defineProperties(item, { + kind: { value: 'file' }, + getAsFile: { value: () => file }, + }) + + const fileTree = await dataTransferToFileTree([item as unknown as DataTransferItem]) + + expect(fileTree.contents).toHaveLength(1) + expect(fileTree.contents[0].name).toBe('notes.unknown-ext') + expect(showWarning).not.toHaveBeenCalled() + }) + + it('Should still skip unix directories with a warning', async () => { + const { showWarning } = await import('@nextcloud/dialogs') + const file = new File([], 'mydir', { type: 'httpd/unix-directory' }) + const item = Object.create(DataTransferItemMock.prototype) + Object.defineProperties(item, { + kind: { value: 'file' }, + getAsFile: { value: () => file }, + }) + + const fileTree = await dataTransferToFileTree([item as unknown as DataTransferItem]) + + expect(fileTree.contents).toHaveLength(0) + expect(showWarning).toHaveBeenCalledTimes(1) + }) })