Skip to content

Commit 03e5ae8

Browse files
authored
fix: bulk upload mimetype wildcard file selection (#8954)
Fixes an issue where using wildcards in upload-enabled collection mimeType restrictions would prevent files from being selected in the bulk upload file selector.
1 parent d89db00 commit 03e5ae8

File tree

5 files changed

+24
-7
lines changed

5 files changed

+24
-7
lines changed

packages/payload/src/exports/shared.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ export { validOperators } from '../types/constants.js'
3535
export { formatFilesize } from '../uploads/formatFilesize.js'
3636

3737
export { isImage } from '../uploads/isImage.js'
38+
3839
export {
3940
deepCopyObject,
4041
deepCopyObjectComplex,
4142
deepCopyObjectSimple,
4243
} from '../utilities/deepCopyObject.js'
43-
4444
export {
4545
deepMerge,
4646
deepMergeWithCombinedArrays,
@@ -49,8 +49,8 @@ export {
4949
} from '../utilities/deepMerge.js'
5050

5151
export { fieldSchemaToJSON } from '../utilities/fieldSchemaToJSON.js'
52-
export { getDataByPath } from '../utilities/getDataByPath.js'
5352

53+
export { getDataByPath } from '../utilities/getDataByPath.js'
5454
export { getSelectMode } from '../utilities/getSelectMode.js'
5555

5656
export { getSiblingData } from '../utilities/getSiblingData.js'
@@ -72,6 +72,8 @@ export { setsAreEqual } from '../utilities/setsAreEqual.js'
7272
export { default as toKebabCase } from '../utilities/toKebabCase.js'
7373

7474
export { unflatten } from '../utilities/unflatten.js'
75+
76+
export { validateMimeType } from '../utilities/validateMimeType.js'
7577
export { wait } from '../utilities/wait.js'
7678
export { default as wordBoundariesRegex } from '../utilities/wordBoundariesRegex.js'
7779
export { versionDefaults } from '../versions/defaults.js'

packages/payload/src/uploads/mimeTypeValidator.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import type { Validate } from '../fields/config/types.js'
22

3+
import { validateMimeType } from '../utilities/validateMimeType.js'
4+
35
export const mimeTypeValidator =
46
(mimeTypes: string[]): Validate =>
57
(val: string, { siblingData }) => {
@@ -11,6 +13,6 @@ export const mimeTypeValidator =
1113
return 'Invalid file type'
1214
}
1315

14-
const cleanedMimeTypes = mimeTypes.map((v) => v.replace('*', ''))
15-
return !cleanedMimeTypes.some((v) => val.startsWith(v)) ? `Invalid file type: '${val}'` : true
16+
const isValidMimeType = validateMimeType(val, mimeTypes)
17+
return isValidMimeType ? true : `Invalid file type: '${val}'`
1618
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export const validateMimeType = (mimeType: string, allowedMimeTypes: string[]): boolean => {
2+
const cleanedMimeTypes = allowedMimeTypes.map((v) => v.replace('*', ''))
3+
return cleanedMimeTypes.some((cleanedMimeType) => mimeType.startsWith(cleanedMimeType))
4+
}

packages/translations/src/clientKeys.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ export const clientTranslationKeys = createClientTranslationKeys([
6868
'error:emailOrPasswordIncorrect',
6969
'error:usernameOrPasswordIncorrect',
7070
'error:loadingDocument',
71+
'error:invalidFileType',
7172
'error:logoutFailed',
7273
'error:noMatchedField',
7374
'error:notAllowedToAccessPage',

packages/ui/src/elements/BulkUpload/index.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33
import type { JsonObject } from 'payload'
44

55
import { useModal } from '@faceless-ui/modal'
6+
import { validateMimeType } from 'payload/shared'
67
import React from 'react'
8+
import { toast } from 'sonner'
79

810
import { useConfig } from '../../providers/Config/index.js'
911
import { EditDepthProvider, useEditDepth } from '../../providers/EditDepth/index.js'
12+
import { useTranslation } from '../../providers/Translation/index.js'
1013
import { Drawer } from '../Drawer/index.js'
1114
import { AddFilesView } from './AddFilesView/index.js'
1215
import { AddingFilesView } from './AddingFilesView/index.js'
@@ -19,6 +22,7 @@ function DrawerContent() {
1922
const { closeModal } = useModal()
2023
const { collectionSlug, drawerSlug } = useBulkUpload()
2124
const { config } = useConfig()
25+
const { t } = useTranslation()
2226

2327
const uploadCollection = config.collections.find((col) => col.slug === collectionSlug)
2428
const uploadConfig = uploadCollection.upload
@@ -31,14 +35,18 @@ function DrawerContent() {
3135
if (
3236
uploadMimeTypes === undefined ||
3337
uploadMimeTypes.length === 0 ||
34-
uploadMimeTypes?.includes(candidateFile.type)
38+
validateMimeType(candidateFile.type, uploadMimeTypes)
3539
) {
3640
fileTransfer.items.add(candidateFile)
3741
}
3842
}
39-
void addFiles(fileTransfer.files)
43+
if (fileTransfer.files.length === 0) {
44+
toast.error(t('error:invalidFileType'))
45+
} else {
46+
void addFiles(fileTransfer.files)
47+
}
4048
},
41-
[addFiles, uploadMimeTypes],
49+
[addFiles, t, uploadMimeTypes],
4250
)
4351

4452
if (!collectionSlug) {

0 commit comments

Comments
 (0)