You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Split out of #37174 (finding 8). The Asset Picker (libs/ui/src/lib/components/dot-asset-picker) already restricts what you can browse to the field that opened it, but not what you can upload. An Image field, or a Story Block dotVideo node, lets you upload any file type from inside the picker — so an Image field can end up holding a PDF and a video node an mp3, exactly the case ASSET_PICKER_MIME_TYPES exists to prevent on the browse side.
Decision taken during refinement: the upload flow is restricted to the mode that opened the picker, using the same restriction config.mimeTypes already applies to browsing.
Root cause notes
buildAssetPickerConfig() already knows the entry point: ASSET_PICKER_MIME_TYPES maps image → ['image/*'], video → ['video/*'], audio → ['audio/*'], and config.mimeTypes is applied to every browse request.
Nothing carries that restriction into the upload path:
the hidden <input type="file" #fileInput hidden /> in dot-asset-picker.component.html has no accept attribute, so the OS dialog offers every file;
dot-upload-dropzone accepts any dropped file;
dot-upload-type-selector always offers both Asset and File with the same copy regardless of mode;
#resolveFilesUpload() / #uploadByBaseType() in dot-asset-picker.component.ts do no type validation before uploading.
Steps to Reproduce
Edit a content type with an Image field and open its asset picker.
Click Upload → the Asset/File popover appears.
Pick either option — the OS file dialog offers every file type, and a PDF or a .zip uploads and lands in an image field's folder just fine.
Repeat from the Story Block/video node: the same unrestricted upload is offered where only video should be.
📎 See Screenshots C and D on #37174 — the Asset/File upload popover (identical in every mode) and the Story Block /video entry point.
Acceptance Criteria
The picker's upload flow honours the mode it was opened in: an Image field offers only images, a Story Block dotVideo node only video, dotAudio only audio; the generic File field keeps offering everything
The restriction is derived from the config the picker already carries (ASSET_PICKER_MIME_TYPES / config.mimeTypes) — no second, hand-maintained list of types
The hidden file input carries a matching accept attribute, so the OS file dialog filters before the user picks
The drag-and-drop dropzone rejects a file outside the allowed types and says why, instead of uploading it
A file that slips through anyway (accept is a hint, not a guarantee) is rejected client-side before the upload request, with a clear message naming the allowed types
The Asset/File type popover reflects the mode — options that cannot apply are not offered, and the copy does not promise "images, documents and media" in a video-only context
After a successful scoped upload, the new asset appears in the list and can be selected without reopening the picker
Regression coverage
Asset Picker specs cover upload restriction per mode: accept attribute, dropzone rejection, and pre-upload validation
The generic File field's unrestricted upload is covered so the scoping does not over-reach
dotCMS Version
Latest from main (includes PR #36848, merged as 8c725747c0).
Problem Statement
Split out of #37174 (finding 8). The Asset Picker (
libs/ui/src/lib/components/dot-asset-picker) already restricts what you can browse to the field that opened it, but not what you can upload. An Image field, or a Story BlockdotVideonode, lets you upload any file type from inside the picker — so an Image field can end up holding a PDF and a video node an mp3, exactly the caseASSET_PICKER_MIME_TYPESexists to prevent on the browse side.Decision taken during refinement: the upload flow is restricted to the mode that opened the picker, using the same restriction
config.mimeTypesalready applies to browsing.Root cause notes
buildAssetPickerConfig()already knows the entry point:ASSET_PICKER_MIME_TYPESmapsimage→['image/*'],video→['video/*'],audio→['audio/*'], andconfig.mimeTypesis applied to every browse request.<input type="file" #fileInput hidden />indot-asset-picker.component.htmlhas noacceptattribute, so the OS dialog offers every file;dot-upload-dropzoneaccepts any dropped file;dot-upload-type-selectoralways offers both Asset and File with the same copy regardless of mode;#resolveFilesUpload()/#uploadByBaseType()indot-asset-picker.component.tsdo no type validation before uploading.Steps to Reproduce
.zipuploads and lands in an image field's folder just fine./videonode: the same unrestricted upload is offered where only video should be.Acceptance Criteria
dotVideonode only video,dotAudioonly audio; the generic File field keeps offering everythingASSET_PICKER_MIME_TYPES/config.mimeTypes) — no second, hand-maintained list of typesacceptattribute, so the OS file dialog filters before the user picksacceptis a hint, not a guarantee) is rejected client-side before the upload request, with a clear message naming the allowed typesRegression coverage
acceptattribute, dropzone rejection, and pre-upload validationdotCMS Version
Latest from
main(includes PR #36848, merged as8c725747c0).Severity
Medium - Some functionality impacted
Links