From 0edb2de4e80c341e80cf38812264f7e1fbb11a2f Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Mon, 10 Apr 2023 14:27:49 +0800 Subject: [PATCH] refactor(console): guard file types in the file input dialog box (#3673) --- .../Uploader/FileUploader/index.tsx | 39 +++++++++++++------ .../translation/admin-console/components.ts | 1 + .../translation/admin-console/components.ts | 1 + .../translation/admin-console/components.ts | 1 + .../translation/admin-console/components.ts | 1 + .../translation/admin-console/components.ts | 1 + .../translation/admin-console/components.ts | 1 + .../translation/admin-console/components.ts | 1 + .../translation/admin-console/components.ts | 1 + .../translation/admin-console/components.ts | 1 + .../translation/admin-console/components.ts | 1 + .../translation/admin-console/components.ts | 1 + .../translation/admin-console/components.ts | 1 + .../translation/admin-console/components.ts | 1 + .../translation/admin-console/components.ts | 1 + .../translation/admin-console/components.ts | 1 + 16 files changed, 42 insertions(+), 12 deletions(-) diff --git a/packages/console/src/components/Uploader/FileUploader/index.tsx b/packages/console/src/components/Uploader/FileUploader/index.tsx index 0da2b89ed..b4106b5bf 100644 --- a/packages/console/src/components/Uploader/FileUploader/index.tsx +++ b/packages/console/src/components/Uploader/FileUploader/index.tsx @@ -2,7 +2,7 @@ import type { AllowedUploadMimeType, UserAssets } from '@logto/schemas'; import { maxUploadFileSize } from '@logto/schemas'; import classNames from 'classnames'; import { useCallback, useEffect, useState } from 'react'; -import { useDropzone } from 'react-dropzone'; +import { type FileRejection, useDropzone } from 'react-dropzone'; import { useTranslation } from 'react-i18next'; import UploaderIcon from '@/assets/images/upload.svg'; @@ -43,35 +43,49 @@ function FileUploader({ const api = useApi(); const onDrop = useCallback( - async (acceptedFiles: File[]) => { + async (acceptedFiles: File[] = [], fileRejection: FileRejection[] = []) => { setUploadError(undefined); - const selectedFile = acceptedFiles[0]; + if (fileRejection.length > 1) { + setUploadError(t('components.uploader.error_file_count')); - if (!selectedFile) { return; } - if (!allowedMimeTypes.map(String).includes(selectedFile.type)) { - setUploadError( - t('components.uploader.error_file_type', { - extensions: convertToFileExtensionArray(allowedMimeTypes), - }) - ); + const rejectedFile = fileRejection[0]?.file; + if (rejectedFile) { + /** + * Note: + * We need to display this invalid file type error, since the user can select an invalid file type by modifying the file input dialog settings. + */ + if (!allowedMimeTypes.map(String).includes(rejectedFile.type)) { + setUploadError( + t('components.uploader.error_file_type', { + extensions: convertToFileExtensionArray(allowedMimeTypes), + }) + ); + } + + return; + } + + const acceptedFile = acceptedFiles[0]; + + if (!acceptedFile) { return; } const fileSizeLimit = Math.min(maxSize, maxUploadFileSize); - if (selectedFile.size > fileSizeLimit) { + if (acceptedFile.size > fileSizeLimit) { setUploadError(t('components.uploader.error_file_size', { size: fileSizeLimit / 1024 })); return; } const formData = new FormData(); - formData.append('file', selectedFile); + formData.append('file', acceptedFile); try { setIsUploading(true); @@ -91,6 +105,7 @@ function FileUploader({ onDrop, disabled: isUploading, multiple: false, + accept: Object.fromEntries(allowedMimeTypes.map((mimeType) => [mimeType, []])), }); return ( diff --git a/packages/phrases/src/locales/de/translation/admin-console/components.ts b/packages/phrases/src/locales/de/translation/admin-console/components.ts index e84e3f4c7..5f9829afd 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/components.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/components.ts @@ -8,6 +8,7 @@ const components = { error_file_size: 'Dateigröße ist zu groß. Bitte lade eine Datei unter {{size, number}}KB hoch.', error_file_type: 'Dateityp wird nicht unterstützt. Nur {{extensions, list(style: narrow; type: conjunction;)}}.', + error_file_count: 'Sie können nur 1 Datei hochladen.', }, }; diff --git a/packages/phrases/src/locales/en/translation/admin-console/components.ts b/packages/phrases/src/locales/en/translation/admin-console/components.ts index 0c86ff769..b6b8c56d7 100644 --- a/packages/phrases/src/locales/en/translation/admin-console/components.ts +++ b/packages/phrases/src/locales/en/translation/admin-console/components.ts @@ -8,6 +8,7 @@ const components = { error_file_size: 'File size is too large. Please upload a file under {{size, number}}KB.', error_file_type: 'File type is not supported. {{extensions, list(style: narrow; type: conjunction;)}} only.', + error_file_count: 'You can only upload 1 file.', }, }; diff --git a/packages/phrases/src/locales/es/translation/admin-console/components.ts b/packages/phrases/src/locales/es/translation/admin-console/components.ts index 70c823a4a..3df9cbdca 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/components.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/components.ts @@ -9,6 +9,7 @@ const components = { 'El archivo es demasiado grande. Por favor, sube un archivo de menos de {{size, number}}KB.', error_file_type: 'El tipo de archivo no es compatible. Solo {{extensions, list(style: narrow; type: conjunction;)}}.', + error_file_count: 'Solo puedes subir 1 archivo.', }, }; diff --git a/packages/phrases/src/locales/fr/translation/admin-console/components.ts b/packages/phrases/src/locales/fr/translation/admin-console/components.ts index 22aa8cd43..13c663fd0 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/components.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/components.ts @@ -9,6 +9,7 @@ const components = { 'La taille du fichier est trop grande. Veuillez télécharger un fichier de moins de {{size, number}}Ko.', error_file_type: "Le type de fichier n'est pas pris en charge. Uniquement {{extensions, list(style: narrow; type: conjunction;)}}.", + error_file_count: 'You can only upload 1 file.', // UNTRANSLATED }, }; diff --git a/packages/phrases/src/locales/it/translation/admin-console/components.ts b/packages/phrases/src/locales/it/translation/admin-console/components.ts index 5bd97b12b..a74eaf637 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/components.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/components.ts @@ -8,6 +8,7 @@ const components = { error_file_size: 'Il file è troppo grande. Carica un file sotto i {{size, number}}KB.', error_file_type: 'Formato file non supportato. Sono accettati solo formati {{extensions, list(style: narrow; type: conjunction;)}}.', + error_file_count: 'Puoi caricare solo 1 file.', }, }; diff --git a/packages/phrases/src/locales/ja/translation/admin-console/components.ts b/packages/phrases/src/locales/ja/translation/admin-console/components.ts index b8f235204..3a1e2094c 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/components.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/components.ts @@ -8,6 +8,7 @@ const components = { error_file_size: '{{size, number}}KB以下のファイルをアップロードしてください。', error_file_type: '{{extensions, list(style: narrow; type: conjunction;)}}のみサポートされます。', + error_file_count: 'You can only upload 1 file.', // UNTRANSLATED }, }; diff --git a/packages/phrases/src/locales/ko/translation/admin-console/components.ts b/packages/phrases/src/locales/ko/translation/admin-console/components.ts index 777d2c40d..927cdab8f 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/components.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/components.ts @@ -8,6 +8,7 @@ const components = { error_file_size: '파일 크기가 너무 커요. {{size, number}}KB 미만의 파일을 업로드해 주세요.', error_file_type: '지원되지 않는 파일 유형이에요. {{extensions, list(style: narrow; type: conjunction;)}} 파일만 사용 가능해요.', + error_file_count: 'You can only upload 1 file.', // UNTRANSLATED }, }; diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/components.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/components.ts index e7dc053b0..ea24515d9 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/components.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/components.ts @@ -9,6 +9,7 @@ const components = { 'Plik jest zbyt duży. Wyślij plik o rozmiarze mniejszym niż {{size, number}}KB.', error_file_type: 'Ten typ pliku nie jest obsługiwany. Obsługiwane formaty to {{extensions, list(style: narrow; type: conjunction;)}}.', + error_file_count: 'Możesz przesłać tylko 1 plik.', }, }; diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/components.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/components.ts index c9463dbea..cdcbca8ea 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/components.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/components.ts @@ -9,6 +9,7 @@ const components = { 'Tamanho do arquivo é muito grande. Por favor, envie um arquivo abaixo de {{size, number}}KB.', error_file_type: 'Tipo de arquivo não é suportado. Apenas {{extensions, list(style: narrow; type: conjunction;)}}.', + error_file_count: 'Você só pode enviar 1 arquivo.', }, }; diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/components.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/components.ts index f92b48237..30826172e 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/components.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/components.ts @@ -9,6 +9,7 @@ const components = { 'O ficheiro é demasiado grande. Por favor carregue um ficheiro com menos de {{size, number}}KB.', error_file_type: 'O tipo de ficheiro não é suportado. Apenas {{extensions, list(style: narrow; type: conjunction;)}}.', + error_file_count: 'Só é possível carregar 1 ficheiro.', }, }; diff --git a/packages/phrases/src/locales/ru/translation/admin-console/components.ts b/packages/phrases/src/locales/ru/translation/admin-console/components.ts index 7947e13fe..66a438177 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/components.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/components.ts @@ -9,6 +9,7 @@ const components = { 'Размер файла слишком большой. Пожалуйста, загрузите файл размером менее {{size, number}} КБ.', error_file_type: 'Тип файла не поддерживается. Допустимы только файлы типа {{extensions, list(style: narrow; type: conjunction;)}}.', + error_file_count: 'You can only upload 1 file.', // UNTRANSLATED }, }; diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/components.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/components.ts index 5878d1a07..8b59535bb 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/components.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/components.ts @@ -9,6 +9,7 @@ const components = { 'Dosya boyutu çok büyük. Lütfen {{size, number}}KB altında bir dosya yükleyin.', error_file_type: 'Dosya türü desteklenmiyor. Yalnızca {{extensions, list(style: narrow; type: conjunction;)}} dosyaları kabul edilir.', + error_file_count: 'Sadece 1 dosya yükleyebilirsiniz.', }, }; diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/components.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/components.ts index a4689316d..9b58000dd 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/components.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/components.ts @@ -8,6 +8,7 @@ const components = { error_file_size: '文件太大了,请上传小于 {{size, number}}KB 的文件。', error_file_type: '不支持该文件类型。只支持 {{extensions, list(style: narrow; type: conjunction;)}} 格式的文件。', + error_file_count: '只能上传一个文件。', }, }; diff --git a/packages/phrases/src/locales/zh-hk/translation/admin-console/components.ts b/packages/phrases/src/locales/zh-hk/translation/admin-console/components.ts index 2ff9ac681..77307e170 100644 --- a/packages/phrases/src/locales/zh-hk/translation/admin-console/components.ts +++ b/packages/phrases/src/locales/zh-hk/translation/admin-console/components.ts @@ -8,6 +8,7 @@ const components = { error_file_size: '檔案太大了,請上傳小於 {{size, number}}KB 的檔案。', error_file_type: '不支援該檔案格式,只支援 {{extensions, list(style: narrow; type: conjunction;)}} 格式的檔案。', + error_file_count: '你只能上載一個檔案。', }, }; diff --git a/packages/phrases/src/locales/zh-tw/translation/admin-console/components.ts b/packages/phrases/src/locales/zh-tw/translation/admin-console/components.ts index 72e036152..22514dba0 100644 --- a/packages/phrases/src/locales/zh-tw/translation/admin-console/components.ts +++ b/packages/phrases/src/locales/zh-tw/translation/admin-console/components.ts @@ -8,6 +8,7 @@ const components = { error_file_size: '文件太大了,請上傳小於 {{size, number}}KB 的文件。', error_file_type: '不支持該文件類型。只支持 {{extensions, list(style: narrow; type: conjunction;)}} 格式的文件。', + error_file_count: '您只能上傳一個檔案。', }, };