@strapi/admin 5.33.4 → 5.35.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 (310) hide show
  1. package/dist/admin/admin/src/components/GradientBadge.js +18 -2
  2. package/dist/admin/admin/src/components/GradientBadge.js.map +1 -1
  3. package/dist/admin/admin/src/components/GradientBadge.mjs +19 -3
  4. package/dist/admin/admin/src/components/GradientBadge.mjs.map +1 -1
  5. package/dist/admin/admin/src/components/Layouts/ActionLayout.js +8 -1
  6. package/dist/admin/admin/src/components/Layouts/ActionLayout.js.map +1 -1
  7. package/dist/admin/admin/src/components/Layouts/ActionLayout.mjs +8 -1
  8. package/dist/admin/admin/src/components/Layouts/ActionLayout.mjs.map +1 -1
  9. package/dist/admin/admin/src/components/Layouts/ContentLayout.js +4 -0
  10. package/dist/admin/admin/src/components/Layouts/ContentLayout.js.map +1 -1
  11. package/dist/admin/admin/src/components/Layouts/ContentLayout.mjs +4 -0
  12. package/dist/admin/admin/src/components/Layouts/ContentLayout.mjs.map +1 -1
  13. package/dist/admin/admin/src/components/Layouts/HeaderLayout.js +84 -50
  14. package/dist/admin/admin/src/components/Layouts/HeaderLayout.js.map +1 -1
  15. package/dist/admin/admin/src/components/Layouts/HeaderLayout.mjs +86 -52
  16. package/dist/admin/admin/src/components/Layouts/HeaderLayout.mjs.map +1 -1
  17. package/dist/admin/admin/src/components/MainNav/MainNavLinks.js +1 -0
  18. package/dist/admin/admin/src/components/MainNav/MainNavLinks.js.map +1 -1
  19. package/dist/admin/admin/src/components/MainNav/MainNavLinks.mjs +1 -0
  20. package/dist/admin/admin/src/components/MainNav/MainNavLinks.mjs.map +1 -1
  21. package/dist/admin/admin/src/components/MainNav/NavLink.js +37 -6
  22. package/dist/admin/admin/src/components/MainNav/NavLink.js.map +1 -1
  23. package/dist/admin/admin/src/components/MainNav/NavLink.mjs +38 -7
  24. package/dist/admin/admin/src/components/MainNav/NavLink.mjs.map +1 -1
  25. package/dist/admin/admin/src/components/NpsSurvey.js +2 -0
  26. package/dist/admin/admin/src/components/NpsSurvey.js.map +1 -1
  27. package/dist/admin/admin/src/components/NpsSurvey.mjs +2 -0
  28. package/dist/admin/admin/src/components/NpsSurvey.mjs.map +1 -1
  29. package/dist/admin/admin/src/components/SubNav.js +41 -20
  30. package/dist/admin/admin/src/components/SubNav.js.map +1 -1
  31. package/dist/admin/admin/src/components/SubNav.mjs +42 -21
  32. package/dist/admin/admin/src/components/SubNav.mjs.map +1 -1
  33. package/dist/admin/admin/src/constants/theme.js +2 -0
  34. package/dist/admin/admin/src/constants/theme.js.map +1 -1
  35. package/dist/admin/admin/src/constants/theme.mjs +2 -1
  36. package/dist/admin/admin/src/constants/theme.mjs.map +1 -1
  37. package/dist/admin/admin/src/core/apis/router.js.map +1 -1
  38. package/dist/admin/admin/src/core/apis/router.mjs.map +1 -1
  39. package/dist/admin/admin/src/features/Tracking.js.map +1 -1
  40. package/dist/admin/admin/src/features/Tracking.mjs.map +1 -1
  41. package/dist/admin/admin/src/hooks/useMenu.js +2 -1
  42. package/dist/admin/admin/src/hooks/useMenu.js.map +1 -1
  43. package/dist/admin/admin/src/hooks/useMenu.mjs +2 -1
  44. package/dist/admin/admin/src/hooks/useMenu.mjs.map +1 -1
  45. package/dist/admin/admin/src/layouts/AuthenticatedLayout.js.map +1 -1
  46. package/dist/admin/admin/src/layouts/AuthenticatedLayout.mjs.map +1 -1
  47. package/dist/admin/admin/src/pages/Auth/components/Register.js +51 -10
  48. package/dist/admin/admin/src/pages/Auth/components/Register.js.map +1 -1
  49. package/dist/admin/admin/src/pages/Auth/components/Register.mjs +51 -10
  50. package/dist/admin/admin/src/pages/Auth/components/Register.mjs.map +1 -1
  51. package/dist/admin/admin/src/pages/Auth/components/ResetPassword.js +12 -3
  52. package/dist/admin/admin/src/pages/Auth/components/ResetPassword.js.map +1 -1
  53. package/dist/admin/admin/src/pages/Auth/components/ResetPassword.mjs +12 -3
  54. package/dist/admin/admin/src/pages/Auth/components/ResetPassword.mjs.map +1 -1
  55. package/dist/admin/admin/src/pages/Home/HomePage.js +1 -0
  56. package/dist/admin/admin/src/pages/Home/HomePage.js.map +1 -1
  57. package/dist/admin/admin/src/pages/Home/HomePage.mjs +1 -0
  58. package/dist/admin/admin/src/pages/Home/HomePage.mjs.map +1 -1
  59. package/dist/admin/admin/src/pages/ProfilePage.js +1 -0
  60. package/dist/admin/admin/src/pages/ProfilePage.js.map +1 -1
  61. package/dist/admin/admin/src/pages/ProfilePage.mjs +1 -0
  62. package/dist/admin/admin/src/pages/ProfilePage.mjs.map +1 -1
  63. package/dist/admin/admin/src/pages/Settings/components/SettingsNav.js +7 -2
  64. package/dist/admin/admin/src/pages/Settings/components/SettingsNav.js.map +1 -1
  65. package/dist/admin/admin/src/pages/Settings/components/SettingsNav.mjs +7 -2
  66. package/dist/admin/admin/src/pages/Settings/components/SettingsNav.mjs.map +1 -1
  67. package/dist/admin/admin/src/pages/Settings/components/Tokens/FormHead.js +44 -26
  68. package/dist/admin/admin/src/pages/Settings/components/Tokens/FormHead.js.map +1 -1
  69. package/dist/admin/admin/src/pages/Settings/components/Tokens/FormHead.mjs +45 -27
  70. package/dist/admin/admin/src/pages/Settings/components/Tokens/FormHead.mjs.map +1 -1
  71. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/ListView.js +1 -0
  72. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/ListView.js.map +1 -1
  73. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/ListView.mjs +1 -0
  74. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/ListView.mjs.map +1 -1
  75. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.js +1 -0
  76. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.js.map +1 -1
  77. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.mjs +1 -0
  78. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.mjs.map +1 -1
  79. package/dist/admin/admin/src/pages/Settings/pages/Roles/CreatePage.js +3 -0
  80. package/dist/admin/admin/src/pages/Settings/pages/Roles/CreatePage.js.map +1 -1
  81. package/dist/admin/admin/src/pages/Settings/pages/Roles/CreatePage.mjs +3 -0
  82. package/dist/admin/admin/src/pages/Settings/pages/Roles/CreatePage.mjs.map +1 -1
  83. package/dist/admin/admin/src/pages/Settings/pages/Roles/EditPage.js +9 -11
  84. package/dist/admin/admin/src/pages/Settings/pages/Roles/EditPage.js.map +1 -1
  85. package/dist/admin/admin/src/pages/Settings/pages/Roles/EditPage.mjs +10 -12
  86. package/dist/admin/admin/src/pages/Settings/pages/Roles/EditPage.mjs.map +1 -1
  87. package/dist/admin/admin/src/pages/Settings/pages/Roles/ListPage.js +1 -0
  88. package/dist/admin/admin/src/pages/Settings/pages/Roles/ListPage.js.map +1 -1
  89. package/dist/admin/admin/src/pages/Settings/pages/Roles/ListPage.mjs +1 -0
  90. package/dist/admin/admin/src/pages/Settings/pages/Roles/ListPage.mjs.map +1 -1
  91. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/ListView.js +1 -0
  92. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/ListView.js.map +1 -1
  93. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/ListView.mjs +1 -0
  94. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/ListView.mjs.map +1 -1
  95. package/dist/admin/admin/src/pages/Settings/pages/Users/EditPage.js +1 -0
  96. package/dist/admin/admin/src/pages/Settings/pages/Users/EditPage.js.map +1 -1
  97. package/dist/admin/admin/src/pages/Settings/pages/Users/EditPage.mjs +1 -0
  98. package/dist/admin/admin/src/pages/Settings/pages/Users/EditPage.mjs.map +1 -1
  99. package/dist/admin/admin/src/pages/Settings/pages/Users/components/CreateActionCE.js +1 -0
  100. package/dist/admin/admin/src/pages/Settings/pages/Users/components/CreateActionCE.js.map +1 -1
  101. package/dist/admin/admin/src/pages/Settings/pages/Users/components/CreateActionCE.mjs +1 -0
  102. package/dist/admin/admin/src/pages/Settings/pages/Users/components/CreateActionCE.mjs.map +1 -1
  103. package/dist/admin/admin/src/pages/Settings/pages/Users/utils/validation.js +12 -3
  104. package/dist/admin/admin/src/pages/Settings/pages/Users/utils/validation.js.map +1 -1
  105. package/dist/admin/admin/src/pages/Settings/pages/Users/utils/validation.mjs +12 -3
  106. package/dist/admin/admin/src/pages/Settings/pages/Users/utils/validation.mjs.map +1 -1
  107. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/ListPage.js +1 -0
  108. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/ListPage.js.map +1 -1
  109. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/ListPage.mjs +1 -0
  110. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/ListPage.mjs.map +1 -1
  111. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/WebhookForm.js +3 -0
  112. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/WebhookForm.js.map +1 -1
  113. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/WebhookForm.mjs +3 -0
  114. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/WebhookForm.mjs.map +1 -1
  115. package/dist/admin/admin/src/router.js +0 -9
  116. package/dist/admin/admin/src/router.js.map +1 -1
  117. package/dist/admin/admin/src/router.mjs +0 -9
  118. package/dist/admin/admin/src/router.mjs.map +1 -1
  119. package/dist/admin/admin/src/translations/ar.json.js +0 -42
  120. package/dist/admin/admin/src/translations/ar.json.js.map +1 -1
  121. package/dist/admin/admin/src/translations/ar.json.mjs +0 -42
  122. package/dist/admin/admin/src/translations/ar.json.mjs.map +1 -1
  123. package/dist/admin/admin/src/translations/ca.json.js +0 -21
  124. package/dist/admin/admin/src/translations/ca.json.js.map +1 -1
  125. package/dist/admin/admin/src/translations/ca.json.mjs +0 -21
  126. package/dist/admin/admin/src/translations/ca.json.mjs.map +1 -1
  127. package/dist/admin/admin/src/translations/de.json.js +422 -66
  128. package/dist/admin/admin/src/translations/de.json.js.map +1 -1
  129. package/dist/admin/admin/src/translations/de.json.mjs +419 -67
  130. package/dist/admin/admin/src/translations/de.json.mjs.map +1 -1
  131. package/dist/admin/admin/src/translations/dk.json.js +0 -6
  132. package/dist/admin/admin/src/translations/dk.json.js.map +1 -1
  133. package/dist/admin/admin/src/translations/dk.json.mjs +0 -6
  134. package/dist/admin/admin/src/translations/dk.json.mjs.map +1 -1
  135. package/dist/admin/admin/src/translations/en.json.js +0 -44
  136. package/dist/admin/admin/src/translations/en.json.js.map +1 -1
  137. package/dist/admin/admin/src/translations/en.json.mjs +0 -44
  138. package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
  139. package/dist/admin/admin/src/translations/es.json.js +0 -25
  140. package/dist/admin/admin/src/translations/es.json.js.map +1 -1
  141. package/dist/admin/admin/src/translations/es.json.mjs +0 -25
  142. package/dist/admin/admin/src/translations/es.json.mjs.map +1 -1
  143. package/dist/admin/admin/src/translations/eu.json.js +0 -43
  144. package/dist/admin/admin/src/translations/eu.json.js.map +1 -1
  145. package/dist/admin/admin/src/translations/eu.json.mjs +0 -43
  146. package/dist/admin/admin/src/translations/eu.json.mjs.map +1 -1
  147. package/dist/admin/admin/src/translations/fr.json.js +0 -6
  148. package/dist/admin/admin/src/translations/fr.json.js.map +1 -1
  149. package/dist/admin/admin/src/translations/fr.json.mjs +0 -6
  150. package/dist/admin/admin/src/translations/fr.json.mjs.map +1 -1
  151. package/dist/admin/admin/src/translations/gu.json.js +0 -21
  152. package/dist/admin/admin/src/translations/gu.json.js.map +1 -1
  153. package/dist/admin/admin/src/translations/gu.json.mjs +0 -21
  154. package/dist/admin/admin/src/translations/gu.json.mjs.map +1 -1
  155. package/dist/admin/admin/src/translations/hi.json.js +0 -21
  156. package/dist/admin/admin/src/translations/hi.json.js.map +1 -1
  157. package/dist/admin/admin/src/translations/hi.json.mjs +0 -21
  158. package/dist/admin/admin/src/translations/hi.json.mjs.map +1 -1
  159. package/dist/admin/admin/src/translations/hu.json.js +0 -43
  160. package/dist/admin/admin/src/translations/hu.json.js.map +1 -1
  161. package/dist/admin/admin/src/translations/hu.json.mjs +0 -43
  162. package/dist/admin/admin/src/translations/hu.json.mjs.map +1 -1
  163. package/dist/admin/admin/src/translations/it.json.js +613 -3
  164. package/dist/admin/admin/src/translations/it.json.js.map +1 -1
  165. package/dist/admin/admin/src/translations/it.json.mjs +605 -4
  166. package/dist/admin/admin/src/translations/it.json.mjs.map +1 -1
  167. package/dist/admin/admin/src/translations/ja.json.js +0 -6
  168. package/dist/admin/admin/src/translations/ja.json.js.map +1 -1
  169. package/dist/admin/admin/src/translations/ja.json.mjs +0 -6
  170. package/dist/admin/admin/src/translations/ja.json.mjs.map +1 -1
  171. package/dist/admin/admin/src/translations/ko.json.js +430 -102
  172. package/dist/admin/admin/src/translations/ko.json.js.map +1 -1
  173. package/dist/admin/admin/src/translations/ko.json.mjs +427 -103
  174. package/dist/admin/admin/src/translations/ko.json.mjs.map +1 -1
  175. package/dist/admin/admin/src/translations/ml.json.js +0 -21
  176. package/dist/admin/admin/src/translations/ml.json.js.map +1 -1
  177. package/dist/admin/admin/src/translations/ml.json.mjs +0 -21
  178. package/dist/admin/admin/src/translations/ml.json.mjs.map +1 -1
  179. package/dist/admin/admin/src/translations/nl.json.js +0 -39
  180. package/dist/admin/admin/src/translations/nl.json.js.map +1 -1
  181. package/dist/admin/admin/src/translations/nl.json.mjs +0 -39
  182. package/dist/admin/admin/src/translations/nl.json.mjs.map +1 -1
  183. package/dist/admin/admin/src/translations/pl.json.js +0 -21
  184. package/dist/admin/admin/src/translations/pl.json.js.map +1 -1
  185. package/dist/admin/admin/src/translations/pl.json.mjs +0 -21
  186. package/dist/admin/admin/src/translations/pl.json.mjs.map +1 -1
  187. package/dist/admin/admin/src/translations/pt-BR.json.js +0 -25
  188. package/dist/admin/admin/src/translations/pt-BR.json.js.map +1 -1
  189. package/dist/admin/admin/src/translations/pt-BR.json.mjs +0 -25
  190. package/dist/admin/admin/src/translations/pt-BR.json.mjs.map +1 -1
  191. package/dist/admin/admin/src/translations/ru.json.js +0 -44
  192. package/dist/admin/admin/src/translations/ru.json.js.map +1 -1
  193. package/dist/admin/admin/src/translations/ru.json.mjs +0 -44
  194. package/dist/admin/admin/src/translations/ru.json.mjs.map +1 -1
  195. package/dist/admin/admin/src/translations/sa.json.js +0 -21
  196. package/dist/admin/admin/src/translations/sa.json.js.map +1 -1
  197. package/dist/admin/admin/src/translations/sa.json.mjs +0 -21
  198. package/dist/admin/admin/src/translations/sa.json.mjs.map +1 -1
  199. package/dist/admin/admin/src/translations/sv.json.js +0 -39
  200. package/dist/admin/admin/src/translations/sv.json.js.map +1 -1
  201. package/dist/admin/admin/src/translations/sv.json.mjs +0 -39
  202. package/dist/admin/admin/src/translations/sv.json.mjs.map +1 -1
  203. package/dist/admin/admin/src/translations/tr.json.js +0 -39
  204. package/dist/admin/admin/src/translations/tr.json.js.map +1 -1
  205. package/dist/admin/admin/src/translations/tr.json.mjs +0 -39
  206. package/dist/admin/admin/src/translations/tr.json.mjs.map +1 -1
  207. package/dist/admin/admin/src/translations/uk.json.js +0 -44
  208. package/dist/admin/admin/src/translations/uk.json.js.map +1 -1
  209. package/dist/admin/admin/src/translations/uk.json.mjs +0 -44
  210. package/dist/admin/admin/src/translations/uk.json.mjs.map +1 -1
  211. package/dist/admin/admin/src/translations/vi.json.js +0 -44
  212. package/dist/admin/admin/src/translations/vi.json.js.map +1 -1
  213. package/dist/admin/admin/src/translations/vi.json.mjs +0 -44
  214. package/dist/admin/admin/src/translations/vi.json.mjs.map +1 -1
  215. package/dist/admin/admin/src/translations/zh-Hans.json.js +0 -44
  216. package/dist/admin/admin/src/translations/zh-Hans.json.js.map +1 -1
  217. package/dist/admin/admin/src/translations/zh-Hans.json.mjs +0 -44
  218. package/dist/admin/admin/src/translations/zh-Hans.json.mjs.map +1 -1
  219. package/dist/admin/admin/src/translations/zh.json.js +0 -39
  220. package/dist/admin/admin/src/translations/zh.json.js.map +1 -1
  221. package/dist/admin/admin/src/translations/zh.json.mjs +0 -39
  222. package/dist/admin/admin/src/translations/zh.json.mjs.map +1 -1
  223. package/dist/admin/admin/tests/mockData.js +0 -1413
  224. package/dist/admin/admin/tests/mockData.js.map +1 -1
  225. package/dist/admin/admin/tests/mockData.mjs +0 -1413
  226. package/dist/admin/admin/tests/mockData.mjs.map +1 -1
  227. package/dist/admin/admin/tests/server.js +0 -99
  228. package/dist/admin/admin/tests/server.js.map +1 -1
  229. package/dist/admin/admin/tests/server.mjs +0 -80
  230. package/dist/admin/admin/tests/server.mjs.map +1 -1
  231. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/SingleSignOnPage.js +1 -0
  232. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/SingleSignOnPage.js.map +1 -1
  233. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/SingleSignOnPage.mjs +1 -0
  234. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/SingleSignOnPage.mjs.map +1 -1
  235. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/Users/components/CreateActionEE.js +2 -0
  236. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/Users/components/CreateActionEE.js.map +1 -1
  237. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/Users/components/CreateActionEE.mjs +2 -0
  238. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/Users/components/CreateActionEE.mjs.map +1 -1
  239. package/dist/admin/index.js +3 -0
  240. package/dist/admin/index.js.map +1 -1
  241. package/dist/admin/index.mjs +1 -1
  242. package/dist/admin/src/components/MainNav/NavLink.d.ts +2 -2
  243. package/dist/admin/src/constants/theme.d.ts +2 -1
  244. package/dist/admin/src/core/apis/router.d.ts +1 -0
  245. package/dist/admin/src/features/Tracking.d.ts +1 -1
  246. package/dist/admin/src/hooks/useMenu.d.ts +1 -0
  247. package/dist/admin/src/index.d.ts +1 -1
  248. package/dist/admin/tests/mockData.d.ts +0 -972
  249. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.js +53 -0
  250. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.js.map +1 -0
  251. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.mjs +51 -0
  252. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.mjs.map +1 -0
  253. package/dist/server/server/src/services/permission/permissions-manager/sanitize.js +7 -8
  254. package/dist/server/server/src/services/permission/permissions-manager/sanitize.js.map +1 -1
  255. package/dist/server/server/src/services/permission/permissions-manager/sanitize.mjs +10 -11
  256. package/dist/server/server/src/services/permission/permissions-manager/sanitize.mjs.map +1 -1
  257. package/dist/server/server/src/services/permission/permissions-manager/validate.js +7 -8
  258. package/dist/server/server/src/services/permission/permissions-manager/validate.js.map +1 -1
  259. package/dist/server/server/src/services/permission/permissions-manager/validate.mjs +10 -11
  260. package/dist/server/server/src/services/permission/permissions-manager/validate.mjs.map +1 -1
  261. package/dist/server/src/services/permission/permissions-manager/permission-fields.d.ts +21 -0
  262. package/dist/server/src/services/permission/permissions-manager/permission-fields.d.ts.map +1 -0
  263. package/dist/server/src/services/permission/permissions-manager/sanitize.d.ts.map +1 -1
  264. package/dist/server/src/services/permission/permissions-manager/validate.d.ts.map +1 -1
  265. package/package.json +7 -7
  266. package/dist/admin/admin/src/pages/Marketplace/MarketplacePage.js +0 -339
  267. package/dist/admin/admin/src/pages/Marketplace/MarketplacePage.js.map +0 -1
  268. package/dist/admin/admin/src/pages/Marketplace/MarketplacePage.mjs +0 -317
  269. package/dist/admin/admin/src/pages/Marketplace/MarketplacePage.mjs.map +0 -1
  270. package/dist/admin/admin/src/pages/Marketplace/components/NpmPackageCard.js +0 -329
  271. package/dist/admin/admin/src/pages/Marketplace/components/NpmPackageCard.js.map +0 -1
  272. package/dist/admin/admin/src/pages/Marketplace/components/NpmPackageCard.mjs +0 -308
  273. package/dist/admin/admin/src/pages/Marketplace/components/NpmPackageCard.mjs.map +0 -1
  274. package/dist/admin/admin/src/pages/Marketplace/components/NpmPackagesFilters.js +0 -121
  275. package/dist/admin/admin/src/pages/Marketplace/components/NpmPackagesFilters.js.map +0 -1
  276. package/dist/admin/admin/src/pages/Marketplace/components/NpmPackagesFilters.mjs +0 -119
  277. package/dist/admin/admin/src/pages/Marketplace/components/NpmPackagesFilters.mjs.map +0 -1
  278. package/dist/admin/admin/src/pages/Marketplace/components/NpmPackagesGrid.js +0 -93
  279. package/dist/admin/admin/src/pages/Marketplace/components/NpmPackagesGrid.js.map +0 -1
  280. package/dist/admin/admin/src/pages/Marketplace/components/NpmPackagesGrid.mjs +0 -91
  281. package/dist/admin/admin/src/pages/Marketplace/components/NpmPackagesGrid.mjs.map +0 -1
  282. package/dist/admin/admin/src/pages/Marketplace/components/OfflineLayout.js +0 -81
  283. package/dist/admin/admin/src/pages/Marketplace/components/OfflineLayout.js.map +0 -1
  284. package/dist/admin/admin/src/pages/Marketplace/components/OfflineLayout.mjs +0 -79
  285. package/dist/admin/admin/src/pages/Marketplace/components/OfflineLayout.mjs.map +0 -1
  286. package/dist/admin/admin/src/pages/Marketplace/components/PageHeader.js +0 -38
  287. package/dist/admin/admin/src/pages/Marketplace/components/PageHeader.js.map +0 -1
  288. package/dist/admin/admin/src/pages/Marketplace/components/PageHeader.mjs +0 -36
  289. package/dist/admin/admin/src/pages/Marketplace/components/PageHeader.mjs.map +0 -1
  290. package/dist/admin/admin/src/pages/Marketplace/components/SortSelect.js +0 -85
  291. package/dist/admin/admin/src/pages/Marketplace/components/SortSelect.js.map +0 -1
  292. package/dist/admin/admin/src/pages/Marketplace/components/SortSelect.mjs +0 -83
  293. package/dist/admin/admin/src/pages/Marketplace/components/SortSelect.mjs.map +0 -1
  294. package/dist/admin/admin/src/pages/Marketplace/hooks/useMarketplaceData.js +0 -134
  295. package/dist/admin/admin/src/pages/Marketplace/hooks/useMarketplaceData.js.map +0 -1
  296. package/dist/admin/admin/src/pages/Marketplace/hooks/useMarketplaceData.mjs +0 -113
  297. package/dist/admin/admin/src/pages/Marketplace/hooks/useMarketplaceData.mjs.map +0 -1
  298. package/dist/admin/admin/src/pages/Marketplace/hooks/useNavigatorOnline.js +0 -44
  299. package/dist/admin/admin/src/pages/Marketplace/hooks/useNavigatorOnline.js.map +0 -1
  300. package/dist/admin/admin/src/pages/Marketplace/hooks/useNavigatorOnline.mjs +0 -23
  301. package/dist/admin/admin/src/pages/Marketplace/hooks/useNavigatorOnline.mjs.map +0 -1
  302. package/dist/admin/src/pages/Marketplace/MarketplacePage.d.ts +0 -19
  303. package/dist/admin/src/pages/Marketplace/components/NpmPackageCard.d.ts +0 -13
  304. package/dist/admin/src/pages/Marketplace/components/NpmPackagesFilters.d.ts +0 -13
  305. package/dist/admin/src/pages/Marketplace/components/NpmPackagesGrid.d.ts +0 -13
  306. package/dist/admin/src/pages/Marketplace/components/OfflineLayout.d.ts +0 -2
  307. package/dist/admin/src/pages/Marketplace/components/PageHeader.d.ts +0 -8
  308. package/dist/admin/src/pages/Marketplace/components/SortSelect.d.ts +0 -51
  309. package/dist/admin/src/pages/Marketplace/hooks/useMarketplaceData.d.ts +0 -93
  310. package/dist/admin/src/pages/Marketplace/hooks/useNavigatorOnline.d.ts +0 -5
