@strapi/admin 5.56.0 → 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 (311) 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/features/Tracking.js +28 -8
  22. package/dist/admin/admin/src/features/Tracking.js.map +1 -1
  23. package/dist/admin/admin/src/features/Tracking.mjs +29 -10
  24. package/dist/admin/admin/src/features/Tracking.mjs.map +1 -1
  25. package/dist/admin/admin/src/layouts/AuthenticatedLayout.js +4 -20
  26. package/dist/admin/admin/src/layouts/AuthenticatedLayout.js.map +1 -1
  27. package/dist/admin/admin/src/layouts/AuthenticatedLayout.mjs +4 -20
  28. package/dist/admin/admin/src/layouts/AuthenticatedLayout.mjs.map +1 -1
  29. package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.js +59 -0
  30. package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.js.map +1 -0
  31. package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.mjs +37 -0
  32. package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.mjs.map +1 -0
  33. package/dist/admin/admin/src/translations/en.json.js +5 -0
  34. package/dist/admin/admin/src/translations/en.json.js.map +1 -1
  35. package/dist/admin/admin/src/translations/en.json.mjs +5 -0
  36. package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
  37. package/dist/admin/admin/src/utils/getFetchClient.js +3 -3
  38. package/dist/admin/admin/src/utils/getFetchClient.js.map +1 -1
  39. package/dist/admin/admin/src/utils/getFetchClient.mjs +2 -2
  40. package/dist/admin/admin/src/utils/getFetchClient.mjs.map +1 -1
  41. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js +6 -1
  42. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js.map +1 -1
  43. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs +6 -1
  44. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs.map +1 -1
  45. package/dist/admin/src/components/MediaLibraryBanner.d.ts +10 -1
  46. package/dist/admin/src/components/TopBanners.d.ts +8 -0
  47. package/dist/admin/src/features/Tracking.d.ts +12 -1
  48. package/dist/admin/src/layouts/useAuthenticatedAccessTracking.d.ts +6 -0
  49. package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.d.ts +5 -0
  50. package/dist/ee/server/src/controllers/admin.d.ts.map +1 -1
  51. package/dist/ee/server/src/controllers/authentication-utils/utils.d.ts +8 -2
  52. package/dist/ee/server/src/controllers/authentication-utils/utils.d.ts.map +1 -1
  53. package/dist/ee/server/src/controllers/authentication.d.ts.map +1 -1
  54. package/dist/ee/server/src/controllers/user.d.ts.map +1 -1
  55. package/dist/ee/server/src/index.d.ts +4 -1
  56. package/dist/ee/server/src/index.d.ts.map +1 -1
  57. package/dist/ee/server/src/services/index.d.ts +4 -1
  58. package/dist/ee/server/src/services/index.d.ts.map +1 -1
  59. package/dist/ee/server/src/services/metrics.d.ts.map +1 -1
  60. package/dist/ee/server/src/services/persist-tables.d.ts.map +1 -1
  61. package/dist/ee/server/src/services/seat-enforcement.d.ts +3 -1
  62. package/dist/ee/server/src/services/seat-enforcement.d.ts.map +1 -1
  63. package/dist/server/ee/server/src/controllers/admin.js +3 -4
  64. package/dist/server/ee/server/src/controllers/admin.js.map +1 -1
  65. package/dist/server/ee/server/src/controllers/admin.mjs +3 -4
  66. package/dist/server/ee/server/src/controllers/admin.mjs.map +1 -1
  67. package/dist/server/ee/server/src/controllers/authentication-utils/utils.js +2 -2
  68. package/dist/server/ee/server/src/controllers/authentication-utils/utils.js.map +1 -1
  69. package/dist/server/ee/server/src/controllers/authentication-utils/utils.mjs +2 -2
  70. package/dist/server/ee/server/src/controllers/authentication-utils/utils.mjs.map +1 -1
  71. package/dist/server/ee/server/src/controllers/authentication.js +11 -11
  72. package/dist/server/ee/server/src/controllers/authentication.js.map +1 -1
  73. package/dist/server/ee/server/src/controllers/authentication.mjs +11 -11
  74. package/dist/server/ee/server/src/controllers/authentication.mjs.map +1 -1
  75. package/dist/server/ee/server/src/controllers/user.js +7 -8
  76. package/dist/server/ee/server/src/controllers/user.js.map +1 -1
  77. package/dist/server/ee/server/src/controllers/user.mjs +8 -9
  78. package/dist/server/ee/server/src/controllers/user.mjs.map +1 -1
  79. package/dist/server/ee/server/src/services/metrics.js +9 -7
  80. package/dist/server/ee/server/src/services/metrics.js.map +1 -1
  81. package/dist/server/ee/server/src/services/metrics.mjs +9 -7
  82. package/dist/server/ee/server/src/services/metrics.mjs.map +1 -1
  83. package/dist/server/ee/server/src/services/persist-tables.js +3 -4
  84. package/dist/server/ee/server/src/services/persist-tables.js.map +1 -1
  85. package/dist/server/ee/server/src/services/persist-tables.mjs +3 -4
  86. package/dist/server/ee/server/src/services/persist-tables.mjs.map +1 -1
  87. package/dist/server/ee/server/src/services/role.js +2 -2
  88. package/dist/server/ee/server/src/services/role.js.map +1 -1
  89. package/dist/server/ee/server/src/services/role.mjs +1 -1
  90. package/dist/server/ee/server/src/services/role.mjs.map +1 -1
  91. package/dist/server/ee/server/src/services/seat-enforcement.js +20 -20
  92. package/dist/server/ee/server/src/services/seat-enforcement.js.map +1 -1
  93. package/dist/server/ee/server/src/services/seat-enforcement.mjs +20 -20
  94. package/dist/server/ee/server/src/services/seat-enforcement.mjs.map +1 -1
  95. package/dist/server/ee/server/src/services/user.js +1 -2
  96. package/dist/server/ee/server/src/services/user.js.map +1 -1
  97. package/dist/server/ee/server/src/services/user.mjs +2 -3
  98. package/dist/server/ee/server/src/services/user.mjs.map +1 -1
  99. package/dist/server/ee/server/src/utils/sso-lock.js +2 -2
  100. package/dist/server/ee/server/src/utils/sso-lock.js.map +1 -1
  101. package/dist/server/ee/server/src/utils/sso-lock.mjs +1 -1
  102. package/dist/server/ee/server/src/utils/sso-lock.mjs.map +1 -1
  103. package/dist/server/server/src/audit-logs/admin-users.js +3 -3
  104. package/dist/server/server/src/audit-logs/admin-users.js.map +1 -1
  105. package/dist/server/server/src/audit-logs/admin-users.mjs +2 -2
  106. package/dist/server/server/src/audit-logs/admin-users.mjs.map +1 -1
  107. package/dist/server/server/src/audit-logs/tokens.js +3 -3
  108. package/dist/server/server/src/audit-logs/tokens.js.map +1 -1
  109. package/dist/server/server/src/audit-logs/tokens.mjs +2 -2
  110. package/dist/server/server/src/audit-logs/tokens.mjs.map +1 -1
  111. package/dist/server/server/src/audit-logs/webhooks.js +2 -2
  112. package/dist/server/server/src/audit-logs/webhooks.js.map +1 -1
  113. package/dist/server/server/src/audit-logs/webhooks.mjs +1 -1
  114. package/dist/server/server/src/audit-logs/webhooks.mjs.map +1 -1
  115. package/dist/server/server/src/bootstrap.js +6 -4
  116. package/dist/server/server/src/bootstrap.js.map +1 -1
  117. package/dist/server/server/src/bootstrap.mjs +6 -4
  118. package/dist/server/server/src/bootstrap.mjs.map +1 -1
  119. package/dist/server/server/src/controllers/admin-token.js +8 -8
  120. package/dist/server/server/src/controllers/admin-token.js.map +1 -1
  121. package/dist/server/server/src/controllers/admin-token.mjs +4 -4
  122. package/dist/server/server/src/controllers/admin-token.mjs.map +1 -1
  123. package/dist/server/server/src/controllers/admin.js +3 -5
  124. package/dist/server/server/src/controllers/admin.js.map +1 -1
  125. package/dist/server/server/src/controllers/admin.mjs +2 -4
  126. package/dist/server/server/src/controllers/admin.mjs.map +1 -1
  127. package/dist/server/server/src/controllers/api-token.js +8 -8
  128. package/dist/server/server/src/controllers/api-token.js.map +1 -1
  129. package/dist/server/server/src/controllers/api-token.mjs +4 -4
  130. package/dist/server/server/src/controllers/api-token.mjs.map +1 -1
  131. package/dist/server/server/src/controllers/formatters/conditions.js +2 -2
  132. package/dist/server/server/src/controllers/formatters/conditions.js.map +1 -1
  133. package/dist/server/server/src/controllers/formatters/conditions.mjs +2 -2
  134. package/dist/server/server/src/controllers/formatters/conditions.mjs.map +1 -1
  135. package/dist/server/server/src/controllers/transfer/index.js +2 -2
  136. package/dist/server/server/src/controllers/transfer/index.js.map +1 -1
  137. package/dist/server/server/src/controllers/transfer/index.mjs +2 -2
  138. package/dist/server/server/src/controllers/transfer/index.mjs.map +1 -1
  139. package/dist/server/server/src/controllers/transfer/token.js +8 -8
  140. package/dist/server/server/src/controllers/transfer/token.js.map +1 -1
  141. package/dist/server/server/src/controllers/transfer/token.mjs +4 -4
  142. package/dist/server/server/src/controllers/transfer/token.mjs.map +1 -1
  143. package/dist/server/server/src/domain/action/index.js +18 -16
  144. package/dist/server/server/src/domain/action/index.js.map +1 -1
  145. package/dist/server/server/src/domain/action/index.mjs +16 -14
  146. package/dist/server/server/src/domain/action/index.mjs.map +1 -1
  147. package/dist/server/server/src/domain/action/provider.mjs +4 -4
  148. package/dist/server/server/src/domain/action/provider.mjs.map +1 -1
  149. package/dist/server/server/src/domain/condition/index.js +7 -4
  150. package/dist/server/server/src/domain/condition/index.js.map +1 -1
  151. package/dist/server/server/src/domain/condition/index.mjs +7 -4
  152. package/dist/server/server/src/domain/condition/index.mjs.map +1 -1
  153. package/dist/server/server/src/domain/permission/index.js +24 -15
  154. package/dist/server/server/src/domain/permission/index.js.map +1 -1
  155. package/dist/server/server/src/domain/permission/index.mjs +21 -12
  156. package/dist/server/server/src/domain/permission/index.mjs.map +1 -1
  157. package/dist/server/server/src/middlewares/rateLimit.js +5 -5
  158. package/dist/server/server/src/middlewares/rateLimit.js.map +1 -1
  159. package/dist/server/server/src/middlewares/rateLimit.mjs +4 -4
  160. package/dist/server/server/src/middlewares/rateLimit.mjs.map +1 -1
  161. package/dist/server/server/src/register.js +6 -0
  162. package/dist/server/server/src/register.js.map +1 -1
  163. package/dist/server/server/src/register.mjs +6 -0
  164. package/dist/server/server/src/register.mjs.map +1 -1
  165. package/dist/server/server/src/services/action.js +1 -2
  166. package/dist/server/server/src/services/action.js.map +1 -1
  167. package/dist/server/server/src/services/action.mjs +1 -2
  168. package/dist/server/server/src/services/action.mjs.map +1 -1
  169. package/dist/server/server/src/services/api-token.js +61 -49
  170. package/dist/server/server/src/services/api-token.js.map +1 -1
  171. package/dist/server/server/src/services/api-token.mjs +53 -41
  172. package/dist/server/server/src/services/api-token.mjs.map +1 -1
  173. package/dist/server/server/src/services/condition.js +2 -2
  174. package/dist/server/server/src/services/condition.js.map +1 -1
  175. package/dist/server/server/src/services/condition.mjs +1 -1
  176. package/dist/server/server/src/services/condition.mjs.map +1 -1
  177. package/dist/server/server/src/services/content-type.js +5 -4
  178. package/dist/server/server/src/services/content-type.js.map +1 -1
  179. package/dist/server/server/src/services/content-type.mjs +8 -7
  180. package/dist/server/server/src/services/content-type.mjs.map +1 -1
  181. package/dist/server/server/src/services/homepage.js +2 -1
  182. package/dist/server/server/src/services/homepage.js.map +1 -1
  183. package/dist/server/server/src/services/homepage.mjs +2 -1
  184. package/dist/server/server/src/services/homepage.mjs.map +1 -1
  185. package/dist/server/server/src/services/passport/local-strategy.js +2 -2
  186. package/dist/server/server/src/services/passport/local-strategy.js.map +1 -1
  187. package/dist/server/server/src/services/passport/local-strategy.mjs +1 -1
  188. package/dist/server/server/src/services/passport/local-strategy.mjs.map +1 -1
  189. package/dist/server/server/src/services/passport.js +1 -2
  190. package/dist/server/server/src/services/passport.js.map +1 -1
  191. package/dist/server/server/src/services/passport.mjs +1 -2
  192. package/dist/server/server/src/services/passport.mjs.map +1 -1
  193. package/dist/server/server/src/services/permission/engine.js +4 -4
  194. package/dist/server/server/src/services/permission/engine.js.map +1 -1
  195. package/dist/server/server/src/services/permission/engine.mjs +2 -2
  196. package/dist/server/server/src/services/permission/engine.mjs.map +1 -1
  197. package/dist/server/server/src/services/permission/permissions-manager/index.js +2 -3
  198. package/dist/server/server/src/services/permission/permissions-manager/index.js.map +1 -1
  199. package/dist/server/server/src/services/permission/permissions-manager/index.mjs +1 -2
  200. package/dist/server/server/src/services/permission/permissions-manager/index.mjs.map +1 -1
  201. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.js +6 -6
  202. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.js.map +1 -1
  203. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.mjs +4 -4
  204. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.mjs.map +1 -1
  205. package/dist/server/server/src/services/permission/permissions-manager/sanitize.js +47 -41
  206. package/dist/server/server/src/services/permission/permissions-manager/sanitize.js.map +1 -1
  207. package/dist/server/server/src/services/permission/permissions-manager/sanitize.mjs +44 -38
  208. package/dist/server/server/src/services/permission/permissions-manager/sanitize.mjs.map +1 -1
  209. package/dist/server/server/src/services/permission/permissions-manager/validate.js +30 -26
  210. package/dist/server/server/src/services/permission/permissions-manager/validate.js.map +1 -1
  211. package/dist/server/server/src/services/permission/permissions-manager/validate.mjs +28 -24
  212. package/dist/server/server/src/services/permission/permissions-manager/validate.mjs.map +1 -1
  213. package/dist/server/server/src/services/permission/queries.js +9 -9
  214. package/dist/server/server/src/services/permission/queries.js.map +1 -1
  215. package/dist/server/server/src/services/permission/queries.mjs +9 -9
  216. package/dist/server/server/src/services/permission/queries.mjs.map +1 -1
  217. package/dist/server/server/src/services/permission/rename-fields.js +118 -0
  218. package/dist/server/server/src/services/permission/rename-fields.js.map +1 -0
  219. package/dist/server/server/src/services/permission/rename-fields.mjs +116 -0
  220. package/dist/server/server/src/services/permission/rename-fields.mjs.map +1 -0
  221. package/dist/server/server/src/services/permission/sections-builder/index.js +2 -2
  222. package/dist/server/server/src/services/permission/sections-builder/index.js.map +1 -1
  223. package/dist/server/server/src/services/permission/sections-builder/index.mjs +2 -2
  224. package/dist/server/server/src/services/permission/sections-builder/index.mjs.map +1 -1
  225. package/dist/server/server/src/services/permission/sections-builder/section.js +1 -2
  226. package/dist/server/server/src/services/permission/sections-builder/section.js.map +1 -1
  227. package/dist/server/server/src/services/permission/sections-builder/section.mjs +1 -2
  228. package/dist/server/server/src/services/permission/sections-builder/section.mjs.map +1 -1
  229. package/dist/server/server/src/services/permission/sections-builder/utils.js +6 -6
  230. package/dist/server/server/src/services/permission/sections-builder/utils.js.map +1 -1
  231. package/dist/server/server/src/services/permission/sections-builder/utils.mjs +4 -4
  232. package/dist/server/server/src/services/permission/sections-builder/utils.mjs.map +1 -1
  233. package/dist/server/server/src/services/role.js +20 -19
  234. package/dist/server/server/src/services/role.js.map +1 -1
  235. package/dist/server/server/src/services/role.mjs +20 -19
  236. package/dist/server/server/src/services/role.mjs.map +1 -1
  237. package/dist/server/server/src/services/transfer/token.js +20 -16
  238. package/dist/server/server/src/services/transfer/token.js.map +1 -1
  239. package/dist/server/server/src/services/transfer/token.mjs +14 -10
  240. package/dist/server/server/src/services/transfer/token.mjs.map +1 -1
  241. package/dist/server/server/src/services/user.js +2 -3
  242. package/dist/server/server/src/services/user.js.map +1 -1
  243. package/dist/server/server/src/services/user.mjs +3 -4
  244. package/dist/server/server/src/services/user.mjs.map +1 -1
  245. package/dist/server/server/src/strategies/api-token-utils.js +2 -3
  246. package/dist/server/server/src/strategies/api-token-utils.js.map +1 -1
  247. package/dist/server/server/src/strategies/api-token-utils.mjs +2 -3
  248. package/dist/server/server/src/strategies/api-token-utils.mjs.map +1 -1
  249. package/dist/server/server/src/strategies/content-api-token.js +3 -3
  250. package/dist/server/server/src/strategies/content-api-token.js.map +1 -1
  251. package/dist/server/server/src/strategies/content-api-token.mjs +1 -1
  252. package/dist/server/server/src/strategies/content-api-token.mjs.map +1 -1
  253. package/dist/server/server/src/strategies/data-transfer.js +4 -4
  254. package/dist/server/server/src/strategies/data-transfer.js.map +1 -1
  255. package/dist/server/server/src/strategies/data-transfer.mjs +3 -3
  256. package/dist/server/server/src/strategies/data-transfer.mjs.map +1 -1
  257. package/dist/server/server/src/validation/common-validators.js +9 -10
  258. package/dist/server/server/src/validation/common-validators.js.map +1 -1
  259. package/dist/server/server/src/validation/common-validators.mjs +13 -14
  260. package/dist/server/server/src/validation/common-validators.mjs.map +1 -1
  261. package/dist/server/server/src/validation/user.js +1 -2
  262. package/dist/server/server/src/validation/user.js.map +1 -1
  263. package/dist/server/server/src/validation/user.mjs +1 -2
  264. package/dist/server/server/src/validation/user.mjs.map +1 -1
  265. package/dist/server/src/audit-logs/tokens.d.ts.map +1 -1
  266. package/dist/server/src/bootstrap.d.ts.map +1 -1
  267. package/dist/server/src/controllers/admin-token.d.ts.map +1 -1
  268. package/dist/server/src/controllers/admin.d.ts.map +1 -1
  269. package/dist/server/src/controllers/api-token.d.ts.map +1 -1
  270. package/dist/server/src/controllers/formatters/conditions.d.ts +1 -1
  271. package/dist/server/src/controllers/formatters/conditions.d.ts.map +1 -1
  272. package/dist/server/src/controllers/homepage.d.ts +1 -1
  273. package/dist/server/src/controllers/index.d.ts +1 -1
  274. package/dist/server/src/controllers/transfer/index.d.ts.map +1 -1
  275. package/dist/server/src/controllers/transfer/token.d.ts.map +1 -1
  276. package/dist/server/src/domain/action/index.d.ts +1 -0
  277. package/dist/server/src/domain/action/index.d.ts.map +1 -1
  278. package/dist/server/src/domain/condition/index.d.ts +2 -2
  279. package/dist/server/src/domain/condition/index.d.ts.map +1 -1
  280. package/dist/server/src/domain/permission/index.d.ts.map +1 -1
  281. package/dist/server/src/index.d.ts +3 -3
  282. package/dist/server/src/index.d.ts.map +1 -1
  283. package/dist/server/src/middlewares/index.d.ts.map +1 -1
  284. package/dist/server/src/middlewares/rateLimit.d.ts.map +1 -1
  285. package/dist/server/src/register.d.ts.map +1 -1
  286. package/dist/server/src/services/action.d.ts.map +1 -1
  287. package/dist/server/src/services/api-token.d.ts.map +1 -1
  288. package/dist/server/src/services/condition.d.ts.map +1 -1
  289. package/dist/server/src/services/content-type.d.ts.map +1 -1
  290. package/dist/server/src/services/homepage.d.ts +1 -1
  291. package/dist/server/src/services/homepage.d.ts.map +1 -1
  292. package/dist/server/src/services/index.d.ts +2 -2
  293. package/dist/server/src/services/index.d.ts.map +1 -1
  294. package/dist/server/src/services/passport/local-strategy.d.ts.map +1 -1
  295. package/dist/server/src/services/passport.d.ts.map +1 -1
  296. package/dist/server/src/services/permission/engine.d.ts.map +1 -1
  297. package/dist/server/src/services/permission/permissions-manager/permission-fields.d.ts.map +1 -1
  298. package/dist/server/src/services/permission/permissions-manager/sanitize.d.ts.map +1 -1
  299. package/dist/server/src/services/permission/permissions-manager/validate.d.ts.map +1 -1
  300. package/dist/server/src/services/permission/queries.d.ts.map +1 -1
  301. package/dist/server/src/services/permission/rename-fields.d.ts +21 -0
  302. package/dist/server/src/services/permission/rename-fields.d.ts.map +1 -0
  303. package/dist/server/src/services/permission/sections-builder/section.d.ts.map +1 -1
  304. package/dist/server/src/services/permission/sections-builder/utils.d.ts +1 -1
  305. package/dist/server/src/services/permission/sections-builder/utils.d.ts.map +1 -1
  306. package/dist/server/src/services/role.d.ts +1 -1
  307. package/dist/server/src/services/role.d.ts.map +1 -1
  308. package/dist/server/src/services/transfer/token.d.ts.map +1 -1
  309. package/dist/server/src/strategies/content-api-token.d.ts.map +1 -1
  310. package/dist/server/src/validation/user.d.ts.map +1 -1
  311. package/package.json +9 -9
