@strapi/admin 5.55.1 → 5.57.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 (388) hide show
  1. package/dist/admin/admin/src/components/Filters.js +1 -1
  2. package/dist/admin/admin/src/components/Filters.js.map +1 -1
  3. package/dist/admin/admin/src/components/Filters.mjs +1 -1
  4. package/dist/admin/admin/src/components/Filters.mjs.map +1 -1
  5. package/dist/admin/admin/src/components/FormInputs/Enumeration.js +2 -2
  6. package/dist/admin/admin/src/components/FormInputs/Enumeration.js.map +1 -1
  7. package/dist/admin/admin/src/components/FormInputs/Enumeration.mjs +2 -2
  8. package/dist/admin/admin/src/components/FormInputs/Enumeration.mjs.map +1 -1
  9. package/dist/admin/admin/src/components/MediaLibraryBanner.js +38 -2
  10. package/dist/admin/admin/src/components/MediaLibraryBanner.js.map +1 -1
  11. package/dist/admin/admin/src/components/MediaLibraryBanner.mjs +18 -2
  12. package/dist/admin/admin/src/components/MediaLibraryBanner.mjs.map +1 -1
  13. package/dist/admin/admin/src/components/RelativeTime.js +9 -0
  14. package/dist/admin/admin/src/components/RelativeTime.js.map +1 -1
  15. package/dist/admin/admin/src/components/RelativeTime.mjs +10 -1
  16. package/dist/admin/admin/src/components/RelativeTime.mjs.map +1 -1
  17. package/dist/admin/admin/src/components/TopBanners.js +52 -0
  18. package/dist/admin/admin/src/components/TopBanners.js.map +1 -0
  19. package/dist/admin/admin/src/components/TopBanners.mjs +30 -0
  20. package/dist/admin/admin/src/components/TopBanners.mjs.map +1 -0
  21. package/dist/admin/admin/src/components/UpsellBanner.js +9 -16
  22. package/dist/admin/admin/src/components/UpsellBanner.js.map +1 -1
  23. package/dist/admin/admin/src/components/UpsellBanner.mjs +11 -18
  24. package/dist/admin/admin/src/components/UpsellBanner.mjs.map +1 -1
  25. package/dist/admin/admin/src/features/Tracking.js +28 -8
  26. package/dist/admin/admin/src/features/Tracking.js.map +1 -1
  27. package/dist/admin/admin/src/features/Tracking.mjs +29 -10
  28. package/dist/admin/admin/src/features/Tracking.mjs.map +1 -1
  29. package/dist/admin/admin/src/layouts/AuthenticatedLayout.js +4 -20
  30. package/dist/admin/admin/src/layouts/AuthenticatedLayout.js.map +1 -1
  31. package/dist/admin/admin/src/layouts/AuthenticatedLayout.mjs +4 -20
  32. package/dist/admin/admin/src/layouts/AuthenticatedLayout.mjs.map +1 -1
  33. package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.js +59 -0
  34. package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.js.map +1 -0
  35. package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.mjs +37 -0
  36. package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.mjs.map +1 -0
  37. package/dist/admin/admin/src/render.js +4 -69
  38. package/dist/admin/admin/src/render.js.map +1 -1
  39. package/dist/admin/admin/src/render.mjs +4 -69
  40. package/dist/admin/admin/src/render.mjs.map +1 -1
  41. package/dist/admin/admin/src/translations/en.json.js +15 -0
  42. package/dist/admin/admin/src/translations/en.json.js.map +1 -1
  43. package/dist/admin/admin/src/translations/en.json.mjs +15 -0
  44. package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
  45. package/dist/admin/admin/src/utils/browserStrapi.js +93 -0
  46. package/dist/admin/admin/src/utils/browserStrapi.js.map +1 -0
  47. package/dist/admin/admin/src/utils/browserStrapi.mjs +91 -0
  48. package/dist/admin/admin/src/utils/browserStrapi.mjs.map +1 -0
  49. package/dist/admin/admin/src/utils/getFetchClient.js +3 -3
  50. package/dist/admin/admin/src/utils/getFetchClient.js.map +1 -1
  51. package/dist/admin/admin/src/utils/getFetchClient.mjs +2 -2
  52. package/dist/admin/admin/src/utils/getFetchClient.mjs.map +1 -1
  53. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.js +2 -1
  54. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.js.map +1 -1
  55. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.mjs +2 -1
  56. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.mjs.map +1 -1
  57. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js +16 -1
  58. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js.map +1 -1
  59. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs +16 -1
  60. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs.map +1 -1
  61. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.js +3 -1
  62. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.js.map +1 -1
  63. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.mjs +3 -1
  64. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.mjs.map +1 -1
  65. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.js +64 -0
  66. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.js.map +1 -0
  67. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.mjs +60 -0
  68. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.mjs.map +1 -0
  69. package/dist/admin/ee/admin/src/services/auditLogs.js +2 -1
  70. package/dist/admin/ee/admin/src/services/auditLogs.js.map +1 -1
  71. package/dist/admin/ee/admin/src/services/auditLogs.mjs +2 -1
  72. package/dist/admin/ee/admin/src/services/auditLogs.mjs.map +1 -1
  73. package/dist/admin/src/components/MediaLibraryBanner.d.ts +10 -1
  74. package/dist/admin/src/components/SubNav.d.ts +2 -2
  75. package/dist/admin/src/components/TopBanners.d.ts +8 -0
  76. package/dist/admin/src/features/Tracking.d.ts +12 -1
  77. package/dist/admin/src/layouts/useAuthenticatedAccessTracking.d.ts +6 -0
  78. package/dist/admin/src/utils/browserStrapi.d.ts +11 -0
  79. package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.d.ts +15 -0
  80. package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.d.ts +14 -0
  81. package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts +10 -1
  82. package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts.map +1 -1
  83. package/dist/ee/server/src/controllers/admin.d.ts +2 -28
  84. package/dist/ee/server/src/controllers/admin.d.ts.map +1 -1
  85. package/dist/ee/server/src/controllers/authentication-utils/utils.d.ts +8 -2
  86. package/dist/ee/server/src/controllers/authentication-utils/utils.d.ts.map +1 -1
  87. package/dist/ee/server/src/controllers/authentication.d.ts.map +1 -1
  88. package/dist/ee/server/src/controllers/index.d.ts +1 -28
  89. package/dist/ee/server/src/controllers/index.d.ts.map +1 -1
  90. package/dist/ee/server/src/controllers/user.d.ts.map +1 -1
  91. package/dist/ee/server/src/index.d.ts +6 -30
  92. package/dist/ee/server/src/index.d.ts.map +1 -1
  93. package/dist/ee/server/src/services/auth.d.ts +1 -1
  94. package/dist/ee/server/src/services/auth.d.ts.map +1 -1
  95. package/dist/ee/server/src/services/index.d.ts +5 -2
  96. package/dist/ee/server/src/services/index.d.ts.map +1 -1
  97. package/dist/ee/server/src/services/metrics.d.ts.map +1 -1
  98. package/dist/ee/server/src/services/persist-tables.d.ts.map +1 -1
  99. package/dist/ee/server/src/services/seat-enforcement.d.ts +3 -1
  100. package/dist/ee/server/src/services/seat-enforcement.d.ts.map +1 -1
  101. package/dist/ee/server/src/services/user.d.ts.map +1 -1
  102. package/dist/server/ee/server/src/audit-logs/services/lifecycles.js +37 -21
  103. package/dist/server/ee/server/src/audit-logs/services/lifecycles.js.map +1 -1
  104. package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs +37 -21
  105. package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs.map +1 -1
  106. package/dist/server/ee/server/src/controllers/admin.js +8 -7
  107. package/dist/server/ee/server/src/controllers/admin.js.map +1 -1
  108. package/dist/server/ee/server/src/controllers/admin.mjs +8 -7
  109. package/dist/server/ee/server/src/controllers/admin.mjs.map +1 -1
  110. package/dist/server/ee/server/src/controllers/authentication-utils/utils.js +2 -2
  111. package/dist/server/ee/server/src/controllers/authentication-utils/utils.js.map +1 -1
  112. package/dist/server/ee/server/src/controllers/authentication-utils/utils.mjs +2 -2
  113. package/dist/server/ee/server/src/controllers/authentication-utils/utils.mjs.map +1 -1
  114. package/dist/server/ee/server/src/controllers/authentication.js +11 -11
  115. package/dist/server/ee/server/src/controllers/authentication.js.map +1 -1
  116. package/dist/server/ee/server/src/controllers/authentication.mjs +11 -11
  117. package/dist/server/ee/server/src/controllers/authentication.mjs.map +1 -1
  118. package/dist/server/ee/server/src/controllers/user.js +7 -8
  119. package/dist/server/ee/server/src/controllers/user.js.map +1 -1
  120. package/dist/server/ee/server/src/controllers/user.mjs +8 -9
  121. package/dist/server/ee/server/src/controllers/user.mjs.map +1 -1
  122. package/dist/server/ee/server/src/index.js +4 -0
  123. package/dist/server/ee/server/src/index.js.map +1 -1
  124. package/dist/server/ee/server/src/index.mjs +4 -0
  125. package/dist/server/ee/server/src/index.mjs.map +1 -1
  126. package/dist/server/ee/server/src/services/auth.js +1 -6
  127. package/dist/server/ee/server/src/services/auth.js.map +1 -1
  128. package/dist/server/ee/server/src/services/auth.mjs +2 -7
  129. package/dist/server/ee/server/src/services/auth.mjs.map +1 -1
  130. package/dist/server/ee/server/src/services/metrics.js +9 -7
  131. package/dist/server/ee/server/src/services/metrics.js.map +1 -1
  132. package/dist/server/ee/server/src/services/metrics.mjs +9 -7
  133. package/dist/server/ee/server/src/services/metrics.mjs.map +1 -1
  134. package/dist/server/ee/server/src/services/persist-tables.js +3 -4
  135. package/dist/server/ee/server/src/services/persist-tables.js.map +1 -1
  136. package/dist/server/ee/server/src/services/persist-tables.mjs +3 -4
  137. package/dist/server/ee/server/src/services/persist-tables.mjs.map +1 -1
  138. package/dist/server/ee/server/src/services/role.js +2 -2
  139. package/dist/server/ee/server/src/services/role.js.map +1 -1
  140. package/dist/server/ee/server/src/services/role.mjs +1 -1
  141. package/dist/server/ee/server/src/services/role.mjs.map +1 -1
  142. package/dist/server/ee/server/src/services/seat-enforcement.js +20 -20
  143. package/dist/server/ee/server/src/services/seat-enforcement.js.map +1 -1
  144. package/dist/server/ee/server/src/services/seat-enforcement.mjs +20 -20
  145. package/dist/server/ee/server/src/services/seat-enforcement.mjs.map +1 -1
  146. package/dist/server/ee/server/src/services/user.js +37 -6
  147. package/dist/server/ee/server/src/services/user.js.map +1 -1
  148. package/dist/server/ee/server/src/services/user.mjs +38 -7
  149. package/dist/server/ee/server/src/services/user.mjs.map +1 -1
  150. package/dist/server/ee/server/src/utils/sso-lock.js +2 -2
  151. package/dist/server/ee/server/src/utils/sso-lock.js.map +1 -1
  152. package/dist/server/ee/server/src/utils/sso-lock.mjs +1 -1
  153. package/dist/server/ee/server/src/utils/sso-lock.mjs.map +1 -1
  154. package/dist/server/server/src/audit-logs/admin-users.js +169 -0
  155. package/dist/server/server/src/audit-logs/admin-users.js.map +1 -0
  156. package/dist/server/server/src/audit-logs/admin-users.mjs +157 -0
  157. package/dist/server/server/src/audit-logs/admin-users.mjs.map +1 -0
  158. package/dist/server/server/src/audit-logs/tokens.js +3 -3
  159. package/dist/server/server/src/audit-logs/tokens.js.map +1 -1
  160. package/dist/server/server/src/audit-logs/tokens.mjs +2 -2
  161. package/dist/server/server/src/audit-logs/tokens.mjs.map +1 -1
  162. package/dist/server/server/src/audit-logs/webhooks.js +106 -0
  163. package/dist/server/server/src/audit-logs/webhooks.js.map +1 -0
  164. package/dist/server/server/src/audit-logs/webhooks.mjs +100 -0
  165. package/dist/server/server/src/audit-logs/webhooks.mjs.map +1 -0
  166. package/dist/server/server/src/bootstrap.js +6 -4
  167. package/dist/server/server/src/bootstrap.js.map +1 -1
  168. package/dist/server/server/src/bootstrap.mjs +6 -4
  169. package/dist/server/server/src/bootstrap.mjs.map +1 -1
  170. package/dist/server/server/src/controllers/admin-token.js +8 -8
  171. package/dist/server/server/src/controllers/admin-token.js.map +1 -1
  172. package/dist/server/server/src/controllers/admin-token.mjs +4 -4
  173. package/dist/server/server/src/controllers/admin-token.mjs.map +1 -1
  174. package/dist/server/server/src/controllers/admin.js +4 -5
  175. package/dist/server/server/src/controllers/admin.js.map +1 -1
  176. package/dist/server/server/src/controllers/admin.mjs +3 -4
  177. package/dist/server/server/src/controllers/admin.mjs.map +1 -1
  178. package/dist/server/server/src/controllers/api-token.js +8 -8
  179. package/dist/server/server/src/controllers/api-token.js.map +1 -1
  180. package/dist/server/server/src/controllers/api-token.mjs +4 -4
  181. package/dist/server/server/src/controllers/api-token.mjs.map +1 -1
  182. package/dist/server/server/src/controllers/authentication.js +8 -1
  183. package/dist/server/server/src/controllers/authentication.js.map +1 -1
  184. package/dist/server/server/src/controllers/authentication.mjs +8 -1
  185. package/dist/server/server/src/controllers/authentication.mjs.map +1 -1
  186. package/dist/server/server/src/controllers/formatters/conditions.js +2 -2
  187. package/dist/server/server/src/controllers/formatters/conditions.js.map +1 -1
  188. package/dist/server/server/src/controllers/formatters/conditions.mjs +2 -2
  189. package/dist/server/server/src/controllers/formatters/conditions.mjs.map +1 -1
  190. package/dist/server/server/src/controllers/transfer/index.js +2 -2
  191. package/dist/server/server/src/controllers/transfer/index.js.map +1 -1
  192. package/dist/server/server/src/controllers/transfer/index.mjs +2 -2
  193. package/dist/server/server/src/controllers/transfer/index.mjs.map +1 -1
  194. package/dist/server/server/src/controllers/transfer/token.js +8 -8
  195. package/dist/server/server/src/controllers/transfer/token.js.map +1 -1
  196. package/dist/server/server/src/controllers/transfer/token.mjs +4 -4
  197. package/dist/server/server/src/controllers/transfer/token.mjs.map +1 -1
  198. package/dist/server/server/src/controllers/webhooks.js +26 -0
  199. package/dist/server/server/src/controllers/webhooks.js.map +1 -1
  200. package/dist/server/server/src/controllers/webhooks.mjs +27 -1
  201. package/dist/server/server/src/controllers/webhooks.mjs.map +1 -1
  202. package/dist/server/server/src/domain/action/index.js +18 -16
  203. package/dist/server/server/src/domain/action/index.js.map +1 -1
  204. package/dist/server/server/src/domain/action/index.mjs +16 -14
  205. package/dist/server/server/src/domain/action/index.mjs.map +1 -1
  206. package/dist/server/server/src/domain/action/provider.mjs +4 -4
  207. package/dist/server/server/src/domain/action/provider.mjs.map +1 -1
  208. package/dist/server/server/src/domain/condition/index.js +7 -4
  209. package/dist/server/server/src/domain/condition/index.js.map +1 -1
  210. package/dist/server/server/src/domain/condition/index.mjs +7 -4
  211. package/dist/server/server/src/domain/condition/index.mjs.map +1 -1
  212. package/dist/server/server/src/domain/permission/index.js +24 -15
  213. package/dist/server/server/src/domain/permission/index.js.map +1 -1
  214. package/dist/server/server/src/domain/permission/index.mjs +21 -12
  215. package/dist/server/server/src/domain/permission/index.mjs.map +1 -1
  216. package/dist/server/server/src/middlewares/rateLimit.js +5 -5
  217. package/dist/server/server/src/middlewares/rateLimit.js.map +1 -1
  218. package/dist/server/server/src/middlewares/rateLimit.mjs +4 -4
  219. package/dist/server/server/src/middlewares/rateLimit.mjs.map +1 -1
  220. package/dist/server/server/src/register.js +6 -0
  221. package/dist/server/server/src/register.js.map +1 -1
  222. package/dist/server/server/src/register.mjs +6 -0
  223. package/dist/server/server/src/register.mjs.map +1 -1
  224. package/dist/server/server/src/services/action.js +1 -2
  225. package/dist/server/server/src/services/action.js.map +1 -1
  226. package/dist/server/server/src/services/action.mjs +1 -2
  227. package/dist/server/server/src/services/action.mjs.map +1 -1
  228. package/dist/server/server/src/services/api-token.js +61 -49
  229. package/dist/server/server/src/services/api-token.js.map +1 -1
  230. package/dist/server/server/src/services/api-token.mjs +53 -41
  231. package/dist/server/server/src/services/api-token.mjs.map +1 -1
  232. package/dist/server/server/src/services/auth.js +27 -6
  233. package/dist/server/server/src/services/auth.js.map +1 -1
  234. package/dist/server/server/src/services/auth.mjs +28 -8
  235. package/dist/server/server/src/services/auth.mjs.map +1 -1
  236. package/dist/server/server/src/services/condition.js +2 -2
  237. package/dist/server/server/src/services/condition.js.map +1 -1
  238. package/dist/server/server/src/services/condition.mjs +1 -1
  239. package/dist/server/server/src/services/condition.mjs.map +1 -1
  240. package/dist/server/server/src/services/content-type.js +5 -4
  241. package/dist/server/server/src/services/content-type.js.map +1 -1
  242. package/dist/server/server/src/services/content-type.mjs +8 -7
  243. package/dist/server/server/src/services/content-type.mjs.map +1 -1
  244. package/dist/server/server/src/services/homepage.js +2 -1
  245. package/dist/server/server/src/services/homepage.js.map +1 -1
  246. package/dist/server/server/src/services/homepage.mjs +2 -1
  247. package/dist/server/server/src/services/homepage.mjs.map +1 -1
  248. package/dist/server/server/src/services/passport/local-strategy.js +2 -2
  249. package/dist/server/server/src/services/passport/local-strategy.js.map +1 -1
  250. package/dist/server/server/src/services/passport/local-strategy.mjs +1 -1
  251. package/dist/server/server/src/services/passport/local-strategy.mjs.map +1 -1
  252. package/dist/server/server/src/services/passport.js +1 -2
  253. package/dist/server/server/src/services/passport.js.map +1 -1
  254. package/dist/server/server/src/services/passport.mjs +1 -2
  255. package/dist/server/server/src/services/passport.mjs.map +1 -1
  256. package/dist/server/server/src/services/permission/engine.js +4 -4
  257. package/dist/server/server/src/services/permission/engine.js.map +1 -1
  258. package/dist/server/server/src/services/permission/engine.mjs +2 -2
  259. package/dist/server/server/src/services/permission/engine.mjs.map +1 -1
  260. package/dist/server/server/src/services/permission/permissions-manager/index.js +2 -3
  261. package/dist/server/server/src/services/permission/permissions-manager/index.js.map +1 -1
  262. package/dist/server/server/src/services/permission/permissions-manager/index.mjs +1 -2
  263. package/dist/server/server/src/services/permission/permissions-manager/index.mjs.map +1 -1
  264. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.js +6 -6
  265. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.js.map +1 -1
  266. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.mjs +4 -4
  267. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.mjs.map +1 -1
  268. package/dist/server/server/src/services/permission/permissions-manager/sanitize.js +47 -41
  269. package/dist/server/server/src/services/permission/permissions-manager/sanitize.js.map +1 -1
  270. package/dist/server/server/src/services/permission/permissions-manager/sanitize.mjs +44 -38
  271. package/dist/server/server/src/services/permission/permissions-manager/sanitize.mjs.map +1 -1
  272. package/dist/server/server/src/services/permission/permissions-manager/validate.js +30 -26
  273. package/dist/server/server/src/services/permission/permissions-manager/validate.js.map +1 -1
  274. package/dist/server/server/src/services/permission/permissions-manager/validate.mjs +28 -24
  275. package/dist/server/server/src/services/permission/permissions-manager/validate.mjs.map +1 -1
  276. package/dist/server/server/src/services/permission/queries.js +9 -9
  277. package/dist/server/server/src/services/permission/queries.js.map +1 -1
  278. package/dist/server/server/src/services/permission/queries.mjs +9 -9
  279. package/dist/server/server/src/services/permission/queries.mjs.map +1 -1
  280. package/dist/server/server/src/services/permission/rename-fields.js +118 -0
  281. package/dist/server/server/src/services/permission/rename-fields.js.map +1 -0
  282. package/dist/server/server/src/services/permission/rename-fields.mjs +116 -0
  283. package/dist/server/server/src/services/permission/rename-fields.mjs.map +1 -0
  284. package/dist/server/server/src/services/permission/sections-builder/index.js +2 -2
  285. package/dist/server/server/src/services/permission/sections-builder/index.js.map +1 -1
  286. package/dist/server/server/src/services/permission/sections-builder/index.mjs +2 -2
  287. package/dist/server/server/src/services/permission/sections-builder/index.mjs.map +1 -1
  288. package/dist/server/server/src/services/permission/sections-builder/section.js +1 -2
  289. package/dist/server/server/src/services/permission/sections-builder/section.js.map +1 -1
  290. package/dist/server/server/src/services/permission/sections-builder/section.mjs +1 -2
  291. package/dist/server/server/src/services/permission/sections-builder/section.mjs.map +1 -1
  292. package/dist/server/server/src/services/permission/sections-builder/utils.js +6 -6
  293. package/dist/server/server/src/services/permission/sections-builder/utils.js.map +1 -1
  294. package/dist/server/server/src/services/permission/sections-builder/utils.mjs +4 -4
  295. package/dist/server/server/src/services/permission/sections-builder/utils.mjs.map +1 -1
  296. package/dist/server/server/src/services/role.js +20 -19
  297. package/dist/server/server/src/services/role.js.map +1 -1
  298. package/dist/server/server/src/services/role.mjs +20 -19
  299. package/dist/server/server/src/services/role.mjs.map +1 -1
  300. package/dist/server/server/src/services/transfer/token.js +20 -16
  301. package/dist/server/server/src/services/transfer/token.js.map +1 -1
  302. package/dist/server/server/src/services/transfer/token.mjs +14 -10
  303. package/dist/server/server/src/services/transfer/token.mjs.map +1 -1
  304. package/dist/server/server/src/services/user.js +50 -12
  305. package/dist/server/server/src/services/user.js.map +1 -1
  306. package/dist/server/server/src/services/user.mjs +52 -14
  307. package/dist/server/server/src/services/user.mjs.map +1 -1
  308. package/dist/server/server/src/strategies/api-token-utils.js +2 -3
  309. package/dist/server/server/src/strategies/api-token-utils.js.map +1 -1
  310. package/dist/server/server/src/strategies/api-token-utils.mjs +2 -3
  311. package/dist/server/server/src/strategies/api-token-utils.mjs.map +1 -1
  312. package/dist/server/server/src/strategies/content-api-token.js +3 -3
  313. package/dist/server/server/src/strategies/content-api-token.js.map +1 -1
  314. package/dist/server/server/src/strategies/content-api-token.mjs +1 -1
  315. package/dist/server/server/src/strategies/content-api-token.mjs.map +1 -1
  316. package/dist/server/server/src/strategies/data-transfer.js +4 -4
  317. package/dist/server/server/src/strategies/data-transfer.js.map +1 -1
  318. package/dist/server/server/src/strategies/data-transfer.mjs +3 -3
  319. package/dist/server/server/src/strategies/data-transfer.mjs.map +1 -1
  320. package/dist/server/server/src/validation/common-validators.js +9 -10
  321. package/dist/server/server/src/validation/common-validators.js.map +1 -1
  322. package/dist/server/server/src/validation/common-validators.mjs +13 -14
  323. package/dist/server/server/src/validation/common-validators.mjs.map +1 -1
  324. package/dist/server/server/src/validation/user.js +1 -2
  325. package/dist/server/server/src/validation/user.js.map +1 -1
  326. package/dist/server/server/src/validation/user.mjs +1 -2
  327. package/dist/server/server/src/validation/user.mjs.map +1 -1
  328. package/dist/server/src/audit-logs/admin-users.d.ts +119 -0
  329. package/dist/server/src/audit-logs/admin-users.d.ts.map +1 -0
  330. package/dist/server/src/audit-logs/tokens.d.ts.map +1 -1
  331. package/dist/server/src/audit-logs/webhooks.d.ts +59 -0
  332. package/dist/server/src/audit-logs/webhooks.d.ts.map +1 -0
  333. package/dist/server/src/bootstrap.d.ts.map +1 -1
  334. package/dist/server/src/controllers/admin-token.d.ts.map +1 -1
  335. package/dist/server/src/controllers/admin.d.ts +2 -11
  336. package/dist/server/src/controllers/admin.d.ts.map +1 -1
  337. package/dist/server/src/controllers/api-token.d.ts.map +1 -1
  338. package/dist/server/src/controllers/authentication.d.ts.map +1 -1
  339. package/dist/server/src/controllers/formatters/conditions.d.ts +1 -1
  340. package/dist/server/src/controllers/formatters/conditions.d.ts.map +1 -1
  341. package/dist/server/src/controllers/homepage.d.ts +1 -1
  342. package/dist/server/src/controllers/index.d.ts +2 -11
  343. package/dist/server/src/controllers/index.d.ts.map +1 -1
  344. package/dist/server/src/controllers/transfer/index.d.ts.map +1 -1
  345. package/dist/server/src/controllers/transfer/token.d.ts.map +1 -1
  346. package/dist/server/src/controllers/webhooks.d.ts.map +1 -1
  347. package/dist/server/src/domain/action/index.d.ts +1 -0
  348. package/dist/server/src/domain/action/index.d.ts.map +1 -1
  349. package/dist/server/src/domain/condition/index.d.ts +2 -2
  350. package/dist/server/src/domain/condition/index.d.ts.map +1 -1
  351. package/dist/server/src/domain/permission/index.d.ts.map +1 -1
  352. package/dist/server/src/domain/user.d.ts +2 -2
  353. package/dist/server/src/index.d.ts +4 -13
  354. package/dist/server/src/index.d.ts.map +1 -1
  355. package/dist/server/src/middlewares/index.d.ts.map +1 -1
  356. package/dist/server/src/middlewares/rateLimit.d.ts.map +1 -1
  357. package/dist/server/src/register.d.ts.map +1 -1
  358. package/dist/server/src/services/action.d.ts.map +1 -1
  359. package/dist/server/src/services/api-token.d.ts.map +1 -1
  360. package/dist/server/src/services/auth.d.ts +6 -1
  361. package/dist/server/src/services/auth.d.ts.map +1 -1
  362. package/dist/server/src/services/condition.d.ts.map +1 -1
  363. package/dist/server/src/services/content-type.d.ts.map +1 -1
  364. package/dist/server/src/services/homepage.d.ts +1 -1
  365. package/dist/server/src/services/homepage.d.ts.map +1 -1
  366. package/dist/server/src/services/index.d.ts +2 -2
  367. package/dist/server/src/services/index.d.ts.map +1 -1
  368. package/dist/server/src/services/passport/local-strategy.d.ts.map +1 -1
  369. package/dist/server/src/services/passport.d.ts.map +1 -1
  370. package/dist/server/src/services/permission/engine.d.ts.map +1 -1
  371. package/dist/server/src/services/permission/permissions-manager/permission-fields.d.ts.map +1 -1
  372. package/dist/server/src/services/permission/permissions-manager/sanitize.d.ts.map +1 -1
  373. package/dist/server/src/services/permission/permissions-manager/validate.d.ts.map +1 -1
  374. package/dist/server/src/services/permission/queries.d.ts.map +1 -1
  375. package/dist/server/src/services/permission/rename-fields.d.ts +21 -0
  376. package/dist/server/src/services/permission/rename-fields.d.ts.map +1 -0
  377. package/dist/server/src/services/permission/sections-builder/section.d.ts.map +1 -1
  378. package/dist/server/src/services/permission/sections-builder/utils.d.ts +1 -1
  379. package/dist/server/src/services/permission/sections-builder/utils.d.ts.map +1 -1
  380. package/dist/server/src/services/role.d.ts +1 -1
  381. package/dist/server/src/services/role.d.ts.map +1 -1
  382. package/dist/server/src/services/transfer/token.d.ts.map +1 -1
  383. package/dist/server/src/services/user.d.ts.map +1 -1
  384. package/dist/server/src/strategies/content-api-token.d.ts.map +1 -1
  385. package/dist/server/src/validation/user.d.ts.map +1 -1
  386. package/dist/shared/contracts/admin.d.ts +36 -2
  387. package/dist/shared/contracts/admin.d.ts.map +1 -1
  388. package/package.json +13 -13
