@strapi/admin 5.30.0 → 5.30.1

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 (342) hide show
  1. package/dist/admin/admin/src/StrapiApp.js.map +1 -1
  2. package/dist/admin/admin/src/StrapiApp.mjs.map +1 -1
  3. package/dist/admin/admin/src/components/ContentBox.js.map +1 -1
  4. package/dist/admin/admin/src/components/ContentBox.mjs.map +1 -1
  5. package/dist/admin/admin/src/components/DescriptionComponentRenderer.js.map +1 -1
  6. package/dist/admin/admin/src/components/DescriptionComponentRenderer.mjs.map +1 -1
  7. package/dist/admin/admin/src/components/Filters.js +1 -1
  8. package/dist/admin/admin/src/components/Filters.js.map +1 -1
  9. package/dist/admin/admin/src/components/Filters.mjs +1 -1
  10. package/dist/admin/admin/src/components/Filters.mjs.map +1 -1
  11. package/dist/admin/admin/src/components/Form.js +8 -3
  12. package/dist/admin/admin/src/components/Form.js.map +1 -1
  13. package/dist/admin/admin/src/components/Form.mjs +8 -3
  14. package/dist/admin/admin/src/components/Form.mjs.map +1 -1
  15. package/dist/admin/admin/src/components/FormInputs/Enumeration.js +1 -1
  16. package/dist/admin/admin/src/components/FormInputs/Enumeration.js.map +1 -1
  17. package/dist/admin/admin/src/components/FormInputs/Enumeration.mjs +1 -1
  18. package/dist/admin/admin/src/components/FormInputs/Enumeration.mjs.map +1 -1
  19. package/dist/admin/admin/src/components/FormInputs/Number.js +1 -1
  20. package/dist/admin/admin/src/components/FormInputs/Number.js.map +1 -1
  21. package/dist/admin/admin/src/components/FormInputs/Number.mjs +1 -1
  22. package/dist/admin/admin/src/components/FormInputs/Number.mjs.map +1 -1
  23. package/dist/admin/admin/src/components/FormInputs/Renderer.js.map +1 -1
  24. package/dist/admin/admin/src/components/FormInputs/Renderer.mjs.map +1 -1
  25. package/dist/admin/admin/src/components/FormInputs/Time.js.map +1 -1
  26. package/dist/admin/admin/src/components/FormInputs/Time.mjs.map +1 -1
  27. package/dist/admin/admin/src/components/GapDropZone.js.map +1 -1
  28. package/dist/admin/admin/src/components/GapDropZone.mjs.map +1 -1
  29. package/dist/admin/admin/src/components/GuidedTour/Overview.js.map +1 -1
  30. package/dist/admin/admin/src/components/GuidedTour/Overview.mjs.map +1 -1
  31. package/dist/admin/admin/src/components/GuidedTour/Steps/ContentTypeBuilderSteps.js.map +1 -1
  32. package/dist/admin/admin/src/components/GuidedTour/Steps/ContentTypeBuilderSteps.mjs.map +1 -1
  33. package/dist/admin/admin/src/components/GuidedTour/Steps/Step.js.map +1 -1
  34. package/dist/admin/admin/src/components/GuidedTour/Steps/Step.mjs.map +1 -1
  35. package/dist/admin/admin/src/components/Layouts/GridLayout.js.map +1 -1
  36. package/dist/admin/admin/src/components/Layouts/GridLayout.mjs.map +1 -1
  37. package/dist/admin/admin/src/components/Layouts/HeaderLayout.js +8 -4
  38. package/dist/admin/admin/src/components/Layouts/HeaderLayout.js.map +1 -1
  39. package/dist/admin/admin/src/components/Layouts/HeaderLayout.mjs +8 -4
  40. package/dist/admin/admin/src/components/Layouts/HeaderLayout.mjs.map +1 -1
  41. package/dist/admin/admin/src/components/NpsSurvey.js +5 -3
  42. package/dist/admin/admin/src/components/NpsSurvey.js.map +1 -1
  43. package/dist/admin/admin/src/components/NpsSurvey.mjs +5 -3
  44. package/dist/admin/admin/src/components/NpsSurvey.mjs.map +1 -1
  45. package/dist/admin/admin/src/components/PageHelpers.js.map +1 -1
  46. package/dist/admin/admin/src/components/PageHelpers.mjs.map +1 -1
  47. package/dist/admin/admin/src/components/PrivateRoute.js.map +1 -1
  48. package/dist/admin/admin/src/components/PrivateRoute.mjs.map +1 -1
  49. package/dist/admin/admin/src/components/RelativeTime.js.map +1 -1
  50. package/dist/admin/admin/src/components/RelativeTime.mjs.map +1 -1
  51. package/dist/admin/admin/src/components/ResizeIndicator.js.map +1 -1
  52. package/dist/admin/admin/src/components/ResizeIndicator.mjs.map +1 -1
  53. package/dist/admin/admin/src/components/Table.js +1 -1
  54. package/dist/admin/admin/src/components/Table.js.map +1 -1
  55. package/dist/admin/admin/src/components/Table.mjs +1 -1
  56. package/dist/admin/admin/src/components/Table.mjs.map +1 -1
  57. package/dist/admin/admin/src/components/Widgets.js.map +1 -1
  58. package/dist/admin/admin/src/components/Widgets.mjs.map +1 -1
  59. package/dist/admin/admin/src/core/apis/CustomFields.js.map +1 -1
  60. package/dist/admin/admin/src/core/apis/CustomFields.mjs.map +1 -1
  61. package/dist/admin/admin/src/core/apis/Plugin.js +0 -1
  62. package/dist/admin/admin/src/core/apis/Plugin.js.map +1 -1
  63. package/dist/admin/admin/src/core/apis/Plugin.mjs +0 -1
  64. package/dist/admin/admin/src/core/apis/Plugin.mjs.map +1 -1
  65. package/dist/admin/admin/src/core/apis/Widgets.js.map +1 -1
  66. package/dist/admin/admin/src/core/apis/Widgets.mjs.map +1 -1
  67. package/dist/admin/admin/src/core/apis/rbac.js.map +1 -1
  68. package/dist/admin/admin/src/core/apis/rbac.mjs.map +1 -1
  69. package/dist/admin/admin/src/core/apis/router.js.map +1 -1
  70. package/dist/admin/admin/src/core/apis/router.mjs.map +1 -1
  71. package/dist/admin/admin/src/features/BackButton.js.map +1 -1
  72. package/dist/admin/admin/src/features/BackButton.mjs.map +1 -1
  73. package/dist/admin/admin/src/features/Tracking.js.map +1 -1
  74. package/dist/admin/admin/src/features/Tracking.mjs.map +1 -1
  75. package/dist/admin/admin/src/features/Widgets.js.map +1 -1
  76. package/dist/admin/admin/src/features/Widgets.mjs.map +1 -1
  77. package/dist/admin/admin/src/hooks/usePersistentState.js.map +1 -1
  78. package/dist/admin/admin/src/hooks/usePersistentState.mjs.map +1 -1
  79. package/dist/admin/admin/src/hooks/useRBAC.js.map +1 -1
  80. package/dist/admin/admin/src/hooks/useRBAC.mjs.map +1 -1
  81. package/dist/admin/admin/src/pages/Auth/components/Register.js.map +1 -1
  82. package/dist/admin/admin/src/pages/Auth/components/Register.mjs.map +1 -1
  83. package/dist/admin/admin/src/pages/Home/HomePage.js.map +1 -1
  84. package/dist/admin/admin/src/pages/Home/HomePage.mjs.map +1 -1
  85. package/dist/admin/admin/src/pages/Marketplace/MarketplacePage.js +2 -2
  86. package/dist/admin/admin/src/pages/Marketplace/MarketplacePage.js.map +1 -1
  87. package/dist/admin/admin/src/pages/Marketplace/MarketplacePage.mjs +2 -2
  88. package/dist/admin/admin/src/pages/Marketplace/MarketplacePage.mjs.map +1 -1
  89. package/dist/admin/admin/src/pages/Marketplace/components/NpmPackageCard.js.map +1 -1
  90. package/dist/admin/admin/src/pages/Marketplace/components/NpmPackageCard.mjs.map +1 -1
  91. package/dist/admin/admin/src/pages/Marketplace/components/NpmPackagesFilters.js.map +1 -1
  92. package/dist/admin/admin/src/pages/Marketplace/components/NpmPackagesFilters.mjs.map +1 -1
  93. package/dist/admin/admin/src/pages/Marketplace/components/PageHeader.js.map +1 -1
  94. package/dist/admin/admin/src/pages/Marketplace/components/PageHeader.mjs.map +1 -1
  95. package/dist/admin/admin/src/pages/Marketplace/hooks/useMarketplaceData.js.map +1 -1
  96. package/dist/admin/admin/src/pages/Marketplace/hooks/useMarketplaceData.mjs.map +1 -1
  97. package/dist/admin/admin/src/pages/Settings/components/SettingsNav.js.map +1 -1
  98. package/dist/admin/admin/src/pages/Settings/components/SettingsNav.mjs.map +1 -1
  99. package/dist/admin/admin/src/pages/Settings/components/Tokens/FormHead.js +8 -1
  100. package/dist/admin/admin/src/pages/Settings/components/Tokens/FormHead.js.map +1 -1
  101. package/dist/admin/admin/src/pages/Settings/components/Tokens/FormHead.mjs +9 -2
  102. package/dist/admin/admin/src/pages/Settings/components/Tokens/FormHead.mjs.map +1 -1
  103. package/dist/admin/admin/src/pages/Settings/components/Tokens/LifeSpanInput.js.map +1 -1
  104. package/dist/admin/admin/src/pages/Settings/components/Tokens/LifeSpanInput.mjs.map +1 -1
  105. package/dist/admin/admin/src/pages/Settings/components/Tokens/Table.js.map +1 -1
  106. package/dist/admin/admin/src/pages/Settings/components/Tokens/Table.mjs.map +1 -1
  107. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/EditViewPage.js.map +1 -1
  108. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/EditViewPage.mjs.map +1 -1
  109. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/CollapsableContentType.js.map +1 -1
  110. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/CollapsableContentType.mjs.map +1 -1
  111. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/utils/transformPermissionsData.js.map +1 -1
  112. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/utils/transformPermissionsData.mjs.map +1 -1
  113. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/ListView.js +2 -0
  114. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/ListView.js.map +1 -1
  115. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/ListView.mjs +2 -0
  116. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/ListView.mjs.map +1 -1
  117. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.js.map +1 -1
  118. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.mjs.map +1 -1
  119. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/LogoInput.js.map +1 -1
  120. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/LogoInput.mjs.map +1 -1
  121. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/utils/files.js.map +1 -1
  122. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/utils/files.mjs.map +1 -1
  123. package/dist/admin/admin/src/pages/Settings/pages/InstalledPlugins.js.map +1 -1
  124. package/dist/admin/admin/src/pages/Settings/pages/InstalledPlugins.mjs.map +1 -1
  125. package/dist/admin/admin/src/pages/Settings/pages/Roles/CreatePage.js +9 -2
  126. package/dist/admin/admin/src/pages/Settings/pages/Roles/CreatePage.js.map +1 -1
  127. package/dist/admin/admin/src/pages/Settings/pages/Roles/CreatePage.mjs +9 -2
  128. package/dist/admin/admin/src/pages/Settings/pages/Roles/CreatePage.mjs.map +1 -1
  129. package/dist/admin/admin/src/pages/Settings/pages/Roles/EditPage.js +9 -2
  130. package/dist/admin/admin/src/pages/Settings/pages/Roles/EditPage.js.map +1 -1
  131. package/dist/admin/admin/src/pages/Settings/pages/Roles/EditPage.mjs +9 -2
  132. package/dist/admin/admin/src/pages/Settings/pages/Roles/EditPage.mjs.map +1 -1
  133. package/dist/admin/admin/src/pages/Settings/pages/Roles/ListPage.js.map +1 -1
  134. package/dist/admin/admin/src/pages/Settings/pages/Roles/ListPage.mjs.map +1 -1
  135. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/CollapsePropertyMatrix.js.map +1 -1
  136. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/CollapsePropertyMatrix.mjs.map +1 -1
  137. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ConditionsModal.js.map +1 -1
  138. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ConditionsModal.mjs.map +1 -1
  139. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ContentTypeCollapses.js.map +1 -1
  140. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ContentTypeCollapses.mjs.map +1 -1
  141. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/GlobalActions.js.map +1 -1
  142. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/GlobalActions.mjs.map +1 -1
  143. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.js.map +1 -1
  144. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.mjs.map +1 -1
  145. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/PluginsAndSettings.js.map +1 -1
  146. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/PluginsAndSettings.mjs.map +1 -1
  147. package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/forms.js.map +1 -1
  148. package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/forms.mjs.map +1 -1
  149. package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/permissions.js.map +1 -1
  150. package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/permissions.mjs.map +1 -1
  151. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/EditView.js.map +1 -1
  152. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/EditView.mjs.map +1 -1
  153. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/ListView.js +2 -0
  154. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/ListView.js.map +1 -1
  155. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/ListView.mjs +2 -0
  156. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/ListView.mjs.map +1 -1
  157. package/dist/admin/admin/src/pages/Settings/pages/Users/EditPage.js +9 -2
  158. package/dist/admin/admin/src/pages/Settings/pages/Users/EditPage.js.map +1 -1
  159. package/dist/admin/admin/src/pages/Settings/pages/Users/EditPage.mjs +9 -2
  160. package/dist/admin/admin/src/pages/Settings/pages/Users/EditPage.mjs.map +1 -1
  161. package/dist/admin/admin/src/pages/Settings/pages/Users/ListPage.js +3 -1
  162. package/dist/admin/admin/src/pages/Settings/pages/Users/ListPage.js.map +1 -1
  163. package/dist/admin/admin/src/pages/Settings/pages/Users/ListPage.mjs +3 -1
  164. package/dist/admin/admin/src/pages/Settings/pages/Users/ListPage.mjs.map +1 -1
  165. package/dist/admin/admin/src/pages/Settings/pages/Users/components/MagicLinkCE.js.map +1 -1
  166. package/dist/admin/admin/src/pages/Settings/pages/Users/components/MagicLinkCE.mjs.map +1 -1
  167. package/dist/admin/admin/src/pages/Settings/pages/Users/components/SelectRoles.js.map +1 -1
  168. package/dist/admin/admin/src/pages/Settings/pages/Users/components/SelectRoles.mjs.map +1 -1
  169. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/EditPage.js.map +1 -1
  170. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/EditPage.mjs.map +1 -1
  171. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/ListPage.js.map +1 -1
  172. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/ListPage.mjs.map +1 -1
  173. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/HeadersInput.js.map +1 -1
  174. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/HeadersInput.mjs.map +1 -1
  175. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/WebhookForm.js +9 -2
  176. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/WebhookForm.js.map +1 -1
  177. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/WebhookForm.mjs +9 -2
  178. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/WebhookForm.mjs.map +1 -1
  179. package/dist/admin/admin/src/pages/UseCasePage.js.map +1 -1
  180. package/dist/admin/admin/src/pages/UseCasePage.mjs.map +1 -1
  181. package/dist/admin/admin/src/services/api.js +2 -1
  182. package/dist/admin/admin/src/services/api.js.map +1 -1
  183. package/dist/admin/admin/src/services/api.mjs +2 -1
  184. package/dist/admin/admin/src/services/api.mjs.map +1 -1
  185. package/dist/admin/admin/src/services/apiTokens.js.map +1 -1
  186. package/dist/admin/admin/src/services/apiTokens.mjs.map +1 -1
  187. package/dist/admin/admin/src/services/transferTokens.js.map +1 -1
  188. package/dist/admin/admin/src/services/transferTokens.mjs.map +1 -1
  189. package/dist/admin/admin/src/services/users.js.map +1 -1
  190. package/dist/admin/admin/src/services/users.mjs.map +1 -1
  191. package/dist/admin/admin/src/services/webhooks.js.map +1 -1
  192. package/dist/admin/admin/src/services/webhooks.mjs.map +1 -1
  193. package/dist/admin/admin/src/utils/cookies.js.map +1 -1
  194. package/dist/admin/admin/src/utils/cookies.mjs.map +1 -1
  195. package/dist/admin/admin/src/utils/getFetchClient.js.map +1 -1
  196. package/dist/admin/admin/src/utils/getFetchClient.mjs.map +1 -1
  197. package/dist/admin/admin/src/utils/getPrefixedId.js.map +1 -1
  198. package/dist/admin/admin/src/utils/getPrefixedId.mjs.map +1 -1
  199. package/dist/admin/admin/src/utils/rulesEngine.js.map +1 -1
  200. package/dist/admin/admin/src/utils/rulesEngine.mjs.map +1 -1
  201. package/dist/admin/admin/src/utils/urls.js.map +1 -1
  202. package/dist/admin/admin/src/utils/urls.mjs.map +1 -1
  203. package/dist/admin/admin/src/utils/users.js.map +1 -1
  204. package/dist/admin/admin/src/utils/users.mjs.map +1 -1
  205. package/dist/admin/ee/admin/src/components/AuditLogs/Widgets.js.map +1 -1
  206. package/dist/admin/ee/admin/src/components/AuditLogs/Widgets.mjs.map +1 -1
  207. package/dist/admin/ee/admin/src/hooks/useLicenseLimitNotification.js.map +1 -1
  208. package/dist/admin/ee/admin/src/hooks/useLicenseLimitNotification.mjs.map +1 -1
  209. package/dist/admin/ee/admin/src/pages/AuthPage/components/SSOProviders.js.map +1 -1
  210. package/dist/admin/ee/admin/src/pages/AuthPage/components/SSOProviders.mjs.map +1 -1
  211. package/dist/admin/ee/admin/src/pages/AuthResponse.js.map +1 -1
  212. package/dist/admin/ee/admin/src/pages/AuthResponse.mjs.map +1 -1
  213. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.js.map +1 -1
  214. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.mjs.map +1 -1
  215. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.js +3 -3
  216. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.js.map +1 -1
  217. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.mjs +3 -3
  218. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.mjs.map +1 -1
  219. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/Modal.js.map +1 -1
  220. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/Modal.mjs.map +1 -1
  221. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useFormatTimeStamp.js.map +1 -1
  222. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useFormatTimeStamp.mjs.map +1 -1
  223. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.js.map +1 -1
  224. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.mjs.map +1 -1
  225. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/Users/components/MagicLinkEE.js.map +1 -1
  226. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/Users/components/MagicLinkEE.mjs.map +1 -1
  227. package/dist/admin/ee/admin/src/services/ai.js +14 -1
  228. package/dist/admin/ee/admin/src/services/ai.js.map +1 -1
  229. package/dist/admin/ee/admin/src/services/ai.mjs +14 -2
  230. package/dist/admin/ee/admin/src/services/ai.mjs.map +1 -1
  231. package/dist/admin/ee/admin/src/services/auditLogs.js.map +1 -1
  232. package/dist/admin/ee/admin/src/services/auditLogs.mjs.map +1 -1
  233. package/dist/admin/ee.js +1 -0
  234. package/dist/admin/ee.js.map +1 -1
  235. package/dist/admin/ee.mjs +1 -1
  236. package/dist/admin/src/components/Form.d.ts +1 -1
  237. package/dist/admin/src/core/store/configure.d.ts +2 -2
  238. package/dist/admin/src/core/store/hooks.d.ts +2 -2
  239. package/dist/admin/src/ee.d.ts +1 -1
  240. package/dist/admin/src/hooks/useAdminRoles.d.ts +1 -1
  241. package/dist/admin/src/pages/Settings/pages/Webhooks/hooks/useWebhooks.d.ts +4 -4
  242. package/dist/admin/src/selectors.d.ts +2 -2
  243. package/dist/admin/src/services/admin.d.ts +6 -6
  244. package/dist/admin/src/services/api.d.ts +1 -1
  245. package/dist/admin/src/services/apiTokens.d.ts +1 -1
  246. package/dist/admin/src/services/auth.d.ts +13 -13
  247. package/dist/admin/src/services/contentApi.d.ts +1 -1
  248. package/dist/admin/src/services/contentManager.d.ts +1 -1
  249. package/dist/admin/src/services/homepage.d.ts +3 -3
  250. package/dist/admin/src/services/transferTokens.d.ts +1 -1
  251. package/dist/admin/src/services/users.d.ts +8 -8
  252. package/dist/admin/src/services/webhooks.d.ts +2 -2
  253. package/dist/admin/tests/utils.d.ts +1 -1
  254. package/dist/ee/admin/src/services/ai.d.ts +6 -3
  255. package/dist/ee/admin/src/services/auditLogs.d.ts +1 -1
  256. package/dist/ee/server/src/ai/containers/ai.d.ts +11 -0
  257. package/dist/ee/server/src/ai/containers/ai.d.ts.map +1 -0
  258. package/dist/ee/server/src/ai/controllers/ai.d.ts +1 -0
  259. package/dist/ee/server/src/ai/controllers/ai.d.ts.map +1 -1
  260. package/dist/ee/server/src/ai/routes/ai.d.ts.map +1 -1
  261. package/dist/ee/server/src/index.d.ts +1 -0
  262. package/dist/ee/server/src/index.d.ts.map +1 -1
  263. package/dist/server/ee/server/src/ai/containers/ai.js +18 -0
  264. package/dist/server/ee/server/src/ai/containers/ai.js.map +1 -0
  265. package/dist/server/ee/server/src/ai/containers/ai.mjs +16 -0
  266. package/dist/server/ee/server/src/ai/containers/ai.mjs.map +1 -0
  267. package/dist/server/ee/server/src/ai/controllers/ai.js +6 -0
  268. package/dist/server/ee/server/src/ai/controllers/ai.js.map +1 -1
  269. package/dist/server/ee/server/src/ai/controllers/ai.mjs +6 -0
  270. package/dist/server/ee/server/src/ai/controllers/ai.mjs.map +1 -1
  271. package/dist/server/ee/server/src/ai/routes/ai.js +11 -0
  272. package/dist/server/ee/server/src/ai/routes/ai.js.map +1 -1
  273. package/dist/server/ee/server/src/ai/routes/ai.mjs +11 -0
  274. package/dist/server/ee/server/src/ai/routes/ai.mjs.map +1 -1
  275. package/dist/server/ee/server/src/audit-logs/services/audit-logs.js.map +1 -1
  276. package/dist/server/ee/server/src/audit-logs/services/audit-logs.mjs.map +1 -1
  277. package/dist/server/ee/server/src/controllers/authentication-utils/constants.js.map +1 -1
  278. package/dist/server/ee/server/src/controllers/authentication-utils/constants.mjs.map +1 -1
  279. package/dist/server/ee/server/src/controllers/authentication-utils/utils.js.map +1 -1
  280. package/dist/server/ee/server/src/controllers/authentication-utils/utils.mjs.map +1 -1
  281. package/dist/server/ee/server/src/controllers/authentication.js.map +1 -1
  282. package/dist/server/ee/server/src/controllers/authentication.mjs.map +1 -1
  283. package/dist/server/ee/server/src/controllers/user.js.map +1 -1
  284. package/dist/server/ee/server/src/controllers/user.mjs.map +1 -1
  285. package/dist/server/ee/server/src/index.js +7 -0
  286. package/dist/server/ee/server/src/index.js.map +1 -1
  287. package/dist/server/ee/server/src/index.mjs +7 -0
  288. package/dist/server/ee/server/src/index.mjs.map +1 -1
  289. package/dist/server/ee/server/src/services/auth.js.map +1 -1
  290. package/dist/server/ee/server/src/services/auth.mjs.map +1 -1
  291. package/dist/server/ee/server/src/services/passport/sso.js.map +1 -1
  292. package/dist/server/ee/server/src/services/passport/sso.mjs.map +1 -1
  293. package/dist/server/ee/server/src/utils/index.js.map +1 -1
  294. package/dist/server/ee/server/src/utils/index.mjs.map +1 -1
  295. package/dist/server/server/src/controllers/transfer/index.js.map +1 -1
  296. package/dist/server/server/src/controllers/transfer/index.mjs.map +1 -1
  297. package/dist/server/server/src/controllers/user.js +10 -0
  298. package/dist/server/server/src/controllers/user.js.map +1 -1
  299. package/dist/server/server/src/controllers/user.mjs +10 -0
  300. package/dist/server/server/src/controllers/user.mjs.map +1 -1
  301. package/dist/server/server/src/domain/action/index.js.map +1 -1
  302. package/dist/server/server/src/domain/action/index.mjs.map +1 -1
  303. package/dist/server/server/src/domain/condition/index.js.map +1 -1
  304. package/dist/server/server/src/domain/condition/index.mjs.map +1 -1
  305. package/dist/server/server/src/domain/permission/index.js.map +1 -1
  306. package/dist/server/server/src/domain/permission/index.mjs.map +1 -1
  307. package/dist/server/server/src/middlewares/rateLimit.js.map +1 -1
  308. package/dist/server/server/src/middlewares/rateLimit.mjs.map +1 -1
  309. package/dist/server/server/src/routes/serve-admin-panel.js.map +1 -1
  310. package/dist/server/server/src/routes/serve-admin-panel.mjs.map +1 -1
  311. package/dist/server/server/src/services/api-token.js.map +1 -1
  312. package/dist/server/server/src/services/api-token.mjs.map +1 -1
  313. package/dist/server/server/src/services/auth.js.map +1 -1
  314. package/dist/server/server/src/services/auth.mjs.map +1 -1
  315. package/dist/server/server/src/services/content-type.js.map +1 -1
  316. package/dist/server/server/src/services/content-type.mjs.map +1 -1
  317. package/dist/server/server/src/services/encryption.js.map +1 -1
  318. package/dist/server/server/src/services/encryption.mjs.map +1 -1
  319. package/dist/server/server/src/services/homepage.js.map +1 -1
  320. package/dist/server/server/src/services/homepage.mjs.map +1 -1
  321. package/dist/server/server/src/services/permission/permissions-manager/sanitize.js.map +1 -1
  322. package/dist/server/server/src/services/permission/permissions-manager/sanitize.mjs.map +1 -1
  323. package/dist/server/server/src/services/permission/permissions-manager/validate.js.map +1 -1
  324. package/dist/server/server/src/services/permission/permissions-manager/validate.mjs.map +1 -1
  325. package/dist/server/server/src/services/role.js.map +1 -1
  326. package/dist/server/server/src/services/role.mjs.map +1 -1
  327. package/dist/server/server/src/services/transfer/token.js.map +1 -1
  328. package/dist/server/server/src/services/transfer/token.mjs.map +1 -1
  329. package/dist/server/server/src/services/user.js.map +1 -1
  330. package/dist/server/server/src/services/user.mjs.map +1 -1
  331. package/dist/server/server/src/utils/index.js.map +1 -1
  332. package/dist/server/server/src/utils/index.mjs.map +1 -1
  333. package/dist/server/server/src/validation/action-provider.js.map +1 -1
  334. package/dist/server/server/src/validation/action-provider.mjs.map +1 -1
  335. package/dist/server/server/src/validation/common-functions/check-fields-are-correctly-nested.js.map +1 -1
  336. package/dist/server/server/src/validation/common-functions/check-fields-are-correctly-nested.mjs.map +1 -1
  337. package/dist/server/server/src/validation/common-validators.js.map +1 -1
  338. package/dist/server/server/src/validation/common-validators.mjs.map +1 -1
  339. package/dist/server/src/controllers/user.d.ts.map +1 -1
  340. package/dist/shared/contracts/ai.d.ts +16 -0
  341. package/dist/shared/contracts/ai.d.ts.map +1 -1
  342. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../../../server/src/domain/condition/index.ts"],"sourcesContent":["import { pipe, merge, set, pick } from 'lodash/fp';\n\nexport type Condition = {\n id: string;\n displayName: string;\n name: string;\n plugin?: string;\n category?: string;\n /**\n * The handler of a {@link Condition}\n */\n handler: (user: object, options: object) => object | boolean;\n};\n\n/**\n * Set of attributes used to create a new {@link Action} object\n */\nexport type CreateConditionPayload = Omit<Condition, 'id'>;\n\nconst DEFAULT_CATEGORY = 'default';\n\n/**\n * Get the default value used for every condition\n * @return {Condition}\n */\nexport const getDefaultConditionAttributes = () => ({\n category: DEFAULT_CATEGORY,\n});\n\n/**\n * Get the list of all the valid attributes of a {@link Condition}\n * @return {string[]}\n */\nexport const conditionFields = ['id', 'displayName', 'handler', 'plugin', 'category'] as const;\n\n/**\n * Remove unwanted attributes from a {@link Condition}\n */\nexport const sanitizeConditionAttributes = pick(conditionFields);\n\nexport const computeConditionId = (condition: CreateConditionPayload) => {\n const { name, plugin } = condition;\n\n if (!plugin) {\n return `api::${name}`;\n }\n\n if (plugin === 'admin') {\n return `admin::${name}`;\n }\n\n return `plugin::${plugin}.${name}`;\n};\n\n/**\n * Assign an id attribute to a {@link CreateConditionPayload} object\n * @param attrs - Payload used to create a condition\n */\nexport const assignConditionId = (attrs: CreateConditionPayload): Condition => {\n const condition = set('id', computeConditionId(attrs), attrs) as CreateConditionPayload & {\n id: string;\n };\n return condition;\n};\n\n/**\n * Transform the given attributes into a domain representation of a Condition\n * @param payload - The condition payload containing the attributes needed to create a {@link Condition}\n */\nexport const create = pipe(\n assignConditionId,\n sanitizeConditionAttributes,\n merge(getDefaultConditionAttributes())\n) as (payload: CreateConditionPayload) => Condition;\n\nexport default {\n assignConditionId,\n computeConditionId,\n conditionFields,\n create,\n getDefaultConditionAttributes,\n sanitizeConditionAttributes,\n};\n"],"names":["DEFAULT_CATEGORY","getDefaultConditionAttributes","category","conditionFields","sanitizeConditionAttributes","pick","computeConditionId","condition","name","plugin","assignConditionId","attrs","set","create","pipe","merge"],"mappings":";;;;;;AAmBA,MAAMA,gBAAmB,GAAA,SAAA;AAEzB;;;AAGC,IACM,MAAMC,6BAAgC,GAAA,KAAO;QAClDC,QAAUF,EAAAA;AACZ,KAAA;AAEA;;;UAIaG,eAAkB,GAAA;AAAC,IAAA,IAAA;AAAM,IAAA,aAAA;AAAe,IAAA,SAAA;AAAW,IAAA,QAAA;AAAU,IAAA;;AAE1E;;AAEC,IACM,MAAMC,2BAA8BC,GAAAA,OAAAA,CAAKF,eAAiB;AAE1D,MAAMG,qBAAqB,CAACC,SAAAA,GAAAA;AACjC,IAAA,MAAM,EAAEC,IAAI,EAAEC,MAAM,EAAE,GAAGF,SAAAA;AAEzB,IAAA,IAAI,CAACE,MAAQ,EAAA;AACX,QAAA,OAAO,CAAC,KAAK,EAAED,IAAAA,CAAK,CAAC;AACvB;AAEA,IAAA,IAAIC,WAAW,OAAS,EAAA;AACtB,QAAA,OAAO,CAAC,OAAO,EAAED,IAAAA,CAAK,CAAC;AACzB;AAEA,IAAA,OAAO,CAAC,QAAQ,EAAEC,OAAO,CAAC,EAAED,KAAK,CAAC;AACpC;AAEA;;;IAIaE,MAAAA,iBAAAA,GAAoB,CAACC,KAAAA,GAAAA;AAChC,IAAA,MAAMJ,SAAYK,GAAAA,MAAAA,CAAI,IAAMN,EAAAA,kBAAAA,CAAmBK,KAAQA,CAAAA,EAAAA,KAAAA,CAAAA;IAGvD,OAAOJ,SAAAA;AACT;AAEA;;;AAGC,IACYM,MAAAA,MAAAA,GAASC,QACpBJ,iBACAN,EAAAA,2BAAAA,EACAW,SAAMd,6BAC4C,EAAA,CAAA;AAEpD,aAAe;AACbS,IAAAA,iBAAAA;AACAJ,IAAAA,kBAAAA;AACAH,IAAAA,eAAAA;AACAU,IAAAA,MAAAA;AACAZ,IAAAA,6BAAAA;AACAG,IAAAA;AACF,CAAE;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../../../../server/src/domain/condition/index.ts"],"sourcesContent":["import { pipe, merge, set, pick } from 'lodash/fp';\n\nexport type Condition = {\n id: string;\n displayName: string;\n name: string;\n plugin?: string;\n category?: string;\n /**\n * The handler of a {@link Condition}\n */\n handler: (user: object, options: object) => object | boolean;\n};\n\n/**\n * Set of attributes used to create a new {@link Action} object\n */\nexport type CreateConditionPayload = Omit<Condition, 'id'>;\n\nconst DEFAULT_CATEGORY = 'default';\n\n/**\n * Get the default value used for every condition\n * @return {Condition}\n */\nexport const getDefaultConditionAttributes = () => ({\n category: DEFAULT_CATEGORY,\n});\n\n/**\n * Get the list of all the valid attributes of a {@link Condition}\n * @return {string[]}\n */\nexport const conditionFields = ['id', 'displayName', 'handler', 'plugin', 'category'] as const;\n\n/**\n * Remove unwanted attributes from a {@link Condition}\n */\nexport const sanitizeConditionAttributes = pick(conditionFields);\n\nexport const computeConditionId = (condition: CreateConditionPayload) => {\n const { name, plugin } = condition;\n\n if (!plugin) {\n return `api::${name}`;\n }\n\n if (plugin === 'admin') {\n return `admin::${name}`;\n }\n\n return `plugin::${plugin}.${name}`;\n};\n\n/**\n * Assign an id attribute to a {@link CreateConditionPayload} object\n * @param attrs - Payload used to create a condition\n */\nexport const assignConditionId = (attrs: CreateConditionPayload): Condition => {\n const condition = set('id', computeConditionId(attrs), attrs) as CreateConditionPayload & {\n id: string;\n };\n return condition;\n};\n\n/**\n * Transform the given attributes into a domain representation of a Condition\n * @param payload - The condition payload containing the attributes needed to create a {@link Condition}\n */\nexport const create = pipe(\n assignConditionId,\n sanitizeConditionAttributes,\n merge(getDefaultConditionAttributes())\n) as (payload: CreateConditionPayload) => Condition;\n\nexport default {\n assignConditionId,\n computeConditionId,\n conditionFields,\n create,\n getDefaultConditionAttributes,\n sanitizeConditionAttributes,\n};\n"],"names":["DEFAULT_CATEGORY","getDefaultConditionAttributes","category","conditionFields","sanitizeConditionAttributes","pick","computeConditionId","condition","name","plugin","assignConditionId","attrs","set","create","pipe","merge"],"mappings":";;;;;;AAmBA,MAAMA,gBAAmB,GAAA,SAAA;AAEzB;;;AAGC,IACM,MAAMC,6BAAgC,GAAA,KAAO;QAClDC,QAAUF,EAAAA;AACZ,KAAA;AAEA;;;UAIaG,eAAkB,GAAA;AAAC,IAAA,IAAA;AAAM,IAAA,aAAA;AAAe,IAAA,SAAA;AAAW,IAAA,QAAA;AAAU,IAAA;;AAE1E;;AAEC,IACM,MAAMC,2BAA8BC,GAAAA,OAAAA,CAAKF,eAAiB;AAE1D,MAAMG,qBAAqB,CAACC,SAAAA,GAAAA;AACjC,IAAA,MAAM,EAAEC,IAAI,EAAEC,MAAM,EAAE,GAAGF,SAAAA;AAEzB,IAAA,IAAI,CAACE,MAAQ,EAAA;QACX,OAAO,CAAC,KAAK,EAAED,IAAM,CAAA,CAAA;AACvB;AAEA,IAAA,IAAIC,WAAW,OAAS,EAAA;QACtB,OAAO,CAAC,OAAO,EAAED,IAAM,CAAA,CAAA;AACzB;AAEA,IAAA,OAAO,CAAC,QAAQ,EAAEC,MAAO,CAAA,CAAC,EAAED,IAAM,CAAA,CAAA;AACpC;AAEA;;;IAIaE,MAAAA,iBAAAA,GAAoB,CAACC,KAAAA,GAAAA;AAChC,IAAA,MAAMJ,SAAYK,GAAAA,MAAAA,CAAI,IAAMN,EAAAA,kBAAAA,CAAmBK,KAAQA,CAAAA,EAAAA,KAAAA,CAAAA;IAGvD,OAAOJ,SAAAA;AACT;AAEA;;;AAGC,IACYM,MAAAA,MAAAA,GAASC,QACpBJ,iBACAN,EAAAA,2BAAAA,EACAW,SAAMd,6BAC4C,EAAA,CAAA;AAEpD,aAAe;AACbS,IAAAA,iBAAAA;AACAJ,IAAAA,kBAAAA;AACAH,IAAAA,eAAAA;AACAU,IAAAA,MAAAA;AACAZ,IAAAA,6BAAAA;AACAG,IAAAA;AACF,CAAE;;;;;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../../../../../server/src/domain/condition/index.ts"],"sourcesContent":["import { pipe, merge, set, pick } from 'lodash/fp';\n\nexport type Condition = {\n id: string;\n displayName: string;\n name: string;\n plugin?: string;\n category?: string;\n /**\n * The handler of a {@link Condition}\n */\n handler: (user: object, options: object) => object | boolean;\n};\n\n/**\n * Set of attributes used to create a new {@link Action} object\n */\nexport type CreateConditionPayload = Omit<Condition, 'id'>;\n\nconst DEFAULT_CATEGORY = 'default';\n\n/**\n * Get the default value used for every condition\n * @return {Condition}\n */\nexport const getDefaultConditionAttributes = () => ({\n category: DEFAULT_CATEGORY,\n});\n\n/**\n * Get the list of all the valid attributes of a {@link Condition}\n * @return {string[]}\n */\nexport const conditionFields = ['id', 'displayName', 'handler', 'plugin', 'category'] as const;\n\n/**\n * Remove unwanted attributes from a {@link Condition}\n */\nexport const sanitizeConditionAttributes = pick(conditionFields);\n\nexport const computeConditionId = (condition: CreateConditionPayload) => {\n const { name, plugin } = condition;\n\n if (!plugin) {\n return `api::${name}`;\n }\n\n if (plugin === 'admin') {\n return `admin::${name}`;\n }\n\n return `plugin::${plugin}.${name}`;\n};\n\n/**\n * Assign an id attribute to a {@link CreateConditionPayload} object\n * @param attrs - Payload used to create a condition\n */\nexport const assignConditionId = (attrs: CreateConditionPayload): Condition => {\n const condition = set('id', computeConditionId(attrs), attrs) as CreateConditionPayload & {\n id: string;\n };\n return condition;\n};\n\n/**\n * Transform the given attributes into a domain representation of a Condition\n * @param payload - The condition payload containing the attributes needed to create a {@link Condition}\n */\nexport const create = pipe(\n assignConditionId,\n sanitizeConditionAttributes,\n merge(getDefaultConditionAttributes())\n) as (payload: CreateConditionPayload) => Condition;\n\nexport default {\n assignConditionId,\n computeConditionId,\n conditionFields,\n create,\n getDefaultConditionAttributes,\n sanitizeConditionAttributes,\n};\n"],"names":["DEFAULT_CATEGORY","getDefaultConditionAttributes","category","conditionFields","sanitizeConditionAttributes","pick","computeConditionId","condition","name","plugin","assignConditionId","attrs","set","create","pipe","merge"],"mappings":";;AAmBA,MAAMA,gBAAmB,GAAA,SAAA;AAEzB;;;AAGC,IACM,MAAMC,6BAAgC,GAAA,KAAO;QAClDC,QAAUF,EAAAA;AACZ,KAAA;AAEA;;;UAIaG,eAAkB,GAAA;AAAC,IAAA,IAAA;AAAM,IAAA,aAAA;AAAe,IAAA,SAAA;AAAW,IAAA,QAAA;AAAU,IAAA;;AAE1E;;AAEC,IACM,MAAMC,2BAA8BC,GAAAA,IAAAA,CAAKF,eAAiB;AAE1D,MAAMG,qBAAqB,CAACC,SAAAA,GAAAA;AACjC,IAAA,MAAM,EAAEC,IAAI,EAAEC,MAAM,EAAE,GAAGF,SAAAA;AAEzB,IAAA,IAAI,CAACE,MAAQ,EAAA;AACX,QAAA,OAAO,CAAC,KAAK,EAAED,IAAAA,CAAK,CAAC;AACvB;AAEA,IAAA,IAAIC,WAAW,OAAS,EAAA;AACtB,QAAA,OAAO,CAAC,OAAO,EAAED,IAAAA,CAAK,CAAC;AACzB;AAEA,IAAA,OAAO,CAAC,QAAQ,EAAEC,OAAO,CAAC,EAAED,KAAK,CAAC;AACpC;AAEA;;;IAIaE,MAAAA,iBAAAA,GAAoB,CAACC,KAAAA,GAAAA;AAChC,IAAA,MAAMJ,SAAYK,GAAAA,GAAAA,CAAI,IAAMN,EAAAA,kBAAAA,CAAmBK,KAAQA,CAAAA,EAAAA,KAAAA,CAAAA;IAGvD,OAAOJ,SAAAA;AACT;AAEA;;;AAGC,IACYM,MAAAA,MAAAA,GAASC,KACpBJ,iBACAN,EAAAA,2BAAAA,EACAW,MAAMd,6BAC4C,EAAA,CAAA;AAEpD,aAAe;AACbS,IAAAA,iBAAAA;AACAJ,IAAAA,kBAAAA;AACAH,IAAAA,eAAAA;AACAU,IAAAA,MAAAA;AACAZ,IAAAA,6BAAAA;AACAG,IAAAA;AACF,CAAE;;;;"}
