@strapi/admin 5.55.1 → 5.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (388) hide show
  1. package/dist/admin/admin/src/components/Filters.js +1 -1
  2. package/dist/admin/admin/src/components/Filters.js.map +1 -1
  3. package/dist/admin/admin/src/components/Filters.mjs +1 -1
  4. package/dist/admin/admin/src/components/Filters.mjs.map +1 -1
  5. package/dist/admin/admin/src/components/FormInputs/Enumeration.js +2 -2
  6. package/dist/admin/admin/src/components/FormInputs/Enumeration.js.map +1 -1
  7. package/dist/admin/admin/src/components/FormInputs/Enumeration.mjs +2 -2
  8. package/dist/admin/admin/src/components/FormInputs/Enumeration.mjs.map +1 -1
  9. package/dist/admin/admin/src/components/MediaLibraryBanner.js +38 -2
  10. package/dist/admin/admin/src/components/MediaLibraryBanner.js.map +1 -1
  11. package/dist/admin/admin/src/components/MediaLibraryBanner.mjs +18 -2
  12. package/dist/admin/admin/src/components/MediaLibraryBanner.mjs.map +1 -1
  13. package/dist/admin/admin/src/components/RelativeTime.js +9 -0
  14. package/dist/admin/admin/src/components/RelativeTime.js.map +1 -1
  15. package/dist/admin/admin/src/components/RelativeTime.mjs +10 -1
  16. package/dist/admin/admin/src/components/RelativeTime.mjs.map +1 -1
  17. package/dist/admin/admin/src/components/TopBanners.js +52 -0
  18. package/dist/admin/admin/src/components/TopBanners.js.map +1 -0
  19. package/dist/admin/admin/src/components/TopBanners.mjs +30 -0
  20. package/dist/admin/admin/src/components/TopBanners.mjs.map +1 -0
  21. package/dist/admin/admin/src/components/UpsellBanner.js +9 -16
  22. package/dist/admin/admin/src/components/UpsellBanner.js.map +1 -1
  23. package/dist/admin/admin/src/components/UpsellBanner.mjs +11 -18
  24. package/dist/admin/admin/src/components/UpsellBanner.mjs.map +1 -1
  25. package/dist/admin/admin/src/features/Tracking.js +28 -8
  26. package/dist/admin/admin/src/features/Tracking.js.map +1 -1
  27. package/dist/admin/admin/src/features/Tracking.mjs +29 -10
  28. package/dist/admin/admin/src/features/Tracking.mjs.map +1 -1
  29. package/dist/admin/admin/src/layouts/AuthenticatedLayout.js +4 -20
  30. package/dist/admin/admin/src/layouts/AuthenticatedLayout.js.map +1 -1
  31. package/dist/admin/admin/src/layouts/AuthenticatedLayout.mjs +4 -20
  32. package/dist/admin/admin/src/layouts/AuthenticatedLayout.mjs.map +1 -1
  33. package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.js +59 -0
  34. package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.js.map +1 -0
  35. package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.mjs +37 -0
  36. package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.mjs.map +1 -0
  37. package/dist/admin/admin/src/render.js +4 -69
  38. package/dist/admin/admin/src/render.js.map +1 -1
  39. package/dist/admin/admin/src/render.mjs +4 -69
  40. package/dist/admin/admin/src/render.mjs.map +1 -1
  41. package/dist/admin/admin/src/translations/en.json.js +15 -0
  42. package/dist/admin/admin/src/translations/en.json.js.map +1 -1
  43. package/dist/admin/admin/src/translations/en.json.mjs +15 -0
  44. package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
  45. package/dist/admin/admin/src/utils/browserStrapi.js +93 -0
  46. package/dist/admin/admin/src/utils/browserStrapi.js.map +1 -0
  47. package/dist/admin/admin/src/utils/browserStrapi.mjs +91 -0
  48. package/dist/admin/admin/src/utils/browserStrapi.mjs.map +1 -0
  49. package/dist/admin/admin/src/utils/getFetchClient.js +3 -3
  50. package/dist/admin/admin/src/utils/getFetchClient.js.map +1 -1
  51. package/dist/admin/admin/src/utils/getFetchClient.mjs +2 -2
  52. package/dist/admin/admin/src/utils/getFetchClient.mjs.map +1 -1
  53. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.js +2 -1
  54. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.js.map +1 -1
  55. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.mjs +2 -1
  56. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.mjs.map +1 -1
  57. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js +16 -1
  58. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js.map +1 -1
  59. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs +16 -1
  60. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs.map +1 -1
  61. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.js +3 -1
  62. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.js.map +1 -1
  63. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.mjs +3 -1
  64. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.mjs.map +1 -1
  65. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.js +64 -0
  66. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.js.map +1 -0
  67. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.mjs +60 -0
  68. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.mjs.map +1 -0
  69. package/dist/admin/ee/admin/src/services/auditLogs.js +2 -1
  70. package/dist/admin/ee/admin/src/services/auditLogs.js.map +1 -1
  71. package/dist/admin/ee/admin/src/services/auditLogs.mjs +2 -1
  72. package/dist/admin/ee/admin/src/services/auditLogs.mjs.map +1 -1
  73. package/dist/admin/src/components/MediaLibraryBanner.d.ts +10 -1
  74. package/dist/admin/src/components/SubNav.d.ts +2 -2
  75. package/dist/admin/src/components/TopBanners.d.ts +8 -0
  76. package/dist/admin/src/features/Tracking.d.ts +12 -1
  77. package/dist/admin/src/layouts/useAuthenticatedAccessTracking.d.ts +6 -0
  78. package/dist/admin/src/utils/browserStrapi.d.ts +11 -0
  79. package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.d.ts +15 -0
  80. package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.d.ts +14 -0
  81. package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts +10 -1
  82. package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts.map +1 -1
  83. package/dist/ee/server/src/controllers/admin.d.ts +2 -28
  84. package/dist/ee/server/src/controllers/admin.d.ts.map +1 -1
  85. package/dist/ee/server/src/controllers/authentication-utils/utils.d.ts +8 -2
  86. package/dist/ee/server/src/controllers/authentication-utils/utils.d.ts.map +1 -1
  87. package/dist/ee/server/src/controllers/authentication.d.ts.map +1 -1
  88. package/dist/ee/server/src/controllers/index.d.ts +1 -28
  89. package/dist/ee/server/src/controllers/index.d.ts.map +1 -1
  90. package/dist/ee/server/src/controllers/user.d.ts.map +1 -1
  91. package/dist/ee/server/src/index.d.ts +6 -30
  92. package/dist/ee/server/src/index.d.ts.map +1 -1
  93. package/dist/ee/server/src/services/auth.d.ts +1 -1
  94. package/dist/ee/server/src/services/auth.d.ts.map +1 -1
  95. package/dist/ee/server/src/services/index.d.ts +5 -2
  96. package/dist/ee/server/src/services/index.d.ts.map +1 -1
  97. package/dist/ee/server/src/services/metrics.d.ts.map +1 -1
  98. package/dist/ee/server/src/services/persist-tables.d.ts.map +1 -1
  99. package/dist/ee/server/src/services/seat-enforcement.d.ts +3 -1
  100. package/dist/ee/server/src/services/seat-enforcement.d.ts.map +1 -1
  101. package/dist/ee/server/src/services/user.d.ts.map +1 -1
  102. package/dist/server/ee/server/src/audit-logs/services/lifecycles.js +37 -21
  103. package/dist/server/ee/server/src/audit-logs/services/lifecycles.js.map +1 -1
  104. package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs +37 -21
  105. package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs.map +1 -1
  106. package/dist/server/ee/server/src/controllers/admin.js +8 -7
  107. package/dist/server/ee/server/src/controllers/admin.js.map +1 -1
  108. package/dist/server/ee/server/src/controllers/admin.mjs +8 -7
  109. package/dist/server/ee/server/src/controllers/admin.mjs.map +1 -1
  110. package/dist/server/ee/server/src/controllers/authentication-utils/utils.js +2 -2
  111. package/dist/server/ee/server/src/controllers/authentication-utils/utils.js.map +1 -1
  112. package/dist/server/ee/server/src/controllers/authentication-utils/utils.mjs +2 -2
  113. package/dist/server/ee/server/src/controllers/authentication-utils/utils.mjs.map +1 -1
  114. package/dist/server/ee/server/src/controllers/authentication.js +11 -11
  115. package/dist/server/ee/server/src/controllers/authentication.js.map +1 -1
  116. package/dist/server/ee/server/src/controllers/authentication.mjs +11 -11
  117. package/dist/server/ee/server/src/controllers/authentication.mjs.map +1 -1
  118. package/dist/server/ee/server/src/controllers/user.js +7 -8
  119. package/dist/server/ee/server/src/controllers/user.js.map +1 -1
  120. package/dist/server/ee/server/src/controllers/user.mjs +8 -9
  121. package/dist/server/ee/server/src/controllers/user.mjs.map +1 -1
  122. package/dist/server/ee/server/src/index.js +4 -0
  123. package/dist/server/ee/server/src/index.js.map +1 -1
  124. package/dist/server/ee/server/src/index.mjs +4 -0
  125. package/dist/server/ee/server/src/index.mjs.map +1 -1
  126. package/dist/server/ee/server/src/services/auth.js +1 -6
  127. package/dist/server/ee/server/src/services/auth.js.map +1 -1
  128. package/dist/server/ee/server/src/services/auth.mjs +2 -7
  129. package/dist/server/ee/server/src/services/auth.mjs.map +1 -1
  130. package/dist/server/ee/server/src/services/metrics.js +9 -7
  131. package/dist/server/ee/server/src/services/metrics.js.map +1 -1
  132. package/dist/server/ee/server/src/services/metrics.mjs +9 -7
  133. package/dist/server/ee/server/src/services/metrics.mjs.map +1 -1
  134. package/dist/server/ee/server/src/services/persist-tables.js +3 -4
  135. package/dist/server/ee/server/src/services/persist-tables.js.map +1 -1
  136. package/dist/server/ee/server/src/services/persist-tables.mjs +3 -4
  137. package/dist/server/ee/server/src/services/persist-tables.mjs.map +1 -1
  138. package/dist/server/ee/server/src/services/role.js +2 -2
  139. package/dist/server/ee/server/src/services/role.js.map +1 -1
  140. package/dist/server/ee/server/src/services/role.mjs +1 -1
  141. package/dist/server/ee/server/src/services/role.mjs.map +1 -1
  142. package/dist/server/ee/server/src/services/seat-enforcement.js +20 -20
  143. package/dist/server/ee/server/src/services/seat-enforcement.js.map +1 -1
  144. package/dist/server/ee/server/src/services/seat-enforcement.mjs +20 -20
  145. package/dist/server/ee/server/src/services/seat-enforcement.mjs.map +1 -1
  146. package/dist/server/ee/server/src/services/user.js +37 -6
  147. package/dist/server/ee/server/src/services/user.js.map +1 -1
  148. package/dist/server/ee/server/src/services/user.mjs +38 -7
  149. package/dist/server/ee/server/src/services/user.mjs.map +1 -1
  150. package/dist/server/ee/server/src/utils/sso-lock.js +2 -2
  151. package/dist/server/ee/server/src/utils/sso-lock.js.map +1 -1
  152. package/dist/server/ee/server/src/utils/sso-lock.mjs +1 -1
  153. package/dist/server/ee/server/src/utils/sso-lock.mjs.map +1 -1
  154. package/dist/server/server/src/audit-logs/admin-users.js +169 -0
  155. package/dist/server/server/src/audit-logs/admin-users.js.map +1 -0
  156. package/dist/server/server/src/audit-logs/admin-users.mjs +157 -0
  157. package/dist/server/server/src/audit-logs/admin-users.mjs.map +1 -0
  158. package/dist/server/server/src/audit-logs/tokens.js +3 -3
  159. package/dist/server/server/src/audit-logs/tokens.js.map +1 -1
  160. package/dist/server/server/src/audit-logs/tokens.mjs +2 -2
  161. package/dist/server/server/src/audit-logs/tokens.mjs.map +1 -1
  162. package/dist/server/server/src/audit-logs/webhooks.js +106 -0
  163. package/dist/server/server/src/audit-logs/webhooks.js.map +1 -0
  164. package/dist/server/server/src/audit-logs/webhooks.mjs +100 -0
  165. package/dist/server/server/src/audit-logs/webhooks.mjs.map +1 -0
  166. package/dist/server/server/src/bootstrap.js +6 -4
  167. package/dist/server/server/src/bootstrap.js.map +1 -1
  168. package/dist/server/server/src/bootstrap.mjs +6 -4
  169. package/dist/server/server/src/bootstrap.mjs.map +1 -1
  170. package/dist/server/server/src/controllers/admin-token.js +8 -8
  171. package/dist/server/server/src/controllers/admin-token.js.map +1 -1
  172. package/dist/server/server/src/controllers/admin-token.mjs +4 -4
  173. package/dist/server/server/src/controllers/admin-token.mjs.map +1 -1
  174. package/dist/server/server/src/controllers/admin.js +4 -5
  175. package/dist/server/server/src/controllers/admin.js.map +1 -1
  176. package/dist/server/server/src/controllers/admin.mjs +3 -4
  177. package/dist/server/server/src/controllers/admin.mjs.map +1 -1
  178. package/dist/server/server/src/controllers/api-token.js +8 -8
  179. package/dist/server/server/src/controllers/api-token.js.map +1 -1
  180. package/dist/server/server/src/controllers/api-token.mjs +4 -4
  181. package/dist/server/server/src/controllers/api-token.mjs.map +1 -1
  182. package/dist/server/server/src/controllers/authentication.js +8 -1
  183. package/dist/server/server/src/controllers/authentication.js.map +1 -1
  184. package/dist/server/server/src/controllers/authentication.mjs +8 -1
  185. package/dist/server/server/src/controllers/authentication.mjs.map +1 -1
  186. package/dist/server/server/src/controllers/formatters/conditions.js +2 -2
  187. package/dist/server/server/src/controllers/formatters/conditions.js.map +1 -1
  188. package/dist/server/server/src/controllers/formatters/conditions.mjs +2 -2
  189. package/dist/server/server/src/controllers/formatters/conditions.mjs.map +1 -1
  190. package/dist/server/server/src/controllers/transfer/index.js +2 -2
  191. package/dist/server/server/src/controllers/transfer/index.js.map +1 -1
  192. package/dist/server/server/src/controllers/transfer/index.mjs +2 -2
  193. package/dist/server/server/src/controllers/transfer/index.mjs.map +1 -1
  194. package/dist/server/server/src/controllers/transfer/token.js +8 -8
  195. package/dist/server/server/src/controllers/transfer/token.js.map +1 -1
  196. package/dist/server/server/src/controllers/transfer/token.mjs +4 -4
  197. package/dist/server/server/src/controllers/transfer/token.mjs.map +1 -1
  198. package/dist/server/server/src/controllers/webhooks.js +26 -0
  199. package/dist/server/server/src/controllers/webhooks.js.map +1 -1
  200. package/dist/server/server/src/controllers/webhooks.mjs +27 -1
  201. package/dist/server/server/src/controllers/webhooks.mjs.map +1 -1
  202. package/dist/server/server/src/domain/action/index.js +18 -16
  203. package/dist/server/server/src/domain/action/index.js.map +1 -1
  204. package/dist/server/server/src/domain/action/index.mjs +16 -14
  205. package/dist/server/server/src/domain/action/index.mjs.map +1 -1
  206. package/dist/server/server/src/domain/action/provider.mjs +4 -4
  207. package/dist/server/server/src/domain/action/provider.mjs.map +1 -1
  208. package/dist/server/server/src/domain/condition/index.js +7 -4
  209. package/dist/server/server/src/domain/condition/index.js.map +1 -1
  210. package/dist/server/server/src/domain/condition/index.mjs +7 -4
  211. package/dist/server/server/src/domain/condition/index.mjs.map +1 -1
  212. package/dist/server/server/src/domain/permission/index.js +24 -15
  213. package/dist/server/server/src/domain/permission/index.js.map +1 -1
  214. package/dist/server/server/src/domain/permission/index.mjs +21 -12
  215. package/dist/server/server/src/domain/permission/index.mjs.map +1 -1
  216. package/dist/server/server/src/middlewares/rateLimit.js +5 -5
  217. package/dist/server/server/src/middlewares/rateLimit.js.map +1 -1
  218. package/dist/server/server/src/middlewares/rateLimit.mjs +4 -4
  219. package/dist/server/server/src/middlewares/rateLimit.mjs.map +1 -1
  220. package/dist/server/server/src/register.js +6 -0
  221. package/dist/server/server/src/register.js.map +1 -1
  222. package/dist/server/server/src/register.mjs +6 -0
  223. package/dist/server/server/src/register.mjs.map +1 -1
  224. package/dist/server/server/src/services/action.js +1 -2
  225. package/dist/server/server/src/services/action.js.map +1 -1
  226. package/dist/server/server/src/services/action.mjs +1 -2
  227. package/dist/server/server/src/services/action.mjs.map +1 -1
  228. package/dist/server/server/src/services/api-token.js +61 -49
  229. package/dist/server/server/src/services/api-token.js.map +1 -1
  230. package/dist/server/server/src/services/api-token.mjs +53 -41
  231. package/dist/server/server/src/services/api-token.mjs.map +1 -1
  232. package/dist/server/server/src/services/auth.js +27 -6
  233. package/dist/server/server/src/services/auth.js.map +1 -1
  234. package/dist/server/server/src/services/auth.mjs +28 -8
  235. package/dist/server/server/src/services/auth.mjs.map +1 -1
  236. package/dist/server/server/src/services/condition.js +2 -2
  237. package/dist/server/server/src/services/condition.js.map +1 -1
  238. package/dist/server/server/src/services/condition.mjs +1 -1
  239. package/dist/server/server/src/services/condition.mjs.map +1 -1
  240. package/dist/server/server/src/services/content-type.js +5 -4
  241. package/dist/server/server/src/services/content-type.js.map +1 -1
  242. package/dist/server/server/src/services/content-type.mjs +8 -7
  243. package/dist/server/server/src/services/content-type.mjs.map +1 -1
  244. package/dist/server/server/src/services/homepage.js +2 -1
  245. package/dist/server/server/src/services/homepage.js.map +1 -1
  246. package/dist/server/server/src/services/homepage.mjs +2 -1
  247. package/dist/server/server/src/services/homepage.mjs.map +1 -1
  248. package/dist/server/server/src/services/passport/local-strategy.js +2 -2
  249. package/dist/server/server/src/services/passport/local-strategy.js.map +1 -1
  250. package/dist/server/server/src/services/passport/local-strategy.mjs +1 -1
  251. package/dist/server/server/src/services/passport/local-strategy.mjs.map +1 -1
  252. package/dist/server/server/src/services/passport.js +1 -2
  253. package/dist/server/server/src/services/passport.js.map +1 -1
  254. package/dist/server/server/src/services/passport.mjs +1 -2
  255. package/dist/server/server/src/services/passport.mjs.map +1 -1
  256. package/dist/server/server/src/services/permission/engine.js +4 -4
  257. package/dist/server/server/src/services/permission/engine.js.map +1 -1
  258. package/dist/server/server/src/services/permission/engine.mjs +2 -2
  259. package/dist/server/server/src/services/permission/engine.mjs.map +1 -1
  260. package/dist/server/server/src/services/permission/permissions-manager/index.js +2 -3
  261. package/dist/server/server/src/services/permission/permissions-manager/index.js.map +1 -1
  262. package/dist/server/server/src/services/permission/permissions-manager/index.mjs +1 -2
  263. package/dist/server/server/src/services/permission/permissions-manager/index.mjs.map +1 -1
  264. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.js +6 -6
  265. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.js.map +1 -1
  266. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.mjs +4 -4
  267. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.mjs.map +1 -1
  268. package/dist/server/server/src/services/permission/permissions-manager/sanitize.js +47 -41
  269. package/dist/server/server/src/services/permission/permissions-manager/sanitize.js.map +1 -1
  270. package/dist/server/server/src/services/permission/permissions-manager/sanitize.mjs +44 -38
  271. package/dist/server/server/src/services/permission/permissions-manager/sanitize.mjs.map +1 -1
  272. package/dist/server/server/src/services/permission/permissions-manager/validate.js +30 -26
  273. package/dist/server/server/src/services/permission/permissions-manager/validate.js.map +1 -1
  274. package/dist/server/server/src/services/permission/permissions-manager/validate.mjs +28 -24
  275. package/dist/server/server/src/services/permission/permissions-manager/validate.mjs.map +1 -1
  276. package/dist/server/server/src/services/permission/queries.js +9 -9
  277. package/dist/server/server/src/services/permission/queries.js.map +1 -1
  278. package/dist/server/server/src/services/permission/queries.mjs +9 -9
  279. package/dist/server/server/src/services/permission/queries.mjs.map +1 -1
  280. package/dist/server/server/src/services/permission/rename-fields.js +118 -0
  281. package/dist/server/server/src/services/permission/rename-fields.js.map +1 -0
  282. package/dist/server/server/src/services/permission/rename-fields.mjs +116 -0
  283. package/dist/server/server/src/services/permission/rename-fields.mjs.map +1 -0
  284. package/dist/server/server/src/services/permission/sections-builder/index.js +2 -2
  285. package/dist/server/server/src/services/permission/sections-builder/index.js.map +1 -1
  286. package/dist/server/server/src/services/permission/sections-builder/index.mjs +2 -2
  287. package/dist/server/server/src/services/permission/sections-builder/index.mjs.map +1 -1
  288. package/dist/server/server/src/services/permission/sections-builder/section.js +1 -2
  289. package/dist/server/server/src/services/permission/sections-builder/section.js.map +1 -1
  290. package/dist/server/server/src/services/permission/sections-builder/section.mjs +1 -2
  291. package/dist/server/server/src/services/permission/sections-builder/section.mjs.map +1 -1
  292. package/dist/server/server/src/services/permission/sections-builder/utils.js +6 -6
  293. package/dist/server/server/src/services/permission/sections-builder/utils.js.map +1 -1
  294. package/dist/server/server/src/services/permission/sections-builder/utils.mjs +4 -4
  295. package/dist/server/server/src/services/permission/sections-builder/utils.mjs.map +1 -1
  296. package/dist/server/server/src/services/role.js +20 -19
  297. package/dist/server/server/src/services/role.js.map +1 -1
  298. package/dist/server/server/src/services/role.mjs +20 -19
  299. package/dist/server/server/src/services/role.mjs.map +1 -1
  300. package/dist/server/server/src/services/transfer/token.js +20 -16
  301. package/dist/server/server/src/services/transfer/token.js.map +1 -1
  302. package/dist/server/server/src/services/transfer/token.mjs +14 -10
  303. package/dist/server/server/src/services/transfer/token.mjs.map +1 -1
  304. package/dist/server/server/src/services/user.js +50 -12
  305. package/dist/server/server/src/services/user.js.map +1 -1
  306. package/dist/server/server/src/services/user.mjs +52 -14
  307. package/dist/server/server/src/services/user.mjs.map +1 -1
  308. package/dist/server/server/src/strategies/api-token-utils.js +2 -3
  309. package/dist/server/server/src/strategies/api-token-utils.js.map +1 -1
  310. package/dist/server/server/src/strategies/api-token-utils.mjs +2 -3
  311. package/dist/server/server/src/strategies/api-token-utils.mjs.map +1 -1
  312. package/dist/server/server/src/strategies/content-api-token.js +3 -3
  313. package/dist/server/server/src/strategies/content-api-token.js.map +1 -1
  314. package/dist/server/server/src/strategies/content-api-token.mjs +1 -1
  315. package/dist/server/server/src/strategies/content-api-token.mjs.map +1 -1
  316. package/dist/server/server/src/strategies/data-transfer.js +4 -4
  317. package/dist/server/server/src/strategies/data-transfer.js.map +1 -1
  318. package/dist/server/server/src/strategies/data-transfer.mjs +3 -3
  319. package/dist/server/server/src/strategies/data-transfer.mjs.map +1 -1
  320. package/dist/server/server/src/validation/common-validators.js +9 -10
  321. package/dist/server/server/src/validation/common-validators.js.map +1 -1
  322. package/dist/server/server/src/validation/common-validators.mjs +13 -14
  323. package/dist/server/server/src/validation/common-validators.mjs.map +1 -1
  324. package/dist/server/server/src/validation/user.js +1 -2
  325. package/dist/server/server/src/validation/user.js.map +1 -1
  326. package/dist/server/server/src/validation/user.mjs +1 -2
  327. package/dist/server/server/src/validation/user.mjs.map +1 -1
  328. package/dist/server/src/audit-logs/admin-users.d.ts +119 -0
  329. package/dist/server/src/audit-logs/admin-users.d.ts.map +1 -0
  330. package/dist/server/src/audit-logs/tokens.d.ts.map +1 -1
  331. package/dist/server/src/audit-logs/webhooks.d.ts +59 -0
  332. package/dist/server/src/audit-logs/webhooks.d.ts.map +1 -0
  333. package/dist/server/src/bootstrap.d.ts.map +1 -1
  334. package/dist/server/src/controllers/admin-token.d.ts.map +1 -1
  335. package/dist/server/src/controllers/admin.d.ts +2 -11
  336. package/dist/server/src/controllers/admin.d.ts.map +1 -1
  337. package/dist/server/src/controllers/api-token.d.ts.map +1 -1
  338. package/dist/server/src/controllers/authentication.d.ts.map +1 -1
  339. package/dist/server/src/controllers/formatters/conditions.d.ts +1 -1
  340. package/dist/server/src/controllers/formatters/conditions.d.ts.map +1 -1
  341. package/dist/server/src/controllers/homepage.d.ts +1 -1
  342. package/dist/server/src/controllers/index.d.ts +2 -11
  343. package/dist/server/src/controllers/index.d.ts.map +1 -1
  344. package/dist/server/src/controllers/transfer/index.d.ts.map +1 -1
  345. package/dist/server/src/controllers/transfer/token.d.ts.map +1 -1
  346. package/dist/server/src/controllers/webhooks.d.ts.map +1 -1
  347. package/dist/server/src/domain/action/index.d.ts +1 -0
  348. package/dist/server/src/domain/action/index.d.ts.map +1 -1
  349. package/dist/server/src/domain/condition/index.d.ts +2 -2
  350. package/dist/server/src/domain/condition/index.d.ts.map +1 -1
  351. package/dist/server/src/domain/permission/index.d.ts.map +1 -1
  352. package/dist/server/src/domain/user.d.ts +2 -2
  353. package/dist/server/src/index.d.ts +4 -13
  354. package/dist/server/src/index.d.ts.map +1 -1
  355. package/dist/server/src/middlewares/index.d.ts.map +1 -1
  356. package/dist/server/src/middlewares/rateLimit.d.ts.map +1 -1
  357. package/dist/server/src/register.d.ts.map +1 -1
  358. package/dist/server/src/services/action.d.ts.map +1 -1
  359. package/dist/server/src/services/api-token.d.ts.map +1 -1
  360. package/dist/server/src/services/auth.d.ts +6 -1
  361. package/dist/server/src/services/auth.d.ts.map +1 -1
  362. package/dist/server/src/services/condition.d.ts.map +1 -1
  363. package/dist/server/src/services/content-type.d.ts.map +1 -1
  364. package/dist/server/src/services/homepage.d.ts +1 -1
  365. package/dist/server/src/services/homepage.d.ts.map +1 -1
  366. package/dist/server/src/services/index.d.ts +2 -2
  367. package/dist/server/src/services/index.d.ts.map +1 -1
  368. package/dist/server/src/services/passport/local-strategy.d.ts.map +1 -1
  369. package/dist/server/src/services/passport.d.ts.map +1 -1
  370. package/dist/server/src/services/permission/engine.d.ts.map +1 -1
  371. package/dist/server/src/services/permission/permissions-manager/permission-fields.d.ts.map +1 -1
  372. package/dist/server/src/services/permission/permissions-manager/sanitize.d.ts.map +1 -1
  373. package/dist/server/src/services/permission/permissions-manager/validate.d.ts.map +1 -1
  374. package/dist/server/src/services/permission/queries.d.ts.map +1 -1
  375. package/dist/server/src/services/permission/rename-fields.d.ts +21 -0
  376. package/dist/server/src/services/permission/rename-fields.d.ts.map +1 -0
  377. package/dist/server/src/services/permission/sections-builder/section.d.ts.map +1 -1
  378. package/dist/server/src/services/permission/sections-builder/utils.d.ts +1 -1
  379. package/dist/server/src/services/permission/sections-builder/utils.d.ts.map +1 -1
  380. package/dist/server/src/services/role.d.ts +1 -1
  381. package/dist/server/src/services/role.d.ts.map +1 -1
  382. package/dist/server/src/services/transfer/token.d.ts.map +1 -1
  383. package/dist/server/src/services/user.d.ts.map +1 -1
  384. package/dist/server/src/strategies/content-api-token.d.ts.map +1 -1
  385. package/dist/server/src/validation/user.d.ts.map +1 -1
  386. package/dist/shared/contracts/admin.d.ts +36 -2
  387. package/dist/shared/contracts/admin.d.ts.map +1 -1
  388. package/package.json +13 -13