@@ -2,7 +2,7 @@
2
2
 
3
3
  var crypto = require('crypto');
4
4
  var assert = require('assert');
5
- var fp = require('lodash/fp');
5
+ var _ = require('lodash');
6
6
  var utils = require('@strapi/utils');
7
7
  require('@strapi/types');
8
8
  var constants = require('../constants.js');
@@ -69,12 +69,14 @@ const hasAccessKey = (attributes)=>{
69
69
  select: SELECT_FIELDS,
70
70
  populate: POPULATE_FIELDS,
71
71
  data: {
72
- ...fp.omit('permissions', attributes),
72
+ ..._.omit(attributes, 'permissions'),
73
73
  accessKey: hash(accessKey),
74
74
  ...getExpirationFields(attributes.lifespan)
75
75
  }
76
76
  });
77
- await Promise.all(fp.uniq(attributes.permissions).map((action)=>strapi.db.query(TRANSFER_TOKEN_PERMISSION_UID).create({
77
+ await Promise.all([
78
+ ...new Set(attributes.permissions)
79
+ ].map((action)=>strapi.db.query(TRANSFER_TOKEN_PERMISSION_UID).create({
78
80
  data: {
79
81
  action,
80
82
  token: transferToken
@@ -83,7 +85,7 @@ const hasAccessKey = (attributes)=>{
83
85
  const currentPermissions = await strapi.db.query(TRANSFER_TOKEN_UID).load(transferToken, 'permissions');
84
86
  if (currentPermissions) {
85
87
  Object.assign(transferToken, {
86
- permissions: fp.map('action', currentPermissions)
88
+ permissions: Array.from(currentPermissions ?? [], (permission)=>permission?.action)
87
89
  });
88
90
  }
89
91
  return transferToken;
@@ -127,15 +129,17 @@ const hasAccessKey = (attributes)=>{
127
129
  id
128
130
  },
129
131
  data: {
130
- ...fp.omit('permissions', attributes)
132
+ ..._.omit(attributes, 'permissions')
131
133
  }
132
134
  });
133
135
  if (attributes.permissions) {
134
136
  const currentPermissionsResult = await strapi.db.query(TRANSFER_TOKEN_UID).load(updatedToken, 'permissions');
135
- const currentPermissions = fp.map('action', currentPermissionsResult || []);
136
- const newPermissions = fp.uniq(attributes.permissions);
137
- const actionsToDelete = fp.difference(currentPermissions, newPermissions);
138
- const actionsToAdd = fp.difference(newPermissions, currentPermissions);
137
+ const currentPermissions = Array.from(currentPermissionsResult || [], (permission)=>permission?.action);
138
+ const newPermissions = [
139
+ ...new Set(attributes.permissions)
140
+ ];
141
+ const actionsToDelete = _.difference(currentPermissions, newPermissions);
142
+ const actionsToAdd = _.difference(newPermissions, currentPermissions);
139
143
  // TODO: improve efficiency here
140
144
  // method using a loop -- works but very inefficient
141
145
  await Promise.all(actionsToDelete.map((action)=>strapi.db.query(TRANSFER_TOKEN_PERMISSION_UID).delete({
@@ -270,8 +274,8 @@ const regenerate = async (id)=>{
270
274
  };
271
275
  const getExpirationFields = (lifespan)=>{
272
276
  // it must be nil or a finite number >= 0
273
- const isValidNumber = fp.isNumber(lifespan) && Number.isFinite(lifespan) && lifespan > 0;
274
- if (!isValidNumber && !fp.isNil(lifespan)) {
277
+ const isValidNumber = _.isNumber(lifespan) && Number.isFinite(lifespan) && lifespan > 0;
278
+ if (!isValidNumber && lifespan != null) {
275
279
  throw new ValidationError('lifespan must be a positive number or null');
276
280
  }
277
281
  return {
@@ -308,7 +312,7 @@ For security reasons, prefer storing the secret in an environment variable and r
308
312
  }
309
313
  return {
310
314
  ...token,
311
- permissions: fp.isArray(token.permissions) ? fp.map('action', token.permissions) : token.permissions
315
+ permissions: Array.isArray(token.permissions) ? Array.from(token.permissions, (permission)=>permission?.action) : token.permissions
312
316
  };
313
317
  };
314
318
  /**
@@ -316,18 +320,18 @@ For security reasons, prefer storing the secret in an environment variable and r
316
320
  */ const assertTokenPermissionsValidity = (attributes)=>{
317
321
  const permissionService = strapi.service('admin::transfer').permission;
318
322
  const validPermissions = permissionService.providers.action.keys();
319
- const invalidPermissions = fp.difference(attributes.permissions, validPermissions);
320
- if (!fp.isEmpty(invalidPermissions)) {
323
+ const invalidPermissions = _.difference(attributes.permissions, validPermissions);
324
+ if (!_.isEmpty(invalidPermissions)) {
321
325
  throw new ValidationError(`Unknown permissions provided: ${invalidPermissions.join(', ')}`);
322
326
  }
323
327
  };
324
328
  /**
325
329
  * Check if a token's lifespan is valid
326
330
  */ const isValidLifespan = (lifespan)=>{
327
- if (fp.isNil(lifespan)) {
331
+ if (lifespan == null) {
328
332
  return true;
329
333
  }
330
- if (!fp.isNumber(lifespan) || !Object.values(constants.TRANSFER_TOKEN_LIFESPANS).includes(lifespan)) {
334
+ if (!_.isNumber(lifespan) || !Object.values(constants.TRANSFER_TOKEN_LIFESPANS).includes(lifespan)) {
331
335
  return false;
332
336
  }
333
337
  return true;
@@ -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,7 +1,6 @@
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');
7
6
  var adminUsers = require('../audit-logs/admin-users.js');
@@ -327,11 +326,11 @@ const createFirstAdmin = async (attributes)=>{
327
326
  /** Find many users (paginated)
328
327
  * @param params
329
328
  */ const findPage = async (params = {})=>{
330
- const query = strapi.get('query-params').transform('admin::user', fp.defaults({
329
+ const query = strapi.get('query-params').transform('admin::user', _.defaults({}, params, {
331
330
  populate: [
332
331
  'roles'
333
332
  ]
334
- }, params));
333
+ }));
335
334
  return strapi.db.query('admin::user').findPage(query);
336
335
  };
337
336
  /** Delete a user
@@ -1 +1 @@
1
- {"version":3,"file":"user.js","sources":["../../../../../server/src/services/user.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-non-null-assertion */\nimport _ from 'lodash';\nimport { defaults } from 'lodash/fp';\nimport { arrays, errors, emitAudit } from '@strapi/utils';\nimport type { Data } from '@strapi/types';\nimport { createUser, hasSuperAdminRole } from '../domain/user';\nimport {\n AUDITED_EVENTS,\n LEGACY_USER_EVENTS,\n emitAdminUserCreated,\n emitAdminUserDeleted,\n emitAdminUserUpdateAudits,\n toAdminUserEvent,\n touchesTrackedFields,\n} from '../audit-logs/admin-users';\nimport type {\n AdminUser,\n AdminRole,\n AdminUserCreationPayload,\n SanitizedAdminUser,\n SanitizedAdminRole,\n AdminUserUpdatePayload,\n // eslint-disable-next-line node/no-unpublished-import\n} from '../../../shared/contracts/shared';\nimport { password as passwordValidator } from '../validation/common-validators';\nimport { getService } from '../utils';\nimport constants from './constants';\n\nconst { SUPER_ADMIN_CODE } = constants;\n\nconst { ApplicationError, ValidationError } = errors;\nconst sanitizeUserRoles = (role: AdminRole): SanitizedAdminRole =>\n _.pick(role, ['id', 'name', 'description', 'code']);\n\nconst getSessionManager = () => {\n const manager = strapi.sessionManager;\n return manager ?? null;\n};\n\n/**\n * Remove private user fields\n * @param user - user to sanitize\n */\nconst sanitizeUser = (user: AdminUser): SanitizedAdminUser => {\n return {\n ..._.omit(user, [\n 'password',\n 'resetPasswordToken',\n 'resetPasswordTokenExpiresAt',\n 'registrationToken',\n 'roles',\n ]),\n roles: user.roles && user.roles.map(sanitizeUserRoles),\n };\n};\n\n/**\n * Create and save a user in database\n * @param attributes A partial user object\n */\nconst createUserInDatabase = async (\n // isActive is added in the controller, it's not sent by the API.\n attributes: Partial<AdminUserCreationPayload> & { isActive?: true }\n): Promise<AdminUser> => {\n const userInfo = {\n registrationToken: getService('token').createToken(),\n ...attributes,\n };\n\n if (_.has(attributes, 'password')) {\n userInfo.password = await getService('auth').hashPassword(attributes.password!);\n }\n\n const user = createUser(userInfo);\n\n const createdUser = await strapi.db\n .query('admin::user')\n .create({ data: user, populate: ['roles'] });\n\n return createdUser;\n};\n\nconst emitUserCreated = async (user: AdminUser) => {\n getService('metrics').sendDidInviteUser();\n\n strapi.eventHub.emit(LEGACY_USER_EVENTS.CREATE, { user: sanitizeUser(user) });\n await emitAdminUserCreated({ strapi }, user);\n};\n\nconst create = async (\n // isActive is added in the controller, it's not sent by the API.\n attributes: Partial<AdminUserCreationPayload> & { isActive?: true }\n): Promise<AdminUser> => {\n const createdUser = await createUserInDatabase(attributes);\n\n await emitUserCreated(createdUser);\n\n return createdUser;\n};\n\nconst createFirstAdmin = async (\n attributes: Omit<Partial<AdminUserCreationPayload>, 'registrationToken' | 'isActive' | 'roles'>\n): Promise<AdminUser> => {\n const createdUser = await strapi.db.transaction(async ({ trx }) => {\n // Serialize first-admin creation across processes by locking a stable role row.\n // SQLite ignores FOR UPDATE, but falls back to its single-writer transaction behavior.\n const superAdminRole = await strapi.db\n .queryBuilder('admin::role')\n .select(['id'])\n .where({ code: SUPER_ADMIN_CODE })\n .first()\n .transacting(trx)\n .forUpdate()\n .execute<AdminRole | undefined>();\n\n if (!superAdminRole) {\n throw new ApplicationError(\n \"Cannot register the first admin because the super admin role doesn't exist.\"\n );\n }\n\n const hasAdmin = await exists();\n\n if (hasAdmin) {\n throw new ApplicationError('You cannot register a new super admin');\n }\n\n return createUserInDatabase({\n ...attributes,\n registrationToken: null,\n isActive: true,\n roles: [superAdminRole.id],\n });\n });\n\n await emitUserCreated(createdUser);\n\n return createdUser;\n};\n\n/**\n * Update a user in database\n * @param id query params to find the user to update\n * @param attributes A partial user object\n */\nconst updateById = async (\n id: Data.ID,\n attributes: Partial<AdminUserUpdatePayload>\n): Promise<AdminUser> => {\n // Check at least one super admin remains\n if (_.has(attributes, 'roles')) {\n const lastAdminUser = await isLastSuperAdminUser(id);\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n const willRemoveSuperAdminRole = !arrays.includesString(attributes.roles!, superAdminRole.id);\n\n if (lastAdminUser && willRemoveSuperAdminRole) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n }\n\n // cannot disable last super admin\n if (attributes.isActive === false) {\n const lastAdminUser = await isLastSuperAdminUser(id);\n if (lastAdminUser) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n }\n\n // The audit log records what changed, so it needs the row before the write\n const previous = touchesTrackedFields(attributes)\n ? await strapi.db.query('admin::user').findOne({ where: { id }, populate: ['roles'] })\n : null;\n\n // hash password if a new one is sent\n if (_.has(attributes, 'password')) {\n const hashedPassword = await getService('auth').hashPassword(attributes.password!);\n\n const updatedUser = await strapi.db.query('admin::user').update({\n where: { id },\n data: {\n ...attributes,\n password: hashedPassword,\n },\n populate: ['roles'],\n });\n\n strapi.eventHub.emit(LEGACY_USER_EVENTS.UPDATE, { user: sanitizeUser(updatedUser) });\n await emitAdminUserUpdateAudits({ strapi }, { previous, updated: updatedUser, attributes });\n\n return updatedUser;\n }\n\n const updatedUser = await strapi.db.query('admin::user').update({\n where: { id },\n data: attributes,\n populate: ['roles'],\n });\n\n if (updatedUser) {\n strapi.eventHub.emit(LEGACY_USER_EVENTS.UPDATE, { user: sanitizeUser(updatedUser) });\n await emitAdminUserUpdateAudits({ strapi }, { previous, updated: updatedUser, attributes });\n }\n\n return updatedUser;\n};\n\n/**\n * Reset a user password by email. (Used in admin:reset CLI)\n * @param email - user email\n * @param password - new password\n */\nconst resetPasswordByEmail = async (email: string, password: string) => {\n const user = await strapi.db\n .query('admin::user')\n .findOne({ where: { email }, populate: ['roles'] });\n\n if (!user) {\n throw new Error(`User not found for email: ${email}`);\n }\n\n try {\n await passwordValidator.validate(password);\n } catch {\n throw new ValidationError(\n 'Invalid password. Expected a minimum of 8 characters with at least one number and one uppercase letter'\n );\n }\n\n await updateById(user.id, { password });\n};\n\n/**\n * Check if a user is the last super admin\n * @param userId user's id to look for\n */\nconst isLastSuperAdminUser = async (userId: Data.ID): Promise<boolean> => {\n const user = (await findOne(userId)) as AdminUser | null;\n if (!user) return false;\n\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n\n return superAdminRole.usersCount === 1 && hasSuperAdminRole(user);\n};\n\n/**\n * Check if a user is the first super admin\n * @param userId user's id to look for\n */\nconst isFirstSuperAdminUser = async (userId: Data.ID): Promise<boolean> => {\n const currentUser = (await findOne(userId)) as AdminUser | null;\n\n if (!currentUser || !hasSuperAdminRole(currentUser)) return false;\n\n const [oldestUser] = await strapi.db.query('admin::user').findMany({\n populate: {\n roles: {\n where: {\n code: { $eq: SUPER_ADMIN_CODE },\n },\n },\n },\n orderBy: { createdAt: 'asc' },\n limit: 1,\n select: ['id'],\n });\n\n return oldestUser.id === currentUser.id;\n};\n\n/**\n * Check if a user with specific attributes exists in the database\n * @param attributes A partial user object\n */\nconst exists = async (attributes = {} as unknown): Promise<boolean> => {\n return (await strapi.db.query('admin::user').count({ where: attributes })) > 0;\n};\n\n/**\n * Returns a user registration info\n * @param registrationToken - a user registration token\n * @returns - Returns user email, firstname and lastname\n */\nconst findRegistrationInfo = async (\n registrationToken: string\n): Promise<Pick<AdminUser, 'email' | 'firstname' | 'lastname'> | undefined> => {\n const user = await strapi.db.query('admin::user').findOne({ where: { registrationToken } });\n\n if (!user) {\n return undefined;\n }\n\n return _.pick(user, ['email', 'firstname', 'lastname']);\n};\n\n/**\n * Registers a user based on a registrationToken and some informations to update\n * @param params\n * @param params.registrationToken registration token\n * @param params.userInfo user info\n */\nconst register = async ({\n registrationToken,\n userInfo,\n}: {\n registrationToken: string;\n userInfo: Partial<AdminUser>;\n}) => {\n const matchingUser = await strapi.db\n .query('admin::user')\n .findOne({ where: { registrationToken } });\n\n if (!matchingUser) {\n throw new ValidationError('Invalid registration info');\n }\n\n const registeredUser = await getService('user').updateById(matchingUser.id, {\n password: userInfo.password,\n firstname: userInfo.firstname,\n lastname: userInfo.lastname,\n registrationToken: null,\n isActive: true,\n });\n\n await emitAudit({ strapi }, AUDITED_EVENTS.INVITE_ACCEPT, toAdminUserEvent(registeredUser));\n\n return registeredUser;\n};\n\n/**\n * Find one user\n */\nconst findOne = async (id: Data.ID, populate = ['roles']) => {\n return strapi.db.query('admin::user').findOne({ where: { id }, populate });\n};\n\n/**\n * Find one user by its email\n * @param email\n * @param populate\n * @returns\n */\nconst findOneByEmail = async (email: string, populate = []) => {\n return strapi.db.query('admin::user').findOne({\n where: { email: { $eqi: email } },\n populate,\n });\n};\n\n/** Find many users (paginated)\n * @param params\n */\nconst findPage = async (params = {}): Promise<unknown> => {\n const query = strapi\n .get('query-params')\n .transform('admin::user', defaults({ populate: ['roles'] }, params));\n\n return strapi.db.query('admin::user').findPage(query);\n};\n\n/** Delete a user\n * @param id id of the user to delete\n */\nconst deleteById = async (id: Data.ID): Promise<AdminUser | null> => {\n // Check at least one super admin remains\n const userToDelete: AdminUser | null = await strapi.db.query('admin::user').findOne({\n where: { id },\n populate: ['roles'],\n });\n\n if (!userToDelete) {\n return null;\n }\n\n if (userToDelete) {\n if (userToDelete.roles.some((r) => r.code === SUPER_ADMIN_CODE)) {\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n if (superAdminRole.usersCount === 1) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n }\n }\n\n const deletedUser = await strapi.db\n .query('admin::user')\n .delete({ where: { id }, populate: ['roles'] });\n\n // Invalidate all sessions for the deleted user\n const sessionManager = getSessionManager();\n if (sessionManager && sessionManager.hasOrigin('admin')) {\n await sessionManager('admin').invalidateRefreshToken(String(id));\n }\n\n strapi.eventHub.emit(LEGACY_USER_EVENTS.DELETE, { user: sanitizeUser(deletedUser) });\n await emitAdminUserDeleted({ strapi }, deletedUser);\n\n return deletedUser;\n};\n\n/** Delete a user\n * @param ids ids of the users to delete\n */\nconst deleteByIds = async (ids: (string | number)[]): Promise<AdminUser[]> => {\n // Check at least one super admin remains\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n const nbOfSuperAdminToDelete = await strapi.db.query('admin::user').count({\n where: {\n id: ids,\n roles: { id: superAdminRole.id },\n },\n });\n\n if (superAdminRole.usersCount === nbOfSuperAdminToDelete) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n\n const deletedUsers = [] as AdminUser[];\n for (const id of ids) {\n const deletedUser = await strapi.db.query('admin::user').delete({\n where: { id },\n populate: ['roles'],\n });\n\n // Invalidate all sessions for the deleted user\n const sessionManager = getSessionManager();\n if (sessionManager && sessionManager.hasOrigin('admin')) {\n await sessionManager('admin').invalidateRefreshToken(String(id));\n }\n\n deletedUsers.push(deletedUser);\n }\n\n strapi.eventHub.emit(LEGACY_USER_EVENTS.DELETE, {\n users: deletedUsers.map((deletedUser) => sanitizeUser(deletedUser)),\n });\n\n for (const deletedUser of deletedUsers) {\n await emitAdminUserDeleted({ strapi }, deletedUser);\n }\n\n return deletedUsers;\n};\n\n/** Count the users that don't have any associated roles\n */\nconst countUsersWithoutRole = async (): Promise<number> => {\n return strapi.db.query('admin::user').count({\n where: {\n roles: {\n id: { $null: true },\n },\n },\n });\n};\n\n/**\n * Count the number of users based on search params\n * @param params params used for the query\n */\nconst count = async (where = {}): Promise<number> => {\n return strapi.db.query('admin::user').count({ where });\n};\n\n/**\n * Assign some roles to several users\n */\nconst assignARoleToAll = async (roleId: Data.ID): Promise<void> => {\n const users = await strapi.db.query('admin::user').findMany({\n select: ['id'],\n where: {\n roles: { id: { $null: true } },\n },\n });\n\n await Promise.all(\n users.map((user) => {\n return strapi.db.query('admin::user').update({\n where: { id: user.id },\n data: { roles: [roleId] },\n });\n })\n );\n};\n\n/** Display a warning if some users don't have at least one role\n */\nconst displayWarningIfUsersDontHaveRole = async (): Promise<void> => {\n const count = await countUsersWithoutRole();\n\n if (count > 0) {\n strapi.log.warn(`Some users (${count}) don't have any role.`);\n }\n};\n\n/** Returns an array of interface languages currently used by users\n */\nconst getLanguagesInUse = async (): Promise<string[]> => {\n const users = await strapi.db.query('admin::user').findMany({ select: ['preferedLanguage'] });\n\n return users.map((user) => user.preferedLanguage || 'en');\n};\nexport default {\n create,\n createFirstAdmin,\n updateById,\n exists,\n findRegistrationInfo,\n register,\n sanitizeUser,\n findOne,\n findOneByEmail,\n findPage,\n deleteById,\n deleteByIds,\n countUsersWithoutRole,\n count,\n assignARoleToAll,\n displayWarningIfUsersDontHaveRole,\n resetPasswordByEmail,\n getLanguagesInUse,\n isFirstSuperAdminUser,\n};\n"],"names":["SUPER_ADMIN_CODE","constants","ApplicationError","ValidationError","errors","sanitizeUserRoles","role","_","pick","getSessionManager","manager","strapi","sessionManager","sanitizeUser","user","omit","roles","map","createUserInDatabase","attributes","userInfo","registrationToken","getService","createToken","has","password","hashPassword","createUser","createdUser","db","query","create","data","populate","emitUserCreated","sendDidInviteUser","eventHub","emit","LEGACY_USER_EVENTS","CREATE","emitAdminUserCreated","createFirstAdmin","transaction","trx","superAdminRole","queryBuilder","select","where","code","first","transacting","forUpdate","execute","hasAdmin","exists","isActive","id","updateById","lastAdminUser","isLastSuperAdminUser","getSuperAdminWithUsersCount","willRemoveSuperAdminRole","arrays","includesString","previous","touchesTrackedFields","findOne","hashedPassword","updatedUser","update","UPDATE","emitAdminUserUpdateAudits","updated","resetPasswordByEmail","email","Error","passwordValidator","validate","userId","usersCount","hasSuperAdminRole","isFirstSuperAdminUser","currentUser","oldestUser","findMany","$eq","orderBy","createdAt","limit","count","findRegistrationInfo","undefined","register","matchingUser","registeredUser","firstname","lastname","emitAudit","AUDITED_EVENTS","INVITE_ACCEPT","toAdminUserEvent","findOneByEmail","$eqi","findPage","params","get","transform","defaults","deleteById","userToDelete","some","r","deletedUser","delete","hasOrigin","invalidateRefreshToken","String","DELETE","emitAdminUserDeleted","deleteByIds","ids","nbOfSuperAdminToDelete","deletedUsers","push","users","countUsersWithoutRole","$null","assignARoleToAll","roleId","Promise","all","displayWarningIfUsersDontHaveRole","log","warn","getLanguagesInUse","preferedLanguage"],"mappings":"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"}
1
+ {"version":3,"file":"user.js","sources":["../../../../../server/src/services/user.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-non-null-assertion */\nimport _, { defaults } from 'lodash';\n\nimport { arrays, errors, emitAudit } from '@strapi/utils';\nimport type { Data } from '@strapi/types';\nimport { createUser, hasSuperAdminRole } from '../domain/user';\nimport {\n AUDITED_EVENTS,\n LEGACY_USER_EVENTS,\n emitAdminUserCreated,\n emitAdminUserDeleted,\n emitAdminUserUpdateAudits,\n toAdminUserEvent,\n touchesTrackedFields,\n} from '../audit-logs/admin-users';\nimport type {\n AdminUser,\n AdminRole,\n AdminUserCreationPayload,\n SanitizedAdminUser,\n SanitizedAdminRole,\n AdminUserUpdatePayload,\n // eslint-disable-next-line node/no-unpublished-import\n} from '../../../shared/contracts/shared';\nimport { password as passwordValidator } from '../validation/common-validators';\nimport { getService } from '../utils';\nimport constants from './constants';\n\nconst { SUPER_ADMIN_CODE } = constants;\n\nconst { ApplicationError, ValidationError } = errors;\nconst sanitizeUserRoles = (role: AdminRole): SanitizedAdminRole =>\n _.pick(role, ['id', 'name', 'description', 'code']);\n\nconst getSessionManager = () => {\n const manager = strapi.sessionManager;\n return manager ?? null;\n};\n\n/**\n * Remove private user fields\n * @param user - user to sanitize\n */\nconst sanitizeUser = (user: AdminUser): SanitizedAdminUser => {\n return {\n ..._.omit(user, [\n 'password',\n 'resetPasswordToken',\n 'resetPasswordTokenExpiresAt',\n 'registrationToken',\n 'roles',\n ]),\n roles: user.roles && user.roles.map(sanitizeUserRoles),\n };\n};\n\n/**\n * Create and save a user in database\n * @param attributes A partial user object\n */\nconst createUserInDatabase = async (\n // isActive is added in the controller, it's not sent by the API.\n attributes: Partial<AdminUserCreationPayload> & { isActive?: true }\n): Promise<AdminUser> => {\n const userInfo = {\n registrationToken: getService('token').createToken(),\n ...attributes,\n };\n\n if (_.has(attributes, 'password')) {\n userInfo.password = await getService('auth').hashPassword(attributes.password!);\n }\n\n const user = createUser(userInfo);\n\n const createdUser = await strapi.db\n .query('admin::user')\n .create({ data: user, populate: ['roles'] });\n\n return createdUser;\n};\n\nconst emitUserCreated = async (user: AdminUser) => {\n getService('metrics').sendDidInviteUser();\n\n strapi.eventHub.emit(LEGACY_USER_EVENTS.CREATE, { user: sanitizeUser(user) });\n await emitAdminUserCreated({ strapi }, user);\n};\n\nconst create = async (\n // isActive is added in the controller, it's not sent by the API.\n attributes: Partial<AdminUserCreationPayload> & { isActive?: true }\n): Promise<AdminUser> => {\n const createdUser = await createUserInDatabase(attributes);\n\n await emitUserCreated(createdUser);\n\n return createdUser;\n};\n\nconst createFirstAdmin = async (\n attributes: Omit<Partial<AdminUserCreationPayload>, 'registrationToken' | 'isActive' | 'roles'>\n): Promise<AdminUser> => {\n const createdUser = await strapi.db.transaction(async ({ trx }) => {\n // Serialize first-admin creation across processes by locking a stable role row.\n // SQLite ignores FOR UPDATE, but falls back to its single-writer transaction behavior.\n const superAdminRole = await strapi.db\n .queryBuilder('admin::role')\n .select(['id'])\n .where({ code: SUPER_ADMIN_CODE })\n .first()\n .transacting(trx)\n .forUpdate()\n .execute<AdminRole | undefined>();\n\n if (!superAdminRole) {\n throw new ApplicationError(\n \"Cannot register the first admin because the super admin role doesn't exist.\"\n );\n }\n\n const hasAdmin = await exists();\n\n if (hasAdmin) {\n throw new ApplicationError('You cannot register a new super admin');\n }\n\n return createUserInDatabase({\n ...attributes,\n registrationToken: null,\n isActive: true,\n roles: [superAdminRole.id],\n });\n });\n\n await emitUserCreated(createdUser);\n\n return createdUser;\n};\n\n/**\n * Update a user in database\n * @param id query params to find the user to update\n * @param attributes A partial user object\n */\nconst updateById = async (\n id: Data.ID,\n attributes: Partial<AdminUserUpdatePayload>\n): Promise<AdminUser> => {\n // Check at least one super admin remains\n if (_.has(attributes, 'roles')) {\n const lastAdminUser = await isLastSuperAdminUser(id);\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n const willRemoveSuperAdminRole = !arrays.includesString(attributes.roles!, superAdminRole.id);\n\n if (lastAdminUser && willRemoveSuperAdminRole) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n }\n\n // cannot disable last super admin\n if (attributes.isActive === false) {\n const lastAdminUser = await isLastSuperAdminUser(id);\n if (lastAdminUser) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n }\n\n // The audit log records what changed, so it needs the row before the write\n const previous = touchesTrackedFields(attributes)\n ? await strapi.db.query('admin::user').findOne({ where: { id }, populate: ['roles'] })\n : null;\n\n // hash password if a new one is sent\n if (_.has(attributes, 'password')) {\n const hashedPassword = await getService('auth').hashPassword(attributes.password!);\n\n const updatedUser = await strapi.db.query('admin::user').update({\n where: { id },\n data: {\n ...attributes,\n password: hashedPassword,\n },\n populate: ['roles'],\n });\n\n strapi.eventHub.emit(LEGACY_USER_EVENTS.UPDATE, { user: sanitizeUser(updatedUser) });\n await emitAdminUserUpdateAudits({ strapi }, { previous, updated: updatedUser, attributes });\n\n return updatedUser;\n }\n\n const updatedUser = await strapi.db.query('admin::user').update({\n where: { id },\n data: attributes,\n populate: ['roles'],\n });\n\n if (updatedUser) {\n strapi.eventHub.emit(LEGACY_USER_EVENTS.UPDATE, { user: sanitizeUser(updatedUser) });\n await emitAdminUserUpdateAudits({ strapi }, { previous, updated: updatedUser, attributes });\n }\n\n return updatedUser;\n};\n\n/**\n * Reset a user password by email. (Used in admin:reset CLI)\n * @param email - user email\n * @param password - new password\n */\nconst resetPasswordByEmail = async (email: string, password: string) => {\n const user = await strapi.db\n .query('admin::user')\n .findOne({ where: { email }, populate: ['roles'] });\n\n if (!user) {\n throw new Error(`User not found for email: ${email}`);\n }\n\n try {\n await passwordValidator.validate(password);\n } catch {\n throw new ValidationError(\n 'Invalid password. Expected a minimum of 8 characters with at least one number and one uppercase letter'\n );\n }\n\n await updateById(user.id, { password });\n};\n\n/**\n * Check if a user is the last super admin\n * @param userId user's id to look for\n */\nconst isLastSuperAdminUser = async (userId: Data.ID): Promise<boolean> => {\n const user = (await findOne(userId)) as AdminUser | null;\n if (!user) return false;\n\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n\n return superAdminRole.usersCount === 1 && hasSuperAdminRole(user);\n};\n\n/**\n * Check if a user is the first super admin\n * @param userId user's id to look for\n */\nconst isFirstSuperAdminUser = async (userId: Data.ID): Promise<boolean> => {\n const currentUser = (await findOne(userId)) as AdminUser | null;\n\n if (!currentUser || !hasSuperAdminRole(currentUser)) return false;\n\n const [oldestUser] = await strapi.db.query('admin::user').findMany({\n populate: {\n roles: {\n where: {\n code: { $eq: SUPER_ADMIN_CODE },\n },\n },\n },\n orderBy: { createdAt: 'asc' },\n limit: 1,\n select: ['id'],\n });\n\n return oldestUser.id === currentUser.id;\n};\n\n/**\n * Check if a user with specific attributes exists in the database\n * @param attributes A partial user object\n */\nconst exists = async (attributes = {} as unknown): Promise<boolean> => {\n return (await strapi.db.query('admin::user').count({ where: attributes })) > 0;\n};\n\n/**\n * Returns a user registration info\n * @param registrationToken - a user registration token\n * @returns - Returns user email, firstname and lastname\n */\nconst findRegistrationInfo = async (\n registrationToken: string\n): Promise<Pick<AdminUser, 'email' | 'firstname' | 'lastname'> | undefined> => {\n const user = await strapi.db.query('admin::user').findOne({ where: { registrationToken } });\n\n if (!user) {\n return undefined;\n }\n\n return _.pick(user, ['email', 'firstname', 'lastname']);\n};\n\n/**\n * Registers a user based on a registrationToken and some informations to update\n * @param params\n * @param params.registrationToken registration token\n * @param params.userInfo user info\n */\nconst register = async ({\n registrationToken,\n userInfo,\n}: {\n registrationToken: string;\n userInfo: Partial<AdminUser>;\n}) => {\n const matchingUser = await strapi.db\n .query('admin::user')\n .findOne({ where: { registrationToken } });\n\n if (!matchingUser) {\n throw new ValidationError('Invalid registration info');\n }\n\n const registeredUser = await getService('user').updateById(matchingUser.id, {\n password: userInfo.password,\n firstname: userInfo.firstname,\n lastname: userInfo.lastname,\n registrationToken: null,\n isActive: true,\n });\n\n await emitAudit({ strapi }, AUDITED_EVENTS.INVITE_ACCEPT, toAdminUserEvent(registeredUser));\n\n return registeredUser;\n};\n\n/**\n * Find one user\n */\nconst findOne = async (id: Data.ID, populate = ['roles']) => {\n return strapi.db.query('admin::user').findOne({ where: { id }, populate });\n};\n\n/**\n * Find one user by its email\n * @param email\n * @param populate\n * @returns\n */\nconst findOneByEmail = async (email: string, populate = []) => {\n return strapi.db.query('admin::user').findOne({\n where: { email: { $eqi: email } },\n populate,\n });\n};\n\n/** Find many users (paginated)\n * @param params\n */\nconst findPage = async (params = {}): Promise<unknown> => {\n const query = strapi\n .get('query-params')\n .transform('admin::user', defaults({}, params, { populate: ['roles'] }));\n\n return strapi.db.query('admin::user').findPage(query);\n};\n\n/** Delete a user\n * @param id id of the user to delete\n */\nconst deleteById = async (id: Data.ID): Promise<AdminUser | null> => {\n // Check at least one super admin remains\n const userToDelete: AdminUser | null = await strapi.db.query('admin::user').findOne({\n where: { id },\n populate: ['roles'],\n });\n\n if (!userToDelete) {\n return null;\n }\n\n if (userToDelete) {\n if (userToDelete.roles.some((r) => r.code === SUPER_ADMIN_CODE)) {\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n if (superAdminRole.usersCount === 1) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n }\n }\n\n const deletedUser = await strapi.db\n .query('admin::user')\n .delete({ where: { id }, populate: ['roles'] });\n\n // Invalidate all sessions for the deleted user\n const sessionManager = getSessionManager();\n if (sessionManager && sessionManager.hasOrigin('admin')) {\n await sessionManager('admin').invalidateRefreshToken(String(id));\n }\n\n strapi.eventHub.emit(LEGACY_USER_EVENTS.DELETE, { user: sanitizeUser(deletedUser) });\n await emitAdminUserDeleted({ strapi }, deletedUser);\n\n return deletedUser;\n};\n\n/** Delete a user\n * @param ids ids of the users to delete\n */\nconst deleteByIds = async (ids: (string | number)[]): Promise<AdminUser[]> => {\n // Check at least one super admin remains\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n const nbOfSuperAdminToDelete = await strapi.db.query('admin::user').count({\n where: {\n id: ids,\n roles: { id: superAdminRole.id },\n },\n });\n\n if (superAdminRole.usersCount === nbOfSuperAdminToDelete) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n\n const deletedUsers = [] as AdminUser[];\n for (const id of ids) {\n const deletedUser = await strapi.db.query('admin::user').delete({\n where: { id },\n populate: ['roles'],\n });\n\n // Invalidate all sessions for the deleted user\n const sessionManager = getSessionManager();\n if (sessionManager && sessionManager.hasOrigin('admin')) {\n await sessionManager('admin').invalidateRefreshToken(String(id));\n }\n\n deletedUsers.push(deletedUser);\n }\n\n strapi.eventHub.emit(LEGACY_USER_EVENTS.DELETE, {\n users: deletedUsers.map((deletedUser) => sanitizeUser(deletedUser)),\n });\n\n for (const deletedUser of deletedUsers) {\n await emitAdminUserDeleted({ strapi }, deletedUser);\n }\n\n return deletedUsers;\n};\n\n/** Count the users that don't have any associated roles\n */\nconst countUsersWithoutRole = async (): Promise<number> => {\n return strapi.db.query('admin::user').count({\n where: {\n roles: {\n id: { $null: true },\n },\n },\n });\n};\n\n/**\n * Count the number of users based on search params\n * @param params params used for the query\n */\nconst count = async (where = {}): Promise<number> => {\n return strapi.db.query('admin::user').count({ where });\n};\n\n/**\n * Assign some roles to several users\n */\nconst assignARoleToAll = async (roleId: Data.ID): Promise<void> => {\n const users = await strapi.db.query('admin::user').findMany({\n select: ['id'],\n where: {\n roles: { id: { $null: true } },\n },\n });\n\n await Promise.all(\n users.map((user) => {\n return strapi.db.query('admin::user').update({\n where: { id: user.id },\n data: { roles: [roleId] },\n });\n })\n );\n};\n\n/** Display a warning if some users don't have at least one role\n */\nconst displayWarningIfUsersDontHaveRole = async (): Promise<void> => {\n const count = await countUsersWithoutRole();\n\n if (count > 0) {\n strapi.log.warn(`Some users (${count}) don't have any role.`);\n }\n};\n\n/** Returns an array of interface languages currently used by users\n */\nconst getLanguagesInUse = async (): Promise<string[]> => {\n const users = await strapi.db.query('admin::user').findMany({ select: ['preferedLanguage'] });\n\n return users.map((user) => user.preferedLanguage || 'en');\n};\nexport default {\n create,\n createFirstAdmin,\n updateById,\n exists,\n findRegistrationInfo,\n register,\n sanitizeUser,\n findOne,\n findOneByEmail,\n findPage,\n deleteById,\n deleteByIds,\n countUsersWithoutRole,\n count,\n assignARoleToAll,\n displayWarningIfUsersDontHaveRole,\n resetPasswordByEmail,\n getLanguagesInUse,\n isFirstSuperAdminUser,\n};\n"],"names":["SUPER_ADMIN_CODE","constants","ApplicationError","ValidationError","errors","sanitizeUserRoles","role","_","pick","getSessionManager","manager","strapi","sessionManager","sanitizeUser","user","omit","roles","map","createUserInDatabase","attributes","userInfo","registrationToken","getService","createToken","has","password","hashPassword","createUser","createdUser","db","query","create","data","populate","emitUserCreated","sendDidInviteUser","eventHub","emit","LEGACY_USER_EVENTS","CREATE","emitAdminUserCreated","createFirstAdmin","transaction","trx","superAdminRole","queryBuilder","select","where","code","first","transacting","forUpdate","execute","hasAdmin","exists","isActive","id","updateById","lastAdminUser","isLastSuperAdminUser","getSuperAdminWithUsersCount","willRemoveSuperAdminRole","arrays","includesString","previous","touchesTrackedFields","findOne","hashedPassword","updatedUser","update","UPDATE","emitAdminUserUpdateAudits","updated","resetPasswordByEmail","email","Error","passwordValidator","validate","userId","usersCount","hasSuperAdminRole","isFirstSuperAdminUser","currentUser","oldestUser","findMany","$eq","orderBy","createdAt","limit","count","findRegistrationInfo","undefined","register","matchingUser","registeredUser","firstname","lastname","emitAudit","AUDITED_EVENTS","INVITE_ACCEPT","toAdminUserEvent","findOneByEmail","$eqi","findPage","params","get","transform","defaults","deleteById","userToDelete","some","r","deletedUser","delete","hasOrigin","invalidateRefreshToken","String","DELETE","emitAdminUserDeleted","deleteByIds","ids","nbOfSuperAdminToDelete","deletedUsers","push","users","countUsersWithoutRole","$null","assignARoleToAll","roleId","Promise","all","displayWarningIfUsersDontHaveRole","log","warn","getLanguagesInUse","preferedLanguage"],"mappings":";;;;;;;;;;;;;;AA4BA,MAAM,EAAEA,gBAAgB,EAAE,GAAGC,SAAAA;AAE7B,MAAM,EAAEC,gBAAgB,EAAEC,eAAe,EAAE,GAAGC,YAAAA;AAC9C,MAAMC,oBAAoB,CAACC,IAAAA,GACzBC,kBAAAA,CAAEC,IAAI,CAACF,IAAAA,EAAM;AAAC,QAAA,IAAA;AAAM,QAAA,MAAA;AAAQ,QAAA,aAAA;AAAe,QAAA;AAAO,KAAA,CAAA;AAEpD,MAAMG,iBAAAA,GAAoB,IAAA;IACxB,MAAMC,OAAAA,GAAUC,OAAOC,cAAc;AACrC,IAAA,OAAOF,OAAAA,IAAW,IAAA;AACpB,CAAA;AAEA;;;IAIA,MAAMG,eAAe,CAACC,IAAAA,GAAAA;IACpB,OAAO;QACL,GAAGP,kBAAAA,CAAEQ,IAAI,CAACD,IAAAA,EAAM;AACd,YAAA,UAAA;AACA,YAAA,oBAAA;AACA,YAAA,6BAAA;AACA,YAAA,mBAAA;AACA,YAAA;SACD,CAAC;AACFE,QAAAA,KAAAA,EAAOF,KAAKE,KAAK,IAAIF,KAAKE,KAAK,CAACC,GAAG,CAACZ,iBAAAA;AACtC,KAAA;AACF,CAAA;AAEA;;;IAIA,MAAMa,oBAAAA,GAAuB;AAE3BC,UAAAA,GAAAA;AAEA,IAAA,MAAMC,QAAAA,GAAW;QACfC,iBAAAA,EAAmBC,gBAAAA,CAAW,SAASC,WAAW,EAAA;AAClD,QAAA,GAAGJ;AACL,KAAA;AAEA,IAAA,IAAIZ,kBAAAA,CAAEiB,GAAG,CAACL,UAAAA,EAAY,UAAA,CAAA,EAAa;QACjCC,QAAAA,CAASK,QAAQ,GAAG,MAAMH,gBAAAA,CAAW,QAAQI,YAAY,CAACP,WAAWM,QAAQ,CAAA;AAC/E,IAAA;AAEA,IAAA,MAAMX,OAAOa,iBAAAA,CAAWP,QAAAA,CAAAA;IAExB,MAAMQ,WAAAA,GAAc,MAAMjB,MAAAA,CAAOkB,EAAE,CAChCC,KAAK,CAAC,aAAA,CAAA,CACNC,MAAM,CAAC;QAAEC,IAAAA,EAAMlB,IAAAA;QAAMmB,QAAAA,EAAU;AAAC,YAAA;AAAQ;AAAC,KAAA,CAAA;IAE5C,OAAOL,WAAAA;AACT,CAAA;AAEA,MAAMM,kBAAkB,OAAOpB,IAAAA,GAAAA;AAC7BQ,IAAAA,gBAAAA,CAAW,WAAWa,iBAAiB,EAAA;AAEvCxB,IAAAA,MAAAA,CAAOyB,QAAQ,CAACC,IAAI,CAACC,6BAAAA,CAAmBC,MAAM,EAAE;AAAEzB,QAAAA,IAAAA,EAAMD,YAAAA,CAAaC,IAAAA;AAAM,KAAA,CAAA;AAC3E,IAAA,MAAM0B,+BAAAA,CAAqB;AAAE7B,QAAAA;KAAO,EAAGG,IAAAA,CAAAA;AACzC,CAAA;AAEA,MAAMiB,MAAAA,GAAS;AAEbZ,UAAAA,GAAAA;IAEA,MAAMS,WAAAA,GAAc,MAAMV,oBAAAA,CAAqBC,UAAAA,CAAAA;AAE/C,IAAA,MAAMe,eAAAA,CAAgBN,WAAAA,CAAAA;IAEtB,OAAOA,WAAAA;AACT,CAAA;AAEA,MAAMa,mBAAmB,OACvBtB,UAAAA,GAAAA;IAEA,MAAMS,WAAAA,GAAc,MAAMjB,MAAAA,CAAOkB,EAAE,CAACa,WAAW,CAAC,OAAO,EAAEC,GAAG,EAAE,GAAA;;;QAG5D,MAAMC,cAAAA,GAAiB,MAAMjC,MAAAA,CAAOkB,EAAE,CACnCgB,YAAY,CAAC,aAAA,CAAA,CACbC,MAAM,CAAC;AAAC,YAAA;AAAK,SAAA,CAAA,CACbC,KAAK,CAAC;YAAEC,IAAAA,EAAMhD;AAAiB,SAAA,CAAA,CAC/BiD,KAAK,EAAA,CACLC,WAAW,CAACP,GAAAA,CAAAA,CACZQ,SAAS,GACTC,OAAO,EAAA;AAEV,QAAA,IAAI,CAACR,cAAAA,EAAgB;AACnB,YAAA,MAAM,IAAI1C,gBAAAA,CACR,6EAAA,CAAA;AAEJ,QAAA;AAEA,QAAA,MAAMmD,WAAW,MAAMC,MAAAA,EAAAA;AAEvB,QAAA,IAAID,QAAAA,EAAU;AACZ,YAAA,MAAM,IAAInD,gBAAAA,CAAiB,uCAAA,CAAA;AAC7B,QAAA;AAEA,QAAA,OAAOgB,oBAAAA,CAAqB;AAC1B,YAAA,GAAGC,UAAU;YACbE,iBAAAA,EAAmB,IAAA;YACnBkC,QAAAA,EAAU,IAAA;YACVvC,KAAAA,EAAO;AAAC4B,gBAAAA,cAAAA,CAAeY;AAAG;AAC5B,SAAA,CAAA;AACF,IAAA,CAAA,CAAA;AAEA,IAAA,MAAMtB,eAAAA,CAAgBN,WAAAA,CAAAA;IAEtB,OAAOA,WAAAA;AACT,CAAA;AAEA;;;;IAKA,MAAM6B,UAAAA,GAAa,OACjBD,EAAAA,EACArC,UAAAA,GAAAA;;AAGA,IAAA,IAAIZ,kBAAAA,CAAEiB,GAAG,CAACL,UAAAA,EAAY,OAAA,CAAA,EAAU;QAC9B,MAAMuC,aAAAA,GAAgB,MAAMC,oBAAAA,CAAqBH,EAAAA,CAAAA;AACjD,QAAA,MAAMZ,cAAAA,GAAiB,MAAMtB,gBAAAA,CAAW,MAAA,CAAA,CAAQsC,2BAA2B,EAAA;QAC3E,MAAMC,wBAAAA,GAA2B,CAACC,YAAAA,CAAOC,cAAc,CAAC5C,UAAAA,CAAWH,KAAK,EAAG4B,cAAAA,CAAeY,EAAE,CAAA;AAE5F,QAAA,IAAIE,iBAAiBG,wBAAAA,EAA0B;AAC7C,YAAA,MAAM,IAAI1D,eAAAA,CAAgB,wDAAA,CAAA;AAC5B,QAAA;AACF,IAAA;;IAGA,IAAIgB,UAAAA,CAAWoC,QAAQ,KAAK,KAAA,EAAO;QACjC,MAAMG,aAAAA,GAAgB,MAAMC,oBAAAA,CAAqBH,EAAAA,CAAAA;AACjD,QAAA,IAAIE,aAAAA,EAAe;AACjB,YAAA,MAAM,IAAIvD,eAAAA,CAAgB,wDAAA,CAAA;AAC5B,QAAA;AACF,IAAA;;IAGA,MAAM6D,QAAAA,GAAWC,+BAAAA,CAAqB9C,UAAAA,CAAAA,GAClC,MAAMR,MAAAA,CAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeoC,OAAO,CAAC;QAAEnB,KAAAA,EAAO;AAAES,YAAAA;AAAG,SAAA;QAAGvB,QAAAA,EAAU;AAAC,YAAA;AAAQ;KAAC,CAAA,GAClF,IAAA;;AAGJ,IAAA,IAAI1B,kBAAAA,CAAEiB,GAAG,CAACL,UAAAA,EAAY,UAAA,CAAA,EAAa;AACjC,QAAA,MAAMgD,iBAAiB,MAAM7C,gBAAAA,CAAW,QAAQI,YAAY,CAACP,WAAWM,QAAQ,CAAA;QAEhF,MAAM2C,WAAAA,GAAc,MAAMzD,MAAAA,CAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeuC,MAAM,CAAC;YAC9DtB,KAAAA,EAAO;AAAES,gBAAAA;AAAG,aAAA;YACZxB,IAAAA,EAAM;AACJ,gBAAA,GAAGb,UAAU;gBACbM,QAAAA,EAAU0C;AACZ,aAAA;YACAlC,QAAAA,EAAU;AAAC,gBAAA;AAAQ;AACrB,SAAA,CAAA;AAEAtB,QAAAA,MAAAA,CAAOyB,QAAQ,CAACC,IAAI,CAACC,6BAAAA,CAAmBgC,MAAM,EAAE;AAAExD,YAAAA,IAAAA,EAAMD,YAAAA,CAAauD,WAAAA;AAAa,SAAA,CAAA;AAClF,QAAA,MAAMG,oCAAAA,CAA0B;AAAE5D,YAAAA;SAAO,EAAG;AAAEqD,YAAAA,QAAAA;YAAUQ,OAAAA,EAASJ,WAAAA;AAAajD,YAAAA;AAAW,SAAA,CAAA;QAEzF,OAAOiD,WAAAA;AACT,IAAA;IAEA,MAAMA,WAAAA,GAAc,MAAMzD,MAAAA,CAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeuC,MAAM,CAAC;QAC9DtB,KAAAA,EAAO;AAAES,YAAAA;AAAG,SAAA;QACZxB,IAAAA,EAAMb,UAAAA;QACNc,QAAAA,EAAU;AAAC,YAAA;AAAQ;AACrB,KAAA,CAAA;AAEA,IAAA,IAAImC,WAAAA,EAAa;AACfzD,QAAAA,MAAAA,CAAOyB,QAAQ,CAACC,IAAI,CAACC,6BAAAA,CAAmBgC,MAAM,EAAE;AAAExD,YAAAA,IAAAA,EAAMD,YAAAA,CAAauD,WAAAA;AAAa,SAAA,CAAA;AAClF,QAAA,MAAMG,oCAAAA,CAA0B;AAAE5D,YAAAA;SAAO,EAAG;AAAEqD,YAAAA,QAAAA;YAAUQ,OAAAA,EAASJ,WAAAA;AAAajD,YAAAA;AAAW,SAAA,CAAA;AAC3F,IAAA;IAEA,OAAOiD,WAAAA;AACT,CAAA;AAEA;;;;IAKA,MAAMK,oBAAAA,GAAuB,OAAOC,KAAAA,EAAejD,QAAAA,GAAAA;IACjD,MAAMX,IAAAA,GAAO,MAAMH,MAAAA,CAAOkB,EAAE,CACzBC,KAAK,CAAC,aAAA,CAAA,CACNoC,OAAO,CAAC;QAAEnB,KAAAA,EAAO;AAAE2B,YAAAA;AAAM,SAAA;QAAGzC,QAAAA,EAAU;AAAC,YAAA;AAAQ;AAAC,KAAA,CAAA;AAEnD,IAAA,IAAI,CAACnB,IAAAA,EAAM;AACT,QAAA,MAAM,IAAI6D,KAAAA,CAAM,CAAC,0BAA0B,EAAED,KAAAA,CAAAA,CAAO,CAAA;AACtD,IAAA;IAEA,IAAI;QACF,MAAME,yBAAAA,CAAkBC,QAAQ,CAACpD,QAAAA,CAAAA;AACnC,IAAA,CAAA,CAAE,OAAM;AACN,QAAA,MAAM,IAAItB,eAAAA,CACR,wGAAA,CAAA;AAEJ,IAAA;IAEA,MAAMsD,UAAAA,CAAW3C,IAAAA,CAAK0C,EAAE,EAAE;AAAE/B,QAAAA;AAAS,KAAA,CAAA;AACvC,CAAA;AAEA;;;IAIA,MAAMkC,uBAAuB,OAAOmB,MAAAA,GAAAA;IAClC,MAAMhE,IAAAA,GAAQ,MAAMoD,OAAAA,CAAQY,MAAAA,CAAAA;IAC5B,IAAI,CAAChE,MAAM,OAAO,KAAA;AAElB,IAAA,MAAM8B,cAAAA,GAAiB,MAAMtB,gBAAAA,CAAW,MAAA,CAAA,CAAQsC,2BAA2B,EAAA;AAE3E,IAAA,OAAOhB,cAAAA,CAAemC,UAAU,KAAK,CAAA,IAAKC,wBAAAA,CAAkBlE,IAAAA,CAAAA;AAC9D,CAAA;AAEA;;;IAIA,MAAMmE,wBAAwB,OAAOH,MAAAA,GAAAA;IACnC,MAAMI,WAAAA,GAAe,MAAMhB,OAAAA,CAAQY,MAAAA,CAAAA;AAEnC,IAAA,IAAI,CAACI,WAAAA,IAAe,CAACF,wBAAAA,CAAkBE,cAAc,OAAO,KAAA;IAE5D,MAAM,CAACC,UAAAA,CAAW,GAAG,MAAMxE,MAAAA,CAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAesD,QAAQ,CAAC;QACjEnD,QAAAA,EAAU;YACRjB,KAAAA,EAAO;gBACL+B,KAAAA,EAAO;oBACLC,IAAAA,EAAM;wBAAEqC,GAAAA,EAAKrF;AAAiB;AAChC;AACF;AACF,SAAA;QACAsF,OAAAA,EAAS;YAAEC,SAAAA,EAAW;AAAM,SAAA;QAC5BC,KAAAA,EAAO,CAAA;QACP1C,MAAAA,EAAQ;AAAC,YAAA;AAAK;AAChB,KAAA,CAAA;AAEA,IAAA,OAAOqC,UAAAA,CAAW3B,EAAE,KAAK0B,WAAAA,CAAY1B,EAAE;AACzC,CAAA;AAEA;;;AAGC,IACD,MAAMF,MAAAA,GAAS,OAAOnC,UAAAA,GAAa,EAAa,GAAA;IAC9C,OAAQ,MAAMR,MAAAA,CAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAe2D,KAAK,CAAC;QAAE1C,KAAAA,EAAO5B;KAAW,CAAA,GAAM,CAAA;AAC/E,CAAA;AAEA;;;;IAKA,MAAMuE,uBAAuB,OAC3BrE,iBAAAA,GAAAA;IAEA,MAAMP,IAAAA,GAAO,MAAMH,MAAAA,CAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeoC,OAAO,CAAC;QAAEnB,KAAAA,EAAO;AAAE1B,YAAAA;AAAkB;AAAE,KAAA,CAAA;AAEzF,IAAA,IAAI,CAACP,IAAAA,EAAM;QACT,OAAO6E,SAAAA;AACT,IAAA;IAEA,OAAOpF,kBAAAA,CAAEC,IAAI,CAACM,IAAAA,EAAM;AAAC,QAAA,OAAA;AAAS,QAAA,WAAA;AAAa,QAAA;AAAW,KAAA,CAAA;AACxD,CAAA;AAEA;;;;;AAKC,IACD,MAAM8E,QAAAA,GAAW,OAAO,EACtBvE,iBAAiB,EACjBD,QAAQ,EAIT,GAAA;IACC,MAAMyE,YAAAA,GAAe,MAAMlF,MAAAA,CAAOkB,EAAE,CACjCC,KAAK,CAAC,aAAA,CAAA,CACNoC,OAAO,CAAC;QAAEnB,KAAAA,EAAO;AAAE1B,YAAAA;AAAkB;AAAE,KAAA,CAAA;AAE1C,IAAA,IAAI,CAACwE,YAAAA,EAAc;AACjB,QAAA,MAAM,IAAI1F,eAAAA,CAAgB,2BAAA,CAAA;AAC5B,IAAA;IAEA,MAAM2F,cAAAA,GAAiB,MAAMxE,gBAAAA,CAAW,MAAA,CAAA,CAAQmC,UAAU,CAACoC,YAAAA,CAAarC,EAAE,EAAE;AAC1E/B,QAAAA,QAAAA,EAAUL,SAASK,QAAQ;AAC3BsE,QAAAA,SAAAA,EAAW3E,SAAS2E,SAAS;AAC7BC,QAAAA,QAAAA,EAAU5E,SAAS4E,QAAQ;QAC3B3E,iBAAAA,EAAmB,IAAA;QACnBkC,QAAAA,EAAU;AACZ,KAAA,CAAA;AAEA,IAAA,MAAM0C,eAAAA,CAAU;AAAEtF,QAAAA;KAAO,EAAGuF,yBAAAA,CAAeC,aAAa,EAAEC,2BAAAA,CAAiBN,cAAAA,CAAAA,CAAAA;IAE3E,OAAOA,cAAAA;AACT,CAAA;AAEA;;AAEC,IACD,MAAM5B,OAAAA,GAAU,OAAOV,EAAAA,EAAavB,QAAAA,GAAW;AAAC,IAAA;AAAQ,CAAA,GAAA;AACtD,IAAA,OAAOtB,OAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeoC,OAAO,CAAC;QAAEnB,KAAAA,EAAO;AAAES,YAAAA;AAAG,SAAA;AAAGvB,QAAAA;AAAS,KAAA,CAAA;AAC1E,CAAA;AAEA;;;;;AAKC,IACD,MAAMoE,cAAAA,GAAiB,OAAO3B,KAAAA,EAAezC,WAAW,EAAE,GAAA;AACxD,IAAA,OAAOtB,OAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeoC,OAAO,CAAC;QAC5CnB,KAAAA,EAAO;YAAE2B,KAAAA,EAAO;gBAAE4B,IAAAA,EAAM5B;AAAM;AAAE,SAAA;AAChCzC,QAAAA;AACF,KAAA,CAAA;AACF,CAAA;AAEA;;AAEC,IACD,MAAMsE,QAAAA,GAAW,OAAOC,MAAAA,GAAS,EAAE,GAAA;IACjC,MAAM1E,KAAAA,GAAQnB,MAAAA,CACX8F,GAAG,CAAC,cAAA,CAAA,CACJC,SAAS,CAAC,aAAA,EAAeC,UAAAA,CAAS,EAAC,EAAGH,MAAAA,EAAQ;QAAEvE,QAAAA,EAAU;AAAC,YAAA;AAAQ;AAAC,KAAA,CAAA,CAAA;AAEvE,IAAA,OAAOtB,OAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeyE,QAAQ,CAACzE,KAAAA,CAAAA;AACjD,CAAA;AAEA;;IAGA,MAAM8E,aAAa,OAAOpD,EAAAA,GAAAA;;IAExB,MAAMqD,YAAAA,GAAiC,MAAMlG,MAAAA,CAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeoC,OAAO,CAAC;QAClFnB,KAAAA,EAAO;AAAES,YAAAA;AAAG,SAAA;QACZvB,QAAAA,EAAU;AAAC,YAAA;AAAQ;AACrB,KAAA,CAAA;AAEA,IAAA,IAAI,CAAC4E,YAAAA,EAAc;QACjB,OAAO,IAAA;AACT,IAAA;AAEA,IAAA,IAAIA,YAAAA,EAAc;QAChB,IAAIA,YAAAA,CAAa7F,KAAK,CAAC8F,IAAI,CAAC,CAACC,CAAAA,GAAMA,CAAAA,CAAE/D,IAAI,KAAKhD,gBAAAA,CAAAA,EAAmB;AAC/D,YAAA,MAAM4C,cAAAA,GAAiB,MAAMtB,gBAAAA,CAAW,MAAA,CAAA,CAAQsC,2BAA2B,EAAA;YAC3E,IAAIhB,cAAAA,CAAemC,UAAU,KAAK,CAAA,EAAG;AACnC,gBAAA,MAAM,IAAI5E,eAAAA,CAAgB,wDAAA,CAAA;AAC5B,YAAA;AACF,QAAA;AACF,IAAA;IAEA,MAAM6G,WAAAA,GAAc,MAAMrG,MAAAA,CAAOkB,EAAE,CAChCC,KAAK,CAAC,aAAA,CAAA,CACNmF,MAAM,CAAC;QAAElE,KAAAA,EAAO;AAAES,YAAAA;AAAG,SAAA;QAAGvB,QAAAA,EAAU;AAAC,YAAA;AAAQ;AAAC,KAAA,CAAA;;AAG/C,IAAA,MAAMrB,cAAAA,GAAiBH,iBAAAA,EAAAA;AACvB,IAAA,IAAIG,cAAAA,IAAkBA,cAAAA,CAAesG,SAAS,CAAC,OAAA,CAAA,EAAU;AACvD,QAAA,MAAMtG,cAAAA,CAAe,OAAA,CAAA,CAASuG,sBAAsB,CAACC,MAAAA,CAAO5D,EAAAA,CAAAA,CAAAA;AAC9D,IAAA;AAEA7C,IAAAA,MAAAA,CAAOyB,QAAQ,CAACC,IAAI,CAACC,6BAAAA,CAAmB+E,MAAM,EAAE;AAAEvG,QAAAA,IAAAA,EAAMD,YAAAA,CAAamG,WAAAA;AAAa,KAAA,CAAA;AAClF,IAAA,MAAMM,+BAAAA,CAAqB;AAAE3G,QAAAA;KAAO,EAAGqG,WAAAA,CAAAA;IAEvC,OAAOA,WAAAA;AACT,CAAA;AAEA;;IAGA,MAAMO,cAAc,OAAOC,GAAAA,GAAAA;;AAEzB,IAAA,MAAM5E,cAAAA,GAAiB,MAAMtB,gBAAAA,CAAW,MAAA,CAAA,CAAQsC,2BAA2B,EAAA;IAC3E,MAAM6D,sBAAAA,GAAyB,MAAM9G,MAAAA,CAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAe2D,KAAK,CAAC;QACxE1C,KAAAA,EAAO;YACLS,EAAAA,EAAIgE,GAAAA;YACJxG,KAAAA,EAAO;AAAEwC,gBAAAA,EAAAA,EAAIZ,eAAeY;AAAG;AACjC;AACF,KAAA,CAAA;IAEA,IAAIZ,cAAAA,CAAemC,UAAU,KAAK0C,sBAAAA,EAAwB;AACxD,QAAA,MAAM,IAAItH,eAAAA,CAAgB,wDAAA,CAAA;AAC5B,IAAA;AAEA,IAAA,MAAMuH,eAAe,EAAE;IACvB,KAAK,MAAMlE,MAAMgE,GAAAA,CAAK;QACpB,MAAMR,WAAAA,GAAc,MAAMrG,MAAAA,CAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAemF,MAAM,CAAC;YAC9DlE,KAAAA,EAAO;AAAES,gBAAAA;AAAG,aAAA;YACZvB,QAAAA,EAAU;AAAC,gBAAA;AAAQ;AACrB,SAAA,CAAA;;AAGA,QAAA,MAAMrB,cAAAA,GAAiBH,iBAAAA,EAAAA;AACvB,QAAA,IAAIG,cAAAA,IAAkBA,cAAAA,CAAesG,SAAS,CAAC,OAAA,CAAA,EAAU;AACvD,YAAA,MAAMtG,cAAAA,CAAe,OAAA,CAAA,CAASuG,sBAAsB,CAACC,MAAAA,CAAO5D,EAAAA,CAAAA,CAAAA;AAC9D,QAAA;AAEAkE,QAAAA,YAAAA,CAAaC,IAAI,CAACX,WAAAA,CAAAA;AACpB,IAAA;AAEArG,IAAAA,MAAAA,CAAOyB,QAAQ,CAACC,IAAI,CAACC,6BAAAA,CAAmB+E,MAAM,EAAE;AAC9CO,QAAAA,KAAAA,EAAOF,YAAAA,CAAazG,GAAG,CAAC,CAAC+F,cAAgBnG,YAAAA,CAAamG,WAAAA,CAAAA;AACxD,KAAA,CAAA;IAEA,KAAK,MAAMA,eAAeU,YAAAA,CAAc;AACtC,QAAA,MAAMJ,+BAAAA,CAAqB;AAAE3G,YAAAA;SAAO,EAAGqG,WAAAA,CAAAA;AACzC,IAAA;IAEA,OAAOU,YAAAA;AACT,CAAA;AAEA;AACC,IACD,MAAMG,qBAAAA,GAAwB,UAAA;AAC5B,IAAA,OAAOlH,OAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAe2D,KAAK,CAAC;QAC1C1C,KAAAA,EAAO;YACL/B,KAAAA,EAAO;gBACLwC,EAAAA,EAAI;oBAAEsE,KAAAA,EAAO;AAAK;AACpB;AACF;AACF,KAAA,CAAA;AACF,CAAA;AAEA;;;AAGC,IACD,MAAMrC,KAAAA,GAAQ,OAAO1C,KAAAA,GAAQ,EAAE,GAAA;AAC7B,IAAA,OAAOpC,OAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAe2D,KAAK,CAAC;AAAE1C,QAAAA;AAAM,KAAA,CAAA;AACtD,CAAA;AAEA;;IAGA,MAAMgF,mBAAmB,OAAOC,MAAAA,GAAAA;IAC9B,MAAMJ,KAAAA,GAAQ,MAAMjH,MAAAA,CAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAesD,QAAQ,CAAC;QAC1DtC,MAAAA,EAAQ;AAAC,YAAA;AAAK,SAAA;QACdC,KAAAA,EAAO;YACL/B,KAAAA,EAAO;gBAAEwC,EAAAA,EAAI;oBAAEsE,KAAAA,EAAO;AAAK;AAAE;AAC/B;AACF,KAAA,CAAA;AAEA,IAAA,MAAMG,QAAQC,GAAG,CACfN,KAAAA,CAAM3G,GAAG,CAAC,CAACH,IAAAA,GAAAA;AACT,QAAA,OAAOH,OAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeuC,MAAM,CAAC;YAC3CtB,KAAAA,EAAO;AAAES,gBAAAA,EAAAA,EAAI1C,KAAK0C;AAAG,aAAA;YACrBxB,IAAAA,EAAM;gBAAEhB,KAAAA,EAAO;AAACgH,oBAAAA;AAAO;AAAC;AAC1B,SAAA,CAAA;AACF,IAAA,CAAA,CAAA,CAAA;AAEJ,CAAA;AAEA;AACC,IACD,MAAMG,iCAAAA,GAAoC,UAAA;AACxC,IAAA,MAAM1C,QAAQ,MAAMoC,qBAAAA,EAAAA;AAEpB,IAAA,IAAIpC,QAAQ,CAAA,EAAG;QACb9E,MAAAA,CAAOyH,GAAG,CAACC,IAAI,CAAC,CAAC,YAAY,EAAE5C,KAAAA,CAAM,sBAAsB,CAAC,CAAA;AAC9D,IAAA;AACF,CAAA;AAEA;AACC,IACD,MAAM6C,iBAAAA,GAAoB,UAAA;IACxB,MAAMV,KAAAA,GAAQ,MAAMjH,MAAAA,CAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAesD,QAAQ,CAAC;QAAEtC,MAAAA,EAAQ;AAAC,YAAA;AAAmB;AAAC,KAAA,CAAA;AAE3F,IAAA,OAAO8E,MAAM3G,GAAG,CAAC,CAACH,IAAAA,GAASA,IAAAA,CAAKyH,gBAAgB,IAAI,IAAA,CAAA;AACtD,CAAA;AACA,WAAe;AACbxG,IAAAA,MAAAA;AACAU,IAAAA,gBAAAA;AACAgB,IAAAA,UAAAA;AACAH,IAAAA,MAAAA;AACAoC,IAAAA,oBAAAA;AACAE,IAAAA,QAAAA;AACA/E,IAAAA,YAAAA;AACAqD,IAAAA,OAAAA;AACAmC,IAAAA,cAAAA;AACAE,IAAAA,QAAAA;AACAK,IAAAA,UAAAA;AACAW,IAAAA,WAAAA;AACAM,IAAAA,qBAAAA;AACApC,IAAAA,KAAAA;AACAsC,IAAAA,gBAAAA;AACAI,IAAAA,iCAAAA;AACA1D,IAAAA,oBAAAA;AACA6D,IAAAA,iBAAAA;AACArD,IAAAA;AACF,CAAA;;;;"}