@@ -0,0 +1,53 @@
1
+ 'use strict';
2
+
3
+ var ability = require('@casl/ability');
4
+ var extra = require('@casl/ability/extra');
5
+ var fp = require('lodash/fp');
6
+
7
+ /**
8
+ * Creates a cached permission fields calculator for a given CASL ability.
9
+ *
10
+ * The cache stores permission field calculations per action+subjectType combination.
11
+ * Results are only cached when rules have no entity-specific conditions, as those
12
+ * must be computed per entity.
13
+ *
14
+ * @param ability - The CASL ability instance to use for permission checks
15
+ * @returns Object with getPermissionFields function and cache
16
+ */ const createPermissionFieldsCache = (ability$1)=>{
17
+ const permissionCache = new Map();
18
+ const getPermissionFields = (actionOverride, subject)=>{
19
+ const subjectType = ability.detectSubjectType(subject);
20
+ const rules = ability$1.rulesFor(actionOverride, subjectType);
21
+ // Check if any rule has conditions that depend on entity data
22
+ // If so, we can't cache - must compute per entity
23
+ const hasEntityConditions = rules.some((rule)=>rule.conditions && !fp.isEmpty(rule.conditions));
24
+ // Return cached result if available and safe to use
25
+ const cacheKey = `${actionOverride}::${String(subjectType)}`;
26
+ if (!hasEntityConditions && permissionCache.has(cacheKey)) {
27
+ return permissionCache.get(cacheKey);
28
+ }
29
+ // Compute permission fields (expensive CASL operation)
30
+ const permittedFields = extra.permittedFieldsOf(ability$1, actionOverride, subject, {
31
+ fieldsFrom: (rule)=>rule.fields || []
32
+ });
33
+ const hasAtLeastOneRegistered = fp.some((fields)=>!fp.isNil(fields), fp.flatMap(fp.prop('fields'), rules));
34
+ const shouldIncludeAll = fp.isEmpty(permittedFields) && !hasAtLeastOneRegistered;
35
+ const result = {
36
+ permittedFields,
37
+ hasAtLeastOneRegistered,
38
+ shouldIncludeAll
39
+ };
40
+ // Cache for reuse if no entity-specific conditions
41
+ if (!hasEntityConditions) {
42
+ permissionCache.set(cacheKey, result);
43
+ }
44
+ return result;
45
+ };
46
+ return {
47
+ getPermissionFields,
48
+ clearCache: ()=>permissionCache.clear()
49
+ };
50
+ };
51
+
52
+ exports.createPermissionFieldsCache = createPermissionFieldsCache;
53
+ //# sourceMappingURL=permission-fields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permission-fields.js","sources":["../../../../../../../server/src/services/permission/permissions-manager/permission-fields.ts"],"sourcesContent":["import { detectSubjectType } from '@casl/ability';\nimport { permittedFieldsOf } from '@casl/ability/extra';\nimport { isEmpty, isNil, flatMap, some, prop } from 'lodash/fp';\n\nimport type { Ability } from '@casl/ability';\n\nexport interface PermissionFieldsResult {\n permittedFields: string[];\n hasAtLeastOneRegistered: boolean;\n shouldIncludeAll: boolean;\n}\n\n/**\n * Creates a cached permission fields calculator for a given CASL ability.\n *\n * The cache stores permission field calculations per action+subjectType combination.\n * Results are only cached when rules have no entity-specific conditions, as those\n * must be computed per entity.\n *\n * @param ability - The CASL ability instance to use for permission checks\n * @returns Object with getPermissionFields function and cache\n */\nexport const createPermissionFieldsCache = (ability: Ability) => {\n const permissionCache = new Map<string, PermissionFieldsResult>();\n\n const getPermissionFields = (actionOverride: string, subject: any): PermissionFieldsResult => {\n const subjectType = detectSubjectType(subject);\n const rules = ability.rulesFor(actionOverride, subjectType);\n\n // Check if any rule has conditions that depend on entity data\n // If so, we can't cache - must compute per entity\n const hasEntityConditions = rules.some(\n (rule: any) => rule.conditions && !isEmpty(rule.conditions)\n );\n\n // Return cached result if available and safe to use\n const cacheKey = `${actionOverride}::${String(subjectType)}`;\n if (!hasEntityConditions && permissionCache.has(cacheKey)) {\n return permissionCache.get(cacheKey)!;\n }\n\n // Compute permission fields (expensive CASL operation)\n const permittedFields = permittedFieldsOf(ability, actionOverride, subject, {\n fieldsFrom: (rule) => rule.fields || [],\n });\n\n const hasAtLeastOneRegistered = some(\n (fields) => !isNil(fields),\n flatMap(prop('fields'), rules)\n );\n const shouldIncludeAll = isEmpty(permittedFields) && !hasAtLeastOneRegistered;\n\n const result: PermissionFieldsResult = {\n permittedFields,\n hasAtLeastOneRegistered,\n shouldIncludeAll,\n };\n\n // Cache for reuse if no entity-specific conditions\n if (!hasEntityConditions) {\n permissionCache.set(cacheKey, result);\n }\n\n return result;\n };\n\n return {\n getPermissionFields,\n clearCache: () => permissionCache.clear(),\n };\n};\n"],"names":["createPermissionFieldsCache","ability","permissionCache","Map","getPermissionFields","actionOverride","subject","subjectType","detectSubjectType","rules","rulesFor","hasEntityConditions","some","rule","conditions","isEmpty","cacheKey","String","has","get","permittedFields","permittedFieldsOf","fieldsFrom","fields","hasAtLeastOneRegistered","isNil","flatMap","prop","shouldIncludeAll","result","set","clearCache","clear"],"mappings":";;;;;;AAYA;;;;;;;;;IAUaA,MAAAA,2BAAAA,GAA8B,CAACC,SAAAA,GAAAA;AAC1C,IAAA,MAAMC,kBAAkB,IAAIC,GAAAA,EAAAA;IAE5B,MAAMC,mBAAAA,GAAsB,CAACC,cAAwBC,EAAAA,OAAAA,GAAAA;AACnD,QAAA,MAAMC,cAAcC,yBAAkBF,CAAAA,OAAAA,CAAAA;AACtC,QAAA,MAAMG,KAAQR,GAAAA,SAAAA,CAAQS,QAAQ,CAACL,cAAgBE,EAAAA,WAAAA,CAAAA;;;AAI/C,QAAA,MAAMI,mBAAsBF,GAAAA,KAAAA,CAAMG,IAAI,CACpC,CAACC,IAAAA,GAAcA,IAAKC,CAAAA,UAAU,IAAI,CAACC,UAAQF,CAAAA,IAAAA,CAAKC,UAAU,CAAA,CAAA;;AAI5D,QAAA,MAAME,WAAW,CAAGX,EAAAA,cAAAA,CAAe,EAAE,EAAEY,OAAOV,WAAc,CAAA,CAAA,CAAA;AAC5D,QAAA,IAAI,CAACI,mBAAAA,IAAuBT,eAAgBgB,CAAAA,GAAG,CAACF,QAAW,CAAA,EAAA;YACzD,OAAOd,eAAAA,CAAgBiB,GAAG,CAACH,QAAAA,CAAAA;AAC7B;;AAGA,QAAA,MAAMI,eAAkBC,GAAAA,uBAAAA,CAAkBpB,SAASI,EAAAA,cAAAA,EAAgBC,OAAS,EAAA;AAC1EgB,YAAAA,UAAAA,EAAY,CAACT,IAAAA,GAASA,IAAKU,CAAAA,MAAM,IAAI;AACvC,SAAA,CAAA;QAEA,MAAMC,uBAAAA,GAA0BZ,QAC9B,CAACW,MAAAA,GAAW,CAACE,QAAMF,CAAAA,MAAAA,CAAAA,EACnBG,UAAQC,CAAAA,OAAAA,CAAK,QAAWlB,CAAAA,EAAAA,KAAAA,CAAAA,CAAAA;QAE1B,MAAMmB,gBAAAA,GAAmBb,UAAQK,CAAAA,eAAAA,CAAAA,IAAoB,CAACI,uBAAAA;AAEtD,QAAA,MAAMK,MAAiC,GAAA;AACrCT,YAAAA,eAAAA;AACAI,YAAAA,uBAAAA;AACAI,YAAAA;AACF,SAAA;;AAGA,QAAA,IAAI,CAACjB,mBAAqB,EAAA;YACxBT,eAAgB4B,CAAAA,GAAG,CAACd,QAAUa,EAAAA,MAAAA,CAAAA;AAChC;QAEA,OAAOA,MAAAA;AACT,KAAA;IAEA,OAAO;AACLzB,QAAAA,mBAAAA;QACA2B,UAAY,EAAA,IAAM7B,gBAAgB8B,KAAK;AACzC,KAAA;AACF;;;;"}
@@ -0,0 +1,51 @@
1
+ import { detectSubjectType } from '@casl/ability';
2
+ import { permittedFieldsOf } from '@casl/ability/extra';
3
+ import { isEmpty, some, isNil, flatMap, prop } from 'lodash/fp';
4
+
5
+ /**
6
+ * Creates a cached permission fields calculator for a given CASL ability.
7
+ *
8
+ * The cache stores permission field calculations per action+subjectType combination.
9
+ * Results are only cached when rules have no entity-specific conditions, as those
10
+ * must be computed per entity.
11
+ *
12
+ * @param ability - The CASL ability instance to use for permission checks
13
+ * @returns Object with getPermissionFields function and cache
14
+ */ const createPermissionFieldsCache = (ability)=>{
15
+ const permissionCache = new Map();
16
+ const getPermissionFields = (actionOverride, subject)=>{
17
+ const subjectType = detectSubjectType(subject);
18
+ const rules = ability.rulesFor(actionOverride, subjectType);
19
+ // Check if any rule has conditions that depend on entity data
20
+ // If so, we can't cache - must compute per entity
21
+ const hasEntityConditions = rules.some((rule)=>rule.conditions && !isEmpty(rule.conditions));
22
+ // Return cached result if available and safe to use
23
+ const cacheKey = `${actionOverride}::${String(subjectType)}`;
24
+ if (!hasEntityConditions && permissionCache.has(cacheKey)) {
25
+ return permissionCache.get(cacheKey);
26
+ }
27
+ // Compute permission fields (expensive CASL operation)
28
+ const permittedFields = permittedFieldsOf(ability, actionOverride, subject, {
29
+ fieldsFrom: (rule)=>rule.fields || []
30
+ });
31
+ const hasAtLeastOneRegistered = some((fields)=>!isNil(fields), flatMap(prop('fields'), rules));
32
+ const shouldIncludeAll = isEmpty(permittedFields) && !hasAtLeastOneRegistered;
33
+ const result = {
34
+ permittedFields,
35
+ hasAtLeastOneRegistered,
36
+ shouldIncludeAll
37
+ };
38
+ // Cache for reuse if no entity-specific conditions
39
+ if (!hasEntityConditions) {
40
+ permissionCache.set(cacheKey, result);
41
+ }
42
+ return result;
43
+ };
44
+ return {
45
+ getPermissionFields,
46
+ clearCache: ()=>permissionCache.clear()
47
+ };
48
+ };
49
+
50
+ export { createPermissionFieldsCache };
51
+ //# sourceMappingURL=permission-fields.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permission-fields.mjs","sources":["../../../../../../../server/src/services/permission/permissions-manager/permission-fields.ts"],"sourcesContent":["import { detectSubjectType } from '@casl/ability';\nimport { permittedFieldsOf } from '@casl/ability/extra';\nimport { isEmpty, isNil, flatMap, some, prop } from 'lodash/fp';\n\nimport type { Ability } from '@casl/ability';\n\nexport interface PermissionFieldsResult {\n permittedFields: string[];\n hasAtLeastOneRegistered: boolean;\n shouldIncludeAll: boolean;\n}\n\n/**\n * Creates a cached permission fields calculator for a given CASL ability.\n *\n * The cache stores permission field calculations per action+subjectType combination.\n * Results are only cached when rules have no entity-specific conditions, as those\n * must be computed per entity.\n *\n * @param ability - The CASL ability instance to use for permission checks\n * @returns Object with getPermissionFields function and cache\n */\nexport const createPermissionFieldsCache = (ability: Ability) => {\n const permissionCache = new Map<string, PermissionFieldsResult>();\n\n const getPermissionFields = (actionOverride: string, subject: any): PermissionFieldsResult => {\n const subjectType = detectSubjectType(subject);\n const rules = ability.rulesFor(actionOverride, subjectType);\n\n // Check if any rule has conditions that depend on entity data\n // If so, we can't cache - must compute per entity\n const hasEntityConditions = rules.some(\n (rule: any) => rule.conditions && !isEmpty(rule.conditions)\n );\n\n // Return cached result if available and safe to use\n const cacheKey = `${actionOverride}::${String(subjectType)}`;\n if (!hasEntityConditions && permissionCache.has(cacheKey)) {\n return permissionCache.get(cacheKey)!;\n }\n\n // Compute permission fields (expensive CASL operation)\n const permittedFields = permittedFieldsOf(ability, actionOverride, subject, {\n fieldsFrom: (rule) => rule.fields || [],\n });\n\n const hasAtLeastOneRegistered = some(\n (fields) => !isNil(fields),\n flatMap(prop('fields'), rules)\n );\n const shouldIncludeAll = isEmpty(permittedFields) && !hasAtLeastOneRegistered;\n\n const result: PermissionFieldsResult = {\n permittedFields,\n hasAtLeastOneRegistered,\n shouldIncludeAll,\n };\n\n // Cache for reuse if no entity-specific conditions\n if (!hasEntityConditions) {\n permissionCache.set(cacheKey, result);\n }\n\n return result;\n };\n\n return {\n getPermissionFields,\n clearCache: () => permissionCache.clear(),\n };\n};\n"],"names":["createPermissionFieldsCache","ability","permissionCache","Map","getPermissionFields","actionOverride","subject","subjectType","detectSubjectType","rules","rulesFor","hasEntityConditions","some","rule","conditions","isEmpty","cacheKey","String","has","get","permittedFields","permittedFieldsOf","fieldsFrom","fields","hasAtLeastOneRegistered","isNil","flatMap","prop","shouldIncludeAll","result","set","clearCache","clear"],"mappings":";;;;AAYA;;;;;;;;;IAUaA,MAAAA,2BAAAA,GAA8B,CAACC,OAAAA,GAAAA;AAC1C,IAAA,MAAMC,kBAAkB,IAAIC,GAAAA,EAAAA;IAE5B,MAAMC,mBAAAA,GAAsB,CAACC,cAAwBC,EAAAA,OAAAA,GAAAA;AACnD,QAAA,MAAMC,cAAcC,iBAAkBF,CAAAA,OAAAA,CAAAA;AACtC,QAAA,MAAMG,KAAQR,GAAAA,OAAAA,CAAQS,QAAQ,CAACL,cAAgBE,EAAAA,WAAAA,CAAAA;;;AAI/C,QAAA,MAAMI,mBAAsBF,GAAAA,KAAAA,CAAMG,IAAI,CACpC,CAACC,IAAAA,GAAcA,IAAKC,CAAAA,UAAU,IAAI,CAACC,OAAQF,CAAAA,IAAAA,CAAKC,UAAU,CAAA,CAAA;;AAI5D,QAAA,MAAME,WAAW,CAAGX,EAAAA,cAAAA,CAAe,EAAE,EAAEY,OAAOV,WAAc,CAAA,CAAA,CAAA;AAC5D,QAAA,IAAI,CAACI,mBAAAA,IAAuBT,eAAgBgB,CAAAA,GAAG,CAACF,QAAW,CAAA,EAAA;YACzD,OAAOd,eAAAA,CAAgBiB,GAAG,CAACH,QAAAA,CAAAA;AAC7B;;AAGA,QAAA,MAAMI,eAAkBC,GAAAA,iBAAAA,CAAkBpB,OAASI,EAAAA,cAAAA,EAAgBC,OAAS,EAAA;AAC1EgB,YAAAA,UAAAA,EAAY,CAACT,IAAAA,GAASA,IAAKU,CAAAA,MAAM,IAAI;AACvC,SAAA,CAAA;QAEA,MAAMC,uBAAAA,GAA0BZ,KAC9B,CAACW,MAAAA,GAAW,CAACE,KAAMF,CAAAA,MAAAA,CAAAA,EACnBG,OAAQC,CAAAA,IAAAA,CAAK,QAAWlB,CAAAA,EAAAA,KAAAA,CAAAA,CAAAA;QAE1B,MAAMmB,gBAAAA,GAAmBb,OAAQK,CAAAA,eAAAA,CAAAA,IAAoB,CAACI,uBAAAA;AAEtD,QAAA,MAAMK,MAAiC,GAAA;AACrCT,YAAAA,eAAAA;AACAI,YAAAA,uBAAAA;AACAI,YAAAA;AACF,SAAA;;AAGA,QAAA,IAAI,CAACjB,mBAAqB,EAAA;YACxBT,eAAgB4B,CAAAA,GAAG,CAACd,QAAUa,EAAAA,MAAAA,CAAAA;AAChC;QAEA,OAAOA,MAAAA;AACT,KAAA;IAEA,OAAO;AACLzB,QAAAA,mBAAAA;QACA2B,UAAY,EAAA,IAAM7B,gBAAgB8B,KAAK;AACzC,KAAA;AACF;;;;"}
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
3
  var ability = require('@casl/ability');