@@ -1,8 +1,9 @@
1
1
  import bcrypt from 'bcryptjs';
2
2
  import ___default from 'lodash';
3
- import { errors } from '@strapi/utils';
3
+ import { errors, emitAudit } from '@strapi/utils';
4
4
  import { getService } from '../utils/index.mjs';
5
5
  import { expiresInToSeconds } from './token.mjs';
6
+ import { AUDITED_EVENTS, toAdminUserEvent } from '../audit-logs/admin-users.mjs';
6
7
  import '@strapi/types';
7
8
 
8
9
  const { ApplicationError } = errors;
@@ -24,12 +25,35 @@ const DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN = '1h';
24
25
  */ const assignResetPasswordToken = async (userId)=>{
25
26
  const resetPasswordToken = getService('token').createToken();
26
27
  const resetPasswordTokenExpiresAt = new Date(Date.now() + getResetPasswordTokenTTL());
27
- await getService('user').updateById(userId, {
28
+ const user = await getService('user').updateById(userId, {
28
29
  resetPasswordToken,
29
30
  resetPasswordTokenExpiresAt
30
31
  });
32
+ // null when the account was deleted between the caller's lookup and this write
33
+ if (user) {
34
+ await emitAudit({
35
+ strapi
36
+ }, AUDITED_EVENTS.PASSWORD_RESET_CREATE, {
37
+ ...toAdminUserEvent(user),
38
+ expiresAt: user.resetPasswordTokenExpiresAt
39
+ });
40
+ }
31
41
  return resetPasswordToken;
32
42
  };
43
+ /**
44
+ * Set the new password and consume the reset token. Shared by the CE and EE auth
45
+ * services, after each has validated the token.
46
+ */ const completePasswordReset = async (user, password)=>{
47
+ const updatedUser = await getService('user').updateById(user.id, {
48
+ password,
49
+ resetPasswordToken: null,
50
+ resetPasswordTokenExpiresAt: null
51
+ });
52
+ await emitAudit({
53
+ strapi
54
+ }, AUDITED_EVENTS.PASSWORD_RESET_CONFIRM, toAdminUserEvent(updatedUser));
55
+ return updatedUser;
56
+ };
33
57
  /**
34
58
  * Reject a reset-password token that has expired — or that has no expiry at all
35
59
  * (tokens issued before this was introduced) — clearing the stale token so it
@@ -148,11 +172,7 @@ const DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN = '1h';
148
172
  throw new ApplicationError();
149
173
  }
150
174
  await assertResetPasswordTokenIsValid(matchingUser);
151
- return getService('user').updateById(matchingUser.id, {
152
- password,
153
- resetPasswordToken: null,
154
- resetPasswordTokenExpiresAt: null
155
- });
175
+ return completePasswordReset(matchingUser, password);
156
176
  };
157
177
  var auth = {
158
178
  checkCredentials,
@@ -162,5 +182,5 @@ var auth = {
162
182
  resetPassword
163
183
  };
164
184
 
165
- export { assertResetPasswordTokenIsValid, assignResetPasswordToken, auth as default, getResetPasswordTokenTTL };
185
+ export { assertResetPasswordTokenIsValid, assignResetPasswordToken, completePasswordReset, auth as default, getResetPasswordTokenTTL };
166
186
  //# sourceMappingURL=auth.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.mjs","sources":["../../../../../server/src/services/auth.ts"],"sourcesContent":["import bcrypt from 'bcryptjs';\nimport _ from 'lodash';\nimport { errors } from '@strapi/utils';\nimport { getService } from '../utils';\nimport { expiresInToSeconds } from './token';\nimport type { AdminUser } from '../../../shared/contracts/shared';\nimport '@strapi/types';\n\nconst { ApplicationError } = errors;\n\n// Default lifetime of an admin reset-password token. Overridable via\n// `admin.forgotPassword.expiresIn` (number of seconds or a shorthand like '15m', '1h').\nconst DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN = '1h';\n\n/**\n * Resolve the reset-password token lifetime, in milliseconds, from config.\n * Falls back to {@link DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN} for unset/invalid values.\n */\nconst getResetPasswordTokenTTL = (): number => {\n const configured = strapi.config.get(\n 'admin.forgotPassword.expiresIn',\n DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN\n );\n const seconds =\n expiresInToSeconds(configured) ??\n (expiresInToSeconds(DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN) as number);\n return seconds * 1000;\n};\n\n/**\n * Create a reset-password token with an expiry and persist it on the user.\n * Shared by the CE and EE auth services so the expiry behaviour can't drift.\n * @returns the generated reset-password token\n */\nconst assignResetPasswordToken = async (userId: AdminUser['id']): Promise<string> => {\n const resetPasswordToken = getService('token').createToken();\n const resetPasswordTokenExpiresAt = new Date(Date.now() + getResetPasswordTokenTTL());\n\n await getService('user').updateById(userId, {\n resetPasswordToken,\n resetPasswordTokenExpiresAt,\n });\n\n return resetPasswordToken;\n};\n\n/**\n * Reject a reset-password token that has expired — or that has no expiry at all\n * (tokens issued before this was introduced) — clearing the stale token so it\n * cannot be retried. Shared by the CE and EE auth services. (GH#25711)\n */\nconst assertResetPasswordTokenIsValid = async (user: AdminUser): Promise<void> => {\n const { resetPasswordTokenExpiresAt } = user;\n const isExpired =\n !resetPasswordTokenExpiresAt || new Date(resetPasswordTokenExpiresAt).getTime() <= Date.now();\n\n if (isExpired) {\n // Clear the stale token so it can no longer be retried.\n await getService('user').updateById(user.id, {\n resetPasswordToken: null,\n resetPasswordTokenExpiresAt: null,\n });\n throw new ApplicationError('This reset password token has expired');\n }\n};\n\n/**\n * hashes a password\n * @param password - password to hash\n * @returns hashed password\n */\nconst hashPassword = (password: string) => bcrypt.hash(password, 10);\n\n/**\n * Validate a password\n * @param password\n * @param hash\n * @returns {Promise<boolean>} is the password valid\n */\nconst validatePassword = (password: string, hash: string) => bcrypt.compare(password, hash);\n\n/**\n * Check login credentials\n * @param email the users email address\n * @param password the users password\n */\nconst checkCredentials = async ({ email, password }: { email: string; password: string }) => {\n const user: AdminUser = await strapi.db.query('admin::user').findOne({ where: { email } });\n\n if (!user || !user.password) {\n return [null, false, { message: 'Invalid credentials' }];\n }\n\n const isValid = await validatePassword(password, user.password);\n\n if (!isValid) {\n return [null, false, { message: 'Invalid credentials' }];\n }\n\n if (!(user.isActive === true)) {\n return [null, false, { message: 'User not active' }];\n }\n\n return [null, user];\n};\n\n/**\n * Send an email to the user if it exists or do nothing\n * @param email user email for which to reset the password\n */\nconst forgotPassword = async ({ email } = {} as { email: string }) => {\n const user: AdminUser = await strapi.db\n .query('admin::user')\n .findOne({ where: { email, isActive: true } });\n if (!user) {\n return;\n }\n\n const resetPasswordToken = await assignResetPasswordToken(user.id);\n\n // Send an email to the admin.\n const url = `${strapi.config.get(\n 'admin.absoluteUrl'\n )}/auth/reset-password?code=${resetPasswordToken}`;\n\n return strapi\n .plugin('email')\n .service('email')\n .sendTemplatedEmail(\n {\n to: user.email,\n from: strapi.config.get('admin.forgotPassword.from'),\n replyTo: strapi.config.get('admin.forgotPassword.replyTo'),\n },\n strapi.config.get('admin.forgotPassword.emailTemplate'),\n {\n url,\n user: _.pick(user, ['email', 'firstname', 'lastname', 'username']),\n }\n )\n .catch((err: unknown) => {\n // log error server side but do not disclose it to the user to avoid leaking informations\n strapi.log.error(err);\n });\n};\n\n/**\n * Reset a user password\n * @param resetPasswordToken token generated to request a password reset\n * @param password new user password\n */\nconst resetPassword = async (\n { resetPasswordToken, password } = {} as { resetPasswordToken: string; password: string }\n) => {\n const matchingUser: AdminUser | undefined = await strapi.db\n .query('admin::user')\n .findOne({ where: { resetPasswordToken, isActive: true } });\n\n if (!matchingUser) {\n throw new ApplicationError();\n }\n\n await assertResetPasswordTokenIsValid(matchingUser);\n\n return getService('user').updateById(matchingUser.id, {\n password,\n resetPasswordToken: null,\n resetPasswordTokenExpiresAt: null,\n });\n};\n\nexport default { checkCredentials, validatePassword, hashPassword, forgotPassword, resetPassword };\nexport { getResetPasswordTokenTTL, assignResetPasswordToken, assertResetPasswordTokenIsValid };\n"],"names":["ApplicationError","errors","DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN","getResetPasswordTokenTTL","configured","strapi","config","get","seconds","expiresInToSeconds","assignResetPasswordToken","userId","resetPasswordToken","getService","createToken","resetPasswordTokenExpiresAt","Date","now","updateById","assertResetPasswordTokenIsValid","user","isExpired","getTime","id","hashPassword","password","bcrypt","hash","validatePassword","compare","checkCredentials","email","db","query","findOne","where","message","isValid","isActive","forgotPassword","url","plugin","service","sendTemplatedEmail","to","from","replyTo","_","pick","catch","err","log","error","resetPassword","matchingUser"],"mappings":"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"}
1
+ {"version":3,"file":"auth.mjs","sources":["../../../../../server/src/services/auth.ts"],"sourcesContent":["import bcrypt from 'bcryptjs';\nimport _ from 'lodash';\nimport { errors, emitAudit } from '@strapi/utils';\nimport { getService } from '../utils';\nimport { expiresInToSeconds } from './token';\nimport { AUDITED_EVENTS, toAdminUserEvent } from '../audit-logs/admin-users';\nimport type { AdminUser } from '../../../shared/contracts/shared';\nimport '@strapi/types';\n\nconst { ApplicationError } = errors;\n\n// Default lifetime of an admin reset-password token. Overridable via\n// `admin.forgotPassword.expiresIn` (number of seconds or a shorthand like '15m', '1h').\nconst DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN = '1h';\n\n/**\n * Resolve the reset-password token lifetime, in milliseconds, from config.\n * Falls back to {@link DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN} for unset/invalid values.\n */\nconst getResetPasswordTokenTTL = (): number => {\n const configured = strapi.config.get(\n 'admin.forgotPassword.expiresIn',\n DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN\n );\n const seconds =\n expiresInToSeconds(configured) ??\n (expiresInToSeconds(DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN) as number);\n return seconds * 1000;\n};\n\n/**\n * Create a reset-password token with an expiry and persist it on the user.\n * Shared by the CE and EE auth services so the expiry behaviour can't drift.\n * @returns the generated reset-password token\n */\nconst assignResetPasswordToken = async (userId: AdminUser['id']): Promise<string> => {\n const resetPasswordToken = getService('token').createToken();\n const resetPasswordTokenExpiresAt = new Date(Date.now() + getResetPasswordTokenTTL());\n\n const user = await getService('user').updateById(userId, {\n resetPasswordToken,\n resetPasswordTokenExpiresAt,\n });\n\n // null when the account was deleted between the caller's lookup and this write\n if (user) {\n await emitAudit({ strapi }, AUDITED_EVENTS.PASSWORD_RESET_CREATE, {\n ...toAdminUserEvent(user),\n expiresAt: user.resetPasswordTokenExpiresAt,\n });\n }\n\n return resetPasswordToken;\n};\n\n/**\n * Set the new password and consume the reset token. Shared by the CE and EE auth\n * services, after each has validated the token.\n */\nconst completePasswordReset = async (user: AdminUser, password: string): Promise<AdminUser> => {\n const updatedUser = await getService('user').updateById(user.id, {\n password,\n resetPasswordToken: null,\n resetPasswordTokenExpiresAt: null,\n });\n\n await emitAudit({ strapi }, AUDITED_EVENTS.PASSWORD_RESET_CONFIRM, toAdminUserEvent(updatedUser));\n\n return updatedUser;\n};\n\n/**\n * Reject a reset-password token that has expired — or that has no expiry at all\n * (tokens issued before this was introduced) — clearing the stale token so it\n * cannot be retried. Shared by the CE and EE auth services. (GH#25711)\n */\nconst assertResetPasswordTokenIsValid = async (user: AdminUser): Promise<void> => {\n const { resetPasswordTokenExpiresAt } = user;\n const isExpired =\n !resetPasswordTokenExpiresAt || new Date(resetPasswordTokenExpiresAt).getTime() <= Date.now();\n\n if (isExpired) {\n // Clear the stale token so it can no longer be retried.\n await getService('user').updateById(user.id, {\n resetPasswordToken: null,\n resetPasswordTokenExpiresAt: null,\n });\n throw new ApplicationError('This reset password token has expired');\n }\n};\n\n/**\n * hashes a password\n * @param password - password to hash\n * @returns hashed password\n */\nconst hashPassword = (password: string) => bcrypt.hash(password, 10);\n\n/**\n * Validate a password\n * @param password\n * @param hash\n * @returns {Promise<boolean>} is the password valid\n */\nconst validatePassword = (password: string, hash: string) => bcrypt.compare(password, hash);\n\n/**\n * Check login credentials\n * @param email the users email address\n * @param password the users password\n */\nconst checkCredentials = async ({ email, password }: { email: string; password: string }) => {\n const user: AdminUser = await strapi.db.query('admin::user').findOne({ where: { email } });\n\n if (!user || !user.password) {\n return [null, false, { message: 'Invalid credentials' }];\n }\n\n const isValid = await validatePassword(password, user.password);\n\n if (!isValid) {\n return [null, false, { message: 'Invalid credentials' }];\n }\n\n if (!(user.isActive === true)) {\n return [null, false, { message: 'User not active' }];\n }\n\n return [null, user];\n};\n\n/**\n * Send an email to the user if it exists or do nothing\n * @param email user email for which to reset the password\n */\nconst forgotPassword = async ({ email } = {} as { email: string }) => {\n const user: AdminUser = await strapi.db\n .query('admin::user')\n .findOne({ where: { email, isActive: true } });\n if (!user) {\n return;\n }\n\n const resetPasswordToken = await assignResetPasswordToken(user.id);\n\n // Send an email to the admin.\n const url = `${strapi.config.get(\n 'admin.absoluteUrl'\n )}/auth/reset-password?code=${resetPasswordToken}`;\n\n return strapi\n .plugin('email')\n .service('email')\n .sendTemplatedEmail(\n {\n to: user.email,\n from: strapi.config.get('admin.forgotPassword.from'),\n replyTo: strapi.config.get('admin.forgotPassword.replyTo'),\n },\n strapi.config.get('admin.forgotPassword.emailTemplate'),\n {\n url,\n user: _.pick(user, ['email', 'firstname', 'lastname', 'username']),\n }\n )\n .catch((err: unknown) => {\n // log error server side but do not disclose it to the user to avoid leaking informations\n strapi.log.error(err);\n });\n};\n\n/**\n * Reset a user password\n * @param resetPasswordToken token generated to request a password reset\n * @param password new user password\n */\nconst resetPassword = async (\n { resetPasswordToken, password } = {} as { resetPasswordToken: string; password: string }\n) => {\n const matchingUser: AdminUser | undefined = await strapi.db\n .query('admin::user')\n .findOne({ where: { resetPasswordToken, isActive: true } });\n\n if (!matchingUser) {\n throw new ApplicationError();\n }\n\n await assertResetPasswordTokenIsValid(matchingUser);\n\n return completePasswordReset(matchingUser, password);\n};\n\nexport default { checkCredentials, validatePassword, hashPassword, forgotPassword, resetPassword };\nexport {\n getResetPasswordTokenTTL,\n assignResetPasswordToken,\n assertResetPasswordTokenIsValid,\n completePasswordReset,\n};\n"],"names":["ApplicationError","errors","DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN","getResetPasswordTokenTTL","configured","strapi","config","get","seconds","expiresInToSeconds","assignResetPasswordToken","userId","resetPasswordToken","getService","createToken","resetPasswordTokenExpiresAt","Date","now","user","updateById","emitAudit","AUDITED_EVENTS","PASSWORD_RESET_CREATE","toAdminUserEvent","expiresAt","completePasswordReset","password","updatedUser","id","PASSWORD_RESET_CONFIRM","assertResetPasswordTokenIsValid","isExpired","getTime","hashPassword","bcrypt","hash","validatePassword","compare","checkCredentials","email","db","query","findOne","where","message","isValid","isActive","forgotPassword","url","plugin","service","sendTemplatedEmail","to","from","replyTo","_","pick","catch","err","log","error","resetPassword","matchingUser"],"mappings":"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"}
@@ -1,11 +1,11 @@
1
1
  'use strict';
2
2
 
3
- var fp = require('lodash/fp');
3
+ var _ = require('lodash');
4
4
  var index = require('../utils/index.js');
5
5
 
6
6
  const isValidCondition = (condition)=>{
7
7
  const { conditionProvider } = index.getService('permission');
8
- return fp.isString(condition) && conditionProvider.has(condition);
8
+ return _.isString(condition) && conditionProvider.has(condition);
9
9
  };
10
10
 
11
11
  exports.isValidCondition = isValidCondition;
@@ -1 +1 @@
1
- {"version":3,"file":"condition.js","sources":["../../../../../server/src/services/condition.ts"],"sourcesContent":["import { isString } from 'lodash/fp';\nimport { getService } from '../utils';\n\nconst isValidCondition = (condition: unknown) => {\n const { conditionProvider } = getService('permission');\n\n return isString(condition) && conditionProvider.has(condition);\n};\n\nexport { isValidCondition };\n"],"names":["isValidCondition","condition","conditionProvider","getService","isString","has"],"mappings":";;;;;AAGA,MAAMA,mBAAmB,CAACC,SAAAA,GAAAA;AACxB,IAAA,MAAM,EAAEC,iBAAiB,EAAE,GAAGC,gBAAAA,CAAW,YAAA,CAAA;AAEzC,IAAA,OAAOC,WAAAA,CAASH,SAAAA,CAAAA,IAAcC,iBAAAA,CAAkBG,GAAG,CAACJ,SAAAA,CAAAA;AACtD;;;;"}
1
+ {"version":3,"file":"condition.js","sources":["../../../../../server/src/services/condition.ts"],"sourcesContent":["import { isString } from 'lodash';\n\nimport { getService } from '../utils';\n\nconst isValidCondition = (condition: unknown) => {\n const { conditionProvider } = getService('permission');\n\n return isString(condition) && conditionProvider.has(condition);\n};\n\nexport { isValidCondition };\n"],"names":["isValidCondition","condition","conditionProvider","getService","isString","has"],"mappings":";;;;;AAIA,MAAMA,mBAAmB,CAACC,SAAAA,GAAAA;AACxB,IAAA,MAAM,EAAEC,iBAAiB,EAAE,GAAGC,gBAAAA,CAAW,YAAA,CAAA;AAEzC,IAAA,OAAOC,UAAAA,CAASH,SAAAA,CAAAA,IAAcC,iBAAAA,CAAkBG,GAAG,CAACJ,SAAAA,CAAAA;AACtD;;;;"}
@@ -1,4 +1,4 @@
1
- import { isString } from 'lodash/fp';
1
+ import { isString } from 'lodash';
2
2
  import { getService } from '../utils/index.mjs';
3
3
 
4
4
  const isValidCondition = (condition)=>{
@@ -1 +1 @@
1
- {"version":3,"file":"condition.mjs","sources":["../../../../../server/src/services/condition.ts"],"sourcesContent":["import { isString } from 'lodash/fp';\nimport { getService } from '../utils';\n\nconst isValidCondition = (condition: unknown) => {\n const { conditionProvider } = getService('permission');\n\n return isString(condition) && conditionProvider.has(condition);\n};\n\nexport { isValidCondition };\n"],"names":["isValidCondition","condition","conditionProvider","getService","isString","has"],"mappings":";;;AAGA,MAAMA,mBAAmB,CAACC,SAAAA,GAAAA;AACxB,IAAA,MAAM,EAAEC,iBAAiB,EAAE,GAAGC,UAAAA,CAAW,YAAA,CAAA;AAEzC,IAAA,OAAOC,QAAAA,CAASH,SAAAA,CAAAA,IAAcC,iBAAAA,CAAkBG,GAAG,CAACJ,SAAAA,CAAAA;AACtD;;;;"}
1
+ {"version":3,"file":"condition.mjs","sources":["../../../../../server/src/services/condition.ts"],"sourcesContent":["import { isString } from 'lodash';\n\nimport { getService } from '../utils';\n\nconst isValidCondition = (condition: unknown) => {\n const { conditionProvider } = getService('permission');\n\n return isString(condition) && conditionProvider.has(condition);\n};\n\nexport { isValidCondition };\n"],"names":["isValidCondition","condition","conditionProvider","getService","isString","has"],"mappings":";;;AAIA,MAAMA,mBAAmB,CAACC,SAAAA,GAAAA;AACxB,IAAA,MAAM,EAAEC,iBAAiB,EAAE,GAAGC,UAAAA,CAAW,YAAA,CAAA;AAEzC,IAAA,OAAOC,QAAAA,CAASH,SAAAA,CAAAA,IAAcC,iBAAAA,CAAkBG,GAAG,CAACJ,SAAAA,CAAAA;AACtD;;;;"}
@@ -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 index = require('../utils/index.js');
7
6
  var index$1 = require('../domain/action/index.js');
@@ -24,7 +23,7 @@ var ___default = /*#__PURE__*/_interopDefault(_);
24
23
  if (nonAuthorizableFields.includes(key)) return fields;
25
24
  const fieldPath = prefix ? `${prefix}.${key}` : key;
26
25
  const shouldBeIncluded = !requiredOnly || attr.required === true;
27
- const insideExistingFields = existingFields && existingFields.some(fp.startsWith(fieldPath));
26
+ const insideExistingFields = existingFields && existingFields.some((field)=>field.startsWith(fieldPath));
28
27
  if (attr.type === 'component') {
29
28
  if (shouldBeIncluded || insideExistingFields) {
30
29
  const compoFields = getNestedFields(components[attr.component], {
@@ -115,11 +114,13 @@ var ___default = /*#__PURE__*/_interopDefault(_);
115
114
  nestedFieldsCache.set(subject, possibleFields);
116
115
  }
117
116
  const currentFields = fields || [];
118
- const validUserFields = fp.uniq(possibleFields.filter((pf)=>currentFields.some((cf)=>pf === cf || fp.startsWith(`${cf}.`, pf))));
117
+ const validUserFields = [
118
+ ...new Set(possibleFields.filter((pf)=>currentFields.some((cf)=>pf === cf || pf.startsWith(`${cf}.`))))
119
+ ];
119
120
  // A field is considered "not nested" if no other valid user field starts with this field's path followed by a dot.
120
121
  // This helps to remove redundant parent paths when a more specific child path is already included.
121
122
  // For example, if 'component.title' is present, 'component' would be filtered out by this condition.
122
- const isNotNestedField = (field)=>!validUserFields.some((validUserField)=>validUserField !== field && fp.startsWith(`${field}.`, validUserField));
123
+ const isNotNestedField = (field)=>!validUserFields.some((validUserField)=>validUserField !== field && validUserField.startsWith(`${field}.`));
123
124
  // Filter out fields that are parent paths of other included fields.
124
125
  const newFields = validUserFields.filter(isNotNestedField);
125
126
  return index$2.default.setProperty('fields', newFields, permission);
@@ -1 +1 @@
1
- {"version":3,"file":"content-type.js","sources":["../../../../../server/src/services/content-type.ts"],"sourcesContent":["import _ from 'lodash';\nimport { uniq, startsWith } from 'lodash/fp';\nimport { contentTypes as contentTypesUtils } from '@strapi/utils';\nimport type { Modules, Struct } from '@strapi/types';\nimport { getService } from '../utils';\nimport actionDomain from '../domain/action';\nimport permissionDomain from '../domain/permission';\n\ninterface FieldOptions {\n prefix?: string; // prefix to add to the path\n nestingLevel?: number; // level of nesting to achieve\n requiredOnly?: boolean; // only returns required nestedFields\n existingFields?: string[]; // fields that are already selected, meaning that some sub-fields may be required\n restrictedSubjects?: string[]; // subjectsId to ignore\n components?: {\n // components where components attributes can be found\n [key: string]: any;\n };\n}\n\n/**\n * Creates an array of paths to the fields and nested fields, without path nodes\n */\nconst getNestedFields = (\n model: Struct.ContentTypeSchema,\n {\n prefix = '',\n nestingLevel = 15,\n components = {},\n requiredOnly = false,\n existingFields = [],\n }: FieldOptions\n): string[] => {\n if (nestingLevel === 0) {\n return prefix ? [prefix] : [];\n }\n\n const nonAuthorizableFields = contentTypesUtils.getNonVisibleAttributes(model);\n\n return _.reduce(\n model.attributes,\n (fields: any, attr: any, key: any) => {\n if (nonAuthorizableFields.includes(key)) return fields;\n\n const fieldPath = prefix ? `${prefix}.${key}` : key;\n const shouldBeIncluded = !requiredOnly || attr.required === true;\n const insideExistingFields = existingFields && existingFields.some(startsWith(fieldPath));\n\n if (attr.type === 'component') {\n if (shouldBeIncluded || insideExistingFields) {\n const compoFields = getNestedFields(components[attr.component], {\n nestingLevel: nestingLevel - 1,\n prefix: fieldPath,\n components,\n requiredOnly,\n existingFields,\n });\n\n if (compoFields.length === 0 && shouldBeIncluded) {\n return fields.concat(fieldPath);\n }\n\n return fields.concat(compoFields);\n }\n return fields;\n }\n\n if (shouldBeIncluded) {\n return fields.concat(fieldPath);\n }\n\n return fields;\n },\n []\n );\n};\n\n/**\n * Creates an array of paths to the fields and nested fields, with path nodes\n */\nconst getNestedFieldsWithIntermediate = (\n model: Struct.ContentTypeSchema,\n { prefix = '', nestingLevel = 15, components = {} }: FieldOptions\n): string[] => {\n if (nestingLevel === 0) {\n return [];\n }\n\n const nonAuthorizableFields = contentTypesUtils.getNonVisibleAttributes(model);\n\n return _.reduce(\n model.attributes,\n (fields: any, attr: any, key: any) => {\n if (nonAuthorizableFields.includes(key)) return fields;\n\n const fieldPath = prefix ? `${prefix}.${key}` : key;\n fields.push(fieldPath);\n\n if (attr.type === 'component') {\n const compoFields = getNestedFieldsWithIntermediate(components[attr.component], {\n nestingLevel: nestingLevel - 1,\n prefix: fieldPath,\n components,\n });\n\n fields.push(...compoFields);\n }\n\n return fields;\n },\n []\n );\n};\n\n/**\n * Creates an array of permissions with the \"properties.fields\" attribute filled\n */\nconst getPermissionsWithNestedFields = (\n actions: any[],\n { nestingLevel, restrictedSubjects = [] }: FieldOptions = {}\n): Modules.Permissions.PermissionRule[] => {\n return actions.reduce((permissions, action) => {\n const validSubjects = action.subjects.filter(\n (subject: any) => !restrictedSubjects.includes(subject)\n );\n\n // Create a Permission for each subject (content-type uid) within the action\n for (const subject of validSubjects) {\n const fields = actionDomain.appliesToProperty('fields', action)\n ? getNestedFields(strapi.contentTypes[subject], {\n components: strapi.components,\n nestingLevel,\n })\n : undefined;\n\n const permission = permissionDomain.create({\n action: action.actionId,\n subject,\n properties: { fields },\n });\n\n permissions.push(permission);\n }\n\n return permissions;\n }, []);\n};\n\n/**\n * Cleans permissions' fields (add required ones, remove the non-existing ones)\n */\nconst cleanPermissionFields = (\n permissions: Modules.Permissions.PermissionRule[]\n): Modules.Permissions.PermissionRule[] => {\n const { actionProvider } = getService('permission');\n const nestedFieldsCache = new Map<string, string[]>();\n\n return permissions.map((permission: any) => {\n const {\n action: actionId,\n subject,\n properties: { fields },\n } = permission;\n\n const action = actionProvider.get(actionId) as any;\n\n // todo see if it's possible to check property on action + subject (async)\n if (!actionDomain.appliesToProperty('fields', action)) {\n return permissionDomain.deleteProperty('fields', permission);\n }\n\n if (!subject || !strapi.contentTypes[subject]) {\n return permission;\n }\n\n let possibleFields = nestedFieldsCache.get(subject);\n if (!possibleFields) {\n possibleFields = getNestedFieldsWithIntermediate(strapi.contentTypes[subject], {\n components: strapi.components,\n });\n nestedFieldsCache.set(subject, possibleFields);\n }\n\n const currentFields: string[] = fields || [];\n\n const validUserFields: string[] = uniq(\n possibleFields.filter((pf) =>\n currentFields.some((cf) => pf === cf || startsWith(`${cf}.`, pf))\n )\n );\n\n // A field is considered \"not nested\" if no other valid user field starts with this field's path followed by a dot.\n // This helps to remove redundant parent paths when a more specific child path is already included.\n // For example, if 'component.title' is present, 'component' would be filtered out by this condition.\n const isNotNestedField = (field: string) =>\n !validUserFields.some(\n (validUserField: string) =>\n validUserField !== field && startsWith(`${field}.`, validUserField)\n );\n\n // Filter out fields that are parent paths of other included fields.\n const newFields = validUserFields.filter(isNotNestedField);\n\n return permissionDomain.setProperty('fields', newFields, permission);\n }, []);\n};\n\nexport {\n getNestedFields,\n getPermissionsWithNestedFields,\n cleanPermissionFields,\n getNestedFieldsWithIntermediate,\n};\n"],"names":["getNestedFields","model","prefix","nestingLevel","components","requiredOnly","existingFields","nonAuthorizableFields","contentTypesUtils","getNonVisibleAttributes","_","reduce","attributes","fields","attr","key","includes","fieldPath","shouldBeIncluded","required","insideExistingFields","some","startsWith","type","compoFields","component","length","concat","getNestedFieldsWithIntermediate","push","getPermissionsWithNestedFields","actions","restrictedSubjects","permissions","action","validSubjects","subjects","filter","subject","actionDomain","appliesToProperty","strapi","contentTypes","undefined","permission","permissionDomain","create","actionId","properties","cleanPermissionFields","actionProvider","getService","nestedFieldsCache","Map","map","get","deleteProperty","possibleFields","set","currentFields","validUserFields","uniq","pf","cf","isNotNestedField","field","validUserField","newFields","setProperty"],"mappings":"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"}
1
+ {"version":3,"file":"content-type.js","sources":["../../../../../server/src/services/content-type.ts"],"sourcesContent":["import _ from 'lodash';\n\nimport { contentTypes as contentTypesUtils } from '@strapi/utils';\nimport type { Modules, Struct } from '@strapi/types';\nimport { getService } from '../utils';\nimport actionDomain from '../domain/action';\nimport permissionDomain from '../domain/permission';\n\ninterface FieldOptions {\n prefix?: string; // prefix to add to the path\n nestingLevel?: number; // level of nesting to achieve\n requiredOnly?: boolean; // only returns required nestedFields\n existingFields?: string[]; // fields that are already selected, meaning that some sub-fields may be required\n restrictedSubjects?: string[]; // subjectsId to ignore\n components?: {\n // components where components attributes can be found\n [key: string]: any;\n };\n}\n\n/**\n * Creates an array of paths to the fields and nested fields, without path nodes\n */\nconst getNestedFields = (\n model: Struct.ContentTypeSchema,\n {\n prefix = '',\n nestingLevel = 15,\n components = {},\n requiredOnly = false,\n existingFields = [],\n }: FieldOptions\n): string[] => {\n if (nestingLevel === 0) {\n return prefix ? [prefix] : [];\n }\n\n const nonAuthorizableFields = contentTypesUtils.getNonVisibleAttributes(model);\n\n return _.reduce(\n model.attributes,\n (fields: any, attr: any, key: any) => {\n if (nonAuthorizableFields.includes(key)) return fields;\n\n const fieldPath = prefix ? `${prefix}.${key}` : key;\n const shouldBeIncluded = !requiredOnly || attr.required === true;\n const insideExistingFields =\n existingFields && existingFields.some((field) => field.startsWith(fieldPath));\n\n if (attr.type === 'component') {\n if (shouldBeIncluded || insideExistingFields) {\n const compoFields = getNestedFields(components[attr.component], {\n nestingLevel: nestingLevel - 1,\n prefix: fieldPath,\n components,\n requiredOnly,\n existingFields,\n });\n\n if (compoFields.length === 0 && shouldBeIncluded) {\n return fields.concat(fieldPath);\n }\n\n return fields.concat(compoFields);\n }\n return fields;\n }\n\n if (shouldBeIncluded) {\n return fields.concat(fieldPath);\n }\n\n return fields;\n },\n []\n );\n};\n\n/**\n * Creates an array of paths to the fields and nested fields, with path nodes\n */\nconst getNestedFieldsWithIntermediate = (\n model: Struct.ContentTypeSchema,\n { prefix = '', nestingLevel = 15, components = {} }: FieldOptions\n): string[] => {\n if (nestingLevel === 0) {\n return [];\n }\n\n const nonAuthorizableFields = contentTypesUtils.getNonVisibleAttributes(model);\n\n return _.reduce(\n model.attributes,\n (fields: any, attr: any, key: any) => {\n if (nonAuthorizableFields.includes(key)) return fields;\n\n const fieldPath = prefix ? `${prefix}.${key}` : key;\n fields.push(fieldPath);\n\n if (attr.type === 'component') {\n const compoFields = getNestedFieldsWithIntermediate(components[attr.component], {\n nestingLevel: nestingLevel - 1,\n prefix: fieldPath,\n components,\n });\n\n fields.push(...compoFields);\n }\n\n return fields;\n },\n []\n );\n};\n\n/**\n * Creates an array of permissions with the \"properties.fields\" attribute filled\n */\nconst getPermissionsWithNestedFields = (\n actions: any[],\n { nestingLevel, restrictedSubjects = [] }: FieldOptions = {}\n): Modules.Permissions.PermissionRule[] => {\n return actions.reduce((permissions, action) => {\n const validSubjects = action.subjects.filter(\n (subject: any) => !restrictedSubjects.includes(subject)\n );\n\n // Create a Permission for each subject (content-type uid) within the action\n for (const subject of validSubjects) {\n const fields = actionDomain.appliesToProperty('fields', action)\n ? getNestedFields(strapi.contentTypes[subject], {\n components: strapi.components,\n nestingLevel,\n })\n : undefined;\n\n const permission = permissionDomain.create({\n action: action.actionId,\n subject,\n properties: { fields },\n });\n\n permissions.push(permission);\n }\n\n return permissions;\n }, []);\n};\n\n/**\n * Cleans permissions' fields (add required ones, remove the non-existing ones)\n */\nconst cleanPermissionFields = (\n permissions: Modules.Permissions.PermissionRule[]\n): Modules.Permissions.PermissionRule[] => {\n const { actionProvider } = getService('permission');\n const nestedFieldsCache = new Map<string, string[]>();\n\n return permissions.map((permission: any) => {\n const {\n action: actionId,\n subject,\n properties: { fields },\n } = permission;\n\n const action = actionProvider.get(actionId) as any;\n\n // todo see if it's possible to check property on action + subject (async)\n if (!actionDomain.appliesToProperty('fields', action)) {\n return permissionDomain.deleteProperty('fields', permission);\n }\n\n if (!subject || !strapi.contentTypes[subject]) {\n return permission;\n }\n\n let possibleFields = nestedFieldsCache.get(subject);\n if (!possibleFields) {\n possibleFields = getNestedFieldsWithIntermediate(strapi.contentTypes[subject], {\n components: strapi.components,\n });\n nestedFieldsCache.set(subject, possibleFields);\n }\n\n const currentFields: string[] = fields || [];\n\n const validUserFields: string[] = [\n ...new Set(\n possibleFields.filter((pf) =>\n currentFields.some((cf) => pf === cf || pf.startsWith(`${cf}.`))\n )\n ),\n ];\n\n // A field is considered \"not nested\" if no other valid user field starts with this field's path followed by a dot.\n // This helps to remove redundant parent paths when a more specific child path is already included.\n // For example, if 'component.title' is present, 'component' would be filtered out by this condition.\n const isNotNestedField = (field: string) =>\n !validUserFields.some(\n (validUserField: string) =>\n validUserField !== field && validUserField.startsWith(`${field}.`)\n );\n\n // Filter out fields that are parent paths of other included fields.\n const newFields = validUserFields.filter(isNotNestedField);\n\n return permissionDomain.setProperty('fields', newFields, permission);\n }, []);\n};\n\nexport {\n getNestedFields,\n getPermissionsWithNestedFields,\n cleanPermissionFields,\n getNestedFieldsWithIntermediate,\n};\n"],"names":["getNestedFields","model","prefix","nestingLevel","components","requiredOnly","existingFields","nonAuthorizableFields","contentTypesUtils","getNonVisibleAttributes","_","reduce","attributes","fields","attr","key","includes","fieldPath","shouldBeIncluded","required","insideExistingFields","some","field","startsWith","type","compoFields","component","length","concat","getNestedFieldsWithIntermediate","push","getPermissionsWithNestedFields","actions","restrictedSubjects","permissions","action","validSubjects","subjects","filter","subject","actionDomain","appliesToProperty","strapi","contentTypes","undefined","permission","permissionDomain","create","actionId","properties","cleanPermissionFields","actionProvider","getService","nestedFieldsCache","Map","map","get","deleteProperty","possibleFields","set","currentFields","validUserFields","Set","pf","cf","isNotNestedField","validUserField","newFields","setProperty"],"mappings":"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"}
@@ -1,8 +1,7 @@
1
1
  import ___default from 'lodash';
2
- import { uniq, startsWith } from 'lodash/fp';
3
2
  import { contentTypes } from '@strapi/utils';
4
3
  import { getService } from '../utils/index.mjs';
5
- import actionDomain from '../domain/action/index.mjs';
4
+ import domain from '../domain/action/index.mjs';
6
5
  import permissionDomain from '../domain/permission/index.mjs';
7
6
 
8
7
  /**
@@ -18,7 +17,7 @@ import permissionDomain from '../domain/permission/index.mjs';
18
17
  if (nonAuthorizableFields.includes(key)) return fields;
19
18
  const fieldPath = prefix ? `${prefix}.${key}` : key;
20
19
  const shouldBeIncluded = !requiredOnly || attr.required === true;
21
- const insideExistingFields = existingFields && existingFields.some(startsWith(fieldPath));
20
+ const insideExistingFields = existingFields && existingFields.some((field)=>field.startsWith(fieldPath));
22
21
  if (attr.type === 'component') {
23
22
  if (shouldBeIncluded || insideExistingFields) {
24
23
  const compoFields = getNestedFields(components[attr.component], {
@@ -70,7 +69,7 @@ import permissionDomain from '../domain/permission/index.mjs';
70
69
  const validSubjects = action.subjects.filter((subject)=>!restrictedSubjects.includes(subject));
71
70
  // Create a Permission for each subject (content-type uid) within the action
72
71
  for (const subject of validSubjects){
73
- const fields = actionDomain.appliesToProperty('fields', action) ? getNestedFields(strapi.contentTypes[subject], {
72
+ const fields = domain.appliesToProperty('fields', action) ? getNestedFields(strapi.contentTypes[subject], {
74
73
  components: strapi.components,
75
74
  nestingLevel
76
75
  }) : undefined;
@@ -95,7 +94,7 @@ import permissionDomain from '../domain/permission/index.mjs';
95
94
  const { action: actionId, subject, properties: { fields } } = permission;
96
95
  const action = actionProvider.get(actionId);
97
96
  // todo see if it's possible to check property on action + subject (async)
98
- if (!actionDomain.appliesToProperty('fields', action)) {
97
+ if (!domain.appliesToProperty('fields', action)) {
99
98
  return permissionDomain.deleteProperty('fields', permission);
100
99
  }
101
100
  if (!subject || !strapi.contentTypes[subject]) {
@@ -109,11 +108,13 @@ import permissionDomain from '../domain/permission/index.mjs';
109
108
  nestedFieldsCache.set(subject, possibleFields);
110
109
  }
111
110
  const currentFields = fields || [];
112
- const validUserFields = uniq(possibleFields.filter((pf)=>currentFields.some((cf)=>pf === cf || startsWith(`${cf}.`, pf))));
111
+ const validUserFields = [
112
+ ...new Set(possibleFields.filter((pf)=>currentFields.some((cf)=>pf === cf || pf.startsWith(`${cf}.`))))
113
+ ];
113
114
  // A field is considered "not nested" if no other valid user field starts with this field's path followed by a dot.
114
115
  // This helps to remove redundant parent paths when a more specific child path is already included.
115
116
  // For example, if 'component.title' is present, 'component' would be filtered out by this condition.
116
- const isNotNestedField = (field)=>!validUserFields.some((validUserField)=>validUserField !== field && startsWith(`${field}.`, validUserField));
117
+ const isNotNestedField = (field)=>!validUserFields.some((validUserField)=>validUserField !== field && validUserField.startsWith(`${field}.`));
117
118
  // Filter out fields that are parent paths of other included fields.
118
119
  const newFields = validUserFields.filter(isNotNestedField);
119
120
  return permissionDomain.setProperty('fields', newFields, permission);
@@ -1 +1 @@
1
- {"version":3,"file":"content-type.mjs","sources":["../../../../../server/src/services/content-type.ts"],"sourcesContent":["import _ from 'lodash';\nimport { uniq, startsWith } from 'lodash/fp';\nimport { contentTypes as contentTypesUtils } from '@strapi/utils';\nimport type { Modules, Struct } from '@strapi/types';\nimport { getService } from '../utils';\nimport actionDomain from '../domain/action';\nimport permissionDomain from '../domain/permission';\n\ninterface FieldOptions {\n prefix?: string; // prefix to add to the path\n nestingLevel?: number; // level of nesting to achieve\n requiredOnly?: boolean; // only returns required nestedFields\n existingFields?: string[]; // fields that are already selected, meaning that some sub-fields may be required\n restrictedSubjects?: string[]; // subjectsId to ignore\n components?: {\n // components where components attributes can be found\n [key: string]: any;\n };\n}\n\n/**\n * Creates an array of paths to the fields and nested fields, without path nodes\n */\nconst getNestedFields = (\n model: Struct.ContentTypeSchema,\n {\n prefix = '',\n nestingLevel = 15,\n components = {},\n requiredOnly = false,\n existingFields = [],\n }: FieldOptions\n): string[] => {\n if (nestingLevel === 0) {\n return prefix ? [prefix] : [];\n }\n\n const nonAuthorizableFields = contentTypesUtils.getNonVisibleAttributes(model);\n\n return _.reduce(\n model.attributes,\n (fields: any, attr: any, key: any) => {\n if (nonAuthorizableFields.includes(key)) return fields;\n\n const fieldPath = prefix ? `${prefix}.${key}` : key;\n const shouldBeIncluded = !requiredOnly || attr.required === true;\n const insideExistingFields = existingFields && existingFields.some(startsWith(fieldPath));\n\n if (attr.type === 'component') {\n if (shouldBeIncluded || insideExistingFields) {\n const compoFields = getNestedFields(components[attr.component], {\n nestingLevel: nestingLevel - 1,\n prefix: fieldPath,\n components,\n requiredOnly,\n existingFields,\n });\n\n if (compoFields.length === 0 && shouldBeIncluded) {\n return fields.concat(fieldPath);\n }\n\n return fields.concat(compoFields);\n }\n return fields;\n }\n\n if (shouldBeIncluded) {\n return fields.concat(fieldPath);\n }\n\n return fields;\n },\n []\n );\n};\n\n/**\n * Creates an array of paths to the fields and nested fields, with path nodes\n */\nconst getNestedFieldsWithIntermediate = (\n model: Struct.ContentTypeSchema,\n { prefix = '', nestingLevel = 15, components = {} }: FieldOptions\n): string[] => {\n if (nestingLevel === 0) {\n return [];\n }\n\n const nonAuthorizableFields = contentTypesUtils.getNonVisibleAttributes(model);\n\n return _.reduce(\n model.attributes,\n (fields: any, attr: any, key: any) => {\n if (nonAuthorizableFields.includes(key)) return fields;\n\n const fieldPath = prefix ? `${prefix}.${key}` : key;\n fields.push(fieldPath);\n\n if (attr.type === 'component') {\n const compoFields = getNestedFieldsWithIntermediate(components[attr.component], {\n nestingLevel: nestingLevel - 1,\n prefix: fieldPath,\n components,\n });\n\n fields.push(...compoFields);\n }\n\n return fields;\n },\n []\n );\n};\n\n/**\n * Creates an array of permissions with the \"properties.fields\" attribute filled\n */\nconst getPermissionsWithNestedFields = (\n actions: any[],\n { nestingLevel, restrictedSubjects = [] }: FieldOptions = {}\n): Modules.Permissions.PermissionRule[] => {\n return actions.reduce((permissions, action) => {\n const validSubjects = action.subjects.filter(\n (subject: any) => !restrictedSubjects.includes(subject)\n );\n\n // Create a Permission for each subject (content-type uid) within the action\n for (const subject of validSubjects) {\n const fields = actionDomain.appliesToProperty('fields', action)\n ? getNestedFields(strapi.contentTypes[subject], {\n components: strapi.components,\n nestingLevel,\n })\n : undefined;\n\n const permission = permissionDomain.create({\n action: action.actionId,\n subject,\n properties: { fields },\n });\n\n permissions.push(permission);\n }\n\n return permissions;\n }, []);\n};\n\n/**\n * Cleans permissions' fields (add required ones, remove the non-existing ones)\n */\nconst cleanPermissionFields = (\n permissions: Modules.Permissions.PermissionRule[]\n): Modules.Permissions.PermissionRule[] => {\n const { actionProvider } = getService('permission');\n const nestedFieldsCache = new Map<string, string[]>();\n\n return permissions.map((permission: any) => {\n const {\n action: actionId,\n subject,\n properties: { fields },\n } = permission;\n\n const action = actionProvider.get(actionId) as any;\n\n // todo see if it's possible to check property on action + subject (async)\n if (!actionDomain.appliesToProperty('fields', action)) {\n return permissionDomain.deleteProperty('fields', permission);\n }\n\n if (!subject || !strapi.contentTypes[subject]) {\n return permission;\n }\n\n let possibleFields = nestedFieldsCache.get(subject);\n if (!possibleFields) {\n possibleFields = getNestedFieldsWithIntermediate(strapi.contentTypes[subject], {\n components: strapi.components,\n });\n nestedFieldsCache.set(subject, possibleFields);\n }\n\n const currentFields: string[] = fields || [];\n\n const validUserFields: string[] = uniq(\n possibleFields.filter((pf) =>\n currentFields.some((cf) => pf === cf || startsWith(`${cf}.`, pf))\n )\n );\n\n // A field is considered \"not nested\" if no other valid user field starts with this field's path followed by a dot.\n // This helps to remove redundant parent paths when a more specific child path is already included.\n // For example, if 'component.title' is present, 'component' would be filtered out by this condition.\n const isNotNestedField = (field: string) =>\n !validUserFields.some(\n (validUserField: string) =>\n validUserField !== field && startsWith(`${field}.`, validUserField)\n );\n\n // Filter out fields that are parent paths of other included fields.\n const newFields = validUserFields.filter(isNotNestedField);\n\n return permissionDomain.setProperty('fields', newFields, permission);\n }, []);\n};\n\nexport {\n getNestedFields,\n getPermissionsWithNestedFields,\n cleanPermissionFields,\n getNestedFieldsWithIntermediate,\n};\n"],"names":["getNestedFields","model","prefix","nestingLevel","components","requiredOnly","existingFields","nonAuthorizableFields","contentTypesUtils","getNonVisibleAttributes","_","reduce","attributes","fields","attr","key","includes","fieldPath","shouldBeIncluded","required","insideExistingFields","some","startsWith","type","compoFields","component","length","concat","getNestedFieldsWithIntermediate","push","getPermissionsWithNestedFields","actions","restrictedSubjects","permissions","action","validSubjects","subjects","filter","subject","actionDomain","appliesToProperty","strapi","contentTypes","undefined","permission","permissionDomain","create","actionId","properties","cleanPermissionFields","actionProvider","getService","nestedFieldsCache","Map","map","get","deleteProperty","possibleFields","set","currentFields","validUserFields","uniq","pf","cf","isNotNestedField","field","validUserField","newFields","setProperty"],"mappings":"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"}
1
+ {"version":3,"file":"content-type.mjs","sources":["../../../../../server/src/services/content-type.ts"],"sourcesContent":["import _ from 'lodash';\n\nimport { contentTypes as contentTypesUtils } from '@strapi/utils';\nimport type { Modules, Struct } from '@strapi/types';\nimport { getService } from '../utils';\nimport actionDomain from '../domain/action';\nimport permissionDomain from '../domain/permission';\n\ninterface FieldOptions {\n prefix?: string; // prefix to add to the path\n nestingLevel?: number; // level of nesting to achieve\n requiredOnly?: boolean; // only returns required nestedFields\n existingFields?: string[]; // fields that are already selected, meaning that some sub-fields may be required\n restrictedSubjects?: string[]; // subjectsId to ignore\n components?: {\n // components where components attributes can be found\n [key: string]: any;\n };\n}\n\n/**\n * Creates an array of paths to the fields and nested fields, without path nodes\n */\nconst getNestedFields = (\n model: Struct.ContentTypeSchema,\n {\n prefix = '',\n nestingLevel = 15,\n components = {},\n requiredOnly = false,\n existingFields = [],\n }: FieldOptions\n): string[] => {\n if (nestingLevel === 0) {\n return prefix ? [prefix] : [];\n }\n\n const nonAuthorizableFields = contentTypesUtils.getNonVisibleAttributes(model);\n\n return _.reduce(\n model.attributes,\n (fields: any, attr: any, key: any) => {\n if (nonAuthorizableFields.includes(key)) return fields;\n\n const fieldPath = prefix ? `${prefix}.${key}` : key;\n const shouldBeIncluded = !requiredOnly || attr.required === true;\n const insideExistingFields =\n existingFields && existingFields.some((field) => field.startsWith(fieldPath));\n\n if (attr.type === 'component') {\n if (shouldBeIncluded || insideExistingFields) {\n const compoFields = getNestedFields(components[attr.component], {\n nestingLevel: nestingLevel - 1,\n prefix: fieldPath,\n components,\n requiredOnly,\n existingFields,\n });\n\n if (compoFields.length === 0 && shouldBeIncluded) {\n return fields.concat(fieldPath);\n }\n\n return fields.concat(compoFields);\n }\n return fields;\n }\n\n if (shouldBeIncluded) {\n return fields.concat(fieldPath);\n }\n\n return fields;\n },\n []\n );\n};\n\n/**\n * Creates an array of paths to the fields and nested fields, with path nodes\n */\nconst getNestedFieldsWithIntermediate = (\n model: Struct.ContentTypeSchema,\n { prefix = '', nestingLevel = 15, components = {} }: FieldOptions\n): string[] => {\n if (nestingLevel === 0) {\n return [];\n }\n\n const nonAuthorizableFields = contentTypesUtils.getNonVisibleAttributes(model);\n\n return _.reduce(\n model.attributes,\n (fields: any, attr: any, key: any) => {\n if (nonAuthorizableFields.includes(key)) return fields;\n\n const fieldPath = prefix ? `${prefix}.${key}` : key;\n fields.push(fieldPath);\n\n if (attr.type === 'component') {\n const compoFields = getNestedFieldsWithIntermediate(components[attr.component], {\n nestingLevel: nestingLevel - 1,\n prefix: fieldPath,\n components,\n });\n\n fields.push(...compoFields);\n }\n\n return fields;\n },\n []\n );\n};\n\n/**\n * Creates an array of permissions with the \"properties.fields\" attribute filled\n */\nconst getPermissionsWithNestedFields = (\n actions: any[],\n { nestingLevel, restrictedSubjects = [] }: FieldOptions = {}\n): Modules.Permissions.PermissionRule[] => {\n return actions.reduce((permissions, action) => {\n const validSubjects = action.subjects.filter(\n (subject: any) => !restrictedSubjects.includes(subject)\n );\n\n // Create a Permission for each subject (content-type uid) within the action\n for (const subject of validSubjects) {\n const fields = actionDomain.appliesToProperty('fields', action)\n ? getNestedFields(strapi.contentTypes[subject], {\n components: strapi.components,\n nestingLevel,\n })\n : undefined;\n\n const permission = permissionDomain.create({\n action: action.actionId,\n subject,\n properties: { fields },\n });\n\n permissions.push(permission);\n }\n\n return permissions;\n }, []);\n};\n\n/**\n * Cleans permissions' fields (add required ones, remove the non-existing ones)\n */\nconst cleanPermissionFields = (\n permissions: Modules.Permissions.PermissionRule[]\n): Modules.Permissions.PermissionRule[] => {\n const { actionProvider } = getService('permission');\n const nestedFieldsCache = new Map<string, string[]>();\n\n return permissions.map((permission: any) => {\n const {\n action: actionId,\n subject,\n properties: { fields },\n } = permission;\n\n const action = actionProvider.get(actionId) as any;\n\n // todo see if it's possible to check property on action + subject (async)\n if (!actionDomain.appliesToProperty('fields', action)) {\n return permissionDomain.deleteProperty('fields', permission);\n }\n\n if (!subject || !strapi.contentTypes[subject]) {\n return permission;\n }\n\n let possibleFields = nestedFieldsCache.get(subject);\n if (!possibleFields) {\n possibleFields = getNestedFieldsWithIntermediate(strapi.contentTypes[subject], {\n components: strapi.components,\n });\n nestedFieldsCache.set(subject, possibleFields);\n }\n\n const currentFields: string[] = fields || [];\n\n const validUserFields: string[] = [\n ...new Set(\n possibleFields.filter((pf) =>\n currentFields.some((cf) => pf === cf || pf.startsWith(`${cf}.`))\n )\n ),\n ];\n\n // A field is considered \"not nested\" if no other valid user field starts with this field's path followed by a dot.\n // This helps to remove redundant parent paths when a more specific child path is already included.\n // For example, if 'component.title' is present, 'component' would be filtered out by this condition.\n const isNotNestedField = (field: string) =>\n !validUserFields.some(\n (validUserField: string) =>\n validUserField !== field && validUserField.startsWith(`${field}.`)\n );\n\n // Filter out fields that are parent paths of other included fields.\n const newFields = validUserFields.filter(isNotNestedField);\n\n return permissionDomain.setProperty('fields', newFields, permission);\n }, []);\n};\n\nexport {\n getNestedFields,\n getPermissionsWithNestedFields,\n cleanPermissionFields,\n getNestedFieldsWithIntermediate,\n};\n"],"names":["getNestedFields","model","prefix","nestingLevel","components","requiredOnly","existingFields","nonAuthorizableFields","contentTypesUtils","getNonVisibleAttributes","_","reduce","attributes","fields","attr","key","includes","fieldPath","shouldBeIncluded","required","insideExistingFields","some","field","startsWith","type","compoFields","component","length","concat","getNestedFieldsWithIntermediate","push","getPermissionsWithNestedFields","actions","restrictedSubjects","permissions","action","validSubjects","subjects","filter","subject","actionDomain","appliesToProperty","strapi","contentTypes","undefined","permission","permissionDomain","create","actionId","properties","cleanPermissionFields","actionProvider","getService","nestedFieldsCache","Map","map","get","deleteProperty","possibleFields","set","currentFields","validUserFields","Set","pf","cf","isNotNestedField","validUserField","newFields","setProperty"],"mappings":"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"}
@@ -17,7 +17,8 @@ const homepageService = ({ strapi })=>{
17
17
  });
18
18
  const countApiTokens = await index.getService('api-token-admin').countAll();
19
19
  const countAdmins = await index.getService('user').count();
20
- const countLocales = await strapi.plugin('i18n')?.service('locales')?.count() ?? null;
20
+ // null tells the homepage no localization plugin is installed, unlike 0 locales
21
+ const countLocales = strapi.localization.isEnabled() === true ? (await strapi.localization.getLocales()).length : null;
21
22
  const countsAssets = await strapi.db.query('plugin::upload.file').count();
22
23
  const countWebhooks = await strapi.db.query('strapi::webhook').count();
23
24
  const componentCategories = new Set(Object.values(strapi.components).map((component)=>component.category));
@@ -1 +1 @@
1
- {"version":3,"file":"homepage.js","sources":["../../../../../server/src/services/homepage.ts"],"sourcesContent":["import { Core } from '@strapi/types';\nimport { getService } from '../utils';\nimport {\n HomepageLayout,\n HomepageLayoutSchema,\n HomepageLayoutWrite,\n HomepageLayoutWriteSchema,\n} from '../controllers/validation/schema';\n\nconst DEFAULT_WIDTH = 6 as const;\nconst keyFor = (userId: number) => `homepage-layout:${userId}`;\n\nconst isContentTypeVisible = (model: any) =>\n model?.pluginOptions?.['content-type-builder']?.visible !== false;\n\nexport const homepageService = ({ strapi }: { strapi: Core.Strapi }) => {\n const adminStore = strapi.store({ type: 'core', name: 'admin' });\n const getKeyStatistics = async () => {\n const contentTypes = Object.entries(strapi.contentTypes).filter(([, contentType]) => {\n return isContentTypeVisible(contentType);\n });\n\n const countApiTokens = await getService('api-token-admin').countAll();\n const countAdmins = await getService('user').count();\n const countLocales = (await strapi.plugin('i18n')?.service('locales')?.count()) ?? null;\n const countsAssets = await strapi.db.query('plugin::upload.file').count();\n const countWebhooks = await strapi.db.query('strapi::webhook').count();\n\n const componentCategories = new Set(\n Object.values(strapi.components).map((component) => component.category)\n );\n const components = Array.from(componentCategories);\n\n return {\n assets: countsAssets,\n contentTypes: contentTypes.length,\n components: components.length,\n locales: countLocales,\n admins: countAdmins,\n webhooks: countWebhooks,\n apiTokens: countApiTokens,\n };\n };\n\n const getHomepageLayout = async (userId: number): Promise<HomepageLayout | null> => {\n const key = keyFor(userId);\n const value = await adminStore.get({ key });\n if (!value) {\n // nothing saved yet\n return null;\n }\n\n return HomepageLayoutSchema.parse(value);\n };\n\n const updateHomepageLayout = async (userId: number, input: unknown): Promise<HomepageLayout> => {\n const write: HomepageLayoutWrite = HomepageLayoutWriteSchema.parse(input);\n\n const key = keyFor(userId);\n\n const currentRaw = await adminStore.get({ key });\n const current: HomepageLayout | null = currentRaw\n ? HomepageLayoutSchema.parse(currentRaw)\n : null;\n\n const widgetsNext = write.widgets ?? current?.widgets ?? [];\n\n // Normalize widths (fill defaults where missing)\n const normalizedWidgets = widgetsNext.map((w) => {\n const prev = current?.widgets.find((cw) => cw.uid === w.uid);\n return {\n uid: w.uid,\n width: w.width ?? prev?.width ?? DEFAULT_WIDTH,\n };\n });\n\n const next: HomepageLayout = {\n version: write.version ?? 1,\n widgets: normalizedWidgets,\n updatedAt: write.updatedAt ?? new Date().toISOString(),\n };\n\n await adminStore.set({ key, value: next });\n return next;\n };\n return {\n getKeyStatistics,\n getHomepageLayout,\n updateHomepageLayout,\n };\n};\n"],"names":["DEFAULT_WIDTH","keyFor","userId","isContentTypeVisible","model","pluginOptions","visible","homepageService","strapi","adminStore","store","type","name","getKeyStatistics","contentTypes","Object","entries","filter","contentType","countApiTokens","getService","countAll","countAdmins","count","countLocales","plugin","service","countsAssets","db","query","countWebhooks","componentCategories","Set","values","components","map","component","category","Array","from","assets","length","locales","admins","webhooks","apiTokens","getHomepageLayout","key","value","get","HomepageLayoutSchema","parse","updateHomepageLayout","input","write","HomepageLayoutWriteSchema","currentRaw","current","widgetsNext","widgets","normalizedWidgets","w","prev","find","cw","uid","width","next","version","updatedAt","Date","toISOString","set"],"mappings":";;;;;AASA,MAAMA,aAAAA,GAAgB,CAAA;AACtB,MAAMC,SAAS,CAACC,MAAAA,GAAmB,CAAC,gBAAgB,EAAEA,MAAAA,CAAAA,CAAQ;AAE9D,MAAMC,oBAAAA,GAAuB,CAACC,KAAAA,GAC5BA,KAAAA,EAAOC,gBAAgB,sBAAA,CAAuB,EAAEC,OAAAA,KAAY,KAAA;AAEvD,MAAMC,eAAAA,GAAkB,CAAC,EAAEC,MAAM,EAA2B,GAAA;IACjE,MAAMC,UAAAA,GAAaD,MAAAA,CAAOE,KAAK,CAAC;QAAEC,IAAAA,EAAM,MAAA;QAAQC,IAAAA,EAAM;AAAQ,KAAA,CAAA;AAC9D,IAAA,MAAMC,gBAAAA,GAAmB,UAAA;QACvB,MAAMC,YAAAA,GAAeC,MAAAA,CAAOC,OAAO,CAACR,MAAAA,CAAOM,YAAY,CAAA,CAAEG,MAAM,CAAC,CAAC,GAAGC,WAAAA,CAAY,GAAA;AAC9E,YAAA,OAAOf,oBAAAA,CAAqBe,WAAAA,CAAAA;AAC9B,QAAA,CAAA,CAAA;AAEA,QAAA,MAAMC,cAAAA,GAAiB,MAAMC,gBAAAA,CAAW,iBAAA,CAAA,CAAmBC,QAAQ,EAAA;AACnE,QAAA,MAAMC,WAAAA,GAAc,MAAMF,gBAAAA,CAAW,MAAA,CAAA,CAAQG,KAAK,EAAA;QAClD,MAAMC,YAAAA,GAAe,MAAOhB,MAAAA,CAAOiB,MAAM,CAAC,MAAA,CAAA,EAASC,OAAAA,CAAQ,SAAA,CAAA,EAAYH,KAAAA,EAAAA,IAAY,IAAA;QACnF,MAAMI,YAAAA,GAAe,MAAMnB,MAAAA,CAAOoB,EAAE,CAACC,KAAK,CAAC,uBAAuBN,KAAK,EAAA;QACvE,MAAMO,aAAAA,GAAgB,MAAMtB,MAAAA,CAAOoB,EAAE,CAACC,KAAK,CAAC,mBAAmBN,KAAK,EAAA;AAEpE,QAAA,MAAMQ,mBAAAA,GAAsB,IAAIC,GAAAA,CAC9BjB,MAAAA,CAAOkB,MAAM,CAACzB,MAAAA,CAAO0B,UAAU,CAAA,CAAEC,GAAG,CAAC,CAACC,SAAAA,GAAcA,UAAUC,QAAQ,CAAA,CAAA;QAExE,MAAMH,UAAAA,GAAaI,KAAAA,CAAMC,IAAI,CAACR,mBAAAA,CAAAA;QAE9B,OAAO;YACLS,MAAAA,EAAQb,YAAAA;AACRb,YAAAA,YAAAA,EAAcA,aAAa2B,MAAM;AACjCP,YAAAA,UAAAA,EAAYA,WAAWO,MAAM;YAC7BC,OAAAA,EAASlB,YAAAA;YACTmB,MAAAA,EAAQrB,WAAAA;YACRsB,QAAAA,EAAUd,aAAAA;YACVe,SAAAA,EAAW1B;AACb,SAAA;AACF,IAAA,CAAA;AAEA,IAAA,MAAM2B,oBAAoB,OAAO5C,MAAAA,GAAAA;AAC/B,QAAA,MAAM6C,MAAM9C,MAAAA,CAAOC,MAAAA,CAAAA;AACnB,QAAA,MAAM8C,KAAAA,GAAQ,MAAMvC,UAAAA,CAAWwC,GAAG,CAAC;AAAEF,YAAAA;AAAI,SAAA,CAAA;AACzC,QAAA,IAAI,CAACC,KAAAA,EAAO;;YAEV,OAAO,IAAA;AACT,QAAA;QAEA,OAAOE,2BAAAA,CAAqBC,KAAK,CAACH,KAAAA,CAAAA;AACpC,IAAA,CAAA;IAEA,MAAMI,oBAAAA,GAAuB,OAAOlD,MAAAA,EAAgBmD,KAAAA,GAAAA;QAClD,MAAMC,KAAAA,GAA6BC,gCAAAA,CAA0BJ,KAAK,CAACE,KAAAA,CAAAA;AAEnE,QAAA,MAAMN,MAAM9C,MAAAA,CAAOC,MAAAA,CAAAA;AAEnB,QAAA,MAAMsD,UAAAA,GAAa,MAAM/C,UAAAA,CAAWwC,GAAG,CAAC;AAAEF,YAAAA;AAAI,SAAA,CAAA;AAC9C,QAAA,MAAMU,OAAAA,GAAiCD,UAAAA,GACnCN,2BAAAA,CAAqBC,KAAK,CAACK,UAAAA,CAAAA,GAC3B,IAAA;AAEJ,QAAA,MAAME,cAAcJ,KAAAA,CAAMK,OAAO,IAAIF,OAAAA,EAASE,WAAW,EAAE;;AAG3D,QAAA,MAAMC,iBAAAA,GAAoBF,WAAAA,CAAYvB,GAAG,CAAC,CAAC0B,CAAAA,GAAAA;YACzC,MAAMC,IAAAA,GAAOL,OAAAA,EAASE,OAAAA,CAAQI,IAAAA,CAAK,CAACC,KAAOA,EAAAA,CAAGC,GAAG,KAAKJ,CAAAA,CAAEI,GAAG,CAAA;YAC3D,OAAO;AACLA,gBAAAA,GAAAA,EAAKJ,EAAEI,GAAG;AACVC,gBAAAA,KAAAA,EAAOL,CAAAA,CAAEK,KAAK,IAAIJ,IAAAA,EAAMI,KAAAA,IAASlE;AACnC,aAAA;AACF,QAAA,CAAA,CAAA;AAEA,QAAA,MAAMmE,IAAAA,GAAuB;YAC3BC,OAAAA,EAASd,KAAAA,CAAMc,OAAO,IAAI,CAAA;YAC1BT,OAAAA,EAASC,iBAAAA;AACTS,YAAAA,SAAAA,EAAWf,KAAAA,CAAMe,SAAS,IAAI,IAAIC,OAAOC,WAAW;AACtD,SAAA;QAEA,MAAM9D,UAAAA,CAAW+D,GAAG,CAAC;AAAEzB,YAAAA,GAAAA;YAAKC,KAAAA,EAAOmB;AAAK,SAAA,CAAA;QACxC,OAAOA,IAAAA;AACT,IAAA,CAAA;IACA,OAAO;AACLtD,QAAAA,gBAAAA;AACAiC,QAAAA,iBAAAA;AACAM,QAAAA;AACF,KAAA;AACF;;;;"}
1
+ {"version":3,"file":"homepage.js","sources":["../../../../../server/src/services/homepage.ts"],"sourcesContent":["import { Core } from '@strapi/types';\nimport { getService } from '../utils';\nimport {\n HomepageLayout,\n HomepageLayoutSchema,\n HomepageLayoutWrite,\n HomepageLayoutWriteSchema,\n} from '../controllers/validation/schema';\n\nconst DEFAULT_WIDTH = 6 as const;\nconst keyFor = (userId: number) => `homepage-layout:${userId}`;\n\nconst isContentTypeVisible = (model: any) =>\n model?.pluginOptions?.['content-type-builder']?.visible !== false;\n\nexport const homepageService = ({ strapi }: { strapi: Core.Strapi }) => {\n const adminStore = strapi.store({ type: 'core', name: 'admin' });\n const getKeyStatistics = async () => {\n const contentTypes = Object.entries(strapi.contentTypes).filter(([, contentType]) => {\n return isContentTypeVisible(contentType);\n });\n\n const countApiTokens = await getService('api-token-admin').countAll();\n const countAdmins = await getService('user').count();\n // null tells the homepage no localization plugin is installed, unlike 0 locales\n const countLocales =\n strapi.localization.isEnabled() === true\n ? (await strapi.localization.getLocales()).length\n : null;\n const countsAssets = await strapi.db.query('plugin::upload.file').count();\n const countWebhooks = await strapi.db.query('strapi::webhook').count();\n\n const componentCategories = new Set(\n Object.values(strapi.components).map((component) => component.category)\n );\n const components = Array.from(componentCategories);\n\n return {\n assets: countsAssets,\n contentTypes: contentTypes.length,\n components: components.length,\n locales: countLocales,\n admins: countAdmins,\n webhooks: countWebhooks,\n apiTokens: countApiTokens,\n };\n };\n\n const getHomepageLayout = async (userId: number): Promise<HomepageLayout | null> => {\n const key = keyFor(userId);\n const value = await adminStore.get({ key });\n if (!value) {\n // nothing saved yet\n return null;\n }\n\n return HomepageLayoutSchema.parse(value);\n };\n\n const updateHomepageLayout = async (userId: number, input: unknown): Promise<HomepageLayout> => {\n const write: HomepageLayoutWrite = HomepageLayoutWriteSchema.parse(input);\n\n const key = keyFor(userId);\n\n const currentRaw = await adminStore.get({ key });\n const current: HomepageLayout | null = currentRaw\n ? HomepageLayoutSchema.parse(currentRaw)\n : null;\n\n const widgetsNext = write.widgets ?? current?.widgets ?? [];\n\n // Normalize widths (fill defaults where missing)\n const normalizedWidgets = widgetsNext.map((w) => {\n const prev = current?.widgets.find((cw) => cw.uid === w.uid);\n return {\n uid: w.uid,\n width: w.width ?? prev?.width ?? DEFAULT_WIDTH,\n };\n });\n\n const next: HomepageLayout = {\n version: write.version ?? 1,\n widgets: normalizedWidgets,\n updatedAt: write.updatedAt ?? new Date().toISOString(),\n };\n\n await adminStore.set({ key, value: next });\n return next;\n };\n return {\n getKeyStatistics,\n getHomepageLayout,\n updateHomepageLayout,\n };\n};\n"],"names":["DEFAULT_WIDTH","keyFor","userId","isContentTypeVisible","model","pluginOptions","visible","homepageService","strapi","adminStore","store","type","name","getKeyStatistics","contentTypes","Object","entries","filter","contentType","countApiTokens","getService","countAll","countAdmins","count","countLocales","localization","isEnabled","getLocales","length","countsAssets","db","query","countWebhooks","componentCategories","Set","values","components","map","component","category","Array","from","assets","locales","admins","webhooks","apiTokens","getHomepageLayout","key","value","get","HomepageLayoutSchema","parse","updateHomepageLayout","input","write","HomepageLayoutWriteSchema","currentRaw","current","widgetsNext","widgets","normalizedWidgets","w","prev","find","cw","uid","width","next","version","updatedAt","Date","toISOString","set"],"mappings":"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"}
@@ -15,7 +15,8 @@ const homepageService = ({ strapi })=>{
15
15
  });
16
16
  const countApiTokens = await getService('api-token-admin').countAll();
17
17
  const countAdmins = await getService('user').count();
18
- const countLocales = await strapi.plugin('i18n')?.service('locales')?.count() ?? null;
18
+ // null tells the homepage no localization plugin is installed, unlike 0 locales
19
+ const countLocales = strapi.localization.isEnabled() === true ? (await strapi.localization.getLocales()).length : null;
19
20
  const countsAssets = await strapi.db.query('plugin::upload.file').count();
20
21
  const countWebhooks = await strapi.db.query('strapi::webhook').count();
21
22
  const componentCategories = new Set(Object.values(strapi.components).map((component)=>component.category));
@@ -1 +1 @@
1
- {"version":3,"file":"homepage.mjs","sources":["../../../../../server/src/services/homepage.ts"],"sourcesContent":["import { Core } from '@strapi/types';\nimport { getService } from '../utils';\nimport {\n HomepageLayout,\n HomepageLayoutSchema,\n HomepageLayoutWrite,\n HomepageLayoutWriteSchema,\n} from '../controllers/validation/schema';\n\nconst DEFAULT_WIDTH = 6 as const;\nconst keyFor = (userId: number) => `homepage-layout:${userId}`;\n\nconst isContentTypeVisible = (model: any) =>\n model?.pluginOptions?.['content-type-builder']?.visible !== false;\n\nexport const homepageService = ({ strapi }: { strapi: Core.Strapi }) => {\n const adminStore = strapi.store({ type: 'core', name: 'admin' });\n const getKeyStatistics = async () => {\n const contentTypes = Object.entries(strapi.contentTypes).filter(([, contentType]) => {\n return isContentTypeVisible(contentType);\n });\n\n const countApiTokens = await getService('api-token-admin').countAll();\n const countAdmins = await getService('user').count();\n const countLocales = (await strapi.plugin('i18n')?.service('locales')?.count()) ?? null;\n const countsAssets = await strapi.db.query('plugin::upload.file').count();\n const countWebhooks = await strapi.db.query('strapi::webhook').count();\n\n const componentCategories = new Set(\n Object.values(strapi.components).map((component) => component.category)\n );\n const components = Array.from(componentCategories);\n\n return {\n assets: countsAssets,\n contentTypes: contentTypes.length,\n components: components.length,\n locales: countLocales,\n admins: countAdmins,\n webhooks: countWebhooks,\n apiTokens: countApiTokens,\n };\n };\n\n const getHomepageLayout = async (userId: number): Promise<HomepageLayout | null> => {\n const key = keyFor(userId);\n const value = await adminStore.get({ key });\n if (!value) {\n // nothing saved yet\n return null;\n }\n\n return HomepageLayoutSchema.parse(value);\n };\n\n const updateHomepageLayout = async (userId: number, input: unknown): Promise<HomepageLayout> => {\n const write: HomepageLayoutWrite = HomepageLayoutWriteSchema.parse(input);\n\n const key = keyFor(userId);\n\n const currentRaw = await adminStore.get({ key });\n const current: HomepageLayout | null = currentRaw\n ? HomepageLayoutSchema.parse(currentRaw)\n : null;\n\n const widgetsNext = write.widgets ?? current?.widgets ?? [];\n\n // Normalize widths (fill defaults where missing)\n const normalizedWidgets = widgetsNext.map((w) => {\n const prev = current?.widgets.find((cw) => cw.uid === w.uid);\n return {\n uid: w.uid,\n width: w.width ?? prev?.width ?? DEFAULT_WIDTH,\n };\n });\n\n const next: HomepageLayout = {\n version: write.version ?? 1,\n widgets: normalizedWidgets,\n updatedAt: write.updatedAt ?? new Date().toISOString(),\n };\n\n await adminStore.set({ key, value: next });\n return next;\n };\n return {\n getKeyStatistics,\n getHomepageLayout,\n updateHomepageLayout,\n };\n};\n"],"names":["DEFAULT_WIDTH","keyFor","userId","isContentTypeVisible","model","pluginOptions","visible","homepageService","strapi","adminStore","store","type","name","getKeyStatistics","contentTypes","Object","entries","filter","contentType","countApiTokens","getService","countAll","countAdmins","count","countLocales","plugin","service","countsAssets","db","query","countWebhooks","componentCategories","Set","values","components","map","component","category","Array","from","assets","length","locales","admins","webhooks","apiTokens","getHomepageLayout","key","value","get","HomepageLayoutSchema","parse","updateHomepageLayout","input","write","HomepageLayoutWriteSchema","currentRaw","current","widgetsNext","widgets","normalizedWidgets","w","prev","find","cw","uid","width","next","version","updatedAt","Date","toISOString","set"],"mappings":"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"}
1
+ {"version":3,"file":"homepage.mjs","sources":["../../../../../server/src/services/homepage.ts"],"sourcesContent":["import { Core } from '@strapi/types';\nimport { getService } from '../utils';\nimport {\n HomepageLayout,\n HomepageLayoutSchema,\n HomepageLayoutWrite,\n HomepageLayoutWriteSchema,\n} from '../controllers/validation/schema';\n\nconst DEFAULT_WIDTH = 6 as const;\nconst keyFor = (userId: number) => `homepage-layout:${userId}`;\n\nconst isContentTypeVisible = (model: any) =>\n model?.pluginOptions?.['content-type-builder']?.visible !== false;\n\nexport const homepageService = ({ strapi }: { strapi: Core.Strapi }) => {\n const adminStore = strapi.store({ type: 'core', name: 'admin' });\n const getKeyStatistics = async () => {\n const contentTypes = Object.entries(strapi.contentTypes).filter(([, contentType]) => {\n return isContentTypeVisible(contentType);\n });\n\n const countApiTokens = await getService('api-token-admin').countAll();\n const countAdmins = await getService('user').count();\n // null tells the homepage no localization plugin is installed, unlike 0 locales\n const countLocales =\n strapi.localization.isEnabled() === true\n ? (await strapi.localization.getLocales()).length\n : null;\n const countsAssets = await strapi.db.query('plugin::upload.file').count();\n const countWebhooks = await strapi.db.query('strapi::webhook').count();\n\n const componentCategories = new Set(\n Object.values(strapi.components).map((component) => component.category)\n );\n const components = Array.from(componentCategories);\n\n return {\n assets: countsAssets,\n contentTypes: contentTypes.length,\n components: components.length,\n locales: countLocales,\n admins: countAdmins,\n webhooks: countWebhooks,\n apiTokens: countApiTokens,\n };\n };\n\n const getHomepageLayout = async (userId: number): Promise<HomepageLayout | null> => {\n const key = keyFor(userId);\n const value = await adminStore.get({ key });\n if (!value) {\n // nothing saved yet\n return null;\n }\n\n return HomepageLayoutSchema.parse(value);\n };\n\n const updateHomepageLayout = async (userId: number, input: unknown): Promise<HomepageLayout> => {\n const write: HomepageLayoutWrite = HomepageLayoutWriteSchema.parse(input);\n\n const key = keyFor(userId);\n\n const currentRaw = await adminStore.get({ key });\n const current: HomepageLayout | null = currentRaw\n ? HomepageLayoutSchema.parse(currentRaw)\n : null;\n\n const widgetsNext = write.widgets ?? current?.widgets ?? [];\n\n // Normalize widths (fill defaults where missing)\n const normalizedWidgets = widgetsNext.map((w) => {\n const prev = current?.widgets.find((cw) => cw.uid === w.uid);\n return {\n uid: w.uid,\n width: w.width ?? prev?.width ?? DEFAULT_WIDTH,\n };\n });\n\n const next: HomepageLayout = {\n version: write.version ?? 1,\n widgets: normalizedWidgets,\n updatedAt: write.updatedAt ?? new Date().toISOString(),\n };\n\n await adminStore.set({ key, value: next });\n return next;\n };\n return {\n getKeyStatistics,\n getHomepageLayout,\n updateHomepageLayout,\n };\n};\n"],"names":["DEFAULT_WIDTH","keyFor","userId","isContentTypeVisible","model","pluginOptions","visible","homepageService","strapi","adminStore","store","type","name","getKeyStatistics","contentTypes","Object","entries","filter","contentType","countApiTokens","getService","countAll","countAdmins","count","countLocales","localization","isEnabled","getLocales","length","countsAssets","db","query","countWebhooks","componentCategories","Set","values","components","map","component","category","Array","from","assets","locales","admins","webhooks","apiTokens","getHomepageLayout","key","value","get","HomepageLayoutSchema","parse","updateHomepageLayout","input","write","HomepageLayoutWriteSchema","currentRaw","current","widgetsNext","widgets","normalizedWidgets","w","prev","find","cw","uid","width","next","version","updatedAt","Date","toISOString","set"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var fp = require('lodash/fp');
3
+ var _ = require('lodash');
4
4
  var passportLocal = require('passport-local');
5
5
  var index = require('../../utils/index.js');
6
6
 
@@ -11,7 +11,7 @@ const createLocalStrategy = (strapi, middleware)=>{
11
11
  session: false
12
12
  }, (email, password, done)=>{
13
13
  return index.getService('auth').checkCredentials({
14
- email: fp.toLower(email),
14
+ email: _.toLower(email),
15
15
  password
16
16
  }).then(async ([error, user, message])=>{
17
17
  if (middleware) {
@@ -1 +1 @@
1
- {"version":3,"file":"local-strategy.js","sources":["../../../../../../server/src/services/passport/local-strategy.ts"],"sourcesContent":["import { toLower } from 'lodash/fp';\nimport { Strategy as LocalStrategy } from 'passport-local';\nimport type { Core } from '@strapi/types';\nimport { getService } from '../../utils';\n\nconst createLocalStrategy = (strapi: Core.Strapi, middleware?: any) => {\n return new LocalStrategy(\n {\n usernameField: 'email',\n passwordField: 'password',\n session: false,\n },\n (email: string, password: string, done: any) => {\n return getService('auth')\n .checkCredentials({ email: toLower(email), password })\n .then(async ([error, user, message]) => {\n if (middleware) {\n return middleware([error, user, message], done);\n }\n\n return done(error, user, message);\n })\n .catch((error) => done(error));\n }\n );\n};\n\nexport default createLocalStrategy;\n"],"names":["createLocalStrategy","strapi","middleware","LocalStrategy","usernameField","passwordField","session","email","password","done","getService","checkCredentials","toLower","then","error","user","message","catch"],"mappings":";;;;;;AAKA,MAAMA,mBAAAA,GAAsB,CAACC,MAAAA,EAAqBC,UAAAA,GAAAA;AAChD,IAAA,OAAO,IAAIC,sBAAAA,CACT;QACEC,aAAAA,EAAe,OAAA;QACfC,aAAAA,EAAe,UAAA;QACfC,OAAAA,EAAS;KACX,EACA,CAACC,OAAeC,QAAAA,EAAkBC,IAAAA,GAAAA;QAChC,OAAOC,gBAAAA,CAAW,MAAA,CAAA,CACfC,gBAAgB,CAAC;AAAEJ,YAAAA,KAAAA,EAAOK,UAAAA,CAAQL,KAAAA,CAAAA;AAAQC,YAAAA;AAAS,SAAA,CAAA,CACnDK,IAAI,CAAC,OAAO,CAACC,KAAAA,EAAOC,MAAMC,OAAAA,CAAQ,GAAA;AACjC,YAAA,IAAId,UAAAA,EAAY;AACd,gBAAA,OAAOA,UAAAA,CAAW;AAACY,oBAAAA,KAAAA;AAAOC,oBAAAA,IAAAA;AAAMC,oBAAAA;iBAAQ,EAAEP,IAAAA,CAAAA;AAC5C,YAAA;YAEA,OAAOA,IAAAA,CAAKK,OAAOC,IAAAA,EAAMC,OAAAA,CAAAA;AAC3B,QAAA,CAAA,CAAA,CACCC,KAAK,CAAC,CAACH,KAAAA,GAAUL,IAAAA,CAAKK,KAAAA,CAAAA,CAAAA;AAC3B,IAAA,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"local-strategy.js","sources":["../../../../../../server/src/services/passport/local-strategy.ts"],"sourcesContent":["import { toLower } from 'lodash';\n\nimport { Strategy as LocalStrategy } from 'passport-local';\nimport type { Core } from '@strapi/types';\nimport { getService } from '../../utils';\n\nconst createLocalStrategy = (strapi: Core.Strapi, middleware?: any) => {\n return new LocalStrategy(\n {\n usernameField: 'email',\n passwordField: 'password',\n session: false,\n },\n (email: string, password: string, done: any) => {\n return getService('auth')\n .checkCredentials({ email: toLower(email), password })\n .then(async ([error, user, message]) => {\n if (middleware) {\n return middleware([error, user, message], done);\n }\n\n return done(error, user, message);\n })\n .catch((error) => done(error));\n }\n );\n};\n\nexport default createLocalStrategy;\n"],"names":["createLocalStrategy","strapi","middleware","LocalStrategy","usernameField","passwordField","session","email","password","done","getService","checkCredentials","toLower","then","error","user","message","catch"],"mappings":";;;;;;AAMA,MAAMA,mBAAAA,GAAsB,CAACC,MAAAA,EAAqBC,UAAAA,GAAAA;AAChD,IAAA,OAAO,IAAIC,sBAAAA,CACT;QACEC,aAAAA,EAAe,OAAA;QACfC,aAAAA,EAAe,UAAA;QACfC,OAAAA,EAAS;KACX,EACA,CAACC,OAAeC,QAAAA,EAAkBC,IAAAA,GAAAA;QAChC,OAAOC,gBAAAA,CAAW,MAAA,CAAA,CACfC,gBAAgB,CAAC;AAAEJ,YAAAA,KAAAA,EAAOK,SAAAA,CAAQL,KAAAA,CAAAA;AAAQC,YAAAA;AAAS,SAAA,CAAA,CACnDK,IAAI,CAAC,OAAO,CAACC,KAAAA,EAAOC,MAAMC,OAAAA,CAAQ,GAAA;AACjC,YAAA,IAAId,UAAAA,EAAY;AACd,gBAAA,OAAOA,UAAAA,CAAW;AAACY,oBAAAA,KAAAA;AAAOC,oBAAAA,IAAAA;AAAMC,oBAAAA;iBAAQ,EAAEP,IAAAA,CAAAA;AAC5C,YAAA;YAEA,OAAOA,IAAAA,CAAKK,OAAOC,IAAAA,EAAMC,OAAAA,CAAAA;AAC3B,QAAA,CAAA,CAAA,CACCC,KAAK,CAAC,CAACH,KAAAA,GAAUL,IAAAA,CAAKK,KAAAA,CAAAA,CAAAA;AAC3B,IAAA,CAAA,CAAA;AAEJ;;;;"}
@@ -1,4 +1,4 @@
1
- import { toLower } from 'lodash/fp';
1
+ import { toLower } from 'lodash';
2
2
  import { Strategy } from 'passport-local';
3
3
  import { getService } from '../../utils/index.mjs';
4
4
 
@@ -1 +1 @@
1
- {"version":3,"file":"local-strategy.mjs","sources":["../../../../../../server/src/services/passport/local-strategy.ts"],"sourcesContent":["import { toLower } from 'lodash/fp';\nimport { Strategy as LocalStrategy } from 'passport-local';\nimport type { Core } from '@strapi/types';\nimport { getService } from '../../utils';\n\nconst createLocalStrategy = (strapi: Core.Strapi, middleware?: any) => {\n return new LocalStrategy(\n {\n usernameField: 'email',\n passwordField: 'password',\n session: false,\n },\n (email: string, password: string, done: any) => {\n return getService('auth')\n .checkCredentials({ email: toLower(email), password })\n .then(async ([error, user, message]) => {\n if (middleware) {\n return middleware([error, user, message], done);\n }\n\n return done(error, user, message);\n })\n .catch((error) => done(error));\n }\n );\n};\n\nexport default createLocalStrategy;\n"],"names":["createLocalStrategy","strapi","middleware","LocalStrategy","usernameField","passwordField","session","email","password","done","getService","checkCredentials","toLower","then","error","user","message","catch"],"mappings":";;;;AAKA,MAAMA,mBAAAA,GAAsB,CAACC,MAAAA,EAAqBC,UAAAA,GAAAA;AAChD,IAAA,OAAO,IAAIC,QAAAA,CACT;QACEC,aAAAA,EAAe,OAAA;QACfC,aAAAA,EAAe,UAAA;QACfC,OAAAA,EAAS;KACX,EACA,CAACC,OAAeC,QAAAA,EAAkBC,IAAAA,GAAAA;QAChC,OAAOC,UAAAA,CAAW,MAAA,CAAA,CACfC,gBAAgB,CAAC;AAAEJ,YAAAA,KAAAA,EAAOK,OAAAA,CAAQL,KAAAA,CAAAA;AAAQC,YAAAA;AAAS,SAAA,CAAA,CACnDK,IAAI,CAAC,OAAO,CAACC,KAAAA,EAAOC,MAAMC,OAAAA,CAAQ,GAAA;AACjC,YAAA,IAAId,UAAAA,EAAY;AACd,gBAAA,OAAOA,UAAAA,CAAW;AAACY,oBAAAA,KAAAA;AAAOC,oBAAAA,IAAAA;AAAMC,oBAAAA;iBAAQ,EAAEP,IAAAA,CAAAA;AAC5C,YAAA;YAEA,OAAOA,IAAAA,CAAKK,OAAOC,IAAAA,EAAMC,OAAAA,CAAAA;AAC3B,QAAA,CAAA,CAAA,CACCC,KAAK,CAAC,CAACH,KAAAA,GAAUL,IAAAA,CAAKK,KAAAA,CAAAA,CAAAA;AAC3B,IAAA,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"local-strategy.mjs","sources":["../../../../../../server/src/services/passport/local-strategy.ts"],"sourcesContent":["import { toLower } from 'lodash';\n\nimport { Strategy as LocalStrategy } from 'passport-local';\nimport type { Core } from '@strapi/types';\nimport { getService } from '../../utils';\n\nconst createLocalStrategy = (strapi: Core.Strapi, middleware?: any) => {\n return new LocalStrategy(\n {\n usernameField: 'email',\n passwordField: 'password',\n session: false,\n },\n (email: string, password: string, done: any) => {\n return getService('auth')\n .checkCredentials({ email: toLower(email), password })\n .then(async ([error, user, message]) => {\n if (middleware) {\n return middleware([error, user, message], done);\n }\n\n return done(error, user, message);\n })\n .catch((error) => done(error));\n }\n );\n};\n\nexport default createLocalStrategy;\n"],"names":["createLocalStrategy","strapi","middleware","LocalStrategy","usernameField","passwordField","session","email","password","done","getService","checkCredentials","toLower","then","error","user","message","catch"],"mappings":";;;;AAMA,MAAMA,mBAAAA,GAAsB,CAACC,MAAAA,EAAqBC,UAAAA,GAAAA;AAChD,IAAA,OAAO,IAAIC,QAAAA,CACT;QACEC,aAAAA,EAAe,OAAA;QACfC,aAAAA,EAAe,UAAA;QACfC,OAAAA,EAAS;KACX,EACA,CAACC,OAAeC,QAAAA,EAAkBC,IAAAA,GAAAA;QAChC,OAAOC,UAAAA,CAAW,MAAA,CAAA,CACfC,gBAAgB,CAAC;AAAEJ,YAAAA,KAAAA,EAAOK,OAAAA,CAAQL,KAAAA,CAAAA;AAAQC,YAAAA;AAAS,SAAA,CAAA,CACnDK,IAAI,CAAC,OAAO,CAACC,KAAAA,EAAOC,MAAMC,OAAAA,CAAQ,GAAA;AACjC,YAAA,IAAId,UAAAA,EAAY;AACd,gBAAA,OAAOA,UAAAA,CAAW;AAACY,oBAAAA,KAAAA;AAAOC,oBAAAA,IAAAA;AAAMC,oBAAAA;iBAAQ,EAAEP,IAAAA,CAAAA;AAC5C,YAAA;YAEA,OAAOA,IAAAA,CAAKK,OAAOC,IAAAA,EAAMC,OAAAA,CAAAA;AAC3B,QAAA,CAAA,CAAA,CACCC,KAAK,CAAC,CAACH,KAAAA,GAAUL,IAAAA,CAAKK,KAAAA,CAAAA,CAAAA;AAC3B,IAAA,CAAA,CAAA;AAEJ;;;;"}
@@ -1,7 +1,6 @@
1
1
  'use strict';
2
2
 
3
3
  var passport$1 = require('koa-passport');
4
- var fp = require('lodash/fp');
5
4
  var localStrategy = require('./passport/local-strategy.js');
6
5
 
7
6
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -12,7 +11,7 @@ const authEventsMapper = {
12
11
  onConnectionSuccess: 'admin.auth.success',
13
12
  onConnectionError: 'admin.auth.error'
14
13
  };
15
- const valueIsFunctionType = ([, value])=>fp.isFunction(value);
14
+ const valueIsFunctionType = ([, value])=>typeof value === 'function';
16
15
  const keyIsValidEventName = ([key])=>{
17
16
  return Object.keys(strapi.service('admin::passport').authEventsMapper).includes(key);
18
17
  };
@@ -1 +1 @@
1
- {"version":3,"file":"passport.js","sources":["../../../../../server/src/services/passport.ts"],"sourcesContent":["import passport from 'koa-passport';\nimport type { Strategy } from 'passport-local';\nimport { isFunction } from 'lodash/fp';\n\nimport createLocalStrategy from './passport/local-strategy';\n\nconst authEventsMapper = {\n onConnectionSuccess: 'admin.auth.success',\n onConnectionError: 'admin.auth.error',\n};\n\nconst valueIsFunctionType = ([, value]: [any, any]) => isFunction(value);\nconst keyIsValidEventName = ([key]: any) => {\n return Object.keys(strapi.service('admin::passport').authEventsMapper).includes(key);\n};\n\nconst getPassportStrategies = () => [createLocalStrategy(strapi)] as Strategy[];\n\nconst registerAuthEvents = () => {\n // @ts-expect-error - TODO: migrate auth service to TS\n const { events = {} } = strapi.config.get('admin.auth', {});\n const { authEventsMapper } = strapi.service('admin::passport');\n\n const eventList = Object.entries(events).filter(keyIsValidEventName).filter(valueIsFunctionType);\n\n for (const [eventName, handler] of eventList) {\n // TODO - TS: ensure the handler is an EventHub.Listener\n strapi.eventHub.on(authEventsMapper[eventName], handler as any);\n }\n};\n\nconst init = () => {\n strapi\n .service('admin::passport')\n .getPassportStrategies()\n .forEach((strategy: Strategy) => passport.use(strategy));\n\n registerAuthEvents();\n\n return passport.initialize();\n};\n\nexport default { init, getPassportStrategies, authEventsMapper };\n"],"names":["authEventsMapper","onConnectionSuccess","onConnectionError","valueIsFunctionType","value","isFunction","keyIsValidEventName","key","Object","keys","strapi","service","includes","getPassportStrategies","createLocalStrategy","registerAuthEvents","events","config","get","eventList","entries","filter","eventName","handler","eventHub","on","init","forEach","strategy","passport","use","initialize"],"mappings":";;;;;;;;;;AAMA,MAAMA,gBAAAA,GAAmB;IACvBC,mBAAAA,EAAqB,oBAAA;IACrBC,iBAAAA,EAAmB;AACrB,CAAA;AAEA,MAAMC,mBAAAA,GAAsB,CAAC,GAAGC,KAAAA,CAAkB,GAAKC,aAAAA,CAAWD,KAAAA,CAAAA;AAClE,MAAME,mBAAAA,GAAsB,CAAC,CAACC,GAAAA,CAAS,GAAA;IACrC,OAAOC,MAAAA,CAAOC,IAAI,CAACC,MAAAA,CAAOC,OAAO,CAAC,iBAAA,CAAA,CAAmBX,gBAAgB,CAAA,CAAEY,QAAQ,CAACL,GAAAA,CAAAA;AAClF,CAAA;AAEA,MAAMM,wBAAwB,IAAM;QAACC,aAAAA,CAAoBJ,MAAAA;AAAQ,KAAA;AAEjE,MAAMK,kBAAAA,GAAqB,IAAA;;AAEzB,IAAA,MAAM,EAAEC,MAAAA,GAAS,EAAE,EAAE,GAAGN,MAAAA,CAAOO,MAAM,CAACC,GAAG,CAAC,YAAA,EAAc,EAAC,CAAA;AACzD,IAAA,MAAM,EAAElB,gBAAgB,EAAE,GAAGU,MAAAA,CAAOC,OAAO,CAAC,iBAAA,CAAA;IAE5C,MAAMQ,SAAAA,GAAYX,OAAOY,OAAO,CAACJ,QAAQK,MAAM,CAACf,mBAAAA,CAAAA,CAAqBe,MAAM,CAAClB,mBAAAA,CAAAA;AAE5E,IAAA,KAAK,MAAM,CAACmB,SAAAA,EAAWC,OAAAA,CAAQ,IAAIJ,SAAAA,CAAW;;AAE5CT,QAAAA,MAAAA,CAAOc,QAAQ,CAACC,EAAE,CAACzB,gBAAgB,CAACsB,UAAU,EAAEC,OAAAA,CAAAA;AAClD,IAAA;AACF,CAAA;AAEA,MAAMG,IAAAA,GAAO,IAAA;IACXhB,MAAAA,CACGC,OAAO,CAAC,iBAAA,CAAA,CACRE,qBAAqB,EAAA,CACrBc,OAAO,CAAC,CAACC,QAAAA,GAAuBC,yBAAAA,CAASC,GAAG,CAACF,QAAAA,CAAAA,CAAAA;AAEhDb,IAAAA,kBAAAA,EAAAA;AAEA,IAAA,OAAOc,0BAASE,UAAU,EAAA;AAC5B,CAAA;AAEA,eAAe;AAAEL,IAAAA,IAAAA;AAAMb,IAAAA,qBAAAA;AAAuBb,IAAAA;AAAiB,CAAA;;;;"}
1
+ {"version":3,"file":"passport.js","sources":["../../../../../server/src/services/passport.ts"],"sourcesContent":["import passport from 'koa-passport';\nimport type { Strategy } from 'passport-local';\n\nimport createLocalStrategy from './passport/local-strategy';\n\nconst authEventsMapper = {\n onConnectionSuccess: 'admin.auth.success',\n onConnectionError: 'admin.auth.error',\n};\n\nconst valueIsFunctionType = ([, value]: [any, any]) => typeof value === 'function';\nconst keyIsValidEventName = ([key]: any) => {\n return Object.keys(strapi.service('admin::passport').authEventsMapper).includes(key);\n};\n\nconst getPassportStrategies = () => [createLocalStrategy(strapi)] as Strategy[];\n\nconst registerAuthEvents = () => {\n // @ts-expect-error - TODO: migrate auth service to TS\n const { events = {} } = strapi.config.get('admin.auth', {});\n const { authEventsMapper } = strapi.service('admin::passport');\n\n const eventList = Object.entries(events).filter(keyIsValidEventName).filter(valueIsFunctionType);\n\n for (const [eventName, handler] of eventList) {\n // TODO - TS: ensure the handler is an EventHub.Listener\n strapi.eventHub.on(authEventsMapper[eventName], handler as any);\n }\n};\n\nconst init = () => {\n strapi\n .service('admin::passport')\n .getPassportStrategies()\n .forEach((strategy: Strategy) => passport.use(strategy));\n\n registerAuthEvents();\n\n return passport.initialize();\n};\n\nexport default { init, getPassportStrategies, authEventsMapper };\n"],"names":["authEventsMapper","onConnectionSuccess","onConnectionError","valueIsFunctionType","value","keyIsValidEventName","key","Object","keys","strapi","service","includes","getPassportStrategies","createLocalStrategy","registerAuthEvents","events","config","get","eventList","entries","filter","eventName","handler","eventHub","on","init","forEach","strategy","passport","use","initialize"],"mappings":";;;;;;;;;AAKA,MAAMA,gBAAAA,GAAmB;IACvBC,mBAAAA,EAAqB,oBAAA;IACrBC,iBAAAA,EAAmB;AACrB,CAAA;AAEA,MAAMC,sBAAsB,CAAC,GAAGC,KAAAA,CAAkB,GAAK,OAAOA,KAAAA,KAAU,UAAA;AACxE,MAAMC,mBAAAA,GAAsB,CAAC,CAACC,GAAAA,CAAS,GAAA;IACrC,OAAOC,MAAAA,CAAOC,IAAI,CAACC,MAAAA,CAAOC,OAAO,CAAC,iBAAA,CAAA,CAAmBV,gBAAgB,CAAA,CAAEW,QAAQ,CAACL,GAAAA,CAAAA;AAClF,CAAA;AAEA,MAAMM,wBAAwB,IAAM;QAACC,aAAAA,CAAoBJ,MAAAA;AAAQ,KAAA;AAEjE,MAAMK,kBAAAA,GAAqB,IAAA;;AAEzB,IAAA,MAAM,EAAEC,MAAAA,GAAS,EAAE,EAAE,GAAGN,MAAAA,CAAOO,MAAM,CAACC,GAAG,CAAC,YAAA,EAAc,EAAC,CAAA;AACzD,IAAA,MAAM,EAAEjB,gBAAgB,EAAE,GAAGS,MAAAA,CAAOC,OAAO,CAAC,iBAAA,CAAA;IAE5C,MAAMQ,SAAAA,GAAYX,OAAOY,OAAO,CAACJ,QAAQK,MAAM,CAACf,mBAAAA,CAAAA,CAAqBe,MAAM,CAACjB,mBAAAA,CAAAA;AAE5E,IAAA,KAAK,MAAM,CAACkB,SAAAA,EAAWC,OAAAA,CAAQ,IAAIJ,SAAAA,CAAW;;AAE5CT,QAAAA,MAAAA,CAAOc,QAAQ,CAACC,EAAE,CAACxB,gBAAgB,CAACqB,UAAU,EAAEC,OAAAA,CAAAA;AAClD,IAAA;AACF,CAAA;AAEA,MAAMG,IAAAA,GAAO,IAAA;IACXhB,MAAAA,CACGC,OAAO,CAAC,iBAAA,CAAA,CACRE,qBAAqB,EAAA,CACrBc,OAAO,CAAC,CAACC,QAAAA,GAAuBC,yBAAAA,CAASC,GAAG,CAACF,QAAAA,CAAAA,CAAAA;AAEhDb,IAAAA,kBAAAA,EAAAA;AAEA,IAAA,OAAOc,0BAASE,UAAU,EAAA;AAC5B,CAAA;AAEA,eAAe;AAAEL,IAAAA,IAAAA;AAAMb,IAAAA,qBAAAA;AAAuBZ,IAAAA;AAAiB,CAAA;;;;"}
@@ -1,12 +1,11 @@
1
1
  import passport$1 from 'koa-passport';
2
- import { isFunction } from 'lodash/fp';
3
2
  import createLocalStrategy from './passport/local-strategy.mjs';
4
3
 
5
4
  const authEventsMapper = {
6
5
  onConnectionSuccess: 'admin.auth.success',
7
6
  onConnectionError: 'admin.auth.error'
8
7
  };
9
- const valueIsFunctionType = ([, value])=>isFunction(value);
8
+ const valueIsFunctionType = ([, value])=>typeof value === 'function';
10
9
  const keyIsValidEventName = ([key])=>{
11
10
  return Object.keys(strapi.service('admin::passport').authEventsMapper).includes(key);
12
11
  };