diff --git a/web/app/components/base/file-uploader/constants.ts b/web/app/components/base/file-uploader/constants.ts
index f738121363..e6cc2995f9 100644
--- a/web/app/components/base/file-uploader/constants.ts
+++ b/web/app/components/base/file-uploader/constants.ts
@@ -1,2 +1,3 @@
export const FILE_SIZE_LIMIT = 15 * 1024 * 1024
+
export const FILE_URL_REGEX = /^(https?|ftp):\/\//
diff --git a/web/app/components/base/file-uploader/file-uploader-in-attachment/file-item.tsx b/web/app/components/base/file-uploader/file-uploader-in-attachment/file-item.tsx
index d125514db3..45d57267aa 100644
--- a/web/app/components/base/file-uploader/file-uploader-in-attachment/file-item.tsx
+++ b/web/app/components/base/file-uploader/file-uploader-in-attachment/file-item.tsx
@@ -31,8 +31,8 @@ const FileInAttachmentItem = ({
onRemove,
onReUpload,
}: FileInAttachmentItemProps) => {
- const { id, name, progress, supportFileType, base64Url, url } = file
- const ext = getFileExtension(name)
+ const { id, name, type, progress, supportFileType, base64Url, url } = file
+ const ext = getFileExtension(name, type)
const isImageFile = supportFileType === SupportUploadFileTypes.image
return (
@@ -52,7 +52,7 @@ const FileInAttachmentItem = ({
{
!isImageFile && (
)
diff --git a/web/app/components/base/file-uploader/file-uploader-in-chat-input/file-item.tsx b/web/app/components/base/file-uploader/file-uploader-in-chat-input/file-item.tsx
index 4c35f65abc..f8c5b13474 100644
--- a/web/app/components/base/file-uploader/file-uploader-in-chat-input/file-item.tsx
+++ b/web/app/components/base/file-uploader/file-uploader-in-chat-input/file-item.tsx
@@ -29,8 +29,8 @@ const FileItem = ({
onRemove,
onReUpload,
}: FileItemProps) => {
- const { id, name, progress } = file
- const ext = getFileExtension(name)
+ const { id, name, type, progress } = file
+ const ext = getFileExtension(name, type)
const uploadError = progress === -1
return (
@@ -59,7 +59,7 @@ const FileItem = ({
{
diff --git a/web/app/components/base/file-uploader/hooks.ts b/web/app/components/base/file-uploader/hooks.ts
index 31a0fdbee6..5e126a87b5 100644
--- a/web/app/components/base/file-uploader/hooks.ts
+++ b/web/app/components/base/file-uploader/hooks.ts
@@ -11,7 +11,6 @@ import type { FileEntity } from './types'
import { useFileStore } from './store'
import {
fileUpload,
- getFileNameFromUrl,
getSupportFileType,
isAllowedFileExtension,
} from './utils'
@@ -97,16 +96,15 @@ export const useFile = (fileConfig: FileUpload) => {
const handleLoadFileFromLink = useCallback((url: string) => {
const allowedFileTypes = fileConfig.allowed_file_types
- const fileName = getFileNameFromUrl(url)
const uploadingFile = {
id: uuid4(),
- name: fileName,
+ name: url,
type: '',
size: 0,
progress: 0,
transferMethod: TransferMethod.remote_url,
- supportFileType: getSupportFileType(fileName, allowedFileTypes?.includes(SupportUploadFileTypes.custom)),
+ supportFileType: '',
url,
}
handleAddFile(uploadingFile)
@@ -117,6 +115,7 @@ export const useFile = (fileConfig: FileUpload) => {
type: res.file_type,
size: res.file_length,
progress: 100,
+ supportFileType: getSupportFileType(url, res.file_type, allowedFileTypes?.includes(SupportUploadFileTypes.custom)),
}
handleUpdateFile(newFile)
}).catch(() => {
@@ -137,7 +136,7 @@ export const useFile = (fileConfig: FileUpload) => {
}, [fileStore])
const handleLocalFileUpload = useCallback((file: File) => {
- if (!isAllowedFileExtension(file.name, fileConfig.allowed_file_types || [], fileConfig.allowed_file_extensions || [])) {
+ if (!isAllowedFileExtension(file.name, file.type, fileConfig.allowed_file_types || [], fileConfig.allowed_file_extensions || [])) {
notify({ type: 'error', message: t('common.fileUploader.fileExtensionNotSupport') })
return
}
@@ -159,7 +158,7 @@ export const useFile = (fileConfig: FileUpload) => {
size: file.size,
progress: 0,
transferMethod: TransferMethod.local_file,
- supportFileType: getSupportFileType(file.name, allowedFileTypes?.includes(SupportUploadFileTypes.custom)),
+ supportFileType: getSupportFileType(file.name, file.type, allowedFileTypes?.includes(SupportUploadFileTypes.custom)),
originalFile: file,
base64Url: isImage ? reader.result as string : '',
}
diff --git a/web/app/components/base/file-uploader/utils.ts b/web/app/components/base/file-uploader/utils.ts
index 78ca453073..d2e3493ce2 100644
--- a/web/app/components/base/file-uploader/utils.ts
+++ b/web/app/components/base/file-uploader/utils.ts
@@ -1,3 +1,4 @@
+import mime from 'mime'
import { FileAppearanceTypeEnum } from './types'
import type { FileEntity } from './types'
import { upload } from '@/service/base'
@@ -39,43 +40,65 @@ export const fileUpload: FileUpload = ({
})
}
-export const getFileAppearanceType = (fileType: string) => {
- if (!fileType)
- return FileAppearanceTypeEnum.custom
+export const getFileExtension = (fileName: string, fileMimetype: string) => {
+ if (fileMimetype)
+ return mime.getExtension(fileMimetype) || ''
- if (fileType.includes('image'))
- return FileAppearanceTypeEnum.image
+ if (fileName) {
+ const fileNamePair = fileName.split('.')
+ const fileNamePairLength = fileNamePair.length
- if (fileType.includes('video'))
- return FileAppearanceTypeEnum.video
-
- if (fileType.includes('audio'))
- return FileAppearanceTypeEnum.audio
-
- if (fileType.includes('pdf'))
- return FileAppearanceTypeEnum.pdf
-
- return FileAppearanceTypeEnum.custom
-}
-
-export const getFileExtension = (fileName: string) => {
- if (!fileName)
- return ''
-
- const fileNamePair = fileName.split('.')
- const fileNamePairLength = fileNamePair.length
-
- if (fileNamePairLength > 1)
- return fileNamePair[fileNamePairLength - 1]
+ if (fileNamePairLength > 1)
+ return fileNamePair[fileNamePairLength - 1]
+ }
return ''
}
-export const getSupportFileType = (fileName: string, isCustom?: boolean) => {
+export const getFileAppearanceType = (fileName: string, fileMimetype: string) => {
+ const extension = getFileExtension(fileName, fileMimetype)
+
+ if (extension === 'gif')
+ return FileAppearanceTypeEnum.gif
+
+ if (FILE_EXTS.image.includes(extension.toUpperCase()))
+ return FileAppearanceTypeEnum.image
+
+ if (FILE_EXTS.video.includes(extension.toUpperCase()))
+ return FileAppearanceTypeEnum.video
+
+ if (FILE_EXTS.audio.includes(extension.toUpperCase()))
+ return FileAppearanceTypeEnum.audio
+
+ if (extension === 'html')
+ return FileAppearanceTypeEnum.code
+
+ if (extension === 'pdf')
+ return FileAppearanceTypeEnum.pdf
+
+ if (extension === 'md' || extension === 'markdown')
+ return FileAppearanceTypeEnum.markdown
+
+ if (extension === 'xlsx' || extension === 'xls')
+ return FileAppearanceTypeEnum.excel
+
+ if (extension === 'docx' || extension === 'doc')
+ return FileAppearanceTypeEnum.word
+
+ if (extension === 'pptx' || extension === 'ppt')
+ return FileAppearanceTypeEnum.ppt
+
+ if (FILE_EXTS.document.includes(extension.toUpperCase()))
+ return FileAppearanceTypeEnum.document
+
+ return FileAppearanceTypeEnum.custom
+}
+
+export const getSupportFileType = (fileName: string, fileMimetype: string, isCustom?: boolean) => {
if (isCustom)
return SupportUploadFileTypes.custom
- const extension = getFileExtension(fileName)
+ const extension = getFileExtension(fileName, fileMimetype)
for (const key in FILE_EXTS) {
if ((FILE_EXTS[key]).includes(extension.toUpperCase()))
return key
@@ -105,6 +128,6 @@ export const getSupportFileExtensionList = (allowFileTypes: string[], allowFileE
return allowFileTypes.map(type => FILE_EXTS[type]).flat()
}
-export const isAllowedFileExtension = (fileName: string, allowFileTypes: string[], allowFileExtensions: string[]) => {
- return getSupportFileExtensionList(allowFileTypes, allowFileExtensions).includes(getFileExtension(fileName).toUpperCase())
+export const isAllowedFileExtension = (fileName: string, fileMimetype: string, allowFileTypes: string[], allowFileExtensions: string[]) => {
+ return getSupportFileExtensionList(allowFileTypes, allowFileExtensions).includes(getFileExtension(fileName, fileMimetype).toUpperCase())
}
diff --git a/web/package.json b/web/package.json
index b775d87184..77fb842737 100644
--- a/web/package.json
+++ b/web/package.json
@@ -60,6 +60,7 @@
"lexical": "^0.16.0",
"lodash-es": "^4.17.21",
"mermaid": "10.4.0",
+ "mime": "^4.0.4",
"negotiator": "^0.6.3",
"next": "^14.1.1",
"next-nprogress-bar": "^2.3.8",
diff --git a/web/yarn.lock b/web/yarn.lock
index bec2059a47..d1eede0f70 100644
--- a/web/yarn.lock
+++ b/web/yarn.lock
@@ -7183,6 +7183,11 @@ mime-types@^2.1.12:
dependencies:
mime-db "1.52.0"
+mime@^4.0.4:
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/mime/-/mime-4.0.4.tgz#9f851b0fc3c289d063b20a7a8055b3014b25664b"
+ integrity sha512-v8yqInVjhXyqP6+Kw4fV3ZzeMRqEW6FotRsKXjRS5VMTNIuXsdRoAvklpoRgSqXm6o9VNH4/C0mgedko9DdLsQ==
+
mimic-fn@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz"
@@ -8816,7 +8821,14 @@ stringify-entities@^4.0.0:
character-entities-html4 "^2.0.0"
character-entities-legacy "^3.0.0"
-"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
+ version "6.0.1"
+ resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
+ integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
+ dependencies:
+ ansi-regex "^5.0.1"
+
+strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -9653,8 +9665,7 @@ word-wrap@^1.2.3:
resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz"
integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
-"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
- name wrap-ansi-cjs
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
version "7.0.0"
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@@ -9672,6 +9683,15 @@ wrap-ansi@^6.2.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"
+wrap-ansi@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz"
+ integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
+ dependencies:
+ ansi-styles "^4.0.0"
+ string-width "^4.1.0"
+ strip-ansi "^6.0.0"
+
wrap-ansi@^8.1.0:
version "8.1.0"
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz"