Skip to content

fix(asset-manager): enforce accept filter on drag-and-dropped files#6778

Open
geonsang-jo wants to merge 1 commit into
GrapesJS:devfrom
geonsang-jo:fix/image-video-validation
Open

fix(asset-manager): enforce accept filter on drag-and-dropped files#6778
geonsang-jo wants to merge 1 commit into
GrapesJS:devfrom
geonsang-jo:fix/image-video-validation

Conversation

@geonsang-jo

Copy link
Copy Markdown
Contributor

Fixes #6032

Problem

Dropping a non-image file (e.g. a video) onto an image component's asset upload zone uploads it and lets you select it as the image src. Reported as drag-drop-only.

Root cause

OpenAssets sets accept="image/*" on the upload input, which filters the native file picker — but browsers do NOT enforce accept on drag-and-dropped files. FileUploader.uploadFile() reads e.dataTransfer.files and uploads them with no validation.

Fix

Filter incoming files in uploadFile() against the input's accept value via a small pure helper (isFileAccepted), and bail out before uploading if none match. Backward-compatible: with no/*/* accept (generic asset managers), nothing is filtered. Custom uploadFile implementations are unaffected.

Tests

Unit tests for isFileAccepted (MIME wildcard / exact / extension / */*) and an integration test asserting a dropped video does not trigger an upload while a dropped image does.

Live demo

Side-by-side StackBlitz (double-click the image to open the Asset Manager, then drop a video vs an image):

Notes on behavior

  • The rejection is silent, consistent with the existing beforeUpload -> false cancel path (which also returns without emitting an event) and with the native accept picker (which silently omits non-matching files).
  • beforeUpload(files) now receives the filtered File[] instead of the raw FileList (type (files: any) => void | false, so type-compatible). Also, when every dropped file is rejected, beforeUpload is not invoked at all (the early return precedes it).

Questions for maintainers

  1. Rejected-file feedback: the AM has no "rejected/invalid" event today, and the existing block hook (beforeUpload -> false) is silent, so this PR keeps rejection silent. If you'd prefer consumers be able to react (e.g. show "only image files allowed"), I'm happy to add an opt-in event following the asset:upload:* convention, e.g. asset:upload:rejected with { files, accept }.
  2. Stale accept on the singleton uploader: OpenAssets.run() only sets accept when truthy and never resets it, and the uploader input is a singleton rendered once (AssetManager.render() builds AssetsView only on first open). So after an image picker sets accept="image/*", a later generic AssetManager.open() with no accept inherits the stale image/* — before this PR that only affected the native picker, now it also makes drag-drop silently filter non-image files there. I can reset it on each open (uploadEl.setAttribute('accept', accept || '*/*')) here or as a follow-up.

Browsers don't apply the input `accept` attribute to dropped files, so
videos dropped on an image upload zone were uploaded and selectable.
Filter dropped files against `accept` in FileUploader.uploadFile().

Closes GrapesJS#6032
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: Image Component allows upload and selection of video files via drag and drop

1 participant