@strapi/upload 5.48.1 → 5.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (419) hide show
  1. package/dist/admin/ai/components/AIAssetCard.js +13 -12
  2. package/dist/admin/ai/components/AIAssetCard.js.map +1 -1
  3. package/dist/admin/ai/components/AIAssetCard.mjs +11 -11
  4. package/dist/admin/ai/components/AIAssetCard.mjs.map +1 -1
  5. package/dist/admin/ai/components/AIUploadModal.js +3 -3
  6. package/dist/admin/ai/components/AIUploadModal.mjs +0 -1
  7. package/dist/admin/ai/components/AIUploadModal.mjs.map +1 -1
  8. package/dist/admin/components/AssetCard/AssetCard.js +3 -4
  9. package/dist/admin/components/AssetCard/AssetCard.js.map +1 -1
  10. package/dist/admin/components/AssetCard/AssetCard.mjs +4 -5
  11. package/dist/admin/components/AssetCard/AssetCard.mjs.map +1 -1
  12. package/dist/admin/components/AssetCard/AssetCardBase.js +0 -1
  13. package/dist/admin/components/AssetCard/AssetCardBase.js.map +1 -1
  14. package/dist/admin/components/AssetCard/AssetCardBase.mjs +0 -1
  15. package/dist/admin/components/AssetCard/AssetCardBase.mjs.map +1 -1
  16. package/dist/admin/components/AssetCard/ImageAssetCard.js +0 -1
  17. package/dist/admin/components/AssetCard/ImageAssetCard.js.map +1 -1
  18. package/dist/admin/components/AssetCard/ImageAssetCard.mjs +0 -1
  19. package/dist/admin/components/AssetCard/ImageAssetCard.mjs.map +1 -1
  20. package/dist/admin/components/AssetCard/UploadingAssetCard.js +6 -6
  21. package/dist/admin/components/AssetCard/UploadingAssetCard.js.map +1 -1
  22. package/dist/admin/components/AssetCard/UploadingAssetCard.mjs +4 -5
  23. package/dist/admin/components/AssetCard/UploadingAssetCard.mjs.map +1 -1
  24. package/dist/admin/components/AssetCard/VideoAssetCard.js +3 -3
  25. package/dist/admin/components/AssetCard/VideoAssetCard.mjs +0 -1
  26. package/dist/admin/components/AssetCard/VideoAssetCard.mjs.map +1 -1
  27. package/dist/admin/components/AssetDialog/AssetDialog.js +3 -3
  28. package/dist/admin/components/AssetDialog/AssetDialog.mjs +0 -1
  29. package/dist/admin/components/AssetDialog/AssetDialog.mjs.map +1 -1
  30. package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.js +0 -1
  31. package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.js.map +1 -1
  32. package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.mjs +0 -1
  33. package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.mjs.map +1 -1
  34. package/dist/admin/components/AssetDialog/BrowseStep/Filters.js +3 -3
  35. package/dist/admin/components/AssetDialog/BrowseStep/Filters.mjs +0 -1
  36. package/dist/admin/components/AssetDialog/BrowseStep/Filters.mjs.map +1 -1
  37. package/dist/admin/components/AssetDialog/BrowseStep/PaginationFooter/Pagination.js +3 -2
  38. package/dist/admin/components/AssetDialog/BrowseStep/PaginationFooter/Pagination.js.map +1 -1
  39. package/dist/admin/components/AssetDialog/BrowseStep/SearchAsset/SearchAsset.js +3 -3
  40. package/dist/admin/components/AssetDialog/BrowseStep/SearchAsset/SearchAsset.mjs +0 -1
  41. package/dist/admin/components/AssetDialog/BrowseStep/SearchAsset/SearchAsset.mjs.map +1 -1
  42. package/dist/admin/components/AssetDialog/SelectedStep/SelectedStep.js +0 -1
  43. package/dist/admin/components/AssetDialog/SelectedStep/SelectedStep.js.map +1 -1
  44. package/dist/admin/components/AssetDialog/SelectedStep/SelectedStep.mjs +0 -1
  45. package/dist/admin/components/AssetDialog/SelectedStep/SelectedStep.mjs.map +1 -1
  46. package/dist/admin/components/AssetGridList/Draggable.js +3 -2
  47. package/dist/admin/components/AssetGridList/Draggable.js.map +1 -1
  48. package/dist/admin/components/Breadcrumbs/CrumbSimpleMenuAsync.js +3 -3
  49. package/dist/admin/components/Breadcrumbs/CrumbSimpleMenuAsync.mjs +0 -1
  50. package/dist/admin/components/Breadcrumbs/CrumbSimpleMenuAsync.mjs.map +1 -1
  51. package/dist/admin/components/BulkMoveDialog/BulkMoveDialog.js +5 -2
  52. package/dist/admin/components/BulkMoveDialog/BulkMoveDialog.js.map +1 -1
  53. package/dist/admin/components/BulkMoveDialog/BulkMoveDialog.mjs +0 -1
  54. package/dist/admin/components/BulkMoveDialog/BulkMoveDialog.mjs.map +1 -1
  55. package/dist/admin/components/CopyLinkButton/CopyLinkButton.js +0 -1
  56. package/dist/admin/components/CopyLinkButton/CopyLinkButton.js.map +1 -1
  57. package/dist/admin/components/CopyLinkButton/CopyLinkButton.mjs +0 -1
  58. package/dist/admin/components/CopyLinkButton/CopyLinkButton.mjs.map +1 -1
  59. package/dist/admin/components/EditAssetDialog/EditAssetContent.js +8 -5
  60. package/dist/admin/components/EditAssetDialog/EditAssetContent.js.map +1 -1
  61. package/dist/admin/components/EditAssetDialog/EditAssetContent.mjs +0 -1
  62. package/dist/admin/components/EditAssetDialog/EditAssetContent.mjs.map +1 -1
  63. package/dist/admin/components/EditAssetDialog/PreviewBox/AssetPreview.js +10 -6
  64. package/dist/admin/components/EditAssetDialog/PreviewBox/AssetPreview.js.map +1 -1
  65. package/dist/admin/components/EditAssetDialog/PreviewBox/AssetPreview.mjs +4 -4
  66. package/dist/admin/components/EditAssetDialog/PreviewBox/AssetPreview.mjs.map +1 -1
  67. package/dist/admin/components/EditAssetDialog/PreviewBox/CroppingActions.js +0 -1
  68. package/dist/admin/components/EditAssetDialog/PreviewBox/CroppingActions.js.map +1 -1
  69. package/dist/admin/components/EditAssetDialog/PreviewBox/CroppingActions.mjs +0 -1
  70. package/dist/admin/components/EditAssetDialog/PreviewBox/CroppingActions.mjs.map +1 -1
  71. package/dist/admin/components/EditAssetDialog/PreviewBox/FocalPointActions.js +0 -1
  72. package/dist/admin/components/EditAssetDialog/PreviewBox/FocalPointActions.js.map +1 -1
  73. package/dist/admin/components/EditAssetDialog/PreviewBox/FocalPointActions.mjs +0 -1
  74. package/dist/admin/components/EditAssetDialog/PreviewBox/FocalPointActions.mjs.map +1 -1
  75. package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.js +9 -6
  76. package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.js.map +1 -1
  77. package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.mjs +3 -4
  78. package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.mjs.map +1 -1
  79. package/dist/admin/components/EditAssetDialog/ReplaceMediaButton.js +3 -3
  80. package/dist/admin/components/EditAssetDialog/ReplaceMediaButton.mjs +0 -1
  81. package/dist/admin/components/EditAssetDialog/ReplaceMediaButton.mjs.map +1 -1
  82. package/dist/admin/components/EditFolderDialog/EditFolderDialog.js +8 -5
  83. package/dist/admin/components/EditFolderDialog/EditFolderDialog.js.map +1 -1
  84. package/dist/admin/components/EditFolderDialog/EditFolderDialog.mjs +0 -1
  85. package/dist/admin/components/EditFolderDialog/EditFolderDialog.mjs.map +1 -1
  86. package/dist/admin/components/EditFolderDialog/ModalHeader/ModalHeader.js +0 -1
  87. package/dist/admin/components/EditFolderDialog/ModalHeader/ModalHeader.js.map +1 -1
  88. package/dist/admin/components/EditFolderDialog/ModalHeader/ModalHeader.mjs +0 -1
  89. package/dist/admin/components/EditFolderDialog/ModalHeader/ModalHeader.mjs.map +1 -1
  90. package/dist/admin/components/FilterPopover/FilterPopover.js +3 -2
  91. package/dist/admin/components/FilterPopover/FilterPopover.js.map +1 -1
  92. package/dist/admin/components/FolderCard/FolderCard/FolderCard.js +3 -2
  93. package/dist/admin/components/FolderCard/FolderCard/FolderCard.js.map +1 -1
  94. package/dist/admin/components/MediaLibraryDialog/MediaLibraryDialog.js +5 -3
  95. package/dist/admin/components/MediaLibraryDialog/MediaLibraryDialog.js.map +1 -1
  96. package/dist/admin/components/MediaLibraryDialog/MediaLibraryDialog.mjs +2 -1
  97. package/dist/admin/components/MediaLibraryDialog/MediaLibraryDialog.mjs.map +1 -1
  98. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAsset.js +3 -4
  99. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAsset.js.map +1 -1
  100. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAsset.mjs +4 -5
  101. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAsset.mjs.map +1 -1
  102. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssetActions.js +0 -1
  103. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssetActions.js.map +1 -1
  104. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssetActions.mjs +0 -1
  105. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssetActions.mjs.map +1 -1
  106. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssets.js +5 -3
  107. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssets.js.map +1 -1
  108. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssets.mjs +2 -1
  109. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssets.mjs.map +1 -1
  110. package/dist/admin/components/MediaLibraryInput/Carousel/EmptyStateAsset.js +4 -4
  111. package/dist/admin/components/MediaLibraryInput/Carousel/EmptyStateAsset.js.map +1 -1
  112. package/dist/admin/components/MediaLibraryInput/Carousel/EmptyStateAsset.mjs +2 -3
  113. package/dist/admin/components/MediaLibraryInput/Carousel/EmptyStateAsset.mjs.map +1 -1
  114. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js +4 -3
  115. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js.map +1 -1
  116. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs +1 -1
  117. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs.map +1 -1
  118. package/dist/admin/components/SelectTree/SelectTree.js +7 -3
  119. package/dist/admin/components/SelectTree/SelectTree.js.map +1 -1
  120. package/dist/admin/components/SortPicker/SortPicker.js +0 -1
  121. package/dist/admin/components/SortPicker/SortPicker.js.map +1 -1
  122. package/dist/admin/components/SortPicker/SortPicker.mjs +0 -1
  123. package/dist/admin/components/SortPicker/SortPicker.mjs.map +1 -1
  124. package/dist/admin/components/TableList/CellContent.js +5 -2
  125. package/dist/admin/components/TableList/CellContent.js.map +1 -1
  126. package/dist/admin/components/TableList/CellContent.mjs +0 -1
  127. package/dist/admin/components/TableList/CellContent.mjs.map +1 -1
  128. package/dist/admin/components/TableList/PreviewCell.js +3 -4
  129. package/dist/admin/components/TableList/PreviewCell.js.map +1 -1
  130. package/dist/admin/components/TableList/PreviewCell.mjs +4 -5
  131. package/dist/admin/components/TableList/PreviewCell.mjs.map +1 -1
  132. package/dist/admin/components/TableList/TableList.js +0 -1
  133. package/dist/admin/components/TableList/TableList.js.map +1 -1
  134. package/dist/admin/components/TableList/TableList.mjs +0 -1
  135. package/dist/admin/components/TableList/TableList.mjs.map +1 -1
  136. package/dist/admin/components/TableList/TableRows.js +0 -1
  137. package/dist/admin/components/TableList/TableRows.js.map +1 -1
  138. package/dist/admin/components/TableList/TableRows.mjs +0 -1
  139. package/dist/admin/components/TableList/TableRows.mjs.map +1 -1
  140. package/dist/admin/components/UploadAssetDialog/AddAssetStep/AddAssetStep.js +0 -1
  141. package/dist/admin/components/UploadAssetDialog/AddAssetStep/AddAssetStep.js.map +1 -1
  142. package/dist/admin/components/UploadAssetDialog/AddAssetStep/AddAssetStep.mjs +0 -1
  143. package/dist/admin/components/UploadAssetDialog/AddAssetStep/AddAssetStep.mjs.map +1 -1
  144. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromComputerForm.js +5 -5
  145. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromComputerForm.js.map +1 -1
  146. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromComputerForm.mjs +3 -4
  147. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromComputerForm.mjs.map +1 -1
  148. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js +3 -3
  149. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs +0 -1
  150. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs.map +1 -1
  151. package/dist/admin/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.js +3 -3
  152. package/dist/admin/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.mjs +0 -1
  153. package/dist/admin/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.mjs.map +1 -1
  154. package/dist/admin/components/UploadAssetDialog/UploadAssetDialog.js +3 -2
  155. package/dist/admin/components/UploadAssetDialog/UploadAssetDialog.js.map +1 -1
  156. package/dist/admin/constants.js +4 -7
  157. package/dist/admin/constants.js.map +1 -1
  158. package/dist/admin/constants.mjs +4 -7
  159. package/dist/admin/constants.mjs.map +1 -1
  160. package/dist/admin/enums.js +14 -16
  161. package/dist/admin/enums.js.map +1 -1
  162. package/dist/admin/enums.mjs +13 -15
  163. package/dist/admin/enums.mjs.map +1 -1
  164. package/dist/admin/future/components/Drawer.js +4 -3
  165. package/dist/admin/future/components/Drawer.js.map +1 -1
  166. package/dist/admin/future/pages/Assets/AssetsPage.js +29 -4
  167. package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
  168. package/dist/admin/future/pages/Assets/AssetsPage.mjs +28 -4
  169. package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
  170. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +5 -4
  171. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
  172. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +2 -2
  173. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
  174. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.js +7 -6
  175. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.js.map +1 -1
  176. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.mjs +4 -4
  177. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.mjs.map +1 -1
  178. package/dist/admin/future/pages/Assets/components/AssetsGrid.js +2 -2
  179. package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
  180. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +2 -2
  181. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
  182. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZone.js +3 -2
  183. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZone.js.map +1 -1
  184. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js +389 -0
  185. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js.map +1 -0
  186. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs +387 -0
  187. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -0
  188. package/dist/admin/future/pages/Assets/components/ImportFromUrlDialog.js +3 -2
  189. package/dist/admin/future/pages/Assets/components/ImportFromUrlDialog.js.map +1 -1
  190. package/dist/admin/future/pages/Assets/hooks/useFolderInfo.js +4 -4
  191. package/dist/admin/future/pages/Assets/hooks/useFolderInfo.js.map +1 -1
  192. package/dist/admin/future/pages/Assets/hooks/useFolderInfo.mjs +4 -4
  193. package/dist/admin/future/pages/Assets/hooks/useFolderInfo.mjs.map +1 -1
  194. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js +48 -2
  195. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js.map +1 -1
  196. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs +48 -2
  197. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs.map +1 -1
  198. package/dist/admin/future/services/folders.js +28 -1
  199. package/dist/admin/future/services/folders.js.map +1 -1
  200. package/dist/admin/future/services/folders.mjs +28 -2
  201. package/dist/admin/future/services/folders.mjs.map +1 -1
  202. package/dist/admin/future/utils/files.js +5 -1
  203. package/dist/admin/future/utils/files.js.map +1 -1
  204. package/dist/admin/future/utils/getAssetIcon.js +4 -4
  205. package/dist/admin/future/utils/getAssetIcon.js.map +1 -1
  206. package/dist/admin/future/utils/getAssetIcon.mjs +4 -4
  207. package/dist/admin/future/utils/getAssetIcon.mjs.map +1 -1
  208. package/dist/admin/hooks/useAIMetadataJob.js +3 -3
  209. package/dist/admin/hooks/useAIMetadataJob.mjs +0 -1
  210. package/dist/admin/hooks/useAIMetadataJob.mjs.map +1 -1
  211. package/dist/admin/hooks/useAssets.js +3 -2
  212. package/dist/admin/hooks/useAssets.js.map +1 -1
  213. package/dist/admin/hooks/useBulkEdit.js +0 -1
  214. package/dist/admin/hooks/useBulkEdit.js.map +1 -1
  215. package/dist/admin/hooks/useBulkEdit.mjs +0 -1
  216. package/dist/admin/hooks/useBulkEdit.mjs.map +1 -1
  217. package/dist/admin/hooks/useBulkMove.js +0 -1
  218. package/dist/admin/hooks/useBulkMove.js.map +1 -1
  219. package/dist/admin/hooks/useBulkMove.mjs +0 -1
  220. package/dist/admin/hooks/useBulkMove.mjs.map +1 -1
  221. package/dist/admin/hooks/useBulkRemove.js +0 -1
  222. package/dist/admin/hooks/useBulkRemove.js.map +1 -1
  223. package/dist/admin/hooks/useBulkRemove.mjs +0 -1
  224. package/dist/admin/hooks/useBulkRemove.mjs.map +1 -1
  225. package/dist/admin/hooks/useCropImg.js +7 -3
  226. package/dist/admin/hooks/useCropImg.js.map +1 -1
  227. package/dist/admin/hooks/useEditAsset.js +3 -3
  228. package/dist/admin/hooks/useEditAsset.mjs +0 -1
  229. package/dist/admin/hooks/useEditAsset.mjs.map +1 -1
  230. package/dist/admin/hooks/useFolder.js +0 -1
  231. package/dist/admin/hooks/useFolder.js.map +1 -1
  232. package/dist/admin/hooks/useFolder.mjs +0 -1
  233. package/dist/admin/hooks/useFolder.mjs.map +1 -1
  234. package/dist/admin/hooks/useFolderStructure.js +0 -1
  235. package/dist/admin/hooks/useFolderStructure.js.map +1 -1
  236. package/dist/admin/hooks/useFolderStructure.mjs +0 -1
  237. package/dist/admin/hooks/useFolderStructure.mjs.map +1 -1
  238. package/dist/admin/hooks/useFolders.js +3 -2
  239. package/dist/admin/hooks/useFolders.js.map +1 -1
  240. package/dist/admin/hooks/useModalQueryParams.js +3 -2
  241. package/dist/admin/hooks/useModalQueryParams.js.map +1 -1
  242. package/dist/admin/hooks/useSelectionState.js +3 -2
  243. package/dist/admin/hooks/useSelectionState.js.map +1 -1
  244. package/dist/admin/hooks/useUpload.js +3 -2
  245. package/dist/admin/hooks/useUpload.js.map +1 -1
  246. package/dist/admin/index.js +0 -1
  247. package/dist/admin/index.js.map +1 -1
  248. package/dist/admin/index.mjs +0 -1
  249. package/dist/admin/index.mjs.map +1 -1
  250. package/dist/admin/pages/App/App.js +3 -3
  251. package/dist/admin/pages/App/App.mjs +0 -1
  252. package/dist/admin/pages/App/App.mjs.map +1 -1
  253. package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.js +7 -4
  254. package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.js.map +1 -1
  255. package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.mjs +0 -1
  256. package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.mjs.map +1 -1
  257. package/dist/admin/pages/App/ConfigureTheView/components/Settings.js +0 -1
  258. package/dist/admin/pages/App/ConfigureTheView/components/Settings.js.map +1 -1
  259. package/dist/admin/pages/App/ConfigureTheView/components/Settings.mjs +0 -1
  260. package/dist/admin/pages/App/ConfigureTheView/components/Settings.mjs.map +1 -1
  261. package/dist/admin/pages/App/ConfigureTheView/state/reducer.js +7 -2
  262. package/dist/admin/pages/App/ConfigureTheView/state/reducer.js.map +1 -1
  263. package/dist/admin/pages/App/MediaLibrary.js +3 -3
  264. package/dist/admin/pages/App/MediaLibrary.mjs +0 -1
  265. package/dist/admin/pages/App/MediaLibrary.mjs.map +1 -1
  266. package/dist/admin/pages/App/components/BulkActions.js +0 -1
  267. package/dist/admin/pages/App/components/BulkActions.js.map +1 -1
  268. package/dist/admin/pages/App/components/BulkActions.mjs +0 -1
  269. package/dist/admin/pages/App/components/BulkActions.mjs.map +1 -1
  270. package/dist/admin/pages/App/components/BulkMoveButton.js +3 -2
  271. package/dist/admin/pages/App/components/BulkMoveButton.js.map +1 -1
  272. package/dist/admin/pages/App/components/EmptyOrNoPermissions.js +0 -1
  273. package/dist/admin/pages/App/components/EmptyOrNoPermissions.js.map +1 -1
  274. package/dist/admin/pages/App/components/EmptyOrNoPermissions.mjs +0 -1
  275. package/dist/admin/pages/App/components/EmptyOrNoPermissions.mjs.map +1 -1
  276. package/dist/admin/pages/App/components/Filters.js +3 -3
  277. package/dist/admin/pages/App/components/Filters.mjs +0 -1
  278. package/dist/admin/pages/App/components/Filters.mjs.map +1 -1
  279. package/dist/admin/pages/App/components/Header.js +0 -1
  280. package/dist/admin/pages/App/components/Header.js.map +1 -1
  281. package/dist/admin/pages/App/components/Header.mjs +0 -1
  282. package/dist/admin/pages/App/components/Header.mjs.map +1 -1
  283. package/dist/admin/pages/SettingsPage/SettingsPage.js +7 -4
  284. package/dist/admin/pages/SettingsPage/SettingsPage.js.map +1 -1
  285. package/dist/admin/pages/SettingsPage/SettingsPage.mjs +0 -1
  286. package/dist/admin/pages/SettingsPage/SettingsPage.mjs.map +1 -1
  287. package/dist/admin/pages/SettingsPage/reducer.js +5 -1
  288. package/dist/admin/pages/SettingsPage/reducer.js.map +1 -1
  289. package/dist/admin/src/components/EditAssetDialog/PreviewBox/PreviewComponents.d.ts +11 -12
  290. package/dist/admin/src/components/EmptyAssets/EmptyAssets.d.ts +0 -1
  291. package/dist/admin/src/components/FolderCard/contexts/FolderCard.d.ts +2 -3
  292. package/dist/admin/src/components/MediaLibraryDialog/MediaLibraryDialog.d.ts +2 -1
  293. package/dist/admin/src/constants.d.ts +5 -4
  294. package/dist/admin/src/enums.d.ts +14 -12
  295. package/dist/admin/src/future/pages/Assets/components/FolderTree/FolderTree.d.ts +19 -0
  296. package/dist/admin/src/future/pages/Assets/hooks/useFolderNavigation.d.ts +2 -0
  297. package/dist/admin/src/future/services/folders.d.ts +2 -2
  298. package/dist/admin/src/future/store/uploadProgress.d.ts +1 -1
  299. package/dist/admin/src/hooks/useCropImg.d.ts +2 -2
  300. package/dist/admin/src/hooks/useEditFolder.d.ts +4 -4
  301. package/dist/admin/src/hooks/useModalQueryParams.d.ts +5 -5
  302. package/dist/admin/src/hooks/usePersistentState.d.ts +0 -1
  303. package/dist/admin/src/hooks/useSettings.d.ts +5 -5
  304. package/dist/admin/src/hooks/useTracking.d.ts +1 -1
  305. package/dist/admin/src/pages/App/ConfigureTheView/state/actions.d.ts +1 -1
  306. package/dist/admin/src/pages/App/ConfigureTheView/state/init.d.ts +1 -1
  307. package/dist/admin/src/utils/getBreadcrumbDataML.d.ts +1 -1
  308. package/dist/admin/src/utils/getFolderParents.d.ts +3 -3
  309. package/dist/admin/src/utils/icons.d.ts +2 -1
  310. package/dist/admin/src/utils/rawFileToAsset.d.ts +1 -1
  311. package/dist/admin/src/utils/urlsToAssets.d.ts +2 -10
  312. package/dist/admin/translations/en.json.js +10 -1
  313. package/dist/admin/translations/en.json.js.map +1 -1
  314. package/dist/admin/translations/en.json.mjs +10 -1
  315. package/dist/admin/translations/en.json.mjs.map +1 -1
  316. package/dist/admin/translations/ja.json.js +175 -0
  317. package/dist/admin/translations/ja.json.js.map +1 -1
  318. package/dist/admin/translations/ja.json.mjs +175 -0
  319. package/dist/admin/translations/ja.json.mjs.map +1 -1
  320. package/dist/admin/utils/formatBytes.js +5 -1
  321. package/dist/admin/utils/formatBytes.js.map +1 -1
  322. package/dist/admin/utils/icons.js +5 -5
  323. package/dist/admin/utils/icons.js.map +1 -1
  324. package/dist/admin/utils/icons.mjs +6 -6
  325. package/dist/admin/utils/icons.mjs.map +1 -1
  326. package/dist/admin/utils/typeFromMime.js +9 -9
  327. package/dist/admin/utils/typeFromMime.js.map +1 -1
  328. package/dist/admin/utils/typeFromMime.mjs +10 -10
  329. package/dist/admin/utils/typeFromMime.mjs.map +1 -1
  330. package/dist/admin/utils/urlYupSchema.js +3 -2
  331. package/dist/admin/utils/urlYupSchema.js.map +1 -1
  332. package/dist/admin/utils/urlsToAssets.js +1 -2
  333. package/dist/admin/utils/urlsToAssets.js.map +1 -1
  334. package/dist/admin/utils/urlsToAssets.mjs +1 -2
  335. package/dist/admin/utils/urlsToAssets.mjs.map +1 -1
  336. package/dist/server/controllers/admin-upload.js +11 -4
  337. package/dist/server/controllers/admin-upload.js.map +1 -1
  338. package/dist/server/controllers/content-api.js +7 -2
  339. package/dist/server/controllers/content-api.js.map +1 -1
  340. package/dist/server/controllers/utils/find-entity-and-check-permissions.js +7 -3
  341. package/dist/server/controllers/utils/find-entity-and-check-permissions.js.map +1 -1
  342. package/dist/server/middlewares/upload.js +7 -2
  343. package/dist/server/middlewares/upload.js.map +1 -1
  344. package/dist/server/register.js +9 -4
  345. package/dist/server/register.js.map +1 -1
  346. package/dist/server/routes/content-api.js +3 -2
  347. package/dist/server/routes/content-api.js.map +1 -1
  348. package/dist/server/routes/validation/upload.js +3 -2
  349. package/dist/server/routes/validation/upload.js.map +1 -1
  350. package/dist/server/services/file.js +13 -6
  351. package/dist/server/services/file.js.map +1 -1
  352. package/dist/server/services/image-manipulation.js +18 -12
  353. package/dist/server/services/image-manipulation.js.map +1 -1
  354. package/dist/server/services/provider.js +24 -0
  355. package/dist/server/services/provider.js.map +1 -1
  356. package/dist/server/services/provider.mjs +24 -0
  357. package/dist/server/services/provider.mjs.map +1 -1
  358. package/dist/server/services/upload.js +99 -32
  359. package/dist/server/services/upload.js.map +1 -1
  360. package/dist/server/services/upload.mjs +69 -10
  361. package/dist/server/services/upload.mjs.map +1 -1
  362. package/dist/server/src/controllers/admin-file.d.ts +4 -12
  363. package/dist/server/src/controllers/admin-file.d.ts.map +1 -1
  364. package/dist/server/src/controllers/admin-folder.d.ts +2 -2
  365. package/dist/server/src/controllers/admin-settings.d.ts +2 -2
  366. package/dist/server/src/controllers/admin-upload.d.ts +3 -3
  367. package/dist/server/src/controllers/content-api.d.ts +2 -2
  368. package/dist/server/src/controllers/content-api.d.ts.map +1 -1
  369. package/dist/server/src/controllers/index.d.ts +14 -23
  370. package/dist/server/src/controllers/index.d.ts.map +1 -1
  371. package/dist/server/src/controllers/utils/find-entity-and-check-permissions.d.ts.map +1 -1
  372. package/dist/server/src/controllers/utils/folders.d.ts.map +1 -1
  373. package/dist/server/src/controllers/validation/admin/configureView.d.ts +1 -1
  374. package/dist/server/src/controllers/validation/admin/folder-file.d.ts +1 -1
  375. package/dist/server/src/controllers/validation/admin/folder-file.d.ts.map +1 -1
  376. package/dist/server/src/controllers/validation/admin/folder.d.ts +2 -2
  377. package/dist/server/src/controllers/validation/admin/folder.d.ts.map +1 -1
  378. package/dist/server/src/controllers/validation/admin/settings.d.ts +1 -1
  379. package/dist/server/src/controllers/validation/admin/upload.d.ts +1 -1
  380. package/dist/server/src/controllers/validation/admin/upload.d.ts.map +1 -1
  381. package/dist/server/src/controllers/validation/admin/utils.d.ts.map +1 -1
  382. package/dist/server/src/controllers/validation/content-api/upload.d.ts.map +1 -1
  383. package/dist/server/src/controllers/view-configuration.d.ts +1 -1
  384. package/dist/server/src/graphql.d.ts.map +1 -1
  385. package/dist/server/src/index.d.ts +37 -53
  386. package/dist/server/src/index.d.ts.map +1 -1
  387. package/dist/server/src/middlewares/upload.d.ts.map +1 -1
  388. package/dist/server/src/services/ai-metadata-jobs.d.ts +1 -1
  389. package/dist/server/src/services/ai-metadata-jobs.d.ts.map +1 -1
  390. package/dist/server/src/services/ai-metadata.d.ts.map +1 -1
  391. package/dist/server/src/services/extensions/utils.d.ts.map +1 -1
  392. package/dist/server/src/services/file.d.ts +2 -2
  393. package/dist/server/src/services/file.d.ts.map +1 -1
  394. package/dist/server/src/services/folder.d.ts +1 -1
  395. package/dist/server/src/services/folder.d.ts.map +1 -1
  396. package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
  397. package/dist/server/src/services/index.d.ts +23 -30
  398. package/dist/server/src/services/index.d.ts.map +1 -1
  399. package/dist/server/src/services/metrics.d.ts.map +1 -1
  400. package/dist/server/src/services/provider.d.ts +2 -1
  401. package/dist/server/src/services/provider.d.ts.map +1 -1
  402. package/dist/server/src/services/upload.d.ts +1 -1
  403. package/dist/server/src/services/upload.d.ts.map +1 -1
  404. package/dist/server/src/services/weekly-metrics.d.ts.map +1 -1
  405. package/dist/server/src/types.d.ts +4 -3
  406. package/dist/server/src/types.d.ts.map +1 -1
  407. package/dist/server/src/utils/cron.d.ts.map +1 -1
  408. package/dist/server/src/utils/index.d.ts.map +1 -1
  409. package/dist/server/src/utils/mime-validation.d.ts.map +1 -1
  410. package/dist/server/utils/mime-validation.js +11 -3
  411. package/dist/server/utils/mime-validation.js.map +1 -1
  412. package/dist/server/utils/mime-validation.mjs +12 -4
  413. package/dist/server/utils/mime-validation.mjs.map +1 -1
  414. package/package.json +9 -9
  415. package/dist/admin/future/enums.js +0 -12
  416. package/dist/admin/future/enums.js.map +0 -1
  417. package/dist/admin/future/enums.mjs +0 -10
  418. package/dist/admin/future/enums.mjs.map +0 -1
  419. package/dist/admin/src/future/enums.d.ts +0 -6