1
+ {"version":3,"file":"index.mjs","sources":["../../../../../../server/src/domain/condition/index.ts"],"sourcesContent":["import { pipe, merge, set, pick } from 'lodash/fp';\n\nexport type Condition = {\n id: string;\n displayName: string;\n name: string;\n plugin?: string;\n category?: string;\n /**\n * The handler of a {@link Condition}\n */\n handler: (user: object, options: object) => object | boolean;\n};\n\n/**\n * Set of attributes used to create a new {@link Action} object\n */\nexport type CreateConditionPayload = Omit<Condition, 'id'>;\n\nconst DEFAULT_CATEGORY = 'default';\n\n/**\n * Get the default value used for every condition\n * @return {Condition}\n */\nexport const getDefaultConditionAttributes = () => ({\n category: DEFAULT_CATEGORY,\n});\n\n/**\n * Get the list of all the valid attributes of a {@link Condition}\n * @return {string[]}\n */\nexport const conditionFields = ['id', 'displayName', 'handler', 'plugin', 'category'] as const;\n\n/**\n * Remove unwanted attributes from a {@link Condition}\n */\nexport const sanitizeConditionAttributes = pick(conditionFields);\n\nexport const computeConditionId = (condition: CreateConditionPayload) => {\n const { name, plugin } = condition;\n\n if (!plugin) {\n return `api::${name}`;\n }\n\n if (plugin === 'admin') {\n return `admin::${name}`;\n }\n\n return `plugin::${plugin}.${name}`;\n};\n\n/**\n * Assign an id attribute to a {@link CreateConditionPayload} object\n * @param attrs - Payload used to create a condition\n */\nexport const assignConditionId = (attrs: CreateConditionPayload): Condition => {\n const condition = set('id', computeConditionId(attrs), attrs) as CreateConditionPayload & {\n id: string;\n };\n return condition;\n};\n\n/**\n * Transform the given attributes into a domain representation of a Condition\n * @param payload - The condition payload containing the attributes needed to create a {@link Condition}\n */\nexport const create = pipe(\n assignConditionId,\n sanitizeConditionAttributes,\n merge(getDefaultConditionAttributes())\n) as (payload: CreateConditionPayload) => Condition;\n\nexport default {\n assignConditionId,\n computeConditionId,\n conditionFields,\n create,\n getDefaultConditionAttributes,\n sanitizeConditionAttributes,\n};\n"],"names":["DEFAULT_CATEGORY","getDefaultConditionAttributes","category","conditionFields","sanitizeConditionAttributes","pick","computeConditionId","condition","name","plugin","assignConditionId","attrs","set","create","pipe","merge"],"mappings":";;AAmBA,MAAMA,gBAAmB,GAAA,SAAA;AAEzB;;;AAGC,IACM,MAAMC,6BAAgC,GAAA,KAAO;QAClDC,QAAUF,EAAAA;AACZ,KAAA;AAEA;;;UAIaG,eAAkB,GAAA;AAAC,IAAA,IAAA;AAAM,IAAA,aAAA;AAAe,IAAA,SAAA;AAAW,IAAA,QAAA;AAAU,IAAA;;AAE1E;;AAEC,IACM,MAAMC,2BAA8BC,GAAAA,IAAAA,CAAKF,eAAiB;AAE1D,MAAMG,qBAAqB,CAACC,SAAAA,GAAAA;AACjC,IAAA,MAAM,EAAEC,IAAI,EAAEC,MAAM,EAAE,GAAGF,SAAAA;AAEzB,IAAA,IAAI,CAACE,MAAQ,EAAA;QACX,OAAO,CAAC,KAAK,EAAED,IAAM,CAAA,CAAA;AACvB;AAEA,IAAA,IAAIC,WAAW,OAAS,EAAA;QACtB,OAAO,CAAC,OAAO,EAAED,IAAM,CAAA,CAAA;AACzB;AAEA,IAAA,OAAO,CAAC,QAAQ,EAAEC,MAAO,CAAA,CAAC,EAAED,IAAM,CAAA,CAAA;AACpC;AAEA;;;IAIaE,MAAAA,iBAAAA,GAAoB,CAACC,KAAAA,GAAAA;AAChC,IAAA,MAAMJ,SAAYK,GAAAA,GAAAA,CAAI,IAAMN,EAAAA,kBAAAA,CAAmBK,KAAQA,CAAAA,EAAAA,KAAAA,CAAAA;IAGvD,OAAOJ,SAAAA;AACT;AAEA;;;AAGC,IACYM,MAAAA,MAAAA,GAASC,KACpBJ,iBACAN,EAAAA,2BAAAA,EACAW,MAAMd,6BAC4C,EAAA,CAAA;AAEpD,aAAe;AACbS,IAAAA,iBAAAA;AACAJ,IAAAA,kBAAAA;AACAH,IAAAA,eAAAA;AACAU,IAAAA,MAAAA;AACAZ,IAAAA,6BAAAA;AACAG,IAAAA;AACF,CAAE;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../../../server/src/domain/permission/index.ts"],"sourcesContent":["import type { Utils } from '@strapi/types';\n\nimport { providerFactory } from '@strapi/utils';\nimport {\n pipe,\n set,\n pick,\n eq,\n omit,\n remove,\n get,\n uniq,\n isArray,\n map,\n curry,\n merge,\n} from 'lodash/fp';\nimport { Permission } from '../../../../shared/contracts/shared';\nimport { SanitizedPermission } from '../../../../shared/contracts/roles';\n\nexport type CreatePermissionPayload = Utils.Object.PartialBy<\n Permission,\n 'actionParameters' | 'conditions' | 'properties' | 'subject' | 'id' | 'createdAt' | 'updatedAt'\n>;\n\ntype Provider = ReturnType<typeof providerFactory>;\n\nexport const permissionFields = [\n 'id',\n 'action',\n 'actionParameters',\n 'subject',\n 'properties',\n 'conditions',\n 'role',\n];\nexport const sanitizedPermissionFields = [\n 'id',\n 'action',\n 'actionParameters',\n 'subject',\n 'properties',\n 'conditions',\n] as const;\n\nexport const sanitizePermissionFields: (p: Permission) => SanitizedPermission =\n pick(sanitizedPermissionFields);\n\n/**\n * Creates a permission with default values\n */\nconst getDefaultPermission = () => ({\n actionParameters: {},\n conditions: [],\n properties: {},\n subject: null,\n});\n\n/**\n * Returns a new permission with the given condition\n * @param condition - The condition to add\n * @param permission - The permission on which we want to add the condition\n * @return\n */\nexport const addCondition = curry((condition: string, permission: Permission): Permission => {\n const { conditions } = permission;\n const newConditions = Array.isArray(conditions)\n ? uniq(conditions.concat(condition))\n : [condition];\n\n return set('conditions', newConditions, permission);\n});\n\n/**\n * Returns a new permission without the given condition\n * @param condition - The condition to remove\n * @param permission - The permission on which we want to remove the condition\n */\nexport const removeCondition = curry((condition: string, permission: Permission): Permission => {\n return set('conditions', remove(eq(condition), permission.conditions), permission);\n});\n\n/**\n * Gets a property or a part of a property from a permission.\n * @param property - The property to get\n * @param permission - The permission on which we want to access the property\n */\nexport const getProperty = curry(\n (property: string, permission: Permission): Permission =>\n get(`properties.${property}`, permission)\n);\n\n/**\n * Set a value for a given property on a new permission object\n * @param property - The name of the property\n * @param value - The value of the property\n * @param permission - The permission on which we want to set the property\n */\nexport const setProperty = (\n property: string,\n value: unknown,\n permission: Permission\n): Permission => {\n return set(`properties.${property}`, value, permission);\n};\n\n/**\n * Returns a new permission without the given property name set\n * @param property - The name of the property to delete\n * @param permission - The permission on which we want to remove the property\n */\nexport const deleteProperty = <TProperty extends string>(\n property: TProperty,\n permission: Permission\n) => omit(`properties.${property}`, permission) as Omit<Permission, TProperty>;\n\n/**\n * Creates a new {@link Permission} object from raw attributes. Set default values for certain fields\n * @param attributes\n */\nexport const create = (attributes: CreatePermissionPayload) => {\n return pipe(pick(permissionFields), merge(getDefaultPermission()))(attributes) as Permission;\n};\n\n/**\n * Using the given condition provider, check and remove invalid condition from the permission's condition array.\n * @param provider - The condition provider used to do the checks\n * @param permission - The condition to sanitize\n */\nexport const sanitizeConditions = curry(\n (provider: Provider, permission: Permission): Permission => {\n if (!isArray(permission.conditions)) {\n return permission;\n }\n\n return permission.conditions\n .filter((condition: string) => !provider.has(condition))\n .reduce(\n (perm: Permission, condition: string) => removeCondition(condition, perm),\n permission\n );\n }\n);\n\n/**\n * Transform raw attributes into valid permissions using the create domain function.\n * @param payload - Can either be a single object of attributes or an array of those objects.\n */\n\nfunction toPermission<T extends CreatePermissionPayload>(payload: T[]): Permission[];\nfunction toPermission<T extends CreatePermissionPayload>(payload: T): Permission;\nfunction toPermission<T extends CreatePermissionPayload>(\n payload: T[] | T\n): Permission[] | Permission {\n if (isArray(payload)) {\n return map((value) => create(value), payload);\n }\n\n return create(payload);\n}\n\nexport { toPermission };\n\nexport default {\n addCondition,\n removeCondition,\n create,\n deleteProperty,\n permissionFields,\n getProperty,\n sanitizedPermissionFields,\n sanitizeConditions,\n sanitizePermissionFields,\n setProperty,\n toPermission,\n};\n"],"names":["permissionFields","sanitizedPermissionFields","sanitizePermissionFields","pick","getDefaultPermission","actionParameters","conditions","properties","subject","addCondition","curry","condition","permission","newConditions","Array","isArray","uniq","concat","set","removeCondition","remove","eq","getProperty","property","get","setProperty","value","deleteProperty","omit","create","attributes","pipe","merge","sanitizeConditions","provider","filter","has","reduce","perm","toPermission","payload","map"],"mappings":";;;;;;MA2BaA,gBAAmB,GAAA;AAC9B,IAAA,IAAA;AACA,IAAA,QAAA;AACA,IAAA,kBAAA;AACA,IAAA,SAAA;AACA,IAAA,YAAA;AACA,IAAA,YAAA;AACA,IAAA;;MAEWC,yBAA4B,GAAA;AACvC,IAAA,IAAA;AACA,IAAA,QAAA;AACA,IAAA,kBAAA;AACA,IAAA,SAAA;AACA,IAAA,YAAA;AACA,IAAA;;AAGK,MAAMC,wBACXC,GAAAA,OAAAA,CAAKF,yBAA2B;AAElC;;IAGA,MAAMG,oBAAuB,GAAA,KAAO;AAClCC,QAAAA,gBAAAA,EAAkB,EAAC;AACnBC,QAAAA,UAAAA,EAAY,EAAE;AACdC,QAAAA,UAAAA,EAAY,EAAC;QACbC,OAAS,EAAA;KACX,CAAA;AAEA;;;;;AAKC,IACM,MAAMC,YAAeC,GAAAA,QAAAA,CAAM,CAACC,SAAmBC,EAAAA,UAAAA,GAAAA;IACpD,MAAM,EAAEN,UAAU,EAAE,GAAGM,UAAAA;IACvB,MAAMC,aAAAA,GAAgBC,MAAMC,OAAO,CAACT,cAChCU,OAAKV,CAAAA,UAAAA,CAAWW,MAAM,CAACN,SACvB,CAAA,CAAA,GAAA;AAACA,QAAAA;AAAU,KAAA;IAEf,OAAOO,MAAAA,CAAI,cAAcL,aAAeD,EAAAA,UAAAA,CAAAA;AAC1C,CAAG;AAEH;;;;AAIC,IACM,MAAMO,eAAkBT,GAAAA,QAAAA,CAAM,CAACC,SAAmBC,EAAAA,UAAAA,GAAAA;AACvD,IAAA,OAAOM,OAAI,YAAcE,EAAAA,SAAAA,CAAOC,MAAGV,SAAYC,CAAAA,EAAAA,UAAAA,CAAWN,UAAU,CAAGM,EAAAA,UAAAA,CAAAA;AACzE,CAAG;AAEH;;;;AAIC,IACM,MAAMU,WAAcZ,GAAAA,QAAAA,CACzB,CAACa,QAAkBX,EAAAA,UAAAA,GACjBY,MAAI,CAAA,CAAC,WAAW,EAAED,QAAS,CAAA,CAAC,EAAEX,UAChC,CAAA;AAEF;;;;;AAKC,IACM,MAAMa,WAAc,GAAA,CACzBF,UACAG,KACAd,EAAAA,UAAAA,GAAAA;AAEA,IAAA,OAAOM,OAAI,CAAC,WAAW,EAAEK,QAAS,CAAA,CAAC,EAAEG,KAAOd,EAAAA,UAAAA,CAAAA;AAC9C;AAEA;;;;AAIC,IACM,MAAMe,cAAiB,GAAA,CAC5BJ,QACAX,EAAAA,UAAAA,GACGgB,OAAK,CAAA,CAAC,WAAW,EAAEL,QAAS,CAAA,CAAC,EAAEX,UAA2C;AAE/E;;;IAIaiB,MAAAA,MAAAA,GAAS,CAACC,UAAAA,GAAAA;AACrB,IAAA,OAAOC,OAAK5B,CAAAA,OAAAA,CAAKH,gBAAmBgC,CAAAA,EAAAA,QAAAA,CAAM5B,oBAAyB0B,EAAAA,CAAAA,CAAAA,CAAAA,UAAAA,CAAAA;AACrE;AAEA;;;;AAIC,IACM,MAAMG,kBAAqBvB,GAAAA,QAAAA,CAChC,CAACwB,QAAoBtB,EAAAA,UAAAA,GAAAA;AACnB,IAAA,IAAI,CAACG,UAAAA,CAAQH,UAAWN,CAAAA,UAAU,CAAG,EAAA;QACnC,OAAOM,UAAAA;AACT;AAEA,IAAA,OAAOA,WAAWN,UAAU,CACzB6B,MAAM,CAAC,CAACxB,YAAsB,CAACuB,QAAAA,CAASE,GAAG,CAACzB,SAAAA,CAAAA,CAAAA,CAC5C0B,MAAM,CACL,CAACC,MAAkB3B,SAAsBQ,GAAAA,eAAAA,CAAgBR,WAAW2B,IACpE1B,CAAAA,EAAAA,UAAAA,CAAAA;AAEN,CACA;AASF,SAAS2B,aACPC,OAAgB,EAAA;AAEhB,IAAA,IAAIzB,WAAQyB,OAAU,CAAA,EAAA;AACpB,QAAA,OAAOC,MAAI,CAAA,CAACf,KAAUG,GAAAA,MAAAA,CAAOH,KAAQc,CAAAA,EAAAA,OAAAA,CAAAA;AACvC;AAEA,IAAA,OAAOX,MAAOW,CAAAA,OAAAA,CAAAA;AAChB;AAIA,uBAAe;AACb/B,IAAAA,YAAAA;AACAU,IAAAA,eAAAA;AACAU,IAAAA,MAAAA;AACAF,IAAAA,cAAAA;AACA3B,IAAAA,gBAAAA;AACAsB,IAAAA,WAAAA;AACArB,IAAAA,yBAAAA;AACAgC,IAAAA,kBAAAA;AACA/B,IAAAA,wBAAAA;AACAuB,IAAAA,WAAAA;AACAc,IAAAA;AACF,CAAE;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../../../../server/src/domain/permission/index.ts"],"sourcesContent":["import type { Utils } from '@strapi/types';\n\nimport { providerFactory } from '@strapi/utils';\nimport {\n pipe,\n set,\n pick,\n eq,\n omit,\n remove,\n get,\n uniq,\n isArray,\n map,\n curry,\n merge,\n} from 'lodash/fp';\nimport { Permission } from '../../../../shared/contracts/shared';\nimport { SanitizedPermission } from '../../../../shared/contracts/roles';\n\nexport type CreatePermissionPayload = Utils.Object.PartialBy<\n Permission,\n 'actionParameters' | 'conditions' | 'properties' | 'subject' | 'id' | 'createdAt' | 'updatedAt'\n>;\n\ntype Provider = ReturnType<typeof providerFactory>;\n\nexport const permissionFields = [\n 'id',\n 'action',\n 'actionParameters',\n 'subject',\n 'properties',\n 'conditions',\n 'role',\n];\nexport const sanitizedPermissionFields = [\n 'id',\n 'action',\n 'actionParameters',\n 'subject',\n 'properties',\n 'conditions',\n] as const;\n\nexport const sanitizePermissionFields: (p: Permission) => SanitizedPermission =\n pick(sanitizedPermissionFields);\n\n/**\n * Creates a permission with default values\n */\nconst getDefaultPermission = () => ({\n actionParameters: {},\n conditions: [],\n properties: {},\n subject: null,\n});\n\n/**\n * Returns a new permission with the given condition\n * @param condition - The condition to add\n * @param permission - The permission on which we want to add the condition\n * @return\n */\nexport const addCondition = curry((condition: string, permission: Permission): Permission => {\n const { conditions } = permission;\n const newConditions = Array.isArray(conditions)\n ? uniq(conditions.concat(condition))\n : [condition];\n\n return set('conditions', newConditions, permission);\n});\n\n/**\n * Returns a new permission without the given condition\n * @param condition - The condition to remove\n * @param permission - The permission on which we want to remove the condition\n */\nexport const removeCondition = curry((condition: string, permission: Permission): Permission => {\n return set('conditions', remove(eq(condition), permission.conditions), permission);\n});\n\n/**\n * Gets a property or a part of a property from a permission.\n * @param property - The property to get\n * @param permission - The permission on which we want to access the property\n */\nexport const getProperty = curry(\n (property: string, permission: Permission): Permission =>\n get(`properties.${property}`, permission)\n);\n\n/**\n * Set a value for a given property on a new permission object\n * @param property - The name of the property\n * @param value - The value of the property\n * @param permission - The permission on which we want to set the property\n */\nexport const setProperty = (\n property: string,\n value: unknown,\n permission: Permission\n): Permission => {\n return set(`properties.${property}`, value, permission);\n};\n\n/**\n * Returns a new permission without the given property name set\n * @param property - The name of the property to delete\n * @param permission - The permission on which we want to remove the property\n */\nexport const deleteProperty = <TProperty extends string>(\n property: TProperty,\n permission: Permission\n) => omit(`properties.${property}`, permission) as Omit<Permission, TProperty>;\n\n/**\n * Creates a new {@link Permission} object from raw attributes. Set default values for certain fields\n * @param attributes\n */\nexport const create = (attributes: CreatePermissionPayload) => {\n return pipe(pick(permissionFields), merge(getDefaultPermission()))(attributes) as Permission;\n};\n\n/**\n * Using the given condition provider, check and remove invalid condition from the permission's condition array.\n * @param provider - The condition provider used to do the checks\n * @param permission - The condition to sanitize\n */\nexport const sanitizeConditions = curry(\n (provider: Provider, permission: Permission): Permission => {\n if (!isArray(permission.conditions)) {\n return permission;\n }\n\n return permission.conditions\n .filter((condition: string) => !provider.has(condition))\n .reduce(\n (perm: Permission, condition: string) => removeCondition(condition, perm),\n permission\n );\n }\n);\n\n/**\n * Transform raw attributes into valid permissions using the create domain function.\n * @param payload - Can either be a single object of attributes or an array of those objects.\n */\n\nfunction toPermission<T extends CreatePermissionPayload>(payload: T[]): Permission[];\nfunction toPermission<T extends CreatePermissionPayload>(payload: T): Permission;\nfunction toPermission<T extends CreatePermissionPayload>(\n payload: T[] | T\n): Permission[] | Permission {\n if (isArray(payload)) {\n return map((value) => create(value), payload);\n }\n\n return create(payload);\n}\n\nexport { toPermission };\n\nexport default {\n addCondition,\n removeCondition,\n create,\n deleteProperty,\n permissionFields,\n getProperty,\n sanitizedPermissionFields,\n sanitizeConditions,\n sanitizePermissionFields,\n setProperty,\n toPermission,\n};\n"],"names":["permissionFields","sanitizedPermissionFields","sanitizePermissionFields","pick","getDefaultPermission","actionParameters","conditions","properties","subject","addCondition","curry","condition","permission","newConditions","Array","isArray","uniq","concat","set","removeCondition","remove","eq","getProperty","property","get","setProperty","value","deleteProperty","omit","create","attributes","pipe","merge","sanitizeConditions","provider","filter","has","reduce","perm","toPermission","payload","map"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../../../../../server/src/domain/permission/index.ts"],"sourcesContent":["import type { Utils } from '@strapi/types';\n\nimport { providerFactory } from '@strapi/utils';\nimport {\n pipe,\n set,\n pick,\n eq,\n omit,\n remove,\n get,\n uniq,\n isArray,\n map,\n curry,\n merge,\n} from 'lodash/fp';\nimport { Permission } from '../../../../shared/contracts/shared';\nimport { SanitizedPermission } from '../../../../shared/contracts/roles';\n\nexport type CreatePermissionPayload = Utils.Object.PartialBy<\n Permission,\n 'actionParameters' | 'conditions' | 'properties' | 'subject' | 'id' | 'createdAt' | 'updatedAt'\n>;\n\ntype Provider = ReturnType<typeof providerFactory>;\n\nexport const permissionFields = [\n 'id',\n 'action',\n 'actionParameters',\n 'subject',\n 'properties',\n 'conditions',\n 'role',\n];\nexport const sanitizedPermissionFields = [\n 'id',\n 'action',\n 'actionParameters',\n 'subject',\n 'properties',\n 'conditions',\n] as const;\n\nexport const sanitizePermissionFields: (p: Permission) => SanitizedPermission =\n pick(sanitizedPermissionFields);\n\n/**\n * Creates a permission with default values\n */\nconst getDefaultPermission = () => ({\n actionParameters: {},\n conditions: [],\n properties: {},\n subject: null,\n});\n\n/**\n * Returns a new permission with the given condition\n * @param condition - The condition to add\n * @param permission - The permission on which we want to add the condition\n * @return\n */\nexport const addCondition = curry((condition: string, permission: Permission): Permission => {\n const { conditions } = permission;\n const newConditions = Array.isArray(conditions)\n ? uniq(conditions.concat(condition))\n : [condition];\n\n return set('conditions', newConditions, permission);\n});\n\n/**\n * Returns a new permission without the given condition\n * @param condition - The condition to remove\n * @param permission - The permission on which we want to remove the condition\n */\nexport const removeCondition = curry((condition: string, permission: Permission): Permission => {\n return set('conditions', remove(eq(condition), permission.conditions), permission);\n});\n\n/**\n * Gets a property or a part of a property from a permission.\n * @param property - The property to get\n * @param permission - The permission on which we want to access the property\n */\nexport const getProperty = curry(\n (property: string, permission: Permission): Permission =>\n get(`properties.${property}`, permission)\n);\n\n/**\n * Set a value for a given property on a new permission object\n * @param property - The name of the property\n * @param value - The value of the property\n * @param permission - The permission on which we want to set the property\n */\nexport const setProperty = (\n property: string,\n value: unknown,\n permission: Permission\n): Permission => {\n return set(`properties.${property}`, value, permission);\n};\n\n/**\n * Returns a new permission without the given property name set\n * @param property - The name of the property to delete\n * @param permission - The permission on which we want to remove the property\n */\nexport const deleteProperty = <TProperty extends string>(\n property: TProperty,\n permission: Permission\n) => omit(`properties.${property}`, permission) as Omit<Permission, TProperty>;\n\n/**\n * Creates a new {@link Permission} object from raw attributes. Set default values for certain fields\n * @param attributes\n */\nexport const create = (attributes: CreatePermissionPayload) => {\n return pipe(pick(permissionFields), merge(getDefaultPermission()))(attributes) as Permission;\n};\n\n/**\n * Using the given condition provider, check and remove invalid condition from the permission's condition array.\n * @param provider - The condition provider used to do the checks\n * @param permission - The condition to sanitize\n */\nexport const sanitizeConditions = curry(\n (provider: Provider, permission: Permission): Permission => {\n if (!isArray(permission.conditions)) {\n return permission;\n }\n\n return permission.conditions\n .filter((condition: string) => !provider.has(condition))\n .reduce(\n (perm: Permission, condition: string) => removeCondition(condition, perm),\n permission\n );\n }\n);\n\n/**\n * Transform raw attributes into valid permissions using the create domain function.\n * @param payload - Can either be a single object of attributes or an array of those objects.\n */\n\nfunction toPermission<T extends CreatePermissionPayload>(payload: T[]): Permission[];\nfunction toPermission<T extends CreatePermissionPayload>(payload: T): Permission;\nfunction toPermission<T extends CreatePermissionPayload>(\n payload: T[] | T\n): Permission[] | Permission {\n if (isArray(payload)) {\n return map((value) => create(value), payload);\n }\n\n return create(payload);\n}\n\nexport { toPermission };\n\nexport default {\n addCondition,\n removeCondition,\n create,\n deleteProperty,\n permissionFields,\n getProperty,\n sanitizedPermissionFields,\n sanitizeConditions,\n sanitizePermissionFields,\n setProperty,\n toPermission,\n};\n"],"names":["permissionFields","sanitizedPermissionFields","sanitizePermissionFields","pick","getDefaultPermission","actionParameters","conditions","properties","subject","addCondition","curry","condition","permission","newConditions","Array","isArray","uniq","concat","set","removeCondition","remove","eq","getProperty","property","get","setProperty","value","deleteProperty","omit","create","attributes","pipe","merge","sanitizeConditions","provider","filter","has","reduce","perm","toPermission","payload","map"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../../../../../../server/src/domain/permission/index.ts"],"sourcesContent":["import type { Utils } from '@strapi/types';\n\nimport { providerFactory } from '@strapi/utils';\nimport {\n pipe,\n set,\n pick,\n eq,\n omit,\n remove,\n get,\n uniq,\n isArray,\n map,\n curry,\n merge,\n} from 'lodash/fp';\nimport { Permission } from '../../../../shared/contracts/shared';\nimport { SanitizedPermission } from '../../../../shared/contracts/roles';\n\nexport type CreatePermissionPayload = Utils.Object.PartialBy<\n Permission,\n 'actionParameters' | 'conditions' | 'properties' | 'subject' | 'id' | 'createdAt' | 'updatedAt'\n>;\n\ntype Provider = ReturnType<typeof providerFactory>;\n\nexport const permissionFields = [\n 'id',\n 'action',\n 'actionParameters',\n 'subject',\n 'properties',\n 'conditions',\n 'role',\n];\nexport const sanitizedPermissionFields = [\n 'id',\n 'action',\n 'actionParameters',\n 'subject',\n 'properties',\n 'conditions',\n] as const;\n\nexport const sanitizePermissionFields: (p: Permission) => SanitizedPermission =\n pick(sanitizedPermissionFields);\n\n/**\n * Creates a permission with default values\n */\nconst getDefaultPermission = () => ({\n actionParameters: {},\n conditions: [],\n properties: {},\n subject: null,\n});\n\n/**\n * Returns a new permission with the given condition\n * @param condition - The condition to add\n * @param permission - The permission on which we want to add the condition\n * @return\n */\nexport const addCondition = curry((condition: string, permission: Permission): Permission => {\n const { conditions } = permission;\n const newConditions = Array.isArray(conditions)\n ? uniq(conditions.concat(condition))\n : [condition];\n\n return set('conditions', newConditions, permission);\n});\n\n/**\n * Returns a new permission without the given condition\n * @param condition - The condition to remove\n * @param permission - The permission on which we want to remove the condition\n */\nexport const removeCondition = curry((condition: string, permission: Permission): Permission => {\n return set('conditions', remove(eq(condition), permission.conditions), permission);\n});\n\n/**\n * Gets a property or a part of a property from a permission.\n * @param property - The property to get\n * @param permission - The permission on which we want to access the property\n */\nexport const getProperty = curry(\n (property: string, permission: Permission): Permission =>\n get(`properties.${property}`, permission)\n);\n\n/**\n * Set a value for a given property on a new permission object\n * @param property - The name of the property\n * @param value - The value of the property\n * @param permission - The permission on which we want to set the property\n */\nexport const setProperty = (\n property: string,\n value: unknown,\n permission: Permission\n): Permission => {\n return set(`properties.${property}`, value, permission);\n};\n\n/**\n * Returns a new permission without the given property name set\n * @param property - The name of the property to delete\n * @param permission - The permission on which we want to remove the property\n */\nexport const deleteProperty = <TProperty extends string>(\n property: TProperty,\n permission: Permission\n) => omit(`properties.${property}`, permission) as Omit<Permission, TProperty>;\n\n/**\n * Creates a new {@link Permission} object from raw attributes. Set default values for certain fields\n * @param attributes\n */\nexport const create = (attributes: CreatePermissionPayload) => {\n return pipe(pick(permissionFields), merge(getDefaultPermission()))(attributes) as Permission;\n};\n\n/**\n * Using the given condition provider, check and remove invalid condition from the permission's condition array.\n * @param provider - The condition provider used to do the checks\n * @param permission - The condition to sanitize\n */\nexport const sanitizeConditions = curry(\n (provider: Provider, permission: Permission): Permission => {\n if (!isArray(permission.conditions)) {\n return permission;\n }\n\n return permission.conditions\n .filter((condition: string) => !provider.has(condition))\n .reduce(\n (perm: Permission, condition: string) => removeCondition(condition, perm),\n permission\n );\n }\n);\n\n/**\n * Transform raw attributes into valid permissions using the create domain function.\n * @param payload - Can either be a single object of attributes or an array of those objects.\n */\n\nfunction toPermission<T extends CreatePermissionPayload>(payload: T[]): Permission[];\nfunction toPermission<T extends CreatePermissionPayload>(payload: T): Permission;\nfunction toPermission<T extends CreatePermissionPayload>(\n payload: T[] | T\n): Permission[] | Permission {\n if (isArray(payload)) {\n return map((value) => create(value), payload);\n }\n\n return create(payload);\n}\n\nexport { toPermission };\n\nexport default {\n addCondition,\n removeCondition,\n create,\n deleteProperty,\n permissionFields,\n getProperty,\n sanitizedPermissionFields,\n sanitizeConditions,\n sanitizePermissionFields,\n setProperty,\n toPermission,\n};\n"],"names":["permissionFields","sanitizedPermissionFields","sanitizePermissionFields","pick","getDefaultPermission","actionParameters","conditions","properties","subject","addCondition","curry","condition","permission","newConditions","Array","isArray","uniq","concat","set","removeCondition","remove","eq","getProperty","property","get","setProperty","value","deleteProperty","omit","create","attributes","pipe","merge","sanitizeConditions","provider","filter","has","reduce","perm","toPermission","payload","map"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"rateLimit.js","sources":["../../../../../server/src/middlewares/rateLimit.ts"],"sourcesContent":["import type { Context, Next } from 'koa';\nimport path from 'path';\nimport utils from '@strapi/utils';\nimport { isString, has, toLower, get } from 'lodash/fp';\nimport type { Core } from '@strapi/types';\n\nconst { RateLimitError } = utils.errors;\n\nexport default (config: any, { strapi }: { strapi: Core.Strapi }) =>\n async (ctx: Context, next: Next) => {\n let rateLimitConfig = strapi.config.get('admin.rateLimit') as any;\n\n if (!rateLimitConfig) {\n rateLimitConfig = {\n enabled: true,\n };\n }\n\n if (!has('enabled', rateLimitConfig)) {\n rateLimitConfig.enabled = true;\n }\n\n if (rateLimitConfig.enabled === true) {\n // TODO: TS - Do the dynamic import\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const rateLimit = require('koa2-ratelimit').RateLimit;\n\n const requestEmail = get('request.body.email')(ctx);\n const userEmail = isString(requestEmail) ? requestEmail.toLowerCase() : 'unknownEmail';\n\n const requestPath = isString(ctx.request.path)\n ? toLower(path.normalize(ctx.request.path)).replace(/\\/$/, '')\n : 'invalidPath';\n\n const loadConfig = {\n interval: { min: 5 },\n max: 5,\n prefixKey: `${userEmail}:${requestPath}:${ctx.request.ip}`,\n handler() {\n throw new RateLimitError();\n },\n ...rateLimitConfig,\n ...config,\n };\n\n return rateLimit.middleware(loadConfig)(ctx, next);\n }\n\n return next();\n };\n"],"names":["RateLimitError","utils","errors","config","strapi","ctx","next","rateLimitConfig","get","enabled","has","rateLimit","require","RateLimit","requestEmail","userEmail","isString","toLowerCase","requestPath","request","path","toLower","normalize","replace","loadConfig","interval","min","max","prefixKey","ip","handler","middleware"],"mappings":";;;;;;AAMA,MAAM,EAAEA,cAAc,EAAE,GAAGC,MAAMC,MAAM;AAEvC,gBAAe,CAAA,CAACC,MAAa,EAAA,EAAEC,MAAM,EAA2B,GAC9D,OAAOC,GAAcC,EAAAA,IAAAA,GAAAA;AACnB,QAAA,IAAIC,eAAkBH,GAAAA,MAAAA,CAAOD,MAAM,CAACK,GAAG,CAAC,iBAAA,CAAA;AAExC,QAAA,IAAI,CAACD,eAAiB,EAAA;YACpBA,eAAkB,GAAA;gBAChBE,OAAS,EAAA;AACX,aAAA;AACF;QAEA,IAAI,CAACC,MAAI,CAAA,SAAA,EAAWH,eAAkB,CAAA,EAAA;AACpCA,YAAAA,eAAAA,CAAgBE,OAAO,GAAG,IAAA;AAC5B;QAEA,IAAIF,eAAAA,CAAgBE,OAAO,KAAK,IAAM,EAAA;;;YAGpC,MAAME,SAAAA,GAAYC,OAAQ,CAAA,gBAAA,CAAA,CAAkBC,SAAS;YAErD,MAAMC,YAAAA,GAAeN,OAAI,oBAAsBH,CAAAA,CAAAA,GAAAA,CAAAA;AAC/C,YAAA,MAAMU,SAAYC,GAAAA,WAAAA,CAASF,YAAgBA,CAAAA,GAAAA,YAAAA,CAAaG,WAAW,EAAK,GAAA,cAAA;AAExE,YAAA,MAAMC,cAAcF,WAASX,CAAAA,GAAAA,CAAIc,OAAO,CAACC,IAAI,IACzCC,UAAQD,CAAAA,IAAAA,CAAKE,SAAS,CAACjB,GAAAA,CAAIc,OAAO,CAACC,IAAI,GAAGG,OAAO,CAAC,OAAO,EACzD,CAAA,GAAA,aAAA;AAEJ,YAAA,MAAMC,UAAa,GAAA;gBACjBC,QAAU,EAAA;oBAAEC,GAAK,EAAA;AAAE,iBAAA;gBACnBC,GAAK,EAAA,CAAA;AACLC,gBAAAA,SAAAA,EAAW,CAAC,EAAEb,SAAU,CAAA,CAAC,EAAEG,WAAAA,CAAY,CAAC,EAAEb,GAAIc,CAAAA,OAAO,CAACU,EAAE,CAAC,CAAC;AAC1DC,gBAAAA,OAAAA,CAAAA,GAAAA;AACE,oBAAA,MAAM,IAAI9B,cAAAA,EAAAA;AACZ,iBAAA;AACA,gBAAA,GAAGO,eAAe;AAClB,gBAAA,GAAGJ;AACL,aAAA;AAEA,YAAA,OAAOQ,SAAUoB,CAAAA,UAAU,CAACP,UAAAA,CAAAA,CAAYnB,GAAKC,EAAAA,IAAAA,CAAAA;AAC/C;QAEA,OAAOA,IAAAA,EAAAA;AACT,KAAA;;;;"}
1
+ {"version":3,"file":"rateLimit.js","sources":["../../../../../server/src/middlewares/rateLimit.ts"],"sourcesContent":["import type { Context, Next } from 'koa';\nimport path from 'path';\nimport utils from '@strapi/utils';\nimport { isString, has, toLower, get } from 'lodash/fp';\nimport type { Core } from '@strapi/types';\n\nconst { RateLimitError } = utils.errors;\n\nexport default (config: any, { strapi }: { strapi: Core.Strapi }) =>\n async (ctx: Context, next: Next) => {\n let rateLimitConfig = strapi.config.get('admin.rateLimit') as any;\n\n if (!rateLimitConfig) {\n rateLimitConfig = {\n enabled: true,\n };\n }\n\n if (!has('enabled', rateLimitConfig)) {\n rateLimitConfig.enabled = true;\n }\n\n if (rateLimitConfig.enabled === true) {\n // TODO: TS - Do the dynamic import\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const rateLimit = require('koa2-ratelimit').RateLimit;\n\n const requestEmail = get('request.body.email')(ctx);\n const userEmail = isString(requestEmail) ? requestEmail.toLowerCase() : 'unknownEmail';\n\n const requestPath = isString(ctx.request.path)\n ? toLower(path.normalize(ctx.request.path)).replace(/\\/$/, '')\n : 'invalidPath';\n\n const loadConfig = {\n interval: { min: 5 },\n max: 5,\n prefixKey: `${userEmail}:${requestPath}:${ctx.request.ip}`,\n handler() {\n throw new RateLimitError();\n },\n ...rateLimitConfig,\n ...config,\n };\n\n return rateLimit.middleware(loadConfig)(ctx, next);\n }\n\n return next();\n };\n"],"names":["RateLimitError","utils","errors","config","strapi","ctx","next","rateLimitConfig","get","enabled","has","rateLimit","require","RateLimit","requestEmail","userEmail","isString","toLowerCase","requestPath","request","path","toLower","normalize","replace","loadConfig","interval","min","max","prefixKey","ip","handler","middleware"],"mappings":";;;;;;AAMA,MAAM,EAAEA,cAAc,EAAE,GAAGC,MAAMC,MAAM;AAEvC,gBAAe,CAAA,CAACC,MAAa,EAAA,EAAEC,MAAM,EAA2B,GAC9D,OAAOC,GAAcC,EAAAA,IAAAA,GAAAA;AACnB,QAAA,IAAIC,eAAkBH,GAAAA,MAAAA,CAAOD,MAAM,CAACK,GAAG,CAAC,iBAAA,CAAA;AAExC,QAAA,IAAI,CAACD,eAAiB,EAAA;YACpBA,eAAkB,GAAA;gBAChBE,OAAS,EAAA;AACX,aAAA;AACF;QAEA,IAAI,CAACC,MAAI,CAAA,SAAA,EAAWH,eAAkB,CAAA,EAAA;AACpCA,YAAAA,eAAAA,CAAgBE,OAAO,GAAG,IAAA;AAC5B;QAEA,IAAIF,eAAAA,CAAgBE,OAAO,KAAK,IAAM,EAAA;;;YAGpC,MAAME,SAAAA,GAAYC,OAAQ,CAAA,gBAAA,CAAA,CAAkBC,SAAS;YAErD,MAAMC,YAAAA,GAAeN,OAAI,oBAAsBH,CAAAA,CAAAA,GAAAA,CAAAA;AAC/C,YAAA,MAAMU,SAAYC,GAAAA,WAAAA,CAASF,YAAgBA,CAAAA,GAAAA,YAAAA,CAAaG,WAAW,EAAK,GAAA,cAAA;AAExE,YAAA,MAAMC,cAAcF,WAASX,CAAAA,GAAAA,CAAIc,OAAO,CAACC,IAAI,IACzCC,UAAQD,CAAAA,IAAAA,CAAKE,SAAS,CAACjB,GAAAA,CAAIc,OAAO,CAACC,IAAI,GAAGG,OAAO,CAAC,OAAO,EACzD,CAAA,GAAA,aAAA;AAEJ,YAAA,MAAMC,UAAa,GAAA;gBACjBC,QAAU,EAAA;oBAAEC,GAAK,EAAA;AAAE,iBAAA;gBACnBC,GAAK,EAAA,CAAA;gBACLC,SAAW,EAAA,CAAA,EAAGb,SAAU,CAAA,CAAC,EAAEG,WAAAA,CAAY,CAAC,EAAEb,GAAIc,CAAAA,OAAO,CAACU,EAAE,CAAE,CAAA;AAC1DC,gBAAAA,OAAAA,CAAAA,GAAAA;AACE,oBAAA,MAAM,IAAI9B,cAAAA,EAAAA;AACZ,iBAAA;AACA,gBAAA,GAAGO,eAAe;AAClB,gBAAA,GAAGJ;AACL,aAAA;AAEA,YAAA,OAAOQ,SAAUoB,CAAAA,UAAU,CAACP,UAAAA,CAAAA,CAAYnB,GAAKC,EAAAA,IAAAA,CAAAA;AAC/C;QAEA,OAAOA,IAAAA,EAAAA;AACT,KAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"rateLimit.mjs","sources":["../../../../../server/src/middlewares/rateLimit.ts"],"sourcesContent":["import type { Context, Next } from 'koa';\nimport path from 'path';\nimport utils from '@strapi/utils';\nimport { isString, has, toLower, get } from 'lodash/fp';\nimport type { Core } from '@strapi/types';\n\nconst { RateLimitError } = utils.errors;\n\nexport default (config: any, { strapi }: { strapi: Core.Strapi }) =>\n async (ctx: Context, next: Next) => {\n let rateLimitConfig = strapi.config.get('admin.rateLimit') as any;\n\n if (!rateLimitConfig) {\n rateLimitConfig = {\n enabled: true,\n };\n }\n\n if (!has('enabled', rateLimitConfig)) {\n rateLimitConfig.enabled = true;\n }\n\n if (rateLimitConfig.enabled === true) {\n // TODO: TS - Do the dynamic import\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const rateLimit = require('koa2-ratelimit').RateLimit;\n\n const requestEmail = get('request.body.email')(ctx);\n const userEmail = isString(requestEmail) ? requestEmail.toLowerCase() : 'unknownEmail';\n\n const requestPath = isString(ctx.request.path)\n ? toLower(path.normalize(ctx.request.path)).replace(/\\/$/, '')\n : 'invalidPath';\n\n const loadConfig = {\n interval: { min: 5 },\n max: 5,\n prefixKey: `${userEmail}:${requestPath}:${ctx.request.ip}`,\n handler() {\n throw new RateLimitError();\n },\n ...rateLimitConfig,\n ...config,\n };\n\n return rateLimit.middleware(loadConfig)(ctx, next);\n }\n\n return next();\n };\n"],"names":["RateLimitError","utils","errors","config","strapi","ctx","next","rateLimitConfig","get","enabled","has","rateLimit","require","RateLimit","requestEmail","userEmail","isString","toLowerCase","requestPath","request","path","toLower","normalize","replace","loadConfig","interval","min","max","prefixKey","ip","handler","middleware"],"mappings":";;;;AAMA,MAAM,EAAEA,cAAc,EAAE,GAAGC,MAAMC,MAAM;AAEvC,gBAAe,CAAA,CAACC,MAAa,EAAA,EAAEC,MAAM,EAA2B,GAC9D,OAAOC,GAAcC,EAAAA,IAAAA,GAAAA;AACnB,QAAA,IAAIC,eAAkBH,GAAAA,MAAAA,CAAOD,MAAM,CAACK,GAAG,CAAC,iBAAA,CAAA;AAExC,QAAA,IAAI,CAACD,eAAiB,EAAA;YACpBA,eAAkB,GAAA;gBAChBE,OAAS,EAAA;AACX,aAAA;AACF;QAEA,IAAI,CAACC,GAAI,CAAA,SAAA,EAAWH,eAAkB,CAAA,EAAA;AACpCA,YAAAA,eAAAA,CAAgBE,OAAO,GAAG,IAAA;AAC5B;QAEA,IAAIF,eAAAA,CAAgBE,OAAO,KAAK,IAAM,EAAA;;;YAGpC,MAAME,SAAAA,GAAYC,OAAQ,CAAA,gBAAA,CAAA,CAAkBC,SAAS;YAErD,MAAMC,YAAAA,GAAeN,IAAI,oBAAsBH,CAAAA,CAAAA,GAAAA,CAAAA;AAC/C,YAAA,MAAMU,SAAYC,GAAAA,QAAAA,CAASF,YAAgBA,CAAAA,GAAAA,YAAAA,CAAaG,WAAW,EAAK,GAAA,cAAA;AAExE,YAAA,MAAMC,cAAcF,QAASX,CAAAA,GAAAA,CAAIc,OAAO,CAACC,IAAI,IACzCC,OAAQD,CAAAA,IAAAA,CAAKE,SAAS,CAACjB,GAAAA,CAAIc,OAAO,CAACC,IAAI,GAAGG,OAAO,CAAC,OAAO,EACzD,CAAA,GAAA,aAAA;AAEJ,YAAA,MAAMC,UAAa,GAAA;gBACjBC,QAAU,EAAA;oBAAEC,GAAK,EAAA;AAAE,iBAAA;gBACnBC,GAAK,EAAA,CAAA;AACLC,gBAAAA,SAAAA,EAAW,CAAC,EAAEb,SAAU,CAAA,CAAC,EAAEG,WAAAA,CAAY,CAAC,EAAEb,GAAIc,CAAAA,OAAO,CAACU,EAAE,CAAC,CAAC;AAC1DC,gBAAAA,OAAAA,CAAAA,GAAAA;AACE,oBAAA,MAAM,IAAI9B,cAAAA,EAAAA;AACZ,iBAAA;AACA,gBAAA,GAAGO,eAAe;AAClB,gBAAA,GAAGJ;AACL,aAAA;AAEA,YAAA,OAAOQ,SAAUoB,CAAAA,UAAU,CAACP,UAAAA,CAAAA,CAAYnB,GAAKC,EAAAA,IAAAA,CAAAA;AAC/C;QAEA,OAAOA,IAAAA,EAAAA;AACT,KAAA;;;;"}
1
+ {"version":3,"file":"rateLimit.mjs","sources":["../../../../../server/src/middlewares/rateLimit.ts"],"sourcesContent":["import type { Context, Next } from 'koa';\nimport path from 'path';\nimport utils from '@strapi/utils';\nimport { isString, has, toLower, get } from 'lodash/fp';\nimport type { Core } from '@strapi/types';\n\nconst { RateLimitError } = utils.errors;\n\nexport default (config: any, { strapi }: { strapi: Core.Strapi }) =>\n async (ctx: Context, next: Next) => {\n let rateLimitConfig = strapi.config.get('admin.rateLimit') as any;\n\n if (!rateLimitConfig) {\n rateLimitConfig = {\n enabled: true,\n };\n }\n\n if (!has('enabled', rateLimitConfig)) {\n rateLimitConfig.enabled = true;\n }\n\n if (rateLimitConfig.enabled === true) {\n // TODO: TS - Do the dynamic import\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const rateLimit = require('koa2-ratelimit').RateLimit;\n\n const requestEmail = get('request.body.email')(ctx);\n const userEmail = isString(requestEmail) ? requestEmail.toLowerCase() : 'unknownEmail';\n\n const requestPath = isString(ctx.request.path)\n ? toLower(path.normalize(ctx.request.path)).replace(/\\/$/, '')\n : 'invalidPath';\n\n const loadConfig = {\n interval: { min: 5 },\n max: 5,\n prefixKey: `${userEmail}:${requestPath}:${ctx.request.ip}`,\n handler() {\n throw new RateLimitError();\n },\n ...rateLimitConfig,\n ...config,\n };\n\n return rateLimit.middleware(loadConfig)(ctx, next);\n }\n\n return next();\n };\n"],"names":["RateLimitError","utils","errors","config","strapi","ctx","next","rateLimitConfig","get","enabled","has","rateLimit","require","RateLimit","requestEmail","userEmail","isString","toLowerCase","requestPath","request","path","toLower","normalize","replace","loadConfig","interval","min","max","prefixKey","ip","handler","middleware"],"mappings":";;;;AAMA,MAAM,EAAEA,cAAc,EAAE,GAAGC,MAAMC,MAAM;AAEvC,gBAAe,CAAA,CAACC,MAAa,EAAA,EAAEC,MAAM,EAA2B,GAC9D,OAAOC,GAAcC,EAAAA,IAAAA,GAAAA;AACnB,QAAA,IAAIC,eAAkBH,GAAAA,MAAAA,CAAOD,MAAM,CAACK,GAAG,CAAC,iBAAA,CAAA;AAExC,QAAA,IAAI,CAACD,eAAiB,EAAA;YACpBA,eAAkB,GAAA;gBAChBE,OAAS,EAAA;AACX,aAAA;AACF;QAEA,IAAI,CAACC,GAAI,CAAA,SAAA,EAAWH,eAAkB,CAAA,EAAA;AACpCA,YAAAA,eAAAA,CAAgBE,OAAO,GAAG,IAAA;AAC5B;QAEA,IAAIF,eAAAA,CAAgBE,OAAO,KAAK,IAAM,EAAA;;;YAGpC,MAAME,SAAAA,GAAYC,OAAQ,CAAA,gBAAA,CAAA,CAAkBC,SAAS;YAErD,MAAMC,YAAAA,GAAeN,IAAI,oBAAsBH,CAAAA,CAAAA,GAAAA,CAAAA;AAC/C,YAAA,MAAMU,SAAYC,GAAAA,QAAAA,CAASF,YAAgBA,CAAAA,GAAAA,YAAAA,CAAaG,WAAW,EAAK,GAAA,cAAA;AAExE,YAAA,MAAMC,cAAcF,QAASX,CAAAA,GAAAA,CAAIc,OAAO,CAACC,IAAI,IACzCC,OAAQD,CAAAA,IAAAA,CAAKE,SAAS,CAACjB,GAAAA,CAAIc,OAAO,CAACC,IAAI,GAAGG,OAAO,CAAC,OAAO,EACzD,CAAA,GAAA,aAAA;AAEJ,YAAA,MAAMC,UAAa,GAAA;gBACjBC,QAAU,EAAA;oBAAEC,GAAK,EAAA;AAAE,iBAAA;gBACnBC,GAAK,EAAA,CAAA;gBACLC,SAAW,EAAA,CAAA,EAAGb,SAAU,CAAA,CAAC,EAAEG,WAAAA,CAAY,CAAC,EAAEb,GAAIc,CAAAA,OAAO,CAACU,EAAE,CAAE,CAAA;AAC1DC,gBAAAA,OAAAA,CAAAA,GAAAA;AACE,oBAAA,MAAM,IAAI9B,cAAAA,EAAAA;AACZ,iBAAA;AACA,gBAAA,GAAGO,eAAe;AAClB,gBAAA,GAAGJ;AACL,aAAA;AAEA,YAAA,OAAOQ,SAAUoB,CAAAA,UAAU,CAACP,UAAAA,CAAAA,CAAYnB,GAAKC,EAAAA,IAAAA,CAAAA;AAC/C;QAEA,OAAOA,IAAAA,EAAAA;AACT,KAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"serve-admin-panel.js","sources":["../../../../../server/src/routes/serve-admin-panel.ts"],"sourcesContent":["import type { Context, Next } from 'koa';\nimport { resolve, join, extname, basename } from 'path';\nimport fse from 'fs-extra';\nimport koaStatic from 'koa-static';\nimport type { Core } from '@strapi/types';\n\nconst registerAdminPanelRoute = ({ strapi }: { strapi: Core.Strapi }) => {\n let buildDir = resolve(strapi.dirs.dist.root, 'build');\n\n if (!fse.pathExistsSync(buildDir)) {\n buildDir = resolve(__dirname, '../../build');\n }\n\n const serveAdminMiddleware = async (ctx: Context, next: Next) => {\n await next();\n\n if (ctx.method !== 'HEAD' && ctx.method !== 'GET') {\n return;\n }\n\n if (ctx.body != null || ctx.status !== 404) {\n return;\n }\n\n ctx.type = 'html';\n ctx.body = fse.createReadStream(join(buildDir, 'index.html'));\n };\n\n strapi.server.routes([\n {\n method: 'GET',\n path: `${strapi.config.admin.path}/:path*`,\n handler: [\n serveAdminMiddleware,\n serveStatic(buildDir, {\n maxage: 31536000,\n defer: false,\n index: 'index.html',\n setHeaders(res: any, path: any) {\n const ext = extname(path);\n // publicly cache static files to avoid unnecessary network & disk access\n if (ext !== '.html') {\n res.setHeader('cache-control', 'public, max-age=31536000, immutable');\n }\n },\n }),\n ],\n config: { auth: false },\n },\n ]);\n};\n\n// serveStatic is not supposed to be used to serve a folder that have sub-folders\nconst serveStatic = (filesDir: any, koaStaticOptions = {}) => {\n const serve = koaStatic(filesDir, koaStaticOptions);\n\n return async (ctx: Context, next: Next) => {\n const prev = ctx.path;\n const newPath = basename(ctx.path);\n\n ctx.path = newPath;\n await serve(ctx, async () => {\n ctx.path = prev;\n await next();\n ctx.path = newPath;\n });\n ctx.path = prev;\n };\n};\n\nexport default registerAdminPanelRoute;\n"],"names":["registerAdminPanelRoute","strapi","buildDir","resolve","dirs","dist","root","fse","pathExistsSync","__dirname","serveAdminMiddleware","ctx","next","method","body","status","type","createReadStream","join","server","routes","path","config","admin","handler","serveStatic","maxage","defer","index","setHeaders","res","ext","extname","setHeader","auth","filesDir","koaStaticOptions","serve","koaStatic","prev","newPath","basename"],"mappings":";;;;;;AAMA,MAAMA,uBAA0B,GAAA,CAAC,EAAEC,MAAM,EAA2B,GAAA;IAClE,IAAIC,QAAAA,GAAWC,aAAQF,MAAOG,CAAAA,IAAI,CAACC,IAAI,CAACC,IAAI,EAAE,OAAA,CAAA;AAE9C,IAAA,IAAI,CAACC,GAAAA,CAAIC,cAAc,CAACN,QAAW,CAAA,EAAA;AACjCA,QAAAA,QAAAA,GAAWC,aAAQM,SAAW,EAAA,aAAA,CAAA;AAChC;IAEA,MAAMC,oBAAAA,GAAuB,OAAOC,GAAcC,EAAAA,IAAAA,GAAAA;QAChD,MAAMA,IAAAA,EAAAA;AAEN,QAAA,IAAID,IAAIE,MAAM,KAAK,UAAUF,GAAIE,CAAAA,MAAM,KAAK,KAAO,EAAA;AACjD,YAAA;AACF;AAEA,QAAA,IAAIF,IAAIG,IAAI,IAAI,QAAQH,GAAII,CAAAA,MAAM,KAAK,GAAK,EAAA;AAC1C,YAAA;AACF;AAEAJ,QAAAA,GAAAA,CAAIK,IAAI,GAAG,MAAA;AACXL,QAAAA,GAAAA,CAAIG,IAAI,GAAGP,GAAAA,CAAIU,gBAAgB,CAACC,UAAKhB,QAAU,EAAA,YAAA,CAAA,CAAA;AACjD,KAAA;IAEAD,MAAOkB,CAAAA,MAAM,CAACC,MAAM,CAAC;AACnB,QAAA;YACEP,MAAQ,EAAA,KAAA;YACRQ,IAAM,EAAA,CAAC,EAAEpB,MAAAA,CAAOqB,MAAM,CAACC,KAAK,CAACF,IAAI,CAAC,OAAO,CAAC;YAC1CG,OAAS,EAAA;AACPd,gBAAAA,oBAAAA;AACAe,gBAAAA,WAAAA,CAAYvB,QAAU,EAAA;oBACpBwB,MAAQ,EAAA,QAAA;oBACRC,KAAO,EAAA,KAAA;oBACPC,KAAO,EAAA,YAAA;oBACPC,UAAWC,CAAAA,CAAAA,GAAQ,EAAET,MAAS,EAAA;AAC5B,wBAAA,MAAMU,MAAMC,YAAQX,CAAAA,MAAAA,CAAAA;;AAEpB,wBAAA,IAAIU,QAAQ,OAAS,EAAA;4BACnBD,GAAIG,CAAAA,SAAS,CAAC,eAAiB,EAAA,qCAAA,CAAA;AACjC;AACF;AACF,iBAAA;AACD,aAAA;YACDX,MAAQ,EAAA;gBAAEY,IAAM,EAAA;AAAM;AACxB;AACD,KAAA,CAAA;AACH;AAEA;AACA,MAAMT,WAAc,GAAA,CAACU,QAAeC,EAAAA,gBAAAA,GAAmB,EAAE,GAAA;IACvD,MAAMC,KAAAA,GAAQC,UAAUH,QAAUC,EAAAA,gBAAAA,CAAAA;AAElC,IAAA,OAAO,OAAOzB,GAAcC,EAAAA,IAAAA,GAAAA;QAC1B,MAAM2B,IAAAA,GAAO5B,IAAIU,IAAI;QACrB,MAAMmB,OAAAA,GAAUC,aAAS9B,CAAAA,GAAAA,CAAIU,IAAI,CAAA;AAEjCV,QAAAA,GAAAA,CAAIU,IAAI,GAAGmB,OAAAA;AACX,QAAA,MAAMH,MAAM1B,GAAK,EAAA,UAAA;AACfA,YAAAA,GAAAA,CAAIU,IAAI,GAAGkB,IAAAA;YACX,MAAM3B,IAAAA,EAAAA;AACND,YAAAA,GAAAA,CAAIU,IAAI,GAAGmB,OAAAA;AACb,SAAA,CAAA;AACA7B,QAAAA,GAAAA,CAAIU,IAAI,GAAGkB,IAAAA;AACb,KAAA;AACF,CAAA;;;;"}
1
+ {"version":3,"file":"serve-admin-panel.js","sources":["../../../../../server/src/routes/serve-admin-panel.ts"],"sourcesContent":["import type { Context, Next } from 'koa';\nimport { resolve, join, extname, basename } from 'path';\nimport fse from 'fs-extra';\nimport koaStatic from 'koa-static';\nimport type { Core } from '@strapi/types';\n\nconst registerAdminPanelRoute = ({ strapi }: { strapi: Core.Strapi }) => {\n let buildDir = resolve(strapi.dirs.dist.root, 'build');\n\n if (!fse.pathExistsSync(buildDir)) {\n buildDir = resolve(__dirname, '../../build');\n }\n\n const serveAdminMiddleware = async (ctx: Context, next: Next) => {\n await next();\n\n if (ctx.method !== 'HEAD' && ctx.method !== 'GET') {\n return;\n }\n\n if (ctx.body != null || ctx.status !== 404) {\n return;\n }\n\n ctx.type = 'html';\n ctx.body = fse.createReadStream(join(buildDir, 'index.html'));\n };\n\n strapi.server.routes([\n {\n method: 'GET',\n path: `${strapi.config.admin.path}/:path*`,\n handler: [\n serveAdminMiddleware,\n serveStatic(buildDir, {\n maxage: 31536000,\n defer: false,\n index: 'index.html',\n setHeaders(res: any, path: any) {\n const ext = extname(path);\n // publicly cache static files to avoid unnecessary network & disk access\n if (ext !== '.html') {\n res.setHeader('cache-control', 'public, max-age=31536000, immutable');\n }\n },\n }),\n ],\n config: { auth: false },\n },\n ]);\n};\n\n// serveStatic is not supposed to be used to serve a folder that have sub-folders\nconst serveStatic = (filesDir: any, koaStaticOptions = {}) => {\n const serve = koaStatic(filesDir, koaStaticOptions);\n\n return async (ctx: Context, next: Next) => {\n const prev = ctx.path;\n const newPath = basename(ctx.path);\n\n ctx.path = newPath;\n await serve(ctx, async () => {\n ctx.path = prev;\n await next();\n ctx.path = newPath;\n });\n ctx.path = prev;\n };\n};\n\nexport default registerAdminPanelRoute;\n"],"names":["registerAdminPanelRoute","strapi","buildDir","resolve","dirs","dist","root","fse","pathExistsSync","__dirname","serveAdminMiddleware","ctx","next","method","body","status","type","createReadStream","join","server","routes","path","config","admin","handler","serveStatic","maxage","defer","index","setHeaders","res","ext","extname","setHeader","auth","filesDir","koaStaticOptions","serve","koaStatic","prev","newPath","basename"],"mappings":";;;;;;AAMA,MAAMA,uBAA0B,GAAA,CAAC,EAAEC,MAAM,EAA2B,GAAA;IAClE,IAAIC,QAAAA,GAAWC,aAAQF,MAAOG,CAAAA,IAAI,CAACC,IAAI,CAACC,IAAI,EAAE,OAAA,CAAA;AAE9C,IAAA,IAAI,CAACC,GAAAA,CAAIC,cAAc,CAACN,QAAW,CAAA,EAAA;AACjCA,QAAAA,QAAAA,GAAWC,aAAQM,SAAW,EAAA,aAAA,CAAA;AAChC;IAEA,MAAMC,oBAAAA,GAAuB,OAAOC,GAAcC,EAAAA,IAAAA,GAAAA;QAChD,MAAMA,IAAAA,EAAAA;AAEN,QAAA,IAAID,IAAIE,MAAM,KAAK,UAAUF,GAAIE,CAAAA,MAAM,KAAK,KAAO,EAAA;AACjD,YAAA;AACF;AAEA,QAAA,IAAIF,IAAIG,IAAI,IAAI,QAAQH,GAAII,CAAAA,MAAM,KAAK,GAAK,EAAA;AAC1C,YAAA;AACF;AAEAJ,QAAAA,GAAAA,CAAIK,IAAI,GAAG,MAAA;AACXL,QAAAA,GAAAA,CAAIG,IAAI,GAAGP,GAAAA,CAAIU,gBAAgB,CAACC,UAAKhB,QAAU,EAAA,YAAA,CAAA,CAAA;AACjD,KAAA;IAEAD,MAAOkB,CAAAA,MAAM,CAACC,MAAM,CAAC;AACnB,QAAA;YACEP,MAAQ,EAAA,KAAA;YACRQ,IAAM,EAAA,CAAA,EAAGpB,OAAOqB,MAAM,CAACC,KAAK,CAACF,IAAI,CAAC,OAAO,CAAC;YAC1CG,OAAS,EAAA;AACPd,gBAAAA,oBAAAA;AACAe,gBAAAA,WAAAA,CAAYvB,QAAU,EAAA;oBACpBwB,MAAQ,EAAA,QAAA;oBACRC,KAAO,EAAA,KAAA;oBACPC,KAAO,EAAA,YAAA;oBACPC,UAAWC,CAAAA,CAAAA,GAAQ,EAAET,MAAS,EAAA;AAC5B,wBAAA,MAAMU,MAAMC,YAAQX,CAAAA,MAAAA,CAAAA;;AAEpB,wBAAA,IAAIU,QAAQ,OAAS,EAAA;4BACnBD,GAAIG,CAAAA,SAAS,CAAC,eAAiB,EAAA,qCAAA,CAAA;AACjC;AACF;AACF,iBAAA;AACD,aAAA;YACDX,MAAQ,EAAA;gBAAEY,IAAM,EAAA;AAAM;AACxB;AACD,KAAA,CAAA;AACH;AAEA;AACA,MAAMT,WAAc,GAAA,CAACU,QAAeC,EAAAA,gBAAAA,GAAmB,EAAE,GAAA;IACvD,MAAMC,KAAAA,GAAQC,UAAUH,QAAUC,EAAAA,gBAAAA,CAAAA;AAElC,IAAA,OAAO,OAAOzB,GAAcC,EAAAA,IAAAA,GAAAA;QAC1B,MAAM2B,IAAAA,GAAO5B,IAAIU,IAAI;QACrB,MAAMmB,OAAAA,GAAUC,aAAS9B,CAAAA,GAAAA,CAAIU,IAAI,CAAA;AAEjCV,QAAAA,GAAAA,CAAIU,IAAI,GAAGmB,OAAAA;AACX,QAAA,MAAMH,MAAM1B,GAAK,EAAA,UAAA;AACfA,YAAAA,GAAAA,CAAIU,IAAI,GAAGkB,IAAAA;YACX,MAAM3B,IAAAA,EAAAA;AACND,YAAAA,GAAAA,CAAIU,IAAI,GAAGmB,OAAAA;AACb,SAAA,CAAA;AACA7B,QAAAA,GAAAA,CAAIU,IAAI,GAAGkB,IAAAA;AACb,KAAA;AACF,CAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"serve-admin-panel.mjs","sources":["../../../../../server/src/routes/serve-admin-panel.ts"],"sourcesContent":["import type { Context, Next } from 'koa';\nimport { resolve, join, extname, basename } from 'path';\nimport fse from 'fs-extra';\nimport koaStatic from 'koa-static';\nimport type { Core } from '@strapi/types';\n\nconst registerAdminPanelRoute = ({ strapi }: { strapi: Core.Strapi }) => {\n let buildDir = resolve(strapi.dirs.dist.root, 'build');\n\n if (!fse.pathExistsSync(buildDir)) {\n buildDir = resolve(__dirname, '../../build');\n }\n\n const serveAdminMiddleware = async (ctx: Context, next: Next) => {\n await next();\n\n if (ctx.method !== 'HEAD' && ctx.method !== 'GET') {\n return;\n }\n\n if (ctx.body != null || ctx.status !== 404) {\n return;\n }\n\n ctx.type = 'html';\n ctx.body = fse.createReadStream(join(buildDir, 'index.html'));\n };\n\n strapi.server.routes([\n {\n method: 'GET',\n path: `${strapi.config.admin.path}/:path*`,\n handler: [\n serveAdminMiddleware,\n serveStatic(buildDir, {\n maxage: 31536000,\n defer: false,\n index: 'index.html',\n setHeaders(res: any, path: any) {\n const ext = extname(path);\n // publicly cache static files to avoid unnecessary network & disk access\n if (ext !== '.html') {\n res.setHeader('cache-control', 'public, max-age=31536000, immutable');\n }\n },\n }),\n ],\n config: { auth: false },\n },\n ]);\n};\n\n// serveStatic is not supposed to be used to serve a folder that have sub-folders\nconst serveStatic = (filesDir: any, koaStaticOptions = {}) => {\n const serve = koaStatic(filesDir, koaStaticOptions);\n\n return async (ctx: Context, next: Next) => {\n const prev = ctx.path;\n const newPath = basename(ctx.path);\n\n ctx.path = newPath;\n await serve(ctx, async () => {\n ctx.path = prev;\n await next();\n ctx.path = newPath;\n });\n ctx.path = prev;\n };\n};\n\nexport default registerAdminPanelRoute;\n"],"names":["registerAdminPanelRoute","strapi","buildDir","resolve","dirs","dist","root","fse","pathExistsSync","__dirname","serveAdminMiddleware","ctx","next","method","body","status","type","createReadStream","join","server","routes","path","config","admin","handler","serveStatic","maxage","defer","index","setHeaders","res","ext","extname","setHeader","auth","filesDir","koaStaticOptions","serve","koaStatic","prev","newPath","basename"],"mappings":";;;;AAMA,MAAMA,uBAA0B,GAAA,CAAC,EAAEC,MAAM,EAA2B,GAAA;IAClE,IAAIC,QAAAA,GAAWC,QAAQF,MAAOG,CAAAA,IAAI,CAACC,IAAI,CAACC,IAAI,EAAE,OAAA,CAAA;AAE9C,IAAA,IAAI,CAACC,GAAAA,CAAIC,cAAc,CAACN,QAAW,CAAA,EAAA;AACjCA,QAAAA,QAAAA,GAAWC,QAAQM,SAAW,EAAA,aAAA,CAAA;AAChC;IAEA,MAAMC,oBAAAA,GAAuB,OAAOC,GAAcC,EAAAA,IAAAA,GAAAA;QAChD,MAAMA,IAAAA,EAAAA;AAEN,QAAA,IAAID,IAAIE,MAAM,KAAK,UAAUF,GAAIE,CAAAA,MAAM,KAAK,KAAO,EAAA;AACjD,YAAA;AACF;AAEA,QAAA,IAAIF,IAAIG,IAAI,IAAI,QAAQH,GAAII,CAAAA,MAAM,KAAK,GAAK,EAAA;AAC1C,YAAA;AACF;AAEAJ,QAAAA,GAAAA,CAAIK,IAAI,GAAG,MAAA;AACXL,QAAAA,GAAAA,CAAIG,IAAI,GAAGP,GAAAA,CAAIU,gBAAgB,CAACC,KAAKhB,QAAU,EAAA,YAAA,CAAA,CAAA;AACjD,KAAA;IAEAD,MAAOkB,CAAAA,MAAM,CAACC,MAAM,CAAC;AACnB,QAAA;YACEP,MAAQ,EAAA,KAAA;YACRQ,IAAM,EAAA,CAAC,EAAEpB,MAAAA,CAAOqB,MAAM,CAACC,KAAK,CAACF,IAAI,CAAC,OAAO,CAAC;YAC1CG,OAAS,EAAA;AACPd,gBAAAA,oBAAAA;AACAe,gBAAAA,WAAAA,CAAYvB,QAAU,EAAA;oBACpBwB,MAAQ,EAAA,QAAA;oBACRC,KAAO,EAAA,KAAA;oBACPC,KAAO,EAAA,YAAA;oBACPC,UAAWC,CAAAA,CAAAA,GAAQ,EAAET,IAAS,EAAA;AAC5B,wBAAA,MAAMU,MAAMC,OAAQX,CAAAA,IAAAA,CAAAA;;AAEpB,wBAAA,IAAIU,QAAQ,OAAS,EAAA;4BACnBD,GAAIG,CAAAA,SAAS,CAAC,eAAiB,EAAA,qCAAA,CAAA;AACjC;AACF;AACF,iBAAA;AACD,aAAA;YACDX,MAAQ,EAAA;gBAAEY,IAAM,EAAA;AAAM;AACxB;AACD,KAAA,CAAA;AACH;AAEA;AACA,MAAMT,WAAc,GAAA,CAACU,QAAeC,EAAAA,gBAAAA,GAAmB,EAAE,GAAA;IACvD,MAAMC,KAAAA,GAAQC,UAAUH,QAAUC,EAAAA,gBAAAA,CAAAA;AAElC,IAAA,OAAO,OAAOzB,GAAcC,EAAAA,IAAAA,GAAAA;QAC1B,MAAM2B,IAAAA,GAAO5B,IAAIU,IAAI;QACrB,MAAMmB,OAAAA,GAAUC,QAAS9B,CAAAA,GAAAA,CAAIU,IAAI,CAAA;AAEjCV,QAAAA,GAAAA,CAAIU,IAAI,GAAGmB,OAAAA;AACX,QAAA,MAAMH,MAAM1B,GAAK,EAAA,UAAA;AACfA,YAAAA,GAAAA,CAAIU,IAAI,GAAGkB,IAAAA;YACX,MAAM3B,IAAAA,EAAAA;AACND,YAAAA,GAAAA,CAAIU,IAAI,GAAGmB,OAAAA;AACb,SAAA,CAAA;AACA7B,QAAAA,GAAAA,CAAIU,IAAI,GAAGkB,IAAAA;AACb,KAAA;AACF,CAAA;;;;"}
1
+ {"version":3,"file":"serve-admin-panel.mjs","sources":["../../../../../server/src/routes/serve-admin-panel.ts"],"sourcesContent":["import type { Context, Next } from 'koa';\nimport { resolve, join, extname, basename } from 'path';\nimport fse from 'fs-extra';\nimport koaStatic from 'koa-static';\nimport type { Core } from '@strapi/types';\n\nconst registerAdminPanelRoute = ({ strapi }: { strapi: Core.Strapi }) => {\n let buildDir = resolve(strapi.dirs.dist.root, 'build');\n\n if (!fse.pathExistsSync(buildDir)) {\n buildDir = resolve(__dirname, '../../build');\n }\n\n const serveAdminMiddleware = async (ctx: Context, next: Next) => {\n await next();\n\n if (ctx.method !== 'HEAD' && ctx.method !== 'GET') {\n return;\n }\n\n if (ctx.body != null || ctx.status !== 404) {\n return;\n }\n\n ctx.type = 'html';\n ctx.body = fse.createReadStream(join(buildDir, 'index.html'));\n };\n\n strapi.server.routes([\n {\n method: 'GET',\n path: `${strapi.config.admin.path}/:path*`,\n handler: [\n serveAdminMiddleware,\n serveStatic(buildDir, {\n maxage: 31536000,\n defer: false,\n index: 'index.html',\n setHeaders(res: any, path: any) {\n const ext = extname(path);\n // publicly cache static files to avoid unnecessary network & disk access\n if (ext !== '.html') {\n res.setHeader('cache-control', 'public, max-age=31536000, immutable');\n }\n },\n }),\n ],\n config: { auth: false },\n },\n ]);\n};\n\n// serveStatic is not supposed to be used to serve a folder that have sub-folders\nconst serveStatic = (filesDir: any, koaStaticOptions = {}) => {\n const serve = koaStatic(filesDir, koaStaticOptions);\n\n return async (ctx: Context, next: Next) => {\n const prev = ctx.path;\n const newPath = basename(ctx.path);\n\n ctx.path = newPath;\n await serve(ctx, async () => {\n ctx.path = prev;\n await next();\n ctx.path = newPath;\n });\n ctx.path = prev;\n };\n};\n\nexport default registerAdminPanelRoute;\n"],"names":["registerAdminPanelRoute","strapi","buildDir","resolve","dirs","dist","root","fse","pathExistsSync","__dirname","serveAdminMiddleware","ctx","next","method","body","status","type","createReadStream","join","server","routes","path","config","admin","handler","serveStatic","maxage","defer","index","setHeaders","res","ext","extname","setHeader","auth","filesDir","koaStaticOptions","serve","koaStatic","prev","newPath","basename"],"mappings":";;;;AAMA,MAAMA,uBAA0B,GAAA,CAAC,EAAEC,MAAM,EAA2B,GAAA;IAClE,IAAIC,QAAAA,GAAWC,QAAQF,MAAOG,CAAAA,IAAI,CAACC,IAAI,CAACC,IAAI,EAAE,OAAA,CAAA;AAE9C,IAAA,IAAI,CAACC,GAAAA,CAAIC,cAAc,CAACN,QAAW,CAAA,EAAA;AACjCA,QAAAA,QAAAA,GAAWC,QAAQM,SAAW,EAAA,aAAA,CAAA;AAChC;IAEA,MAAMC,oBAAAA,GAAuB,OAAOC,GAAcC,EAAAA,IAAAA,GAAAA;QAChD,MAAMA,IAAAA,EAAAA;AAEN,QAAA,IAAID,IAAIE,MAAM,KAAK,UAAUF,GAAIE,CAAAA,MAAM,KAAK,KAAO,EAAA;AACjD,YAAA;AACF;AAEA,QAAA,IAAIF,IAAIG,IAAI,IAAI,QAAQH,GAAII,CAAAA,MAAM,KAAK,GAAK,EAAA;AAC1C,YAAA;AACF;AAEAJ,QAAAA,GAAAA,CAAIK,IAAI,GAAG,MAAA;AACXL,QAAAA,GAAAA,CAAIG,IAAI,GAAGP,GAAAA,CAAIU,gBAAgB,CAACC,KAAKhB,QAAU,EAAA,YAAA,CAAA,CAAA;AACjD,KAAA;IAEAD,MAAOkB,CAAAA,MAAM,CAACC,MAAM,CAAC;AACnB,QAAA;YACEP,MAAQ,EAAA,KAAA;YACRQ,IAAM,EAAA,CAAA,EAAGpB,OAAOqB,MAAM,CAACC,KAAK,CAACF,IAAI,CAAC,OAAO,CAAC;YAC1CG,OAAS,EAAA;AACPd,gBAAAA,oBAAAA;AACAe,gBAAAA,WAAAA,CAAYvB,QAAU,EAAA;oBACpBwB,MAAQ,EAAA,QAAA;oBACRC,KAAO,EAAA,KAAA;oBACPC,KAAO,EAAA,YAAA;oBACPC,UAAWC,CAAAA,CAAAA,GAAQ,EAAET,IAAS,EAAA;AAC5B,wBAAA,MAAMU,MAAMC,OAAQX,CAAAA,IAAAA,CAAAA;;AAEpB,wBAAA,IAAIU,QAAQ,OAAS,EAAA;4BACnBD,GAAIG,CAAAA,SAAS,CAAC,eAAiB,EAAA,qCAAA,CAAA;AACjC;AACF;AACF,iBAAA;AACD,aAAA;YACDX,MAAQ,EAAA;gBAAEY,IAAM,EAAA;AAAM;AACxB;AACD,KAAA,CAAA;AACH;AAEA;AACA,MAAMT,WAAc,GAAA,CAACU,QAAeC,EAAAA,gBAAAA,GAAmB,EAAE,GAAA;IACvD,MAAMC,KAAAA,GAAQC,UAAUH,QAAUC,EAAAA,gBAAAA,CAAAA;AAElC,IAAA,OAAO,OAAOzB,GAAcC,EAAAA,IAAAA,GAAAA;QAC1B,MAAM2B,IAAAA,GAAO5B,IAAIU,IAAI;QACrB,MAAMmB,OAAAA,GAAUC,QAAS9B,CAAAA,GAAAA,CAAIU,IAAI,CAAA;AAEjCV,QAAAA,GAAAA,CAAIU,IAAI,GAAGmB,OAAAA;AACX,QAAA,MAAMH,MAAM1B,GAAK,EAAA,UAAA;AACfA,YAAAA,GAAAA,CAAIU,IAAI,GAAGkB,IAAAA;YACX,MAAM3B,IAAAA,EAAAA;AACND,YAAAA,GAAAA,CAAIU,IAAI,GAAGmB,OAAAA;AACb,SAAA,CAAA;AACA7B,QAAAA,GAAAA,CAAIU,IAAI,GAAGkB,IAAAA;AACb,KAAA;AACF,CAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"api-token.js","sources":["../../../../../server/src/services/api-token.ts"],"sourcesContent":["import crypto from 'crypto';\nimport { omit, difference, isNil, isEmpty, map, isArray, uniq, isNumber } from 'lodash/fp';\nimport { errors } from '@strapi/utils';\nimport type { Update, ApiToken, ApiTokenBody } from '../../../shared/contracts/api-token';\nimport constants from './constants';\nimport { getService } from '../utils';\n\nconst { ValidationError, NotFoundError } = errors;\n\ntype ApiTokenPermission = {\n id: number | `${number}`;\n action: string;\n token: DBApiToken | number;\n};\n\ntype DBApiToken = ApiToken & {\n permissions: (number | ApiTokenPermission)[];\n};\n\nconst SELECT_FIELDS = [\n 'id',\n 'name',\n 'description',\n 'lastUsedAt',\n 'type',\n 'lifespan',\n 'expiresAt',\n 'createdAt',\n 'updatedAt',\n];\n\nconst POPULATE_FIELDS = ['permissions'];\n\n// TODO: we need to ensure the permissions are actually valid registered permissions!\n\n/**\n * Assert that a token's permissions attribute is valid for its type\n */\nconst assertCustomTokenPermissionsValidity = (\n type: ApiTokenBody['type'],\n permissions: ApiTokenBody['permissions']\n) => {\n // Ensure non-custom tokens doesn't have permissions\n if (type !== constants.API_TOKEN_TYPE.CUSTOM && !isEmpty(permissions)) {\n throw new ValidationError('Non-custom tokens should not reference permissions');\n }\n\n // Custom type tokens should always have permissions attached to them\n if (type === constants.API_TOKEN_TYPE.CUSTOM && !isArray(permissions)) {\n throw new ValidationError('Missing permissions attribute for custom token');\n }\n\n // Permissions provided for a custom type token should be valid/registered permissions UID\n if (type === constants.API_TOKEN_TYPE.CUSTOM) {\n const validPermissions = strapi.contentAPI.permissions.providers.action.keys();\n const invalidPermissions = difference(permissions, validPermissions) as string[];\n\n if (!isEmpty(invalidPermissions)) {\n throw new ValidationError(`Unknown permissions provided: ${invalidPermissions.join(', ')}`);\n }\n }\n};\n\n/**\n * Check if a token's lifespan is valid\n */\nconst isValidLifespan = (lifespan: unknown) => {\n if (isNil(lifespan)) {\n return true;\n }\n\n if (!isNumber(lifespan) || !Object.values(constants.API_TOKEN_LIFESPANS).includes(lifespan)) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Assert that a token's lifespan is valid\n */\nconst assertValidLifespan = (lifespan: unknown) => {\n if (!isValidLifespan(lifespan)) {\n throw new ValidationError(\n `lifespan must be one of the following values:\n ${Object.values(constants.API_TOKEN_LIFESPANS).join(', ')}`\n );\n }\n};\n\n/**\n * Flatten a token's database permissions objects to an array of strings\n */\nconst flattenTokenPermissions = (token: DBApiToken): ApiToken => {\n if (!token) {\n return token;\n }\n\n return {\n ...token,\n permissions: isArray(token.permissions) ? map('action', token.permissions) : token.permissions,\n };\n};\n\ntype WhereParams = {\n id?: string | number;\n name?: string;\n lastUsedAt?: number;\n description?: string;\n accessKey?: string;\n};\n\n/**\n * Get a token\n */\nconst getBy = async (whereParams: WhereParams = {}): Promise<ApiToken | null> => {\n if (Object.keys(whereParams).length === 0) {\n return null;\n }\n\n const token = await strapi.db.query('admin::api-token').findOne({\n select: [...SELECT_FIELDS, 'encryptedKey'],\n populate: POPULATE_FIELDS,\n where: whereParams,\n });\n\n if (!token) {\n return token;\n }\n\n const { encryptedKey, ...rest } = token;\n\n if (!encryptedKey) {\n return flattenTokenPermissions(rest);\n }\n\n const accessKey = getService('encryption').decrypt(encryptedKey);\n\n return flattenTokenPermissions({\n ...rest,\n accessKey,\n });\n};\n\n/**\n * Check if token exists\n */\nconst exists = async (whereParams: WhereParams = {}): Promise<boolean> => {\n const apiToken = await getBy(whereParams);\n\n return !!apiToken;\n};\n\n/**\n * Return a secure sha512 hash of an accessKey\n */\nconst hash = (accessKey: string) => {\n return crypto\n .createHmac('sha512', strapi.config.get('admin.apiToken.salt'))\n .update(accessKey)\n .digest('hex');\n};\n\nconst getExpirationFields = (lifespan: ApiTokenBody['lifespan']) => {\n // it must be nil or a finite number >= 0\n const isValidNumber = isNumber(lifespan) && Number.isFinite(lifespan) && lifespan > 0;\n if (!isValidNumber && !isNil(lifespan)) {\n throw new ValidationError('lifespan must be a positive number or null');\n }\n\n return {\n lifespan: lifespan || null,\n expiresAt: lifespan ? Date.now() + lifespan : null,\n };\n};\n\n/**\n * Create a token and its permissions\n */\nconst create = async (attributes: ApiTokenBody): Promise<ApiToken> => {\n const encryptionService = getService('encryption');\n const accessKey = crypto.randomBytes(128).toString('hex');\n const encryptedKey = encryptionService.encrypt(accessKey);\n\n assertCustomTokenPermissionsValidity(attributes.type, attributes.permissions);\n assertValidLifespan(attributes.lifespan);\n\n // Create the token\n const apiToken: ApiToken = await strapi.db.query('admin::api-token').create({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n data: {\n ...omit('permissions', attributes),\n accessKey: hash(accessKey),\n encryptedKey,\n ...getExpirationFields(attributes.lifespan),\n },\n });\n\n const result: ApiToken = { ...apiToken, accessKey };\n\n // If this is a custom type token, create and the related permissions\n if (attributes.type === constants.API_TOKEN_TYPE.CUSTOM) {\n // TODO: createMany doesn't seem to create relation properly, implement a better way rather than a ton of queries\n // const permissionsCount = await strapi.db.query('admin::api-token-permission').createMany({\n // populate: POPULATE_FIELDS,\n // data: attributes.permissions.map(action => ({ action, token: apiToken })),\n // });\n await Promise.all(\n uniq(attributes.permissions).map((action) =>\n strapi.db.query('admin::api-token-permission').create({\n data: { action, token: apiToken },\n })\n )\n );\n\n const currentPermissions = await strapi.db\n .query('admin::api-token')\n .load(apiToken, 'permissions');\n\n if (currentPermissions) {\n Object.assign(result, { permissions: map('action', currentPermissions) });\n }\n }\n\n return result;\n};\n\nconst regenerate = async (id: string | number): Promise<ApiToken> => {\n const accessKey = crypto.randomBytes(128).toString('hex');\n const encryptionService = getService('encryption');\n const encryptedKey = encryptionService.encrypt(accessKey);\n\n const apiToken: ApiToken = await strapi.db.query('admin::api-token').update({\n select: ['id', 'accessKey'],\n where: { id },\n data: {\n accessKey: hash(accessKey),\n encryptedKey,\n },\n });\n\n if (!apiToken) {\n throw new NotFoundError('The provided token id does not exist');\n }\n\n return {\n ...apiToken,\n accessKey,\n };\n};\n\nconst checkSaltIsDefined = () => {\n if (!strapi.config.get('admin.apiToken.salt')) {\n // TODO V5: stop reading API_TOKEN_SALT\n if (process.env.API_TOKEN_SALT) {\n process.emitWarning(`[deprecated] In future versions, Strapi will stop reading directly from the environment variable API_TOKEN_SALT. Please set apiToken.salt in config/admin.js instead.\nFor security reasons, keep storing the secret in an environment variable and use env() to read it in config/admin.js (ex: \\`apiToken: { salt: env('API_TOKEN_SALT') }\\`). See https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.html#configuration-using-environment-variables.`);\n\n strapi.config.set('admin.apiToken.salt', process.env.API_TOKEN_SALT);\n } else {\n throw new Error(\n `Missing apiToken.salt. Please set apiToken.salt in config/admin.js (ex: you can generate one using Node with \\`crypto.randomBytes(16).toString('base64')\\`).\nFor security reasons, prefer storing the secret in an environment variable and read it in config/admin.js. See https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.html#configuration-using-environment-variables.`\n );\n }\n }\n};\n\n/**\n * Return a list of all tokens and their permissions\n */\nconst list = async (): Promise<Array<ApiToken>> => {\n const tokens: Array<DBApiToken> = await strapi.db.query('admin::api-token').findMany({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n orderBy: { name: 'ASC' },\n });\n\n if (!tokens) {\n return tokens;\n }\n\n return tokens.map((token) => flattenTokenPermissions(token));\n};\n\n/**\n * Revoke (delete) a token\n */\nconst revoke = async (id: string | number): Promise<ApiToken> => {\n return strapi.db\n .query('admin::api-token')\n .delete({ select: SELECT_FIELDS, populate: POPULATE_FIELDS, where: { id } });\n};\n\n/**\n * Retrieve a token by id\n */\nconst getById = async (id: string | number) => {\n return getBy({ id });\n};\n\n/**\n * Retrieve a token by name\n */\nconst getByName = async (name: string) => {\n return getBy({ name });\n};\n\n/**\n * Update a token and its permissions\n */\nconst update = async (\n id: string | number,\n attributes: Update.Request['body']\n): Promise<ApiToken> => {\n // retrieve token without permissions\n const originalToken: DBApiToken = await strapi.db\n .query('admin::api-token')\n .findOne({ where: { id } });\n\n if (!originalToken) {\n throw new NotFoundError('Token not found');\n }\n\n const changingTypeToCustom =\n attributes.type === constants.API_TOKEN_TYPE.CUSTOM &&\n originalToken.type !== constants.API_TOKEN_TYPE.CUSTOM;\n\n // if we're updating the permissions on any token type, or changing from non-custom to custom, ensure they're still valid\n // if neither type nor permissions are changing, we don't need to validate again or else we can't allow partial update\n if (attributes.permissions || changingTypeToCustom) {\n assertCustomTokenPermissionsValidity(\n attributes.type || originalToken.type,\n attributes.permissions || originalToken.permissions\n );\n }\n\n assertValidLifespan(attributes.lifespan);\n\n const updatedToken: ApiToken = await strapi.db.query('admin::api-token').update({\n select: SELECT_FIELDS,\n where: { id },\n data: omit('permissions', attributes),\n });\n\n // custom tokens need to have their permissions updated as well\n if (updatedToken.type === constants.API_TOKEN_TYPE.CUSTOM && attributes.permissions) {\n const currentPermissionsResult = await strapi.db\n .query('admin::api-token')\n .load(updatedToken, 'permissions');\n\n const currentPermissions = map('action', currentPermissionsResult || []);\n const newPermissions = uniq(attributes.permissions);\n\n const actionsToDelete = difference(currentPermissions, newPermissions);\n const actionsToAdd = difference(newPermissions, currentPermissions);\n\n // TODO: improve efficiency here\n // method using a loop -- works but very inefficient\n await Promise.all(\n actionsToDelete.map((action) =>\n strapi.db.query('admin::api-token-permission').delete({\n where: { action, token: id },\n })\n )\n );\n\n // TODO: improve efficiency here\n // using a loop -- works but very inefficient\n await Promise.all(\n actionsToAdd.map((action) =>\n strapi.db.query('admin::api-token-permission').create({\n data: { action, token: id },\n })\n )\n );\n }\n // if type is not custom, make sure any old permissions get removed\n else if (updatedToken.type !== constants.API_TOKEN_TYPE.CUSTOM) {\n await strapi.db.query('admin::api-token-permission').delete({\n where: { token: id },\n });\n }\n\n // retrieve permissions\n const permissionsFromDb = await strapi.db\n .query('admin::api-token')\n .load(updatedToken, 'permissions');\n\n return {\n ...updatedToken,\n permissions: permissionsFromDb ? permissionsFromDb.map((p: any) => p.action) : undefined,\n };\n};\n\nconst count = async (where = {}): Promise<number> => {\n return strapi.db.query('admin::api-token').count({ where });\n};\n\nexport {\n create,\n count,\n regenerate,\n exists,\n checkSaltIsDefined,\n hash,\n list,\n revoke,\n getById,\n update,\n getByName,\n getBy,\n};\n"],"names":["ValidationError","NotFoundError","errors","SELECT_FIELDS","POPULATE_FIELDS","assertCustomTokenPermissionsValidity","type","permissions","constants","API_TOKEN_TYPE","CUSTOM","isEmpty","isArray","validPermissions","strapi","contentAPI","providers","action","keys","invalidPermissions","difference","join","isValidLifespan","lifespan","isNil","isNumber","Object","values","API_TOKEN_LIFESPANS","includes","assertValidLifespan","flattenTokenPermissions","token","map","getBy","whereParams","length","db","query","findOne","select","populate","where","encryptedKey","rest","accessKey","getService","decrypt","exists","apiToken","hash","crypto","createHmac","config","get","update","digest","getExpirationFields","isValidNumber","Number","isFinite","expiresAt","Date","now","create","attributes","encryptionService","randomBytes","toString","encrypt","data","omit","result","Promise","all","uniq","currentPermissions","load","assign","regenerate","id","checkSaltIsDefined","process","env","API_TOKEN_SALT","emitWarning","set","Error","list","tokens","findMany","orderBy","name","revoke","delete","getById","getByName","originalToken","changingTypeToCustom","updatedToken","currentPermissionsResult","newPermissions","actionsToDelete","actionsToAdd","permissionsFromDb","p","undefined","count"],"mappings":"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"}
1
+ {"version":3,"file":"api-token.js","sources":["../../../../../server/src/services/api-token.ts"],"sourcesContent":["import crypto from 'crypto';\nimport { omit, difference, isNil, isEmpty, map, isArray, uniq, isNumber } from 'lodash/fp';\nimport { errors } from '@strapi/utils';\nimport type { Update, ApiToken, ApiTokenBody } from '../../../shared/contracts/api-token';\nimport constants from './constants';\nimport { getService } from '../utils';\n\nconst { ValidationError, NotFoundError } = errors;\n\ntype ApiTokenPermission = {\n id: number | `${number}`;\n action: string;\n token: DBApiToken | number;\n};\n\ntype DBApiToken = ApiToken & {\n permissions: (number | ApiTokenPermission)[];\n};\n\nconst SELECT_FIELDS = [\n 'id',\n 'name',\n 'description',\n 'lastUsedAt',\n 'type',\n 'lifespan',\n 'expiresAt',\n 'createdAt',\n 'updatedAt',\n];\n\nconst POPULATE_FIELDS = ['permissions'];\n\n// TODO: we need to ensure the permissions are actually valid registered permissions!\n\n/**\n * Assert that a token's permissions attribute is valid for its type\n */\nconst assertCustomTokenPermissionsValidity = (\n type: ApiTokenBody['type'],\n permissions: ApiTokenBody['permissions']\n) => {\n // Ensure non-custom tokens doesn't have permissions\n if (type !== constants.API_TOKEN_TYPE.CUSTOM && !isEmpty(permissions)) {\n throw new ValidationError('Non-custom tokens should not reference permissions');\n }\n\n // Custom type tokens should always have permissions attached to them\n if (type === constants.API_TOKEN_TYPE.CUSTOM && !isArray(permissions)) {\n throw new ValidationError('Missing permissions attribute for custom token');\n }\n\n // Permissions provided for a custom type token should be valid/registered permissions UID\n if (type === constants.API_TOKEN_TYPE.CUSTOM) {\n const validPermissions = strapi.contentAPI.permissions.providers.action.keys();\n const invalidPermissions = difference(permissions, validPermissions) as string[];\n\n if (!isEmpty(invalidPermissions)) {\n throw new ValidationError(`Unknown permissions provided: ${invalidPermissions.join(', ')}`);\n }\n }\n};\n\n/**\n * Check if a token's lifespan is valid\n */\nconst isValidLifespan = (lifespan: unknown) => {\n if (isNil(lifespan)) {\n return true;\n }\n\n if (!isNumber(lifespan) || !Object.values(constants.API_TOKEN_LIFESPANS).includes(lifespan)) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Assert that a token's lifespan is valid\n */\nconst assertValidLifespan = (lifespan: unknown) => {\n if (!isValidLifespan(lifespan)) {\n throw new ValidationError(\n `lifespan must be one of the following values:\n ${Object.values(constants.API_TOKEN_LIFESPANS).join(', ')}`\n );\n }\n};\n\n/**\n * Flatten a token's database permissions objects to an array of strings\n */\nconst flattenTokenPermissions = (token: DBApiToken): ApiToken => {\n if (!token) {\n return token;\n }\n\n return {\n ...token,\n permissions: isArray(token.permissions) ? map('action', token.permissions) : token.permissions,\n };\n};\n\ntype WhereParams = {\n id?: string | number;\n name?: string;\n lastUsedAt?: number;\n description?: string;\n accessKey?: string;\n};\n\n/**\n * Get a token\n */\nconst getBy = async (whereParams: WhereParams = {}): Promise<ApiToken | null> => {\n if (Object.keys(whereParams).length === 0) {\n return null;\n }\n\n const token = await strapi.db.query('admin::api-token').findOne({\n select: [...SELECT_FIELDS, 'encryptedKey'],\n populate: POPULATE_FIELDS,\n where: whereParams,\n });\n\n if (!token) {\n return token;\n }\n\n const { encryptedKey, ...rest } = token;\n\n if (!encryptedKey) {\n return flattenTokenPermissions(rest);\n }\n\n const accessKey = getService('encryption').decrypt(encryptedKey);\n\n return flattenTokenPermissions({\n ...rest,\n accessKey,\n });\n};\n\n/**\n * Check if token exists\n */\nconst exists = async (whereParams: WhereParams = {}): Promise<boolean> => {\n const apiToken = await getBy(whereParams);\n\n return !!apiToken;\n};\n\n/**\n * Return a secure sha512 hash of an accessKey\n */\nconst hash = (accessKey: string) => {\n return crypto\n .createHmac('sha512', strapi.config.get('admin.apiToken.salt'))\n .update(accessKey)\n .digest('hex');\n};\n\nconst getExpirationFields = (lifespan: ApiTokenBody['lifespan']) => {\n // it must be nil or a finite number >= 0\n const isValidNumber = isNumber(lifespan) && Number.isFinite(lifespan) && lifespan > 0;\n if (!isValidNumber && !isNil(lifespan)) {\n throw new ValidationError('lifespan must be a positive number or null');\n }\n\n return {\n lifespan: lifespan || null,\n expiresAt: lifespan ? Date.now() + lifespan : null,\n };\n};\n\n/**\n * Create a token and its permissions\n */\nconst create = async (attributes: ApiTokenBody): Promise<ApiToken> => {\n const encryptionService = getService('encryption');\n const accessKey = crypto.randomBytes(128).toString('hex');\n const encryptedKey = encryptionService.encrypt(accessKey);\n\n assertCustomTokenPermissionsValidity(attributes.type, attributes.permissions);\n assertValidLifespan(attributes.lifespan);\n\n // Create the token\n const apiToken: ApiToken = await strapi.db.query('admin::api-token').create({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n data: {\n ...omit('permissions', attributes),\n accessKey: hash(accessKey),\n encryptedKey,\n ...getExpirationFields(attributes.lifespan),\n },\n });\n\n const result: ApiToken = { ...apiToken, accessKey };\n\n // If this is a custom type token, create and the related permissions\n if (attributes.type === constants.API_TOKEN_TYPE.CUSTOM) {\n // TODO: createMany doesn't seem to create relation properly, implement a better way rather than a ton of queries\n // const permissionsCount = await strapi.db.query('admin::api-token-permission').createMany({\n // populate: POPULATE_FIELDS,\n // data: attributes.permissions.map(action => ({ action, token: apiToken })),\n // });\n await Promise.all(\n uniq(attributes.permissions).map((action) =>\n strapi.db.query('admin::api-token-permission').create({\n data: { action, token: apiToken },\n })\n )\n );\n\n const currentPermissions = await strapi.db\n .query('admin::api-token')\n .load(apiToken, 'permissions');\n\n if (currentPermissions) {\n Object.assign(result, { permissions: map('action', currentPermissions) });\n }\n }\n\n return result;\n};\n\nconst regenerate = async (id: string | number): Promise<ApiToken> => {\n const accessKey = crypto.randomBytes(128).toString('hex');\n const encryptionService = getService('encryption');\n const encryptedKey = encryptionService.encrypt(accessKey);\n\n const apiToken: ApiToken = await strapi.db.query('admin::api-token').update({\n select: ['id', 'accessKey'],\n where: { id },\n data: {\n accessKey: hash(accessKey),\n encryptedKey,\n },\n });\n\n if (!apiToken) {\n throw new NotFoundError('The provided token id does not exist');\n }\n\n return {\n ...apiToken,\n accessKey,\n };\n};\n\nconst checkSaltIsDefined = () => {\n if (!strapi.config.get('admin.apiToken.salt')) {\n // TODO V5: stop reading API_TOKEN_SALT\n if (process.env.API_TOKEN_SALT) {\n process.emitWarning(`[deprecated] In future versions, Strapi will stop reading directly from the environment variable API_TOKEN_SALT. Please set apiToken.salt in config/admin.js instead.\nFor security reasons, keep storing the secret in an environment variable and use env() to read it in config/admin.js (ex: \\`apiToken: { salt: env('API_TOKEN_SALT') }\\`). See https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.html#configuration-using-environment-variables.`);\n\n strapi.config.set('admin.apiToken.salt', process.env.API_TOKEN_SALT);\n } else {\n throw new Error(\n `Missing apiToken.salt. Please set apiToken.salt in config/admin.js (ex: you can generate one using Node with \\`crypto.randomBytes(16).toString('base64')\\`).\nFor security reasons, prefer storing the secret in an environment variable and read it in config/admin.js. See https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.html#configuration-using-environment-variables.`\n );\n }\n }\n};\n\n/**\n * Return a list of all tokens and their permissions\n */\nconst list = async (): Promise<Array<ApiToken>> => {\n const tokens: Array<DBApiToken> = await strapi.db.query('admin::api-token').findMany({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n orderBy: { name: 'ASC' },\n });\n\n if (!tokens) {\n return tokens;\n }\n\n return tokens.map((token) => flattenTokenPermissions(token));\n};\n\n/**\n * Revoke (delete) a token\n */\nconst revoke = async (id: string | number): Promise<ApiToken> => {\n return strapi.db\n .query('admin::api-token')\n .delete({ select: SELECT_FIELDS, populate: POPULATE_FIELDS, where: { id } });\n};\n\n/**\n * Retrieve a token by id\n */\nconst getById = async (id: string | number) => {\n return getBy({ id });\n};\n\n/**\n * Retrieve a token by name\n */\nconst getByName = async (name: string) => {\n return getBy({ name });\n};\n\n/**\n * Update a token and its permissions\n */\nconst update = async (\n id: string | number,\n attributes: Update.Request['body']\n): Promise<ApiToken> => {\n // retrieve token without permissions\n const originalToken: DBApiToken = await strapi.db\n .query('admin::api-token')\n .findOne({ where: { id } });\n\n if (!originalToken) {\n throw new NotFoundError('Token not found');\n }\n\n const changingTypeToCustom =\n attributes.type === constants.API_TOKEN_TYPE.CUSTOM &&\n originalToken.type !== constants.API_TOKEN_TYPE.CUSTOM;\n\n // if we're updating the permissions on any token type, or changing from non-custom to custom, ensure they're still valid\n // if neither type nor permissions are changing, we don't need to validate again or else we can't allow partial update\n if (attributes.permissions || changingTypeToCustom) {\n assertCustomTokenPermissionsValidity(\n attributes.type || originalToken.type,\n attributes.permissions || originalToken.permissions\n );\n }\n\n assertValidLifespan(attributes.lifespan);\n\n const updatedToken: ApiToken = await strapi.db.query('admin::api-token').update({\n select: SELECT_FIELDS,\n where: { id },\n data: omit('permissions', attributes),\n });\n\n // custom tokens need to have their permissions updated as well\n if (updatedToken.type === constants.API_TOKEN_TYPE.CUSTOM && attributes.permissions) {\n const currentPermissionsResult = await strapi.db\n .query('admin::api-token')\n .load(updatedToken, 'permissions');\n\n const currentPermissions = map('action', currentPermissionsResult || []);\n const newPermissions = uniq(attributes.permissions);\n\n const actionsToDelete = difference(currentPermissions, newPermissions);\n const actionsToAdd = difference(newPermissions, currentPermissions);\n\n // TODO: improve efficiency here\n // method using a loop -- works but very inefficient\n await Promise.all(\n actionsToDelete.map((action) =>\n strapi.db.query('admin::api-token-permission').delete({\n where: { action, token: id },\n })\n )\n );\n\n // TODO: improve efficiency here\n // using a loop -- works but very inefficient\n await Promise.all(\n actionsToAdd.map((action) =>\n strapi.db.query('admin::api-token-permission').create({\n data: { action, token: id },\n })\n )\n );\n }\n // if type is not custom, make sure any old permissions get removed\n else if (updatedToken.type !== constants.API_TOKEN_TYPE.CUSTOM) {\n await strapi.db.query('admin::api-token-permission').delete({\n where: { token: id },\n });\n }\n\n // retrieve permissions\n const permissionsFromDb = await strapi.db\n .query('admin::api-token')\n .load(updatedToken, 'permissions');\n\n return {\n ...updatedToken,\n permissions: permissionsFromDb ? permissionsFromDb.map((p: any) => p.action) : undefined,\n };\n};\n\nconst count = async (where = {}): Promise<number> => {\n return strapi.db.query('admin::api-token').count({ where });\n};\n\nexport {\n create,\n count,\n regenerate,\n exists,\n checkSaltIsDefined,\n hash,\n list,\n revoke,\n getById,\n update,\n getByName,\n getBy,\n};\n"],"names":["ValidationError","NotFoundError","errors","SELECT_FIELDS","POPULATE_FIELDS","assertCustomTokenPermissionsValidity","type","permissions","constants","API_TOKEN_TYPE","CUSTOM","isEmpty","isArray","validPermissions","strapi","contentAPI","providers","action","keys","invalidPermissions","difference","join","isValidLifespan","lifespan","isNil","isNumber","Object","values","API_TOKEN_LIFESPANS","includes","assertValidLifespan","flattenTokenPermissions","token","map","getBy","whereParams","length","db","query","findOne","select","populate","where","encryptedKey","rest","accessKey","getService","decrypt","exists","apiToken","hash","crypto","createHmac","config","get","update","digest","getExpirationFields","isValidNumber","Number","isFinite","expiresAt","Date","now","create","attributes","encryptionService","randomBytes","toString","encrypt","data","omit","result","Promise","all","uniq","currentPermissions","load","assign","regenerate","id","checkSaltIsDefined","process","env","API_TOKEN_SALT","emitWarning","set","Error","list","tokens","findMany","orderBy","name","revoke","delete","getById","getByName","originalToken","changingTypeToCustom","updatedToken","currentPermissionsResult","newPermissions","actionsToDelete","actionsToAdd","permissionsFromDb","p","undefined","count"],"mappings":";;;;;;;;AAOA,MAAM,EAAEA,eAAe,EAAEC,aAAa,EAAE,GAAGC,YAAAA;AAY3C,MAAMC,aAAgB,GAAA;AACpB,IAAA,IAAA;AACA,IAAA,MAAA;AACA,IAAA,aAAA;AACA,IAAA,YAAA;AACA,IAAA,MAAA;AACA,IAAA,UAAA;AACA,IAAA,WAAA;AACA,IAAA,WAAA;AACA,IAAA;AACD,CAAA;AAED,MAAMC,eAAkB,GAAA;AAAC,IAAA;AAAc,CAAA;AAEvC;AAEA;;IAGA,MAAMC,oCAAuC,GAAA,CAC3CC,IACAC,EAAAA,WAAAA,GAAAA;;IAGA,IAAID,IAAAA,KAASE,UAAUC,cAAc,CAACC,MAAM,IAAI,CAACC,WAAQJ,WAAc,CAAA,EAAA;AACrE,QAAA,MAAM,IAAIP,eAAgB,CAAA,oDAAA,CAAA;AAC5B;;IAGA,IAAIM,IAAAA,KAASE,UAAUC,cAAc,CAACC,MAAM,IAAI,CAACE,WAAQL,WAAc,CAAA,EAAA;AACrE,QAAA,MAAM,IAAIP,eAAgB,CAAA,gDAAA,CAAA;AAC5B;;AAGA,IAAA,IAAIM,IAASE,KAAAA,SAAAA,CAAUC,cAAc,CAACC,MAAM,EAAE;QAC5C,MAAMG,gBAAAA,GAAmBC,MAAOC,CAAAA,UAAU,CAACR,WAAW,CAACS,SAAS,CAACC,MAAM,CAACC,IAAI,EAAA;QAC5E,MAAMC,kBAAAA,GAAqBC,cAAWb,WAAaM,EAAAA,gBAAAA,CAAAA;QAEnD,IAAI,CAACF,WAAQQ,kBAAqB,CAAA,EAAA;YAChC,MAAM,IAAInB,gBAAgB,CAAC,8BAA8B,EAAEmB,kBAAmBE,CAAAA,IAAI,CAAC,IAAO,CAAA,CAAA,CAAA,CAAA;AAC5F;AACF;AACF,CAAA;AAEA;;IAGA,MAAMC,kBAAkB,CAACC,QAAAA,GAAAA;AACvB,IAAA,IAAIC,SAAMD,QAAW,CAAA,EAAA;QACnB,OAAO,IAAA;AACT;AAEA,IAAA,IAAI,CAACE,WAAAA,CAASF,QAAa,CAAA,IAAA,CAACG,MAAOC,CAAAA,MAAM,CAACnB,SAAAA,CAAUoB,mBAAmB,CAAA,CAAEC,QAAQ,CAACN,QAAW,CAAA,EAAA;QAC3F,OAAO,KAAA;AACT;IAEA,OAAO,IAAA;AACT,CAAA;AAEA;;IAGA,MAAMO,sBAAsB,CAACP,QAAAA,GAAAA;IAC3B,IAAI,CAACD,gBAAgBC,QAAW,CAAA,EAAA;QAC9B,MAAM,IAAIvB,gBACR,CAAC;MACD,EAAE0B,MAAAA,CAAOC,MAAM,CAACnB,SAAAA,CAAUoB,mBAAmB,CAAEP,CAAAA,IAAI,CAAC,IAAO,CAAA,CAAA,CAAA,CAAA;AAE/D;AACF,CAAA;AAEA;;IAGA,MAAMU,0BAA0B,CAACC,KAAAA,GAAAA;AAC/B,IAAA,IAAI,CAACA,KAAO,EAAA;QACV,OAAOA,KAAAA;AACT;IAEA,OAAO;AACL,QAAA,GAAGA,KAAK;QACRzB,WAAaK,EAAAA,UAAAA,CAAQoB,KAAMzB,CAAAA,WAAW,CAAI0B,GAAAA,MAAAA,CAAI,UAAUD,KAAMzB,CAAAA,WAAW,CAAIyB,GAAAA,KAAAA,CAAMzB;AACrF,KAAA;AACF,CAAA;AAUA;;AAEC,IACK2B,MAAAA,KAAAA,GAAQ,OAAOC,WAAAA,GAA2B,EAAE,GAAA;AAChD,IAAA,IAAIT,OAAOR,IAAI,CAACiB,WAAaC,CAAAA,CAAAA,MAAM,KAAK,CAAG,EAAA;QACzC,OAAO,IAAA;AACT;IAEA,MAAMJ,KAAAA,GAAQ,MAAMlB,MAAOuB,CAAAA,EAAE,CAACC,KAAK,CAAC,kBAAoBC,CAAAA,CAAAA,OAAO,CAAC;QAC9DC,MAAQ,EAAA;AAAIrC,YAAAA,GAAAA,aAAAA;AAAe,YAAA;AAAe,SAAA;QAC1CsC,QAAUrC,EAAAA,eAAAA;QACVsC,KAAOP,EAAAA;AACT,KAAA,CAAA;AAEA,IAAA,IAAI,CAACH,KAAO,EAAA;QACV,OAAOA,KAAAA;AACT;AAEA,IAAA,MAAM,EAAEW,YAAY,EAAE,GAAGC,MAAM,GAAGZ,KAAAA;AAElC,IAAA,IAAI,CAACW,YAAc,EAAA;AACjB,QAAA,OAAOZ,uBAAwBa,CAAAA,IAAAA,CAAAA;AACjC;AAEA,IAAA,MAAMC,SAAYC,GAAAA,gBAAAA,CAAW,YAAcC,CAAAA,CAAAA,OAAO,CAACJ,YAAAA,CAAAA;AAEnD,IAAA,OAAOZ,uBAAwB,CAAA;AAC7B,QAAA,GAAGa,IAAI;AACPC,QAAAA;AACF,KAAA,CAAA;AACF;AAEA;;AAEC,IACKG,MAAAA,MAAAA,GAAS,OAAOb,WAAAA,GAA2B,EAAE,GAAA;IACjD,MAAMc,QAAAA,GAAW,MAAMf,KAAMC,CAAAA,WAAAA,CAAAA;AAE7B,IAAA,OAAO,CAAC,CAACc,QAAAA;AACX;AAEA;;IAGA,MAAMC,OAAO,CAACL,SAAAA,GAAAA;AACZ,IAAA,OAAOM,MACJC,CAAAA,UAAU,CAAC,QAAA,EAAUtC,OAAOuC,MAAM,CAACC,GAAG,CAAC,qBACvCC,CAAAA,CAAAA,CAAAA,MAAM,CAACV,SAAAA,CAAAA,CACPW,MAAM,CAAC,KAAA,CAAA;AACZ;AAEA,MAAMC,sBAAsB,CAAClC,QAAAA,GAAAA;;AAE3B,IAAA,MAAMmC,gBAAgBjC,WAASF,CAAAA,QAAAA,CAAAA,IAAaoC,OAAOC,QAAQ,CAACrC,aAAaA,QAAW,GAAA,CAAA;AACpF,IAAA,IAAI,CAACmC,aAAAA,IAAiB,CAAClC,QAAAA,CAAMD,QAAW,CAAA,EAAA;AACtC,QAAA,MAAM,IAAIvB,eAAgB,CAAA,4CAAA,CAAA;AAC5B;IAEA,OAAO;AACLuB,QAAAA,QAAAA,EAAUA,QAAY,IAAA,IAAA;AACtBsC,QAAAA,SAAAA,EAAWtC,QAAWuC,GAAAA,IAAAA,CAAKC,GAAG,EAAA,GAAKxC,QAAW,GAAA;AAChD,KAAA;AACF,CAAA;AAEA;;IAGA,MAAMyC,SAAS,OAAOC,UAAAA,GAAAA;AACpB,IAAA,MAAMC,oBAAoBpB,gBAAW,CAAA,YAAA,CAAA;AACrC,IAAA,MAAMD,YAAYM,MAAOgB,CAAAA,WAAW,CAAC,GAAA,CAAA,CAAKC,QAAQ,CAAC,KAAA,CAAA;IACnD,MAAMzB,YAAAA,GAAeuB,iBAAkBG,CAAAA,OAAO,CAACxB,SAAAA,CAAAA;AAE/CxC,IAAAA,oCAAAA,CAAqC4D,UAAW3D,CAAAA,IAAI,EAAE2D,UAAAA,CAAW1D,WAAW,CAAA;AAC5EuB,IAAAA,mBAAAA,CAAoBmC,WAAW1C,QAAQ,CAAA;;IAGvC,MAAM0B,QAAAA,GAAqB,MAAMnC,MAAOuB,CAAAA,EAAE,CAACC,KAAK,CAAC,kBAAoB0B,CAAAA,CAAAA,MAAM,CAAC;QAC1ExB,MAAQrC,EAAAA,aAAAA;QACRsC,QAAUrC,EAAAA,eAAAA;QACVkE,IAAM,EAAA;YACJ,GAAGC,OAAAA,CAAK,eAAeN,UAAW,CAAA;AAClCpB,YAAAA,SAAAA,EAAWK,IAAKL,CAAAA,SAAAA,CAAAA;AAChBF,YAAAA,YAAAA;YACA,GAAGc,mBAAAA,CAAoBQ,UAAW1C,CAAAA,QAAQ;AAC5C;AACF,KAAA,CAAA;AAEA,IAAA,MAAMiD,MAAmB,GAAA;AAAE,QAAA,GAAGvB,QAAQ;AAAEJ,QAAAA;AAAU,KAAA;;AAGlD,IAAA,IAAIoB,WAAW3D,IAAI,KAAKE,UAAUC,cAAc,CAACC,MAAM,EAAE;;;;;;AAMvD,QAAA,MAAM+D,QAAQC,GAAG,CACfC,QAAKV,UAAW1D,CAAAA,WAAW,EAAE0B,GAAG,CAAC,CAAChB,MAAAA,GAChCH,OAAOuB,EAAE,CAACC,KAAK,CAAC,6BAAA,CAAA,CAA+B0B,MAAM,CAAC;gBACpDM,IAAM,EAAA;AAAErD,oBAAAA,MAAAA;oBAAQe,KAAOiB,EAAAA;AAAS;AAClC,aAAA,CAAA,CAAA,CAAA;QAIJ,MAAM2B,kBAAAA,GAAqB,MAAM9D,MAAAA,CAAOuB,EAAE,CACvCC,KAAK,CAAC,kBAAA,CAAA,CACNuC,IAAI,CAAC5B,QAAU,EAAA,aAAA,CAAA;AAElB,QAAA,IAAI2B,kBAAoB,EAAA;YACtBlD,MAAOoD,CAAAA,MAAM,CAACN,MAAQ,EAAA;AAAEjE,gBAAAA,WAAAA,EAAa0B,OAAI,QAAU2C,EAAAA,kBAAAA;AAAoB,aAAA,CAAA;AACzE;AACF;IAEA,OAAOJ,MAAAA;AACT;AAEA,MAAMO,aAAa,OAAOC,EAAAA,GAAAA;AACxB,IAAA,MAAMnC,YAAYM,MAAOgB,CAAAA,WAAW,CAAC,GAAA,CAAA,CAAKC,QAAQ,CAAC,KAAA,CAAA;AACnD,IAAA,MAAMF,oBAAoBpB,gBAAW,CAAA,YAAA,CAAA;IACrC,MAAMH,YAAAA,GAAeuB,iBAAkBG,CAAAA,OAAO,CAACxB,SAAAA,CAAAA;IAE/C,MAAMI,QAAAA,GAAqB,MAAMnC,MAAOuB,CAAAA,EAAE,CAACC,KAAK,CAAC,kBAAoBiB,CAAAA,CAAAA,MAAM,CAAC;QAC1Ef,MAAQ,EAAA;AAAC,YAAA,IAAA;AAAM,YAAA;AAAY,SAAA;QAC3BE,KAAO,EAAA;AAAEsC,YAAAA;AAAG,SAAA;QACZV,IAAM,EAAA;AACJzB,YAAAA,SAAAA,EAAWK,IAAKL,CAAAA,SAAAA,CAAAA;AAChBF,YAAAA;AACF;AACF,KAAA,CAAA;AAEA,IAAA,IAAI,CAACM,QAAU,EAAA;AACb,QAAA,MAAM,IAAIhD,aAAc,CAAA,sCAAA,CAAA;AAC1B;IAEA,OAAO;AACL,QAAA,GAAGgD,QAAQ;AACXJ,QAAAA;AACF,KAAA;AACF;AAEA,MAAMoC,kBAAqB,GAAA,IAAA;AACzB,IAAA,IAAI,CAACnE,MAAOuC,CAAAA,MAAM,CAACC,GAAG,CAAC,qBAAwB,CAAA,EAAA;;AAE7C,QAAA,IAAI4B,OAAQC,CAAAA,GAAG,CAACC,cAAc,EAAE;YAC9BF,OAAQG,CAAAA,WAAW,CAAC,CAAC;sUAC2S,CAAC,CAAA;YAEjUvE,MAAOuC,CAAAA,MAAM,CAACiC,GAAG,CAAC,uBAAuBJ,OAAQC,CAAAA,GAAG,CAACC,cAAc,CAAA;SAC9D,MAAA;YACL,MAAM,IAAIG,MACR,CAAC;uQAC8P,CAAC,CAAA;AAEpQ;AACF;AACF;AAEA;;AAEC,UACKC,IAAO,GAAA,UAAA;IACX,MAAMC,MAAAA,GAA4B,MAAM3E,MAAOuB,CAAAA,EAAE,CAACC,KAAK,CAAC,kBAAoBoD,CAAAA,CAAAA,QAAQ,CAAC;QACnFlD,MAAQrC,EAAAA,aAAAA;QACRsC,QAAUrC,EAAAA,eAAAA;QACVuF,OAAS,EAAA;YAAEC,IAAM,EAAA;AAAM;AACzB,KAAA,CAAA;AAEA,IAAA,IAAI,CAACH,MAAQ,EAAA;QACX,OAAOA,MAAAA;AACT;AAEA,IAAA,OAAOA,MAAOxD,CAAAA,GAAG,CAAC,CAACD,QAAUD,uBAAwBC,CAAAA,KAAAA,CAAAA,CAAAA;AACvD;AAEA;;IAGA,MAAM6D,SAAS,OAAOb,EAAAA,GAAAA;AACpB,IAAA,OAAOlE,OAAOuB,EAAE,CACbC,KAAK,CAAC,kBAAA,CAAA,CACNwD,MAAM,CAAC;QAAEtD,MAAQrC,EAAAA,aAAAA;QAAesC,QAAUrC,EAAAA,eAAAA;QAAiBsC,KAAO,EAAA;AAAEsC,YAAAA;AAAG;AAAE,KAAA,CAAA;AAC9E;AAEA;;IAGA,MAAMe,UAAU,OAAOf,EAAAA,GAAAA;AACrB,IAAA,OAAO9C,KAAM,CAAA;AAAE8C,QAAAA;AAAG,KAAA,CAAA;AACpB;AAEA;;IAGA,MAAMgB,YAAY,OAAOJ,IAAAA,GAAAA;AACvB,IAAA,OAAO1D,KAAM,CAAA;AAAE0D,QAAAA;AAAK,KAAA,CAAA;AACtB;AAEA;;IAGA,MAAMrC,MAAS,GAAA,OACbyB,EACAf,EAAAA,UAAAA,GAAAA;;IAGA,MAAMgC,aAAAA,GAA4B,MAAMnF,MAAOuB,CAAAA,EAAE,CAC9CC,KAAK,CAAC,kBACNC,CAAAA,CAAAA,OAAO,CAAC;QAAEG,KAAO,EAAA;AAAEsC,YAAAA;AAAG;AAAE,KAAA,CAAA;AAE3B,IAAA,IAAI,CAACiB,aAAe,EAAA;AAClB,QAAA,MAAM,IAAIhG,aAAc,CAAA,iBAAA,CAAA;AAC1B;AAEA,IAAA,MAAMiG,oBACJjC,GAAAA,UAAAA,CAAW3D,IAAI,KAAKE,UAAUC,cAAc,CAACC,MAAM,IACnDuF,cAAc3F,IAAI,KAAKE,SAAUC,CAAAA,cAAc,CAACC,MAAM;;;IAIxD,IAAIuD,UAAAA,CAAW1D,WAAW,IAAI2F,oBAAsB,EAAA;QAClD7F,oCACE4D,CAAAA,UAAAA,CAAW3D,IAAI,IAAI2F,aAAc3F,CAAAA,IAAI,EACrC2D,UAAW1D,CAAAA,WAAW,IAAI0F,aAAAA,CAAc1F,WAAW,CAAA;AAEvD;AAEAuB,IAAAA,mBAAAA,CAAoBmC,WAAW1C,QAAQ,CAAA;IAEvC,MAAM4E,YAAAA,GAAyB,MAAMrF,MAAOuB,CAAAA,EAAE,CAACC,KAAK,CAAC,kBAAoBiB,CAAAA,CAAAA,MAAM,CAAC;QAC9Ef,MAAQrC,EAAAA,aAAAA;QACRuC,KAAO,EAAA;AAAEsC,YAAAA;AAAG,SAAA;AACZV,QAAAA,IAAAA,EAAMC,QAAK,aAAeN,EAAAA,UAAAA;AAC5B,KAAA,CAAA;;IAGA,IAAIkC,YAAAA,CAAa7F,IAAI,KAAKE,SAAUC,CAAAA,cAAc,CAACC,MAAM,IAAIuD,UAAW1D,CAAAA,WAAW,EAAE;QACnF,MAAM6F,wBAAAA,GAA2B,MAAMtF,MAAAA,CAAOuB,EAAE,CAC7CC,KAAK,CAAC,kBAAA,CAAA,CACNuC,IAAI,CAACsB,YAAc,EAAA,aAAA,CAAA;AAEtB,QAAA,MAAMvB,kBAAqB3C,GAAAA,MAAAA,CAAI,QAAUmE,EAAAA,wBAAAA,IAA4B,EAAE,CAAA;QACvE,MAAMC,cAAAA,GAAiB1B,OAAKV,CAAAA,UAAAA,CAAW1D,WAAW,CAAA;QAElD,MAAM+F,eAAAA,GAAkBlF,cAAWwD,kBAAoByB,EAAAA,cAAAA,CAAAA;QACvD,MAAME,YAAAA,GAAenF,cAAWiF,cAAgBzB,EAAAA,kBAAAA,CAAAA;;;AAIhD,QAAA,MAAMH,OAAQC,CAAAA,GAAG,CACf4B,eAAAA,CAAgBrE,GAAG,CAAC,CAAChB,MACnBH,GAAAA,MAAAA,CAAOuB,EAAE,CAACC,KAAK,CAAC,6BAAA,CAAA,CAA+BwD,MAAM,CAAC;gBACpDpD,KAAO,EAAA;AAAEzB,oBAAAA,MAAAA;oBAAQe,KAAOgD,EAAAA;AAAG;AAC7B,aAAA,CAAA,CAAA,CAAA;;;AAMJ,QAAA,MAAMP,OAAQC,CAAAA,GAAG,CACf6B,YAAAA,CAAatE,GAAG,CAAC,CAAChB,MAChBH,GAAAA,MAAAA,CAAOuB,EAAE,CAACC,KAAK,CAAC,6BAAA,CAAA,CAA+B0B,MAAM,CAAC;gBACpDM,IAAM,EAAA;AAAErD,oBAAAA,MAAAA;oBAAQe,KAAOgD,EAAAA;AAAG;AAC5B,aAAA,CAAA,CAAA,CAAA;KAKD,MAAA,IAAImB,aAAa7F,IAAI,KAAKE,UAAUC,cAAc,CAACC,MAAM,EAAE;AAC9D,QAAA,MAAMI,OAAOuB,EAAE,CAACC,KAAK,CAAC,6BAAA,CAAA,CAA+BwD,MAAM,CAAC;YAC1DpD,KAAO,EAAA;gBAAEV,KAAOgD,EAAAA;AAAG;AACrB,SAAA,CAAA;AACF;;IAGA,MAAMwB,iBAAAA,GAAoB,MAAM1F,MAAAA,CAAOuB,EAAE,CACtCC,KAAK,CAAC,kBAAA,CAAA,CACNuC,IAAI,CAACsB,YAAc,EAAA,aAAA,CAAA;IAEtB,OAAO;AACL,QAAA,GAAGA,YAAY;QACf5F,WAAaiG,EAAAA,iBAAAA,GAAoBA,kBAAkBvE,GAAG,CAAC,CAACwE,CAAWA,GAAAA,CAAAA,CAAExF,MAAM,CAAIyF,GAAAA;AACjF,KAAA;AACF;AAEA,MAAMC,KAAQ,GAAA,OAAOjE,KAAQ,GAAA,EAAE,GAAA;AAC7B,IAAA,OAAO5B,OAAOuB,EAAE,CAACC,KAAK,CAAC,kBAAA,CAAA,CAAoBqE,KAAK,CAAC;AAAEjE,QAAAA;AAAM,KAAA,CAAA;AAC3D;;;;;;;;;;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"api-token.mjs","sources":["../../../../../server/src/services/api-token.ts"],"sourcesContent":["import crypto from 'crypto';\nimport { omit, difference, isNil, isEmpty, map, isArray, uniq, isNumber } from 'lodash/fp';\nimport { errors } from '@strapi/utils';\nimport type { Update, ApiToken, ApiTokenBody } from '../../../shared/contracts/api-token';\nimport constants from './constants';\nimport { getService } from '../utils';\n\nconst { ValidationError, NotFoundError } = errors;\n\ntype ApiTokenPermission = {\n id: number | `${number}`;\n action: string;\n token: DBApiToken | number;\n};\n\ntype DBApiToken = ApiToken & {\n permissions: (number | ApiTokenPermission)[];\n};\n\nconst SELECT_FIELDS = [\n 'id',\n 'name',\n 'description',\n 'lastUsedAt',\n 'type',\n 'lifespan',\n 'expiresAt',\n 'createdAt',\n 'updatedAt',\n];\n\nconst POPULATE_FIELDS = ['permissions'];\n\n// TODO: we need to ensure the permissions are actually valid registered permissions!\n\n/**\n * Assert that a token's permissions attribute is valid for its type\n */\nconst assertCustomTokenPermissionsValidity = (\n type: ApiTokenBody['type'],\n permissions: ApiTokenBody['permissions']\n) => {\n // Ensure non-custom tokens doesn't have permissions\n if (type !== constants.API_TOKEN_TYPE.CUSTOM && !isEmpty(permissions)) {\n throw new ValidationError('Non-custom tokens should not reference permissions');\n }\n\n // Custom type tokens should always have permissions attached to them\n if (type === constants.API_TOKEN_TYPE.CUSTOM && !isArray(permissions)) {\n throw new ValidationError('Missing permissions attribute for custom token');\n }\n\n // Permissions provided for a custom type token should be valid/registered permissions UID\n if (type === constants.API_TOKEN_TYPE.CUSTOM) {\n const validPermissions = strapi.contentAPI.permissions.providers.action.keys();\n const invalidPermissions = difference(permissions, validPermissions) as string[];\n\n if (!isEmpty(invalidPermissions)) {\n throw new ValidationError(`Unknown permissions provided: ${invalidPermissions.join(', ')}`);\n }\n }\n};\n\n/**\n * Check if a token's lifespan is valid\n */\nconst isValidLifespan = (lifespan: unknown) => {\n if (isNil(lifespan)) {\n return true;\n }\n\n if (!isNumber(lifespan) || !Object.values(constants.API_TOKEN_LIFESPANS).includes(lifespan)) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Assert that a token's lifespan is valid\n */\nconst assertValidLifespan = (lifespan: unknown) => {\n if (!isValidLifespan(lifespan)) {\n throw new ValidationError(\n `lifespan must be one of the following values:\n ${Object.values(constants.API_TOKEN_LIFESPANS).join(', ')}`\n );\n }\n};\n\n/**\n * Flatten a token's database permissions objects to an array of strings\n */\nconst flattenTokenPermissions = (token: DBApiToken): ApiToken => {\n if (!token) {\n return token;\n }\n\n return {\n ...token,\n permissions: isArray(token.permissions) ? map('action', token.permissions) : token.permissions,\n };\n};\n\ntype WhereParams = {\n id?: string | number;\n name?: string;\n lastUsedAt?: number;\n description?: string;\n accessKey?: string;\n};\n\n/**\n * Get a token\n */\nconst getBy = async (whereParams: WhereParams = {}): Promise<ApiToken | null> => {\n if (Object.keys(whereParams).length === 0) {\n return null;\n }\n\n const token = await strapi.db.query('admin::api-token').findOne({\n select: [...SELECT_FIELDS, 'encryptedKey'],\n populate: POPULATE_FIELDS,\n where: whereParams,\n });\n\n if (!token) {\n return token;\n }\n\n const { encryptedKey, ...rest } = token;\n\n if (!encryptedKey) {\n return flattenTokenPermissions(rest);\n }\n\n const accessKey = getService('encryption').decrypt(encryptedKey);\n\n return flattenTokenPermissions({\n ...rest,\n accessKey,\n });\n};\n\n/**\n * Check if token exists\n */\nconst exists = async (whereParams: WhereParams = {}): Promise<boolean> => {\n const apiToken = await getBy(whereParams);\n\n return !!apiToken;\n};\n\n/**\n * Return a secure sha512 hash of an accessKey\n */\nconst hash = (accessKey: string) => {\n return crypto\n .createHmac('sha512', strapi.config.get('admin.apiToken.salt'))\n .update(accessKey)\n .digest('hex');\n};\n\nconst getExpirationFields = (lifespan: ApiTokenBody['lifespan']) => {\n // it must be nil or a finite number >= 0\n const isValidNumber = isNumber(lifespan) && Number.isFinite(lifespan) && lifespan > 0;\n if (!isValidNumber && !isNil(lifespan)) {\n throw new ValidationError('lifespan must be a positive number or null');\n }\n\n return {\n lifespan: lifespan || null,\n expiresAt: lifespan ? Date.now() + lifespan : null,\n };\n};\n\n/**\n * Create a token and its permissions\n */\nconst create = async (attributes: ApiTokenBody): Promise<ApiToken> => {\n const encryptionService = getService('encryption');\n const accessKey = crypto.randomBytes(128).toString('hex');\n const encryptedKey = encryptionService.encrypt(accessKey);\n\n assertCustomTokenPermissionsValidity(attributes.type, attributes.permissions);\n assertValidLifespan(attributes.lifespan);\n\n // Create the token\n const apiToken: ApiToken = await strapi.db.query('admin::api-token').create({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n data: {\n ...omit('permissions', attributes),\n accessKey: hash(accessKey),\n encryptedKey,\n ...getExpirationFields(attributes.lifespan),\n },\n });\n\n const result: ApiToken = { ...apiToken, accessKey };\n\n // If this is a custom type token, create and the related permissions\n if (attributes.type === constants.API_TOKEN_TYPE.CUSTOM) {\n // TODO: createMany doesn't seem to create relation properly, implement a better way rather than a ton of queries\n // const permissionsCount = await strapi.db.query('admin::api-token-permission').createMany({\n // populate: POPULATE_FIELDS,\n // data: attributes.permissions.map(action => ({ action, token: apiToken })),\n // });\n await Promise.all(\n uniq(attributes.permissions).map((action) =>\n strapi.db.query('admin::api-token-permission').create({\n data: { action, token: apiToken },\n })\n )\n );\n\n const currentPermissions = await strapi.db\n .query('admin::api-token')\n .load(apiToken, 'permissions');\n\n if (currentPermissions) {\n Object.assign(result, { permissions: map('action', currentPermissions) });\n }\n }\n\n return result;\n};\n\nconst regenerate = async (id: string | number): Promise<ApiToken> => {\n const accessKey = crypto.randomBytes(128).toString('hex');\n const encryptionService = getService('encryption');\n const encryptedKey = encryptionService.encrypt(accessKey);\n\n const apiToken: ApiToken = await strapi.db.query('admin::api-token').update({\n select: ['id', 'accessKey'],\n where: { id },\n data: {\n accessKey: hash(accessKey),\n encryptedKey,\n },\n });\n\n if (!apiToken) {\n throw new NotFoundError('The provided token id does not exist');\n }\n\n return {\n ...apiToken,\n accessKey,\n };\n};\n\nconst checkSaltIsDefined = () => {\n if (!strapi.config.get('admin.apiToken.salt')) {\n // TODO V5: stop reading API_TOKEN_SALT\n if (process.env.API_TOKEN_SALT) {\n process.emitWarning(`[deprecated] In future versions, Strapi will stop reading directly from the environment variable API_TOKEN_SALT. Please set apiToken.salt in config/admin.js instead.\nFor security reasons, keep storing the secret in an environment variable and use env() to read it in config/admin.js (ex: \\`apiToken: { salt: env('API_TOKEN_SALT') }\\`). See https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.html#configuration-using-environment-variables.`);\n\n strapi.config.set('admin.apiToken.salt', process.env.API_TOKEN_SALT);\n } else {\n throw new Error(\n `Missing apiToken.salt. Please set apiToken.salt in config/admin.js (ex: you can generate one using Node with \\`crypto.randomBytes(16).toString('base64')\\`).\nFor security reasons, prefer storing the secret in an environment variable and read it in config/admin.js. See https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.html#configuration-using-environment-variables.`\n );\n }\n }\n};\n\n/**\n * Return a list of all tokens and their permissions\n */\nconst list = async (): Promise<Array<ApiToken>> => {\n const tokens: Array<DBApiToken> = await strapi.db.query('admin::api-token').findMany({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n orderBy: { name: 'ASC' },\n });\n\n if (!tokens) {\n return tokens;\n }\n\n return tokens.map((token) => flattenTokenPermissions(token));\n};\n\n/**\n * Revoke (delete) a token\n */\nconst revoke = async (id: string | number): Promise<ApiToken> => {\n return strapi.db\n .query('admin::api-token')\n .delete({ select: SELECT_FIELDS, populate: POPULATE_FIELDS, where: { id } });\n};\n\n/**\n * Retrieve a token by id\n */\nconst getById = async (id: string | number) => {\n return getBy({ id });\n};\n\n/**\n * Retrieve a token by name\n */\nconst getByName = async (name: string) => {\n return getBy({ name });\n};\n\n/**\n * Update a token and its permissions\n */\nconst update = async (\n id: string | number,\n attributes: Update.Request['body']\n): Promise<ApiToken> => {\n // retrieve token without permissions\n const originalToken: DBApiToken = await strapi.db\n .query('admin::api-token')\n .findOne({ where: { id } });\n\n if (!originalToken) {\n throw new NotFoundError('Token not found');\n }\n\n const changingTypeToCustom =\n attributes.type === constants.API_TOKEN_TYPE.CUSTOM &&\n originalToken.type !== constants.API_TOKEN_TYPE.CUSTOM;\n\n // if we're updating the permissions on any token type, or changing from non-custom to custom, ensure they're still valid\n // if neither type nor permissions are changing, we don't need to validate again or else we can't allow partial update\n if (attributes.permissions || changingTypeToCustom) {\n assertCustomTokenPermissionsValidity(\n attributes.type || originalToken.type,\n attributes.permissions || originalToken.permissions\n );\n }\n\n assertValidLifespan(attributes.lifespan);\n\n const updatedToken: ApiToken = await strapi.db.query('admin::api-token').update({\n select: SELECT_FIELDS,\n where: { id },\n data: omit('permissions', attributes),\n });\n\n // custom tokens need to have their permissions updated as well\n if (updatedToken.type === constants.API_TOKEN_TYPE.CUSTOM && attributes.permissions) {\n const currentPermissionsResult = await strapi.db\n .query('admin::api-token')\n .load(updatedToken, 'permissions');\n\n const currentPermissions = map('action', currentPermissionsResult || []);\n const newPermissions = uniq(attributes.permissions);\n\n const actionsToDelete = difference(currentPermissions, newPermissions);\n const actionsToAdd = difference(newPermissions, currentPermissions);\n\n // TODO: improve efficiency here\n // method using a loop -- works but very inefficient\n await Promise.all(\n actionsToDelete.map((action) =>\n strapi.db.query('admin::api-token-permission').delete({\n where: { action, token: id },\n })\n )\n );\n\n // TODO: improve efficiency here\n // using a loop -- works but very inefficient\n await Promise.all(\n actionsToAdd.map((action) =>\n strapi.db.query('admin::api-token-permission').create({\n data: { action, token: id },\n })\n )\n );\n }\n // if type is not custom, make sure any old permissions get removed\n else if (updatedToken.type !== constants.API_TOKEN_TYPE.CUSTOM) {\n await strapi.db.query('admin::api-token-permission').delete({\n where: { token: id },\n });\n }\n\n // retrieve permissions\n const permissionsFromDb = await strapi.db\n .query('admin::api-token')\n .load(updatedToken, 'permissions');\n\n return {\n ...updatedToken,\n permissions: permissionsFromDb ? permissionsFromDb.map((p: any) => p.action) : undefined,\n };\n};\n\nconst count = async (where = {}): Promise<number> => {\n return strapi.db.query('admin::api-token').count({ where });\n};\n\nexport {\n create,\n count,\n regenerate,\n exists,\n checkSaltIsDefined,\n hash,\n list,\n revoke,\n getById,\n update,\n getByName,\n getBy,\n};\n"],"names":["ValidationError","NotFoundError","errors","SELECT_FIELDS","POPULATE_FIELDS","assertCustomTokenPermissionsValidity","type","permissions","constants","API_TOKEN_TYPE","CUSTOM","isEmpty","isArray","validPermissions","strapi","contentAPI","providers","action","keys","invalidPermissions","difference","join","isValidLifespan","lifespan","isNil","isNumber","Object","values","API_TOKEN_LIFESPANS","includes","assertValidLifespan","flattenTokenPermissions","token","map","getBy","whereParams","length","db","query","findOne","select","populate","where","encryptedKey","rest","accessKey","getService","decrypt","exists","apiToken","hash","crypto","createHmac","config","get","update","digest","getExpirationFields","isValidNumber","Number","isFinite","expiresAt","Date","now","create","attributes","encryptionService","randomBytes","toString","encrypt","data","omit","result","Promise","all","uniq","currentPermissions","load","assign","regenerate","id","checkSaltIsDefined","process","env","API_TOKEN_SALT","emitWarning","set","Error","list","tokens","findMany","orderBy","name","revoke","delete","getById","getByName","originalToken","changingTypeToCustom","updatedToken","currentPermissionsResult","newPermissions","actionsToDelete","actionsToAdd","permissionsFromDb","p","undefined","count"],"mappings":"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"}
1
+ {"version":3,"file":"api-token.mjs","sources":["../../../../../server/src/services/api-token.ts"],"sourcesContent":["import crypto from 'crypto';\nimport { omit, difference, isNil, isEmpty, map, isArray, uniq, isNumber } from 'lodash/fp';\nimport { errors } from '@strapi/utils';\nimport type { Update, ApiToken, ApiTokenBody } from '../../../shared/contracts/api-token';\nimport constants from './constants';\nimport { getService } from '../utils';\n\nconst { ValidationError, NotFoundError } = errors;\n\ntype ApiTokenPermission = {\n id: number | `${number}`;\n action: string;\n token: DBApiToken | number;\n};\n\ntype DBApiToken = ApiToken & {\n permissions: (number | ApiTokenPermission)[];\n};\n\nconst SELECT_FIELDS = [\n 'id',\n 'name',\n 'description',\n 'lastUsedAt',\n 'type',\n 'lifespan',\n 'expiresAt',\n 'createdAt',\n 'updatedAt',\n];\n\nconst POPULATE_FIELDS = ['permissions'];\n\n// TODO: we need to ensure the permissions are actually valid registered permissions!\n\n/**\n * Assert that a token's permissions attribute is valid for its type\n */\nconst assertCustomTokenPermissionsValidity = (\n type: ApiTokenBody['type'],\n permissions: ApiTokenBody['permissions']\n) => {\n // Ensure non-custom tokens doesn't have permissions\n if (type !== constants.API_TOKEN_TYPE.CUSTOM && !isEmpty(permissions)) {\n throw new ValidationError('Non-custom tokens should not reference permissions');\n }\n\n // Custom type tokens should always have permissions attached to them\n if (type === constants.API_TOKEN_TYPE.CUSTOM && !isArray(permissions)) {\n throw new ValidationError('Missing permissions attribute for custom token');\n }\n\n // Permissions provided for a custom type token should be valid/registered permissions UID\n if (type === constants.API_TOKEN_TYPE.CUSTOM) {\n const validPermissions = strapi.contentAPI.permissions.providers.action.keys();\n const invalidPermissions = difference(permissions, validPermissions) as string[];\n\n if (!isEmpty(invalidPermissions)) {\n throw new ValidationError(`Unknown permissions provided: ${invalidPermissions.join(', ')}`);\n }\n }\n};\n\n/**\n * Check if a token's lifespan is valid\n */\nconst isValidLifespan = (lifespan: unknown) => {\n if (isNil(lifespan)) {\n return true;\n }\n\n if (!isNumber(lifespan) || !Object.values(constants.API_TOKEN_LIFESPANS).includes(lifespan)) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Assert that a token's lifespan is valid\n */\nconst assertValidLifespan = (lifespan: unknown) => {\n if (!isValidLifespan(lifespan)) {\n throw new ValidationError(\n `lifespan must be one of the following values:\n ${Object.values(constants.API_TOKEN_LIFESPANS).join(', ')}`\n );\n }\n};\n\n/**\n * Flatten a token's database permissions objects to an array of strings\n */\nconst flattenTokenPermissions = (token: DBApiToken): ApiToken => {\n if (!token) {\n return token;\n }\n\n return {\n ...token,\n permissions: isArray(token.permissions) ? map('action', token.permissions) : token.permissions,\n };\n};\n\ntype WhereParams = {\n id?: string | number;\n name?: string;\n lastUsedAt?: number;\n description?: string;\n accessKey?: string;\n};\n\n/**\n * Get a token\n */\nconst getBy = async (whereParams: WhereParams = {}): Promise<ApiToken | null> => {\n if (Object.keys(whereParams).length === 0) {\n return null;\n }\n\n const token = await strapi.db.query('admin::api-token').findOne({\n select: [...SELECT_FIELDS, 'encryptedKey'],\n populate: POPULATE_FIELDS,\n where: whereParams,\n });\n\n if (!token) {\n return token;\n }\n\n const { encryptedKey, ...rest } = token;\n\n if (!encryptedKey) {\n return flattenTokenPermissions(rest);\n }\n\n const accessKey = getService('encryption').decrypt(encryptedKey);\n\n return flattenTokenPermissions({\n ...rest,\n accessKey,\n });\n};\n\n/**\n * Check if token exists\n */\nconst exists = async (whereParams: WhereParams = {}): Promise<boolean> => {\n const apiToken = await getBy(whereParams);\n\n return !!apiToken;\n};\n\n/**\n * Return a secure sha512 hash of an accessKey\n */\nconst hash = (accessKey: string) => {\n return crypto\n .createHmac('sha512', strapi.config.get('admin.apiToken.salt'))\n .update(accessKey)\n .digest('hex');\n};\n\nconst getExpirationFields = (lifespan: ApiTokenBody['lifespan']) => {\n // it must be nil or a finite number >= 0\n const isValidNumber = isNumber(lifespan) && Number.isFinite(lifespan) && lifespan > 0;\n if (!isValidNumber && !isNil(lifespan)) {\n throw new ValidationError('lifespan must be a positive number or null');\n }\n\n return {\n lifespan: lifespan || null,\n expiresAt: lifespan ? Date.now() + lifespan : null,\n };\n};\n\n/**\n * Create a token and its permissions\n */\nconst create = async (attributes: ApiTokenBody): Promise<ApiToken> => {\n const encryptionService = getService('encryption');\n const accessKey = crypto.randomBytes(128).toString('hex');\n const encryptedKey = encryptionService.encrypt(accessKey);\n\n assertCustomTokenPermissionsValidity(attributes.type, attributes.permissions);\n assertValidLifespan(attributes.lifespan);\n\n // Create the token\n const apiToken: ApiToken = await strapi.db.query('admin::api-token').create({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n data: {\n ...omit('permissions', attributes),\n accessKey: hash(accessKey),\n encryptedKey,\n ...getExpirationFields(attributes.lifespan),\n },\n });\n\n const result: ApiToken = { ...apiToken, accessKey };\n\n // If this is a custom type token, create and the related permissions\n if (attributes.type === constants.API_TOKEN_TYPE.CUSTOM) {\n // TODO: createMany doesn't seem to create relation properly, implement a better way rather than a ton of queries\n // const permissionsCount = await strapi.db.query('admin::api-token-permission').createMany({\n // populate: POPULATE_FIELDS,\n // data: attributes.permissions.map(action => ({ action, token: apiToken })),\n // });\n await Promise.all(\n uniq(attributes.permissions).map((action) =>\n strapi.db.query('admin::api-token-permission').create({\n data: { action, token: apiToken },\n })\n )\n );\n\n const currentPermissions = await strapi.db\n .query('admin::api-token')\n .load(apiToken, 'permissions');\n\n if (currentPermissions) {\n Object.assign(result, { permissions: map('action', currentPermissions) });\n }\n }\n\n return result;\n};\n\nconst regenerate = async (id: string | number): Promise<ApiToken> => {\n const accessKey = crypto.randomBytes(128).toString('hex');\n const encryptionService = getService('encryption');\n const encryptedKey = encryptionService.encrypt(accessKey);\n\n const apiToken: ApiToken = await strapi.db.query('admin::api-token').update({\n select: ['id', 'accessKey'],\n where: { id },\n data: {\n accessKey: hash(accessKey),\n encryptedKey,\n },\n });\n\n if (!apiToken) {\n throw new NotFoundError('The provided token id does not exist');\n }\n\n return {\n ...apiToken,\n accessKey,\n };\n};\n\nconst checkSaltIsDefined = () => {\n if (!strapi.config.get('admin.apiToken.salt')) {\n // TODO V5: stop reading API_TOKEN_SALT\n if (process.env.API_TOKEN_SALT) {\n process.emitWarning(`[deprecated] In future versions, Strapi will stop reading directly from the environment variable API_TOKEN_SALT. Please set apiToken.salt in config/admin.js instead.\nFor security reasons, keep storing the secret in an environment variable and use env() to read it in config/admin.js (ex: \\`apiToken: { salt: env('API_TOKEN_SALT') }\\`). See https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.html#configuration-using-environment-variables.`);\n\n strapi.config.set('admin.apiToken.salt', process.env.API_TOKEN_SALT);\n } else {\n throw new Error(\n `Missing apiToken.salt. Please set apiToken.salt in config/admin.js (ex: you can generate one using Node with \\`crypto.randomBytes(16).toString('base64')\\`).\nFor security reasons, prefer storing the secret in an environment variable and read it in config/admin.js. See https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.html#configuration-using-environment-variables.`\n );\n }\n }\n};\n\n/**\n * Return a list of all tokens and their permissions\n */\nconst list = async (): Promise<Array<ApiToken>> => {\n const tokens: Array<DBApiToken> = await strapi.db.query('admin::api-token').findMany({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n orderBy: { name: 'ASC' },\n });\n\n if (!tokens) {\n return tokens;\n }\n\n return tokens.map((token) => flattenTokenPermissions(token));\n};\n\n/**\n * Revoke (delete) a token\n */\nconst revoke = async (id: string | number): Promise<ApiToken> => {\n return strapi.db\n .query('admin::api-token')\n .delete({ select: SELECT_FIELDS, populate: POPULATE_FIELDS, where: { id } });\n};\n\n/**\n * Retrieve a token by id\n */\nconst getById = async (id: string | number) => {\n return getBy({ id });\n};\n\n/**\n * Retrieve a token by name\n */\nconst getByName = async (name: string) => {\n return getBy({ name });\n};\n\n/**\n * Update a token and its permissions\n */\nconst update = async (\n id: string | number,\n attributes: Update.Request['body']\n): Promise<ApiToken> => {\n // retrieve token without permissions\n const originalToken: DBApiToken = await strapi.db\n .query('admin::api-token')\n .findOne({ where: { id } });\n\n if (!originalToken) {\n throw new NotFoundError('Token not found');\n }\n\n const changingTypeToCustom =\n attributes.type === constants.API_TOKEN_TYPE.CUSTOM &&\n originalToken.type !== constants.API_TOKEN_TYPE.CUSTOM;\n\n // if we're updating the permissions on any token type, or changing from non-custom to custom, ensure they're still valid\n // if neither type nor permissions are changing, we don't need to validate again or else we can't allow partial update\n if (attributes.permissions || changingTypeToCustom) {\n assertCustomTokenPermissionsValidity(\n attributes.type || originalToken.type,\n attributes.permissions || originalToken.permissions\n );\n }\n\n assertValidLifespan(attributes.lifespan);\n\n const updatedToken: ApiToken = await strapi.db.query('admin::api-token').update({\n select: SELECT_FIELDS,\n where: { id },\n data: omit('permissions', attributes),\n });\n\n // custom tokens need to have their permissions updated as well\n if (updatedToken.type === constants.API_TOKEN_TYPE.CUSTOM && attributes.permissions) {\n const currentPermissionsResult = await strapi.db\n .query('admin::api-token')\n .load(updatedToken, 'permissions');\n\n const currentPermissions = map('action', currentPermissionsResult || []);\n const newPermissions = uniq(attributes.permissions);\n\n const actionsToDelete = difference(currentPermissions, newPermissions);\n const actionsToAdd = difference(newPermissions, currentPermissions);\n\n // TODO: improve efficiency here\n // method using a loop -- works but very inefficient\n await Promise.all(\n actionsToDelete.map((action) =>\n strapi.db.query('admin::api-token-permission').delete({\n where: { action, token: id },\n })\n )\n );\n\n // TODO: improve efficiency here\n // using a loop -- works but very inefficient\n await Promise.all(\n actionsToAdd.map((action) =>\n strapi.db.query('admin::api-token-permission').create({\n data: { action, token: id },\n })\n )\n );\n }\n // if type is not custom, make sure any old permissions get removed\n else if (updatedToken.type !== constants.API_TOKEN_TYPE.CUSTOM) {\n await strapi.db.query('admin::api-token-permission').delete({\n where: { token: id },\n });\n }\n\n // retrieve permissions\n const permissionsFromDb = await strapi.db\n .query('admin::api-token')\n .load(updatedToken, 'permissions');\n\n return {\n ...updatedToken,\n permissions: permissionsFromDb ? permissionsFromDb.map((p: any) => p.action) : undefined,\n };\n};\n\nconst count = async (where = {}): Promise<number> => {\n return strapi.db.query('admin::api-token').count({ where });\n};\n\nexport {\n create,\n count,\n regenerate,\n exists,\n checkSaltIsDefined,\n hash,\n list,\n revoke,\n getById,\n update,\n getByName,\n getBy,\n};\n"],"names":["ValidationError","NotFoundError","errors","SELECT_FIELDS","POPULATE_FIELDS","assertCustomTokenPermissionsValidity","type","permissions","constants","API_TOKEN_TYPE","CUSTOM","isEmpty","isArray","validPermissions","strapi","contentAPI","providers","action","keys","invalidPermissions","difference","join","isValidLifespan","lifespan","isNil","isNumber","Object","values","API_TOKEN_LIFESPANS","includes","assertValidLifespan","flattenTokenPermissions","token","map","getBy","whereParams","length","db","query","findOne","select","populate","where","encryptedKey","rest","accessKey","getService","decrypt","exists","apiToken","hash","crypto","createHmac","config","get","update","digest","getExpirationFields","isValidNumber","Number","isFinite","expiresAt","Date","now","create","attributes","encryptionService","randomBytes","toString","encrypt","data","omit","result","Promise","all","uniq","currentPermissions","load","assign","regenerate","id","checkSaltIsDefined","process","env","API_TOKEN_SALT","emitWarning","set","Error","list","tokens","findMany","orderBy","name","revoke","delete","getById","getByName","originalToken","changingTypeToCustom","updatedToken","currentPermissionsResult","newPermissions","actionsToDelete","actionsToAdd","permissionsFromDb","p","undefined","count"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sources":["../../../../../server/src/services/auth.ts"],"sourcesContent":["import bcrypt from 'bcryptjs';\nimport _ from 'lodash';\nimport { errors } from '@strapi/utils';\nimport { getService } from '../utils';\nimport type { AdminUser } from '../../../shared/contracts/shared';\nimport '@strapi/types';\n\nconst { ApplicationError } = errors;\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 = getService('token').createToken();\n await getService('user').updateById(user.id, { resetPasswordToken });\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 return getService('user').updateById(matchingUser.id, {\n password,\n resetPasswordToken: null,\n });\n};\n\nexport default { checkCredentials, validatePassword, hashPassword, forgotPassword, resetPassword };\n"],"names":["ApplicationError","errors","hashPassword","password","bcrypt","hash","validatePassword","compare","checkCredentials","email","user","strapi","db","query","findOne","where","message","isValid","isActive","forgotPassword","resetPasswordToken","getService","createToken","updateById","id","url","config","get","plugin","service","sendTemplatedEmail","to","from","replyTo","_","pick","catch","err","log","error","resetPassword","matchingUser"],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sources":["../../../../../server/src/services/auth.ts"],"sourcesContent":["import bcrypt from 'bcryptjs';\nimport _ from 'lodash';\nimport { errors } from '@strapi/utils';\nimport { getService } from '../utils';\nimport type { AdminUser } from '../../../shared/contracts/shared';\nimport '@strapi/types';\n\nconst { ApplicationError } = errors;\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 = getService('token').createToken();\n await getService('user').updateById(user.id, { resetPasswordToken });\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 return getService('user').updateById(matchingUser.id, {\n password,\n resetPasswordToken: null,\n });\n};\n\nexport default { checkCredentials, validatePassword, hashPassword, forgotPassword, resetPassword };\n"],"names":["ApplicationError","errors","hashPassword","password","bcrypt","hash","validatePassword","compare","checkCredentials","email","user","strapi","db","query","findOne","where","message","isValid","isActive","forgotPassword","resetPasswordToken","getService","createToken","updateById","id","url","config","get","plugin","service","sendTemplatedEmail","to","from","replyTo","_","pick","catch","err","log","error","resetPassword","matchingUser"],"mappings":"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"}
@@ -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 type { AdminUser } from '../../../shared/contracts/shared';\nimport '@strapi/types';\n\nconst { ApplicationError } = errors;\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 = getService('token').createToken();\n await getService('user').updateById(user.id, { resetPasswordToken });\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 return getService('user').updateById(matchingUser.id, {\n password,\n resetPasswordToken: null,\n });\n};\n\nexport default { checkCredentials, validatePassword, hashPassword, forgotPassword, resetPassword };\n"],"names":["ApplicationError","errors","hashPassword","password","bcrypt","hash","validatePassword","compare","checkCredentials","email","user","strapi","db","query","findOne","where","message","isValid","isActive","forgotPassword","resetPasswordToken","getService","createToken","updateById","id","url","config","get","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 } from '@strapi/utils';\nimport { getService } from '../utils';\nimport type { AdminUser } from '../../../shared/contracts/shared';\nimport '@strapi/types';\n\nconst { ApplicationError } = errors;\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 = getService('token').createToken();\n await getService('user').updateById(user.id, { resetPasswordToken });\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 return getService('user').updateById(matchingUser.id, {\n password,\n resetPasswordToken: null,\n });\n};\n\nexport default { checkCredentials, validatePassword, hashPassword, forgotPassword, resetPassword };\n"],"names":["ApplicationError","errors","hashPassword","password","bcrypt","hash","validatePassword","compare","checkCredentials","email","user","strapi","db","query","findOne","where","message","isValid","isActive","forgotPassword","resetPasswordToken","getService","createToken","updateById","id","url","config","get","plugin","service","sendTemplatedEmail","to","from","replyTo","_","pick","catch","err","log","error","resetPassword","matchingUser"],"mappings":"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"}