@@ -1,5 +1,5 @@
1
+ import { defaults, intersection, get, omit, isObject, isEmpty } from 'lodash';
1
2
  import { subject } from '@casl/ability';
2
- import { omit, isArray, defaults, intersection, uniq, getOr, isObject, isEmpty } from 'lodash/fp';
3
3
  import { errors, validate, contentTypes, createModelCache, async, traverseEntity, traverse } from '@strapi/utils';
4
4
  import { createPermissionFieldsCache } from './permission-fields.mjs';
5
5
  import { ADMIN_USER_ALLOWED_FIELDS } from '../../../domain/user.mjs';
@@ -100,7 +100,7 @@ var createValidateHelpers = (({ action, ability, model })=>{
100
100
  // TODO
101
101
  // @ts-expect-error define the correct return type
102
102
  const wrappedValidate = async (data, options = {})=>{
103
- if (isArray(data)) {
103
+ if (Array.isArray(data)) {
104
104
  return Promise.all(data.map((entity)=>wrappedValidate(entity, options)));
105
105
  }
106
106
  const { subject, action: actionOverride } = getDefaultOptions(data, options);
@@ -119,26 +119,26 @@ var createValidateHelpers = (({ action, ability, model })=>{
119
119
  return wrappedValidate;
120
120
  };
121
121
  const getDefaultOptions = (data, options)=>{
122
- return defaults({
122
+ return defaults({}, options, {
123
123
  subject: subject(model, data),
124
124
  action
125
- }, options);
125
+ });
126
126
  };
127
127
  /**
128
128
  * Omit creator fields' (createdBy & updatedBy) roles from the admin API responses
129
- */ const omitCreatorRoles = omit([
130
- `${CREATED_BY_ATTRIBUTE}.roles`,
131
- `${UPDATED_BY_ATTRIBUTE}.roles`
132
- ]);
129
+ */ const omitCreatorRoles = (data)=>omit(data, [
130
+ `${CREATED_BY_ATTRIBUTE}.roles`,
131
+ `${UPDATED_BY_ATTRIBUTE}.roles`
132
+ ]);
133
133
  /**
134
134
  * Visitor used to remove hidden fields from the admin API responses
135
135
  */ const throwHiddenFields = ({ key, schema, path })=>{
136
- const isHidden = getOr(false, [
136
+ const isHidden = get(schema, [
137
137
  'config',
138
138
  'attributes',
139
139
  key,
140
140
  'hidden'
141
- ], schema);
141
+ ], false);
142
142
  if (isHidden) {
143
143
  throwInvalidKey({
144
144
  key,
@@ -159,22 +159,26 @@ var createValidateHelpers = (({ action, ability, model })=>{
159
159
  const getInputFields = (fields = [])=>{
160
160
  const nonVisibleAttributes = getNonVisibleAttributes(schema);
161
161
  const writableAttributes = getWritableAttributes(schema);
162
- const nonVisibleWritableAttributes = intersection(nonVisibleAttributes, writableAttributes);
163
- return uniq([
164
- ...fields,
165
- ...COMPONENT_FIELDS,
166
- ...nonVisibleWritableAttributes
167
- ]);
162
+ const nonVisibleWritableAttributes = intersection(writableAttributes, nonVisibleAttributes);
163
+ return [
164
+ ...new Set([
165
+ ...fields,
166
+ ...COMPONENT_FIELDS,
167
+ ...nonVisibleWritableAttributes
168
+ ])
169
+ ];
168
170
  };
169
171
  const getQueryFields = (fields = [])=>{
170
- return uniq([
171
- ...fields,
172
- ...STATIC_FIELDS,
173
- ...COMPONENT_FIELDS,
174
- CREATED_AT_ATTRIBUTE,
175
- UPDATED_AT_ATTRIBUTE,
176
- PUBLISHED_AT_ATTRIBUTE
177
- ]);
172
+ return [
173
+ ...new Set([
174
+ ...fields,
175
+ ...STATIC_FIELDS,
176
+ ...COMPONENT_FIELDS,
177
+ CREATED_AT_ATTRIBUTE,
178
+ UPDATED_AT_ATTRIBUTE,
179
+ PUBLISHED_AT_ATTRIBUTE
180
+ ])
181
+ ];
178
182
  };
179
183
  return {
180
184
  validateQuery: wrapValidate(createValidateQuery),
@@ -1 +1 @@
1
- {"version":3,"file":"validate.mjs","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 createValidateFilters = (ctx: any) =>\n 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 createValidateSort = (ctx: any) =>\n 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 createValidateFields = (ctx: any) =>\n async.pipe(\n traverse.traverseQueryFields(throwDisallowedFields(permittedFields), ctx),\n traverse.traverseQueryFields(throwPassword, ctx)\n );\n\n const validateFilters = createValidateFilters(ctx);\n const validateSort = createValidateSort(ctx);\n const validateFields = createValidateFields(ctx);\n\n const validateNestedPopulate = async ({ key, value, schema, attribute, getModel }: any) => {\n if (attribute) {\n return;\n }\n\n const nestedCtx = { schema, getModel };\n\n if (key === 'sort') {\n await createValidateSort(nestedCtx)(value);\n }\n\n if (key === 'filters') {\n await createValidateFilters(nestedCtx)(value);\n }\n\n if (key === 'fields') {\n await createValidateFields(nestedCtx)(value);\n }\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 traverse.traverseQueryPopulate(validateNestedPopulate, 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","createValidateFilters","async","pipe","traverse","traverseQueryFilters","throwDisallowedAdminUserFields","value","isObject","isEmpty","attribute","createValidateSort","traverseQuerySort","createValidateFields","traverseQueryFields","validateFilters","validateSort","validateFields","validateNestedPopulate","nestedCtx","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
+ {"version":3,"file":"validate.mjs","sources":["../../../../../../../server/src/services/permission/permissions-manager/validate.ts"],"sourcesContent":["import { omit, defaults, isEmpty, intersection, get, isObject } from 'lodash';\nimport { subject as asSubject } from '@casl/ability';\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 createValidateFilters = (ctx: any) =>\n 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 createValidateSort = (ctx: any) =>\n 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 createValidateFields = (ctx: any) =>\n async.pipe(\n traverse.traverseQueryFields(throwDisallowedFields(permittedFields), ctx),\n traverse.traverseQueryFields(throwPassword, ctx)\n );\n\n const validateFilters = createValidateFilters(ctx);\n const validateSort = createValidateSort(ctx);\n const validateFields = createValidateFields(ctx);\n\n const validateNestedPopulate = async ({ key, value, schema, attribute, getModel }: any) => {\n if (attribute) {\n return;\n }\n\n const nestedCtx = { schema, getModel };\n\n if (key === 'sort') {\n await createValidateSort(nestedCtx)(value);\n }\n\n if (key === 'filters') {\n await createValidateFilters(nestedCtx)(value);\n }\n\n if (key === 'fields') {\n await createValidateFields(nestedCtx)(value);\n }\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 traverse.traverseQueryPopulate(validateNestedPopulate, 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 (Array.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({}, options, { subject: asSubject(model, data), action });\n };\n\n /**\n * Omit creator fields' (createdBy & updatedBy) roles from the admin API responses\n */\n const omitCreatorRoles = <T extends object>(data: T) =>\n omit(data, [`${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 = get(schema, ['config', 'attributes', key, 'hidden'], false);\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(writableAttributes, nonVisibleAttributes);\n\n return [...new Set([...fields, ...COMPONENT_FIELDS, ...nonVisibleWritableAttributes])];\n };\n\n const getQueryFields = (fields = []) => {\n return [\n ...new Set([\n ...fields,\n ...STATIC_FIELDS,\n ...COMPONENT_FIELDS,\n CREATED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n PUBLISHED_AT_ATTRIBUTE,\n ]),\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","createValidateFilters","async","pipe","traverse","traverseQueryFilters","throwDisallowedAdminUserFields","value","isObject","isEmpty","attribute","createValidateSort","traverseQuerySort","createValidateFields","traverseQueryFields","validateFilters","validateSort","validateFields","validateNestedPopulate","nestedCtx","validatePopulate","traverseQueryPopulate","throwHiddenFields","query","filters","sort","populate","createValidateInput","getInputFields","traverseEntity","omitCreatorRoles","wrapValidate","createValidateFunction","getPermissionFields","createPermissionFieldsCache","wrappedValidate","data","Array","isArray","Promise","all","map","entity","subject","actionOverride","getDefaultOptions","hasAtLeastOneRegistered","validateOptions","validateFunction","defaults","asSubject","omit","isHidden","get","uid","ADMIN_USER_ALLOWED_FIELDS","includes","nonVisibleAttributes","writableAttributes","nonVisibleWritableAttributes","intersection","Set","validateQuery","validateInput"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var fp = require('lodash/fp');
3
+ var _ = require('lodash');
4
4
  var pmap = require('p-map');
5
5
  var index = require('../../utils/index.js');
6
6
  var index$1 = require('../../domain/permission/index.js');
@@ -24,7 +24,7 @@ var pmap__default = /*#__PURE__*/_interopDefault(pmap);
24
24
  }
25
25
  });
26
26
  if (permissionsToDelete.length > 0) {
27
- await deleteByIds(permissionsToDelete.map(fp.prop('id')));
27
+ await deleteByIds(permissionsToDelete.map((permission)=>permission?.id));
28
28
  }
29
29
  };
30
30
  /**
@@ -105,13 +105,13 @@ const filterPermissionsToRemove = async (permissions)=>{
105
105
  const { applyToProperties } = options;
106
106
  const invalidProperties = await Promise.all((applyToProperties || []).map(async (property)=>{
107
107
  const applies = await actionProvider.appliesToProperty(property, permission.action, permission.subject);
108
- return applies && fp.isNil(index$1.default.getProperty(property, permission));
108
+ return applies && index$1.default.getProperty(property, permission) == null;
109
109
  }));
110
110
  const isRegisteredAction = actionProvider.has(permission.action);
111
- const hasInvalidProperties = fp.isArray(applyToProperties) && invalidProperties.every(fp.eq(true));
112
- const isInvalidSubject = fp.isArray(subjects) && !subjects.includes(permission.subject);
111
+ const hasInvalidProperties = Array.isArray(applyToProperties) && invalidProperties.every((result)=>result === true);
112
+ const isInvalidSubject = Array.isArray(subjects) && !subjects.includes(permission.subject);
113
113
  // On an api token permission, nil properties mean "everything", not "invalid"
114
- const hasApiToken = !fp.isNil(fp.prop('apiToken', permission));
114
+ const hasApiToken = _.get(permission, 'apiToken') != null;
115
115
  // If the permission has an invalid action, an invalid subject or invalid properties, then add it to the toBeRemoved collection
116
116
  if (!isRegisteredAction || isInvalidSubject || hasInvalidProperties && !hasApiToken) {
117
117
  permissionsToRemove.push(permission);
@@ -148,9 +148,9 @@ const filterPermissionsToRemove = async (permissions)=>{
148
148
  const remainingPermissions = permissions.filter((permission)=>!permissionsIdToRemove.includes(permission.id));
149
149
  const permissionsWithCleanFields = contentTypeService.cleanPermissionFields(remainingPermissions);
150
150
  // Update only the ones that need to be updated
151
- const permissionsNeedingToBeUpdated = fp.differenceWith((a, b)=>{
152
- return a.id === b.id && fp.xor(a.properties.fields, b.properties.fields).length === 0;
153
- }, permissionsWithCleanFields, remainingPermissions);
151
+ const permissionsNeedingToBeUpdated = _.differenceWith(permissionsWithCleanFields, remainingPermissions, (a, b)=>{
152
+ return a.id === b.id && _.xor(b.properties.fields, a.properties.fields).length === 0;
153
+ });
154
154
  const updatePromiseProvider = (permission)=>{
155
155
  return update({
156
156
  id: permission.id
@@ -1 +1 @@
1
- {"version":3,"file":"queries.js","sources":["../../../../../../server/src/services/permission/queries.ts"],"sourcesContent":["import { isNil, isArray, prop, xor, eq, differenceWith } from 'lodash/fp';\nimport pmap from 'p-map';\nimport type { Data } from '@strapi/types';\nimport { getService } from '../../utils';\nimport permissionDomain, { CreatePermissionPayload } from '../../domain/permission';\nimport type { AdminUser, Permission } from '../../../../shared/contracts/shared';\nimport { Action } from '../../domain/action';\n\n/**\n * Delete permissions of roles in database\n * @param rolesIds ids of roles\n */\nexport const deleteByRolesIds = async (rolesIds: Data.ID[]): Promise<void> => {\n const permissionsToDelete = await strapi.db.query('admin::permission').findMany({\n select: ['id'],\n where: {\n role: { id: rolesIds },\n },\n });\n\n if (permissionsToDelete.length > 0) {\n await deleteByIds(permissionsToDelete.map(prop('id')));\n }\n};\n\n/**\n * Delete permissions\n * @param ids ids of permissions\n */\nexport const deleteByIds = async (ids: Data.ID[]): Promise<void> => {\n const result: unknown[] = [];\n for (const id of ids) {\n const queryResult = await strapi.db.query('admin::permission').delete({ where: { id } });\n result.push(queryResult);\n }\n strapi.eventHub.emit('permission.delete', { permissions: result });\n};\n\n/**\n * Create many permissions\n * @param permissions\n */\nexport const createMany = async (permissions: CreatePermissionPayload[]): Promise<Permission[]> => {\n const createdPermissions: CreatePermissionPayload[] = [];\n for (const permission of permissions) {\n const newPerm = await strapi.db.query('admin::permission').create({ data: permission });\n createdPermissions.push(newPerm);\n }\n\n const permissionsToReturn = permissionDomain.toPermission(createdPermissions);\n strapi.eventHub.emit('permission.create', { permissions: permissionsToReturn });\n\n return permissionsToReturn;\n};\n\n/**\n * Update a permission\n * @param params\n * @param attributes\n */\nconst update = async (params: unknown, attributes: Partial<Permission>) => {\n const updatedPermission = (await strapi.db\n .query('admin::permission')\n .update({ where: params, data: attributes })) as Permission;\n\n const permissionToReturn = permissionDomain.toPermission(updatedPermission);\n strapi.eventHub.emit('permission.update', { permissions: permissionToReturn });\n\n return permissionToReturn;\n};\n\n/**\n * Find assigned permissions in the database\n * @param params query params to find the permissions\n */\nexport const findMany = async (params = {}): Promise<Permission[]> => {\n const rawPermissions = await strapi.db.query('admin::permission').findMany(params);\n\n return permissionDomain.toPermission(rawPermissions);\n};\n\n/**\n * Find all permissions for a user\n * @param user - user\n */\nexport const findUserPermissions = async (user: AdminUser): Promise<Permission[]> => {\n return findMany({ where: { role: { users: { id: user.id } } } });\n};\n\nconst filterPermissionsToRemove = async (permissions: Permission[]) => {\n const { actionProvider } = getService('permission');\n\n const permissionsToRemove: Permission[] = [];\n\n for (const permission of permissions) {\n const { subjects, options = {} as Action['options'] } =\n (actionProvider.get(permission.action) as Action) || {};\n const { applyToProperties } = options;\n\n const invalidProperties = await Promise.all(\n (applyToProperties || []).map(async (property) => {\n const applies = await actionProvider.appliesToProperty(\n property,\n permission.action,\n permission.subject\n );\n\n return applies && isNil(permissionDomain.getProperty(property, permission));\n })\n );\n\n const isRegisteredAction = actionProvider.has(permission.action);\n const hasInvalidProperties = isArray(applyToProperties) && invalidProperties.every(eq(true));\n const isInvalidSubject = isArray(subjects) && !subjects.includes(permission.subject as string);\n // On an api token permission, nil properties mean \"everything\", not \"invalid\"\n const hasApiToken = !isNil(prop('apiToken', permission));\n\n // If the permission has an invalid action, an invalid subject or invalid properties, then add it to the toBeRemoved collection\n if (!isRegisteredAction || isInvalidSubject || (hasInvalidProperties && !hasApiToken)) {\n permissionsToRemove.push(permission);\n }\n }\n\n return permissionsToRemove;\n};\n\n/**\n * Removes permissions in database that don't exist anymore\n */\nexport const cleanPermissionsInDatabase = async (): Promise<void> => {\n const pageSize = 200;\n\n const contentTypeService = getService('content-type');\n\n const total = await strapi.db.query('admin::permission').count();\n const pageCount = Math.ceil(total / pageSize);\n\n for (let page = 0; page < pageCount; page += 1) {\n // 1. Find invalid permissions and collect their ID to delete them later\n const results = (await strapi.db.query('admin::permission').findMany({\n limit: pageSize,\n offset: page * pageSize,\n populate: ['role', 'apiToken'],\n })) as Permission[];\n\n const permissions = permissionDomain.toPermission(results);\n const permissionsToRemove = await filterPermissionsToRemove(permissions);\n\n // Also remove orphaned permissions (no role AND no apiToken)\n const orphanedPermissions = permissions.filter(\n (permission: any) => !permission.role && !permission.apiToken\n );\n\n const permissionsIdToRemove = Array.from(\n new Set([...permissionsToRemove, ...orphanedPermissions].map((p) => p.id))\n );\n\n // 2. Clean permissions' fields (add required ones, remove the non-existing ones)\n const remainingPermissions = permissions.filter(\n (permission: Permission) => !permissionsIdToRemove.includes(permission.id)\n );\n\n const permissionsWithCleanFields = contentTypeService.cleanPermissionFields(\n remainingPermissions\n ) as Permission[];\n\n // Update only the ones that need to be updated\n const permissionsNeedingToBeUpdated = differenceWith(\n (a: Permission, b: Permission) => {\n return a.id === b.id && xor(a.properties.fields, b.properties.fields).length === 0;\n },\n permissionsWithCleanFields,\n remainingPermissions\n );\n\n const updatePromiseProvider = (permission: Permission) => {\n return update({ id: permission.id }, permission);\n };\n\n // Execute all the queries, update the database\n await Promise.all([\n deleteByIds(permissionsIdToRemove),\n pmap(permissionsNeedingToBeUpdated, updatePromiseProvider, {\n concurrency: 100,\n stopOnError: true,\n }),\n ]);\n }\n};\n\nexport default {\n createMany,\n findMany,\n deleteByRolesIds,\n deleteByIds,\n findUserPermissions,\n cleanPermissionsInDatabase,\n};\n"],"names":["deleteByRolesIds","rolesIds","permissionsToDelete","strapi","db","query","findMany","select","where","role","id","length","deleteByIds","map","prop","ids","result","queryResult","delete","push","eventHub","emit","permissions","createMany","createdPermissions","permission","newPerm","create","data","permissionsToReturn","permissionDomain","toPermission","update","params","attributes","updatedPermission","permissionToReturn","rawPermissions","findUserPermissions","user","users","filterPermissionsToRemove","actionProvider","getService","permissionsToRemove","subjects","options","get","action","applyToProperties","invalidProperties","Promise","all","property","applies","appliesToProperty","subject","isNil","getProperty","isRegisteredAction","has","hasInvalidProperties","isArray","every","eq","isInvalidSubject","includes","hasApiToken","cleanPermissionsInDatabase","pageSize","contentTypeService","total","count","pageCount","Math","ceil","page","results","limit","offset","populate","orphanedPermissions","filter","apiToken","permissionsIdToRemove","Array","from","Set","p","remainingPermissions","permissionsWithCleanFields","cleanPermissionFields","permissionsNeedingToBeUpdated","differenceWith","a","b","xor","properties","fields","updatePromiseProvider","pmap","concurrency","stopOnError"],"mappings":"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"}
1
+ {"version":3,"file":"queries.js","sources":["../../../../../../server/src/services/permission/queries.ts"],"sourcesContent":["import { get, xor, differenceWith } from 'lodash';\n\nimport pmap from 'p-map';\nimport type { Data } from '@strapi/types';\nimport { getService } from '../../utils';\nimport permissionDomain, { CreatePermissionPayload } from '../../domain/permission';\nimport type { AdminUser, Permission } from '../../../../shared/contracts/shared';\nimport { Action } from '../../domain/action';\n\n/**\n * Delete permissions of roles in database\n * @param rolesIds ids of roles\n */\nexport const deleteByRolesIds = async (rolesIds: Data.ID[]): Promise<void> => {\n const permissionsToDelete = await strapi.db.query('admin::permission').findMany({\n select: ['id'],\n where: {\n role: { id: rolesIds },\n },\n });\n\n if (permissionsToDelete.length > 0) {\n await deleteByIds(permissionsToDelete.map((permission) => permission?.id));\n }\n};\n\n/**\n * Delete permissions\n * @param ids ids of permissions\n */\nexport const deleteByIds = async (ids: Data.ID[]): Promise<void> => {\n const result: unknown[] = [];\n for (const id of ids) {\n const queryResult = await strapi.db.query('admin::permission').delete({ where: { id } });\n result.push(queryResult);\n }\n strapi.eventHub.emit('permission.delete', { permissions: result });\n};\n\n/**\n * Create many permissions\n * @param permissions\n */\nexport const createMany = async (permissions: CreatePermissionPayload[]): Promise<Permission[]> => {\n const createdPermissions: CreatePermissionPayload[] = [];\n for (const permission of permissions) {\n const newPerm = await strapi.db.query('admin::permission').create({ data: permission });\n createdPermissions.push(newPerm);\n }\n\n const permissionsToReturn = permissionDomain.toPermission(createdPermissions);\n strapi.eventHub.emit('permission.create', { permissions: permissionsToReturn });\n\n return permissionsToReturn;\n};\n\n/**\n * Update a permission\n * @param params\n * @param attributes\n */\nconst update = async (params: unknown, attributes: Partial<Permission>) => {\n const updatedPermission = (await strapi.db\n .query('admin::permission')\n .update({ where: params, data: attributes })) as Permission;\n\n const permissionToReturn = permissionDomain.toPermission(updatedPermission);\n strapi.eventHub.emit('permission.update', { permissions: permissionToReturn });\n\n return permissionToReturn;\n};\n\n/**\n * Find assigned permissions in the database\n * @param params query params to find the permissions\n */\nexport const findMany = async (params = {}): Promise<Permission[]> => {\n const rawPermissions = await strapi.db.query('admin::permission').findMany(params);\n\n return permissionDomain.toPermission(rawPermissions);\n};\n\n/**\n * Find all permissions for a user\n * @param user - user\n */\nexport const findUserPermissions = async (user: AdminUser): Promise<Permission[]> => {\n return findMany({ where: { role: { users: { id: user.id } } } });\n};\n\nconst filterPermissionsToRemove = async (permissions: Permission[]) => {\n const { actionProvider } = getService('permission');\n\n const permissionsToRemove: Permission[] = [];\n\n for (const permission of permissions) {\n const { subjects, options = {} as Action['options'] } =\n (actionProvider.get(permission.action) as Action) || {};\n const { applyToProperties } = options;\n\n const invalidProperties = await Promise.all(\n (applyToProperties || []).map(async (property) => {\n const applies = await actionProvider.appliesToProperty(\n property,\n permission.action,\n permission.subject\n );\n\n return applies && permissionDomain.getProperty(property, permission) == null;\n })\n );\n\n const isRegisteredAction = actionProvider.has(permission.action);\n const hasInvalidProperties =\n Array.isArray(applyToProperties) && invalidProperties.every((result) => result === true);\n const isInvalidSubject =\n Array.isArray(subjects) && !subjects.includes(permission.subject as string);\n // On an api token permission, nil properties mean \"everything\", not \"invalid\"\n const hasApiToken = get(permission, 'apiToken') != null;\n\n // If the permission has an invalid action, an invalid subject or invalid properties, then add it to the toBeRemoved collection\n if (!isRegisteredAction || isInvalidSubject || (hasInvalidProperties && !hasApiToken)) {\n permissionsToRemove.push(permission);\n }\n }\n\n return permissionsToRemove;\n};\n\n/**\n * Removes permissions in database that don't exist anymore\n */\nexport const cleanPermissionsInDatabase = async (): Promise<void> => {\n const pageSize = 200;\n\n const contentTypeService = getService('content-type');\n\n const total = await strapi.db.query('admin::permission').count();\n const pageCount = Math.ceil(total / pageSize);\n\n for (let page = 0; page < pageCount; page += 1) {\n // 1. Find invalid permissions and collect their ID to delete them later\n const results = (await strapi.db.query('admin::permission').findMany({\n limit: pageSize,\n offset: page * pageSize,\n populate: ['role', 'apiToken'],\n })) as Permission[];\n\n const permissions = permissionDomain.toPermission(results);\n const permissionsToRemove = await filterPermissionsToRemove(permissions);\n\n // Also remove orphaned permissions (no role AND no apiToken)\n const orphanedPermissions = permissions.filter(\n (permission: any) => !permission.role && !permission.apiToken\n );\n\n const permissionsIdToRemove = Array.from(\n new Set([...permissionsToRemove, ...orphanedPermissions].map((p) => p.id))\n );\n\n // 2. Clean permissions' fields (add required ones, remove the non-existing ones)\n const remainingPermissions = permissions.filter(\n (permission: Permission) => !permissionsIdToRemove.includes(permission.id)\n );\n\n const permissionsWithCleanFields = contentTypeService.cleanPermissionFields(\n remainingPermissions\n ) as Permission[];\n\n // Update only the ones that need to be updated\n const permissionsNeedingToBeUpdated = differenceWith(\n permissionsWithCleanFields,\n remainingPermissions,\n (a: Permission, b: Permission) => {\n return a.id === b.id && xor(b.properties.fields, a.properties.fields).length === 0;\n }\n );\n\n const updatePromiseProvider = (permission: Permission) => {\n return update({ id: permission.id }, permission);\n };\n\n // Execute all the queries, update the database\n await Promise.all([\n deleteByIds(permissionsIdToRemove),\n pmap(permissionsNeedingToBeUpdated, updatePromiseProvider, {\n concurrency: 100,\n stopOnError: true,\n }),\n ]);\n }\n};\n\nexport default {\n createMany,\n findMany,\n deleteByRolesIds,\n deleteByIds,\n findUserPermissions,\n cleanPermissionsInDatabase,\n};\n"],"names":["deleteByRolesIds","rolesIds","permissionsToDelete","strapi","db","query","findMany","select","where","role","id","length","deleteByIds","map","permission","ids","result","queryResult","delete","push","eventHub","emit","permissions","createMany","createdPermissions","newPerm","create","data","permissionsToReturn","permissionDomain","toPermission","update","params","attributes","updatedPermission","permissionToReturn","rawPermissions","findUserPermissions","user","users","filterPermissionsToRemove","actionProvider","getService","permissionsToRemove","subjects","options","get","action","applyToProperties","invalidProperties","Promise","all","property","applies","appliesToProperty","subject","getProperty","isRegisteredAction","has","hasInvalidProperties","Array","isArray","every","isInvalidSubject","includes","hasApiToken","cleanPermissionsInDatabase","pageSize","contentTypeService","total","count","pageCount","Math","ceil","page","results","limit","offset","populate","orphanedPermissions","filter","apiToken","permissionsIdToRemove","from","Set","p","remainingPermissions","permissionsWithCleanFields","cleanPermissionFields","permissionsNeedingToBeUpdated","differenceWith","a","b","xor","properties","fields","updatePromiseProvider","pmap","concurrency","stopOnError"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { differenceWith, xor, prop, isNil, isArray, eq } from 'lodash/fp';
1
+ import { differenceWith, xor, get } from 'lodash';
2
2
  import pmap from 'p-map';
3
3
  import { getService } from '../../utils/index.mjs';
4
4
  import permissionDomain from '../../domain/permission/index.mjs';
@@ -18,7 +18,7 @@ import permissionDomain from '../../domain/permission/index.mjs';
18
18
  }
19
19
  });
20
20
  if (permissionsToDelete.length > 0) {
21
- await deleteByIds(permissionsToDelete.map(prop('id')));
21
+ await deleteByIds(permissionsToDelete.map((permission)=>permission?.id));
22
22
  }
23
23
  };
24
24
  /**
@@ -99,13 +99,13 @@ const filterPermissionsToRemove = async (permissions)=>{
99
99
  const { applyToProperties } = options;
100
100
  const invalidProperties = await Promise.all((applyToProperties || []).map(async (property)=>{
101
101
  const applies = await actionProvider.appliesToProperty(property, permission.action, permission.subject);
102
- return applies && isNil(permissionDomain.getProperty(property, permission));
102
+ return applies && permissionDomain.getProperty(property, permission) == null;
103
103
  }));
104
104
  const isRegisteredAction = actionProvider.has(permission.action);
105
- const hasInvalidProperties = isArray(applyToProperties) && invalidProperties.every(eq(true));
106
- const isInvalidSubject = isArray(subjects) && !subjects.includes(permission.subject);
105
+ const hasInvalidProperties = Array.isArray(applyToProperties) && invalidProperties.every((result)=>result === true);
106
+ const isInvalidSubject = Array.isArray(subjects) && !subjects.includes(permission.subject);
107
107
  // On an api token permission, nil properties mean "everything", not "invalid"
108
- const hasApiToken = !isNil(prop('apiToken', permission));
108
+ const hasApiToken = get(permission, 'apiToken') != null;
109
109
  // If the permission has an invalid action, an invalid subject or invalid properties, then add it to the toBeRemoved collection
110
110
  if (!isRegisteredAction || isInvalidSubject || hasInvalidProperties && !hasApiToken) {
111
111
  permissionsToRemove.push(permission);
@@ -142,9 +142,9 @@ const filterPermissionsToRemove = async (permissions)=>{
142
142
  const remainingPermissions = permissions.filter((permission)=>!permissionsIdToRemove.includes(permission.id));
143
143
  const permissionsWithCleanFields = contentTypeService.cleanPermissionFields(remainingPermissions);
144
144
  // Update only the ones that need to be updated
145
- const permissionsNeedingToBeUpdated = differenceWith((a, b)=>{
146
- return a.id === b.id && xor(a.properties.fields, b.properties.fields).length === 0;
147
- }, permissionsWithCleanFields, remainingPermissions);
145
+ const permissionsNeedingToBeUpdated = differenceWith(permissionsWithCleanFields, remainingPermissions, (a, b)=>{
146
+ return a.id === b.id && xor(b.properties.fields, a.properties.fields).length === 0;
147
+ });
148
148
  const updatePromiseProvider = (permission)=>{
149
149
  return update({
150
150
  id: permission.id
@@ -1 +1 @@
1
- {"version":3,"file":"queries.mjs","sources":["../../../../../../server/src/services/permission/queries.ts"],"sourcesContent":["import { isNil, isArray, prop, xor, eq, differenceWith } from 'lodash/fp';\nimport pmap from 'p-map';\nimport type { Data } from '@strapi/types';\nimport { getService } from '../../utils';\nimport permissionDomain, { CreatePermissionPayload } from '../../domain/permission';\nimport type { AdminUser, Permission } from '../../../../shared/contracts/shared';\nimport { Action } from '../../domain/action';\n\n/**\n * Delete permissions of roles in database\n * @param rolesIds ids of roles\n */\nexport const deleteByRolesIds = async (rolesIds: Data.ID[]): Promise<void> => {\n const permissionsToDelete = await strapi.db.query('admin::permission').findMany({\n select: ['id'],\n where: {\n role: { id: rolesIds },\n },\n });\n\n if (permissionsToDelete.length > 0) {\n await deleteByIds(permissionsToDelete.map(prop('id')));\n }\n};\n\n/**\n * Delete permissions\n * @param ids ids of permissions\n */\nexport const deleteByIds = async (ids: Data.ID[]): Promise<void> => {\n const result: unknown[] = [];\n for (const id of ids) {\n const queryResult = await strapi.db.query('admin::permission').delete({ where: { id } });\n result.push(queryResult);\n }\n strapi.eventHub.emit('permission.delete', { permissions: result });\n};\n\n/**\n * Create many permissions\n * @param permissions\n */\nexport const createMany = async (permissions: CreatePermissionPayload[]): Promise<Permission[]> => {\n const createdPermissions: CreatePermissionPayload[] = [];\n for (const permission of permissions) {\n const newPerm = await strapi.db.query('admin::permission').create({ data: permission });\n createdPermissions.push(newPerm);\n }\n\n const permissionsToReturn = permissionDomain.toPermission(createdPermissions);\n strapi.eventHub.emit('permission.create', { permissions: permissionsToReturn });\n\n return permissionsToReturn;\n};\n\n/**\n * Update a permission\n * @param params\n * @param attributes\n */\nconst update = async (params: unknown, attributes: Partial<Permission>) => {\n const updatedPermission = (await strapi.db\n .query('admin::permission')\n .update({ where: params, data: attributes })) as Permission;\n\n const permissionToReturn = permissionDomain.toPermission(updatedPermission);\n strapi.eventHub.emit('permission.update', { permissions: permissionToReturn });\n\n return permissionToReturn;\n};\n\n/**\n * Find assigned permissions in the database\n * @param params query params to find the permissions\n */\nexport const findMany = async (params = {}): Promise<Permission[]> => {\n const rawPermissions = await strapi.db.query('admin::permission').findMany(params);\n\n return permissionDomain.toPermission(rawPermissions);\n};\n\n/**\n * Find all permissions for a user\n * @param user - user\n */\nexport const findUserPermissions = async (user: AdminUser): Promise<Permission[]> => {\n return findMany({ where: { role: { users: { id: user.id } } } });\n};\n\nconst filterPermissionsToRemove = async (permissions: Permission[]) => {\n const { actionProvider } = getService('permission');\n\n const permissionsToRemove: Permission[] = [];\n\n for (const permission of permissions) {\n const { subjects, options = {} as Action['options'] } =\n (actionProvider.get(permission.action) as Action) || {};\n const { applyToProperties } = options;\n\n const invalidProperties = await Promise.all(\n (applyToProperties || []).map(async (property) => {\n const applies = await actionProvider.appliesToProperty(\n property,\n permission.action,\n permission.subject\n );\n\n return applies && isNil(permissionDomain.getProperty(property, permission));\n })\n );\n\n const isRegisteredAction = actionProvider.has(permission.action);\n const hasInvalidProperties = isArray(applyToProperties) && invalidProperties.every(eq(true));\n const isInvalidSubject = isArray(subjects) && !subjects.includes(permission.subject as string);\n // On an api token permission, nil properties mean \"everything\", not \"invalid\"\n const hasApiToken = !isNil(prop('apiToken', permission));\n\n // If the permission has an invalid action, an invalid subject or invalid properties, then add it to the toBeRemoved collection\n if (!isRegisteredAction || isInvalidSubject || (hasInvalidProperties && !hasApiToken)) {\n permissionsToRemove.push(permission);\n }\n }\n\n return permissionsToRemove;\n};\n\n/**\n * Removes permissions in database that don't exist anymore\n */\nexport const cleanPermissionsInDatabase = async (): Promise<void> => {\n const pageSize = 200;\n\n const contentTypeService = getService('content-type');\n\n const total = await strapi.db.query('admin::permission').count();\n const pageCount = Math.ceil(total / pageSize);\n\n for (let page = 0; page < pageCount; page += 1) {\n // 1. Find invalid permissions and collect their ID to delete them later\n const results = (await strapi.db.query('admin::permission').findMany({\n limit: pageSize,\n offset: page * pageSize,\n populate: ['role', 'apiToken'],\n })) as Permission[];\n\n const permissions = permissionDomain.toPermission(results);\n const permissionsToRemove = await filterPermissionsToRemove(permissions);\n\n // Also remove orphaned permissions (no role AND no apiToken)\n const orphanedPermissions = permissions.filter(\n (permission: any) => !permission.role && !permission.apiToken\n );\n\n const permissionsIdToRemove = Array.from(\n new Set([...permissionsToRemove, ...orphanedPermissions].map((p) => p.id))\n );\n\n // 2. Clean permissions' fields (add required ones, remove the non-existing ones)\n const remainingPermissions = permissions.filter(\n (permission: Permission) => !permissionsIdToRemove.includes(permission.id)\n );\n\n const permissionsWithCleanFields = contentTypeService.cleanPermissionFields(\n remainingPermissions\n ) as Permission[];\n\n // Update only the ones that need to be updated\n const permissionsNeedingToBeUpdated = differenceWith(\n (a: Permission, b: Permission) => {\n return a.id === b.id && xor(a.properties.fields, b.properties.fields).length === 0;\n },\n permissionsWithCleanFields,\n remainingPermissions\n );\n\n const updatePromiseProvider = (permission: Permission) => {\n return update({ id: permission.id }, permission);\n };\n\n // Execute all the queries, update the database\n await Promise.all([\n deleteByIds(permissionsIdToRemove),\n pmap(permissionsNeedingToBeUpdated, updatePromiseProvider, {\n concurrency: 100,\n stopOnError: true,\n }),\n ]);\n }\n};\n\nexport default {\n createMany,\n findMany,\n deleteByRolesIds,\n deleteByIds,\n findUserPermissions,\n cleanPermissionsInDatabase,\n};\n"],"names":["deleteByRolesIds","rolesIds","permissionsToDelete","strapi","db","query","findMany","select","where","role","id","length","deleteByIds","map","prop","ids","result","queryResult","delete","push","eventHub","emit","permissions","createMany","createdPermissions","permission","newPerm","create","data","permissionsToReturn","permissionDomain","toPermission","update","params","attributes","updatedPermission","permissionToReturn","rawPermissions","findUserPermissions","user","users","filterPermissionsToRemove","actionProvider","getService","permissionsToRemove","subjects","options","get","action","applyToProperties","invalidProperties","Promise","all","property","applies","appliesToProperty","subject","isNil","getProperty","isRegisteredAction","has","hasInvalidProperties","isArray","every","eq","isInvalidSubject","includes","hasApiToken","cleanPermissionsInDatabase","pageSize","contentTypeService","total","count","pageCount","Math","ceil","page","results","limit","offset","populate","orphanedPermissions","filter","apiToken","permissionsIdToRemove","Array","from","Set","p","remainingPermissions","permissionsWithCleanFields","cleanPermissionFields","permissionsNeedingToBeUpdated","differenceWith","a","b","xor","properties","fields","updatePromiseProvider","pmap","concurrency","stopOnError"],"mappings":"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"}
1
+ {"version":3,"file":"queries.mjs","sources":["../../../../../../server/src/services/permission/queries.ts"],"sourcesContent":["import { get, xor, differenceWith } from 'lodash';\n\nimport pmap from 'p-map';\nimport type { Data } from '@strapi/types';\nimport { getService } from '../../utils';\nimport permissionDomain, { CreatePermissionPayload } from '../../domain/permission';\nimport type { AdminUser, Permission } from '../../../../shared/contracts/shared';\nimport { Action } from '../../domain/action';\n\n/**\n * Delete permissions of roles in database\n * @param rolesIds ids of roles\n */\nexport const deleteByRolesIds = async (rolesIds: Data.ID[]): Promise<void> => {\n const permissionsToDelete = await strapi.db.query('admin::permission').findMany({\n select: ['id'],\n where: {\n role: { id: rolesIds },\n },\n });\n\n if (permissionsToDelete.length > 0) {\n await deleteByIds(permissionsToDelete.map((permission) => permission?.id));\n }\n};\n\n/**\n * Delete permissions\n * @param ids ids of permissions\n */\nexport const deleteByIds = async (ids: Data.ID[]): Promise<void> => {\n const result: unknown[] = [];\n for (const id of ids) {\n const queryResult = await strapi.db.query('admin::permission').delete({ where: { id } });\n result.push(queryResult);\n }\n strapi.eventHub.emit('permission.delete', { permissions: result });\n};\n\n/**\n * Create many permissions\n * @param permissions\n */\nexport const createMany = async (permissions: CreatePermissionPayload[]): Promise<Permission[]> => {\n const createdPermissions: CreatePermissionPayload[] = [];\n for (const permission of permissions) {\n const newPerm = await strapi.db.query('admin::permission').create({ data: permission });\n createdPermissions.push(newPerm);\n }\n\n const permissionsToReturn = permissionDomain.toPermission(createdPermissions);\n strapi.eventHub.emit('permission.create', { permissions: permissionsToReturn });\n\n return permissionsToReturn;\n};\n\n/**\n * Update a permission\n * @param params\n * @param attributes\n */\nconst update = async (params: unknown, attributes: Partial<Permission>) => {\n const updatedPermission = (await strapi.db\n .query('admin::permission')\n .update({ where: params, data: attributes })) as Permission;\n\n const permissionToReturn = permissionDomain.toPermission(updatedPermission);\n strapi.eventHub.emit('permission.update', { permissions: permissionToReturn });\n\n return permissionToReturn;\n};\n\n/**\n * Find assigned permissions in the database\n * @param params query params to find the permissions\n */\nexport const findMany = async (params = {}): Promise<Permission[]> => {\n const rawPermissions = await strapi.db.query('admin::permission').findMany(params);\n\n return permissionDomain.toPermission(rawPermissions);\n};\n\n/**\n * Find all permissions for a user\n * @param user - user\n */\nexport const findUserPermissions = async (user: AdminUser): Promise<Permission[]> => {\n return findMany({ where: { role: { users: { id: user.id } } } });\n};\n\nconst filterPermissionsToRemove = async (permissions: Permission[]) => {\n const { actionProvider } = getService('permission');\n\n const permissionsToRemove: Permission[] = [];\n\n for (const permission of permissions) {\n const { subjects, options = {} as Action['options'] } =\n (actionProvider.get(permission.action) as Action) || {};\n const { applyToProperties } = options;\n\n const invalidProperties = await Promise.all(\n (applyToProperties || []).map(async (property) => {\n const applies = await actionProvider.appliesToProperty(\n property,\n permission.action,\n permission.subject\n );\n\n return applies && permissionDomain.getProperty(property, permission) == null;\n })\n );\n\n const isRegisteredAction = actionProvider.has(permission.action);\n const hasInvalidProperties =\n Array.isArray(applyToProperties) && invalidProperties.every((result) => result === true);\n const isInvalidSubject =\n Array.isArray(subjects) && !subjects.includes(permission.subject as string);\n // On an api token permission, nil properties mean \"everything\", not \"invalid\"\n const hasApiToken = get(permission, 'apiToken') != null;\n\n // If the permission has an invalid action, an invalid subject or invalid properties, then add it to the toBeRemoved collection\n if (!isRegisteredAction || isInvalidSubject || (hasInvalidProperties && !hasApiToken)) {\n permissionsToRemove.push(permission);\n }\n }\n\n return permissionsToRemove;\n};\n\n/**\n * Removes permissions in database that don't exist anymore\n */\nexport const cleanPermissionsInDatabase = async (): Promise<void> => {\n const pageSize = 200;\n\n const contentTypeService = getService('content-type');\n\n const total = await strapi.db.query('admin::permission').count();\n const pageCount = Math.ceil(total / pageSize);\n\n for (let page = 0; page < pageCount; page += 1) {\n // 1. Find invalid permissions and collect their ID to delete them later\n const results = (await strapi.db.query('admin::permission').findMany({\n limit: pageSize,\n offset: page * pageSize,\n populate: ['role', 'apiToken'],\n })) as Permission[];\n\n const permissions = permissionDomain.toPermission(results);\n const permissionsToRemove = await filterPermissionsToRemove(permissions);\n\n // Also remove orphaned permissions (no role AND no apiToken)\n const orphanedPermissions = permissions.filter(\n (permission: any) => !permission.role && !permission.apiToken\n );\n\n const permissionsIdToRemove = Array.from(\n new Set([...permissionsToRemove, ...orphanedPermissions].map((p) => p.id))\n );\n\n // 2. Clean permissions' fields (add required ones, remove the non-existing ones)\n const remainingPermissions = permissions.filter(\n (permission: Permission) => !permissionsIdToRemove.includes(permission.id)\n );\n\n const permissionsWithCleanFields = contentTypeService.cleanPermissionFields(\n remainingPermissions\n ) as Permission[];\n\n // Update only the ones that need to be updated\n const permissionsNeedingToBeUpdated = differenceWith(\n permissionsWithCleanFields,\n remainingPermissions,\n (a: Permission, b: Permission) => {\n return a.id === b.id && xor(b.properties.fields, a.properties.fields).length === 0;\n }\n );\n\n const updatePromiseProvider = (permission: Permission) => {\n return update({ id: permission.id }, permission);\n };\n\n // Execute all the queries, update the database\n await Promise.all([\n deleteByIds(permissionsIdToRemove),\n pmap(permissionsNeedingToBeUpdated, updatePromiseProvider, {\n concurrency: 100,\n stopOnError: true,\n }),\n ]);\n }\n};\n\nexport default {\n createMany,\n findMany,\n deleteByRolesIds,\n deleteByIds,\n findUserPermissions,\n cleanPermissionsInDatabase,\n};\n"],"names":["deleteByRolesIds","rolesIds","permissionsToDelete","strapi","db","query","findMany","select","where","role","id","length","deleteByIds","map","permission","ids","result","queryResult","delete","push","eventHub","emit","permissions","createMany","createdPermissions","newPerm","create","data","permissionsToReturn","permissionDomain","toPermission","update","params","attributes","updatedPermission","permissionToReturn","rawPermissions","findUserPermissions","user","users","filterPermissionsToRemove","actionProvider","getService","permissionsToRemove","subjects","options","get","action","applyToProperties","invalidProperties","Promise","all","property","applies","appliesToProperty","subject","getProperty","isRegisteredAction","has","hasInvalidProperties","Array","isArray","every","isInvalidSubject","includes","hasApiToken","cleanPermissionsInDatabase","pageSize","contentTypeService","total","count","pageCount","Math","ceil","page","results","limit","offset","populate","orphanedPermissions","filter","apiToken","permissionsIdToRemove","from","Set","p","remainingPermissions","permissionsWithCleanFields","cleanPermissionFields","permissionsNeedingToBeUpdated","differenceWith","a","b","xor","properties","fields","updatePromiseProvider","pmap","concurrency","stopOnError"],"mappings":";;;;;AASA;;;IAIO,MAAMA,gBAAAA,GAAmB,OAAOC,QAAAA,GAAAA;IACrC,MAAMC,mBAAAA,GAAsB,MAAMC,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAAC,mBAAA,CAAA,CAAqBC,QAAQ,CAAC;QAC9EC,MAAAA,EAAQ;AAAC,YAAA;AAAK,SAAA;QACdC,KAAAA,EAAO;YACLC,IAAAA,EAAM;gBAAEC,EAAAA,EAAIT;AAAS;AACvB;AACF,KAAA,CAAA;IAEA,IAAIC,mBAAAA,CAAoBS,MAAM,GAAG,CAAA,EAAG;AAClC,QAAA,MAAMC,YAAYV,mBAAAA,CAAoBW,GAAG,CAAC,CAACC,aAAeA,UAAAA,EAAYJ,EAAAA,CAAAA,CAAAA;AACxE,IAAA;AACF;AAEA;;;IAIO,MAAME,WAAAA,GAAc,OAAOG,GAAAA,GAAAA;AAChC,IAAA,MAAMC,SAAoB,EAAE;IAC5B,KAAK,MAAMN,MAAMK,GAAAA,CAAK;QACpB,MAAME,WAAAA,GAAc,MAAMd,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAAC,mBAAA,CAAA,CAAqBa,MAAM,CAAC;YAAEV,KAAAA,EAAO;AAAEE,gBAAAA;AAAG;AAAE,SAAA,CAAA;AACtFM,QAAAA,MAAAA,CAAOG,IAAI,CAACF,WAAAA,CAAAA;AACd,IAAA;AACAd,IAAAA,MAAAA,CAAOiB,QAAQ,CAACC,IAAI,CAAC,mBAAA,EAAqB;QAAEC,WAAAA,EAAaN;AAAO,KAAA,CAAA;AAClE;AAEA;;;IAIO,MAAMO,UAAAA,GAAa,OAAOD,WAAAA,GAAAA;AAC/B,IAAA,MAAME,qBAAgD,EAAE;IACxD,KAAK,MAAMV,cAAcQ,WAAAA,CAAa;QACpC,MAAMG,OAAAA,GAAU,MAAMtB,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAAC,mBAAA,CAAA,CAAqBqB,MAAM,CAAC;YAAEC,IAAAA,EAAMb;AAAW,SAAA,CAAA;AACrFU,QAAAA,kBAAAA,CAAmBL,IAAI,CAACM,OAAAA,CAAAA;AAC1B,IAAA;IAEA,MAAMG,mBAAAA,GAAsBC,gBAAAA,CAAiBC,YAAY,CAACN,kBAAAA,CAAAA;AAC1DrB,IAAAA,MAAAA,CAAOiB,QAAQ,CAACC,IAAI,CAAC,mBAAA,EAAqB;QAAEC,WAAAA,EAAaM;AAAoB,KAAA,CAAA;IAE7E,OAAOA,mBAAAA;AACT;AAEA;;;;IAKA,MAAMG,MAAAA,GAAS,OAAOC,MAAAA,EAAiBC,UAAAA,GAAAA;IACrC,MAAMC,iBAAAA,GAAqB,MAAM/B,MAAAA,CAAOC,EAAE,CACvCC,KAAK,CAAC,mBAAA,CAAA,CACN0B,MAAM,CAAC;QAAEvB,KAAAA,EAAOwB,MAAAA;QAAQL,IAAAA,EAAMM;AAAW,KAAA,CAAA;IAE5C,MAAME,kBAAAA,GAAqBN,gBAAAA,CAAiBC,YAAY,CAACI,iBAAAA,CAAAA;AACzD/B,IAAAA,MAAAA,CAAOiB,QAAQ,CAACC,IAAI,CAAC,mBAAA,EAAqB;QAAEC,WAAAA,EAAaa;AAAmB,KAAA,CAAA;IAE5E,OAAOA,kBAAAA;AACT,CAAA;AAEA;;;AAGC,IACM,MAAM7B,QAAAA,GAAW,OAAO0B,MAAAA,GAAS,EAAE,GAAA;IACxC,MAAMI,cAAAA,GAAiB,MAAMjC,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAAC,mBAAA,CAAA,CAAqBC,QAAQ,CAAC0B,MAAAA,CAAAA;IAE3E,OAAOH,gBAAAA,CAAiBC,YAAY,CAACM,cAAAA,CAAAA;AACvC;AAEA;;;IAIO,MAAMC,mBAAAA,GAAsB,OAAOC,IAAAA,GAAAA;AACxC,IAAA,OAAOhC,QAAAA,CAAS;QAAEE,KAAAA,EAAO;YAAEC,IAAAA,EAAM;gBAAE8B,KAAAA,EAAO;AAAE7B,oBAAAA,EAAAA,EAAI4B,KAAK5B;AAAG;AAAE;AAAE;AAAE,KAAA,CAAA;AAChE;AAEA,MAAM8B,4BAA4B,OAAOlB,WAAAA,GAAAA;AACvC,IAAA,MAAM,EAAEmB,cAAc,EAAE,GAAGC,UAAAA,CAAW,YAAA,CAAA;AAEtC,IAAA,MAAMC,sBAAoC,EAAE;IAE5C,KAAK,MAAM7B,cAAcQ,WAAAA,CAAa;AACpC,QAAA,MAAM,EAAEsB,QAAQ,EAAEC,OAAAA,GAAU,EAAuB,EAAE,GAClDJ,eAAeK,GAAG,CAAChC,UAAAA,CAAWiC,MAAM,KAAgB,EAAC;QACxD,MAAM,EAAEC,iBAAiB,EAAE,GAAGH,OAAAA;AAE9B,QAAA,MAAMI,iBAAAA,GAAoB,MAAMC,OAAAA,CAAQC,GAAG,CACxCH,CAAAA,iBAAAA,IAAqB,EAAC,EAAGnC,GAAG,CAAC,OAAOuC,QAAAA,GAAAA;YACnC,MAAMC,OAAAA,GAAU,MAAMZ,cAAAA,CAAea,iBAAiB,CACpDF,UACAtC,UAAAA,CAAWiC,MAAM,EACjBjC,UAAAA,CAAWyC,OAAO,CAAA;AAGpB,YAAA,OAAOF,OAAAA,IAAWxB,gBAAAA,CAAiB2B,WAAW,CAACJ,UAAUtC,UAAAA,CAAAA,IAAe,IAAA;AAC1E,QAAA,CAAA,CAAA,CAAA;AAGF,QAAA,MAAM2C,kBAAAA,GAAqBhB,cAAAA,CAAeiB,GAAG,CAAC5C,WAAWiC,MAAM,CAAA;QAC/D,MAAMY,oBAAAA,GACJC,KAAAA,CAAMC,OAAO,CAACb,iBAAAA,CAAAA,IAAsBC,kBAAkBa,KAAK,CAAC,CAAC9C,MAAAA,GAAWA,MAAAA,KAAW,IAAA,CAAA;QACrF,MAAM+C,gBAAAA,GACJH,KAAAA,CAAMC,OAAO,CAACjB,QAAAA,CAAAA,IAAa,CAACA,QAAAA,CAASoB,QAAQ,CAAClD,UAAAA,CAAWyC,OAAO,CAAA;;QAElE,MAAMU,WAAAA,GAAcnB,GAAAA,CAAIhC,UAAAA,EAAY,UAAA,CAAA,IAAe,IAAA;;AAGnD,QAAA,IAAI,CAAC2C,kBAAAA,IAAsBM,gBAAAA,IAAqBJ,oBAAAA,IAAwB,CAACM,WAAAA,EAAc;AACrFtB,YAAAA,mBAAAA,CAAoBxB,IAAI,CAACL,UAAAA,CAAAA;AAC3B,QAAA;AACF,IAAA;IAEA,OAAO6B,mBAAAA;AACT,CAAA;AAEA;;UAGauB,0BAAAA,GAA6B,UAAA;AACxC,IAAA,MAAMC,QAAAA,GAAW,GAAA;AAEjB,IAAA,MAAMC,qBAAqB1B,UAAAA,CAAW,cAAA,CAAA;IAEtC,MAAM2B,KAAAA,GAAQ,MAAMlE,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAAC,qBAAqBiE,KAAK,EAAA;AAC9D,IAAA,MAAMC,SAAAA,GAAYC,IAAAA,CAAKC,IAAI,CAACJ,KAAAA,GAAQF,QAAAA,CAAAA;AAEpC,IAAA,IAAK,IAAIO,IAAAA,GAAO,CAAA,EAAGA,IAAAA,GAAOH,SAAAA,EAAWG,QAAQ,CAAA,CAAG;;QAE9C,MAAMC,OAAAA,GAAW,MAAMxE,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAAC,mBAAA,CAAA,CAAqBC,QAAQ,CAAC;YACnEsE,KAAAA,EAAOT,QAAAA;AACPU,YAAAA,MAAAA,EAAQH,IAAAA,GAAOP,QAAAA;YACfW,QAAAA,EAAU;AAAC,gBAAA,MAAA;AAAQ,gBAAA;AAAW;AAChC,SAAA,CAAA;QAEA,MAAMxD,WAAAA,GAAcO,gBAAAA,CAAiBC,YAAY,CAAC6C,OAAAA,CAAAA;QAClD,MAAMhC,mBAAAA,GAAsB,MAAMH,yBAAAA,CAA0BlB,WAAAA,CAAAA;;AAG5D,QAAA,MAAMyD,mBAAAA,GAAsBzD,WAAAA,CAAY0D,MAAM,CAC5C,CAAClE,UAAAA,GAAoB,CAACA,UAAAA,CAAWL,IAAI,IAAI,CAACK,UAAAA,CAAWmE,QAAQ,CAAA;AAG/D,QAAA,MAAMC,qBAAAA,GAAwBtB,KAAAA,CAAMuB,IAAI,CACtC,IAAIC,GAAAA,CAAI;AAAIzC,YAAAA,GAAAA,mBAAAA;AAAwBoC,YAAAA,GAAAA;AAAoB,SAAA,CAAClE,GAAG,CAAC,CAACwE,CAAAA,GAAMA,EAAE3E,EAAE,CAAA,CAAA,CAAA;;QAI1E,MAAM4E,oBAAAA,GAAuBhE,WAAAA,CAAY0D,MAAM,CAC7C,CAAClE,UAAAA,GAA2B,CAACoE,qBAAAA,CAAsBlB,QAAQ,CAAClD,UAAAA,CAAWJ,EAAE,CAAA,CAAA;QAG3E,MAAM6E,0BAAAA,GAA6BnB,kBAAAA,CAAmBoB,qBAAqB,CACzEF,oBAAAA,CAAAA;;AAIF,QAAA,MAAMG,6BAAAA,GAAgCC,cAAAA,CACpCH,0BAAAA,EACAD,oBAAAA,EACA,CAACK,CAAAA,EAAeC,CAAAA,GAAAA;AACd,YAAA,OAAOD,EAAEjF,EAAE,KAAKkF,EAAElF,EAAE,IAAImF,IAAID,CAAAA,CAAEE,UAAU,CAACC,MAAM,EAAEJ,CAAAA,CAAEG,UAAU,CAACC,MAAM,CAAA,CAAEpF,MAAM,KAAK,CAAA;AACnF,QAAA,CAAA,CAAA;AAGF,QAAA,MAAMqF,wBAAwB,CAAClF,UAAAA,GAAAA;AAC7B,YAAA,OAAOiB,MAAAA,CAAO;AAAErB,gBAAAA,EAAAA,EAAII,WAAWJ;aAAG,EAAGI,UAAAA,CAAAA;AACvC,QAAA,CAAA;;QAGA,MAAMoC,OAAAA,CAAQC,GAAG,CAAC;YAChBvC,WAAAA,CAAYsE,qBAAAA,CAAAA;AACZe,YAAAA,IAAAA,CAAKR,+BAA+BO,qBAAAA,EAAuB;gBACzDE,WAAAA,EAAa,GAAA;gBACbC,WAAAA,EAAa;AACf,aAAA;AACD,SAAA,CAAA;AACH,IAAA;AACF;;;;"}
@@ -0,0 +1,118 @@
1
+ 'use strict';
2
+
3
+ var _ = require('lodash');
4
+ var contentType = require('../content-type.js');
5
+
6
+ const PERMISSION_UID = 'admin::permission';
7
+ /**
8
+ * Carries attribute renames to the `properties.fields` of admin permissions
9
+ * (roles and admin API tokens).
10
+ *
11
+ * Runs from the generated rename migration, inside its transaction, before the
12
+ * admin bootstrap cleans permission fields against the new schema. Without it,
13
+ * the cleanup drops every renamed field from every role but the super admin.
14
+ *
15
+ * `strapi.contentTypes` / `strapi.components` already hold the new schema at
16
+ * that point, so every new field path is mapped back to the path it had before
17
+ * the renames, segment by segment (a component field path goes through its
18
+ * parent's component). This also composes a parent rename with a rename inside
19
+ * its component in the same save.
20
+ */ const createPermissionFieldRenamer = ({ strapi })=>{
21
+ const getOldPath = (subject, path, originsOf)=>{
22
+ let ownerUid = subject;
23
+ let owner = strapi.contentTypes[subject];
24
+ return path.split('.').map((segment)=>{
25
+ const origin = originsOf[ownerUid]?.[segment] ?? segment;
26
+ const attribute = owner?.attributes?.[segment];
27
+ if (attribute?.type === 'component' && attribute.component) {
28
+ ownerUid = attribute.component;
29
+ owner = strapi.components[attribute.component];
30
+ } else {
31
+ owner = undefined;
32
+ }
33
+ return origin;
34
+ }).join('.');
35
+ };
36
+ /**
37
+ * `old path -> new path` per subject, for the subjects with at least one
38
+ * renamed path.
39
+ */ const getRenamedPaths = (renames)=>{
40
+ // Per model: final name -> origin name.
41
+ const originsOf = {};
42
+ for (const [uid, mapping] of Object.entries(renames)){
43
+ originsOf[uid] = _.invert(mapping);
44
+ }
45
+ const renamedPaths = new Map();
46
+ for (const [subject, contentType$1] of Object.entries(strapi.contentTypes)){
47
+ const paths = contentType.getNestedFieldsWithIntermediate(contentType$1, {
48
+ components: strapi.components
49
+ });
50
+ const byOldPath = {};
51
+ for (const path of paths){
52
+ const oldPath = getOldPath(subject, path, originsOf);
53
+ if (oldPath !== path) {
54
+ byOldPath[oldPath] = path;
55
+ }
56
+ }
57
+ if (!_.isEmpty(byOldPath)) {
58
+ renamedPaths.set(subject, byOldPath);
59
+ }
60
+ }
61
+ return renamedPaths;
62
+ };
63
+ return async (trx, renames)=>{
64
+ if (_.isEmpty(renames)) {
65
+ return;
66
+ }
67
+ // Fresh database: the table is created by schema sync after the migrations.
68
+ const { tableName } = strapi.db.metadata.get(PERMISSION_UID);
69
+ if (!await strapi.db.getSchemaConnection(trx).hasTable(tableName)) {
70
+ return;
71
+ }
72
+ const renamedPaths = getRenamedPaths(renames);
73
+ if (renamedPaths.size === 0) {
74
+ return;
75
+ }
76
+ // Joins the migration transaction.
77
+ const permissions = await strapi.db.query(PERMISSION_UID).findMany({
78
+ select: [
79
+ 'id',
80
+ 'subject',
81
+ 'properties'
82
+ ],
83
+ where: {
84
+ subject: {
85
+ $in: [
86
+ ...renamedPaths.keys()
87
+ ]
88
+ }
89
+ }
90
+ });
91
+ for (const permission of permissions){
92
+ const fields = permission.properties?.fields;
93
+ const byOldPath = permission.subject ? renamedPaths.get(permission.subject) : undefined;
94
+ if (!Array.isArray(fields) || !byOldPath) {
95
+ continue;
96
+ }
97
+ // One pass over the old paths, so a swap is applied once.
98
+ const newFields = _.uniq(fields.map((field)=>byOldPath[field] ?? field));
99
+ if (_.xor(fields, newFields).length === 0) {
100
+ continue;
101
+ }
102
+ await strapi.db.query(PERMISSION_UID).update({
103
+ where: {
104
+ id: permission.id
105
+ },
106
+ data: {
107
+ properties: {
108
+ ...permission.properties,
109
+ fields: newFields
110
+ }
111
+ }
112
+ });
113
+ }
114
+ };
115
+ };
116
+
117
+ exports.createPermissionFieldRenamer = createPermissionFieldRenamer;
118
+ //# sourceMappingURL=rename-fields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rename-fields.js","sources":["../../../../../../server/src/services/permission/rename-fields.ts"],"sourcesContent":["import { invert, isEmpty, uniq, xor } from 'lodash';\nimport type { Core, Struct } from '@strapi/types';\n\nimport { getNestedFieldsWithIntermediate } from '../content-type';\n\ntype AttributeRenameHandler = Parameters<\n Core.Strapi['db']['schema']['registerAttributeRenameHandler']\n>[0];\n\ntype AttributeRenames = Parameters<AttributeRenameHandler>[1];\n\ninterface PermissionRow {\n id: number | string;\n subject: string | null;\n properties?: { fields?: unknown } | null;\n}\n\nconst PERMISSION_UID = 'admin::permission';\n\n/**\n * Carries attribute renames to the `properties.fields` of admin permissions\n * (roles and admin API tokens).\n *\n * Runs from the generated rename migration, inside its transaction, before the\n * admin bootstrap cleans permission fields against the new schema. Without it,\n * the cleanup drops every renamed field from every role but the super admin.\n *\n * `strapi.contentTypes` / `strapi.components` already hold the new schema at\n * that point, so every new field path is mapped back to the path it had before\n * the renames, segment by segment (a component field path goes through its\n * parent's component). This also composes a parent rename with a rename inside\n * its component in the same save.\n */\nexport const createPermissionFieldRenamer = ({\n strapi,\n}: {\n strapi: Core.Strapi;\n}): AttributeRenameHandler => {\n const getOldPath = (\n subject: string,\n path: string,\n originsOf: Record<string, Record<string, string>>\n ): string => {\n let ownerUid = subject;\n let owner: Struct.Schema | undefined =\n strapi.contentTypes[subject as keyof typeof strapi.contentTypes];\n\n return path\n .split('.')\n .map((segment) => {\n const origin = originsOf[ownerUid]?.[segment] ?? segment;\n const attribute = owner?.attributes?.[segment] as\n | { type?: string; component?: string }\n | undefined;\n\n if (attribute?.type === 'component' && attribute.component) {\n ownerUid = attribute.component;\n owner = strapi.components[attribute.component as keyof typeof strapi.components];\n } else {\n owner = undefined;\n }\n\n return origin;\n })\n .join('.');\n };\n\n /**\n * `old path -> new path` per subject, for the subjects with at least one\n * renamed path.\n */\n const getRenamedPaths = (renames: AttributeRenames): Map<string, Record<string, string>> => {\n // Per model: final name -> origin name.\n const originsOf: Record<string, Record<string, string>> = {};\n for (const [uid, mapping] of Object.entries(renames)) {\n originsOf[uid] = invert(mapping);\n }\n\n const renamedPaths = new Map<string, Record<string, string>>();\n\n for (const [subject, contentType] of Object.entries(strapi.contentTypes)) {\n const paths = getNestedFieldsWithIntermediate(contentType as Struct.ContentTypeSchema, {\n components: strapi.components,\n });\n\n const byOldPath: Record<string, string> = {};\n for (const path of paths) {\n const oldPath = getOldPath(subject, path, originsOf);\n if (oldPath !== path) {\n byOldPath[oldPath] = path;\n }\n }\n\n if (!isEmpty(byOldPath)) {\n renamedPaths.set(subject, byOldPath);\n }\n }\n\n return renamedPaths;\n };\n\n return async (trx, renames) => {\n if (isEmpty(renames)) {\n return;\n }\n\n // Fresh database: the table is created by schema sync after the migrations.\n const { tableName } = strapi.db.metadata.get(PERMISSION_UID);\n if (!(await strapi.db.getSchemaConnection(trx).hasTable(tableName))) {\n return;\n }\n\n const renamedPaths = getRenamedPaths(renames);\n if (renamedPaths.size === 0) {\n return;\n }\n\n // Joins the migration transaction.\n const permissions = (await strapi.db.query(PERMISSION_UID).findMany({\n select: ['id', 'subject', 'properties'],\n where: { subject: { $in: [...renamedPaths.keys()] } },\n })) as PermissionRow[];\n\n for (const permission of permissions) {\n const fields = permission.properties?.fields;\n const byOldPath = permission.subject ? renamedPaths.get(permission.subject) : undefined;\n\n if (!Array.isArray(fields) || !byOldPath) {\n continue;\n }\n\n // One pass over the old paths, so a swap is applied once.\n const newFields = uniq(fields.map((field: string) => byOldPath[field] ?? field));\n\n if (xor(fields, newFields).length === 0) {\n continue;\n }\n\n await strapi.db.query(PERMISSION_UID).update({\n where: { id: permission.id },\n data: { properties: { ...permission.properties, fields: newFields } },\n });\n }\n };\n};\n"],"names":["PERMISSION_UID","createPermissionFieldRenamer","strapi","getOldPath","subject","path","originsOf","ownerUid","owner","contentTypes","split","map","segment","origin","attribute","attributes","type","component","components","undefined","join","getRenamedPaths","renames","uid","mapping","Object","entries","invert","renamedPaths","Map","contentType","paths","getNestedFieldsWithIntermediate","byOldPath","oldPath","isEmpty","set","trx","tableName","db","metadata","get","getSchemaConnection","hasTable","size","permissions","query","findMany","select","where","$in","keys","permission","fields","properties","Array","isArray","newFields","uniq","field","xor","length","update","id","data"],"mappings":"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"}