@@ -4,6 +4,7 @@ export declare const services: {
4
4
  }) => {
5
5
  checkFileSize(file: import("../types").UploadableFile): Promise<void>;
6
6
  upload(file: import("../types").UploadableFile): Promise<void>;
7
+ replace(newFile: import("../types").UploadableFile, oldFile: import("../types").File): Promise<void>;
7
8
  };
8
9
  upload: ({ strapi }: {
9
10
  strapi: import("@strapi/types/dist/core").Strapi;
@@ -13,11 +14,11 @@ export declare const services: {
13
14
  type: string;
14
15
  size: number;
15
16
  }, fileInfo?: Partial<import("../types").FileInfo>, metas?: {
16
- refId?: (string | number) | undefined;
17
- ref?: string | undefined;
18
- field?: string | undefined;
19
- path?: string | undefined;
20
- tmpWorkingDirectory?: string | undefined;
17
+ refId?: string | number;
18
+ ref?: string;
19
+ field?: string;
20
+ path?: string;
21
+ tmpWorkingDirectory?: string;
21
22
  }) => Promise<Omit<import("../types").UploadableFile, "getStream">>;
22
23
  upload: ({ data, files, }: {
23
24
  data: Record<string, unknown>;
@@ -25,13 +26,13 @@ export declare const services: {
25
26
  }, opts?: {
26
27
  user?: {
27
28
  id: string | number;
28
- } | undefined;
29
- } | undefined) => Promise<any[]>;
29
+ };
30
+ }) => Promise<any[]>;
30
31
  updateFileInfo: (id: string | number, { name, alternativeText, caption, focalPoint, folder }: import("../types").FileInfo, opts?: {
31
32
  user?: {
32
33
  id: string | number;
33
- } | undefined;
34
- } | undefined) => Promise<any>;
34
+ };
35
+ }) => Promise<any>;
35
36
  replace: (id: string | number, { data, file }: {
36
37
  data: {
37
38
  fileInfo: import("../types").FileInfo;
@@ -40,8 +41,8 @@ export declare const services: {
40
41
  }, opts?: {
41
42
  user?: {
42
43
  id: string | number;
43
- } | undefined;
44
- } | undefined) => Promise<any>;
44
+ };
45
+ }) => Promise<any>;
45
46
  findOne: (id: string | number, populate?: {}) => Promise<any>;
