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.
This commit is contained in:
@@ -35,12 +35,12 @@ export { validOperators } from '../types/constants.js'
|
|||||||
export { formatFilesize } from '../uploads/formatFilesize.js'
|
export { formatFilesize } from '../uploads/formatFilesize.js'
|
||||||
|
|
||||||
export { isImage } from '../uploads/isImage.js'
|
export { isImage } from '../uploads/isImage.js'
|
||||||
|
|
||||||
export {
|
export {
|
||||||
deepCopyObject,
|
deepCopyObject,
|
||||||
deepCopyObjectComplex,
|
deepCopyObjectComplex,
|
||||||
deepCopyObjectSimple,
|
deepCopyObjectSimple,
|
||||||
} from '../utilities/deepCopyObject.js'
|
} from '../utilities/deepCopyObject.js'
|
||||||
|
|
||||||
export {
|
export {
|
||||||
deepMerge,
|
deepMerge,
|
||||||
deepMergeWithCombinedArrays,
|
deepMergeWithCombinedArrays,
|
||||||
@@ -49,8 +49,8 @@ export {
|
|||||||
} from '../utilities/deepMerge.js'
|
} from '../utilities/deepMerge.js'
|
||||||
|
|
||||||
export { fieldSchemaToJSON } from '../utilities/fieldSchemaToJSON.js'
|
export { fieldSchemaToJSON } from '../utilities/fieldSchemaToJSON.js'
|
||||||
export { getDataByPath } from '../utilities/getDataByPath.js'
|
|
||||||
|
|
||||||
|
export { getDataByPath } from '../utilities/getDataByPath.js'
|
||||||
export { getSelectMode } from '../utilities/getSelectMode.js'
|
export { getSelectMode } from '../utilities/getSelectMode.js'
|
||||||
|
|
||||||
export { getSiblingData } from '../utilities/getSiblingData.js'
|
export { getSiblingData } from '../utilities/getSiblingData.js'
|
||||||
@@ -72,6 +72,8 @@ export { setsAreEqual } from '../utilities/setsAreEqual.js'
|
|||||||
export { default as toKebabCase } from '../utilities/toKebabCase.js'
|
export { default as toKebabCase } from '../utilities/toKebabCase.js'
|
||||||
|
|
||||||
export { unflatten } from '../utilities/unflatten.js'
|
export { unflatten } from '../utilities/unflatten.js'
|
||||||
|
|
||||||
|
export { validateMimeType } from '../utilities/validateMimeType.js'
|
||||||
export { wait } from '../utilities/wait.js'
|
export { wait } from '../utilities/wait.js'
|
||||||
export { default as wordBoundariesRegex } from '../utilities/wordBoundariesRegex.js'
|
export { default as wordBoundariesRegex } from '../utilities/wordBoundariesRegex.js'
|
||||||
export { versionDefaults } from '../versions/defaults.js'
|
export { versionDefaults } from '../versions/defaults.js'
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import type { Validate } from '../fields/config/types.js'
|
import type { Validate } from '../fields/config/types.js'
|
||||||
|
|
||||||
|
import { validateMimeType } from '../utilities/validateMimeType.js'
|
||||||
|
|
||||||
export const mimeTypeValidator =
|
export const mimeTypeValidator =
|
||||||
(mimeTypes: string[]): Validate =>
|
(mimeTypes: string[]): Validate =>
|
||||||
(val: string, { siblingData }) => {
|
(val: string, { siblingData }) => {
|
||||||
@@ -11,6 +13,6 @@ export const mimeTypeValidator =
|
|||||||
return 'Invalid file type'
|
return 'Invalid file type'
|
||||||
}
|
}
|
||||||
|
|
||||||
const cleanedMimeTypes = mimeTypes.map((v) => v.replace('*', ''))
|
const isValidMimeType = validateMimeType(val, mimeTypes)
|
||||||
return !cleanedMimeTypes.some((v) => val.startsWith(v)) ? `Invalid file type: '${val}'` : true
|
return isValidMimeType ? true : `Invalid file type: '${val}'`
|
||||||
}
|
}
|
||||||
|
|||||||
4
packages/payload/src/utilities/validateMimeType.ts
Normal file
4
packages/payload/src/utilities/validateMimeType.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export const validateMimeType = (mimeType: string, allowedMimeTypes: string[]): boolean => {
|
||||||
|
const cleanedMimeTypes = allowedMimeTypes.map((v) => v.replace('*', ''))
|
||||||
|
return cleanedMimeTypes.some((cleanedMimeType) => mimeType.startsWith(cleanedMimeType))
|
||||||
|
}
|
||||||
@@ -68,6 +68,7 @@ export const clientTranslationKeys = createClientTranslationKeys([
|
|||||||
'error:emailOrPasswordIncorrect',
|
'error:emailOrPasswordIncorrect',
|
||||||
'error:usernameOrPasswordIncorrect',
|
'error:usernameOrPasswordIncorrect',
|
||||||
'error:loadingDocument',
|
'error:loadingDocument',
|
||||||
|
'error:invalidFileType',
|
||||||
'error:logoutFailed',
|
'error:logoutFailed',
|
||||||
'error:noMatchedField',
|
'error:noMatchedField',
|
||||||
'error:notAllowedToAccessPage',
|
'error:notAllowedToAccessPage',
|
||||||
|
|||||||
@@ -3,10 +3,13 @@
|
|||||||
import type { JsonObject } from 'payload'
|
import type { JsonObject } from 'payload'
|
||||||
|
|
||||||
import { useModal } from '@faceless-ui/modal'
|
import { useModal } from '@faceless-ui/modal'
|
||||||
|
import { validateMimeType } from 'payload/shared'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import { toast } from 'sonner'
|
||||||
|
|
||||||
import { useConfig } from '../../providers/Config/index.js'
|
import { useConfig } from '../../providers/Config/index.js'
|
||||||
import { EditDepthProvider, useEditDepth } from '../../providers/EditDepth/index.js'
|
import { EditDepthProvider, useEditDepth } from '../../providers/EditDepth/index.js'
|
||||||
|
import { useTranslation } from '../../providers/Translation/index.js'
|
||||||
import { Drawer } from '../Drawer/index.js'
|
import { Drawer } from '../Drawer/index.js'
|
||||||
import { AddFilesView } from './AddFilesView/index.js'
|
import { AddFilesView } from './AddFilesView/index.js'
|
||||||
import { AddingFilesView } from './AddingFilesView/index.js'
|
import { AddingFilesView } from './AddingFilesView/index.js'
|
||||||
@@ -19,6 +22,7 @@ function DrawerContent() {
|
|||||||
const { closeModal } = useModal()
|
const { closeModal } = useModal()
|
||||||
const { collectionSlug, drawerSlug } = useBulkUpload()
|
const { collectionSlug, drawerSlug } = useBulkUpload()
|
||||||
const { config } = useConfig()
|
const { config } = useConfig()
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const uploadCollection = config.collections.find((col) => col.slug === collectionSlug)
|
const uploadCollection = config.collections.find((col) => col.slug === collectionSlug)
|
||||||
const uploadConfig = uploadCollection.upload
|
const uploadConfig = uploadCollection.upload
|
||||||
@@ -31,14 +35,18 @@ function DrawerContent() {
|
|||||||
if (
|
if (
|
||||||
uploadMimeTypes === undefined ||
|
uploadMimeTypes === undefined ||
|
||||||
uploadMimeTypes.length === 0 ||
|
uploadMimeTypes.length === 0 ||
|
||||||
uploadMimeTypes?.includes(candidateFile.type)
|
validateMimeType(candidateFile.type, uploadMimeTypes)
|
||||||
) {
|
) {
|
||||||
fileTransfer.items.add(candidateFile)
|
fileTransfer.items.add(candidateFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void addFiles(fileTransfer.files)
|
if (fileTransfer.files.length === 0) {
|
||||||
|
toast.error(t('error:invalidFileType'))
|
||||||
|
} else {
|
||||||
|
void addFiles(fileTransfer.files)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[addFiles, uploadMimeTypes],
|
[addFiles, t, uploadMimeTypes],
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!collectionSlug) {
|
if (!collectionSlug) {
|
||||||
|
|||||||
Reference in New Issue
Block a user