@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 +1 @@
1
- {"version":3,"file":"token.js","sources":["../../../../../../server/src/services/transfer/token.ts"],"sourcesContent":["import crypto from 'crypto';\nimport assert from 'assert';\nimport { map, isArray, omit, uniq, isNil, difference, isEmpty, isNumber } from 'lodash/fp';\nimport { errors, emitAudit } from '@strapi/utils';\nimport '@strapi/types';\nimport constants from '../constants';\nimport { getService } from '../../utils';\nimport { AUDITED_EVENTS, getTokenChanges, toActionRefs } from '../../audit-logs/tokens';\nimport {\n DatabaseTransferToken,\n SanitizedTransferToken,\n TokenCreatePayload,\n TokenUpdatePayload,\n TransferToken,\n TransferTokenPermission,\n} from '../../../../shared/contracts/transfer';\n\nconst { ValidationError, NotFoundError } = errors;\n\nconst TRANSFER_TOKEN_UID = 'admin::transfer-token';\nconst TRANSFER_TOKEN_PERMISSION_UID = 'admin::transfer-token-permission';\n\nconst SELECT_FIELDS = [\n 'id',\n 'name',\n 'description',\n 'lastUsedAt',\n 'lifespan',\n 'expiresAt',\n 'createdAt',\n 'updatedAt',\n] as const;\n\nconst POPULATE_FIELDS = ['permissions'] as const;\n\n/**\n * Return a list of all tokens and their permissions\n */\nconst list = async (): Promise<SanitizedTransferToken[]> => {\n const tokens: DatabaseTransferToken[] = await strapi.db.query(TRANSFER_TOKEN_UID).findMany({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n orderBy: { name: 'ASC' },\n });\n\n if (!tokens) return tokens;\n return tokens.map((token) => flattenTokenPermissions(token));\n};\n\n/**\n * Create a random token's access key\n */\nconst generateRandomAccessKey = (): string => crypto.randomBytes(128).toString('hex');\n\n/**\n * Validate the given access key's format and returns it if valid\n */\nconst validateAccessKey = (accessKey: string): string => {\n assert(typeof accessKey === 'string', 'Access key needs to be a string');\n assert(accessKey.length >= 15, 'Access key needs to have at least 15 characters');\n\n return accessKey;\n};\n\nexport const hasAccessKey = <T extends { accessKey?: string }>(\n attributes: T\n): attributes is T & { accessKey: string } => {\n return 'accessKey' in attributes;\n};\n\n/**\n * Create a token and its permissions\n */\nconst create = async (attributes: TokenCreatePayload): Promise<TransferToken> => {\n const accessKey = hasAccessKey(attributes)\n ? validateAccessKey(attributes.accessKey)\n : generateRandomAccessKey();\n\n // Make sure the access key isn't picked up directly from the attributes for the next steps\n delete attributes.accessKey;\n\n assertTokenPermissionsValidity(attributes);\n assertValidLifespan(attributes.lifespan);\n\n const result = (await strapi.db.transaction(async () => {\n const transferToken = await strapi.db.query(TRANSFER_TOKEN_UID).create({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n data: {\n ...omit('permissions', attributes),\n accessKey: hash(accessKey),\n ...getExpirationFields(attributes.lifespan),\n },\n });\n\n await Promise.all(\n uniq(attributes.permissions).map((action) =>\n strapi.db\n .query(TRANSFER_TOKEN_PERMISSION_UID)\n .create({ data: { action, token: transferToken } })\n )\n );\n\n const currentPermissions: TransferTokenPermission[] = await strapi.db\n .query(TRANSFER_TOKEN_UID)\n .load(transferToken, 'permissions');\n\n if (currentPermissions) {\n Object.assign(transferToken, { permissions: map('action', currentPermissions) });\n }\n\n return transferToken;\n })) as TransferToken;\n\n await emitAudit({ strapi }, AUDITED_EVENTS.TOKEN_CREATE, {\n tokenId: result.id,\n name: result.name,\n kind: 'transfer',\n description: result.description ?? null,\n lifespan: result.lifespan,\n expiresAt: result.expiresAt,\n permissions: result.permissions ?? [],\n });\n\n return { ...result, accessKey };\n};\n\n/**\n * Update a token and its permissions\n */\nconst update = async (\n id: string | number,\n attributes: TokenUpdatePayload\n): Promise<SanitizedTransferToken> => {\n // Populated with its permissions: the audit row for this update lists what changed,\n // so the state before the write is needed.\n const originalToken: DatabaseTransferToken | null = await strapi.db\n .query(TRANSFER_TOKEN_UID)\n .findOne({ where: { id }, populate: POPULATE_FIELDS });\n\n if (!originalToken) {\n throw new NotFoundError('Token not found');\n }\n\n assertTokenPermissionsValidity(attributes);\n assertValidLifespan(attributes.lifespan);\n\n const updated = (await strapi.db.transaction(async () => {\n const updatedToken = await strapi.db.query(TRANSFER_TOKEN_UID).update({\n select: SELECT_FIELDS,\n where: { id },\n data: {\n ...omit('permissions', attributes),\n },\n });\n\n if (attributes.permissions) {\n const currentPermissionsResult = await strapi.db\n .query(TRANSFER_TOKEN_UID)\n .load(updatedToken, 'permissions');\n\n const currentPermissions = map('action', currentPermissionsResult || []);\n const newPermissions = uniq(attributes.permissions);\n\n const actionsToDelete = difference(currentPermissions, newPermissions);\n const actionsToAdd = difference(newPermissions, currentPermissions);\n\n // TODO: improve efficiency here\n // method using a loop -- works but very inefficient\n await Promise.all(\n actionsToDelete.map((action) =>\n strapi.db.query(TRANSFER_TOKEN_PERMISSION_UID).delete({\n where: { action, token: id },\n })\n )\n );\n\n // TODO: improve efficiency here\n // using a loop -- works but very inefficient\n await Promise.all(\n actionsToAdd.map((action) =>\n strapi.db.query(TRANSFER_TOKEN_PERMISSION_UID).create({\n data: { action, token: id },\n })\n )\n );\n }\n\n // retrieve permissions\n const permissionsFromDb: TransferTokenPermission[] = await strapi.db\n .query(TRANSFER_TOKEN_UID)\n .load(updatedToken, 'permissions');\n\n return {\n ...updatedToken,\n permissions: permissionsFromDb ? permissionsFromDb.map((p) => p.action) : undefined,\n };\n })) as SanitizedTransferToken;\n\n const changes = getTokenChanges(\n {\n name: originalToken.name,\n description: originalToken.description,\n permissions: toActionRefs(originalToken.permissions),\n },\n { name: updated.name, description: updated.description, permissions: updated.permissions ?? [] }\n );\n\n if (Object.keys(changes).length > 0) {\n await emitAudit({ strapi }, AUDITED_EVENTS.TOKEN_UPDATE, {\n tokenId: originalToken.id,\n name: updated.name,\n kind: 'transfer',\n changes,\n });\n }\n\n return updated;\n};\n\n/**\n * Revoke (delete) a token\n */\nconst revoke = async (id: string | number): Promise<SanitizedTransferToken> => {\n const deleted = (await strapi.db.transaction(async () =>\n strapi.db\n .query(TRANSFER_TOKEN_UID)\n .delete({ select: SELECT_FIELDS, populate: POPULATE_FIELDS, where: { id } })\n )) as SanitizedTransferToken | null;\n\n if (deleted) {\n await emitAudit({ strapi }, AUDITED_EVENTS.TOKEN_DELETE, {\n tokenId: deleted.id,\n name: deleted.name,\n kind: 'transfer',\n });\n }\n\n return deleted as SanitizedTransferToken;\n};\n\n/**\n * Get a token\n */\nconst getBy = async (\n whereParams = {} as {\n id?: string | number;\n name?: string;\n lastUsedAt?: number;\n description?: string;\n accessKey?: string;\n }\n): Promise<SanitizedTransferToken | null> => {\n if (Object.keys(whereParams).length === 0) {\n return null;\n }\n\n const token = await strapi.db\n .query(TRANSFER_TOKEN_UID)\n .findOne({ select: SELECT_FIELDS, populate: POPULATE_FIELDS, where: whereParams });\n\n if (!token) {\n return token;\n }\n\n return flattenTokenPermissions(token);\n};\n\n/**\n * Retrieve a token by id\n */\nconst getById = async (id: string | number): Promise<SanitizedTransferToken | null> => {\n return getBy({ id });\n};\n\n/**\n * Retrieve a token by name\n */\nconst getByName = async (name: string): Promise<SanitizedTransferToken | null> => {\n return getBy({ name });\n};\n\n/**\n * Check if token exists\n */\nconst exists = async (\n whereParams = {} as {\n id?: string | number;\n name?: string;\n lastUsedAt?: number;\n description?: string;\n accessKey?: string;\n }\n): Promise<boolean> => {\n const transferToken = await getBy(whereParams);\n\n return !!transferToken;\n};\n\nconst regenerate = async (id: string | number): Promise<TransferToken> => {\n const accessKey = crypto.randomBytes(128).toString('hex');\n const transferToken = (await strapi.db.transaction(async () =>\n strapi.db.query(TRANSFER_TOKEN_UID).update({\n select: ['id', 'name', 'accessKey'],\n where: { id },\n data: {\n accessKey: hash(accessKey),\n },\n })\n )) as TransferToken;\n\n if (!transferToken) {\n throw new NotFoundError('The provided token id does not exist');\n }\n\n await emitAudit({ strapi }, AUDITED_EVENTS.TOKEN_REGENERATE, {\n tokenId: transferToken.id,\n name: transferToken.name,\n kind: 'transfer',\n });\n\n return {\n ...transferToken,\n accessKey,\n };\n};\n\nconst getExpirationFields = (lifespan: TransferToken['lifespan']) => {\n // it must be nil or a finite number >= 0\n const isValidNumber = isNumber(lifespan) && Number.isFinite(lifespan) && lifespan > 0;\n if (!isValidNumber && !isNil(lifespan)) {\n throw new ValidationError('lifespan must be a positive number or null');\n }\n\n return {\n lifespan: lifespan || null,\n expiresAt: lifespan ? Date.now() + lifespan : null,\n };\n};\n\n/**\n * Return a secure sha512 hash of an accessKey\n */\nconst hash = (accessKey: string): string => {\n const { hasValidTokenSalt } = getService('transfer').utils;\n\n if (!hasValidTokenSalt()) {\n throw new TypeError('Required token salt is not defined');\n }\n\n return crypto\n .createHmac('sha512', strapi.config.get('admin.transfer.token.salt'))\n .update(accessKey)\n .digest('hex');\n};\n\nconst checkSaltIsDefined = () => {\n const { hasValidTokenSalt } = getService('transfer').utils;\n\n // Ignore the check if the data-transfer feature is manually disabled\n if (!strapi.config.get('server.transfer.remote.enabled')) {\n return;\n }\n\n if (!hasValidTokenSalt()) {\n process.emitWarning(\n `Missing transfer.token.salt: Data transfer features have been disabled.\nPlease set transfer.token.salt in config/admin.js (ex: you can generate one using Node with \\`crypto.randomBytes(16).toString('base64')\\`)\nFor security reasons, prefer storing the secret in an environment variable and read it in config/admin.js. See https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.html#configuration-using-environment-variables.`\n );\n }\n};\n\n/**\n * Flatten a token's database permissions objects to an array of strings\n */\nconst flattenTokenPermissions = (token: DatabaseTransferToken): TransferToken => {\n if (!token) {\n return token;\n }\n\n return {\n ...token,\n permissions: isArray(token.permissions)\n ? map('action', token.permissions as TransferTokenPermission[])\n : token.permissions,\n };\n};\n\n/**\n * Assert that a token's permissions are valid\n */\nconst assertTokenPermissionsValidity = (attributes: TokenUpdatePayload) => {\n const permissionService = strapi.service('admin::transfer').permission;\n const validPermissions = permissionService.providers.action.keys();\n const invalidPermissions = difference(attributes.permissions, validPermissions);\n\n if (!isEmpty(invalidPermissions)) {\n throw new ValidationError(`Unknown permissions provided: ${invalidPermissions.join(', ')}`);\n }\n};\n\n/**\n * Check if a token's lifespan is valid\n */\nconst isValidLifespan = (lifespan: unknown) => {\n if (isNil(lifespan)) {\n return true;\n }\n\n if (\n !isNumber(lifespan) ||\n !Object.values(constants.TRANSFER_TOKEN_LIFESPANS).includes(lifespan)\n ) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Assert that a token's lifespan is valid\n */\nconst assertValidLifespan = (lifespan: unknown) => {\n if (!isValidLifespan(lifespan)) {\n throw new ValidationError(\n `lifespan must be one of the following values:\n ${Object.values(constants.TRANSFER_TOKEN_LIFESPANS).join(', ')}`\n );\n }\n};\n\nexport {\n create,\n list,\n exists,\n getBy,\n getById,\n getByName,\n update,\n revoke,\n regenerate,\n hash,\n checkSaltIsDefined,\n};\n"],"names":["ValidationError","NotFoundError","errors","TRANSFER_TOKEN_UID","TRANSFER_TOKEN_PERMISSION_UID","SELECT_FIELDS","POPULATE_FIELDS","list","tokens","strapi","db","query","findMany","select","populate","orderBy","name","map","token","flattenTokenPermissions","generateRandomAccessKey","crypto","randomBytes","toString","validateAccessKey","accessKey","assert","length","hasAccessKey","attributes","create","assertTokenPermissionsValidity","assertValidLifespan","lifespan","result","transaction","transferToken","data","omit","hash","getExpirationFields","Promise","all","uniq","permissions","action","currentPermissions","load","Object","assign","emitAudit","AUDITED_EVENTS","TOKEN_CREATE","tokenId","id","kind","description","expiresAt","update","originalToken","findOne","where","updated","updatedToken","currentPermissionsResult","newPermissions","actionsToDelete","difference","actionsToAdd","delete","permissionsFromDb","p","undefined","changes","getTokenChanges","toActionRefs","keys","TOKEN_UPDATE","revoke","deleted","TOKEN_DELETE","getBy","whereParams","getById","getByName","exists","regenerate","TOKEN_REGENERATE","isValidNumber","isNumber","Number","isFinite","isNil","Date","now","hasValidTokenSalt","getService","utils","TypeError","createHmac","config","get","digest","checkSaltIsDefined","process","emitWarning","isArray","permissionService","service","permission","validPermissions","providers","invalidPermissions","isEmpty","join","isValidLifespan","values","constants","TRANSFER_TOKEN_LIFESPANS","includes"],"mappings":"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"}
1
+ {"version":3,"file":"token.js","sources":["../../../../../../server/src/services/transfer/token.ts"],"sourcesContent":["import crypto from 'crypto';\nimport assert from 'assert';\nimport { omit, difference, isEmpty, isNumber } from 'lodash';\n\nimport { errors, emitAudit } from '@strapi/utils';\nimport '@strapi/types';\nimport constants from '../constants';\nimport { getService } from '../../utils';\nimport { AUDITED_EVENTS, getTokenChanges, toActionRefs } from '../../audit-logs/tokens';\nimport {\n DatabaseTransferToken,\n SanitizedTransferToken,\n TokenCreatePayload,\n TokenUpdatePayload,\n TransferToken,\n TransferTokenPermission,\n} from '../../../../shared/contracts/transfer';\n\nconst { ValidationError, NotFoundError } = errors;\n\nconst TRANSFER_TOKEN_UID = 'admin::transfer-token';\nconst TRANSFER_TOKEN_PERMISSION_UID = 'admin::transfer-token-permission';\n\nconst SELECT_FIELDS = [\n 'id',\n 'name',\n 'description',\n 'lastUsedAt',\n 'lifespan',\n 'expiresAt',\n 'createdAt',\n 'updatedAt',\n] as const;\n\nconst POPULATE_FIELDS = ['permissions'] as const;\n\n/**\n * Return a list of all tokens and their permissions\n */\nconst list = async (): Promise<SanitizedTransferToken[]> => {\n const tokens: DatabaseTransferToken[] = await strapi.db.query(TRANSFER_TOKEN_UID).findMany({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n orderBy: { name: 'ASC' },\n });\n\n if (!tokens) return tokens;\n return tokens.map((token) => flattenTokenPermissions(token));\n};\n\n/**\n * Create a random token's access key\n */\nconst generateRandomAccessKey = (): string => crypto.randomBytes(128).toString('hex');\n\n/**\n * Validate the given access key's format and returns it if valid\n */\nconst validateAccessKey = (accessKey: string): string => {\n assert(typeof accessKey === 'string', 'Access key needs to be a string');\n assert(accessKey.length >= 15, 'Access key needs to have at least 15 characters');\n\n return accessKey;\n};\n\nexport const hasAccessKey = <T extends { accessKey?: string }>(\n attributes: T\n): attributes is T & { accessKey: string } => {\n return 'accessKey' in attributes;\n};\n\n/**\n * Create a token and its permissions\n */\nconst create = async (attributes: TokenCreatePayload): Promise<TransferToken> => {\n const accessKey = hasAccessKey(attributes)\n ? validateAccessKey(attributes.accessKey)\n : generateRandomAccessKey();\n\n // Make sure the access key isn't picked up directly from the attributes for the next steps\n delete attributes.accessKey;\n\n assertTokenPermissionsValidity(attributes);\n assertValidLifespan(attributes.lifespan);\n\n const result = (await strapi.db.transaction(async () => {\n const transferToken = await strapi.db.query(TRANSFER_TOKEN_UID).create({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n data: {\n ...omit(attributes, 'permissions'),\n accessKey: hash(accessKey),\n ...getExpirationFields(attributes.lifespan),\n },\n });\n\n await Promise.all(\n [...new Set(attributes.permissions)].map((action) =>\n strapi.db\n .query(TRANSFER_TOKEN_PERMISSION_UID)\n .create({ data: { action, token: transferToken } })\n )\n );\n\n const currentPermissions: TransferTokenPermission[] = await strapi.db\n .query(TRANSFER_TOKEN_UID)\n .load(transferToken, 'permissions');\n\n if (currentPermissions) {\n Object.assign(transferToken, {\n permissions: Array.from(currentPermissions ?? [], (permission) => permission?.action),\n });\n }\n\n return transferToken;\n })) as TransferToken;\n\n await emitAudit({ strapi }, AUDITED_EVENTS.TOKEN_CREATE, {\n tokenId: result.id,\n name: result.name,\n kind: 'transfer',\n description: result.description ?? null,\n lifespan: result.lifespan,\n expiresAt: result.expiresAt,\n permissions: result.permissions ?? [],\n });\n\n return { ...result, accessKey };\n};\n\n/**\n * Update a token and its permissions\n */\nconst update = async (\n id: string | number,\n attributes: TokenUpdatePayload\n): Promise<SanitizedTransferToken> => {\n // Populated with its permissions: the audit row for this update lists what changed,\n // so the state before the write is needed.\n const originalToken: DatabaseTransferToken | null = await strapi.db\n .query(TRANSFER_TOKEN_UID)\n .findOne({ where: { id }, populate: POPULATE_FIELDS });\n\n if (!originalToken) {\n throw new NotFoundError('Token not found');\n }\n\n assertTokenPermissionsValidity(attributes);\n assertValidLifespan(attributes.lifespan);\n\n const updated = (await strapi.db.transaction(async () => {\n const updatedToken = await strapi.db.query(TRANSFER_TOKEN_UID).update({\n select: SELECT_FIELDS,\n where: { id },\n data: {\n ...omit(attributes, 'permissions'),\n },\n });\n\n if (attributes.permissions) {\n const currentPermissionsResult = await strapi.db\n .query(TRANSFER_TOKEN_UID)\n .load(updatedToken, 'permissions');\n\n const currentPermissions = Array.from(\n currentPermissionsResult || [],\n (permission: TransferTokenPermission) => permission?.action\n );\n const newPermissions = [...new Set(attributes.permissions)];\n\n const actionsToDelete = difference(currentPermissions, newPermissions);\n const actionsToAdd = difference(newPermissions, currentPermissions);\n\n // TODO: improve efficiency here\n // method using a loop -- works but very inefficient\n await Promise.all(\n actionsToDelete.map((action) =>\n strapi.db.query(TRANSFER_TOKEN_PERMISSION_UID).delete({\n where: { action, token: id },\n })\n )\n );\n\n // TODO: improve efficiency here\n // using a loop -- works but very inefficient\n await Promise.all(\n actionsToAdd.map((action) =>\n strapi.db.query(TRANSFER_TOKEN_PERMISSION_UID).create({\n data: { action, token: id },\n })\n )\n );\n }\n\n // retrieve permissions\n const permissionsFromDb: TransferTokenPermission[] = await strapi.db\n .query(TRANSFER_TOKEN_UID)\n .load(updatedToken, 'permissions');\n\n return {\n ...updatedToken,\n permissions: permissionsFromDb ? permissionsFromDb.map((p) => p.action) : undefined,\n };\n })) as SanitizedTransferToken;\n\n const changes = getTokenChanges(\n {\n name: originalToken.name,\n description: originalToken.description,\n permissions: toActionRefs(originalToken.permissions),\n },\n { name: updated.name, description: updated.description, permissions: updated.permissions ?? [] }\n );\n\n if (Object.keys(changes).length > 0) {\n await emitAudit({ strapi }, AUDITED_EVENTS.TOKEN_UPDATE, {\n tokenId: originalToken.id,\n name: updated.name,\n kind: 'transfer',\n changes,\n });\n }\n\n return updated;\n};\n\n/**\n * Revoke (delete) a token\n */\nconst revoke = async (id: string | number): Promise<SanitizedTransferToken> => {\n const deleted = (await strapi.db.transaction(async () =>\n strapi.db\n .query(TRANSFER_TOKEN_UID)\n .delete({ select: SELECT_FIELDS, populate: POPULATE_FIELDS, where: { id } })\n )) as SanitizedTransferToken | null;\n\n if (deleted) {\n await emitAudit({ strapi }, AUDITED_EVENTS.TOKEN_DELETE, {\n tokenId: deleted.id,\n name: deleted.name,\n kind: 'transfer',\n });\n }\n\n return deleted as SanitizedTransferToken;\n};\n\n/**\n * Get a token\n */\nconst getBy = async (\n whereParams = {} as {\n id?: string | number;\n name?: string;\n lastUsedAt?: number;\n description?: string;\n accessKey?: string;\n }\n): Promise<SanitizedTransferToken | null> => {\n if (Object.keys(whereParams).length === 0) {\n return null;\n }\n\n const token = await strapi.db\n .query(TRANSFER_TOKEN_UID)\n .findOne({ select: SELECT_FIELDS, populate: POPULATE_FIELDS, where: whereParams });\n\n if (!token) {\n return token;\n }\n\n return flattenTokenPermissions(token);\n};\n\n/**\n * Retrieve a token by id\n */\nconst getById = async (id: string | number): Promise<SanitizedTransferToken | null> => {\n return getBy({ id });\n};\n\n/**\n * Retrieve a token by name\n */\nconst getByName = async (name: string): Promise<SanitizedTransferToken | null> => {\n return getBy({ name });\n};\n\n/**\n * Check if token exists\n */\nconst exists = async (\n whereParams = {} as {\n id?: string | number;\n name?: string;\n lastUsedAt?: number;\n description?: string;\n accessKey?: string;\n }\n): Promise<boolean> => {\n const transferToken = await getBy(whereParams);\n\n return !!transferToken;\n};\n\nconst regenerate = async (id: string | number): Promise<TransferToken> => {\n const accessKey = crypto.randomBytes(128).toString('hex');\n const transferToken = (await strapi.db.transaction(async () =>\n strapi.db.query(TRANSFER_TOKEN_UID).update({\n select: ['id', 'name', 'accessKey'],\n where: { id },\n data: {\n accessKey: hash(accessKey),\n },\n })\n )) as TransferToken;\n\n if (!transferToken) {\n throw new NotFoundError('The provided token id does not exist');\n }\n\n await emitAudit({ strapi }, AUDITED_EVENTS.TOKEN_REGENERATE, {\n tokenId: transferToken.id,\n name: transferToken.name,\n kind: 'transfer',\n });\n\n return {\n ...transferToken,\n accessKey,\n };\n};\n\nconst getExpirationFields = (lifespan: TransferToken['lifespan']) => {\n // it must be nil or a finite number >= 0\n const isValidNumber = isNumber(lifespan) && Number.isFinite(lifespan) && lifespan > 0;\n if (!isValidNumber && lifespan != null) {\n throw new ValidationError('lifespan must be a positive number or null');\n }\n\n return {\n lifespan: lifespan || null,\n expiresAt: lifespan ? Date.now() + lifespan : null,\n };\n};\n\n/**\n * Return a secure sha512 hash of an accessKey\n */\nconst hash = (accessKey: string): string => {\n const { hasValidTokenSalt } = getService('transfer').utils;\n\n if (!hasValidTokenSalt()) {\n throw new TypeError('Required token salt is not defined');\n }\n\n return crypto\n .createHmac('sha512', strapi.config.get('admin.transfer.token.salt'))\n .update(accessKey)\n .digest('hex');\n};\n\nconst checkSaltIsDefined = () => {\n const { hasValidTokenSalt } = getService('transfer').utils;\n\n // Ignore the check if the data-transfer feature is manually disabled\n if (!strapi.config.get('server.transfer.remote.enabled')) {\n return;\n }\n\n if (!hasValidTokenSalt()) {\n process.emitWarning(\n `Missing transfer.token.salt: Data transfer features have been disabled.\nPlease set transfer.token.salt in config/admin.js (ex: you can generate one using Node with \\`crypto.randomBytes(16).toString('base64')\\`)\nFor security reasons, prefer storing the secret in an environment variable and read it in config/admin.js. See https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.html#configuration-using-environment-variables.`\n );\n }\n};\n\n/**\n * Flatten a token's database permissions objects to an array of strings\n */\nconst flattenTokenPermissions = (token: DatabaseTransferToken): TransferToken => {\n if (!token) {\n return token;\n }\n\n return {\n ...token,\n permissions: Array.isArray(token.permissions)\n ? Array.from(\n token.permissions as TransferTokenPermission[],\n (permission) => permission?.action\n )\n : token.permissions,\n };\n};\n\n/**\n * Assert that a token's permissions are valid\n */\nconst assertTokenPermissionsValidity = (attributes: TokenUpdatePayload) => {\n const permissionService = strapi.service('admin::transfer').permission;\n const validPermissions = permissionService.providers.action.keys();\n const invalidPermissions = difference(attributes.permissions, validPermissions);\n\n if (!isEmpty(invalidPermissions)) {\n throw new ValidationError(`Unknown permissions provided: ${invalidPermissions.join(', ')}`);\n }\n};\n\n/**\n * Check if a token's lifespan is valid\n */\nconst isValidLifespan = (lifespan: unknown) => {\n if (lifespan == null) {\n return true;\n }\n\n if (\n !isNumber(lifespan) ||\n !Object.values(constants.TRANSFER_TOKEN_LIFESPANS).includes(lifespan)\n ) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Assert that a token's lifespan is valid\n */\nconst assertValidLifespan = (lifespan: unknown) => {\n if (!isValidLifespan(lifespan)) {\n throw new ValidationError(\n `lifespan must be one of the following values:\n ${Object.values(constants.TRANSFER_TOKEN_LIFESPANS).join(', ')}`\n );\n }\n};\n\nexport {\n create,\n list,\n exists,\n getBy,\n getById,\n getByName,\n update,\n revoke,\n regenerate,\n hash,\n checkSaltIsDefined,\n};\n"],"names":["ValidationError","NotFoundError","errors","TRANSFER_TOKEN_UID","TRANSFER_TOKEN_PERMISSION_UID","SELECT_FIELDS","POPULATE_FIELDS","list","tokens","strapi","db","query","findMany","select","populate","orderBy","name","map","token","flattenTokenPermissions","generateRandomAccessKey","crypto","randomBytes","toString","validateAccessKey","accessKey","assert","length","hasAccessKey","attributes","create","assertTokenPermissionsValidity","assertValidLifespan","lifespan","result","transaction","transferToken","data","omit","hash","getExpirationFields","Promise","all","Set","permissions","action","currentPermissions","load","Object","assign","Array","from","permission","emitAudit","AUDITED_EVENTS","TOKEN_CREATE","tokenId","id","kind","description","expiresAt","update","originalToken","findOne","where","updated","updatedToken","currentPermissionsResult","newPermissions","actionsToDelete","difference","actionsToAdd","delete","permissionsFromDb","p","undefined","changes","getTokenChanges","toActionRefs","keys","TOKEN_UPDATE","revoke","deleted","TOKEN_DELETE","getBy","whereParams","getById","getByName","exists","regenerate","TOKEN_REGENERATE","isValidNumber","isNumber","Number","isFinite","Date","now","hasValidTokenSalt","getService","utils","TypeError","createHmac","config","get","digest","checkSaltIsDefined","process","emitWarning","isArray","permissionService","service","validPermissions","providers","invalidPermissions","isEmpty","join","isValidLifespan","values","constants","TRANSFER_TOKEN_LIFESPANS","includes"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import crypto from 'crypto';
2
2
  import assert from 'assert';
3
- import { omit, uniq, map, difference, isEmpty, isNumber, isNil, isArray } from 'lodash/fp';
3
+ import { omit, difference, isEmpty, isNumber } from 'lodash';
4
4
  import { errors, emitAudit } from '@strapi/utils';
5
5
  import '@strapi/types';
6
6
  import constants from '../constants.mjs';
@@ -62,12 +62,14 @@ const hasAccessKey = (attributes)=>{
62
62
  select: SELECT_FIELDS,
63
63
  populate: POPULATE_FIELDS,
64
64
  data: {
65
- ...omit('permissions', attributes),
65
+ ...omit(attributes, 'permissions'),
66
66
  accessKey: hash(accessKey),
67
67
  ...getExpirationFields(attributes.lifespan)
68
68
  }
69
69
  });
70
- await Promise.all(uniq(attributes.permissions).map((action)=>strapi.db.query(TRANSFER_TOKEN_PERMISSION_UID).create({
70
+ await Promise.all([
71
+ ...new Set(attributes.permissions)
72
+ ].map((action)=>strapi.db.query(TRANSFER_TOKEN_PERMISSION_UID).create({
71
73
  data: {
72
74
  action,
73
75
  token: transferToken
@@ -76,7 +78,7 @@ const hasAccessKey = (attributes)=>{
76
78
  const currentPermissions = await strapi.db.query(TRANSFER_TOKEN_UID).load(transferToken, 'permissions');
77
79
  if (currentPermissions) {
78
80
  Object.assign(transferToken, {
79
- permissions: map('action', currentPermissions)
81
+ permissions: Array.from(currentPermissions ?? [], (permission)=>permission?.action)
80
82
  });
81
83
  }
82
84
  return transferToken;
@@ -120,13 +122,15 @@ const hasAccessKey = (attributes)=>{
120
122
  id
121
123
  },
122
124
  data: {
123
- ...omit('permissions', attributes)
125
+ ...omit(attributes, 'permissions')
124
126
  }
125
127
  });
126
128
  if (attributes.permissions) {
127
129
  const currentPermissionsResult = await strapi.db.query(TRANSFER_TOKEN_UID).load(updatedToken, 'permissions');
128
- const currentPermissions = map('action', currentPermissionsResult || []);
129
- const newPermissions = uniq(attributes.permissions);
130
+ const currentPermissions = Array.from(currentPermissionsResult || [], (permission)=>permission?.action);
131
+ const newPermissions = [
132
+ ...new Set(attributes.permissions)
133
+ ];
130
134
  const actionsToDelete = difference(currentPermissions, newPermissions);
131
135
  const actionsToAdd = difference(newPermissions, currentPermissions);
132
136
  // TODO: improve efficiency here
@@ -264,7 +268,7 @@ const regenerate = async (id)=>{
264
268
  const getExpirationFields = (lifespan)=>{
265
269
  // it must be nil or a finite number >= 0
266
270
  const isValidNumber = isNumber(lifespan) && Number.isFinite(lifespan) && lifespan > 0;
267
- if (!isValidNumber && !isNil(lifespan)) {
271
+ if (!isValidNumber && lifespan != null) {
268
272
  throw new ValidationError('lifespan must be a positive number or null');
269
273
  }
270
274
  return {
@@ -301,7 +305,7 @@ For security reasons, prefer storing the secret in an environment variable and r
301
305
  }
302
306
  return {
303
307
  ...token,
304
- permissions: isArray(token.permissions) ? map('action', token.permissions) : token.permissions
308
+ permissions: Array.isArray(token.permissions) ? Array.from(token.permissions, (permission)=>permission?.action) : token.permissions
305
309
  };
306
310
  };
307
311
  /**
@@ -317,7 +321,7 @@ For security reasons, prefer storing the secret in an environment variable and r
317
321
  /**
318
322
  * Check if a token's lifespan is valid
319
323
  */ const isValidLifespan = (lifespan)=>{
320
- if (isNil(lifespan)) {
324
+ if (lifespan == null) {
321
325
  return true;
322
326
  }
323
327
  if (!isNumber(lifespan) || !Object.values(constants.TRANSFER_TOKEN_LIFESPANS).includes(lifespan)) {
@@ -1 +1 @@
1
- {"version":3,"file":"token.mjs","sources":["../../../../../../server/src/services/transfer/token.ts"],"sourcesContent":["import crypto from 'crypto';\nimport assert from 'assert';\nimport { map, isArray, omit, uniq, isNil, difference, isEmpty, isNumber } from 'lodash/fp';\nimport { errors, emitAudit } from '@strapi/utils';\nimport '@strapi/types';\nimport constants from '../constants';\nimport { getService } from '../../utils';\nimport { AUDITED_EVENTS, getTokenChanges, toActionRefs } from '../../audit-logs/tokens';\nimport {\n DatabaseTransferToken,\n SanitizedTransferToken,\n TokenCreatePayload,\n TokenUpdatePayload,\n TransferToken,\n TransferTokenPermission,\n} from '../../../../shared/contracts/transfer';\n\nconst { ValidationError, NotFoundError } = errors;\n\nconst TRANSFER_TOKEN_UID = 'admin::transfer-token';\nconst TRANSFER_TOKEN_PERMISSION_UID = 'admin::transfer-token-permission';\n\nconst SELECT_FIELDS = [\n 'id',\n 'name',\n 'description',\n 'lastUsedAt',\n 'lifespan',\n 'expiresAt',\n 'createdAt',\n 'updatedAt',\n] as const;\n\nconst POPULATE_FIELDS = ['permissions'] as const;\n\n/**\n * Return a list of all tokens and their permissions\n */\nconst list = async (): Promise<SanitizedTransferToken[]> => {\n const tokens: DatabaseTransferToken[] = await strapi.db.query(TRANSFER_TOKEN_UID).findMany({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n orderBy: { name: 'ASC' },\n });\n\n if (!tokens) return tokens;\n return tokens.map((token) => flattenTokenPermissions(token));\n};\n\n/**\n * Create a random token's access key\n */\nconst generateRandomAccessKey = (): string => crypto.randomBytes(128).toString('hex');\n\n/**\n * Validate the given access key's format and returns it if valid\n */\nconst validateAccessKey = (accessKey: string): string => {\n assert(typeof accessKey === 'string', 'Access key needs to be a string');\n assert(accessKey.length >= 15, 'Access key needs to have at least 15 characters');\n\n return accessKey;\n};\n\nexport const hasAccessKey = <T extends { accessKey?: string }>(\n attributes: T\n): attributes is T & { accessKey: string } => {\n return 'accessKey' in attributes;\n};\n\n/**\n * Create a token and its permissions\n */\nconst create = async (attributes: TokenCreatePayload): Promise<TransferToken> => {\n const accessKey = hasAccessKey(attributes)\n ? validateAccessKey(attributes.accessKey)\n : generateRandomAccessKey();\n\n // Make sure the access key isn't picked up directly from the attributes for the next steps\n delete attributes.accessKey;\n\n assertTokenPermissionsValidity(attributes);\n assertValidLifespan(attributes.lifespan);\n\n const result = (await strapi.db.transaction(async () => {\n const transferToken = await strapi.db.query(TRANSFER_TOKEN_UID).create({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n data: {\n ...omit('permissions', attributes),\n accessKey: hash(accessKey),\n ...getExpirationFields(attributes.lifespan),\n },\n });\n\n await Promise.all(\n uniq(attributes.permissions).map((action) =>\n strapi.db\n .query(TRANSFER_TOKEN_PERMISSION_UID)\n .create({ data: { action, token: transferToken } })\n )\n );\n\n const currentPermissions: TransferTokenPermission[] = await strapi.db\n .query(TRANSFER_TOKEN_UID)\n .load(transferToken, 'permissions');\n\n if (currentPermissions) {\n Object.assign(transferToken, { permissions: map('action', currentPermissions) });\n }\n\n return transferToken;\n })) as TransferToken;\n\n await emitAudit({ strapi }, AUDITED_EVENTS.TOKEN_CREATE, {\n tokenId: result.id,\n name: result.name,\n kind: 'transfer',\n description: result.description ?? null,\n lifespan: result.lifespan,\n expiresAt: result.expiresAt,\n permissions: result.permissions ?? [],\n });\n\n return { ...result, accessKey };\n};\n\n/**\n * Update a token and its permissions\n */\nconst update = async (\n id: string | number,\n attributes: TokenUpdatePayload\n): Promise<SanitizedTransferToken> => {\n // Populated with its permissions: the audit row for this update lists what changed,\n // so the state before the write is needed.\n const originalToken: DatabaseTransferToken | null = await strapi.db\n .query(TRANSFER_TOKEN_UID)\n .findOne({ where: { id }, populate: POPULATE_FIELDS });\n\n if (!originalToken) {\n throw new NotFoundError('Token not found');\n }\n\n assertTokenPermissionsValidity(attributes);\n assertValidLifespan(attributes.lifespan);\n\n const updated = (await strapi.db.transaction(async () => {\n const updatedToken = await strapi.db.query(TRANSFER_TOKEN_UID).update({\n select: SELECT_FIELDS,\n where: { id },\n data: {\n ...omit('permissions', attributes),\n },\n });\n\n if (attributes.permissions) {\n const currentPermissionsResult = await strapi.db\n .query(TRANSFER_TOKEN_UID)\n .load(updatedToken, 'permissions');\n\n const currentPermissions = map('action', currentPermissionsResult || []);\n const newPermissions = uniq(attributes.permissions);\n\n const actionsToDelete = difference(currentPermissions, newPermissions);\n const actionsToAdd = difference(newPermissions, currentPermissions);\n\n // TODO: improve efficiency here\n // method using a loop -- works but very inefficient\n await Promise.all(\n actionsToDelete.map((action) =>\n strapi.db.query(TRANSFER_TOKEN_PERMISSION_UID).delete({\n where: { action, token: id },\n })\n )\n );\n\n // TODO: improve efficiency here\n // using a loop -- works but very inefficient\n await Promise.all(\n actionsToAdd.map((action) =>\n strapi.db.query(TRANSFER_TOKEN_PERMISSION_UID).create({\n data: { action, token: id },\n })\n )\n );\n }\n\n // retrieve permissions\n const permissionsFromDb: TransferTokenPermission[] = await strapi.db\n .query(TRANSFER_TOKEN_UID)\n .load(updatedToken, 'permissions');\n\n return {\n ...updatedToken,\n permissions: permissionsFromDb ? permissionsFromDb.map((p) => p.action) : undefined,\n };\n })) as SanitizedTransferToken;\n\n const changes = getTokenChanges(\n {\n name: originalToken.name,\n description: originalToken.description,\n permissions: toActionRefs(originalToken.permissions),\n },\n { name: updated.name, description: updated.description, permissions: updated.permissions ?? [] }\n );\n\n if (Object.keys(changes).length > 0) {\n await emitAudit({ strapi }, AUDITED_EVENTS.TOKEN_UPDATE, {\n tokenId: originalToken.id,\n name: updated.name,\n kind: 'transfer',\n changes,\n });\n }\n\n return updated;\n};\n\n/**\n * Revoke (delete) a token\n */\nconst revoke = async (id: string | number): Promise<SanitizedTransferToken> => {\n const deleted = (await strapi.db.transaction(async () =>\n strapi.db\n .query(TRANSFER_TOKEN_UID)\n .delete({ select: SELECT_FIELDS, populate: POPULATE_FIELDS, where: { id } })\n )) as SanitizedTransferToken | null;\n\n if (deleted) {\n await emitAudit({ strapi }, AUDITED_EVENTS.TOKEN_DELETE, {\n tokenId: deleted.id,\n name: deleted.name,\n kind: 'transfer',\n });\n }\n\n return deleted as SanitizedTransferToken;\n};\n\n/**\n * Get a token\n */\nconst getBy = async (\n whereParams = {} as {\n id?: string | number;\n name?: string;\n lastUsedAt?: number;\n description?: string;\n accessKey?: string;\n }\n): Promise<SanitizedTransferToken | null> => {\n if (Object.keys(whereParams).length === 0) {\n return null;\n }\n\n const token = await strapi.db\n .query(TRANSFER_TOKEN_UID)\n .findOne({ select: SELECT_FIELDS, populate: POPULATE_FIELDS, where: whereParams });\n\n if (!token) {\n return token;\n }\n\n return flattenTokenPermissions(token);\n};\n\n/**\n * Retrieve a token by id\n */\nconst getById = async (id: string | number): Promise<SanitizedTransferToken | null> => {\n return getBy({ id });\n};\n\n/**\n * Retrieve a token by name\n */\nconst getByName = async (name: string): Promise<SanitizedTransferToken | null> => {\n return getBy({ name });\n};\n\n/**\n * Check if token exists\n */\nconst exists = async (\n whereParams = {} as {\n id?: string | number;\n name?: string;\n lastUsedAt?: number;\n description?: string;\n accessKey?: string;\n }\n): Promise<boolean> => {\n const transferToken = await getBy(whereParams);\n\n return !!transferToken;\n};\n\nconst regenerate = async (id: string | number): Promise<TransferToken> => {\n const accessKey = crypto.randomBytes(128).toString('hex');\n const transferToken = (await strapi.db.transaction(async () =>\n strapi.db.query(TRANSFER_TOKEN_UID).update({\n select: ['id', 'name', 'accessKey'],\n where: { id },\n data: {\n accessKey: hash(accessKey),\n },\n })\n )) as TransferToken;\n\n if (!transferToken) {\n throw new NotFoundError('The provided token id does not exist');\n }\n\n await emitAudit({ strapi }, AUDITED_EVENTS.TOKEN_REGENERATE, {\n tokenId: transferToken.id,\n name: transferToken.name,\n kind: 'transfer',\n });\n\n return {\n ...transferToken,\n accessKey,\n };\n};\n\nconst getExpirationFields = (lifespan: TransferToken['lifespan']) => {\n // it must be nil or a finite number >= 0\n const isValidNumber = isNumber(lifespan) && Number.isFinite(lifespan) && lifespan > 0;\n if (!isValidNumber && !isNil(lifespan)) {\n throw new ValidationError('lifespan must be a positive number or null');\n }\n\n return {\n lifespan: lifespan || null,\n expiresAt: lifespan ? Date.now() + lifespan : null,\n };\n};\n\n/**\n * Return a secure sha512 hash of an accessKey\n */\nconst hash = (accessKey: string): string => {\n const { hasValidTokenSalt } = getService('transfer').utils;\n\n if (!hasValidTokenSalt()) {\n throw new TypeError('Required token salt is not defined');\n }\n\n return crypto\n .createHmac('sha512', strapi.config.get('admin.transfer.token.salt'))\n .update(accessKey)\n .digest('hex');\n};\n\nconst checkSaltIsDefined = () => {\n const { hasValidTokenSalt } = getService('transfer').utils;\n\n // Ignore the check if the data-transfer feature is manually disabled\n if (!strapi.config.get('server.transfer.remote.enabled')) {\n return;\n }\n\n if (!hasValidTokenSalt()) {\n process.emitWarning(\n `Missing transfer.token.salt: Data transfer features have been disabled.\nPlease set transfer.token.salt in config/admin.js (ex: you can generate one using Node with \\`crypto.randomBytes(16).toString('base64')\\`)\nFor security reasons, prefer storing the secret in an environment variable and read it in config/admin.js. See https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.html#configuration-using-environment-variables.`\n );\n }\n};\n\n/**\n * Flatten a token's database permissions objects to an array of strings\n */\nconst flattenTokenPermissions = (token: DatabaseTransferToken): TransferToken => {\n if (!token) {\n return token;\n }\n\n return {\n ...token,\n permissions: isArray(token.permissions)\n ? map('action', token.permissions as TransferTokenPermission[])\n : token.permissions,\n };\n};\n\n/**\n * Assert that a token's permissions are valid\n */\nconst assertTokenPermissionsValidity = (attributes: TokenUpdatePayload) => {\n const permissionService = strapi.service('admin::transfer').permission;\n const validPermissions = permissionService.providers.action.keys();\n const invalidPermissions = difference(attributes.permissions, validPermissions);\n\n if (!isEmpty(invalidPermissions)) {\n throw new ValidationError(`Unknown permissions provided: ${invalidPermissions.join(', ')}`);\n }\n};\n\n/**\n * Check if a token's lifespan is valid\n */\nconst isValidLifespan = (lifespan: unknown) => {\n if (isNil(lifespan)) {\n return true;\n }\n\n if (\n !isNumber(lifespan) ||\n !Object.values(constants.TRANSFER_TOKEN_LIFESPANS).includes(lifespan)\n ) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Assert that a token's lifespan is valid\n */\nconst assertValidLifespan = (lifespan: unknown) => {\n if (!isValidLifespan(lifespan)) {\n throw new ValidationError(\n `lifespan must be one of the following values:\n ${Object.values(constants.TRANSFER_TOKEN_LIFESPANS).join(', ')}`\n );\n }\n};\n\nexport {\n create,\n list,\n exists,\n getBy,\n getById,\n getByName,\n update,\n revoke,\n regenerate,\n hash,\n checkSaltIsDefined,\n};\n"],"names":["ValidationError","NotFoundError","errors","TRANSFER_TOKEN_UID","TRANSFER_TOKEN_PERMISSION_UID","SELECT_FIELDS","POPULATE_FIELDS","list","tokens","strapi","db","query","findMany","select","populate","orderBy","name","map","token","flattenTokenPermissions","generateRandomAccessKey","crypto","randomBytes","toString","validateAccessKey","accessKey","assert","length","hasAccessKey","attributes","create","assertTokenPermissionsValidity","assertValidLifespan","lifespan","result","transaction","transferToken","data","omit","hash","getExpirationFields","Promise","all","uniq","permissions","action","currentPermissions","load","Object","assign","emitAudit","AUDITED_EVENTS","TOKEN_CREATE","tokenId","id","kind","description","expiresAt","update","originalToken","findOne","where","updated","updatedToken","currentPermissionsResult","newPermissions","actionsToDelete","difference","actionsToAdd","delete","permissionsFromDb","p","undefined","changes","getTokenChanges","toActionRefs","keys","TOKEN_UPDATE","revoke","deleted","TOKEN_DELETE","getBy","whereParams","getById","getByName","exists","regenerate","TOKEN_REGENERATE","isValidNumber","isNumber","Number","isFinite","isNil","Date","now","hasValidTokenSalt","getService","utils","TypeError","createHmac","config","get","digest","checkSaltIsDefined","process","emitWarning","isArray","permissionService","service","permission","validPermissions","providers","invalidPermissions","isEmpty","join","isValidLifespan","values","constants","TRANSFER_TOKEN_LIFESPANS","includes"],"mappings":"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"}
1
+ {"version":3,"file":"token.mjs","sources":["../../../../../../server/src/services/transfer/token.ts"],"sourcesContent":["import crypto from 'crypto';\nimport assert from 'assert';\nimport { omit, difference, isEmpty, isNumber } from 'lodash';\n\nimport { errors, emitAudit } from '@strapi/utils';\nimport '@strapi/types';\nimport constants from '../constants';\nimport { getService } from '../../utils';\nimport { AUDITED_EVENTS, getTokenChanges, toActionRefs } from '../../audit-logs/tokens';\nimport {\n DatabaseTransferToken,\n SanitizedTransferToken,\n TokenCreatePayload,\n TokenUpdatePayload,\n TransferToken,\n TransferTokenPermission,\n} from '../../../../shared/contracts/transfer';\n\nconst { ValidationError, NotFoundError } = errors;\n\nconst TRANSFER_TOKEN_UID = 'admin::transfer-token';\nconst TRANSFER_TOKEN_PERMISSION_UID = 'admin::transfer-token-permission';\n\nconst SELECT_FIELDS = [\n 'id',\n 'name',\n 'description',\n 'lastUsedAt',\n 'lifespan',\n 'expiresAt',\n 'createdAt',\n 'updatedAt',\n] as const;\n\nconst POPULATE_FIELDS = ['permissions'] as const;\n\n/**\n * Return a list of all tokens and their permissions\n */\nconst list = async (): Promise<SanitizedTransferToken[]> => {\n const tokens: DatabaseTransferToken[] = await strapi.db.query(TRANSFER_TOKEN_UID).findMany({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n orderBy: { name: 'ASC' },\n });\n\n if (!tokens) return tokens;\n return tokens.map((token) => flattenTokenPermissions(token));\n};\n\n/**\n * Create a random token's access key\n */\nconst generateRandomAccessKey = (): string => crypto.randomBytes(128).toString('hex');\n\n/**\n * Validate the given access key's format and returns it if valid\n */\nconst validateAccessKey = (accessKey: string): string => {\n assert(typeof accessKey === 'string', 'Access key needs to be a string');\n assert(accessKey.length >= 15, 'Access key needs to have at least 15 characters');\n\n return accessKey;\n};\n\nexport const hasAccessKey = <T extends { accessKey?: string }>(\n attributes: T\n): attributes is T & { accessKey: string } => {\n return 'accessKey' in attributes;\n};\n\n/**\n * Create a token and its permissions\n */\nconst create = async (attributes: TokenCreatePayload): Promise<TransferToken> => {\n const accessKey = hasAccessKey(attributes)\n ? validateAccessKey(attributes.accessKey)\n : generateRandomAccessKey();\n\n // Make sure the access key isn't picked up directly from the attributes for the next steps\n delete attributes.accessKey;\n\n assertTokenPermissionsValidity(attributes);\n assertValidLifespan(attributes.lifespan);\n\n const result = (await strapi.db.transaction(async () => {\n const transferToken = await strapi.db.query(TRANSFER_TOKEN_UID).create({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n data: {\n ...omit(attributes, 'permissions'),\n accessKey: hash(accessKey),\n ...getExpirationFields(attributes.lifespan),\n },\n });\n\n await Promise.all(\n [...new Set(attributes.permissions)].map((action) =>\n strapi.db\n .query(TRANSFER_TOKEN_PERMISSION_UID)\n .create({ data: { action, token: transferToken } })\n )\n );\n\n const currentPermissions: TransferTokenPermission[] = await strapi.db\n .query(TRANSFER_TOKEN_UID)\n .load(transferToken, 'permissions');\n\n if (currentPermissions) {\n Object.assign(transferToken, {\n permissions: Array.from(currentPermissions ?? [], (permission) => permission?.action),\n });\n }\n\n return transferToken;\n })) as TransferToken;\n\n await emitAudit({ strapi }, AUDITED_EVENTS.TOKEN_CREATE, {\n tokenId: result.id,\n name: result.name,\n kind: 'transfer',\n description: result.description ?? null,\n lifespan: result.lifespan,\n expiresAt: result.expiresAt,\n permissions: result.permissions ?? [],\n });\n\n return { ...result, accessKey };\n};\n\n/**\n * Update a token and its permissions\n */\nconst update = async (\n id: string | number,\n attributes: TokenUpdatePayload\n): Promise<SanitizedTransferToken> => {\n // Populated with its permissions: the audit row for this update lists what changed,\n // so the state before the write is needed.\n const originalToken: DatabaseTransferToken | null = await strapi.db\n .query(TRANSFER_TOKEN_UID)\n .findOne({ where: { id }, populate: POPULATE_FIELDS });\n\n if (!originalToken) {\n throw new NotFoundError('Token not found');\n }\n\n assertTokenPermissionsValidity(attributes);\n assertValidLifespan(attributes.lifespan);\n\n const updated = (await strapi.db.transaction(async () => {\n const updatedToken = await strapi.db.query(TRANSFER_TOKEN_UID).update({\n select: SELECT_FIELDS,\n where: { id },\n data: {\n ...omit(attributes, 'permissions'),\n },\n });\n\n if (attributes.permissions) {\n const currentPermissionsResult = await strapi.db\n .query(TRANSFER_TOKEN_UID)\n .load(updatedToken, 'permissions');\n\n const currentPermissions = Array.from(\n currentPermissionsResult || [],\n (permission: TransferTokenPermission) => permission?.action\n );\n const newPermissions = [...new Set(attributes.permissions)];\n\n const actionsToDelete = difference(currentPermissions, newPermissions);\n const actionsToAdd = difference(newPermissions, currentPermissions);\n\n // TODO: improve efficiency here\n // method using a loop -- works but very inefficient\n await Promise.all(\n actionsToDelete.map((action) =>\n strapi.db.query(TRANSFER_TOKEN_PERMISSION_UID).delete({\n where: { action, token: id },\n })\n )\n );\n\n // TODO: improve efficiency here\n // using a loop -- works but very inefficient\n await Promise.all(\n actionsToAdd.map((action) =>\n strapi.db.query(TRANSFER_TOKEN_PERMISSION_UID).create({\n data: { action, token: id },\n })\n )\n );\n }\n\n // retrieve permissions\n const permissionsFromDb: TransferTokenPermission[] = await strapi.db\n .query(TRANSFER_TOKEN_UID)\n .load(updatedToken, 'permissions');\n\n return {\n ...updatedToken,\n permissions: permissionsFromDb ? permissionsFromDb.map((p) => p.action) : undefined,\n };\n })) as SanitizedTransferToken;\n\n const changes = getTokenChanges(\n {\n name: originalToken.name,\n description: originalToken.description,\n permissions: toActionRefs(originalToken.permissions),\n },\n { name: updated.name, description: updated.description, permissions: updated.permissions ?? [] }\n );\n\n if (Object.keys(changes).length > 0) {\n await emitAudit({ strapi }, AUDITED_EVENTS.TOKEN_UPDATE, {\n tokenId: originalToken.id,\n name: updated.name,\n kind: 'transfer',\n changes,\n });\n }\n\n return updated;\n};\n\n/**\n * Revoke (delete) a token\n */\nconst revoke = async (id: string | number): Promise<SanitizedTransferToken> => {\n const deleted = (await strapi.db.transaction(async () =>\n strapi.db\n .query(TRANSFER_TOKEN_UID)\n .delete({ select: SELECT_FIELDS, populate: POPULATE_FIELDS, where: { id } })\n )) as SanitizedTransferToken | null;\n\n if (deleted) {\n await emitAudit({ strapi }, AUDITED_EVENTS.TOKEN_DELETE, {\n tokenId: deleted.id,\n name: deleted.name,\n kind: 'transfer',\n });\n }\n\n return deleted as SanitizedTransferToken;\n};\n\n/**\n * Get a token\n */\nconst getBy = async (\n whereParams = {} as {\n id?: string | number;\n name?: string;\n lastUsedAt?: number;\n description?: string;\n accessKey?: string;\n }\n): Promise<SanitizedTransferToken | null> => {\n if (Object.keys(whereParams).length === 0) {\n return null;\n }\n\n const token = await strapi.db\n .query(TRANSFER_TOKEN_UID)\n .findOne({ select: SELECT_FIELDS, populate: POPULATE_FIELDS, where: whereParams });\n\n if (!token) {\n return token;\n }\n\n return flattenTokenPermissions(token);\n};\n\n/**\n * Retrieve a token by id\n */\nconst getById = async (id: string | number): Promise<SanitizedTransferToken | null> => {\n return getBy({ id });\n};\n\n/**\n * Retrieve a token by name\n */\nconst getByName = async (name: string): Promise<SanitizedTransferToken | null> => {\n return getBy({ name });\n};\n\n/**\n * Check if token exists\n */\nconst exists = async (\n whereParams = {} as {\n id?: string | number;\n name?: string;\n lastUsedAt?: number;\n description?: string;\n accessKey?: string;\n }\n): Promise<boolean> => {\n const transferToken = await getBy(whereParams);\n\n return !!transferToken;\n};\n\nconst regenerate = async (id: string | number): Promise<TransferToken> => {\n const accessKey = crypto.randomBytes(128).toString('hex');\n const transferToken = (await strapi.db.transaction(async () =>\n strapi.db.query(TRANSFER_TOKEN_UID).update({\n select: ['id', 'name', 'accessKey'],\n where: { id },\n data: {\n accessKey: hash(accessKey),\n },\n })\n )) as TransferToken;\n\n if (!transferToken) {\n throw new NotFoundError('The provided token id does not exist');\n }\n\n await emitAudit({ strapi }, AUDITED_EVENTS.TOKEN_REGENERATE, {\n tokenId: transferToken.id,\n name: transferToken.name,\n kind: 'transfer',\n });\n\n return {\n ...transferToken,\n accessKey,\n };\n};\n\nconst getExpirationFields = (lifespan: TransferToken['lifespan']) => {\n // it must be nil or a finite number >= 0\n const isValidNumber = isNumber(lifespan) && Number.isFinite(lifespan) && lifespan > 0;\n if (!isValidNumber && lifespan != null) {\n throw new ValidationError('lifespan must be a positive number or null');\n }\n\n return {\n lifespan: lifespan || null,\n expiresAt: lifespan ? Date.now() + lifespan : null,\n };\n};\n\n/**\n * Return a secure sha512 hash of an accessKey\n */\nconst hash = (accessKey: string): string => {\n const { hasValidTokenSalt } = getService('transfer').utils;\n\n if (!hasValidTokenSalt()) {\n throw new TypeError('Required token salt is not defined');\n }\n\n return crypto\n .createHmac('sha512', strapi.config.get('admin.transfer.token.salt'))\n .update(accessKey)\n .digest('hex');\n};\n\nconst checkSaltIsDefined = () => {\n const { hasValidTokenSalt } = getService('transfer').utils;\n\n // Ignore the check if the data-transfer feature is manually disabled\n if (!strapi.config.get('server.transfer.remote.enabled')) {\n return;\n }\n\n if (!hasValidTokenSalt()) {\n process.emitWarning(\n `Missing transfer.token.salt: Data transfer features have been disabled.\nPlease set transfer.token.salt in config/admin.js (ex: you can generate one using Node with \\`crypto.randomBytes(16).toString('base64')\\`)\nFor security reasons, prefer storing the secret in an environment variable and read it in config/admin.js. See https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.html#configuration-using-environment-variables.`\n );\n }\n};\n\n/**\n * Flatten a token's database permissions objects to an array of strings\n */\nconst flattenTokenPermissions = (token: DatabaseTransferToken): TransferToken => {\n if (!token) {\n return token;\n }\n\n return {\n ...token,\n permissions: Array.isArray(token.permissions)\n ? Array.from(\n token.permissions as TransferTokenPermission[],\n (permission) => permission?.action\n )\n : token.permissions,\n };\n};\n\n/**\n * Assert that a token's permissions are valid\n */\nconst assertTokenPermissionsValidity = (attributes: TokenUpdatePayload) => {\n const permissionService = strapi.service('admin::transfer').permission;\n const validPermissions = permissionService.providers.action.keys();\n const invalidPermissions = difference(attributes.permissions, validPermissions);\n\n if (!isEmpty(invalidPermissions)) {\n throw new ValidationError(`Unknown permissions provided: ${invalidPermissions.join(', ')}`);\n }\n};\n\n/**\n * Check if a token's lifespan is valid\n */\nconst isValidLifespan = (lifespan: unknown) => {\n if (lifespan == null) {\n return true;\n }\n\n if (\n !isNumber(lifespan) ||\n !Object.values(constants.TRANSFER_TOKEN_LIFESPANS).includes(lifespan)\n ) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Assert that a token's lifespan is valid\n */\nconst assertValidLifespan = (lifespan: unknown) => {\n if (!isValidLifespan(lifespan)) {\n throw new ValidationError(\n `lifespan must be one of the following values:\n ${Object.values(constants.TRANSFER_TOKEN_LIFESPANS).join(', ')}`\n );\n }\n};\n\nexport {\n create,\n list,\n exists,\n getBy,\n getById,\n getByName,\n update,\n revoke,\n regenerate,\n hash,\n checkSaltIsDefined,\n};\n"],"names":["ValidationError","NotFoundError","errors","TRANSFER_TOKEN_UID","TRANSFER_TOKEN_PERMISSION_UID","SELECT_FIELDS","POPULATE_FIELDS","list","tokens","strapi","db","query","findMany","select","populate","orderBy","name","map","token","flattenTokenPermissions","generateRandomAccessKey","crypto","randomBytes","toString","validateAccessKey","accessKey","assert","length","hasAccessKey","attributes","create","assertTokenPermissionsValidity","assertValidLifespan","lifespan","result","transaction","transferToken","data","omit","hash","getExpirationFields","Promise","all","Set","permissions","action","currentPermissions","load","Object","assign","Array","from","permission","emitAudit","AUDITED_EVENTS","TOKEN_CREATE","tokenId","id","kind","description","expiresAt","update","originalToken","findOne","where","updated","updatedToken","currentPermissionsResult","newPermissions","actionsToDelete","difference","actionsToAdd","delete","permissionsFromDb","p","undefined","changes","getTokenChanges","toActionRefs","keys","TOKEN_UPDATE","revoke","deleted","TOKEN_DELETE","getBy","whereParams","getById","getByName","exists","regenerate","TOKEN_REGENERATE","isValidNumber","isNumber","Number","isFinite","Date","now","hasValidTokenSalt","getService","utils","TypeError","createHmac","config","get","digest","checkSaltIsDefined","process","emitWarning","isArray","permissionService","service","validPermissions","providers","invalidPermissions","isEmpty","join","isValidLifespan","values","constants","TRANSFER_TOKEN_LIFESPANS","includes"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
3
  var _ = require('lodash');
4
- var fp = require('lodash/fp');
5
4
  var utils = require('@strapi/utils');
6
5
  var user$1 = require('../domain/user.js');
6
+ var adminUsers = require('../audit-logs/admin-users.js');
7
7
  var commonValidators = require('../validation/common-validators.js');
8
8
  var index = require('../utils/index.js');
9
9
  var constants = require('./constants.js');
@@ -60,16 +60,19 @@ attributes)=>{
60
60
  });
61
61
  return createdUser;
62
62
  };
63
- const emitUserCreated = (user)=>{
63
+ const emitUserCreated = async (user)=>{
64
64
  index.getService('metrics').sendDidInviteUser();
65
- strapi.eventHub.emit('user.create', {
65
+ strapi.eventHub.emit(adminUsers.LEGACY_USER_EVENTS.CREATE, {
66
66
  user: sanitizeUser(user)
67
67
  });
68
+ await adminUsers.emitAdminUserCreated({
69
+ strapi
70
+ }, user);
68
71
  };
69
72
  const create = async (// isActive is added in the controller, it's not sent by the API.
70
73
  attributes)=>{
71
74
  const createdUser = await createUserInDatabase(attributes);
72
- emitUserCreated(createdUser);
75
+ await emitUserCreated(createdUser);
73
76
  return createdUser;
74
77
  };
75
78
  const createFirstAdmin = async (attributes)=>{
@@ -97,7 +100,7 @@ const createFirstAdmin = async (attributes)=>{
97
100
  ]
98
101
  });
99
102
  });
100
- emitUserCreated(createdUser);
103
+ await emitUserCreated(createdUser);
101
104
  return createdUser;
102
105
  };
103
106
  /**
@@ -121,6 +124,15 @@ const createFirstAdmin = async (attributes)=>{
121
124
  throw new ValidationError('You must have at least one user with super admin role.');
122
125
  }
123
126
  }
127
+ // The audit log records what changed, so it needs the row before the write
128
+ const previous = adminUsers.touchesTrackedFields(attributes) ? await strapi.db.query('admin::user').findOne({
129
+ where: {
130
+ id
131
+ },
132
+ populate: [
133
+ 'roles'
134
+ ]
135
+ }) : null;
124
136
  // hash password if a new one is sent
125
137
  if (___default.default.has(attributes, 'password')) {
126
138
  const hashedPassword = await index.getService('auth').hashPassword(attributes.password);
@@ -136,9 +148,16 @@ const createFirstAdmin = async (attributes)=>{
136
148
  'roles'
137
149
  ]
138
150
  });
139
- strapi.eventHub.emit('user.update', {
151
+ strapi.eventHub.emit(adminUsers.LEGACY_USER_EVENTS.UPDATE, {
140
152
  user: sanitizeUser(updatedUser)
141
153
  });
154
+ await adminUsers.emitAdminUserUpdateAudits({
155
+ strapi
156
+ }, {
157
+ previous,
158
+ updated: updatedUser,
159
+ attributes
160
+ });
142
161
  return updatedUser;
143
162
  }
144
163
  const updatedUser = await strapi.db.query('admin::user').update({
@@ -151,9 +170,16 @@ const createFirstAdmin = async (attributes)=>{
151
170
  ]
152
171
  });
153
172
  if (updatedUser) {
154
- strapi.eventHub.emit('user.update', {
173
+ strapi.eventHub.emit(adminUsers.LEGACY_USER_EVENTS.UPDATE, {
155
174
  user: sanitizeUser(updatedUser)
156
175
  });
176
+ await adminUsers.emitAdminUserUpdateAudits({
177
+ strapi
178
+ }, {
179
+ previous,
180
+ updated: updatedUser,
181
+ attributes
182
+ });
157
183
  }
158
184
  return updatedUser;
159
185
  };
@@ -258,13 +284,17 @@ const createFirstAdmin = async (attributes)=>{
258
284
  if (!matchingUser) {
259
285
  throw new ValidationError('Invalid registration info');
260
286
  }
261
- return index.getService('user').updateById(matchingUser.id, {
287
+ const registeredUser = await index.getService('user').updateById(matchingUser.id, {
262
288
  password: userInfo.password,
263
289
  firstname: userInfo.firstname,
264
290
  lastname: userInfo.lastname,
265
291
  registrationToken: null,
266
292
  isActive: true
267
293
  });
294
+ await utils.emitAudit({
295
+ strapi
296
+ }, adminUsers.AUDITED_EVENTS.INVITE_ACCEPT, adminUsers.toAdminUserEvent(registeredUser));
297
+ return registeredUser;
268
298
  };
269
299
  /**
270
300
  * Find one user
@@ -296,11 +326,11 @@ const createFirstAdmin = async (attributes)=>{
296
326
  /** Find many users (paginated)
297
327
  * @param params
298
328
  */ const findPage = async (params = {})=>{
299
- const query = strapi.get('query-params').transform('admin::user', fp.defaults({
329
+ const query = strapi.get('query-params').transform('admin::user', _.defaults({}, params, {
300
330
  populate: [
301
331
  'roles'
302
332
  ]
303
- }, params));
333
+ }));
304
334
  return strapi.db.query('admin::user').findPage(query);
305
335
  };
306
336
  /** Delete a user
@@ -339,9 +369,12 @@ const createFirstAdmin = async (attributes)=>{
339
369
  if (sessionManager && sessionManager.hasOrigin('admin')) {
340
370
  await sessionManager('admin').invalidateRefreshToken(String(id));
341
371
  }
342
- strapi.eventHub.emit('user.delete', {
372
+ strapi.eventHub.emit(adminUsers.LEGACY_USER_EVENTS.DELETE, {
343
373
  user: sanitizeUser(deletedUser)
344
374
  });
375
+ await adminUsers.emitAdminUserDeleted({
376
+ strapi
377
+ }, deletedUser);
345
378
  return deletedUser;
346
379
  };
347
380
  /** Delete a user
@@ -377,9 +410,14 @@ const createFirstAdmin = async (attributes)=>{
377
410
  }
378
411
  deletedUsers.push(deletedUser);
379
412
  }
380
- strapi.eventHub.emit('user.delete', {
413
+ strapi.eventHub.emit(adminUsers.LEGACY_USER_EVENTS.DELETE, {
381
414
  users: deletedUsers.map((deletedUser)=>sanitizeUser(deletedUser))
382
415
  });
416
+ for (const deletedUser of deletedUsers){
417
+ await adminUsers.emitAdminUserDeleted({
418
+ strapi
419
+ }, deletedUser);
420
+ }
383
421
  return deletedUsers;
384
422
  };
385
423
  /** Count the users that don't have any associated roles