From b9c6183e524411f831c3142aa88b17aa3e3a0fbb Mon Sep 17 00:00:00 2001 From: Aleksandra Bozek Date: Wed, 16 Sep 2026 13:41:35 +0200 Subject: [PATCH 1/2] IBX-8651: Added file type validation for image fields --- .../public/js/scripts/fieldType/base/base-preview-field.js | 2 +- .../views/themes/admin/ui/field_type/edit/ezimage.html.twig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bundle/Resources/public/js/scripts/fieldType/base/base-preview-field.js b/src/bundle/Resources/public/js/scripts/fieldType/base/base-preview-field.js index 71410d2865..71d4f2b573 100644 --- a/src/bundle/Resources/public/js/scripts/fieldType/base/base-preview-field.js +++ b/src/bundle/Resources/public/js/scripts/fieldType/base/base-preview-field.js @@ -80,7 +80,7 @@ const [file] = event.dataTransfer.files; if (!this.checkCanDrop(file)) { - return; + return this.showFileTypeError(); } if (this.maxFileSize > 0 && file.size > this.maxFileSize) { diff --git a/src/bundle/Resources/views/themes/admin/ui/field_type/edit/ezimage.html.twig b/src/bundle/Resources/views/themes/admin/ui/field_type/edit/ezimage.html.twig index 66c8464730..64b0d3655d 100644 --- a/src/bundle/Resources/views/themes/admin/ui/field_type/edit/ezimage.html.twig +++ b/src/bundle/Resources/views/themes/admin/ui/field_type/edit/ezimage.html.twig @@ -6,7 +6,7 @@ {% set preview_block_name = 'ezimage_preview' %} {% set max_file_size = min(form.parent.vars.value.fieldDefinition.validatorConfiguration.FileSizeValidator.maxFileSize * 1024 * 1024, max_upload_size|round) %} - {% if mime_types is defined %} + {% if mime_types is defined and mime_types is not empty %} {% set attr = attr|merge({'data-allowed-file-types': mime_types|join(','), 'accept': mime_types|join(',') }) %} {% else %} {% set attr = attr|merge({'accept': 'image/*' }) %} From 980f5bde09e9034c7eb3fc31b443c045e564c23b Mon Sep 17 00:00:00 2001 From: Aleksandra Bozek Date: Mon, 19 Oct 2026 15:32:42 +0200 Subject: [PATCH 2/2] Validated file type on input change --- .../scripts/fieldType/base/base-file-field.js | 20 +++++++++++++++++-- .../fieldType/base/base-preview-field.js | 5 ++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/bundle/Resources/public/js/scripts/fieldType/base/base-file-field.js b/src/bundle/Resources/public/js/scripts/fieldType/base/base-file-field.js index dba938d38d..abf7354828 100644 --- a/src/bundle/Resources/public/js/scripts/fieldType/base/base-file-field.js +++ b/src/bundle/Resources/public/js/scripts/fieldType/base/base-file-field.js @@ -16,7 +16,6 @@ const isRequired = input.required || this.fieldContainer.classList.contains('ibexa-field-edit--required'); const dataMaxSize = +input.dataset.maxFileSize; const maxFileSize = parseInt(dataMaxSize, 10); - const { allowedFileTypes = [] } = input.dataset; const isEmpty = input.files && !input.files.length && dataContainer && !dataContainer.hasAttribute('hidden'); let result = { isError: false }; @@ -33,13 +32,30 @@ result = this.validateFileSize(); } - if (!isEmpty && allowedFileTypes.length > 0 && file && !allowedFileTypes.includes(file.type)) { + if (!isEmpty && file && !this.isFileTypeAllowed(file, input)) { result = this.showFileTypeError(); } return result; } + isFileTypeAllowed(file, input) { + const { allowedFileTypes = '' } = input.dataset; + const { accept } = input; + + if (!allowedFileTypes.length && !accept.length) { + return true; + } + + if (accept.length && accept.includes('/*')) { + const pattern = accept.substr(0, accept.indexOf('*')); + + return file.type.includes(pattern); + } + + return allowedFileTypes.includes(file.type); + } + validateFileSize() { return this.showFileSizeError(); } diff --git a/src/bundle/Resources/public/js/scripts/fieldType/base/base-preview-field.js b/src/bundle/Resources/public/js/scripts/fieldType/base/base-preview-field.js index 71d4f2b573..d0d32e9dbb 100644 --- a/src/bundle/Resources/public/js/scripts/fieldType/base/base-preview-field.js +++ b/src/bundle/Resources/public/js/scripts/fieldType/base/base-preview-field.js @@ -140,7 +140,10 @@ * @param {Event} event */ handleInputChange(event) { - if (this.maxFileSize > 0 && event.currentTarget.files[0].size > this.maxFileSize) { + const [file] = event.currentTarget.files; + const isFileSizeExceeded = this.maxFileSize > 0 && file.size > this.maxFileSize; + + if (isFileSizeExceeded || !this.checkCanDrop(file)) { return this.resetInputField(); }