46
47
  findMany: (query?: any) => Promise<import("../types").File[]>;
47
48
  findPage: (query?: any) => Promise<{
@@ -64,20 +65,12 @@ export declare const services: {
64
65
  autoOrientation: import("yup").BooleanSchema<boolean | undefined, Record<string, any>, boolean | undefined>;
65
66
  aiMetadata: import("yup").BooleanSchema<boolean, Record<string, any>, boolean>;
66
67
  }> | null>;
67
- setSettings: (value: import("yup/lib/object").AssertsShape<{
68
- sizeOptimization: import("yup/lib/boolean").RequiredBooleanSchema<boolean | undefined, Record<string, any>>;
69
- responsiveDimensions: import("yup/lib/boolean").RequiredBooleanSchema<boolean | undefined, Record<string, any>>;
70
- autoOrientation: import("yup").BooleanSchema<boolean | undefined, Record<string, any>, boolean | undefined>;
71
- aiMetadata: import("yup").BooleanSchema<boolean, Record<string, any>, boolean>;
72
- }>) => Promise<void>;
68
+ setSettings: (value: import("../controllers/validation/admin/settings").Settings) => Promise<void>;
73
69
  getConfiguration: () => Promise<import("yup/lib/object").AssertsShape<{
74
70
  pageSize: import("yup/lib/number").RequiredNumberSchema<number | undefined, Record<string, any>>;
75
71
  sort: import("yup/lib/mixed").MixedSchema<any, Record<string, any>, any>;
76
72
  }> | null>;
77
- setConfiguration: (value: import("yup/lib/object").AssertsShape<{
78
- pageSize: import("yup/lib/number").RequiredNumberSchema<number | undefined, Record<string, any>>;
79
- sort: import("yup/lib/mixed").MixedSchema<any, Record<string, any>, any>;
80
- }>) => Promise<void>;
73
+ setConfiguration: (value: import("../controllers/validation/admin/configureView").ViewConfiguration) => Promise<void>;
81
74
  _uploadImage: (fileData: import("../types").UploadableFile) => Promise<void>;
82
75
  };
83
76
  folder: {
@@ -85,7 +78,7 @@ export declare const services: {
85
78
  user: {
86
79
  id: string | number;
87
80
  };
88
- } | undefined) => Promise<any>;
81
+ }) => Promise<any>;
89
82
  exists: (params?: {}) => Promise<boolean>;