4
- var extra = require('@casl/ability/extra');
5
4
  var fp = require('lodash/fp');
6
5
  var utils = require('@strapi/utils');
6
+ var permissionFields = require('./permission-fields.js');
7
7
  var user = require('../../../domain/user.js');
8
8
 
9
9
  const { visitors: { removePassword, expandWildcardPopulate } } = utils.sanitize;
@@ -19,9 +19,11 @@ const STATIC_FIELDS = [
19
19
  var createSanitizeHelpers = (({ action, ability: ability$1, model })=>{
20
20
  const schema = strapi.getModel(model);
21
21
  const { removeDisallowedFields } = utils.sanitize.visitors;
22
+ // Create request-scoped model cache to avoid redundant getModel() calls
23
+ const modelCache = utils.createModelCache(strapi.getModel.bind(strapi));
22
24
  const ctx = {
23
25
  schema,
24
- getModel: strapi.getModel.bind(strapi)
26
+ getModel: modelCache.getModel
25
27
  };
26
28
  const createSanitizeQuery = (options = {})=>{
27
29
  const { fields } = options;
@@ -87,6 +89,7 @@ var createSanitizeHelpers = (({ action, ability: ability$1, model })=>{
87
89
  omitCreatorRoles);
88
90
  };
89
91
  const wrapSanitize = (createSanitizeFunction)=>{
92
+ const { getPermissionFields } = permissionFields.createPermissionFieldsCache(ability$1);
90
93
  // TODO
91
94
  // @ts-expect-error define the correct return type
92
95
  const wrappedSanitize = async (data, options = {})=>{
@@ -94,15 +97,11 @@ var createSanitizeHelpers = (({ action, ability: ability$1, model })=>{
94
97
  return Promise.all(data.map((entity)=>wrappedSanitize(entity, options)));
95
98
  }
96
99
  const { subject, action: actionOverride } = getDefaultOptions(data, options);
97
- const permittedFields = extra.permittedFieldsOf(ability$1, actionOverride, subject, {
98
- fieldsFrom: (rule)=>rule.fields || []
99
- });
100
- const hasAtLeastOneRegistered = fp.some((fields)=>!fp.isNil(fields), fp.flatMap(fp.prop('fields'), ability$1.rulesFor(actionOverride, ability.detectSubjectType(subject))));
101
- const shouldIncludeAllFields = fp.isEmpty(permittedFields) && !hasAtLeastOneRegistered;
100
+ const { permittedFields, hasAtLeastOneRegistered, shouldIncludeAll } = getPermissionFields(actionOverride, subject);
102
101
  const sanitizeOptions = {
103
102
  ...options,
104
103
  fields: {
105
- shouldIncludeAll: shouldIncludeAllFields,
104
+ shouldIncludeAll,
106
105
  permitted: permittedFields,
107
106
  hasAtLeastOneRegistered
108
107
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sanitize.js","sources":["../../../../../../../server/src/services/permission/permissions-manager/sanitize.ts"],"sourcesContent":["import { subject as asSubject, detectSubjectType } from '@casl/ability';\nimport { permittedFieldsOf } from '@casl/ability/extra';\nimport {\n defaults,\n omit,\n isArray,\n isEmpty,\n isNil,\n flatMap,\n some,\n prop,\n uniq,\n intersection,\n pick,\n getOr,\n isObject,\n cloneDeep,\n} from 'lodash/fp';\n\nimport type { UID } from '@strapi/types';\n\nimport { contentTypes, traverseEntity, sanitize, async, traverse } from '@strapi/utils';\nimport { ADMIN_USER_ALLOWED_FIELDS } from '../../../domain/user';\n\nconst {\n visitors: { removePassword, expandWildcardPopulate },\n} = sanitize;\n\nconst {\n constants,\n isScalarAttribute,\n getNonVisibleAttributes,\n getNonWritableAttributes,\n getWritableAttributes,\n} = contentTypes;\nconst {\n ID_ATTRIBUTE,\n DOC_ID_ATTRIBUTE,\n CREATED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n PUBLISHED_AT_ATTRIBUTE,\n CREATED_BY_ATTRIBUTE,\n UPDATED_BY_ATTRIBUTE,\n} = constants;\n\nconst COMPONENT_FIELDS = ['__component'];\nconst STATIC_FIELDS = [ID_ATTRIBUTE, DOC_ID_ATTRIBUTE];\n\nexport default ({ action, ability, model }: any) => {\n const schema = strapi.getModel(model);\n\n const { removeDisallowedFields } = sanitize.visitors;\n\n const ctx = {\n schema,\n getModel: strapi.getModel.bind(strapi),\n };\n\n const createSanitizeQuery = (options = {} as any) => {\n const { fields } = options;\n\n // TODO: sanitize relations to admin users in all sanitizers\n const permittedFields = fields.shouldIncludeAll ? null : getQueryFields(fields.permitted);\n\n const sanitizeFilters = async.pipe(\n traverse.traverseQueryFilters(removeDisallowedFields(permittedFields), ctx),\n traverse.traverseQueryFilters(omitDisallowedAdminUserFields, ctx),\n traverse.traverseQueryFilters(omitHiddenFields, ctx),\n traverse.traverseQueryFilters(removePassword, ctx),\n traverse.traverseQueryFilters(({ key, value }, { remove }) => {\n if (isObject(value) && isEmpty(value)) {\n remove(key);\n }\n }, ctx)\n );\n\n const sanitizeSort = async.pipe(\n traverse.traverseQuerySort(removeDisallowedFields(permittedFields), ctx),\n traverse.traverseQuerySort(omitDisallowedAdminUserFields, ctx),\n traverse.traverseQuerySort(omitHiddenFields, ctx),\n traverse.traverseQuerySort(removePassword, ctx),\n traverse.traverseQuerySort(({ key, attribute, value }, { remove }) => {\n if (!isScalarAttribute(attribute) && isEmpty(value)) {\n remove(key);\n }\n }, ctx)\n );\n\n const sanitizePopulate = async.pipe(\n traverse.traverseQueryPopulate(expandWildcardPopulate, ctx),\n traverse.traverseQueryPopulate(removeDisallowedFields(permittedFields), ctx),\n traverse.traverseQueryPopulate(omitDisallowedAdminUserFields, ctx),\n traverse.traverseQueryPopulate(omitHiddenFields, ctx),\n traverse.traverseQueryPopulate(removePassword, ctx)\n );\n\n const sanitizeFields = async.pipe(\n traverse.traverseQueryFields(removeDisallowedFields(permittedFields), ctx),\n traverse.traverseQueryFields(omitHiddenFields, ctx),\n traverse.traverseQueryFields(removePassword, ctx)\n );\n\n return async (query: any) => {\n const sanitizedQuery = cloneDeep(query);\n\n if (query.filters) {\n Object.assign(sanitizedQuery, { filters: await sanitizeFilters(query.filters) });\n }\n\n if (query.sort) {\n Object.assign(sanitizedQuery, { sort: await sanitizeSort(query.sort) });\n }\n\n if (query.populate) {\n Object.assign(sanitizedQuery, { populate: await sanitizePopulate(query.populate) });\n }\n\n if (query.fields) {\n Object.assign(sanitizedQuery, { fields: await sanitizeFields(query.fields) });\n }\n\n return sanitizedQuery;\n };\n };\n\n const createSanitizeOutput = (options = {} as any) => {\n const { fields } = options;\n\n const permittedFields = fields.shouldIncludeAll ? null : getOutputFields(fields.permitted);\n\n return async.pipe(\n // Remove fields hidden from the admin\n traverseEntity(omitHiddenFields, ctx),\n // Remove unallowed fields from admin::user relations\n traverseEntity(pickAllowedAdminUserFields, ctx),\n // Remove not allowed fields (RBAC)\n traverseEntity(removeDisallowedFields(permittedFields), ctx),\n // Remove all fields of type 'password'\n sanitize.sanitizers.sanitizePasswords({\n schema,\n getModel(uid: string) {\n return strapi.getModel(uid as UID.Schema);\n },\n })\n );\n };\n\n const createSanitizeInput = (options = {} as any) => {\n const { fields } = options;\n\n const permittedFields = fields.shouldIncludeAll ? null : getInputFields(fields.permitted);\n\n return async.pipe(\n // Remove fields hidden from the admin\n traverseEntity(omitHiddenFields, ctx),\n // Remove not allowed fields (RBAC)\n traverseEntity(removeDisallowedFields(permittedFields), ctx),\n // Remove roles from createdBy & updatedBy fields\n omitCreatorRoles\n );\n };\n\n const wrapSanitize = (createSanitizeFunction: any) => {\n // TODO\n // @ts-expect-error define the correct return type\n const wrappedSanitize = async (data: unknown, options = {} as any) => {\n if (isArray(data)) {\n return Promise.all(data.map((entity: unknown) => wrappedSanitize(entity, options)));\n }\n\n const { subject, action: actionOverride } = getDefaultOptions(data, options);\n\n const permittedFields = permittedFieldsOf(ability, actionOverride, subject, {\n fieldsFrom: (rule) => rule.fields || [],\n });\n\n const hasAtLeastOneRegistered = some(\n (fields) => !isNil(fields),\n flatMap(prop('fields'), ability.rulesFor(actionOverride, detectSubjectType(subject)))\n );\n const shouldIncludeAllFields = isEmpty(permittedFields) && !hasAtLeastOneRegistered;\n\n const sanitizeOptions = {\n ...options,\n fields: {\n shouldIncludeAll: shouldIncludeAllFields,\n permitted: permittedFields,\n hasAtLeastOneRegistered,\n },\n };\n\n const sanitizeFunction = createSanitizeFunction(sanitizeOptions);\n\n return sanitizeFunction(data);\n };\n\n return wrappedSanitize;\n };\n\n const getDefaultOptions = (data: any, options: unknown) => {\n return defaults({ subject: asSubject(model, data), action }, options);\n };\n\n /**\n * Omit creator fields' (createdBy & updatedBy) roles from the admin API responses\n */\n const omitCreatorRoles = omit([`${CREATED_BY_ATTRIBUTE}.roles`, `${UPDATED_BY_ATTRIBUTE}.roles`]);\n\n /**\n * Visitor used to remove hidden fields from the admin API responses\n */\n const omitHiddenFields = ({ key, schema }: any, { remove }: any) => {\n const isHidden = getOr(false, ['config', 'attributes', key, 'hidden'], schema);\n\n if (isHidden) {\n remove(key);\n }\n };\n\n /**\n * Visitor used to only select needed fields from the admin users entities & avoid leaking sensitive information\n */\n const pickAllowedAdminUserFields = ({ attribute, key, value }: any, { set }: any) => {\n const pickAllowedFields = pick(ADMIN_USER_ALLOWED_FIELDS);\n if (!attribute) {\n return;\n }\n\n if (attribute.type === 'relation' && attribute.target === 'admin::user' && value) {\n if (Array.isArray(value)) {\n set(key, value.map(pickAllowedFields));\n } else {\n set(key, pickAllowedFields(value));\n }\n }\n };\n\n /**\n * Visitor used to omit disallowed fields from the admin users entities & avoid leaking sensitive information\n */\n const omitDisallowedAdminUserFields = ({ key, attribute, schema }: any, { remove }: any) => {\n if (schema.uid === 'admin::user' && attribute && !ADMIN_USER_ALLOWED_FIELDS.includes(key)) {\n remove(key);\n }\n };\n\n const getInputFields = (fields = []) => {\n const nonVisibleAttributes = getNonVisibleAttributes(schema);\n const writableAttributes = getWritableAttributes(schema);\n\n const nonVisibleWritableAttributes = intersection(nonVisibleAttributes, writableAttributes);\n\n return uniq([...fields, ...COMPONENT_FIELDS, ...nonVisibleWritableAttributes]);\n };\n\n const getOutputFields = (fields = []) => {\n const nonWritableAttributes = getNonWritableAttributes(schema);\n const nonVisibleAttributes = getNonVisibleAttributes(schema);\n\n return uniq([\n ...fields,\n ...STATIC_FIELDS,\n ...COMPONENT_FIELDS,\n ...nonWritableAttributes,\n ...nonVisibleAttributes,\n CREATED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n ]);\n };\n\n const getQueryFields = (fields = []) => {\n const nonVisibleAttributes = getNonVisibleAttributes(schema);\n const writableAttributes = getWritableAttributes(schema);\n\n const nonVisibleWritableAttributes = intersection(nonVisibleAttributes, writableAttributes);\n\n return uniq([\n ...fields,\n ...STATIC_FIELDS,\n ...COMPONENT_FIELDS,\n ...nonVisibleWritableAttributes,\n CREATED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n PUBLISHED_AT_ATTRIBUTE,\n CREATED_BY_ATTRIBUTE,\n UPDATED_BY_ATTRIBUTE,\n ]);\n };\n\n return {\n sanitizeOutput: wrapSanitize(createSanitizeOutput),\n sanitizeInput: wrapSanitize(createSanitizeInput),\n sanitizeQuery: wrapSanitize(createSanitizeQuery),\n };\n};\n"],"names":["visitors","removePassword","expandWildcardPopulate","sanitize","constants","isScalarAttribute","getNonVisibleAttributes","getNonWritableAttributes","getWritableAttributes","contentTypes","ID_ATTRIBUTE","DOC_ID_ATTRIBUTE","CREATED_AT_ATTRIBUTE","UPDATED_AT_ATTRIBUTE","PUBLISHED_AT_ATTRIBUTE","CREATED_BY_ATTRIBUTE","UPDATED_BY_ATTRIBUTE","COMPONENT_FIELDS","STATIC_FIELDS","action","ability","model","schema","strapi","getModel","removeDisallowedFields","ctx","bind","createSanitizeQuery","options","fields","permittedFields","shouldIncludeAll","getQueryFields","permitted","sanitizeFilters","async","pipe","traverse","traverseQueryFilters","omitDisallowedAdminUserFields","omitHiddenFields","key","value","remove","isObject","isEmpty","sanitizeSort","traverseQuerySort","attribute","sanitizePopulate","traverseQueryPopulate","sanitizeFields","traverseQueryFields","query","sanitizedQuery","cloneDeep","filters","Object","assign","sort","populate","createSanitizeOutput","getOutputFields","traverseEntity","pickAllowedAdminUserFields","sanitizers","sanitizePasswords","uid","createSanitizeInput","getInputFields","omitCreatorRoles","wrapSanitize","createSanitizeFunction","wrappedSanitize","data","isArray","Promise","all","map","entity","subject","actionOverride","getDefaultOptions","permittedFieldsOf","fieldsFrom","rule","hasAtLeastOneRegistered","some","isNil","flatMap","prop","rulesFor","detectSubjectType","shouldIncludeAllFields","sanitizeOptions","sanitizeFunction","defaults","asSubject","omit","isHidden","getOr","set","pickAllowedFields","pick","ADMIN_USER_ALLOWED_FIELDS","type","target","Array","includes","nonVisibleAttributes","writableAttributes","nonVisibleWritableAttributes","intersection","uniq","nonWritableAttributes","sanitizeOutput","sanitizeInput","sanitizeQuery"],"mappings":"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"}
1
+ {"version":3,"file":"sanitize.js","sources":["../../../../../../../server/src/services/permission/permissions-manager/sanitize.ts"],"sourcesContent":["import { subject as asSubject } from '@casl/ability';\nimport {\n defaults,\n omit,\n isArray,\n isEmpty,\n uniq,\n intersection,\n pick,\n getOr,\n isObject,\n cloneDeep,\n} from 'lodash/fp';\n\nimport type { UID } from '@strapi/types';\n\nimport {\n contentTypes,\n traverseEntity,\n sanitize,\n async,\n traverse,\n createModelCache,\n} from '@strapi/utils';\nimport { createPermissionFieldsCache } from './permission-fields';\nimport { ADMIN_USER_ALLOWED_FIELDS } from '../../../domain/user';\n\nconst {\n visitors: { removePassword, expandWildcardPopulate },\n} = sanitize;\n\nconst {\n constants,\n isScalarAttribute,\n getNonVisibleAttributes,\n getNonWritableAttributes,\n getWritableAttributes,\n} = contentTypes;\nconst {\n ID_ATTRIBUTE,\n DOC_ID_ATTRIBUTE,\n CREATED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n PUBLISHED_AT_ATTRIBUTE,\n CREATED_BY_ATTRIBUTE,\n UPDATED_BY_ATTRIBUTE,\n} = constants;\n\nconst COMPONENT_FIELDS = ['__component'];\nconst STATIC_FIELDS = [ID_ATTRIBUTE, DOC_ID_ATTRIBUTE];\n\nexport default ({ action, ability, model }: any) => {\n const schema = strapi.getModel(model);\n\n const { removeDisallowedFields } = sanitize.visitors;\n\n // Create request-scoped model cache to avoid redundant getModel() calls\n const modelCache = createModelCache(strapi.getModel.bind(strapi));\n\n const ctx = {\n schema,\n getModel: modelCache.getModel,\n };\n\n const createSanitizeQuery = (options = {} as any) => {\n const { fields } = options;\n\n // TODO: sanitize relations to admin users in all sanitizers\n const permittedFields = fields.shouldIncludeAll ? null : getQueryFields(fields.permitted);\n\n const sanitizeFilters = async.pipe(\n traverse.traverseQueryFilters(removeDisallowedFields(permittedFields), ctx),\n traverse.traverseQueryFilters(omitDisallowedAdminUserFields, ctx),\n traverse.traverseQueryFilters(omitHiddenFields, ctx),\n traverse.traverseQueryFilters(removePassword, ctx),\n traverse.traverseQueryFilters(({ key, value }, { remove }) => {\n if (isObject(value) && isEmpty(value)) {\n remove(key);\n }\n }, ctx)\n );\n\n const sanitizeSort = async.pipe(\n traverse.traverseQuerySort(removeDisallowedFields(permittedFields), ctx),\n traverse.traverseQuerySort(omitDisallowedAdminUserFields, ctx),\n traverse.traverseQuerySort(omitHiddenFields, ctx),\n traverse.traverseQuerySort(removePassword, ctx),\n traverse.traverseQuerySort(({ key, attribute, value }, { remove }) => {\n if (!isScalarAttribute(attribute) && isEmpty(value)) {\n remove(key);\n }\n }, ctx)\n );\n\n const sanitizePopulate = async.pipe(\n traverse.traverseQueryPopulate(expandWildcardPopulate, ctx),\n traverse.traverseQueryPopulate(removeDisallowedFields(permittedFields), ctx),\n traverse.traverseQueryPopulate(omitDisallowedAdminUserFields, ctx),\n traverse.traverseQueryPopulate(omitHiddenFields, ctx),\n traverse.traverseQueryPopulate(removePassword, ctx)\n );\n\n const sanitizeFields = async.pipe(\n traverse.traverseQueryFields(removeDisallowedFields(permittedFields), ctx),\n traverse.traverseQueryFields(omitHiddenFields, ctx),\n traverse.traverseQueryFields(removePassword, ctx)\n );\n\n return async (query: any) => {\n const sanitizedQuery = cloneDeep(query);\n\n if (query.filters) {\n Object.assign(sanitizedQuery, { filters: await sanitizeFilters(query.filters) });\n }\n\n if (query.sort) {\n Object.assign(sanitizedQuery, { sort: await sanitizeSort(query.sort) });\n }\n\n if (query.populate) {\n Object.assign(sanitizedQuery, { populate: await sanitizePopulate(query.populate) });\n }\n\n if (query.fields) {\n Object.assign(sanitizedQuery, { fields: await sanitizeFields(query.fields) });\n }\n\n return sanitizedQuery;\n };\n };\n\n const createSanitizeOutput = (options = {} as any) => {\n const { fields } = options;\n\n const permittedFields = fields.shouldIncludeAll ? null : getOutputFields(fields.permitted);\n\n return async.pipe(\n // Remove fields hidden from the admin\n traverseEntity(omitHiddenFields, ctx),\n // Remove unallowed fields from admin::user relations\n traverseEntity(pickAllowedAdminUserFields, ctx),\n // Remove not allowed fields (RBAC)\n traverseEntity(removeDisallowedFields(permittedFields), ctx),\n // Remove all fields of type 'password'\n sanitize.sanitizers.sanitizePasswords({\n schema,\n getModel(uid: string) {\n return strapi.getModel(uid as UID.Schema);\n },\n })\n );\n };\n\n const createSanitizeInput = (options = {} as any) => {\n const { fields } = options;\n\n const permittedFields = fields.shouldIncludeAll ? null : getInputFields(fields.permitted);\n\n return async.pipe(\n // Remove fields hidden from the admin\n traverseEntity(omitHiddenFields, ctx),\n // Remove not allowed fields (RBAC)\n traverseEntity(removeDisallowedFields(permittedFields), ctx),\n // Remove roles from createdBy & updatedBy fields\n omitCreatorRoles\n );\n };\n\n const wrapSanitize = (createSanitizeFunction: any) => {\n const { getPermissionFields } = createPermissionFieldsCache(ability);\n\n // TODO\n // @ts-expect-error define the correct return type\n const wrappedSanitize = async (data: unknown, options = {} as any) => {\n if (isArray(data)) {\n return Promise.all(data.map((entity: unknown) => wrappedSanitize(entity, options)));\n }\n\n const { subject, action: actionOverride } = getDefaultOptions(data, options);\n\n const { permittedFields, hasAtLeastOneRegistered, shouldIncludeAll } = getPermissionFields(\n actionOverride,\n subject\n );\n\n const sanitizeOptions = {\n ...options,\n fields: {\n shouldIncludeAll,\n permitted: permittedFields,\n hasAtLeastOneRegistered,\n },\n };\n\n const sanitizeFunction = createSanitizeFunction(sanitizeOptions);\n\n return sanitizeFunction(data);\n };\n\n return wrappedSanitize;\n };\n\n const getDefaultOptions = (data: any, options: unknown) => {\n return defaults({ subject: asSubject(model, data), action }, options);\n };\n\n /**\n * Omit creator fields' (createdBy & updatedBy) roles from the admin API responses\n */\n const omitCreatorRoles = omit([`${CREATED_BY_ATTRIBUTE}.roles`, `${UPDATED_BY_ATTRIBUTE}.roles`]);\n\n /**\n * Visitor used to remove hidden fields from the admin API responses\n */\n const omitHiddenFields = ({ key, schema }: any, { remove }: any) => {\n const isHidden = getOr(false, ['config', 'attributes', key, 'hidden'], schema);\n\n if (isHidden) {\n remove(key);\n }\n };\n\n /**\n * Visitor used to only select needed fields from the admin users entities & avoid leaking sensitive information\n */\n const pickAllowedAdminUserFields = ({ attribute, key, value }: any, { set }: any) => {\n const pickAllowedFields = pick(ADMIN_USER_ALLOWED_FIELDS);\n if (!attribute) {\n return;\n }\n\n if (attribute.type === 'relation' && attribute.target === 'admin::user' && value) {\n if (Array.isArray(value)) {\n set(key, value.map(pickAllowedFields));\n } else {\n set(key, pickAllowedFields(value));\n }\n }\n };\n\n /**\n * Visitor used to omit disallowed fields from the admin users entities & avoid leaking sensitive information\n */\n const omitDisallowedAdminUserFields = ({ key, attribute, schema }: any, { remove }: any) => {\n if (schema.uid === 'admin::user' && attribute && !ADMIN_USER_ALLOWED_FIELDS.includes(key)) {\n remove(key);\n }\n };\n\n const getInputFields = (fields = []) => {\n const nonVisibleAttributes = getNonVisibleAttributes(schema);\n const writableAttributes = getWritableAttributes(schema);\n\n const nonVisibleWritableAttributes = intersection(nonVisibleAttributes, writableAttributes);\n\n return uniq([...fields, ...COMPONENT_FIELDS, ...nonVisibleWritableAttributes]);\n };\n\n const getOutputFields = (fields = []) => {\n const nonWritableAttributes = getNonWritableAttributes(schema);\n const nonVisibleAttributes = getNonVisibleAttributes(schema);\n\n return uniq([\n ...fields,\n ...STATIC_FIELDS,\n ...COMPONENT_FIELDS,\n ...nonWritableAttributes,\n ...nonVisibleAttributes,\n CREATED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n ]);\n };\n\n const getQueryFields = (fields = []) => {\n const nonVisibleAttributes = getNonVisibleAttributes(schema);\n const writableAttributes = getWritableAttributes(schema);\n\n const nonVisibleWritableAttributes = intersection(nonVisibleAttributes, writableAttributes);\n\n return uniq([\n ...fields,\n ...STATIC_FIELDS,\n ...COMPONENT_FIELDS,\n ...nonVisibleWritableAttributes,\n CREATED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n PUBLISHED_AT_ATTRIBUTE,\n CREATED_BY_ATTRIBUTE,\n UPDATED_BY_ATTRIBUTE,\n ]);\n };\n\n return {\n sanitizeOutput: wrapSanitize(createSanitizeOutput),\n sanitizeInput: wrapSanitize(createSanitizeInput),\n sanitizeQuery: wrapSanitize(createSanitizeQuery),\n };\n};\n"],"names":["visitors","removePassword","expandWildcardPopulate","sanitize","constants","isScalarAttribute","getNonVisibleAttributes","getNonWritableAttributes","getWritableAttributes","contentTypes","ID_ATTRIBUTE","DOC_ID_ATTRIBUTE","CREATED_AT_ATTRIBUTE","UPDATED_AT_ATTRIBUTE","PUBLISHED_AT_ATTRIBUTE","CREATED_BY_ATTRIBUTE","UPDATED_BY_ATTRIBUTE","COMPONENT_FIELDS","STATIC_FIELDS","action","ability","model","schema","strapi","getModel","removeDisallowedFields","modelCache","createModelCache","bind","ctx","createSanitizeQuery","options","fields","permittedFields","shouldIncludeAll","getQueryFields","permitted","sanitizeFilters","async","pipe","traverse","traverseQueryFilters","omitDisallowedAdminUserFields","omitHiddenFields","key","value","remove","isObject","isEmpty","sanitizeSort","traverseQuerySort","attribute","sanitizePopulate","traverseQueryPopulate","sanitizeFields","traverseQueryFields","query","sanitizedQuery","cloneDeep","filters","Object","assign","sort","populate","createSanitizeOutput","getOutputFields","traverseEntity","pickAllowedAdminUserFields","sanitizers","sanitizePasswords","uid","createSanitizeInput","getInputFields","omitCreatorRoles","wrapSanitize","createSanitizeFunction","getPermissionFields","createPermissionFieldsCache","wrappedSanitize","data","isArray","Promise","all","map","entity","subject","actionOverride","getDefaultOptions","hasAtLeastOneRegistered","sanitizeOptions","sanitizeFunction","defaults","asSubject","omit","isHidden","getOr","set","pickAllowedFields","pick","ADMIN_USER_ALLOWED_FIELDS","type","target","Array","includes","nonVisibleAttributes","writableAttributes","nonVisibleWritableAttributes","intersection","uniq","nonWritableAttributes","sanitizeOutput","sanitizeInput","sanitizeQuery"],"mappings":";;;;;;;;AA2BA,MAAM,EACJA,UAAU,EAAEC,cAAc,EAAEC,sBAAsB,EAAE,EACrD,GAAGC,cAAAA;AAEJ,MAAM,EACJC,SAAS,EACTC,iBAAiB,EACjBC,uBAAuB,EACvBC,wBAAwB,EACxBC,qBAAqB,EACtB,GAAGC,kBAAAA;AACJ,MAAM,EACJC,YAAY,EACZC,gBAAgB,EAChBC,oBAAoB,EACpBC,oBAAoB,EACpBC,sBAAsB,EACtBC,oBAAoB,EACpBC,oBAAoB,EACrB,GAAGZ,SAAAA;AAEJ,MAAMa,gBAAmB,GAAA;AAAC,IAAA;AAAc,CAAA;AACxC,MAAMC,aAAgB,GAAA;AAACR,IAAAA,YAAAA;AAAcC,IAAAA;AAAiB,CAAA;AAEtD,4BAAe,CAAA,CAAC,EAAEQ,MAAM,WAAEC,SAAO,EAAEC,KAAK,EAAO,GAAA;IAC7C,MAAMC,MAAAA,GAASC,MAAOC,CAAAA,QAAQ,CAACH,KAAAA,CAAAA;AAE/B,IAAA,MAAM,EAAEI,sBAAsB,EAAE,GAAGtB,eAASH,QAAQ;;AAGpD,IAAA,MAAM0B,aAAaC,sBAAiBJ,CAAAA,MAAAA,CAAOC,QAAQ,CAACI,IAAI,CAACL,MAAAA,CAAAA,CAAAA;AAEzD,IAAA,MAAMM,GAAM,GAAA;AACVP,QAAAA,MAAAA;AACAE,QAAAA,QAAAA,EAAUE,WAAWF;AACvB,KAAA;AAEA,IAAA,MAAMM,mBAAsB,GAAA,CAACC,OAAU,GAAA,EAAS,GAAA;QAC9C,MAAM,EAAEC,MAAM,EAAE,GAAGD,OAAAA;;AAGnB,QAAA,MAAME,kBAAkBD,MAAOE,CAAAA,gBAAgB,GAAG,IAAOC,GAAAA,cAAAA,CAAeH,OAAOI,SAAS,CAAA;AAExF,QAAA,MAAMC,kBAAkBC,WAAMC,CAAAA,IAAI,CAChCC,cAAAA,CAASC,oBAAoB,CAAChB,sBAAAA,CAAuBQ,eAAkBJ,CAAAA,EAAAA,GAAAA,CAAAA,EACvEW,eAASC,oBAAoB,CAACC,6BAA+Bb,EAAAA,GAAAA,CAAAA,EAC7DW,eAASC,oBAAoB,CAACE,gBAAkBd,EAAAA,GAAAA,CAAAA,EAChDW,eAASC,oBAAoB,CAACxC,cAAgB4B,EAAAA,GAAAA,CAAAA,EAC9CW,eAASC,oBAAoB,CAAC,CAAC,EAAEG,GAAG,EAAEC,KAAK,EAAE,EAAE,EAAEC,MAAM,EAAE,GAAA;YACvD,IAAIC,WAAAA,CAASF,KAAUG,CAAAA,IAAAA,UAAAA,CAAQH,KAAQ,CAAA,EAAA;gBACrCC,MAAOF,CAAAA,GAAAA,CAAAA;AACT;SACCf,EAAAA,GAAAA,CAAAA,CAAAA;AAGL,QAAA,MAAMoB,eAAeX,WAAMC,CAAAA,IAAI,CAC7BC,cAAAA,CAASU,iBAAiB,CAACzB,sBAAAA,CAAuBQ,eAAkBJ,CAAAA,EAAAA,GAAAA,CAAAA,EACpEW,eAASU,iBAAiB,CAACR,+BAA+Bb,GAC1DW,CAAAA,EAAAA,cAAAA,CAASU,iBAAiB,CAACP,gBAAAA,EAAkBd,GAC7CW,CAAAA,EAAAA,cAAAA,CAASU,iBAAiB,CAACjD,cAAAA,EAAgB4B,MAC3CW,cAASU,CAAAA,iBAAiB,CAAC,CAAC,EAAEN,GAAG,EAAEO,SAAS,EAAEN,KAAK,EAAE,EAAE,EAAEC,MAAM,EAAE,GAAA;AAC/D,YAAA,IAAI,CAACzC,iBAAAA,CAAkB8C,SAAcH,CAAAA,IAAAA,UAAAA,CAAQH,KAAQ,CAAA,EAAA;gBACnDC,MAAOF,CAAAA,GAAAA,CAAAA;AACT;SACCf,EAAAA,GAAAA,CAAAA,CAAAA;AAGL,QAAA,MAAMuB,gBAAmBd,GAAAA,WAAAA,CAAMC,IAAI,CACjCC,cAASa,CAAAA,qBAAqB,CAACnD,sBAAAA,EAAwB2B,GACvDW,CAAAA,EAAAA,cAAAA,CAASa,qBAAqB,CAAC5B,sBAAuBQ,CAAAA,eAAAA,CAAAA,EAAkBJ,GACxEW,CAAAA,EAAAA,cAAAA,CAASa,qBAAqB,CAACX,6BAA+Bb,EAAAA,GAAAA,CAAAA,EAC9DW,cAASa,CAAAA,qBAAqB,CAACV,gBAAAA,EAAkBd,GACjDW,CAAAA,EAAAA,cAAAA,CAASa,qBAAqB,CAACpD,cAAgB4B,EAAAA,GAAAA,CAAAA,CAAAA;AAGjD,QAAA,MAAMyB,iBAAiBhB,WAAMC,CAAAA,IAAI,CAC/BC,cAASe,CAAAA,mBAAmB,CAAC9B,sBAAuBQ,CAAAA,eAAAA,CAAAA,EAAkBJ,GACtEW,CAAAA,EAAAA,cAAAA,CAASe,mBAAmB,CAACZ,gBAAAA,EAAkBd,MAC/CW,cAASe,CAAAA,mBAAmB,CAACtD,cAAgB4B,EAAAA,GAAAA,CAAAA,CAAAA;AAG/C,QAAA,OAAO,OAAO2B,KAAAA,GAAAA;AACZ,YAAA,MAAMC,iBAAiBC,YAAUF,CAAAA,KAAAA,CAAAA;YAEjC,IAAIA,KAAAA,CAAMG,OAAO,EAAE;gBACjBC,MAAOC,CAAAA,MAAM,CAACJ,cAAgB,EAAA;oBAAEE,OAAS,EAAA,MAAMtB,eAAgBmB,CAAAA,KAAAA,CAAMG,OAAO;AAAE,iBAAA,CAAA;AAChF;YAEA,IAAIH,KAAAA,CAAMM,IAAI,EAAE;gBACdF,MAAOC,CAAAA,MAAM,CAACJ,cAAgB,EAAA;oBAAEK,IAAM,EAAA,MAAMb,YAAaO,CAAAA,KAAAA,CAAMM,IAAI;AAAE,iBAAA,CAAA;AACvE;YAEA,IAAIN,KAAAA,CAAMO,QAAQ,EAAE;gBAClBH,MAAOC,CAAAA,MAAM,CAACJ,cAAgB,EAAA;oBAAEM,QAAU,EAAA,MAAMX,gBAAiBI,CAAAA,KAAAA,CAAMO,QAAQ;AAAE,iBAAA,CAAA;AACnF;YAEA,IAAIP,KAAAA,CAAMxB,MAAM,EAAE;gBAChB4B,MAAOC,CAAAA,MAAM,CAACJ,cAAgB,EAAA;oBAAEzB,MAAQ,EAAA,MAAMsB,cAAeE,CAAAA,KAAAA,CAAMxB,MAAM;AAAE,iBAAA,CAAA;AAC7E;YAEA,OAAOyB,cAAAA;AACT,SAAA;AACF,KAAA;AAEA,IAAA,MAAMO,oBAAuB,GAAA,CAACjC,OAAU,GAAA,EAAS,GAAA;QAC/C,MAAM,EAAEC,MAAM,EAAE,GAAGD,OAAAA;AAEnB,QAAA,MAAME,kBAAkBD,MAAOE,CAAAA,gBAAgB,GAAG,IAAO+B,GAAAA,eAAAA,CAAgBjC,OAAOI,SAAS,CAAA;QAEzF,OAAOE,WAAAA,CAAMC,IAAI;QAEf2B,oBAAevB,CAAAA,gBAAAA,EAAkBd;QAEjCqC,oBAAeC,CAAAA,0BAAAA,EAA4BtC;QAE3CqC,oBAAezC,CAAAA,sBAAAA,CAAuBQ,eAAkBJ,CAAAA,EAAAA,GAAAA,CAAAA;QAExD1B,cAASiE,CAAAA,UAAU,CAACC,iBAAiB,CAAC;AACpC/C,YAAAA,MAAAA;AACAE,YAAAA,QAAAA,CAAAA,CAAS8C,GAAW,EAAA;gBAClB,OAAO/C,MAAAA,CAAOC,QAAQ,CAAC8C,GAAAA,CAAAA;AACzB;AACF,SAAA,CAAA,CAAA;AAEJ,KAAA;AAEA,IAAA,MAAMC,mBAAsB,GAAA,CAACxC,OAAU,GAAA,EAAS,GAAA;QAC9C,MAAM,EAAEC,MAAM,EAAE,GAAGD,OAAAA;AAEnB,QAAA,MAAME,kBAAkBD,MAAOE,CAAAA,gBAAgB,GAAG,IAAOsC,GAAAA,cAAAA,CAAexC,OAAOI,SAAS,CAAA;QAExF,OAAOE,WAAAA,CAAMC,IAAI;QAEf2B,oBAAevB,CAAAA,gBAAAA,EAAkBd;QAEjCqC,oBAAezC,CAAAA,sBAAAA,CAAuBQ,eAAkBJ,CAAAA,EAAAA,GAAAA,CAAAA;AAExD4C,QAAAA,gBAAAA,CAAAA;AAEJ,KAAA;AAEA,IAAA,MAAMC,eAAe,CAACC,sBAAAA,GAAAA;AACpB,QAAA,MAAM,EAAEC,mBAAmB,EAAE,GAAGC,4CAA4BzD,CAAAA,SAAAA,CAAAA;;;AAI5D,QAAA,MAAM0D,eAAkB,GAAA,OAAOC,IAAehD,EAAAA,OAAAA,GAAU,EAAS,GAAA;AAC/D,YAAA,IAAIiD,WAAQD,IAAO,CAAA,EAAA;gBACjB,OAAOE,OAAAA,CAAQC,GAAG,CAACH,IAAAA,CAAKI,GAAG,CAAC,CAACC,MAAoBN,GAAAA,eAAAA,CAAgBM,MAAQrD,EAAAA,OAAAA,CAAAA,CAAAA,CAAAA;AAC3E;YAEA,MAAM,EAAEsD,OAAO,EAAElE,MAAAA,EAAQmE,cAAc,EAAE,GAAGC,kBAAkBR,IAAMhD,EAAAA,OAAAA,CAAAA;YAEpE,MAAM,EAAEE,eAAe,EAAEuD,uBAAuB,EAAEtD,gBAAgB,EAAE,GAAG0C,mBAAAA,CACrEU,cACAD,EAAAA,OAAAA,CAAAA;AAGF,YAAA,MAAMI,eAAkB,GAAA;AACtB,gBAAA,GAAG1D,OAAO;gBACVC,MAAQ,EAAA;AACNE,oBAAAA,gBAAAA;oBACAE,SAAWH,EAAAA,eAAAA;AACXuD,oBAAAA;AACF;AACF,aAAA;AAEA,YAAA,MAAME,mBAAmBf,sBAAuBc,CAAAA,eAAAA,CAAAA;AAEhD,YAAA,OAAOC,gBAAiBX,CAAAA,IAAAA,CAAAA;AAC1B,SAAA;QAEA,OAAOD,eAAAA;AACT,KAAA;IAEA,MAAMS,iBAAAA,GAAoB,CAACR,IAAWhD,EAAAA,OAAAA,GAAAA;AACpC,QAAA,OAAO4D,WAAS,CAAA;AAAEN,YAAAA,OAAAA,EAASO,gBAAUvE,KAAO0D,EAAAA,IAAAA,CAAAA;AAAO5D,YAAAA;SAAUY,EAAAA,OAAAA,CAAAA;AAC/D,KAAA;AAEA;;MAGA,MAAM0C,mBAAmBoB,OAAK,CAAA;QAAC,CAAG9E,EAAAA,oBAAAA,CAAqB,MAAM,CAAC;QAAE,CAAGC,EAAAA,oBAAAA,CAAqB,MAAM;AAAE,KAAA,CAAA;AAEhG;;MAGA,MAAM2B,gBAAmB,GAAA,CAAC,EAAEC,GAAG,EAAEtB,MAAM,EAAO,EAAE,EAAEwB,MAAM,EAAO,GAAA;QAC7D,MAAMgD,QAAAA,GAAWC,SAAM,KAAO,EAAA;AAAC,YAAA,QAAA;AAAU,YAAA,YAAA;AAAcnD,YAAAA,GAAAA;AAAK,YAAA;SAAS,EAAEtB,MAAAA,CAAAA;AAEvE,QAAA,IAAIwE,QAAU,EAAA;YACZhD,MAAOF,CAAAA,GAAAA,CAAAA;AACT;AACF,KAAA;AAEA;;AAEC,MACD,MAAMuB,0BAAAA,GAA6B,CAAC,EAAEhB,SAAS,EAAEP,GAAG,EAAEC,KAAK,EAAO,EAAE,EAAEmD,GAAG,EAAO,GAAA;AAC9E,QAAA,MAAMC,oBAAoBC,OAAKC,CAAAA,8BAAAA,CAAAA;AAC/B,QAAA,IAAI,CAAChD,SAAW,EAAA;AACd,YAAA;AACF;QAEA,IAAIA,SAAAA,CAAUiD,IAAI,KAAK,UAAA,IAAcjD,UAAUkD,MAAM,KAAK,iBAAiBxD,KAAO,EAAA;YAChF,IAAIyD,KAAAA,CAAMtB,OAAO,CAACnC,KAAQ,CAAA,EAAA;gBACxBmD,GAAIpD,CAAAA,GAAAA,EAAKC,KAAMsC,CAAAA,GAAG,CAACc,iBAAAA,CAAAA,CAAAA;aACd,MAAA;AACLD,gBAAAA,GAAAA,CAAIpD,KAAKqD,iBAAkBpD,CAAAA,KAAAA,CAAAA,CAAAA;AAC7B;AACF;AACF,KAAA;AAEA;;AAEC,MACD,MAAMH,6BAAAA,GAAgC,CAAC,EAAEE,GAAG,EAAEO,SAAS,EAAE7B,MAAM,EAAO,EAAE,EAAEwB,MAAM,EAAO,GAAA;QACrF,IAAIxB,MAAAA,CAAOgD,GAAG,KAAK,aAAA,IAAiBnB,aAAa,CAACgD,8BAAAA,CAA0BI,QAAQ,CAAC3D,GAAM,CAAA,EAAA;YACzFE,MAAOF,CAAAA,GAAAA,CAAAA;AACT;AACF,KAAA;IAEA,MAAM4B,cAAAA,GAAiB,CAACxC,MAAAA,GAAS,EAAE,GAAA;AACjC,QAAA,MAAMwE,uBAAuBlG,uBAAwBgB,CAAAA,MAAAA,CAAAA;AACrD,QAAA,MAAMmF,qBAAqBjG,qBAAsBc,CAAAA,MAAAA,CAAAA;QAEjD,MAAMoF,4BAAAA,GAA+BC,gBAAaH,oBAAsBC,EAAAA,kBAAAA,CAAAA;AAExE,QAAA,OAAOG,OAAK,CAAA;AAAI5E,YAAAA,GAAAA,MAAAA;AAAWf,YAAAA,GAAAA,gBAAAA;AAAqByF,YAAAA,GAAAA;AAA6B,SAAA,CAAA;AAC/E,KAAA;IAEA,MAAMzC,eAAAA,GAAkB,CAACjC,MAAAA,GAAS,EAAE,GAAA;AAClC,QAAA,MAAM6E,wBAAwBtG,wBAAyBe,CAAAA,MAAAA,CAAAA;AACvD,QAAA,MAAMkF,uBAAuBlG,uBAAwBgB,CAAAA,MAAAA,CAAAA;AAErD,QAAA,OAAOsF,OAAK,CAAA;AACP5E,YAAAA,GAAAA,MAAAA;AACAd,YAAAA,GAAAA,aAAAA;AACAD,YAAAA,GAAAA,gBAAAA;AACA4F,YAAAA,GAAAA,qBAAAA;AACAL,YAAAA,GAAAA,oBAAAA;AACH5F,YAAAA,oBAAAA;AACAC,YAAAA;AACD,SAAA,CAAA;AACH,KAAA;IAEA,MAAMsB,cAAAA,GAAiB,CAACH,MAAAA,GAAS,EAAE,GAAA;AACjC,QAAA,MAAMwE,uBAAuBlG,uBAAwBgB,CAAAA,MAAAA,CAAAA;AACrD,QAAA,MAAMmF,qBAAqBjG,qBAAsBc,CAAAA,MAAAA,CAAAA;QAEjD,MAAMoF,4BAAAA,GAA+BC,gBAAaH,oBAAsBC,EAAAA,kBAAAA,CAAAA;AAExE,QAAA,OAAOG,OAAK,CAAA;AACP5E,YAAAA,GAAAA,MAAAA;AACAd,YAAAA,GAAAA,aAAAA;AACAD,YAAAA,GAAAA,gBAAAA;AACAyF,YAAAA,GAAAA,4BAAAA;AACH9F,YAAAA,oBAAAA;AACAC,YAAAA,oBAAAA;AACAC,YAAAA,sBAAAA;AACAC,YAAAA,oBAAAA;AACAC,YAAAA;AACD,SAAA,CAAA;AACH,KAAA;IAEA,OAAO;AACL8F,QAAAA,cAAAA,EAAgBpC,YAAaV,CAAAA,oBAAAA,CAAAA;AAC7B+C,QAAAA,aAAAA,EAAerC,YAAaH,CAAAA,mBAAAA,CAAAA;AAC5ByC,QAAAA,aAAAA,EAAetC,YAAa5C,CAAAA,mBAAAA;AAC9B,KAAA;AACF,CAAA;;;;"}
@@ -1,7 +1,7 @@
1
- import { detectSubjectType, subject } from '@casl/ability';
2
- import { permittedFieldsOf } from '@casl/ability/extra';
3
- import { omit, isArray, some, isNil, flatMap, prop, isEmpty, defaults, isObject, cloneDeep, getOr, pick, intersection, uniq } from 'lodash/fp';
4
- import { sanitize, contentTypes, async, traverse, traverseEntity } from '@strapi/utils';
1
+ import { subject } from '@casl/ability';
2
+ import { omit, isArray, defaults, isObject, isEmpty, cloneDeep, getOr, pick, intersection, uniq } from 'lodash/fp';
3
+ import { sanitize, createModelCache, contentTypes, async, traverse, traverseEntity } from '@strapi/utils';
4
+ import { createPermissionFieldsCache } from './permission-fields.mjs';
5
5
  import { ADMIN_USER_ALLOWED_FIELDS } from '../../../domain/user.mjs';
6
6
 
7
7
  const { visitors: { removePassword, expandWildcardPopulate } } = sanitize;
@@ -17,9 +17,11 @@ const STATIC_FIELDS = [
17
17
  var createSanitizeHelpers = (({ action, ability, model })=>{
18
18
  const schema = strapi.getModel(model);
19
19
  const { removeDisallowedFields } = sanitize.visitors;
20
+ // Create request-scoped model cache to avoid redundant getModel() calls
21
+ const modelCache = createModelCache(strapi.getModel.bind(strapi));
20
22
  const ctx = {
21
23
  schema,
22
- getModel: strapi.getModel.bind(strapi)
24
+ getModel: modelCache.getModel
23
25
  };
24
26
  const createSanitizeQuery = (options = {})=>{
25
27
  const { fields } = options;
@@ -85,6 +87,7 @@ var createSanitizeHelpers = (({ action, ability, model })=>{
85
87
  omitCreatorRoles);
86
88
  };
87
89
  const wrapSanitize = (createSanitizeFunction)=>{
90
+ const { getPermissionFields } = createPermissionFieldsCache(ability);
88
91
  // TODO
89
92
  // @ts-expect-error define the correct return type
90
93
  const wrappedSanitize = async (data, options = {})=>{
@@ -92,15 +95,11 @@ var createSanitizeHelpers = (({ action, ability, model })=>{
92
95
  return Promise.all(data.map((entity)=>wrappedSanitize(entity, options)));
93
96
  }
94
97
  const { subject, action: actionOverride } = getDefaultOptions(data, options);
95
- const permittedFields = permittedFieldsOf(ability, actionOverride, subject, {
96
- fieldsFrom: (rule)=>rule.fields || []
97
- });
98
- const hasAtLeastOneRegistered = some((fields)=>!isNil(fields), flatMap(prop('fields'), ability.rulesFor(actionOverride, detectSubjectType(subject))));
99
- const shouldIncludeAllFields = isEmpty(permittedFields) && !hasAtLeastOneRegistered;
98
+ const { permittedFields, hasAtLeastOneRegistered, shouldIncludeAll } = getPermissionFields(actionOverride, subject);
100
99
  const sanitizeOptions = {
101
100
  ...options,
102
101
  fields: {
103
- shouldIncludeAll: shouldIncludeAllFields,
102
+ shouldIncludeAll,
104
103
  permitted: permittedFields,
105
104
  hasAtLeastOneRegistered
106
105
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sanitize.mjs","sources":["../../../../../../../server/src/services/permission/permissions-manager/sanitize.ts"],"sourcesContent":["import { subject as asSubject, detectSubjectType } from '@casl/ability';\nimport { permittedFieldsOf } from '@casl/ability/extra';\nimport {\n defaults,\n omit,\n isArray,\n isEmpty,\n isNil,\n flatMap,\n some,\n prop,\n uniq,\n intersection,\n pick,\n getOr,\n isObject,\n cloneDeep,\n} from 'lodash/fp';\n\nimport type { UID } from '@strapi/types';\n\nimport { contentTypes, traverseEntity, sanitize, async, traverse } from '@strapi/utils';\nimport { ADMIN_USER_ALLOWED_FIELDS } from '../../../domain/user';\n\nconst {\n visitors: { removePassword, expandWildcardPopulate },\n} = sanitize;\n\nconst {\n constants,\n isScalarAttribute,\n getNonVisibleAttributes,\n getNonWritableAttributes,\n getWritableAttributes,\n} = contentTypes;\nconst {\n ID_ATTRIBUTE,\n DOC_ID_ATTRIBUTE,\n CREATED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n PUBLISHED_AT_ATTRIBUTE,\n CREATED_BY_ATTRIBUTE,\n UPDATED_BY_ATTRIBUTE,\n} = constants;\n\nconst COMPONENT_FIELDS = ['__component'];\nconst STATIC_FIELDS = [ID_ATTRIBUTE, DOC_ID_ATTRIBUTE];\n\nexport default ({ action, ability, model }: any) => {\n const schema = strapi.getModel(model);\n\n const { removeDisallowedFields } = sanitize.visitors;\n\n const ctx = {\n schema,\n getModel: strapi.getModel.bind(strapi),\n };\n\n const createSanitizeQuery = (options = {} as any) => {\n const { fields } = options;\n\n // TODO: sanitize relations to admin users in all sanitizers\n const permittedFields = fields.shouldIncludeAll ? null : getQueryFields(fields.permitted);\n\n const sanitizeFilters = async.pipe(\n traverse.traverseQueryFilters(removeDisallowedFields(permittedFields), ctx),\n traverse.traverseQueryFilters(omitDisallowedAdminUserFields, ctx),\n traverse.traverseQueryFilters(omitHiddenFields, ctx),\n traverse.traverseQueryFilters(removePassword, ctx),\n traverse.traverseQueryFilters(({ key, value }, { remove }) => {\n if (isObject(value) && isEmpty(value)) {\n remove(key);\n }\n }, ctx)\n );\n\n const sanitizeSort = async.pipe(\n traverse.traverseQuerySort(removeDisallowedFields(permittedFields), ctx),\n traverse.traverseQuerySort(omitDisallowedAdminUserFields, ctx),\n traverse.traverseQuerySort(omitHiddenFields, ctx),\n traverse.traverseQuerySort(removePassword, ctx),\n traverse.traverseQuerySort(({ key, attribute, value }, { remove }) => {\n if (!isScalarAttribute(attribute) && isEmpty(value)) {\n remove(key);\n }\n }, ctx)\n );\n\n const sanitizePopulate = async.pipe(\n traverse.traverseQueryPopulate(expandWildcardPopulate, ctx),\n traverse.traverseQueryPopulate(removeDisallowedFields(permittedFields), ctx),\n traverse.traverseQueryPopulate(omitDisallowedAdminUserFields, ctx),\n traverse.traverseQueryPopulate(omitHiddenFields, ctx),\n traverse.traverseQueryPopulate(removePassword, ctx)\n );\n\n const sanitizeFields = async.pipe(\n traverse.traverseQueryFields(removeDisallowedFields(permittedFields), ctx),\n traverse.traverseQueryFields(omitHiddenFields, ctx),\n traverse.traverseQueryFields(removePassword, ctx)\n );\n\n return async (query: any) => {\n const sanitizedQuery = cloneDeep(query);\n\n if (query.filters) {\n Object.assign(sanitizedQuery, { filters: await sanitizeFilters(query.filters) });\n }\n\n if (query.sort) {\n Object.assign(sanitizedQuery, { sort: await sanitizeSort(query.sort) });\n }\n\n if (query.populate) {\n Object.assign(sanitizedQuery, { populate: await sanitizePopulate(query.populate) });\n }\n\n if (query.fields) {\n Object.assign(sanitizedQuery, { fields: await sanitizeFields(query.fields) });\n }\n\n return sanitizedQuery;\n };\n };\n\n const createSanitizeOutput = (options = {} as any) => {\n const { fields } = options;\n\n const permittedFields = fields.shouldIncludeAll ? null : getOutputFields(fields.permitted);\n\n return async.pipe(\n // Remove fields hidden from the admin\n traverseEntity(omitHiddenFields, ctx),\n // Remove unallowed fields from admin::user relations\n traverseEntity(pickAllowedAdminUserFields, ctx),\n // Remove not allowed fields (RBAC)\n traverseEntity(removeDisallowedFields(permittedFields), ctx),\n // Remove all fields of type 'password'\n sanitize.sanitizers.sanitizePasswords({\n schema,\n getModel(uid: string) {\n return strapi.getModel(uid as UID.Schema);\n },\n })\n );\n };\n\n const createSanitizeInput = (options = {} as any) => {\n const { fields } = options;\n\n const permittedFields = fields.shouldIncludeAll ? null : getInputFields(fields.permitted);\n\n return async.pipe(\n // Remove fields hidden from the admin\n traverseEntity(omitHiddenFields, ctx),\n // Remove not allowed fields (RBAC)\n traverseEntity(removeDisallowedFields(permittedFields), ctx),\n // Remove roles from createdBy & updatedBy fields\n omitCreatorRoles\n );\n };\n\n const wrapSanitize = (createSanitizeFunction: any) => {\n // TODO\n // @ts-expect-error define the correct return type\n const wrappedSanitize = async (data: unknown, options = {} as any) => {\n if (isArray(data)) {\n return Promise.all(data.map((entity: unknown) => wrappedSanitize(entity, options)));\n }\n\n const { subject, action: actionOverride } = getDefaultOptions(data, options);\n\n const permittedFields = permittedFieldsOf(ability, actionOverride, subject, {\n fieldsFrom: (rule) => rule.fields || [],\n });\n\n const hasAtLeastOneRegistered = some(\n (fields) => !isNil(fields),\n flatMap(prop('fields'), ability.rulesFor(actionOverride, detectSubjectType(subject)))\n );\n const shouldIncludeAllFields = isEmpty(permittedFields) && !hasAtLeastOneRegistered;\n\n const sanitizeOptions = {\n ...options,\n fields: {\n shouldIncludeAll: shouldIncludeAllFields,\n permitted: permittedFields,\n hasAtLeastOneRegistered,\n },\n };\n\n const sanitizeFunction = createSanitizeFunction(sanitizeOptions);\n\n return sanitizeFunction(data);\n };\n\n return wrappedSanitize;\n };\n\n const getDefaultOptions = (data: any, options: unknown) => {\n return defaults({ subject: asSubject(model, data), action }, options);\n };\n\n /**\n * Omit creator fields' (createdBy & updatedBy) roles from the admin API responses\n */\n const omitCreatorRoles = omit([`${CREATED_BY_ATTRIBUTE}.roles`, `${UPDATED_BY_ATTRIBUTE}.roles`]);\n\n /**\n * Visitor used to remove hidden fields from the admin API responses\n */\n const omitHiddenFields = ({ key, schema }: any, { remove }: any) => {\n const isHidden = getOr(false, ['config', 'attributes', key, 'hidden'], schema);\n\n if (isHidden) {\n remove(key);\n }\n };\n\n /**\n * Visitor used to only select needed fields from the admin users entities & avoid leaking sensitive information\n */\n const pickAllowedAdminUserFields = ({ attribute, key, value }: any, { set }: any) => {\n const pickAllowedFields = pick(ADMIN_USER_ALLOWED_FIELDS);\n if (!attribute) {\n return;\n }\n\n if (attribute.type === 'relation' && attribute.target === 'admin::user' && value) {\n if (Array.isArray(value)) {\n set(key, value.map(pickAllowedFields));\n } else {\n set(key, pickAllowedFields(value));\n }\n }\n };\n\n /**\n * Visitor used to omit disallowed fields from the admin users entities & avoid leaking sensitive information\n */\n const omitDisallowedAdminUserFields = ({ key, attribute, schema }: any, { remove }: any) => {\n if (schema.uid === 'admin::user' && attribute && !ADMIN_USER_ALLOWED_FIELDS.includes(key)) {\n remove(key);\n }\n };\n\n const getInputFields = (fields = []) => {\n const nonVisibleAttributes = getNonVisibleAttributes(schema);\n const writableAttributes = getWritableAttributes(schema);\n\n const nonVisibleWritableAttributes = intersection(nonVisibleAttributes, writableAttributes);\n\n return uniq([...fields, ...COMPONENT_FIELDS, ...nonVisibleWritableAttributes]);\n };\n\n const getOutputFields = (fields = []) => {\n const nonWritableAttributes = getNonWritableAttributes(schema);\n const nonVisibleAttributes = getNonVisibleAttributes(schema);\n\n return uniq([\n ...fields,\n ...STATIC_FIELDS,\n ...COMPONENT_FIELDS,\n ...nonWritableAttributes,\n ...nonVisibleAttributes,\n CREATED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n ]);\n };\n\n const getQueryFields = (fields = []) => {\n const nonVisibleAttributes = getNonVisibleAttributes(schema);\n const writableAttributes = getWritableAttributes(schema);\n\n const nonVisibleWritableAttributes = intersection(nonVisibleAttributes, writableAttributes);\n\n return uniq([\n ...fields,\n ...STATIC_FIELDS,\n ...COMPONENT_FIELDS,\n ...nonVisibleWritableAttributes,\n CREATED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n PUBLISHED_AT_ATTRIBUTE,\n CREATED_BY_ATTRIBUTE,\n UPDATED_BY_ATTRIBUTE,\n ]);\n };\n\n return {\n sanitizeOutput: wrapSanitize(createSanitizeOutput),\n sanitizeInput: wrapSanitize(createSanitizeInput),\n sanitizeQuery: wrapSanitize(createSanitizeQuery),\n };\n};\n"],"names":["visitors","removePassword","expandWildcardPopulate","sanitize","constants","isScalarAttribute","getNonVisibleAttributes","getNonWritableAttributes","getWritableAttributes","contentTypes","ID_ATTRIBUTE","DOC_ID_ATTRIBUTE","CREATED_AT_ATTRIBUTE","UPDATED_AT_ATTRIBUTE","PUBLISHED_AT_ATTRIBUTE","CREATED_BY_ATTRIBUTE","UPDATED_BY_ATTRIBUTE","COMPONENT_FIELDS","STATIC_FIELDS","action","ability","model","schema","strapi","getModel","removeDisallowedFields","ctx","bind","createSanitizeQuery","options","fields","permittedFields","shouldIncludeAll","getQueryFields","permitted","sanitizeFilters","async","pipe","traverse","traverseQueryFilters","omitDisallowedAdminUserFields","omitHiddenFields","key","value","remove","isObject","isEmpty","sanitizeSort","traverseQuerySort","attribute","sanitizePopulate","traverseQueryPopulate","sanitizeFields","traverseQueryFields","query","sanitizedQuery","cloneDeep","filters","Object","assign","sort","populate","createSanitizeOutput","getOutputFields","traverseEntity","pickAllowedAdminUserFields","sanitizers","sanitizePasswords","uid","createSanitizeInput","getInputFields","omitCreatorRoles","wrapSanitize","createSanitizeFunction","wrappedSanitize","data","isArray","Promise","all","map","entity","subject","actionOverride","getDefaultOptions","permittedFieldsOf","fieldsFrom","rule","hasAtLeastOneRegistered","some","isNil","flatMap","prop","rulesFor","detectSubjectType","shouldIncludeAllFields","sanitizeOptions","sanitizeFunction","defaults","asSubject","omit","isHidden","getOr","set","pickAllowedFields","pick","ADMIN_USER_ALLOWED_FIELDS","type","target","Array","includes","nonVisibleAttributes","writableAttributes","nonVisibleWritableAttributes","intersection","uniq","nonWritableAttributes","sanitizeOutput","sanitizeInput","sanitizeQuery"],"mappings":"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"}
1
+ {"version":3,"file":"sanitize.mjs","sources":["../../../../../../../server/src/services/permission/permissions-manager/sanitize.ts"],"sourcesContent":["import { subject as asSubject } from '@casl/ability';\nimport {\n defaults,\n omit,\n isArray,\n isEmpty,\n uniq,\n intersection,\n pick,\n getOr,\n isObject,\n cloneDeep,\n} from 'lodash/fp';\n\nimport type { UID } from '@strapi/types';\n\nimport {\n contentTypes,\n traverseEntity,\n sanitize,\n async,\n traverse,\n createModelCache,\n} from '@strapi/utils';\nimport { createPermissionFieldsCache } from './permission-fields';\nimport { ADMIN_USER_ALLOWED_FIELDS } from '../../../domain/user';\n\nconst {\n visitors: { removePassword, expandWildcardPopulate },\n} = sanitize;\n\nconst {\n constants,\n isScalarAttribute,\n getNonVisibleAttributes,\n getNonWritableAttributes,\n getWritableAttributes,\n} = contentTypes;\nconst {\n ID_ATTRIBUTE,\n DOC_ID_ATTRIBUTE,\n CREATED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n PUBLISHED_AT_ATTRIBUTE,\n CREATED_BY_ATTRIBUTE,\n UPDATED_BY_ATTRIBUTE,\n} = constants;\n\nconst COMPONENT_FIELDS = ['__component'];\nconst STATIC_FIELDS = [ID_ATTRIBUTE, DOC_ID_ATTRIBUTE];\n\nexport default ({ action, ability, model }: any) => {\n const schema = strapi.getModel(model);\n\n const { removeDisallowedFields } = sanitize.visitors;\n\n // Create request-scoped model cache to avoid redundant getModel() calls\n const modelCache = createModelCache(strapi.getModel.bind(strapi));\n\n const ctx = {\n schema,\n getModel: modelCache.getModel,\n };\n\n const createSanitizeQuery = (options = {} as any) => {\n const { fields } = options;\n\n // TODO: sanitize relations to admin users in all sanitizers\n const permittedFields = fields.shouldIncludeAll ? null : getQueryFields(fields.permitted);\n\n const sanitizeFilters = async.pipe(\n traverse.traverseQueryFilters(removeDisallowedFields(permittedFields), ctx),\n traverse.traverseQueryFilters(omitDisallowedAdminUserFields, ctx),\n traverse.traverseQueryFilters(omitHiddenFields, ctx),\n traverse.traverseQueryFilters(removePassword, ctx),\n traverse.traverseQueryFilters(({ key, value }, { remove }) => {\n if (isObject(value) && isEmpty(value)) {\n remove(key);\n }\n }, ctx)\n );\n\n const sanitizeSort = async.pipe(\n traverse.traverseQuerySort(removeDisallowedFields(permittedFields), ctx),\n traverse.traverseQuerySort(omitDisallowedAdminUserFields, ctx),\n traverse.traverseQuerySort(omitHiddenFields, ctx),\n traverse.traverseQuerySort(removePassword, ctx),\n traverse.traverseQuerySort(({ key, attribute, value }, { remove }) => {\n if (!isScalarAttribute(attribute) && isEmpty(value)) {\n remove(key);\n }\n }, ctx)\n );\n\n const sanitizePopulate = async.pipe(\n traverse.traverseQueryPopulate(expandWildcardPopulate, ctx),\n traverse.traverseQueryPopulate(removeDisallowedFields(permittedFields), ctx),\n traverse.traverseQueryPopulate(omitDisallowedAdminUserFields, ctx),\n traverse.traverseQueryPopulate(omitHiddenFields, ctx),\n traverse.traverseQueryPopulate(removePassword, ctx)\n );\n\n const sanitizeFields = async.pipe(\n traverse.traverseQueryFields(removeDisallowedFields(permittedFields), ctx),\n traverse.traverseQueryFields(omitHiddenFields, ctx),\n traverse.traverseQueryFields(removePassword, ctx)\n );\n\n return async (query: any) => {\n const sanitizedQuery = cloneDeep(query);\n\n if (query.filters) {\n Object.assign(sanitizedQuery, { filters: await sanitizeFilters(query.filters) });\n }\n\n if (query.sort) {\n Object.assign(sanitizedQuery, { sort: await sanitizeSort(query.sort) });\n }\n\n if (query.populate) {\n Object.assign(sanitizedQuery, { populate: await sanitizePopulate(query.populate) });\n }\n\n if (query.fields) {\n Object.assign(sanitizedQuery, { fields: await sanitizeFields(query.fields) });\n }\n\n return sanitizedQuery;\n };\n };\n\n const createSanitizeOutput = (options = {} as any) => {\n const { fields } = options;\n\n const permittedFields = fields.shouldIncludeAll ? null : getOutputFields(fields.permitted);\n\n return async.pipe(\n // Remove fields hidden from the admin\n traverseEntity(omitHiddenFields, ctx),\n // Remove unallowed fields from admin::user relations\n traverseEntity(pickAllowedAdminUserFields, ctx),\n // Remove not allowed fields (RBAC)\n traverseEntity(removeDisallowedFields(permittedFields), ctx),\n // Remove all fields of type 'password'\n sanitize.sanitizers.sanitizePasswords({\n schema,\n getModel(uid: string) {\n return strapi.getModel(uid as UID.Schema);\n },\n })\n );\n };\n\n const createSanitizeInput = (options = {} as any) => {\n const { fields } = options;\n\n const permittedFields = fields.shouldIncludeAll ? null : getInputFields(fields.permitted);\n\n return async.pipe(\n // Remove fields hidden from the admin\n traverseEntity(omitHiddenFields, ctx),\n // Remove not allowed fields (RBAC)\n traverseEntity(removeDisallowedFields(permittedFields), ctx),\n // Remove roles from createdBy & updatedBy fields\n omitCreatorRoles\n );\n };\n\n const wrapSanitize = (createSanitizeFunction: any) => {\n const { getPermissionFields } = createPermissionFieldsCache(ability);\n\n // TODO\n // @ts-expect-error define the correct return type\n const wrappedSanitize = async (data: unknown, options = {} as any) => {\n if (isArray(data)) {\n return Promise.all(data.map((entity: unknown) => wrappedSanitize(entity, options)));\n }\n\n const { subject, action: actionOverride } = getDefaultOptions(data, options);\n\n const { permittedFields, hasAtLeastOneRegistered, shouldIncludeAll } = getPermissionFields(\n actionOverride,\n subject\n );\n\n const sanitizeOptions = {\n ...options,\n fields: {\n shouldIncludeAll,\n permitted: permittedFields,\n hasAtLeastOneRegistered,\n },\n };\n\n const sanitizeFunction = createSanitizeFunction(sanitizeOptions);\n\n return sanitizeFunction(data);\n };\n\n return wrappedSanitize;\n };\n\n const getDefaultOptions = (data: any, options: unknown) => {\n return defaults({ subject: asSubject(model, data), action }, options);\n };\n\n /**\n * Omit creator fields' (createdBy & updatedBy) roles from the admin API responses\n */\n const omitCreatorRoles = omit([`${CREATED_BY_ATTRIBUTE}.roles`, `${UPDATED_BY_ATTRIBUTE}.roles`]);\n\n /**\n * Visitor used to remove hidden fields from the admin API responses\n */\n const omitHiddenFields = ({ key, schema }: any, { remove }: any) => {\n const isHidden = getOr(false, ['config', 'attributes', key, 'hidden'], schema);\n\n if (isHidden) {\n remove(key);\n }\n };\n\n /**\n * Visitor used to only select needed fields from the admin users entities & avoid leaking sensitive information\n */\n const pickAllowedAdminUserFields = ({ attribute, key, value }: any, { set }: any) => {\n const pickAllowedFields = pick(ADMIN_USER_ALLOWED_FIELDS);\n if (!attribute) {\n return;\n }\n\n if (attribute.type === 'relation' && attribute.target === 'admin::user' && value) {\n if (Array.isArray(value)) {\n set(key, value.map(pickAllowedFields));\n } else {\n set(key, pickAllowedFields(value));\n }\n }\n };\n\n /**\n * Visitor used to omit disallowed fields from the admin users entities & avoid leaking sensitive information\n */\n const omitDisallowedAdminUserFields = ({ key, attribute, schema }: any, { remove }: any) => {\n if (schema.uid === 'admin::user' && attribute && !ADMIN_USER_ALLOWED_FIELDS.includes(key)) {\n remove(key);\n }\n };\n\n const getInputFields = (fields = []) => {\n const nonVisibleAttributes = getNonVisibleAttributes(schema);\n const writableAttributes = getWritableAttributes(schema);\n\n const nonVisibleWritableAttributes = intersection(nonVisibleAttributes, writableAttributes);\n\n return uniq([...fields, ...COMPONENT_FIELDS, ...nonVisibleWritableAttributes]);\n };\n\n const getOutputFields = (fields = []) => {\n const nonWritableAttributes = getNonWritableAttributes(schema);\n const nonVisibleAttributes = getNonVisibleAttributes(schema);\n\n return uniq([\n ...fields,\n ...STATIC_FIELDS,\n ...COMPONENT_FIELDS,\n ...nonWritableAttributes,\n ...nonVisibleAttributes,\n CREATED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n ]);\n };\n\n const getQueryFields = (fields = []) => {\n const nonVisibleAttributes = getNonVisibleAttributes(schema);\n const writableAttributes = getWritableAttributes(schema);\n\n const nonVisibleWritableAttributes = intersection(nonVisibleAttributes, writableAttributes);\n\n return uniq([\n ...fields,\n ...STATIC_FIELDS,\n ...COMPONENT_FIELDS,\n ...nonVisibleWritableAttributes,\n CREATED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n PUBLISHED_AT_ATTRIBUTE,\n CREATED_BY_ATTRIBUTE,\n UPDATED_BY_ATTRIBUTE,\n ]);\n };\n\n return {\n sanitizeOutput: wrapSanitize(createSanitizeOutput),\n sanitizeInput: wrapSanitize(createSanitizeInput),\n sanitizeQuery: wrapSanitize(createSanitizeQuery),\n };\n};\n"],"names":["visitors","removePassword","expandWildcardPopulate","sanitize","constants","isScalarAttribute","getNonVisibleAttributes","getNonWritableAttributes","getWritableAttributes","contentTypes","ID_ATTRIBUTE","DOC_ID_ATTRIBUTE","CREATED_AT_ATTRIBUTE","UPDATED_AT_ATTRIBUTE","PUBLISHED_AT_ATTRIBUTE","CREATED_BY_ATTRIBUTE","UPDATED_BY_ATTRIBUTE","COMPONENT_FIELDS","STATIC_FIELDS","action","ability","model","schema","strapi","getModel","removeDisallowedFields","modelCache","createModelCache","bind","ctx","createSanitizeQuery","options","fields","permittedFields","shouldIncludeAll","getQueryFields","permitted","sanitizeFilters","async","pipe","traverse","traverseQueryFilters","omitDisallowedAdminUserFields","omitHiddenFields","key","value","remove","isObject","isEmpty","sanitizeSort","traverseQuerySort","attribute","sanitizePopulate","traverseQueryPopulate","sanitizeFields","traverseQueryFields","query","sanitizedQuery","cloneDeep","filters","Object","assign","sort","populate","createSanitizeOutput","getOutputFields","traverseEntity","pickAllowedAdminUserFields","sanitizers","sanitizePasswords","uid","createSanitizeInput","getInputFields","omitCreatorRoles","wrapSanitize","createSanitizeFunction","getPermissionFields","createPermissionFieldsCache","wrappedSanitize","data","isArray","Promise","all","map","entity","subject","actionOverride","getDefaultOptions","hasAtLeastOneRegistered","sanitizeOptions","sanitizeFunction","defaults","asSubject","omit","isHidden","getOr","set","pickAllowedFields","pick","ADMIN_USER_ALLOWED_FIELDS","type","target","Array","includes","nonVisibleAttributes","writableAttributes","nonVisibleWritableAttributes","intersection","uniq","nonWritableAttributes","sanitizeOutput","sanitizeInput","sanitizeQuery"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
3
  var ability = require('@casl/ability');
4
- var extra = require('@casl/ability/extra');
5
4
  var fp = require('lodash/fp');
6
5
  var utils = require('@strapi/utils');
6
+ var permissionFields = require('./permission-fields.js');
7
7
  var user = require('../../../domain/user.js');
8
8
 
9
9
  const { ValidationError } = utils.errors;
@@ -23,9 +23,11 @@ const throwInvalidKey = ({ key, path })=>{
23
23
  };
24
24
  var createValidateHelpers = (({ action, ability: ability$1, model })=>{
25
25
  const schema = strapi.getModel(model);
26
+ // Create request-scoped model cache to avoid redundant getModel() calls
27
+ const modelCache = utils.createModelCache(strapi.getModel.bind(strapi));
26
28
  const ctx = {
27
29
  schema,
28
- getModel: strapi.getModel.bind(strapi)
30
+ getModel: modelCache.getModel
29
31
  };
30
32
  const createValidateQuery = (options = {})=>{
31
33
  const { fields } = options;
@@ -75,6 +77,7 @@ var createValidateHelpers = (({ action, ability: ability$1, model })=>{
75
77
  omitCreatorRoles);
76
78
  };
77
79
  const wrapValidate = (createValidateFunction)=>{
80
+ const { getPermissionFields } = permissionFields.createPermissionFieldsCache(ability$1);
78
81
  // TODO
79
82
  // @ts-expect-error define the correct return type
80
83
  const wrappedValidate = async (data, options = {})=>{
@@ -82,15 +85,11 @@ var createValidateHelpers = (({ action, ability: ability$1, model })=>{
82
85
  return Promise.all(data.map((entity)=>wrappedValidate(entity, options)));
83
86
  }
84
87
  const { subject, action: actionOverride } = getDefaultOptions(data, options);
85
- const permittedFields = extra.permittedFieldsOf(ability$1, actionOverride, subject, {
86
- fieldsFrom: (rule)=>rule.fields || []
87
- });
88
- const hasAtLeastOneRegistered = fp.some((fields)=>!fp.isNil(fields), fp.flatMap(fp.prop('fields'), ability$1.rulesFor(actionOverride, ability.detectSubjectType(subject))));
89
- const shouldIncludeAllFields = fp.isEmpty(permittedFields) && !hasAtLeastOneRegistered;
88
+ const { permittedFields, hasAtLeastOneRegistered, shouldIncludeAll } = getPermissionFields(actionOverride, subject);
90
89
  const validateOptions = {
91
90
  ...options,
92
91
  fields: {
93
- shouldIncludeAll: shouldIncludeAllFields,
92
+ shouldIncludeAll,
94
93
  permitted: permittedFields,
95
94
  hasAtLeastOneRegistered
96
95
  }
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sources":["../../../../../../../server/src/services/permission/permissions-manager/validate.ts"],"sourcesContent":["import { subject as asSubject, detectSubjectType } from '@casl/ability';\nimport { permittedFieldsOf } from '@casl/ability/extra';\nimport {\n defaults,\n omit,\n isArray,\n isEmpty,\n isNil,\n flatMap,\n some,\n prop,\n uniq,\n intersection,\n getOr,\n isObject,\n} from 'lodash/fp';\n\nimport { contentTypes, traverseEntity, traverse, validate, async, errors } from '@strapi/utils';\nimport { ADMIN_USER_ALLOWED_FIELDS } from '../../../domain/user';\n\nconst { ValidationError } = errors;\nconst { throwPassword, throwDisallowedFields } = validate.visitors;\n\nconst { constants, isScalarAttribute, getNonVisibleAttributes, getWritableAttributes } =\n contentTypes;\nconst {\n ID_ATTRIBUTE,\n DOC_ID_ATTRIBUTE,\n CREATED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n PUBLISHED_AT_ATTRIBUTE,\n CREATED_BY_ATTRIBUTE,\n UPDATED_BY_ATTRIBUTE,\n} = constants;\n\nconst COMPONENT_FIELDS = ['__component'];\n\nconst STATIC_FIELDS = [ID_ATTRIBUTE, DOC_ID_ATTRIBUTE];\n\nconst throwInvalidKey = ({ key, path }: { key: string; path?: string | null }) => {\n const msg = path && path !== key ? `Invalid key ${key} at ${path}` : `Invalid key ${key}`;\n\n throw new ValidationError(msg);\n};\n\nexport default ({ action, ability, model }: any) => {\n const schema = strapi.getModel(model);\n\n const ctx = {\n schema,\n getModel: strapi.getModel.bind(strapi),\n };\n\n const createValidateQuery = (options = {} as any) => {\n const { fields } = options;\n\n // TODO: validate relations to admin users in all validators\n const permittedFields = fields.shouldIncludeAll ? null : getQueryFields(fields.permitted);\n\n const validateFilters = async.pipe(\n traverse.traverseQueryFilters(throwDisallowedFields(permittedFields), ctx),\n traverse.traverseQueryFilters(throwDisallowedAdminUserFields, ctx),\n traverse.traverseQueryFilters(throwPassword, ctx),\n traverse.traverseQueryFilters(({ key, value, path }) => {\n if (isObject(value) && isEmpty(value)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n }, ctx)\n );\n\n const validateSort = async.pipe(\n traverse.traverseQuerySort(throwDisallowedFields(permittedFields), ctx),\n traverse.traverseQuerySort(throwDisallowedAdminUserFields, ctx),\n traverse.traverseQuerySort(throwPassword, ctx),\n traverse.traverseQuerySort(({ key, attribute, value, path }) => {\n if (!isScalarAttribute(attribute) && isEmpty(value)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n }, ctx)\n );\n\n const validateFields = async.pipe(\n traverse.traverseQueryFields(throwDisallowedFields(permittedFields), ctx),\n traverse.traverseQueryFields(throwPassword, ctx)\n );\n\n const validatePopulate = async.pipe(\n traverse.traverseQueryPopulate(throwDisallowedFields(permittedFields), ctx),\n traverse.traverseQueryPopulate(throwDisallowedAdminUserFields, ctx),\n traverse.traverseQueryPopulate(throwHiddenFields, ctx),\n traverse.traverseQueryPopulate(throwPassword, ctx)\n );\n\n return async (query: any) => {\n if (query.filters) {\n await validateFilters(query.filters);\n }\n\n if (query.sort) {\n await validateSort(query.sort);\n }\n\n if (query.fields) {\n await validateFields(query.fields);\n }\n\n // a wildcard is always valid; its conversion will be handled by the entity service and can be optimized with sanitizer\n if (query.populate && query.populate !== '*') {\n await validatePopulate(query.populate);\n }\n\n return true;\n };\n };\n\n const createValidateInput = (options = {} as any) => {\n const { fields } = options;\n\n const permittedFields = fields.shouldIncludeAll ? null : getInputFields(fields.permitted);\n\n return async.pipe(\n // Remove fields hidden from the admin\n traverseEntity(throwHiddenFields, ctx),\n // Remove not allowed fields (RBAC)\n traverseEntity(throwDisallowedFields(permittedFields), ctx),\n // Remove roles from createdBy & updatedBy fields\n omitCreatorRoles\n );\n };\n\n const wrapValidate = (createValidateFunction: any) => {\n // TODO\n // @ts-expect-error define the correct return type\n const wrappedValidate = async (data, options = {}): Promise<unknown> => {\n if (isArray(data)) {\n return Promise.all(data.map((entity: unknown) => wrappedValidate(entity, options)));\n }\n\n const { subject, action: actionOverride } = getDefaultOptions(data, options);\n\n const permittedFields = permittedFieldsOf(ability, actionOverride, subject, {\n fieldsFrom: (rule) => rule.fields || [],\n });\n\n const hasAtLeastOneRegistered = some(\n (fields) => !isNil(fields),\n flatMap(prop('fields'), ability.rulesFor(actionOverride, detectSubjectType(subject)))\n );\n const shouldIncludeAllFields = isEmpty(permittedFields) && !hasAtLeastOneRegistered;\n\n const validateOptions = {\n ...options,\n fields: {\n shouldIncludeAll: shouldIncludeAllFields,\n permitted: permittedFields,\n hasAtLeastOneRegistered,\n },\n };\n\n const validateFunction = createValidateFunction(validateOptions);\n\n return validateFunction(data);\n };\n\n return wrappedValidate;\n };\n\n const getDefaultOptions = (data: any, options: unknown) => {\n return defaults({ subject: asSubject(model, data), action }, options);\n };\n\n /**\n * Omit creator fields' (createdBy & updatedBy) roles from the admin API responses\n */\n const omitCreatorRoles = omit([`${CREATED_BY_ATTRIBUTE}.roles`, `${UPDATED_BY_ATTRIBUTE}.roles`]);\n\n /**\n * Visitor used to remove hidden fields from the admin API responses\n */\n const throwHiddenFields = ({ key, schema, path }: any) => {\n const isHidden = getOr(false, ['config', 'attributes', key, 'hidden'], schema);\n\n if (isHidden) {\n throwInvalidKey({ key, path: path.attribute });\n }\n };\n\n /**\n * Visitor used to omit disallowed fields from the admin users entities & avoid leaking sensitive information\n */\n const throwDisallowedAdminUserFields = ({ key, attribute, schema, path }: any) => {\n if (schema.uid === 'admin::user' && attribute && !ADMIN_USER_ALLOWED_FIELDS.includes(key)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n };\n\n const getInputFields = (fields = []) => {\n const nonVisibleAttributes = getNonVisibleAttributes(schema);\n const writableAttributes = getWritableAttributes(schema);\n\n const nonVisibleWritableAttributes = intersection(nonVisibleAttributes, writableAttributes);\n\n return uniq([...fields, ...COMPONENT_FIELDS, ...nonVisibleWritableAttributes]);\n };\n\n const getQueryFields = (fields = []) => {\n return uniq([\n ...fields,\n ...STATIC_FIELDS,\n ...COMPONENT_FIELDS,\n CREATED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n PUBLISHED_AT_ATTRIBUTE,\n ]);\n };\n\n return {\n validateQuery: wrapValidate(createValidateQuery),\n validateInput: wrapValidate(createValidateInput),\n };\n};\n"],"names":["ValidationError","errors","throwPassword","throwDisallowedFields","validate","visitors","constants","isScalarAttribute","getNonVisibleAttributes","getWritableAttributes","contentTypes","ID_ATTRIBUTE","DOC_ID_ATTRIBUTE","CREATED_AT_ATTRIBUTE","UPDATED_AT_ATTRIBUTE","PUBLISHED_AT_ATTRIBUTE","CREATED_BY_ATTRIBUTE","UPDATED_BY_ATTRIBUTE","COMPONENT_FIELDS","STATIC_FIELDS","throwInvalidKey","key","path","msg","action","ability","model","schema","strapi","getModel","ctx","bind","createValidateQuery","options","fields","permittedFields","shouldIncludeAll","getQueryFields","permitted","validateFilters","async","pipe","traverse","traverseQueryFilters","throwDisallowedAdminUserFields","value","isObject","isEmpty","attribute","validateSort","traverseQuerySort","validateFields","traverseQueryFields","validatePopulate","traverseQueryPopulate","throwHiddenFields","query","filters","sort","populate","createValidateInput","getInputFields","traverseEntity","omitCreatorRoles","wrapValidate","createValidateFunction","wrappedValidate","data","isArray","Promise","all","map","entity","subject","actionOverride","getDefaultOptions","permittedFieldsOf","fieldsFrom","rule","hasAtLeastOneRegistered","some","isNil","flatMap","prop","rulesFor","detectSubjectType","shouldIncludeAllFields","validateOptions","validateFunction","defaults","asSubject","omit","isHidden","getOr","uid","ADMIN_USER_ALLOWED_FIELDS","includes","nonVisibleAttributes","writableAttributes","nonVisibleWritableAttributes","intersection","uniq","validateQuery","validateInput"],"mappings":"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"}
1
+ {"version":3,"file":"validate.js","sources":["../../../../../../../server/src/services/permission/permissions-manager/validate.ts"],"sourcesContent":["import { subject as asSubject } from '@casl/ability';\nimport { defaults, omit, isArray, isEmpty, uniq, intersection, getOr, isObject } from 'lodash/fp';\n\nimport {\n contentTypes,\n traverseEntity,\n traverse,\n validate,\n async,\n errors,\n createModelCache,\n} from '@strapi/utils';\nimport { createPermissionFieldsCache } from './permission-fields';\n\nimport { ADMIN_USER_ALLOWED_FIELDS } from '../../../domain/user';\n\nconst { ValidationError } = errors;\nconst { throwPassword, throwDisallowedFields } = validate.visitors;\n\nconst { constants, isScalarAttribute, getNonVisibleAttributes, getWritableAttributes } =\n contentTypes;\nconst {\n ID_ATTRIBUTE,\n DOC_ID_ATTRIBUTE,\n CREATED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n PUBLISHED_AT_ATTRIBUTE,\n CREATED_BY_ATTRIBUTE,\n UPDATED_BY_ATTRIBUTE,\n} = constants;\n\nconst COMPONENT_FIELDS = ['__component'];\n\nconst STATIC_FIELDS = [ID_ATTRIBUTE, DOC_ID_ATTRIBUTE];\n\nconst throwInvalidKey = ({ key, path }: { key: string; path?: string | null }) => {\n const msg = path && path !== key ? `Invalid key ${key} at ${path}` : `Invalid key ${key}`;\n\n throw new ValidationError(msg);\n};\n\nexport default ({ action, ability, model }: any) => {\n const schema = strapi.getModel(model);\n\n // Create request-scoped model cache to avoid redundant getModel() calls\n const modelCache = createModelCache(strapi.getModel.bind(strapi));\n\n const ctx = {\n schema,\n getModel: modelCache.getModel,\n };\n\n const createValidateQuery = (options = {} as any) => {\n const { fields } = options;\n\n // TODO: validate relations to admin users in all validators\n const permittedFields = fields.shouldIncludeAll ? null : getQueryFields(fields.permitted);\n\n const validateFilters = async.pipe(\n traverse.traverseQueryFilters(throwDisallowedFields(permittedFields), ctx),\n traverse.traverseQueryFilters(throwDisallowedAdminUserFields, ctx),\n traverse.traverseQueryFilters(throwPassword, ctx),\n traverse.traverseQueryFilters(({ key, value, path }) => {\n if (isObject(value) && isEmpty(value)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n }, ctx)\n );\n\n const validateSort = async.pipe(\n traverse.traverseQuerySort(throwDisallowedFields(permittedFields), ctx),\n traverse.traverseQuerySort(throwDisallowedAdminUserFields, ctx),\n traverse.traverseQuerySort(throwPassword, ctx),\n traverse.traverseQuerySort(({ key, attribute, value, path }) => {\n if (!isScalarAttribute(attribute) && isEmpty(value)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n }, ctx)\n );\n\n const validateFields = async.pipe(\n traverse.traverseQueryFields(throwDisallowedFields(permittedFields), ctx),\n traverse.traverseQueryFields(throwPassword, ctx)\n );\n\n const validatePopulate = async.pipe(\n traverse.traverseQueryPopulate(throwDisallowedFields(permittedFields), ctx),\n traverse.traverseQueryPopulate(throwDisallowedAdminUserFields, ctx),\n traverse.traverseQueryPopulate(throwHiddenFields, ctx),\n traverse.traverseQueryPopulate(throwPassword, ctx)\n );\n\n return async (query: any) => {\n if (query.filters) {\n await validateFilters(query.filters);\n }\n\n if (query.sort) {\n await validateSort(query.sort);\n }\n\n if (query.fields) {\n await validateFields(query.fields);\n }\n\n // a wildcard is always valid; its conversion will be handled by the entity service and can be optimized with sanitizer\n if (query.populate && query.populate !== '*') {\n await validatePopulate(query.populate);\n }\n\n return true;\n };\n };\n\n const createValidateInput = (options = {} as any) => {\n const { fields } = options;\n\n const permittedFields = fields.shouldIncludeAll ? null : getInputFields(fields.permitted);\n\n return async.pipe(\n // Remove fields hidden from the admin\n traverseEntity(throwHiddenFields, ctx),\n // Remove not allowed fields (RBAC)\n traverseEntity(throwDisallowedFields(permittedFields), ctx),\n // Remove roles from createdBy & updatedBy fields\n omitCreatorRoles\n );\n };\n\n const wrapValidate = (createValidateFunction: any) => {\n const { getPermissionFields } = createPermissionFieldsCache(ability);\n\n // TODO\n // @ts-expect-error define the correct return type\n const wrappedValidate = async (data, options = {}): Promise<unknown> => {\n if (isArray(data)) {\n return Promise.all(data.map((entity: unknown) => wrappedValidate(entity, options)));\n }\n\n const { subject, action: actionOverride } = getDefaultOptions(data, options);\n\n const { permittedFields, hasAtLeastOneRegistered, shouldIncludeAll } = getPermissionFields(\n actionOverride,\n subject\n );\n\n const validateOptions = {\n ...options,\n fields: {\n shouldIncludeAll,\n permitted: permittedFields,\n hasAtLeastOneRegistered,\n },\n };\n\n const validateFunction = createValidateFunction(validateOptions);\n\n return validateFunction(data);\n };\n\n return wrappedValidate;\n };\n\n const getDefaultOptions = (data: any, options: unknown) => {\n return defaults({ subject: asSubject(model, data), action }, options);\n };\n\n /**\n * Omit creator fields' (createdBy & updatedBy) roles from the admin API responses\n */\n const omitCreatorRoles = omit([`${CREATED_BY_ATTRIBUTE}.roles`, `${UPDATED_BY_ATTRIBUTE}.roles`]);\n\n /**\n * Visitor used to remove hidden fields from the admin API responses\n */\n const throwHiddenFields = ({ key, schema, path }: any) => {\n const isHidden = getOr(false, ['config', 'attributes', key, 'hidden'], schema);\n\n if (isHidden) {\n throwInvalidKey({ key, path: path.attribute });\n }\n };\n\n /**\n * Visitor used to omit disallowed fields from the admin users entities & avoid leaking sensitive information\n */\n const throwDisallowedAdminUserFields = ({ key, attribute, schema, path }: any) => {\n if (schema.uid === 'admin::user' && attribute && !ADMIN_USER_ALLOWED_FIELDS.includes(key)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n };\n\n const getInputFields = (fields = []) => {\n const nonVisibleAttributes = getNonVisibleAttributes(schema);\n const writableAttributes = getWritableAttributes(schema);\n\n const nonVisibleWritableAttributes = intersection(nonVisibleAttributes, writableAttributes);\n\n return uniq([...fields, ...COMPONENT_FIELDS, ...nonVisibleWritableAttributes]);\n };\n\n const getQueryFields = (fields = []) => {\n return uniq([\n ...fields,\n ...STATIC_FIELDS,\n ...COMPONENT_FIELDS,\n CREATED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n PUBLISHED_AT_ATTRIBUTE,\n ]);\n };\n\n return {\n validateQuery: wrapValidate(createValidateQuery),\n validateInput: wrapValidate(createValidateInput),\n };\n};\n"],"names":["ValidationError","errors","throwPassword","throwDisallowedFields","validate","visitors","constants","isScalarAttribute","getNonVisibleAttributes","getWritableAttributes","contentTypes","ID_ATTRIBUTE","DOC_ID_ATTRIBUTE","CREATED_AT_ATTRIBUTE","UPDATED_AT_ATTRIBUTE","PUBLISHED_AT_ATTRIBUTE","CREATED_BY_ATTRIBUTE","UPDATED_BY_ATTRIBUTE","COMPONENT_FIELDS","STATIC_FIELDS","throwInvalidKey","key","path","msg","action","ability","model","schema","strapi","getModel","modelCache","createModelCache","bind","ctx","createValidateQuery","options","fields","permittedFields","shouldIncludeAll","getQueryFields","permitted","validateFilters","async","pipe","traverse","traverseQueryFilters","throwDisallowedAdminUserFields","value","isObject","isEmpty","attribute","validateSort","traverseQuerySort","validateFields","traverseQueryFields","validatePopulate","traverseQueryPopulate","throwHiddenFields","query","filters","sort","populate","createValidateInput","getInputFields","traverseEntity","omitCreatorRoles","wrapValidate","createValidateFunction","getPermissionFields","createPermissionFieldsCache","wrappedValidate","data","isArray","Promise","all","map","entity","subject","actionOverride","getDefaultOptions","hasAtLeastOneRegistered","validateOptions","validateFunction","defaults","asSubject","omit","isHidden","getOr","uid","ADMIN_USER_ALLOWED_FIELDS","includes","nonVisibleAttributes","writableAttributes","nonVisibleWritableAttributes","intersection","uniq","validateQuery","validateInput"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import { detectSubjectType, subject } from '@casl/ability';
2
- import { permittedFieldsOf } from '@casl/ability/extra';
3
- import { omit, isArray, some, isNil, flatMap, prop, isEmpty, defaults, isObject, getOr, intersection, uniq } from 'lodash/fp';
4
- import { validate, contentTypes, async, traverse, traverseEntity, errors } from '@strapi/utils';
1
+ import { subject } from '@casl/ability';
2
+ import { omit, isArray, defaults, isObject, isEmpty, getOr, intersection, uniq } from 'lodash/fp';
3
+ import { validate, createModelCache, contentTypes, async, traverse, traverseEntity, errors } from '@strapi/utils';
4
+ import { createPermissionFieldsCache } from './permission-fields.mjs';
5
5
  import { ADMIN_USER_ALLOWED_FIELDS } from '../../../domain/user.mjs';
6
6
 
7
7
  const { ValidationError } = errors;
@@ -21,9 +21,11 @@ const throwInvalidKey = ({ key, path })=>{
21
21
  };
22
22
  var createValidateHelpers = (({ action, ability, model })=>{
23
23
  const schema = strapi.getModel(model);
24
+ // Create request-scoped model cache to avoid redundant getModel() calls
25
+ const modelCache = createModelCache(strapi.getModel.bind(strapi));
24
26
  const ctx = {
25
27
  schema,
26
- getModel: strapi.getModel.bind(strapi)
28
+ getModel: modelCache.getModel
27
29
  };
28
30
  const createValidateQuery = (options = {})=>{
29
31
  const { fields } = options;
@@ -73,6 +75,7 @@ var createValidateHelpers = (({ action, ability, model })=>{
73
75
  omitCreatorRoles);
74
76
  };
75
77
  const wrapValidate = (createValidateFunction)=>{
78
+ const { getPermissionFields } = createPermissionFieldsCache(ability);
76
79
  // TODO
77
80
  // @ts-expect-error define the correct return type
78
81
  const wrappedValidate = async (data, options = {})=>{
@@ -80,15 +83,11 @@ var createValidateHelpers = (({ action, ability, model })=>{
80
83
  return Promise.all(data.map((entity)=>wrappedValidate(entity, options)));
81
84
  }
82
85
  const { subject, action: actionOverride } = getDefaultOptions(data, options);
83
- const permittedFields = permittedFieldsOf(ability, actionOverride, subject, {
84
- fieldsFrom: (rule)=>rule.fields || []
85
- });
86
- const hasAtLeastOneRegistered = some((fields)=>!isNil(fields), flatMap(prop('fields'), ability.rulesFor(actionOverride, detectSubjectType(subject))));
87
- const shouldIncludeAllFields = isEmpty(permittedFields) && !hasAtLeastOneRegistered;
86
+ const { permittedFields, hasAtLeastOneRegistered, shouldIncludeAll } = getPermissionFields(actionOverride, subject);
88
87
  const validateOptions = {
89
88
  ...options,
90
89
  fields: {
91
- shouldIncludeAll: shouldIncludeAllFields,
90
+ shouldIncludeAll,
92
91
  permitted: permittedFields,
93
92
  hasAtLeastOneRegistered
94
93
  }