90
83
  deleteByIds: (ids?: never[]) => Promise<{
91
84
  folders: any[];
@@ -105,14 +98,14 @@ export declare const services: {
105
98
  path: string;
106
99
  }>;
107
100
  getStructure: () => Promise<number[] & (Partial<import("../types").Folder> & {
108
- children: (Partial<import("../types").Folder> & any)[];
101
+ children: (Partial<import("../types").Folder> & /*elided*/ any)[];
109
102
  })[]>;
110
103
  };
111
104
  file: {
112
- getFolderPath: (folderId?: number | null | undefined) => Promise<any>;
105
+ getFolderPath: (folderId?: number | null) => Promise<any>;
113
106
  deleteByIds: (ids?: number[]) => Promise<any[]>;
114
107
  signFileUrls: (file: import("../types").File) => Promise<import("../types").File>;
115
- fetchUrlToInputFile: (url: string, tmpWorkingDirectory: string, sizeLimit?: number | undefined) => Promise<import("./file").FetchUrlResult>;
108
+ fetchUrlToInputFile: (url: string, tmpWorkingDirectory: string, sizeLimit?: number) => Promise<import("./file").FetchUrlResult>;
116
109
  };
117
110
  weeklyMetrics: ({ strapi }: {
118
111
  strapi: import("@strapi/types/dist/core").Strapi;
@@ -131,7 +124,7 @@ export declare const services: {
131
124
  metrics: ({ strapi }: {
132
125
  strapi: import("@strapi/types/dist/core").Strapi;
133
126
  }) => {
134
- trackUsage(event: string, properties?: Record<string, any> | undefined): Promise<boolean>;
127
+ trackUsage(event: string, properties?: Record<string, any>): Promise<boolean>;
135
128
  sendUploadPluginMetrics(): Promise<void>;
136
129
  };
137
130
  'image-manipulation': {
@@ -165,19 +158,19 @@ export declare const services: {
165
158
  imagesWithoutMetadataCount: number;
166
159
  totalImages: number;
167
160
  }>;
168
- updateFilesWithAIMetadata(files: import("../types").File[], metadataResults: ({
161
+ updateFilesWithAIMetadata(files: import("../types").File[], metadataResults: Array<{
169
162
  altText: string;
170
163
  caption: string;
171
- } | null)[], user: {
164
+ } | null>, user: {
172
165
  id: string | number;
173
166
  }): Promise<void>;
174
167
  processExistingFiles(jobId: number, user: {
175
168
  id: string | number;
176
169
  }): Promise<void>;
177
- processFiles(files: import("../types").File[]): Promise<({
170
+ processFiles(files: import("../types").File[]): Promise<Array<{
178
171
  altText: string;
179
172
  caption: string;
180
- } | null)[]>;
173
+ } | null>>;
181
174
  };
182
175
  aiMetadataJobs: ({ strapi }: {
183
176
  strapi: import("@strapi/types/dist/core").Strapi;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/src/services/index.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAYpB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/src/services/index.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;iBAa0mF,CAAC;eAAe,CAAC;iBAAqB,CAAC;gBAAoB,CAAC;+BAAmC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAD9tF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../../../server/src/services/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;qCAMd;IAAE,MAAM,EAAE,KAAK,MAAM,CAAA;CAAE;sBACzB,MAAM,eAAe,OAAO,MAAM,EAAE,GAAG,CAAC;;;AADlE,wBA0BG"}
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../../../server/src/services/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;yBAM1B,YAAY;IAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAA;CAAE;sBACzB,MAAM,eAAe,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;;;AADlE,wBA0BG"}
@@ -1,10 +1,11 @@
1
1
  import type { Core } from '@strapi/types';
2
- import { UploadableFile } from '../types';
2
+ import { File, UploadableFile } from '../types';
3
3
  declare const _default: ({ strapi }: {
4
4
  strapi: Core.Strapi;
5
5
  }) => {
6
6
  checkFileSize(file: UploadableFile): Promise<void>;
7
7
  upload(file: UploadableFile): Promise<void>;
8
+ replace(newFile: UploadableFile, oldFile: File): Promise<void>;
8
9
  };
9
10
  export default _default;
10
11
  //# sourceMappingURL=provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../../server/src/services/provider.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAU,cAAc,EAAE,MAAM,UAAU,CAAC;qCAEtB;IAAE,MAAM,EAAE,KAAK,MAAM,CAAA;CAAE;wBACvB,cAAc;iBAKrB,cAAc;;AANnC,wBA2BG"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../../server/src/services/provider.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAU,IAAI,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;yBAExC,YAAY;IAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAA;CAAE;wBACvB,cAAc;iBAKrB,cAAc;qBAsBV,cAAc,WAAW,IAAI;;AA5BtD,wBA2DG"}
@@ -23,7 +23,7 @@ declare const _default: ({ strapi }: {
23
23
  field?: string;
24
24
  path?: string;
25
25
  tmpWorkingDirectory?: string;
26
- }) => Promise<Omit<UploadableFile, 'getStream'>>;
26
+ }) => Promise<Omit<UploadableFile, "getStream">>;
27
27
  upload: ({ data, files, }: {
28
28
  data: Record<string, unknown>;
29
29
  files: InputFile[];
@@ -1 +1 @@
1
- {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../../server/src/services/upload.ts"],"names":[],"mappings":"AAMA,OAAO,EAML,UAAU,IAAI,eAAe,EAC9B,MAAM,eAAe,CAAC;AAGvB,OAAO,KAAK,EAAE,IAAI,EAAO,MAAM,eAAe,CAAC;AAK/C,OAAO,KAAK,EAAU,IAAI,EAAE,SAAS,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAClF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AACvF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0CAA0C,CAAC;AAEzE,KAAK,IAAI,GAAG;IACV,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;CACrB,CAAC;AAEF,KAAK,EAAE,GAAG,MAAM,GAAG,MAAM,CAAC;AAE1B,KAAK,aAAa,GAAG;IACnB,IAAI,CAAC,EAAE,IAAI,CAAC;CACb,CAAC;qCAgB0B;IAAE,MAAM,EAAE,KAAK,MAAM,CAAA;CAAE;+CAsErB;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,aAChE,QAAQ,QAAQ,CAAC,UACpB;QACL,KAAK,CAAC,EAAE,EAAE,CAAC;QACX,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,mBAAmB,CAAC,EAAE,MAAM,CAAC;KAC9B,KACA,QAAQ,KAAK,cAAc,EAAE,WAAW,CAAC,CAAC;+BA2GxC;QACD,IAAI,EAAE,OAAO,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9B,KAAK,EAAE,SAAS,EAAE,CAAC;KACpB,SACM,aAAa;yBA6HhB,EAAE,0DACkD,QAAQ,SACzD,aAAa;kBA4BhB,EAAE,kBACU;QAAE,IAAI,EAAE;YAAE,QAAQ,EAAE,QAAQ,CAAA;SAAE,CAAC;QAAC,IAAI,EAAE,SAAS,CAAA;KAAE,SAC1D,aAAa;kBAkGK,EAAE;uBAgBE,GAAG,KAAQ,QAAQ,IAAI,EAAE,CAAC;uBAS1B,GAAG;;;;;;;;;+BAyDK,GAAG;;;;mBA4Cd,IAAI;;;;;;;yBAiCE,QAAQ;;;;;8BAoBT,iBAAiB;IAqBhD;;;OAGG;6BA1ZgC,cAAc;;AA9OrD,wBA2oBE"}
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../../server/src/services/upload.ts"],"names":[],"mappings":"AAMA,OAAO,EAML,UAAU,IAAI,eAAe,EAC9B,MAAM,eAAe,CAAC;AAGvB,OAAO,KAAK,EAAE,IAAI,EAAO,MAAM,eAAe,CAAC;AAK/C,OAAO,KAAK,EAAU,IAAI,EAAE,SAAS,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAClF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AACvF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0CAA0C,CAAC;AAEzE,KAAK,IAAI,GAAG;IACV,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;CACrB,CAAC;AAEF,KAAK,EAAE,GAAG,MAAM,GAAG,MAAM,CAAC;AAE1B,KAAK,aAAa,GAAG;IACnB,IAAI,CAAC,EAAE,IAAI,CAAC;CACb,CAAC;yBAgBc,YAAY;IAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAA;CAAE;+CAsErB;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,aAChE,OAAO,CAAC,QAAQ,CAAC,UACpB;QACL,KAAK,CAAC,EAAE,EAAE,CAAC;QACX,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,mBAAmB,CAAC,EAAE,MAAM,CAAC;KAC9B,KACA,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;+BA2GxC;QACD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9B,KAAK,EAAE,SAAS,EAAE,CAAC;KACpB,SACM,aAAa;yBAiMhB,EAAE,0DACkD,QAAQ,SACzD,aAAa;kBA4BhB,EAAE,kBACU;QAAE,IAAI,EAAE;YAAE,QAAQ,EAAE,QAAQ,CAAA;SAAE,CAAC;QAAC,IAAI,EAAE,SAAS,CAAA;KAAE,SAC1D,aAAa;kBAsGK,EAAE;uBAgBE,GAAG,KAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;uBAS1B,GAAG;;;;;;;;;+BAyDK,GAAG;;;;mBA4Cd,IAAI;;;;;;;yBAiCE,QAAQ;;;;;8BAoBT,iBAAiB;IAqBhD;;;OAGG;6BAlegC,cAAc;;AA9OrD,wBAmtBE"}
@@ -1 +1 @@
1
- {"version":3,"file":"weekly-metrics.d.ts","sourceRoot":"","sources":["../../../../server/src/services/weekly-metrics.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;qCAoBd;IAAE,MAAM,EAAE,KAAK,MAAM,CAAA;CAAE;;;;;;;;;sCAyFT,QAAQ,MAAM,CAAC;;;AAzFzD,wBAoHG"}
1
+ {"version":3,"file":"weekly-metrics.d.ts","sourceRoot":"","sources":["../../../../server/src/services/weekly-metrics.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;yBAoB1B,YAAY;IAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAA;CAAE;;;;;;;;;sCAyFT,OAAO,CAAC,MAAM,CAAC;;;AAzFzD,wBAoHG"}
@@ -1,6 +1,3 @@
1
- /// <reference types="node" />
2
- /// <reference types="node" />
3
- /// <reference types="node" />
4
1
  import type { File as FormidableFile } from 'formidable';
5
2
  export type InputFile = FormidableFile & {
6
3
  path?: string;
@@ -70,6 +67,10 @@ export interface Config {
70
67
  concurrency?: number;
71
68
  };
72
69
  concurrentUploadSize?: number;
70
+ security?: {
71
+ allowedTypes?: string[];
72
+ deniedTypes?: string[];
73
+ };
73
74
  }
74
75
  export interface UploadableFile extends Omit<File, 'id'> {
75
76
  filepath?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../server/src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../server/src/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"cron.d.ts","sourceRoot":"","sources":["../../../../server/src/utils/cron.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,uBAAuB,SAAU,IAAI,WAC0C,CAAC;AAEtF,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
1
+ {"version":3,"file":"cron.d.ts","sourceRoot":"","sources":["../../../../server/src/utils/cron.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,uBAAuB,GAAI,MAAM,IAAI,WAC0C,CAAC;AAEtF,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAC;AAC7C,OAAO,KAAK,iBAAiB,MAAM,gCAAgC,CAAC;AACpE,OAAO,KAAK,eAAe,MAAM,+BAA+B,CAAC;AACjE,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAC;AAC7C,OAAO,KAAK,IAAI,MAAM,kBAAkB,CAAC;AACzC,OAAO,KAAK,aAAa,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AAC/C,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAEhF,KAAK,QAAQ,GAAG;IACd,MAAM,EAAE,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;IAClC,oBAAoB,EAAE,OAAO,iBAAiB,CAAC;IAC/C,QAAQ,EAAE,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;IACtC,MAAM,EAAE,OAAO,MAAM,CAAC;IACtB,IAAI,EAAE,OAAO,IAAI,CAAC;IAClB,aAAa,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;IAChD,OAAO,EAAE,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;IACpC,mBAAmB,EAAE,OAAO,eAAe,CAAC;IAC5C,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,UAAU,EAAE,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;IACvD,cAAc,EAAE,UAAU,CAAC,OAAO,2BAA2B,CAAC,CAAC;CAChE,CAAC;AAEF,eAAO,MAAM,UAAU,uCAAwC,KAAK,KAAG,QAAQ,CAAC,KAAK,CAEpF,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAC;AAC7C,OAAO,KAAK,iBAAiB,MAAM,gCAAgC,CAAC;AACpE,OAAO,KAAK,eAAe,MAAM,+BAA+B,CAAC;AACjE,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAC;AAC7C,OAAO,KAAK,IAAI,MAAM,kBAAkB,CAAC;AACzC,OAAO,KAAK,aAAa,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AAC/C,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAEhF,KAAK,QAAQ,GAAG;IACd,MAAM,EAAE,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;IAClC,oBAAoB,EAAE,OAAO,iBAAiB,CAAC;IAC/C,QAAQ,EAAE,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;IACtC,MAAM,EAAE,OAAO,MAAM,CAAC;IACtB,IAAI,EAAE,OAAO,IAAI,CAAC;IAClB,aAAa,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;IAChD,OAAO,EAAE,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;IACpC,mBAAmB,EAAE,OAAO,eAAe,CAAC;IAC5C,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,UAAU,EAAE,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;IACvD,cAAc,EAAE,UAAU,CAAC,OAAO,2BAA2B,CAAC,CAAC;CAChE,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,KAAK,SAAS,MAAM,QAAQ,EAAE,MAAM,KAAK,KAAG,QAAQ,CAAC,KAAK,CAEpF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"mime-validation.d.ts","sourceRoot":"","sources":["../../../../server/src/utils/mime-validation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAG1C,MAAM,MAAM,cAAc,GAAG;IAC3B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AACF,KAAK,qBAAqB,GAAG;IAC3B,IAAI,EAAE,uBAAuB,GAAG,kBAAkB,GAAG,eAAe,CAAC;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,qBAAqB,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,GAAG,CAAC;IACV,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,qBAAqB,CAAC;CAC9B,CAAC;AAOF,wBAAsB,cAAc,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAoC3E;AAsBD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAcnF;AA6ED,wBAAgB,eAAe,CAAC,IAAI,EAAE,GAAG;;;EAWxC;AAED,wBAAsB,YAAY,CAChC,IAAI,EAAE,GAAG,EACT,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,IAAI,CAAC,MAAM,GAClB,OAAO,CAAC,gBAAgB,CAAC,CA0K3B;AA2BD,wBAAsB,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAoEhG;AAED,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,GAAG,EACV,MAAM,EAAE,IAAI,CAAC,MAAM,GAClB,OAAO,CAAC;IACT,UAAU,EAAE,GAAG,EAAE,CAAC;IAClB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;CAC5B,CAAC,CAyCD;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,EAAE,GAAG,EAAE,CAAC;IAClB,YAAY,EAAE,GAAG,CAAC;IAClB,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B,CAAC;AAEF;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,GAAG,EACf,IAAI,EAAE,GAAG,EACT,MAAM,EAAE,IAAI,CAAC,MAAM,GAClB,OAAO,CAAC,mBAAmB,CAAC,CAoD9B"}
1
+ {"version":3,"file":"mime-validation.d.ts","sourceRoot":"","sources":["../../../../server/src/utils/mime-validation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAG1C,MAAM,MAAM,cAAc,GAAG;IAC3B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AACF,KAAK,qBAAqB,GAAG;IAC3B,IAAI,EAAE,uBAAuB,GAAG,kBAAkB,GAAG,eAAe,CAAC;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,qBAAqB,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,GAAG,CAAC;IACV,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,qBAAqB,CAAC;CAC9B,CAAC;AAeF,wBAAsB,cAAc,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAoC3E;AAsBD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAcnF;AA6ED,wBAAgB,eAAe,CAAC,IAAI,EAAE,GAAG;;;EAWxC;AAED,wBAAsB,YAAY,CAChC,IAAI,EAAE,GAAG,EACT,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,IAAI,CAAC,MAAM,GAClB,OAAO,CAAC,gBAAgB,CAAC,CAmL3B;AA2BD,wBAAsB,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAoEhG;AAED,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,GAAG,EACV,MAAM,EAAE,IAAI,CAAC,MAAM,GAClB,OAAO,CAAC;IACT,UAAU,EAAE,GAAG,EAAE,CAAC;IAClB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;CAC5B,CAAC,CAyCD;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,EAAE,GAAG,EAAE,CAAC;IAClB,YAAY,EAAE,GAAG,CAAC;IAClB,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B,CAAC;AAEF;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,GAAG,EACf,IAAI,EAAE,GAAG,EACT,MAAM,EAAE,IAAI,CAAC,MAAM,GAClB,OAAO,CAAC,mBAAmB,CAAC,CAoD9B"}
@@ -6,8 +6,14 @@ var mimeTypes = require('mime-types');
6
6
  var utils = require('@strapi/utils');
7
7
 
8
8
  async function readFileChunk(filePath, chunkSize = 4100) {
9
- const buffer = await promises.readFile(filePath);
10
- return buffer.length > chunkSize ? buffer.subarray(0, chunkSize) : buffer;
9
+ const file = await promises.open(filePath, 'r');
10
+ try {
11
+ const buffer = Buffer.alloc(chunkSize);
12
+ const { bytesRead } = await file.read(buffer, 0, chunkSize, 0);
13
+ return buffer.subarray(0, bytesRead);
14
+ } finally{
15
+ await file.close();
16
+ }
11
17
  }
12
18
  async function detectMimeType(file) {
13
19
  let buffer;
@@ -175,7 +181,9 @@ async function validateFile(file, config, strapi) {
175
181
  // Reject if detected is not in allow list (extension/declared cannot override).
176
182
  // Exception: file-type often returns application/zip for Office formats (docx, xlsx); skip so the next block can allow via extension type.
177
183
  const isZipWithAllowedExt = detectedMime === 'application/zip' && expectedMimeFromExt && expectedMimeFromExt !== 'application/zip' && Array.isArray(allowedTypes) && allowedTypes.length > 0 && matchesMimePattern(expectedMimeFromExt, allowedTypes);
178
- if (detectedMime && Array.isArray(allowedTypes) && allowedTypes.length > 0 && !matchesMimePattern(detectedMime, allowedTypes) && !isZipWithAllowedExt) {
184
+ // Exception: file-type often returns application/xml for SVG; trust .svg extension when image/svg+xml is allowed.
185
+ const isSvgXmlWithAllowedExt = detectedMime === 'application/xml' && fileExt === '.svg' && expectedMimeFromExt === 'image/svg+xml' && Array.isArray(allowedTypes) && allowedTypes.length > 0 && matchesMimePattern(expectedMimeFromExt, allowedTypes);
186
+ if (detectedMime && Array.isArray(allowedTypes) && allowedTypes.length > 0 && !matchesMimePattern(detectedMime, allowedTypes) && !isZipWithAllowedExt && !isSvgXmlWithAllowedExt) {
179
187
  return {
180
188
  isValid: false,
181
189
  error: {
@@ -1 +1 @@
1
- {"version":3,"file":"mime-validation.js","sources":["../../../server/src/utils/mime-validation.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { extname } from 'node:path';\nimport { lookup } from 'mime-types';\nimport type { Core } from '@strapi/types';\nimport { errors } from '@strapi/utils';\n\nexport type SecurityConfig = {\n allowedTypes?: string[];\n deniedTypes?: string[];\n};\ntype UploadValidationError = {\n code: 'MIME_TYPE_NOT_ALLOWED' | 'VALIDATION_ERROR' | 'UNKNOWN_ERROR';\n message: string;\n details: Record<string, any>;\n};\n\ntype ValidationResult = {\n isValid: boolean;\n error?: UploadValidationError;\n detectedMime?: string;\n};\n\ntype ErrorDetail = {\n file: any;\n originalIndex: number;\n error: UploadValidationError;\n};\n\nasync function readFileChunk(filePath: string, chunkSize: number = 4100): Promise<Buffer> {\n const buffer = await readFile(filePath);\n return buffer.length > chunkSize ? buffer.subarray(0, chunkSize) : buffer;\n}\n\nexport async function detectMimeType(file: any): Promise<string | undefined> {\n let buffer: Buffer;\n\n // Support multiple property names used by different multipart parsers (formidable uses filepath)\n const filePath = file.filepath ?? file.path ?? file.tempFilePath ?? file.filePath;\n\n if (filePath) {\n try {\n buffer = await readFileChunk(filePath, 4100);\n } catch (error) {\n throw new Error(\n `Failed to read file: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n } else if (file.buffer) {\n buffer = file.buffer.length > 4100 ? file.buffer.subarray(0, 4100) : file.buffer;\n } else {\n // No file path or buffer; cannot detect MIME. Validation will use declared/extension or reject.\n return undefined;\n }\n\n try {\n /**\n * Use dynamic import to support file-type which is ESM-only\n * Static imports fail during CommonJS build since bundler can't transform ESM-only packages\n * @see https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c\n */\n const { fileTypeFromBuffer } = await import('file-type');\n\n const result = await fileTypeFromBuffer(new Uint8Array(buffer));\n return result?.mime;\n } catch (error) {\n throw new Error(\n `Failed to detect MIME type: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\nfunction matchesMimePattern(mimeType: string, patterns: string[]): boolean {\n if (!patterns?.length) return false;\n\n return patterns.some((pattern) => {\n const normalizedPattern = pattern.toLowerCase();\n const normalizedMimeType = mimeType.toLowerCase();\n\n if (normalizedPattern.includes('*')) {\n const regexPattern = normalizedPattern.replace(/\\*/g, '.*');\n\n const regex = new RegExp(`^${regexPattern}$`);\n const matches = regex.test(normalizedMimeType);\n return matches;\n }\n\n const exactMatch = normalizedPattern === normalizedMimeType;\n return exactMatch;\n });\n}\n\nexport function isMimeTypeAllowed(mimeType: string, config: SecurityConfig): boolean {\n const { allowedTypes, deniedTypes } = config;\n\n if (!mimeType) return false;\n\n if (deniedTypes?.length && matchesMimePattern(mimeType, deniedTypes)) {\n return false;\n }\n\n if (Array.isArray(allowedTypes)) {\n return allowedTypes.length > 0 && matchesMimePattern(mimeType, allowedTypes);\n }\n\n return true;\n}\n\n/**\n * Single gate for allow/deny. Returns ValidationResult.\n * Doc: docs/docs/01-core/upload/01-backend/01-mime-validation.md\n */\nfunction validateAllowBanLists(\n mimetype: string,\n fileName: string,\n declaredType: string,\n detectedType: string | undefined,\n config: SecurityConfig\n): ValidationResult {\n if (!mimetype) {\n return {\n isValid: false,\n error: {\n code: 'MIME_TYPE_NOT_ALLOWED',\n message: 'MIME type is not allowed',\n details: {\n fileName,\n reason: 'No MIME type to validate',\n declaredType,\n detectedType,\n allowedTypes: config.allowedTypes,\n deniedTypes: config.deniedTypes,\n },\n },\n };\n }\n if (config.deniedTypes?.length && matchesMimePattern(mimetype, config.deniedTypes)) {\n return buildNotAllowedError(fileName, declaredType, detectedType, mimetype, config);\n }\n if (!Array.isArray(config.allowedTypes)) {\n return { isValid: true, detectedMime: mimetype };\n }\n if (config.allowedTypes.length === 0) {\n return {\n isValid: false,\n error: {\n code: 'MIME_TYPE_NOT_ALLOWED',\n message: 'MIME type is not allowed',\n details: {\n fileName,\n reason: 'Allow list is empty',\n declaredType,\n detectedType,\n allowedTypes: config.allowedTypes,\n deniedTypes: config.deniedTypes,\n },\n },\n };\n }\n if (matchesMimePattern(mimetype, config.allowedTypes)) {\n return { isValid: true, detectedMime: mimetype };\n }\n return {\n isValid: false,\n error: {\n code: 'MIME_TYPE_NOT_ALLOWED',\n message: `File type '${mimetype}' is not allowed`,\n details: {\n fileName,\n declaredType,\n detectedType,\n finalType: mimetype,\n allowedTypes: config.allowedTypes,\n deniedTypes: config.deniedTypes,\n },\n },\n };\n}\n\nfunction isDeclaredGeneric(declaredMimeType: string): boolean {\n return !declaredMimeType || declaredMimeType === 'application/octet-stream';\n}\n\nexport function extractFileInfo(file: any) {\n const fileName =\n file.originalFilename ||\n file.name ||\n file.filename ||\n file.newFilename ||\n file.originalname ||\n 'unknown';\n const declaredMimeType = file.mimetype || file.type || file.mimeType || file.mime || '';\n\n return { fileName, declaredMimeType };\n}\n\nexport async function validateFile(\n file: any,\n config: SecurityConfig,\n strapi: Core.Strapi\n): Promise<ValidationResult> {\n const { allowedTypes, deniedTypes } = config;\n\n const { fileName, declaredMimeType } = extractFileInfo(file);\n\n const fileExt = extname(fileName).toLowerCase();\n const expectedMimeFromExt = fileExt ? lookup(fileExt) || null : null;\n\n // Reject if declared type is denied.\n if (\n !isDeclaredGeneric(declaredMimeType) &&\n deniedTypes?.length &&\n matchesMimePattern(declaredMimeType, deniedTypes)\n ) {\n return buildNotAllowedError(fileName, declaredMimeType, undefined, declaredMimeType, config);\n }\n\n // Reject if extension's type is denied.\n if (\n expectedMimeFromExt &&\n deniedTypes?.length &&\n matchesMimePattern(expectedMimeFromExt, deniedTypes)\n ) {\n return buildNotAllowedError(fileName, declaredMimeType, undefined, expectedMimeFromExt, config);\n }\n\n // Run content detection.\n let detectedMime: string | undefined;\n try {\n detectedMime = await detectMimeType(file);\n } catch (error) {\n const errMsg = error instanceof Error ? error.message : String(error);\n strapi.log.warn(`Failed to detect MIME type from file: ${errMsg}`, {\n fileName,\n error: errMsg,\n });\n }\n\n const declaredMatchesExtension =\n !isDeclaredGeneric(declaredMimeType) &&\n expectedMimeFromExt !== null &&\n expectedMimeFromExt !== undefined &&\n (matchesMimePattern(declaredMimeType, [expectedMimeFromExt]) ||\n matchesMimePattern(expectedMimeFromExt, [declaredMimeType]));\n const detectedMatchesDeclared =\n detectedMime && declaredMimeType && matchesMimePattern(detectedMime, [declaredMimeType]);\n\n // Trusted declaration: declared matches extension and detection confirms.\n if (declaredMatchesExtension && detectedMatchesDeclared) {\n return validateAllowBanLists(\n declaredMimeType,\n fileName,\n declaredMimeType,\n detectedMime,\n config\n );\n }\n\n // Reject if detected type is denied.\n if (detectedMime && deniedTypes?.length && matchesMimePattern(detectedMime, deniedTypes)) {\n return buildNotAllowedError(fileName, declaredMimeType, detectedMime, detectedMime, config);\n }\n\n // Reject if detected is not in allow list (extension/declared cannot override).\n // Exception: file-type often returns application/zip for Office formats (docx, xlsx); skip so the next block can allow via extension type.\n const isZipWithAllowedExt =\n detectedMime === 'application/zip' &&\n expectedMimeFromExt &&\n expectedMimeFromExt !== 'application/zip' &&\n Array.isArray(allowedTypes) &&\n allowedTypes.length > 0 &&\n matchesMimePattern(expectedMimeFromExt, allowedTypes);\n if (\n detectedMime &&\n Array.isArray(allowedTypes) &&\n allowedTypes.length > 0 &&\n !matchesMimePattern(detectedMime, allowedTypes) &&\n !isZipWithAllowedExt\n ) {\n return {\n isValid: false,\n error: {\n code: 'MIME_TYPE_NOT_ALLOWED',\n message: 'MIME type is not allowed',\n details: {\n fileName,\n reason:\n 'File content was detected as a type not in the allow list; extension or declared type cannot override',\n declaredType: declaredMimeType,\n detectedType: detectedMime,\n expectedMimeFromExtension: expectedMimeFromExt,\n allowedTypes,\n deniedTypes,\n },\n },\n };\n }\n\n // Use detected type when defined and (no extension, or detected matches extension, or declared is generic).\n const detectedMatchesExtension =\n detectedMime &&\n expectedMimeFromExt !== null &&\n expectedMimeFromExt !== undefined &&\n matchesMimePattern(detectedMime, [expectedMimeFromExt]);\n if (\n detectedMime &&\n (!expectedMimeFromExt || detectedMatchesExtension || isDeclaredGeneric(declaredMimeType))\n ) {\n // Office/zip exception: use extension type when detection returned application/zip and extension is in allow list.\n if (\n detectedMime === 'application/zip' &&\n expectedMimeFromExt &&\n expectedMimeFromExt !== 'application/zip'\n ) {\n const extResult = validateAllowBanLists(\n expectedMimeFromExt,\n fileName,\n declaredMimeType,\n detectedMime,\n config\n );\n if (extResult.isValid) {\n strapi.log.warn(\n 'MIME type detection returned application/zip; trusting extension for allow list',\n { fileName, fileExtension: fileExt, expectedMimeFromExtension: expectedMimeFromExt }\n );\n return extResult;\n }\n }\n return validateAllowBanLists(detectedMime, fileName, declaredMimeType, detectedMime, config);\n }\n\n // Use extension's type when present.\n if (expectedMimeFromExt) {\n return validateAllowBanLists(\n expectedMimeFromExt,\n fileName,\n declaredMimeType,\n detectedMime,\n config\n );\n }\n\n // Use declared type as last resort.\n if (declaredMimeType) {\n return validateAllowBanLists(\n declaredMimeType,\n fileName,\n declaredMimeType,\n detectedMime,\n config\n );\n }\n\n // Reject when no type can be chosen.\n return {\n isValid: false,\n error: {\n code: 'MIME_TYPE_NOT_ALLOWED',\n message: 'Cannot verify file type for security reasons',\n details: {\n fileName,\n reason: 'No MIME type to validate (no declared type, no extension, no detection)',\n declaredType: declaredMimeType,\n detectedType: detectedMime,\n allowedTypes,\n deniedTypes,\n },\n },\n };\n}\n\nfunction buildNotAllowedError(\n fileName: string,\n declaredType: string,\n detectedType: string | undefined,\n rejectedType: string,\n config: SecurityConfig\n): ValidationResult {\n return {\n isValid: false,\n error: {\n code: 'MIME_TYPE_NOT_ALLOWED',\n message: `File type '${rejectedType}' is not allowed`,\n details: {\n fileName,\n declaredType,\n detectedType,\n finalType: rejectedType,\n allowedTypes: config.allowedTypes,\n deniedTypes: config.deniedTypes,\n reason: 'MIME type is in the denied list',\n },\n },\n };\n}\n\nexport async function validateFiles(files: any, strapi: Core.Strapi): Promise<ValidationResult[]> {\n const filesArray = Array.isArray(files) ? files : [files];\n\n if (!filesArray.length) {\n return [];\n }\n\n // Use array path so 'plugin::upload' is a single key (lodash string path splits on '.')\n let config: SecurityConfig = strapi.config.get(\n ['plugin::upload', 'security'],\n {}\n ) as SecurityConfig;\n if (!config || typeof config !== 'object') {\n config = {};\n }\n if (\n config.allowedTypes &&\n (!Array.isArray(config.allowedTypes) ||\n !config.allowedTypes.every((item) => typeof item === 'string'))\n ) {\n throw new errors.ApplicationError(\n 'Invalid configuration: allowedTypes must be an array of strings.'\n );\n }\n\n if (\n config.deniedTypes &&\n (!Array.isArray(config.deniedTypes) ||\n !config.deniedTypes.every((item) => typeof item === 'string'))\n ) {\n throw new errors.ApplicationError(\n 'Invalid configuration: deniedTypes must be an array of strings.'\n );\n }\n\n if (!config.allowedTypes && !config.deniedTypes) {\n strapi.log.warn(\n 'No upload security configuration found. Consider configuring plugin.upload.security for enhanced file validation.'\n );\n // Do not return; we still run validation so MIME detection runs and stored file gets detected type when possible\n }\n\n const validationPromises = filesArray.map(async (file, index) => {\n try {\n return await validateFile(file, config, strapi);\n } catch (error) {\n strapi.log.error('Unexpected error during file validation', {\n fileIndex: index,\n fileName: file?.name || file?.originalname,\n error: error instanceof Error ? error.message : String(error),\n });\n\n return {\n isValid: false,\n error: {\n code: 'VALIDATION_ERROR' as const,\n message: `Validation failed for file at index ${index}`,\n details: {\n index,\n fileName: file?.name || file?.originalname,\n originalError: error instanceof Error ? error.message : String(error),\n },\n },\n };\n }\n });\n\n return Promise.all(validationPromises);\n}\n\nexport async function enforceUploadSecurity(\n files: any,\n strapi: Core.Strapi\n): Promise<{\n validFiles: any[];\n validFileNames: string[];\n errors: Array<ErrorDetail>;\n}> {\n const validationResults = await validateFiles(files, strapi);\n const filesArray = Array.isArray(files) ? files : [files];\n\n const validFiles: any[] = [];\n const validFileNames: string[] = [];\n const errors: Array<ErrorDetail> = [];\n\n for (const [index, result] of validationResults.entries()) {\n if (result.isValid) {\n const file = filesArray[index];\n // Enrich file with detected MIME type for use in storage\n if (result.detectedMime) {\n file.detectedMimeType = result.detectedMime;\n }\n validFiles.push(file);\n validFileNames.push(file.originalFilename || file.name);\n } else if (result.error) {\n errors.push({\n file: filesArray[index],\n originalIndex: index,\n error: result.error,\n });\n } else {\n // Handle case where validation failed but no error details are provided\n errors.push({\n file: filesArray[index],\n originalIndex: index,\n error: {\n code: 'UNKNOWN_ERROR' as const,\n message: 'File validation failed for unknown reason',\n details: {\n index,\n fileName: filesArray[index]?.name || filesArray[index]?.originalname,\n },\n },\n });\n }\n }\n\n return { validFiles, validFileNames, errors };\n}\n\nexport type FileUploadError = {\n name: string;\n message: string;\n};\n\nexport type PrepareUploadResult = {\n validFiles: any[];\n filteredBody: any;\n errors: FileUploadError[];\n};\n\n/**\n * Prepare files and body for upload by enforcing security and parsing fileInfo\n */\nexport async function prepareUploadRequest(\n filesInput: any,\n body: any,\n strapi: Core.Strapi\n): Promise<PrepareUploadResult> {\n const securityResults = await enforceUploadSecurity(filesInput, strapi);\n\n let filteredBody = body;\n if (body?.fileInfo) {\n // Parse JSON strings in fileInfo\n let parsedFileInfo = body.fileInfo;\n if (Array.isArray(body.fileInfo)) {\n parsedFileInfo = body.fileInfo.map((fi: any) =>\n typeof fi === 'string' ? JSON.parse(fi) : fi\n );\n } else if (typeof body.fileInfo === 'string') {\n parsedFileInfo = JSON.parse(body.fileInfo);\n }\n\n // Filter fileInfo by index - only keep entries for files that passed validation\n if (Array.isArray(parsedFileInfo)) {\n const invalidIndices = new Set(securityResults.errors.map((e) => e.originalIndex));\n const filteredFileInfo = parsedFileInfo.filter(\n (_: any, index: number) => !invalidIndices.has(index)\n );\n\n if (filteredFileInfo.length === 1) {\n filteredBody = {\n ...body,\n fileInfo: filteredFileInfo[0],\n };\n } else {\n filteredBody = {\n ...body,\n fileInfo: filteredFileInfo,\n };\n }\n } else {\n filteredBody = {\n ...body,\n fileInfo: parsedFileInfo,\n };\n }\n }\n\n // Map errors to simplified format\n const uploadErrors: FileUploadError[] = securityResults.errors.map((e) => ({\n name: e.file?.originalFilename || e.file?.name || 'unknown',\n message: e.error.message,\n }));\n\n return {\n validFiles: securityResults.validFiles,\n filteredBody,\n errors: uploadErrors,\n };\n}\n"],"names":["readFileChunk","filePath","chunkSize","buffer","readFile","length","subarray","detectMimeType","file","filepath","path","tempFilePath","error","Error","message","String","undefined","fileTypeFromBuffer","result","Uint8Array","mime","matchesMimePattern","mimeType","patterns","some","pattern","normalizedPattern","toLowerCase","normalizedMimeType","includes","regexPattern","replace","regex","RegExp","matches","test","exactMatch","validateAllowBanLists","mimetype","fileName","declaredType","detectedType","config","isValid","code","details","reason","allowedTypes","deniedTypes","buildNotAllowedError","Array","isArray","detectedMime","finalType","isDeclaredGeneric","declaredMimeType","extractFileInfo","originalFilename","name","filename","newFilename","originalname","type","validateFile","strapi","fileExt","extname","expectedMimeFromExt","lookup","errMsg","log","warn","declaredMatchesExtension","detectedMatchesDeclared","isZipWithAllowedExt","expectedMimeFromExtension","detectedMatchesExtension","extResult","fileExtension","rejectedType","validateFiles","files","filesArray","get","every","item","errors","ApplicationError","validationPromises","map","index","fileIndex","originalError","Promise","all","enforceUploadSecurity","validationResults","validFiles","validFileNames","entries","detectedMimeType","push","originalIndex","prepareUploadRequest","filesInput","body","securityResults","filteredBody","fileInfo","parsedFileInfo","fi","JSON","parse","invalidIndices","Set","e","filteredFileInfo","filter","_","has","uploadErrors"],"mappings":"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"}
1
+ {"version":3,"file":"mime-validation.js","sources":["../../../server/src/utils/mime-validation.ts"],"sourcesContent":["import { open } from 'node:fs/promises';\nimport { extname } from 'node:path';\nimport { lookup } from 'mime-types';\nimport type { Core } from '@strapi/types';\nimport { errors } from '@strapi/utils';\n\nexport type SecurityConfig = {\n allowedTypes?: string[];\n deniedTypes?: string[];\n};\ntype UploadValidationError = {\n code: 'MIME_TYPE_NOT_ALLOWED' | 'VALIDATION_ERROR' | 'UNKNOWN_ERROR';\n message: string;\n details: Record<string, any>;\n};\n\ntype ValidationResult = {\n isValid: boolean;\n error?: UploadValidationError;\n detectedMime?: string;\n};\n\ntype ErrorDetail = {\n file: any;\n originalIndex: number;\n error: UploadValidationError;\n};\n\nasync function readFileChunk(filePath: string, chunkSize: number = 4100): Promise<Buffer> {\n const file = await open(filePath, 'r');\n\n try {\n const buffer = Buffer.alloc(chunkSize);\n const { bytesRead } = await file.read(buffer, 0, chunkSize, 0);\n\n return buffer.subarray(0, bytesRead);\n } finally {\n await file.close();\n }\n}\n\nexport async function detectMimeType(file: any): Promise<string | undefined> {\n let buffer: Buffer;\n\n // Support multiple property names used by different multipart parsers (formidable uses filepath)\n const filePath = file.filepath ?? file.path ?? file.tempFilePath ?? file.filePath;\n\n if (filePath) {\n try {\n buffer = await readFileChunk(filePath, 4100);\n } catch (error) {\n throw new Error(\n `Failed to read file: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n } else if (file.buffer) {\n buffer = file.buffer.length > 4100 ? file.buffer.subarray(0, 4100) : file.buffer;\n } else {\n // No file path or buffer; cannot detect MIME. Validation will use declared/extension or reject.\n return undefined;\n }\n\n try {\n /**\n * Use dynamic import to support file-type which is ESM-only\n * Static imports fail during CommonJS build since bundler can't transform ESM-only packages\n * @see https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c\n */\n const { fileTypeFromBuffer } = await import('file-type');\n\n const result = await fileTypeFromBuffer(new Uint8Array(buffer));\n return result?.mime;\n } catch (error) {\n throw new Error(\n `Failed to detect MIME type: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\nfunction matchesMimePattern(mimeType: string, patterns: string[]): boolean {\n if (!patterns?.length) return false;\n\n return patterns.some((pattern) => {\n const normalizedPattern = pattern.toLowerCase();\n const normalizedMimeType = mimeType.toLowerCase();\n\n if (normalizedPattern.includes('*')) {\n const regexPattern = normalizedPattern.replace(/\\*/g, '.*');\n\n const regex = new RegExp(`^${regexPattern}$`);\n const matches = regex.test(normalizedMimeType);\n return matches;\n }\n\n const exactMatch = normalizedPattern === normalizedMimeType;\n return exactMatch;\n });\n}\n\nexport function isMimeTypeAllowed(mimeType: string, config: SecurityConfig): boolean {\n const { allowedTypes, deniedTypes } = config;\n\n if (!mimeType) return false;\n\n if (deniedTypes?.length && matchesMimePattern(mimeType, deniedTypes)) {\n return false;\n }\n\n if (Array.isArray(allowedTypes)) {\n return allowedTypes.length > 0 && matchesMimePattern(mimeType, allowedTypes);\n }\n\n return true;\n}\n\n/**\n * Single gate for allow/deny. Returns ValidationResult.\n * Doc: docs/docs/01-core/upload/01-backend/01-mime-validation.md\n */\nfunction validateAllowBanLists(\n mimetype: string,\n fileName: string,\n declaredType: string,\n detectedType: string | undefined,\n config: SecurityConfig\n): ValidationResult {\n if (!mimetype) {\n return {\n isValid: false,\n error: {\n code: 'MIME_TYPE_NOT_ALLOWED',\n message: 'MIME type is not allowed',\n details: {\n fileName,\n reason: 'No MIME type to validate',\n declaredType,\n detectedType,\n allowedTypes: config.allowedTypes,\n deniedTypes: config.deniedTypes,\n },\n },\n };\n }\n if (config.deniedTypes?.length && matchesMimePattern(mimetype, config.deniedTypes)) {\n return buildNotAllowedError(fileName, declaredType, detectedType, mimetype, config);\n }\n if (!Array.isArray(config.allowedTypes)) {\n return { isValid: true, detectedMime: mimetype };\n }\n if (config.allowedTypes.length === 0) {\n return {\n isValid: false,\n error: {\n code: 'MIME_TYPE_NOT_ALLOWED',\n message: 'MIME type is not allowed',\n details: {\n fileName,\n reason: 'Allow list is empty',\n declaredType,\n detectedType,\n allowedTypes: config.allowedTypes,\n deniedTypes: config.deniedTypes,\n },\n },\n };\n }\n if (matchesMimePattern(mimetype, config.allowedTypes)) {\n return { isValid: true, detectedMime: mimetype };\n }\n return {\n isValid: false,\n error: {\n code: 'MIME_TYPE_NOT_ALLOWED',\n message: `File type '${mimetype}' is not allowed`,\n details: {\n fileName,\n declaredType,\n detectedType,\n finalType: mimetype,\n allowedTypes: config.allowedTypes,\n deniedTypes: config.deniedTypes,\n },\n },\n };\n}\n\nfunction isDeclaredGeneric(declaredMimeType: string): boolean {\n return !declaredMimeType || declaredMimeType === 'application/octet-stream';\n}\n\nexport function extractFileInfo(file: any) {\n const fileName =\n file.originalFilename ||\n file.name ||\n file.filename ||\n file.newFilename ||\n file.originalname ||\n 'unknown';\n const declaredMimeType = file.mimetype || file.type || file.mimeType || file.mime || '';\n\n return { fileName, declaredMimeType };\n}\n\nexport async function validateFile(\n file: any,\n config: SecurityConfig,\n strapi: Core.Strapi\n): Promise<ValidationResult> {\n const { allowedTypes, deniedTypes } = config;\n\n const { fileName, declaredMimeType } = extractFileInfo(file);\n\n const fileExt = extname(fileName).toLowerCase();\n const expectedMimeFromExt = fileExt ? lookup(fileExt) || null : null;\n\n // Reject if declared type is denied.\n if (\n !isDeclaredGeneric(declaredMimeType) &&\n deniedTypes?.length &&\n matchesMimePattern(declaredMimeType, deniedTypes)\n ) {\n return buildNotAllowedError(fileName, declaredMimeType, undefined, declaredMimeType, config);\n }\n\n // Reject if extension's type is denied.\n if (\n expectedMimeFromExt &&\n deniedTypes?.length &&\n matchesMimePattern(expectedMimeFromExt, deniedTypes)\n ) {\n return buildNotAllowedError(fileName, declaredMimeType, undefined, expectedMimeFromExt, config);\n }\n\n // Run content detection.\n let detectedMime: string | undefined;\n try {\n detectedMime = await detectMimeType(file);\n } catch (error) {\n const errMsg = error instanceof Error ? error.message : String(error);\n strapi.log.warn(`Failed to detect MIME type from file: ${errMsg}`, {\n fileName,\n error: errMsg,\n });\n }\n\n const declaredMatchesExtension =\n !isDeclaredGeneric(declaredMimeType) &&\n expectedMimeFromExt !== null &&\n expectedMimeFromExt !== undefined &&\n (matchesMimePattern(declaredMimeType, [expectedMimeFromExt]) ||\n matchesMimePattern(expectedMimeFromExt, [declaredMimeType]));\n const detectedMatchesDeclared =\n detectedMime && declaredMimeType && matchesMimePattern(detectedMime, [declaredMimeType]);\n\n // Trusted declaration: declared matches extension and detection confirms.\n if (declaredMatchesExtension && detectedMatchesDeclared) {\n return validateAllowBanLists(\n declaredMimeType,\n fileName,\n declaredMimeType,\n detectedMime,\n config\n );\n }\n\n // Reject if detected type is denied.\n if (detectedMime && deniedTypes?.length && matchesMimePattern(detectedMime, deniedTypes)) {\n return buildNotAllowedError(fileName, declaredMimeType, detectedMime, detectedMime, config);\n }\n\n // Reject if detected is not in allow list (extension/declared cannot override).\n // Exception: file-type often returns application/zip for Office formats (docx, xlsx); skip so the next block can allow via extension type.\n const isZipWithAllowedExt =\n detectedMime === 'application/zip' &&\n expectedMimeFromExt &&\n expectedMimeFromExt !== 'application/zip' &&\n Array.isArray(allowedTypes) &&\n allowedTypes.length > 0 &&\n matchesMimePattern(expectedMimeFromExt, allowedTypes);\n // Exception: file-type often returns application/xml for SVG; trust .svg extension when image/svg+xml is allowed.\n const isSvgXmlWithAllowedExt =\n detectedMime === 'application/xml' &&\n fileExt === '.svg' &&\n expectedMimeFromExt === 'image/svg+xml' &&\n Array.isArray(allowedTypes) &&\n allowedTypes.length > 0 &&\n matchesMimePattern(expectedMimeFromExt, allowedTypes);\n if (\n detectedMime &&\n Array.isArray(allowedTypes) &&\n allowedTypes.length > 0 &&\n !matchesMimePattern(detectedMime, allowedTypes) &&\n !isZipWithAllowedExt &&\n !isSvgXmlWithAllowedExt\n ) {\n return {\n isValid: false,\n error: {\n code: 'MIME_TYPE_NOT_ALLOWED',\n message: 'MIME type is not allowed',\n details: {\n fileName,\n reason:\n 'File content was detected as a type not in the allow list; extension or declared type cannot override',\n declaredType: declaredMimeType,\n detectedType: detectedMime,\n expectedMimeFromExtension: expectedMimeFromExt,\n allowedTypes,\n deniedTypes,\n },\n },\n };\n }\n\n // Use detected type when defined and (no extension, or detected matches extension, or declared is generic).\n const detectedMatchesExtension =\n detectedMime &&\n expectedMimeFromExt !== null &&\n expectedMimeFromExt !== undefined &&\n matchesMimePattern(detectedMime, [expectedMimeFromExt]);\n if (\n detectedMime &&\n (!expectedMimeFromExt || detectedMatchesExtension || isDeclaredGeneric(declaredMimeType))\n ) {\n // Office/zip exception: use extension type when detection returned application/zip and extension is in allow list.\n if (\n detectedMime === 'application/zip' &&\n expectedMimeFromExt &&\n expectedMimeFromExt !== 'application/zip'\n ) {\n const extResult = validateAllowBanLists(\n expectedMimeFromExt,\n fileName,\n declaredMimeType,\n detectedMime,\n config\n );\n if (extResult.isValid) {\n strapi.log.warn(\n 'MIME type detection returned application/zip; trusting extension for allow list',\n { fileName, fileExtension: fileExt, expectedMimeFromExtension: expectedMimeFromExt }\n );\n return extResult;\n }\n }\n return validateAllowBanLists(detectedMime, fileName, declaredMimeType, detectedMime, config);\n }\n\n // Use extension's type when present.\n if (expectedMimeFromExt) {\n return validateAllowBanLists(\n expectedMimeFromExt,\n fileName,\n declaredMimeType,\n detectedMime,\n config\n );\n }\n\n // Use declared type as last resort.\n if (declaredMimeType) {\n return validateAllowBanLists(\n declaredMimeType,\n fileName,\n declaredMimeType,\n detectedMime,\n config\n );\n }\n\n // Reject when no type can be chosen.\n return {\n isValid: false,\n error: {\n code: 'MIME_TYPE_NOT_ALLOWED',\n message: 'Cannot verify file type for security reasons',\n details: {\n fileName,\n reason: 'No MIME type to validate (no declared type, no extension, no detection)',\n declaredType: declaredMimeType,\n detectedType: detectedMime,\n allowedTypes,\n deniedTypes,\n },\n },\n };\n}\n\nfunction buildNotAllowedError(\n fileName: string,\n declaredType: string,\n detectedType: string | undefined,\n rejectedType: string,\n config: SecurityConfig\n): ValidationResult {\n return {\n isValid: false,\n error: {\n code: 'MIME_TYPE_NOT_ALLOWED',\n message: `File type '${rejectedType}' is not allowed`,\n details: {\n fileName,\n declaredType,\n detectedType,\n finalType: rejectedType,\n allowedTypes: config.allowedTypes,\n deniedTypes: config.deniedTypes,\n reason: 'MIME type is in the denied list',\n },\n },\n };\n}\n\nexport async function validateFiles(files: any, strapi: Core.Strapi): Promise<ValidationResult[]> {\n const filesArray = Array.isArray(files) ? files : [files];\n\n if (!filesArray.length) {\n return [];\n }\n\n // Use array path so 'plugin::upload' is a single key (lodash string path splits on '.')\n let config: SecurityConfig = strapi.config.get(\n ['plugin::upload', 'security'],\n {}\n ) as SecurityConfig;\n if (!config || typeof config !== 'object') {\n config = {};\n }\n if (\n config.allowedTypes &&\n (!Array.isArray(config.allowedTypes) ||\n !config.allowedTypes.every((item) => typeof item === 'string'))\n ) {\n throw new errors.ApplicationError(\n 'Invalid configuration: allowedTypes must be an array of strings.'\n );\n }\n\n if (\n config.deniedTypes &&\n (!Array.isArray(config.deniedTypes) ||\n !config.deniedTypes.every((item) => typeof item === 'string'))\n ) {\n throw new errors.ApplicationError(\n 'Invalid configuration: deniedTypes must be an array of strings.'\n );\n }\n\n if (!config.allowedTypes && !config.deniedTypes) {\n strapi.log.warn(\n 'No upload security configuration found. Consider configuring plugin.upload.security for enhanced file validation.'\n );\n // Do not return; we still run validation so MIME detection runs and stored file gets detected type when possible\n }\n\n const validationPromises = filesArray.map(async (file, index) => {\n try {\n return await validateFile(file, config, strapi);\n } catch (error) {\n strapi.log.error('Unexpected error during file validation', {\n fileIndex: index,\n fileName: file?.name || file?.originalname,\n error: error instanceof Error ? error.message : String(error),\n });\n\n return {\n isValid: false,\n error: {\n code: 'VALIDATION_ERROR' as const,\n message: `Validation failed for file at index ${index}`,\n details: {\n index,\n fileName: file?.name || file?.originalname,\n originalError: error instanceof Error ? error.message : String(error),\n },\n },\n };\n }\n });\n\n return Promise.all(validationPromises);\n}\n\nexport async function enforceUploadSecurity(\n files: any,\n strapi: Core.Strapi\n): Promise<{\n validFiles: any[];\n validFileNames: string[];\n errors: Array<ErrorDetail>;\n}> {\n const validationResults = await validateFiles(files, strapi);\n const filesArray = Array.isArray(files) ? files : [files];\n\n const validFiles: any[] = [];\n const validFileNames: string[] = [];\n const errors: Array<ErrorDetail> = [];\n\n for (const [index, result] of validationResults.entries()) {\n if (result.isValid) {\n const file = filesArray[index];\n // Enrich file with detected MIME type for use in storage\n if (result.detectedMime) {\n file.detectedMimeType = result.detectedMime;\n }\n validFiles.push(file);\n validFileNames.push(file.originalFilename || file.name);\n } else if (result.error) {\n errors.push({\n file: filesArray[index],\n originalIndex: index,\n error: result.error,\n });\n } else {\n // Handle case where validation failed but no error details are provided\n errors.push({\n file: filesArray[index],\n originalIndex: index,\n error: {\n code: 'UNKNOWN_ERROR' as const,\n message: 'File validation failed for unknown reason',\n details: {\n index,\n fileName: filesArray[index]?.name || filesArray[index]?.originalname,\n },\n },\n });\n }\n }\n\n return { validFiles, validFileNames, errors };\n}\n\nexport type FileUploadError = {\n name: string;\n message: string;\n};\n\nexport type PrepareUploadResult = {\n validFiles: any[];\n filteredBody: any;\n errors: FileUploadError[];\n};\n\n/**\n * Prepare files and body for upload by enforcing security and parsing fileInfo\n */\nexport async function prepareUploadRequest(\n filesInput: any,\n body: any,\n strapi: Core.Strapi\n): Promise<PrepareUploadResult> {\n const securityResults = await enforceUploadSecurity(filesInput, strapi);\n\n let filteredBody = body;\n if (body?.fileInfo) {\n // Parse JSON strings in fileInfo\n let parsedFileInfo = body.fileInfo;\n if (Array.isArray(body.fileInfo)) {\n parsedFileInfo = body.fileInfo.map((fi: any) =>\n typeof fi === 'string' ? JSON.parse(fi) : fi\n );\n } else if (typeof body.fileInfo === 'string') {\n parsedFileInfo = JSON.parse(body.fileInfo);\n }\n\n // Filter fileInfo by index - only keep entries for files that passed validation\n if (Array.isArray(parsedFileInfo)) {\n const invalidIndices = new Set(securityResults.errors.map((e) => e.originalIndex));\n const filteredFileInfo = parsedFileInfo.filter(\n (_: any, index: number) => !invalidIndices.has(index)\n );\n\n if (filteredFileInfo.length === 1) {\n filteredBody = {\n ...body,\n fileInfo: filteredFileInfo[0],\n };\n } else {\n filteredBody = {\n ...body,\n fileInfo: filteredFileInfo,\n };\n }\n } else {\n filteredBody = {\n ...body,\n fileInfo: parsedFileInfo,\n };\n }\n }\n\n // Map errors to simplified format\n const uploadErrors: FileUploadError[] = securityResults.errors.map((e) => ({\n name: e.file?.originalFilename || e.file?.name || 'unknown',\n message: e.error.message,\n }));\n\n return {\n validFiles: securityResults.validFiles,\n filteredBody,\n errors: uploadErrors,\n };\n}\n"],"names":["readFileChunk","filePath","chunkSize","file","open","buffer","Buffer","alloc","bytesRead","read","subarray","close","detectMimeType","filepath","path","tempFilePath","error","Error","message","String","length","undefined","fileTypeFromBuffer","result","Uint8Array","mime","matchesMimePattern","mimeType","patterns","some","pattern","normalizedPattern","toLowerCase","normalizedMimeType","includes","regexPattern","replace","regex","RegExp","matches","test","exactMatch","validateAllowBanLists","mimetype","fileName","declaredType","detectedType","config","isValid","code","details","reason","allowedTypes","deniedTypes","buildNotAllowedError","Array","isArray","detectedMime","finalType","isDeclaredGeneric","declaredMimeType","extractFileInfo","originalFilename","name","filename","newFilename","originalname","type","validateFile","strapi","fileExt","extname","expectedMimeFromExt","lookup","errMsg","log","warn","declaredMatchesExtension","detectedMatchesDeclared","isZipWithAllowedExt","isSvgXmlWithAllowedExt","expectedMimeFromExtension","detectedMatchesExtension","extResult","fileExtension","rejectedType","validateFiles","files","filesArray","get","every","item","errors","ApplicationError","validationPromises","map","index","fileIndex","originalError","Promise","all","enforceUploadSecurity","validationResults","validFiles","validFileNames","entries","detectedMimeType","push","originalIndex","prepareUploadRequest","filesInput","body","securityResults","filteredBody","fileInfo","parsedFileInfo","fi","JSON","parse","invalidIndices","Set","e","filteredFileInfo","filter","_","has","uploadErrors"],"mappings":"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"}
@@ -1,11 +1,17 @@
1
- import { readFile } from 'node:fs/promises';
1
+ import { open } from 'node:fs/promises';
2
2
  import { extname } from 'node:path';
3
3
  import { lookup } from 'mime-types';
4
4
  import { errors } from '@strapi/utils';
5
5
 
6
6
  async function readFileChunk(filePath, chunkSize = 4100) {
7
- const buffer = await readFile(filePath);
8
- return buffer.length > chunkSize ? buffer.subarray(0, chunkSize) : buffer;
7
+ const file = await open(filePath, 'r');
8
+ try {
9
+ const buffer = Buffer.alloc(chunkSize);
10
+ const { bytesRead } = await file.read(buffer, 0, chunkSize, 0);
11
+ return buffer.subarray(0, bytesRead);
12
+ } finally{
13
+ await file.close();
14
+ }
9
15
  }
10
16
  async function detectMimeType(file) {
11
17
  let buffer;
@@ -173,7 +179,9 @@ async function validateFile(file, config, strapi) {
173
179
  // Reject if detected is not in allow list (extension/declared cannot override).
174
180
  // Exception: file-type often returns application/zip for Office formats (docx, xlsx); skip so the next block can allow via extension type.
175
181
  const isZipWithAllowedExt = detectedMime === 'application/zip' && expectedMimeFromExt && expectedMimeFromExt !== 'application/zip' && Array.isArray(allowedTypes) && allowedTypes.length > 0 && matchesMimePattern(expectedMimeFromExt, allowedTypes);
176
- if (detectedMime && Array.isArray(allowedTypes) && allowedTypes.length > 0 && !matchesMimePattern(detectedMime, allowedTypes) && !isZipWithAllowedExt) {
182
+ // Exception: file-type often returns application/xml for SVG; trust .svg extension when image/svg+xml is allowed.
183
+ const isSvgXmlWithAllowedExt = detectedMime === 'application/xml' && fileExt === '.svg' && expectedMimeFromExt === 'image/svg+xml' && Array.isArray(allowedTypes) && allowedTypes.length > 0 && matchesMimePattern(expectedMimeFromExt, allowedTypes);
184
+ if (detectedMime && Array.isArray(allowedTypes) && allowedTypes.length > 0 && !matchesMimePattern(detectedMime, allowedTypes) && !isZipWithAllowedExt && !isSvgXmlWithAllowedExt) {
177
185
  return {
178
186
  isValid: false,
179
187
  error: {