@strapi/admin 5.57.0 → 5.59.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (415) 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/ConfirmDialog.js +10 -9
  4. package/dist/admin/admin/src/components/ConfirmDialog.js.map +1 -1
  5. package/dist/admin/admin/src/components/ConfirmDialog.mjs +10 -9
  6. package/dist/admin/admin/src/components/ConfirmDialog.mjs.map +1 -1
  7. package/dist/admin/admin/src/components/Filters.js +57 -12
  8. package/dist/admin/admin/src/components/Filters.js.map +1 -1
  9. package/dist/admin/admin/src/components/Filters.mjs +57 -12
  10. package/dist/admin/admin/src/components/Filters.mjs.map +1 -1
  11. package/dist/admin/admin/src/components/Form.js +3 -1
  12. package/dist/admin/admin/src/components/Form.js.map +1 -1
  13. package/dist/admin/admin/src/components/Form.mjs +3 -1
  14. package/dist/admin/admin/src/components/Form.mjs.map +1 -1
  15. package/dist/admin/admin/src/components/FormInputs/Boolean.js +3 -2
  16. package/dist/admin/admin/src/components/FormInputs/Boolean.js.map +1 -1
  17. package/dist/admin/admin/src/components/FormInputs/Boolean.mjs +3 -2
  18. package/dist/admin/admin/src/components/FormInputs/Boolean.mjs.map +1 -1
  19. package/dist/admin/admin/src/components/FormInputs/Enumeration.js +2 -1
  20. package/dist/admin/admin/src/components/FormInputs/Enumeration.js.map +1 -1
  21. package/dist/admin/admin/src/components/FormInputs/Enumeration.mjs +2 -1
  22. package/dist/admin/admin/src/components/FormInputs/Enumeration.mjs.map +1 -1
  23. package/dist/admin/admin/src/components/LeftMenu.js +5 -1
  24. package/dist/admin/admin/src/components/LeftMenu.js.map +1 -1
  25. package/dist/admin/admin/src/components/LeftMenu.mjs +5 -1
  26. package/dist/admin/admin/src/components/LeftMenu.mjs.map +1 -1
  27. package/dist/admin/admin/src/components/PageHelpers.js +2 -1
  28. package/dist/admin/admin/src/components/PageHelpers.js.map +1 -1
  29. package/dist/admin/admin/src/components/PageHelpers.mjs +2 -1
  30. package/dist/admin/admin/src/components/PageHelpers.mjs.map +1 -1
  31. package/dist/admin/admin/src/components/Pagination.js +7 -6
  32. package/dist/admin/admin/src/components/Pagination.js.map +1 -1
  33. package/dist/admin/admin/src/components/Pagination.mjs +7 -6
  34. package/dist/admin/admin/src/components/Pagination.mjs.map +1 -1
  35. package/dist/admin/admin/src/components/RelativeTime.js +2 -1
  36. package/dist/admin/admin/src/components/RelativeTime.js.map +1 -1
  37. package/dist/admin/admin/src/components/RelativeTime.mjs +2 -1
  38. package/dist/admin/admin/src/components/RelativeTime.mjs.map +1 -1
  39. package/dist/admin/admin/src/components/SubNav.js +6 -12
  40. package/dist/admin/admin/src/components/SubNav.js.map +1 -1
  41. package/dist/admin/admin/src/components/SubNav.mjs +7 -13
  42. package/dist/admin/admin/src/components/SubNav.mjs.map +1 -1
  43. package/dist/admin/admin/src/components/Table.js +3 -1
  44. package/dist/admin/admin/src/components/Table.js.map +1 -1
  45. package/dist/admin/admin/src/components/Table.mjs +3 -1
  46. package/dist/admin/admin/src/components/Table.mjs.map +1 -1
  47. package/dist/admin/admin/src/components/UpsellBanner.js.map +1 -1
  48. package/dist/admin/admin/src/components/UpsellBanner.mjs.map +1 -1
  49. package/dist/admin/admin/src/components/WidgetRoot.js.map +1 -1
  50. package/dist/admin/admin/src/components/WidgetRoot.mjs.map +1 -1
  51. package/dist/admin/admin/src/constants.js +14 -0
  52. package/dist/admin/admin/src/constants.js.map +1 -1
  53. package/dist/admin/admin/src/constants.mjs +14 -0
  54. package/dist/admin/admin/src/constants.mjs.map +1 -1
  55. package/dist/admin/admin/src/core/apis/Plugin.js.map +1 -1
  56. package/dist/admin/admin/src/core/apis/Plugin.mjs.map +1 -1
  57. package/dist/admin/admin/src/features/Auth.js +2 -1
  58. package/dist/admin/admin/src/features/Auth.js.map +1 -1
  59. package/dist/admin/admin/src/features/Auth.mjs +2 -1
  60. package/dist/admin/admin/src/features/Auth.mjs.map +1 -1
  61. package/dist/admin/admin/src/features/StrapiApp.js.map +1 -1
  62. package/dist/admin/admin/src/features/StrapiApp.mjs.map +1 -1
  63. package/dist/admin/admin/src/features/Tracking.js.map +1 -1
  64. package/dist/admin/admin/src/features/Tracking.mjs.map +1 -1
  65. package/dist/admin/admin/src/pages/Auth/components/ResetPassword.js +6 -12
  66. package/dist/admin/admin/src/pages/Auth/components/ResetPassword.js.map +1 -1
  67. package/dist/admin/admin/src/pages/Auth/components/ResetPassword.mjs +6 -12
  68. package/dist/admin/admin/src/pages/Auth/components/ResetPassword.mjs.map +1 -1
  69. package/dist/admin/admin/src/pages/Home/components/FreeTrialEndedModal.js.map +1 -1
  70. package/dist/admin/admin/src/pages/Home/components/FreeTrialEndedModal.mjs.map +1 -1
  71. package/dist/admin/admin/src/pages/ProfilePage.js +2 -2
  72. package/dist/admin/admin/src/pages/ProfilePage.js.map +1 -1
  73. package/dist/admin/admin/src/pages/ProfilePage.mjs +2 -2
  74. package/dist/admin/admin/src/pages/ProfilePage.mjs.map +1 -1
  75. package/dist/admin/admin/src/pages/Settings/components/SettingsNav.js +10 -2
  76. package/dist/admin/admin/src/pages/Settings/components/SettingsNav.js.map +1 -1
  77. package/dist/admin/admin/src/pages/Settings/components/SettingsNav.mjs +10 -2
  78. package/dist/admin/admin/src/pages/Settings/components/SettingsNav.mjs.map +1 -1
  79. package/dist/admin/admin/src/pages/Settings/components/Tokens/FormApiTokenContainer.js +4 -1
  80. package/dist/admin/admin/src/pages/Settings/components/Tokens/FormApiTokenContainer.js.map +1 -1
  81. package/dist/admin/admin/src/pages/Settings/components/Tokens/FormApiTokenContainer.mjs +4 -1
  82. package/dist/admin/admin/src/pages/Settings/components/Tokens/FormApiTokenContainer.mjs.map +1 -1
  83. package/dist/admin/admin/src/pages/Settings/components/Tokens/Table.js +3 -1
  84. package/dist/admin/admin/src/pages/Settings/components/Tokens/Table.js.map +1 -1
  85. package/dist/admin/admin/src/pages/Settings/components/Tokens/Table.mjs +3 -1
  86. package/dist/admin/admin/src/pages/Settings/components/Tokens/Table.mjs.map +1 -1
  87. package/dist/admin/admin/src/pages/Settings/components/Tokens/TokenTypeSelect.js +2 -1
  88. package/dist/admin/admin/src/pages/Settings/components/Tokens/TokenTypeSelect.js.map +1 -1
  89. package/dist/admin/admin/src/pages/Settings/components/Tokens/TokenTypeSelect.mjs +2 -1
  90. package/dist/admin/admin/src/pages/Settings/components/Tokens/TokenTypeSelect.mjs.map +1 -1
  91. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/BoundRoute.js +6 -5
  92. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/BoundRoute.js.map +1 -1
  93. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/BoundRoute.mjs +6 -5
  94. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/BoundRoute.mjs.map +1 -1
  95. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/CollapsableContentType.js +2 -1
  96. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/CollapsableContentType.js.map +1 -1
  97. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/CollapsableContentType.mjs +2 -1
  98. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/CollapsableContentType.mjs.map +1 -1
  99. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/utils/transformPermissionsData.js +4 -4
  100. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/utils/transformPermissionsData.js.map +1 -1
  101. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/utils/transformPermissionsData.mjs +4 -4
  102. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/utils/transformPermissionsData.mjs.map +1 -1
  103. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.js +7 -58
  104. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.js.map +1 -1
  105. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.mjs +7 -58
  106. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.mjs.map +1 -1
  107. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/DiagnosticSnapshotModal.js +217 -0
  108. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/DiagnosticSnapshotModal.js.map +1 -0
  109. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/DiagnosticSnapshotModal.mjs +195 -0
  110. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/DiagnosticSnapshotModal.mjs.map +1 -0
  111. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/LogoInput.js.map +1 -1
  112. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/LogoInput.mjs.map +1 -1
  113. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/PlanCard.js +185 -0
  114. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/PlanCard.js.map +1 -0
  115. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/PlanCard.mjs +162 -0
  116. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/PlanCard.mjs.map +1 -0
  117. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/SupportCard.js +342 -0
  118. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/SupportCard.js.map +1 -0
  119. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/SupportCard.mjs +320 -0
  120. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/SupportCard.mjs.map +1 -0
  121. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/CollapsePropertyMatrix.js +9 -4
  122. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/CollapsePropertyMatrix.js.map +1 -1
  123. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/CollapsePropertyMatrix.mjs +9 -4
  124. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/CollapsePropertyMatrix.mjs.map +1 -1
  125. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ConditionsModal.js +15 -9
  126. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ConditionsModal.js.map +1 -1
  127. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ConditionsModal.mjs +15 -9
  128. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ConditionsModal.mjs.map +1 -1
  129. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ContentTypeCollapses.js +5 -2
  130. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ContentTypeCollapses.js.map +1 -1
  131. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ContentTypeCollapses.mjs +5 -2
  132. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ContentTypeCollapses.mjs.map +1 -1
  133. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/GlobalActions.js +2 -1
  134. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/GlobalActions.js.map +1 -1
  135. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/GlobalActions.mjs +2 -1
  136. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/GlobalActions.mjs.map +1 -1
  137. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.js +2 -1
  138. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.js.map +1 -1
  139. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.mjs +2 -1
  140. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.mjs.map +1 -1
  141. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/PluginsAndSettings.js +2 -1
  142. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/PluginsAndSettings.js.map +1 -1
  143. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/PluginsAndSettings.mjs +2 -1
  144. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/PluginsAndSettings.mjs.map +1 -1
  145. package/dist/admin/admin/src/pages/Settings/pages/Roles/hooks/usePermissionsDataManager.js.map +1 -1
  146. package/dist/admin/admin/src/pages/Settings/pages/Roles/hooks/usePermissionsDataManager.mjs.map +1 -1
  147. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/EditView.js +3 -1
  148. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/EditView.js.map +1 -1
  149. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/EditView.mjs +3 -1
  150. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/EditView.mjs.map +1 -1
  151. package/dist/admin/admin/src/pages/Settings/pages/Users/EditPage.js.map +1 -1
  152. package/dist/admin/admin/src/pages/Settings/pages/Users/EditPage.mjs.map +1 -1
  153. package/dist/admin/admin/src/pages/Settings/pages/Users/ListPage.js.map +1 -1
  154. package/dist/admin/admin/src/pages/Settings/pages/Users/ListPage.mjs.map +1 -1
  155. package/dist/admin/admin/src/pages/Settings/pages/Users/components/NewUserForm.js.map +1 -1
  156. package/dist/admin/admin/src/pages/Settings/pages/Users/components/NewUserForm.mjs.map +1 -1
  157. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/Events.js +4 -1
  158. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/Events.js.map +1 -1
  159. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/Events.mjs +4 -1
  160. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/Events.mjs.map +1 -1
  161. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/HeadersInput.js +18 -3
  162. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/HeadersInput.js.map +1 -1
  163. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/HeadersInput.mjs +18 -3
  164. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/HeadersInput.mjs.map +1 -1
  165. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/WebhookForm.js.map +1 -1
  166. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/WebhookForm.mjs.map +1 -1
  167. package/dist/admin/admin/src/router.js.map +1 -1
  168. package/dist/admin/admin/src/router.mjs.map +1 -1
  169. package/dist/admin/admin/src/services/admin.js +11 -1
  170. package/dist/admin/admin/src/services/admin.js.map +1 -1
  171. package/dist/admin/admin/src/services/admin.mjs +11 -2
  172. package/dist/admin/admin/src/services/admin.mjs.map +1 -1
  173. package/dist/admin/admin/src/services/users.js.map +1 -1
  174. package/dist/admin/admin/src/services/users.mjs.map +1 -1
  175. package/dist/admin/admin/src/translations/en.json.js +71 -4
  176. package/dist/admin/admin/src/translations/en.json.js.map +1 -1
  177. package/dist/admin/admin/src/translations/en.json.mjs +71 -4
  178. package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
  179. package/dist/admin/admin/src/translations/eu.json.js +1 -1
  180. package/dist/admin/admin/src/translations/eu.json.mjs +1 -1
  181. package/dist/admin/admin/src/utils/browserStrapi.js +1 -1
  182. package/dist/admin/admin/src/utils/browserStrapi.js.map +1 -1
  183. package/dist/admin/admin/src/utils/browserStrapi.mjs +1 -1
  184. package/dist/admin/admin/src/utils/browserStrapi.mjs.map +1 -1
  185. package/dist/admin/admin/src/utils/cookies.js +7 -6
  186. package/dist/admin/admin/src/utils/cookies.js.map +1 -1
  187. package/dist/admin/admin/src/utils/cookies.mjs +7 -6
  188. package/dist/admin/admin/src/utils/cookies.mjs.map +1 -1
  189. package/dist/admin/admin/src/utils/getFetchClient.js +24 -0
  190. package/dist/admin/admin/src/utils/getFetchClient.js.map +1 -1
  191. package/dist/admin/admin/src/utils/getFetchClient.mjs +24 -1
  192. package/dist/admin/admin/src/utils/getFetchClient.mjs.map +1 -1
  193. package/dist/admin/admin/tests/utils.js +2 -1
  194. package/dist/admin/admin/tests/utils.js.map +1 -1
  195. package/dist/admin/admin/tests/utils.mjs +2 -1
  196. package/dist/admin/admin/tests/utils.mjs.map +1 -1
  197. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.js +52 -22
  198. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.js.map +1 -1
  199. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.mjs +53 -23
  200. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.mjs.map +1 -1
  201. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AdminSeatInfo.js +16 -29
  202. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AdminSeatInfo.js.map +1 -1
  203. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AdminSeatInfo.mjs +18 -31
  204. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AdminSeatInfo.mjs.map +1 -1
  205. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/LicenseInfo.js +473 -0
  206. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/LicenseInfo.js.map +1 -0
  207. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/LicenseInfo.mjs +471 -0
  208. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/LicenseInfo.mjs.map +1 -0
  209. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js +2 -0
  210. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js.map +1 -1
  211. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs +2 -0
  212. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs.map +1 -1
  213. package/dist/admin/index.js +1 -0
  214. package/dist/admin/index.js.map +1 -1
  215. package/dist/admin/index.mjs +1 -1
  216. package/dist/admin/shared/utils/auth-cookie-path.js +13 -10
  217. package/dist/admin/shared/utils/auth-cookie-path.js.map +1 -1
  218. package/dist/admin/shared/utils/auth-cookie-path.mjs +13 -10
  219. package/dist/admin/shared/utils/auth-cookie-path.mjs.map +1 -1
  220. package/dist/admin/shared/utils/get-project-type.js +49 -0
  221. package/dist/admin/shared/utils/get-project-type.js.map +1 -0
  222. package/dist/admin/shared/utils/get-project-type.mjs +46 -0
  223. package/dist/admin/shared/utils/get-project-type.mjs.map +1 -0
  224. package/dist/admin/src/components/Filters.d.ts +1 -1
  225. package/dist/admin/src/components/Form.d.ts +1 -1
  226. package/dist/admin/src/constants.d.ts +10 -0
  227. package/dist/admin/src/pages/Settings/pages/ApiTokens/EditView/components/BoundRoute.d.ts +1 -1
  228. package/dist/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.d.ts +1 -1
  229. package/dist/admin/src/pages/Settings/pages/ApplicationInfo/components/DiagnosticSnapshotModal.d.ts +12 -0
  230. package/dist/admin/src/pages/Settings/pages/ApplicationInfo/components/PlanCard.d.ts +14 -0
  231. package/dist/admin/src/pages/Settings/pages/ApplicationInfo/components/SupportCard.d.ts +2 -0
  232. package/dist/admin/src/services/admin.d.ts +2 -2
  233. package/dist/admin/src/types/permissions.d.ts +1 -0
  234. package/dist/admin/src/utils/cookies.d.ts +7 -6
  235. package/dist/admin/src/utils/getFetchClient.d.ts +25 -0
  236. package/dist/ee/admin/src/hooks/useLicenseLimits.d.ts +29 -0
  237. package/dist/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.d.ts +6 -1
  238. package/dist/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/LicenseInfo.d.ts +2 -0
  239. package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.d.ts +2 -0
  240. package/dist/ee/server/src/audit-logs/entitlements.d.ts +8 -0
  241. package/dist/ee/server/src/audit-logs/entitlements.d.ts.map +1 -0
  242. package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts +16 -0
  243. package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts.map +1 -1
  244. package/dist/ee/server/src/controllers/admin.d.ts +36 -10
  245. package/dist/ee/server/src/controllers/admin.d.ts.map +1 -1
  246. package/dist/ee/server/src/controllers/authentication-utils/middlewares.d.ts.map +1 -1
  247. package/dist/ee/server/src/controllers/index.d.ts +36 -10
  248. package/dist/ee/server/src/controllers/index.d.ts.map +1 -1
  249. package/dist/ee/server/src/index.d.ts +36 -10
  250. package/dist/ee/server/src/index.d.ts.map +1 -1
  251. package/dist/ee/server/src/services/seat-enforcement.d.ts.map +1 -1
  252. package/dist/ee/server/src/validation/role.d.ts.map +1 -1
  253. package/dist/server/ee/server/src/audit-logs/entitlements.js +25 -0
  254. package/dist/server/ee/server/src/audit-logs/entitlements.js.map +1 -0
  255. package/dist/server/ee/server/src/audit-logs/entitlements.mjs +23 -0
  256. package/dist/server/ee/server/src/audit-logs/entitlements.mjs.map +1 -0
  257. package/dist/server/ee/server/src/audit-logs/services/lifecycles.js +20 -8
  258. package/dist/server/ee/server/src/audit-logs/services/lifecycles.js.map +1 -1
  259. package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs +19 -9
  260. package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs.map +1 -1
  261. package/dist/server/ee/server/src/audit-logs/utils/csv.js +3 -3
  262. package/dist/server/ee/server/src/audit-logs/utils/csv.js.map +1 -1
  263. package/dist/server/ee/server/src/audit-logs/utils/csv.mjs +3 -3
  264. package/dist/server/ee/server/src/audit-logs/utils/csv.mjs.map +1 -1
  265. package/dist/server/ee/server/src/controllers/admin.js +76 -3
  266. package/dist/server/ee/server/src/controllers/admin.js.map +1 -1
  267. package/dist/server/ee/server/src/controllers/admin.mjs +76 -3
  268. package/dist/server/ee/server/src/controllers/admin.mjs.map +1 -1
  269. package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.js +28 -10
  270. package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.js.map +1 -1
  271. package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.mjs +28 -10
  272. package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.mjs.map +1 -1
  273. package/dist/server/ee/server/src/index.js +2 -0
  274. package/dist/server/ee/server/src/index.js.map +1 -1
  275. package/dist/server/ee/server/src/index.mjs +2 -0
  276. package/dist/server/ee/server/src/index.mjs.map +1 -1
  277. package/dist/server/ee/server/src/services/seat-enforcement.js.map +1 -1
  278. package/dist/server/ee/server/src/services/seat-enforcement.mjs.map +1 -1
  279. package/dist/server/ee/server/src/validation/role.js +4 -2
  280. package/dist/server/ee/server/src/validation/role.js.map +1 -1
  281. package/dist/server/ee/server/src/validation/role.mjs +4 -2
  282. package/dist/server/ee/server/src/validation/role.mjs.map +1 -1
  283. package/dist/server/server/src/ai/services/ai.js.map +1 -1
  284. package/dist/server/server/src/ai/services/ai.mjs.map +1 -1
  285. package/dist/server/server/src/audit-logs/auth.js +72 -0
  286. package/dist/server/server/src/audit-logs/auth.js.map +1 -0
  287. package/dist/server/server/src/audit-logs/auth.mjs +67 -0
  288. package/dist/server/server/src/audit-logs/auth.mjs.map +1 -0
  289. package/dist/server/server/src/config/admin-actions.js +7 -0
  290. package/dist/server/server/src/config/admin-actions.js.map +1 -1
  291. package/dist/server/server/src/config/admin-actions.mjs +7 -0
  292. package/dist/server/server/src/config/admin-actions.mjs.map +1 -1
  293. package/dist/server/server/src/controllers/admin.js +17 -12
  294. package/dist/server/server/src/controllers/admin.js.map +1 -1
  295. package/dist/server/server/src/controllers/admin.mjs +17 -12
  296. package/dist/server/server/src/controllers/admin.mjs.map +1 -1
  297. package/dist/server/server/src/controllers/authentication.js +34 -8
  298. package/dist/server/server/src/controllers/authentication.js.map +1 -1
  299. package/dist/server/server/src/controllers/authentication.mjs +34 -8
  300. package/dist/server/server/src/controllers/authentication.mjs.map +1 -1
  301. package/dist/server/server/src/domain/permission/index.js.map +1 -1
  302. package/dist/server/server/src/domain/permission/index.mjs.map +1 -1
  303. package/dist/server/server/src/register.js +4 -0
  304. package/dist/server/server/src/register.js.map +1 -1
  305. package/dist/server/server/src/register.mjs +4 -0
  306. package/dist/server/server/src/register.mjs.map +1 -1
  307. package/dist/server/server/src/routes/admin.js +18 -0
  308. package/dist/server/server/src/routes/admin.js.map +1 -1
  309. package/dist/server/server/src/routes/admin.mjs +18 -0
  310. package/dist/server/server/src/routes/admin.mjs.map +1 -1
  311. package/dist/server/server/src/services/api-token.js +4 -8
  312. package/dist/server/server/src/services/api-token.js.map +1 -1
  313. package/dist/server/server/src/services/api-token.mjs +4 -8
  314. package/dist/server/server/src/services/api-token.mjs.map +1 -1
  315. package/dist/server/server/src/services/auth.js +4 -2
  316. package/dist/server/server/src/services/auth.js.map +1 -1
  317. package/dist/server/server/src/services/auth.mjs +4 -3
  318. package/dist/server/server/src/services/auth.mjs.map +1 -1
  319. package/dist/server/server/src/services/constants.js +4 -0
  320. package/dist/server/server/src/services/constants.js.map +1 -1
  321. package/dist/server/server/src/services/constants.mjs +4 -0
  322. package/dist/server/server/src/services/constants.mjs.map +1 -1
  323. package/dist/server/server/src/services/debug-dump.js +173 -0
  324. package/dist/server/server/src/services/debug-dump.js.map +1 -0
  325. package/dist/server/server/src/services/debug-dump.mjs +166 -0
  326. package/dist/server/server/src/services/debug-dump.mjs.map +1 -0
  327. package/dist/server/server/src/services/index.js +3 -1
  328. package/dist/server/server/src/services/index.js.map +1 -1
  329. package/dist/server/server/src/services/index.mjs +3 -1
  330. package/dist/server/server/src/services/index.mjs.map +1 -1
  331. package/dist/server/server/src/services/permission/rename-fields.js.map +1 -1
  332. package/dist/server/server/src/services/permission/rename-fields.mjs.map +1 -1
  333. package/dist/server/server/src/services/permission/sections-builder/handlers.js.map +1 -1
  334. package/dist/server/server/src/services/permission/sections-builder/handlers.mjs.map +1 -1
  335. package/dist/server/server/src/services/role.js +8 -5
  336. package/dist/server/server/src/services/role.js.map +1 -1
  337. package/dist/server/server/src/services/role.mjs +8 -5
  338. package/dist/server/server/src/services/role.mjs.map +1 -1
  339. package/dist/server/server/src/utils/debug-dump/redact.js +197 -0
  340. package/dist/server/server/src/utils/debug-dump/redact.js.map +1 -0
  341. package/dist/server/server/src/utils/debug-dump/redact.mjs +194 -0
  342. package/dist/server/server/src/utils/debug-dump/redact.mjs.map +1 -0
  343. package/dist/server/server/src/validation/admin-tokens.js +4 -4
  344. package/dist/server/server/src/validation/admin-tokens.js.map +1 -1
  345. package/dist/server/server/src/validation/admin-tokens.mjs +4 -4
  346. package/dist/server/server/src/validation/admin-tokens.mjs.map +1 -1
  347. package/dist/server/server/src/validation/api-tokens.js +4 -4
  348. package/dist/server/server/src/validation/api-tokens.js.map +1 -1
  349. package/dist/server/server/src/validation/api-tokens.mjs +4 -4
  350. package/dist/server/server/src/validation/api-tokens.mjs.map +1 -1
  351. package/dist/server/server/src/validation/role.js +6 -4
  352. package/dist/server/server/src/validation/role.js.map +1 -1
  353. package/dist/server/server/src/validation/role.mjs +6 -4
  354. package/dist/server/server/src/validation/role.mjs.map +1 -1
  355. package/dist/server/server/src/validation/transfer/token.js +4 -4
  356. package/dist/server/server/src/validation/transfer/token.js.map +1 -1
  357. package/dist/server/server/src/validation/transfer/token.mjs +4 -4
  358. package/dist/server/server/src/validation/transfer/token.mjs.map +1 -1
  359. package/dist/server/shared/utils/auth-cookie-path.js +13 -10
  360. package/dist/server/shared/utils/auth-cookie-path.js.map +1 -1
  361. package/dist/server/shared/utils/auth-cookie-path.mjs +13 -10
  362. package/dist/server/shared/utils/auth-cookie-path.mjs.map +1 -1
  363. package/dist/server/shared/utils/get-project-type.js +49 -0
  364. package/dist/server/shared/utils/get-project-type.js.map +1 -0
  365. package/dist/server/shared/utils/get-project-type.mjs +46 -0
  366. package/dist/server/shared/utils/get-project-type.mjs.map +1 -0
  367. package/dist/server/shared/utils/session-auth.js +70 -3
  368. package/dist/server/shared/utils/session-auth.js.map +1 -1
  369. package/dist/server/shared/utils/session-auth.mjs +70 -4
  370. package/dist/server/shared/utils/session-auth.mjs.map +1 -1
  371. package/dist/server/src/ai/services/ai.d.ts.map +1 -1
  372. package/dist/server/src/audit-logs/auth.d.ts +72 -0
  373. package/dist/server/src/audit-logs/auth.d.ts.map +1 -0
  374. package/dist/server/src/config/admin-actions.d.ts.map +1 -1
  375. package/dist/server/src/controllers/admin.d.ts +3 -0
  376. package/dist/server/src/controllers/admin.d.ts.map +1 -1
  377. package/dist/server/src/controllers/authentication.d.ts.map +1 -1
  378. package/dist/server/src/controllers/index.d.ts +3 -0
  379. package/dist/server/src/controllers/index.d.ts.map +1 -1
  380. package/dist/server/src/domain/permission/index.d.ts.map +1 -1
  381. package/dist/server/src/index.d.ts +8 -0
  382. package/dist/server/src/index.d.ts.map +1 -1
  383. package/dist/server/src/register.d.ts.map +1 -1
  384. package/dist/server/src/routes/admin.d.ts.map +1 -1
  385. package/dist/server/src/services/auth.d.ts +6 -0
  386. package/dist/server/src/services/auth.d.ts.map +1 -1
  387. package/dist/server/src/services/constants.d.ts +2 -0
  388. package/dist/server/src/services/constants.d.ts.map +1 -1
  389. package/dist/server/src/services/debug-dump.d.ts +9 -0
  390. package/dist/server/src/services/debug-dump.d.ts.map +1 -0
  391. package/dist/server/src/services/index.d.ts +5 -0
  392. package/dist/server/src/services/index.d.ts.map +1 -1
  393. package/dist/server/src/services/permission/rename-fields.d.ts.map +1 -1
  394. package/dist/server/src/services/permission/sections-builder/handlers.d.ts.map +1 -1
  395. package/dist/server/src/services/role.d.ts.map +1 -1
  396. package/dist/server/src/utils/debug-dump/redact.d.ts +8 -0
  397. package/dist/server/src/utils/debug-dump/redact.d.ts.map +1 -0
  398. package/dist/server/src/validation/role.d.ts.map +1 -1
  399. package/dist/shared/contracts/admin.d.ts +106 -0
  400. package/dist/shared/contracts/admin.d.ts.map +1 -1
  401. package/dist/shared/contracts/transfer.d.ts.map +1 -1
  402. package/dist/shared/utils/__tests__/get-project-type.test.d.ts +1 -0
  403. package/dist/shared/utils/__tests__/get-project-type.test.d.ts.map +1 -0
  404. package/dist/shared/utils/auth-cookie-path.d.ts +13 -10
  405. package/dist/shared/utils/auth-cookie-path.d.ts.map +1 -1
  406. package/dist/shared/utils/get-project-type.d.ts +37 -0
  407. package/dist/shared/utils/get-project-type.d.ts.map +1 -0
  408. package/dist/shared/utils/session-auth.d.ts +16 -0
  409. package/dist/shared/utils/session-auth.d.ts.map +1 -1
  410. package/package.json +8 -8
  411. package/dist/admin/admin/src/utils/getProjectType.js +0 -22
  412. package/dist/admin/admin/src/utils/getProjectType.js.map +0 -1
  413. package/dist/admin/admin/src/utils/getProjectType.mjs +0 -20
  414. package/dist/admin/admin/src/utils/getProjectType.mjs.map +0 -1
  415. package/dist/admin/src/utils/getProjectType.d.ts +0 -16
@@ -1 +1 @@
1
- {"version":3,"file":"role.mjs","sources":["../../../../../server/src/services/role.ts"],"sourcesContent":["import _, { omit, pick, differenceWith, differenceBy, isEqual } from 'lodash';\n/* eslint-disable @typescript-eslint/no-explicit-any */ // TODO: TS - Use database parameters interface when they are ready\n/* eslint-disable @typescript-eslint/default-param-last */\n\nimport { dates, arrays, hooks as hooksUtils, errors } from '@strapi/utils';\nimport type { Data } from '@strapi/types';\n\nimport permissionDomain from '../domain/permission';\nimport type { AdminUser, AdminRole, Permission } from '../../../shared/contracts/shared';\nimport type { Action } from '../domain/action';\n\nimport { validatePermissionsExist } from '../validation/permission';\nimport roleConstants from './constants';\nimport { getService } from '../utils';\n\nconst { SUPER_ADMIN_CODE, CONTENT_TYPE_SECTION } = roleConstants;\n\nconst { createAsyncSeriesWaterfallHook } = hooksUtils;\nconst { ApplicationError } = errors;\n\nconst hooks = {\n willResetSuperAdminPermissions: createAsyncSeriesWaterfallHook(),\n willValidateUpdatePermissions: createAsyncSeriesWaterfallHook(),\n};\n\nconst ACTIONS = {\n publish: 'plugin::content-manager.explorer.publish',\n};\n\nconst sanitizeRole = <T extends object>(role: T): Omit<T, 'users' | 'permissions'> =>\n omit(role, ['users', 'permissions']) as Omit<T, 'users' | 'permissions'>;\n\nexport type AdminRoleWithUsersCount = AdminRole & { usersCount: number };\n\nconst COMPARABLE_FIELDS = ['conditions', 'properties', 'subject', 'action', 'actionParameters'];\nconst pickComparableFields = (permission: Permission) => pick(permission, COMPARABLE_FIELDS);\n\nconst jsonClean = <T extends object>(data: T): T => JSON.parse(JSON.stringify(data));\n\n/**\n * Compare two permissions\n */\nconst arePermissionsEqual = (p1: Permission, p2: Permission): boolean => {\n if (p1.action === p2.action) {\n return isEqual(jsonClean(pickComparableFields(p1)), jsonClean(pickComparableFields(p2)));\n }\n\n return false;\n};\n\n/**\n * Create and save a role in database\n * @param attributes A partial role object\n */\nconst create = async (attributes: Partial<AdminRole>): Promise<AdminRole> => {\n const alreadyExists = await exists({ name: attributes.name });\n\n if (alreadyExists) {\n throw new ApplicationError(\n `The name must be unique and a role with name \\`${attributes.name}\\` already exists.`\n );\n }\n const autoGeneratedCode = `${_.kebabCase(attributes.name)}-${dates.timestampCode()}`;\n\n const rolesWithCode = {\n ...attributes,\n code: attributes.code || autoGeneratedCode,\n };\n\n const result = await strapi.db.query('admin::role').create({ data: rolesWithCode });\n strapi.eventHub.emit('role.create', { role: sanitizeRole(result) });\n\n return result;\n};\n\n/**\n * Find a role in database\n * @param params query params to find the role\n * @param populate\n */\nconst findOne = (params = {}, populate?: unknown): Promise<AdminRole> => {\n return strapi.db.query('admin::role').findOne({ where: params, populate });\n};\n\n/**\n * Find a role in database with usersCounts\n * @param params query params to find the role\n * @param populate\n */\nconst findOneWithUsersCount = async (\n params = {},\n populate?: unknown\n): Promise<AdminRoleWithUsersCount> => {\n const role = await strapi.db.query('admin::role').findOne({ where: params, populate });\n\n if (role) {\n role.usersCount = await getUsersCount(role.id);\n }\n\n return role;\n};\n\n/**\n * Find roles in database\n * @param params query params to find the roles\n * @param populate\n */\nconst find = (params = {}, populate: unknown): Promise<AdminRole[]> => {\n return strapi.db.query('admin::role').findMany({ where: params, populate });\n};\n\n/**\n * Find all roles in database\n */\nconst findAllWithUsersCount = async (params: any): Promise<AdminRoleWithUsersCount[]> => {\n const roles: AdminRoleWithUsersCount[] = await strapi.db\n .query('admin::role')\n .findMany(strapi.get('query-params').transform('admin::role', params));\n\n for (const role of roles) {\n role.usersCount = await getUsersCount(role.id);\n }\n\n return roles;\n};\n\n/**\n * Update a role in database\n * @param params query params to find the role to update\n * @param attributes A partial role object\n */\nconst update = async (params: any, attributes: Partial<AdminRole>): Promise<AdminRole> => {\n const sanitizedAttributes = _.omit(attributes, ['code']);\n\n if (_.has(params, 'id') && _.has(sanitizedAttributes, 'name')) {\n const alreadyExists = await exists({\n name: sanitizedAttributes.name,\n id: { $ne: params.id },\n });\n if (alreadyExists) {\n throw new ApplicationError(\n `The name must be unique and a role with name \\`${sanitizedAttributes.name}\\` already exists.`\n );\n }\n }\n\n const result = await strapi.db\n .query('admin::role')\n .update({ where: params, data: sanitizedAttributes });\n\n strapi.eventHub.emit('role.update', { role: sanitizeRole(result) });\n\n return result;\n};\n\n/**\n * Check if a role exists in database\n * @param params query params to find the role\n */\nconst exists = async (params = {} as unknown): Promise<boolean> => {\n const count = await strapi.db.query('admin::role').count({ where: params });\n return count > 0;\n};\n\n/**\n * Count the number of roles based on search params\n * @param params params used for the query\n */\nconst count = async (params = {} as any): Promise<number> => {\n return strapi.db.query('admin::role').count(params);\n};\n\n/**\n * Check if the given roles id can be deleted safely, throw otherwise\n * @param ids\n */\nconst checkRolesIdForDeletion = async (ids = [] as Data.ID[]) => {\n const superAdminRole = await getSuperAdmin();\n\n if (superAdminRole && arrays.includesString(ids, superAdminRole.id)) {\n throw new ApplicationError('You cannot delete the super admin role');\n }\n\n for (const roleId of ids) {\n const usersCount = await getUsersCount(roleId);\n if (usersCount !== 0) {\n throw new ApplicationError('Some roles are still assigned to some users');\n }\n }\n};\n\n/**\n * Delete roles in database if they have no user assigned\n * @param ids query params to find the roles\n */\nconst deleteByIds = async (ids = [] as Data.ID[]): Promise<AdminRole[]> => {\n await checkRolesIdForDeletion(ids);\n\n await getService('permission').deleteByRolesIds(ids);\n\n const deletedRoles: AdminRole[] = [];\n for (const id of ids) {\n const deletedRole = await strapi.db.query('admin::role').delete({ where: { id } });\n\n if (deletedRole) {\n strapi.eventHub.emit('role.delete', { role: deletedRole });\n deletedRoles.push(deletedRole);\n }\n }\n\n return deletedRoles;\n};\n\n/** Count the number of users for some roles\n */\nconst getUsersCount = async (roleId: Data.ID): Promise<number> => {\n return strapi.db.query('admin::user').count({ where: { roles: { id: roleId } } });\n};\n\n/** Returns admin role\n */\nconst getSuperAdmin = (): Promise<AdminRole | undefined> => findOne({ code: SUPER_ADMIN_CODE });\n\n/** Returns admin role with userCount\n * @returns {Promise<role>}\n */\nconst getSuperAdminWithUsersCount = () => findOneWithUsersCount({ code: SUPER_ADMIN_CODE });\n\n/** Create superAdmin, Author and Editor role is no role already exist\n */\nconst createRolesIfNoneExist = async () => {\n const someRolesExist = await exists();\n if (someRolesExist) {\n return;\n }\n\n const { actionProvider } = getService('permission');\n\n const allActions = actionProvider.values();\n const contentTypesActions = allActions.filter((a) => a.section === 'contentTypes');\n\n // create 3 roles\n const superAdminRole = await create({\n name: 'Super Admin',\n code: 'strapi-super-admin',\n description: 'Super Admins can access and manage all features and settings.',\n });\n\n await getService('user').assignARoleToAll(superAdminRole.id);\n\n const editorRole = await create({\n name: 'Editor',\n code: 'strapi-editor',\n description: 'Editors can manage and publish contents including those of other users.',\n });\n\n const authorRole = await create({\n name: 'Author',\n code: 'strapi-author',\n description: 'Authors can manage the content they have created.',\n });\n\n // create content-type permissions for each role\n // Exclude non-displayed content types (e.g. plugin::users-permissions.role) from Editor/Author\n // since those types are in explorer.read subjects only for super admin relation reads.\n const nonDisplayedUids = Object.values(strapi.contentTypes as Record<string, any>)\n .filter((ct) => ct?.pluginOptions?.['content-manager']?.visible === false)\n .map((ct) => ct.uid as string);\n\n const editorPermissions = getService('content-type').getPermissionsWithNestedFields(\n contentTypesActions,\n {\n restrictedSubjects: ['plugin::users-permissions.user', ...nonDisplayedUids],\n }\n );\n\n const authorPermissions = editorPermissions\n .filter(({ action }: any) => action !== ACTIONS.publish)\n .map((permission: any) =>\n permissionDomain.create({ ...permission, conditions: ['admin::is-creator'] })\n );\n\n editorPermissions.push(...getDefaultPluginPermissions());\n authorPermissions.push(...getDefaultPluginPermissions({ isAuthor: true }));\n\n // assign permissions to roles\n await addPermissions(editorRole.id, editorPermissions);\n await addPermissions(authorRole.id, authorPermissions);\n};\n\nconst getDefaultPluginPermissions = ({ isAuthor = false } = {}) => {\n const conditions = isAuthor ? ['admin::is-creator'] : [];\n\n // add plugin permissions for each role\n return [\n { action: 'plugin::upload.read', conditions },\n { action: 'plugin::upload.configure-view' },\n { action: 'plugin::upload.assets.create' },\n { action: 'plugin::upload.assets.update', conditions },\n { action: 'plugin::upload.assets.download' },\n { action: 'plugin::upload.assets.copy-link' },\n ].map(permissionDomain.create);\n};\n\n/** Display a warning if the role superAdmin doesn't exist\n * or if the role is not assigned to at least one user\n */\nconst displayWarningIfNoSuperAdmin = async () => {\n const superAdminRole = await getSuperAdminWithUsersCount();\n const someUsersExists = await getService('user').exists();\n\n if (!superAdminRole) {\n strapi.log.warn(\"Your application doesn't have a super admin role.\");\n } else if (someUsersExists && superAdminRole.usersCount === 0) {\n strapi.log.warn(\"Your application doesn't have a super admin user.\");\n }\n};\n\n/**\n * Assign permissions to a role\n * @param roleId - role Data.ID\n * @param {Array<Permission{action,subject,fields,conditions}>} permissions - permissions to assign to the role\n */\nconst assignPermissions = async (\n roleId: Data.ID,\n permissions: Array<Pick<Permission, 'action' | 'subject' | 'conditions'>> = []\n) => {\n await validatePermissionsExist(permissions);\n\n // Internal actions are not handled by the role service, so any permission\n // with an internal action is filtered out\n const internalActions = getService('permission')\n .actionProvider.values()\n .filter((action) => action.section === 'internal')\n .map((action) => action.actionId);\n\n const superAdmin = await getService('role').getSuperAdmin();\n const isSuperAdmin = superAdmin && superAdmin.id === roleId;\n const assignRole = <T extends object>(permission: T) => ({ ...permission, role: roleId });\n\n const permissionsWithRole = permissions\n // Add the role attribute to every permission\n .map(assignRole)\n // Transform each permission into a Permission instance\n .map(permissionDomain.create);\n\n const existingPermissions = await getService('permission').findMany({\n where: { role: { id: roleId } },\n populate: ['role'],\n });\n\n const permissionsToAdd = differenceWith(\n permissionsWithRole,\n existingPermissions,\n arePermissionsEqual\n ).filter((permission: Permission) => !internalActions.includes(permission.action));\n\n const permissionsToDelete = differenceWith(\n existingPermissions,\n permissionsWithRole,\n arePermissionsEqual\n ).filter((permission: Permission) => !internalActions.includes(permission.action));\n\n const permissionsToReturn = differenceBy(permissionsToDelete, existingPermissions, 'id');\n\n if (permissionsToDelete.length > 0) {\n await getService('permission').deleteByIds(\n permissionsToDelete.map((permission) => permission?.id)\n );\n }\n\n if (permissionsToAdd.length > 0) {\n const newPermissions = await addPermissions(roleId, permissionsToAdd);\n permissionsToReturn.push(...newPermissions);\n }\n\n if (!isSuperAdmin && (permissionsToAdd.length || permissionsToDelete.length)) {\n await getService('metrics').sendDidUpdateRolePermissions();\n }\n\n if (permissionsToAdd.length > 0 || permissionsToDelete.length > 0) {\n await getService('api-token-admin').syncPermissionsForRole(roleId);\n }\n\n return permissionsToReturn;\n};\n\nconst addPermissions = async (roleId: Data.ID, permissions: any) => {\n const { conditionProvider, createMany } = getService('permission');\n const { sanitizeConditions } = permissionDomain;\n\n const permissionsWithRole = permissions\n .map((permission: Permission) => ({ ...permission, role: roleId }))\n // @ts-expect-error - refactor domain/permission Condition type, as it's now expecting\n // a string but it should be a Condition interface\n .map(sanitizeConditions(conditionProvider))\n .map(permissionDomain.create);\n\n return createMany(permissionsWithRole);\n};\n\nconst isContentTypeAction = (action: Action) => action.section === CONTENT_TYPE_SECTION;\n\n/**\n * Reset super admin permissions (giving it all permissions)\n */\nconst resetSuperAdminPermissions = async () => {\n const superAdminRole = await getService('role').getSuperAdmin();\n if (!superAdminRole) {\n return;\n }\n\n const permissionService = getService('permission');\n const contentTypeService = getService('content-type');\n\n const allActions = permissionService.actionProvider.values() as Action[];\n\n const contentTypesActions = allActions.filter((action) => isContentTypeAction(action));\n const otherActions = allActions.filter((action) => !isContentTypeAction(action));\n\n // First, get the content-types permissions\n const permissions = contentTypeService.getPermissionsWithNestedFields(\n contentTypesActions\n ) as Permission[];\n\n // Then add every other permission\n const otherPermissions = otherActions.reduce((acc, action) => {\n const { actionId, subjects } = action;\n\n if (Array.isArray(subjects)) {\n acc.push(\n ...subjects.map((subject) => permissionDomain.create({ action: actionId, subject }))\n );\n } else {\n acc.push(permissionDomain.create({ action: actionId }));\n }\n\n return acc;\n }, [] as Permission[]);\n\n permissions.push(...otherPermissions);\n\n const transformedPermissions = (await hooks.willResetSuperAdminPermissions.call(\n permissions\n )) as Permission[];\n\n await assignPermissions(superAdminRole.id, transformedPermissions);\n};\n\n/**\n * Check if a user object includes the super admin role\n */\nconst hasSuperAdminRole = (user: AdminUser): boolean => {\n const roles = _.get(user, 'roles', []) as AdminRole[];\n\n return roles.map((role) => role?.code).includes(SUPER_ADMIN_CODE);\n};\n\nconst constants = {\n superAdminCode: SUPER_ADMIN_CODE,\n};\n\nexport default {\n hooks,\n sanitizeRole,\n create,\n findOne,\n findOneWithUsersCount,\n find,\n findAllWithUsersCount,\n update,\n exists,\n count,\n deleteByIds,\n getUsersCount,\n getSuperAdmin,\n getSuperAdminWithUsersCount,\n createRolesIfNoneExist,\n displayWarningIfNoSuperAdmin,\n addPermissions,\n hasSuperAdminRole,\n assignPermissions,\n resetSuperAdminPermissions,\n checkRolesIdForDeletion,\n constants,\n};\n"],"names":["SUPER_ADMIN_CODE","CONTENT_TYPE_SECTION","roleConstants","createAsyncSeriesWaterfallHook","hooksUtils","ApplicationError","errors","hooks","willResetSuperAdminPermissions","willValidateUpdatePermissions","ACTIONS","publish","sanitizeRole","role","omit","COMPARABLE_FIELDS","pickComparableFields","permission","pick","jsonClean","data","JSON","parse","stringify","arePermissionsEqual","p1","p2","action","isEqual","create","attributes","alreadyExists","exists","name","autoGeneratedCode","_","kebabCase","dates","timestampCode","rolesWithCode","code","result","strapi","db","query","eventHub","emit","findOne","params","populate","where","findOneWithUsersCount","usersCount","getUsersCount","id","find","findMany","findAllWithUsersCount","roles","get","transform","update","sanitizedAttributes","has","$ne","count","checkRolesIdForDeletion","ids","superAdminRole","getSuperAdmin","arrays","includesString","roleId","deleteByIds","getService","deleteByRolesIds","deletedRoles","deletedRole","delete","push","getSuperAdminWithUsersCount","createRolesIfNoneExist","someRolesExist","actionProvider","allActions","values","contentTypesActions","filter","a","section","description","assignARoleToAll","editorRole","authorRole","nonDisplayedUids","Object","contentTypes","ct","pluginOptions","visible","map","uid","editorPermissions","getPermissionsWithNestedFields","restrictedSubjects","authorPermissions","permissionDomain","conditions","getDefaultPluginPermissions","isAuthor","addPermissions","displayWarningIfNoSuperAdmin","someUsersExists","log","warn","assignPermissions","permissions","validatePermissionsExist","internalActions","actionId","superAdmin","isSuperAdmin","assignRole","permissionsWithRole","existingPermissions","permissionsToAdd","differenceWith","includes","permissionsToDelete","permissionsToReturn","differenceBy","length","newPermissions","sendDidUpdateRolePermissions","syncPermissionsForRole","conditionProvider","createMany","sanitizeConditions","isContentTypeAction","resetSuperAdminPermissions","permissionService","contentTypeService","otherActions","otherPermissions","reduce","acc","subjects","Array","isArray","subject","transformedPermissions","call","hasSuperAdminRole","user","constants","superAdminCode"],"mappings":";;;;;;;AAeA,MAAM,EAAEA,gBAAgB,EAAEC,oBAAoB,EAAE,GAAGC,WAAAA;AAEnD,MAAM,EAAEC,8BAA8B,EAAE,GAAGC,OAAAA;AAC3C,MAAM,EAAEC,gBAAgB,EAAE,GAAGC,MAAAA;AAE7B,MAAMC,KAAAA,GAAQ;IACZC,8BAAAA,EAAgCL,8BAAAA,EAAAA;IAChCM,6BAAAA,EAA+BN,8BAAAA;AACjC,CAAA;AAEA,MAAMO,OAAAA,GAAU;IACdC,OAAAA,EAAS;AACX,CAAA;AAEA,MAAMC,YAAAA,GAAe,CAAmBC,IAAAA,GACtCC,IAAAA,CAAKD,IAAAA,EAAM;AAAC,QAAA,OAAA;AAAS,QAAA;AAAc,KAAA,CAAA;AAIrC,MAAME,iBAAAA,GAAoB;AAAC,IAAA,YAAA;AAAc,IAAA,YAAA;AAAc,IAAA,SAAA;AAAW,IAAA,QAAA;AAAU,IAAA;AAAmB,CAAA;AAC/F,MAAMC,oBAAAA,GAAuB,CAACC,UAAAA,GAA2BC,IAAAA,CAAKD,UAAAA,EAAYF,iBAAAA,CAAAA;AAE1E,MAAMI,SAAAA,GAAY,CAAmBC,IAAAA,GAAeC,IAAAA,CAAKC,KAAK,CAACD,IAAAA,CAAKE,SAAS,CAACH,IAAAA,CAAAA,CAAAA;AAE9E;;IAGA,MAAMI,mBAAAA,GAAsB,CAACC,EAAAA,EAAgBC,EAAAA,GAAAA;AAC3C,IAAA,IAAID,EAAAA,CAAGE,MAAM,KAAKD,EAAAA,CAAGC,MAAM,EAAE;AAC3B,QAAA,OAAOC,OAAAA,CAAQT,SAAAA,CAAUH,oBAAAA,CAAqBS,EAAAA,CAAAA,CAAAA,EAAMN,UAAUH,oBAAAA,CAAqBU,EAAAA,CAAAA,CAAAA,CAAAA;AACrF,IAAA;IAEA,OAAO,KAAA;AACT,CAAA;AAEA;;;IAIA,MAAMG,SAAS,OAAOC,UAAAA,GAAAA;IACpB,MAAMC,aAAAA,GAAgB,MAAMC,MAAAA,CAAO;AAAEC,QAAAA,IAAAA,EAAMH,WAAWG;AAAK,KAAA,CAAA;AAE3D,IAAA,IAAIF,aAAAA,EAAe;QACjB,MAAM,IAAI1B,iBACR,CAAC,+CAA+C,EAAEyB,UAAAA,CAAWG,IAAI,CAAC,kBAAkB,CAAC,CAAA;AAEzF,IAAA;AACA,IAAA,MAAMC,iBAAAA,GAAoB,CAAA,EAAGC,UAAAA,CAAEC,SAAS,CAACN,UAAAA,CAAWG,IAAI,CAAA,CAAE,CAAC,EAAEI,KAAAA,CAAMC,aAAa,EAAA,CAAA,CAAI;AAEpF,IAAA,MAAMC,aAAAA,GAAgB;AACpB,QAAA,GAAGT,UAAU;QACbU,IAAAA,EAAMV,UAAAA,CAAWU,IAAI,IAAIN;AAC3B,KAAA;IAEA,MAAMO,MAAAA,GAAS,MAAMC,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAef,MAAM,CAAC;QAAET,IAAAA,EAAMmB;AAAc,KAAA,CAAA;AACjFG,IAAAA,MAAAA,CAAOG,QAAQ,CAACC,IAAI,CAAC,aAAA,EAAe;AAAEjC,QAAAA,IAAAA,EAAMD,YAAAA,CAAa6B,MAAAA;AAAQ,KAAA,CAAA;IAEjE,OAAOA,MAAAA;AACT,CAAA;AAEA;;;;AAIC,IACD,MAAMM,OAAAA,GAAU,CAACC,MAAAA,GAAS,EAAE,EAAEC,QAAAA,GAAAA;AAC5B,IAAA,OAAOP,OAAOC,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeG,OAAO,CAAC;QAAEG,KAAAA,EAAOF,MAAAA;AAAQC,QAAAA;AAAS,KAAA,CAAA;AAC1E,CAAA;AAEA;;;;AAIC,IACD,MAAME,qBAAAA,GAAwB,OAC5BH,MAAAA,GAAS,EAAE,EACXC,QAAAA,GAAAA;IAEA,MAAMpC,IAAAA,GAAO,MAAM6B,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeG,OAAO,CAAC;QAAEG,KAAAA,EAAOF,MAAAA;AAAQC,QAAAA;AAAS,KAAA,CAAA;AAEpF,IAAA,IAAIpC,IAAAA,EAAM;AACRA,QAAAA,IAAAA,CAAKuC,UAAU,GAAG,MAAMC,aAAAA,CAAcxC,KAAKyC,EAAE,CAAA;AAC/C,IAAA;IAEA,OAAOzC,IAAAA;AACT,CAAA;AAEA;;;;AAIC,IACD,MAAM0C,IAAAA,GAAO,CAACP,MAAAA,GAAS,EAAE,EAAEC,QAAAA,GAAAA;AACzB,IAAA,OAAOP,OAAOC,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeY,QAAQ,CAAC;QAAEN,KAAAA,EAAOF,MAAAA;AAAQC,QAAAA;AAAS,KAAA,CAAA;AAC3E,CAAA;AAEA;;IAGA,MAAMQ,wBAAwB,OAAOT,MAAAA,GAAAA;AACnC,IAAA,MAAMU,QAAmC,MAAMhB,MAAAA,CAAOC,EAAE,CACrDC,KAAK,CAAC,aAAA,CAAA,CACNY,QAAQ,CAACd,OAAOiB,GAAG,CAAC,cAAA,CAAA,CAAgBC,SAAS,CAAC,aAAA,EAAeZ,MAAAA,CAAAA,CAAAA;IAEhE,KAAK,MAAMnC,QAAQ6C,KAAAA,CAAO;AACxB7C,QAAAA,IAAAA,CAAKuC,UAAU,GAAG,MAAMC,aAAAA,CAAcxC,KAAKyC,EAAE,CAAA;AAC/C,IAAA;IAEA,OAAOI,KAAAA;AACT,CAAA;AAEA;;;;IAKA,MAAMG,MAAAA,GAAS,OAAOb,MAAAA,EAAalB,UAAAA,GAAAA;AACjC,IAAA,MAAMgC,mBAAAA,GAAsB3B,UAAAA,CAAErB,IAAI,CAACgB,UAAAA,EAAY;AAAC,QAAA;AAAO,KAAA,CAAA;IAEvD,IAAIK,UAAAA,CAAE4B,GAAG,CAACf,MAAAA,EAAQ,SAASb,UAAAA,CAAE4B,GAAG,CAACD,mBAAAA,EAAqB,MAAA,CAAA,EAAS;QAC7D,MAAM/B,aAAAA,GAAgB,MAAMC,MAAAA,CAAO;AACjCC,YAAAA,IAAAA,EAAM6B,oBAAoB7B,IAAI;YAC9BqB,EAAAA,EAAI;AAAEU,gBAAAA,GAAAA,EAAKhB,OAAOM;AAAG;AACvB,SAAA,CAAA;AACA,QAAA,IAAIvB,aAAAA,EAAe;YACjB,MAAM,IAAI1B,iBACR,CAAC,+CAA+C,EAAEyD,mBAAAA,CAAoB7B,IAAI,CAAC,kBAAkB,CAAC,CAAA;AAElG,QAAA;AACF,IAAA;IAEA,MAAMQ,MAAAA,GAAS,MAAMC,MAAAA,CAAOC,EAAE,CAC3BC,KAAK,CAAC,aAAA,CAAA,CACNiB,MAAM,CAAC;QAAEX,KAAAA,EAAOF,MAAAA;QAAQ5B,IAAAA,EAAM0C;AAAoB,KAAA,CAAA;AAErDpB,IAAAA,MAAAA,CAAOG,QAAQ,CAACC,IAAI,CAAC,aAAA,EAAe;AAAEjC,QAAAA,IAAAA,EAAMD,YAAAA,CAAa6B,MAAAA;AAAQ,KAAA,CAAA;IAEjE,OAAOA,MAAAA;AACT,CAAA;AAEA;;;AAGC,IACD,MAAMT,MAAAA,GAAS,OAAOgB,MAAAA,GAAS,EAAa,GAAA;IAC1C,MAAMiB,KAAAA,GAAQ,MAAMvB,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeqB,KAAK,CAAC;QAAEf,KAAAA,EAAOF;AAAO,KAAA,CAAA;AACzE,IAAA,OAAOiB,KAAAA,GAAQ,CAAA;AACjB,CAAA;AAEA;;;AAGC,IACD,MAAMA,KAAAA,GAAQ,OAAOjB,MAAAA,GAAS,EAAS,GAAA;AACrC,IAAA,OAAON,OAAOC,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeqB,KAAK,CAACjB,MAAAA,CAAAA;AAC9C,CAAA;AAEA;;;AAGC,IACD,MAAMkB,uBAAAA,GAA0B,OAAOC,GAAAA,GAAM,EAAE,GAAa;AAC1D,IAAA,MAAMC,iBAAiB,MAAMC,aAAAA,EAAAA;AAE7B,IAAA,IAAID,kBAAkBE,MAAAA,CAAOC,cAAc,CAACJ,GAAAA,EAAKC,cAAAA,CAAed,EAAE,CAAA,EAAG;AACnE,QAAA,MAAM,IAAIjD,gBAAAA,CAAiB,wCAAA,CAAA;AAC7B,IAAA;IAEA,KAAK,MAAMmE,UAAUL,GAAAA,CAAK;QACxB,MAAMf,UAAAA,GAAa,MAAMC,aAAAA,CAAcmB,MAAAA,CAAAA;AACvC,QAAA,IAAIpB,eAAe,CAAA,EAAG;AACpB,YAAA,MAAM,IAAI/C,gBAAAA,CAAiB,6CAAA,CAAA;AAC7B,QAAA;AACF,IAAA;AACF,CAAA;AAEA;;;AAGC,IACD,MAAMoE,WAAAA,GAAc,OAAON,GAAAA,GAAM,EAAE,GAAa;AAC9C,IAAA,MAAMD,uBAAAA,CAAwBC,GAAAA,CAAAA;IAE9B,MAAMO,UAAAA,CAAW,YAAA,CAAA,CAAcC,gBAAgB,CAACR,GAAAA,CAAAA;AAEhD,IAAA,MAAMS,eAA4B,EAAE;IACpC,KAAK,MAAMtB,MAAMa,GAAAA,CAAK;QACpB,MAAMU,WAAAA,GAAc,MAAMnC,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAekC,MAAM,CAAC;YAAE5B,KAAAA,EAAO;AAAEI,gBAAAA;AAAG;AAAE,SAAA,CAAA;AAEhF,QAAA,IAAIuB,WAAAA,EAAa;AACfnC,YAAAA,MAAAA,CAAOG,QAAQ,CAACC,IAAI,CAAC,aAAA,EAAe;gBAAEjC,IAAAA,EAAMgE;AAAY,aAAA,CAAA;AACxDD,YAAAA,YAAAA,CAAaG,IAAI,CAACF,WAAAA,CAAAA;AACpB,QAAA;AACF,IAAA;IAEA,OAAOD,YAAAA;AACT,CAAA;AAEA;IAEA,MAAMvB,gBAAgB,OAAOmB,MAAAA,GAAAA;AAC3B,IAAA,OAAO9B,OAAOC,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeqB,KAAK,CAAC;QAAEf,KAAAA,EAAO;YAAEQ,KAAAA,EAAO;gBAAEJ,EAAAA,EAAIkB;AAAO;AAAE;AAAE,KAAA,CAAA;AACjF,CAAA;AAEA;IAEA,MAAMH,aAAAA,GAAgB,IAAsCtB,OAAAA,CAAQ;QAAEP,IAAAA,EAAMxC;AAAiB,KAAA,CAAA;AAE7F;;IAGA,MAAMgF,2BAAAA,GAA8B,IAAM7B,qBAAAA,CAAsB;QAAEX,IAAAA,EAAMxC;AAAiB,KAAA,CAAA;AAEzF;AACC,IACD,MAAMiF,sBAAAA,GAAyB,UAAA;AAC7B,IAAA,MAAMC,iBAAiB,MAAMlD,MAAAA,EAAAA;AAC7B,IAAA,IAAIkD,cAAAA,EAAgB;AAClB,QAAA;AACF,IAAA;AAEA,IAAA,MAAM,EAAEC,cAAc,EAAE,GAAGT,UAAAA,CAAW,YAAA,CAAA;IAEtC,MAAMU,UAAAA,GAAaD,eAAeE,MAAM,EAAA;IACxC,MAAMC,mBAAAA,GAAsBF,WAAWG,MAAM,CAAC,CAACC,CAAAA,GAAMA,CAAAA,CAAEC,OAAO,KAAK,cAAA,CAAA;;IAGnE,MAAMrB,cAAAA,GAAiB,MAAMvC,MAAAA,CAAO;QAClCI,IAAAA,EAAM,aAAA;QACNO,IAAAA,EAAM,oBAAA;QACNkD,WAAAA,EAAa;AACf,KAAA,CAAA;AAEA,IAAA,MAAMhB,UAAAA,CAAW,MAAA,CAAA,CAAQiB,gBAAgB,CAACvB,eAAed,EAAE,CAAA;IAE3D,MAAMsC,UAAAA,GAAa,MAAM/D,MAAAA,CAAO;QAC9BI,IAAAA,EAAM,QAAA;QACNO,IAAAA,EAAM,eAAA;QACNkD,WAAAA,EAAa;AACf,KAAA,CAAA;IAEA,MAAMG,UAAAA,GAAa,MAAMhE,MAAAA,CAAO;QAC9BI,IAAAA,EAAM,QAAA;QACNO,IAAAA,EAAM,eAAA;QACNkD,WAAAA,EAAa;AACf,KAAA,CAAA;;;;IAKA,MAAMI,gBAAAA,GAAmBC,OAAOV,MAAM,CAAC3C,OAAOsD,YAAY,CAAA,CACvDT,MAAM,CAAC,CAACU,EAAAA,GAAOA,IAAIC,aAAAA,GAAgB,iBAAA,CAAkB,EAAEC,OAAAA,KAAY,KAAA,CAAA,CACnEC,GAAG,CAAC,CAACH,EAAAA,GAAOA,EAAAA,CAAGI,GAAG,CAAA;AAErB,IAAA,MAAMC,iBAAAA,GAAoB5B,UAAAA,CAAW,cAAA,CAAA,CAAgB6B,8BAA8B,CACjFjB,mBAAAA,EACA;QACEkB,kBAAAA,EAAoB;AAAC,YAAA,gCAAA;AAAqCV,YAAAA,GAAAA;AAAiB;AAC7E,KAAA,CAAA;AAGF,IAAA,MAAMW,oBAAoBH,iBAAAA,CACvBf,MAAM,CAAC,CAAC,EAAE5D,MAAM,EAAO,GAAKA,WAAWjB,OAAAA,CAAQC,OAAO,EACtDyF,GAAG,CAAC,CAACnF,UAAAA,GACJyF,gBAAAA,CAAiB7E,MAAM,CAAC;AAAE,YAAA,GAAGZ,UAAU;YAAE0F,UAAAA,EAAY;AAAC,gBAAA;AAAoB;AAAC,SAAA,CAAA,CAAA;AAG/EL,IAAAA,iBAAAA,CAAkBvB,IAAI,CAAA,GAAI6B,2BAAAA,EAAAA,CAAAA;IAC1BH,iBAAAA,CAAkB1B,IAAI,IAAI6B,2BAAAA,CAA4B;QAAEC,QAAAA,EAAU;AAAK,KAAA,CAAA,CAAA;;IAGvE,MAAMC,cAAAA,CAAelB,UAAAA,CAAWtC,EAAE,EAAEgD,iBAAAA,CAAAA;IACpC,MAAMQ,cAAAA,CAAejB,UAAAA,CAAWvC,EAAE,EAAEmD,iBAAAA,CAAAA;AACtC,CAAA;AAEA,MAAMG,2BAAAA,GAA8B,CAAC,EAAEC,QAAAA,GAAW,KAAK,EAAE,GAAG,EAAE,GAAA;AAC5D,IAAA,MAAMF,aAAaE,QAAAA,GAAW;AAAC,QAAA;AAAoB,KAAA,GAAG,EAAE;;IAGxD,OAAO;AACL,QAAA;YAAElF,MAAAA,EAAQ,qBAAA;AAAuBgF,YAAAA;AAAW,SAAA;AAC5C,QAAA;YAAEhF,MAAAA,EAAQ;AAAgC,SAAA;AAC1C,QAAA;YAAEA,MAAAA,EAAQ;AAA+B,SAAA;AACzC,QAAA;YAAEA,MAAAA,EAAQ,8BAAA;AAAgCgF,YAAAA;AAAW,SAAA;AACrD,QAAA;YAAEhF,MAAAA,EAAQ;AAAiC,SAAA;AAC3C,QAAA;YAAEA,MAAAA,EAAQ;AAAkC;KAC7C,CAACyE,GAAG,CAACM,gBAAAA,CAAiB7E,MAAM,CAAA;AAC/B,CAAA;AAEA;;AAEC,IACD,MAAMkF,4BAAAA,GAA+B,UAAA;AACnC,IAAA,MAAM3C,iBAAiB,MAAMY,2BAAAA,EAAAA;AAC7B,IAAA,MAAMgC,eAAAA,GAAkB,MAAMtC,UAAAA,CAAW,MAAA,CAAA,CAAQ1C,MAAM,EAAA;AAEvD,IAAA,IAAI,CAACoC,cAAAA,EAAgB;QACnB1B,MAAAA,CAAOuE,GAAG,CAACC,IAAI,CAAC,mDAAA,CAAA;AAClB,IAAA,CAAA,MAAO,IAAIF,eAAAA,IAAmB5C,cAAAA,CAAehB,UAAU,KAAK,CAAA,EAAG;QAC7DV,MAAAA,CAAOuE,GAAG,CAACC,IAAI,CAAC,mDAAA,CAAA;AAClB,IAAA;AACF,CAAA;AAEA;;;;AAIC,IACD,MAAMC,iBAAAA,GAAoB,OACxB3C,MAAAA,EACA4C,cAA4E,EAAE,GAAA;AAE9E,IAAA,MAAMC,wBAAAA,CAAyBD,WAAAA,CAAAA;;;IAI/B,MAAME,eAAAA,GAAkB5C,WAAW,YAAA,CAAA,CAChCS,cAAc,CAACE,MAAM,EAAA,CACrBE,MAAM,CAAC,CAAC5D,SAAWA,MAAAA,CAAO8D,OAAO,KAAK,UAAA,CAAA,CACtCW,GAAG,CAAC,CAACzE,MAAAA,GAAWA,OAAO4F,QAAQ,CAAA;AAElC,IAAA,MAAMC,UAAAA,GAAa,MAAM9C,UAAAA,CAAW,MAAA,CAAA,CAAQL,aAAa,EAAA;AACzD,IAAA,MAAMoD,YAAAA,GAAeD,UAAAA,IAAcA,UAAAA,CAAWlE,EAAE,KAAKkB,MAAAA;IACrD,MAAMkD,UAAAA,GAAa,CAAmBzG,UAAAA,IAAmB;AAAE,YAAA,GAAGA,UAAU;YAAEJ,IAAAA,EAAM2D;SAAO,CAAA;IAEvF,MAAMmD,mBAAAA,GAAsBP,WAC1B;KACChB,GAAG,CAACsB,WACL;KACCtB,GAAG,CAACM,iBAAiB7E,MAAM,CAAA;AAE9B,IAAA,MAAM+F,mBAAAA,GAAsB,MAAMlD,UAAAA,CAAW,YAAA,CAAA,CAAclB,QAAQ,CAAC;QAClEN,KAAAA,EAAO;YAAErC,IAAAA,EAAM;gBAAEyC,EAAAA,EAAIkB;AAAO;AAAE,SAAA;QAC9BvB,QAAAA,EAAU;AAAC,YAAA;AAAO;AACpB,KAAA,CAAA;AAEA,IAAA,MAAM4E,gBAAAA,GAAmBC,cAAAA,CACvBH,mBAAAA,EACAC,mBAAAA,EACApG,qBACA+D,MAAM,CAAC,CAACtE,UAAAA,GAA2B,CAACqG,eAAAA,CAAgBS,QAAQ,CAAC9G,WAAWU,MAAM,CAAA,CAAA;AAEhF,IAAA,MAAMqG,mBAAAA,GAAsBF,cAAAA,CAC1BF,mBAAAA,EACAD,mBAAAA,EACAnG,qBACA+D,MAAM,CAAC,CAACtE,UAAAA,GAA2B,CAACqG,eAAAA,CAAgBS,QAAQ,CAAC9G,WAAWU,MAAM,CAAA,CAAA;IAEhF,MAAMsG,mBAAAA,GAAsBC,YAAAA,CAAaF,mBAAAA,EAAqBJ,mBAAAA,EAAqB,IAAA,CAAA;IAEnF,IAAII,mBAAAA,CAAoBG,MAAM,GAAG,CAAA,EAAG;QAClC,MAAMzD,UAAAA,CAAW,cAAcD,WAAW,CACxCuD,oBAAoB5B,GAAG,CAAC,CAACnF,UAAAA,GAAeA,UAAAA,EAAYqC,EAAAA,CAAAA,CAAAA;AAExD,IAAA;IAEA,IAAIuE,gBAAAA,CAAiBM,MAAM,GAAG,CAAA,EAAG;QAC/B,MAAMC,cAAAA,GAAiB,MAAMtB,cAAAA,CAAetC,MAAAA,EAAQqD,gBAAAA,CAAAA;AACpDI,QAAAA,mBAAAA,CAAoBlD,IAAI,CAAA,GAAIqD,cAAAA,CAAAA;AAC9B,IAAA;IAEA,IAAI,CAACX,iBAAiBI,gBAAAA,CAAiBM,MAAM,IAAIH,mBAAAA,CAAoBG,MAAK,CAAA,EAAI;QAC5E,MAAMzD,UAAAA,CAAW,WAAW2D,4BAA4B,EAAA;AAC1D,IAAA;AAEA,IAAA,IAAIR,iBAAiBM,MAAM,GAAG,KAAKH,mBAAAA,CAAoBG,MAAM,GAAG,CAAA,EAAG;QACjE,MAAMzD,UAAAA,CAAW,iBAAA,CAAA,CAAmB4D,sBAAsB,CAAC9D,MAAAA,CAAAA;AAC7D,IAAA;IAEA,OAAOyD,mBAAAA;AACT,CAAA;AAEA,MAAMnB,cAAAA,GAAiB,OAAOtC,MAAAA,EAAiB4C,WAAAA,GAAAA;AAC7C,IAAA,MAAM,EAAEmB,iBAAiB,EAAEC,UAAU,EAAE,GAAG9D,UAAAA,CAAW,YAAA,CAAA;IACrD,MAAM,EAAE+D,kBAAkB,EAAE,GAAG/B,gBAAAA;AAE/B,IAAA,MAAMiB,sBAAsBP,WAAAA,CACzBhB,GAAG,CAAC,CAACnF,cAA4B;AAAE,YAAA,GAAGA,UAAU;YAAEJ,IAAAA,EAAM2D;AAAO,SAAA,EAChE;;AAEC4B,KAAAA,GAAG,CAACqC,kBAAAA,CAAmBF,iBAAAA,CAAAA,CAAAA,CACvBnC,GAAG,CAACM,iBAAiB7E,MAAM,CAAA;AAE9B,IAAA,OAAO2G,UAAAA,CAAWb,mBAAAA,CAAAA;AACpB,CAAA;AAEA,MAAMe,mBAAAA,GAAsB,CAAC/G,MAAAA,GAAmBA,MAAAA,CAAO8D,OAAO,KAAKxF,oBAAAA;AAEnE;;AAEC,IACD,MAAM0I,0BAAAA,GAA6B,UAAA;AACjC,IAAA,MAAMvE,cAAAA,GAAiB,MAAMM,UAAAA,CAAW,MAAA,CAAA,CAAQL,aAAa,EAAA;AAC7D,IAAA,IAAI,CAACD,cAAAA,EAAgB;AACnB,QAAA;AACF,IAAA;AAEA,IAAA,MAAMwE,oBAAoBlE,UAAAA,CAAW,YAAA,CAAA;AACrC,IAAA,MAAMmE,qBAAqBnE,UAAAA,CAAW,cAAA,CAAA;AAEtC,IAAA,MAAMU,UAAAA,GAAawD,iBAAAA,CAAkBzD,cAAc,CAACE,MAAM,EAAA;AAE1D,IAAA,MAAMC,sBAAsBF,UAAAA,CAAWG,MAAM,CAAC,CAAC5D,SAAW+G,mBAAAA,CAAoB/G,MAAAA,CAAAA,CAAAA;AAC9E,IAAA,MAAMmH,eAAe1D,UAAAA,CAAWG,MAAM,CAAC,CAAC5D,MAAAA,GAAW,CAAC+G,mBAAAA,CAAoB/G,MAAAA,CAAAA,CAAAA;;IAGxE,MAAMyF,WAAAA,GAAcyB,kBAAAA,CAAmBtC,8BAA8B,CACnEjB,mBAAAA,CAAAA;;AAIF,IAAA,MAAMyD,gBAAAA,GAAmBD,YAAAA,CAAaE,MAAM,CAAC,CAACC,GAAAA,EAAKtH,MAAAA,GAAAA;AACjD,QAAA,MAAM,EAAE4F,QAAQ,EAAE2B,QAAQ,EAAE,GAAGvH,MAAAA;QAE/B,IAAIwH,KAAAA,CAAMC,OAAO,CAACF,QAAAA,CAAAA,EAAW;YAC3BD,GAAAA,CAAIlE,IAAI,IACHmE,QAAAA,CAAS9C,GAAG,CAAC,CAACiD,OAAAA,GAAY3C,gBAAAA,CAAiB7E,MAAM,CAAC;oBAAEF,MAAAA,EAAQ4F,QAAAA;AAAU8B,oBAAAA;AAAQ,iBAAA,CAAA,CAAA,CAAA;QAErF,CAAA,MAAO;AACLJ,YAAAA,GAAAA,CAAIlE,IAAI,CAAC2B,gBAAAA,CAAiB7E,MAAM,CAAC;gBAAEF,MAAAA,EAAQ4F;AAAS,aAAA,CAAA,CAAA;AACtD,QAAA;QAEA,OAAO0B,GAAAA;AACT,IAAA,CAAA,EAAG,EAAE,CAAA;AAEL7B,IAAAA,WAAAA,CAAYrC,IAAI,CAAA,GAAIgE,gBAAAA,CAAAA;AAEpB,IAAA,MAAMO,yBAA0B,MAAM/I,KAAAA,CAAMC,8BAA8B,CAAC+I,IAAI,CAC7EnC,WAAAA,CAAAA;IAGF,MAAMD,iBAAAA,CAAkB/C,cAAAA,CAAed,EAAE,EAAEgG,sBAAAA,CAAAA;AAC7C,CAAA;AAEA;;IAGA,MAAME,oBAAoB,CAACC,IAAAA,GAAAA;AACzB,IAAA,MAAM/F,QAAQvB,UAAAA,CAAEwB,GAAG,CAAC8F,IAAAA,EAAM,SAAS,EAAE,CAAA;IAErC,OAAO/F,KAAAA,CAAM0C,GAAG,CAAC,CAACvF,OAASA,IAAAA,EAAM2B,IAAAA,CAAAA,CAAMuF,QAAQ,CAAC/H,gBAAAA,CAAAA;AAClD,CAAA;AAEA,MAAM0J,SAAAA,GAAY;IAChBC,cAAAA,EAAgB3J;AAClB,CAAA;AAEA,WAAe;AACbO,IAAAA,KAAAA;AACAK,IAAAA,YAAAA;AACAiB,IAAAA,MAAAA;AACAkB,IAAAA,OAAAA;AACAI,IAAAA,qBAAAA;AACAI,IAAAA,IAAAA;AACAE,IAAAA,qBAAAA;AACAI,IAAAA,MAAAA;AACA7B,IAAAA,MAAAA;AACAiC,IAAAA,KAAAA;AACAQ,IAAAA,WAAAA;AACApB,IAAAA,aAAAA;AACAgB,IAAAA,aAAAA;AACAW,IAAAA,2BAAAA;AACAC,IAAAA,sBAAAA;AACA8B,IAAAA,4BAAAA;AACAD,IAAAA,cAAAA;AACA0C,IAAAA,iBAAAA;AACArC,IAAAA,iBAAAA;AACAwB,IAAAA,0BAAAA;AACAzE,IAAAA,uBAAAA;AACAwF,IAAAA;AACF,CAAA;;;;"}
1
+ {"version":3,"file":"role.mjs","sources":["../../../../../server/src/services/role.ts"],"sourcesContent":["import _, { omit, pick, differenceWith, differenceBy, isEqual } from 'lodash';\n/* eslint-disable @typescript-eslint/no-explicit-any */ // TODO: TS - Use database parameters interface when they are ready\n/* eslint-disable @typescript-eslint/default-param-last */\n\nimport { dates, arrays, hooks as hooksUtils, errors } from '@strapi/utils';\nimport type { Data } from '@strapi/types';\n\nimport permissionDomain from '../domain/permission';\nimport type { AdminUser, AdminRole, Permission } from '../../../shared/contracts/shared';\nimport type { Action } from '../domain/action';\n\nimport { validatePermissionsExist } from '../validation/permission';\nimport roleConstants from './constants';\nimport { getService } from '../utils';\n\nconst { SUPER_ADMIN_CODE, CONTENT_TYPE_SECTION, ROLE_TEXT_MAX_LENGTH } = roleConstants;\n\nconst { createAsyncSeriesWaterfallHook } = hooksUtils;\nconst { ApplicationError } = errors;\n\nconst hooks = {\n willResetSuperAdminPermissions: createAsyncSeriesWaterfallHook(),\n willValidateUpdatePermissions: createAsyncSeriesWaterfallHook(),\n};\n\nconst ACTIONS = {\n publish: 'plugin::content-manager.explorer.publish',\n};\n\nconst sanitizeRole = <T extends object>(role: T): Omit<T, 'users' | 'permissions'> =>\n omit(role, ['users', 'permissions']) as Omit<T, 'users' | 'permissions'>;\n\nexport type AdminRoleWithUsersCount = AdminRole & { usersCount: number };\n\nconst COMPARABLE_FIELDS = ['conditions', 'properties', 'subject', 'action', 'actionParameters'];\nconst pickComparableFields = (permission: Permission) => pick(permission, COMPARABLE_FIELDS);\n\nconst jsonClean = <T extends object>(data: T): T => JSON.parse(JSON.stringify(data));\n\n/**\n * Compare two permissions\n */\nconst arePermissionsEqual = (p1: Permission, p2: Permission): boolean => {\n if (p1.action === p2.action) {\n return isEqual(jsonClean(pickComparableFields(p1)), jsonClean(pickComparableFields(p2)));\n }\n\n return false;\n};\n\n/**\n * Create and save a role in database\n * @param attributes A partial role object\n */\nconst create = async (attributes: Partial<AdminRole>): Promise<AdminRole> => {\n const alreadyExists = await exists({ name: attributes.name });\n\n if (alreadyExists) {\n throw new ApplicationError(\n `The name must be unique and a role with name \\`${attributes.name}\\` already exists.`\n );\n }\n // The kebab-cased name can be longer than the name itself, so trim it to keep the code within its column\n const codeSuffix = `-${dates.timestampCode()}`;\n const codePrefix = _.trimEnd(\n _.kebabCase(attributes.name).slice(0, ROLE_TEXT_MAX_LENGTH - codeSuffix.length),\n '-'\n );\n const autoGeneratedCode = `${codePrefix}${codeSuffix}`;\n\n const rolesWithCode = {\n ...attributes,\n code: attributes.code || autoGeneratedCode,\n };\n\n const result = await strapi.db.query('admin::role').create({ data: rolesWithCode });\n strapi.eventHub.emit('role.create', { role: sanitizeRole(result) });\n\n return result;\n};\n\n/**\n * Find a role in database\n * @param params query params to find the role\n * @param populate\n */\nconst findOne = (params = {}, populate?: unknown): Promise<AdminRole> => {\n return strapi.db.query('admin::role').findOne({ where: params, populate });\n};\n\n/**\n * Find a role in database with usersCounts\n * @param params query params to find the role\n * @param populate\n */\nconst findOneWithUsersCount = async (\n params = {},\n populate?: unknown\n): Promise<AdminRoleWithUsersCount> => {\n const role = await strapi.db.query('admin::role').findOne({ where: params, populate });\n\n if (role) {\n role.usersCount = await getUsersCount(role.id);\n }\n\n return role;\n};\n\n/**\n * Find roles in database\n * @param params query params to find the roles\n * @param populate\n */\nconst find = (params = {}, populate: unknown): Promise<AdminRole[]> => {\n return strapi.db.query('admin::role').findMany({ where: params, populate });\n};\n\n/**\n * Find all roles in database\n */\nconst findAllWithUsersCount = async (params: any): Promise<AdminRoleWithUsersCount[]> => {\n const roles: AdminRoleWithUsersCount[] = await strapi.db\n .query('admin::role')\n .findMany(strapi.get('query-params').transform('admin::role', params));\n\n for (const role of roles) {\n role.usersCount = await getUsersCount(role.id);\n }\n\n return roles;\n};\n\n/**\n * Update a role in database\n * @param params query params to find the role to update\n * @param attributes A partial role object\n */\nconst update = async (params: any, attributes: Partial<AdminRole>): Promise<AdminRole> => {\n const sanitizedAttributes = _.omit(attributes, ['code']);\n\n if (_.has(params, 'id') && _.has(sanitizedAttributes, 'name')) {\n const alreadyExists = await exists({\n name: sanitizedAttributes.name,\n id: { $ne: params.id },\n });\n if (alreadyExists) {\n throw new ApplicationError(\n `The name must be unique and a role with name \\`${sanitizedAttributes.name}\\` already exists.`\n );\n }\n }\n\n const result = await strapi.db\n .query('admin::role')\n .update({ where: params, data: sanitizedAttributes });\n\n strapi.eventHub.emit('role.update', { role: sanitizeRole(result) });\n\n return result;\n};\n\n/**\n * Check if a role exists in database\n * @param params query params to find the role\n */\nconst exists = async (params = {} as unknown): Promise<boolean> => {\n const count = await strapi.db.query('admin::role').count({ where: params });\n return count > 0;\n};\n\n/**\n * Count the number of roles based on search params\n * @param params params used for the query\n */\nconst count = async (params = {} as any): Promise<number> => {\n return strapi.db.query('admin::role').count(params);\n};\n\n/**\n * Check if the given roles id can be deleted safely, throw otherwise\n * @param ids\n */\nconst checkRolesIdForDeletion = async (ids = [] as Data.ID[]) => {\n const superAdminRole = await getSuperAdmin();\n\n if (superAdminRole && arrays.includesString(ids, superAdminRole.id)) {\n throw new ApplicationError('You cannot delete the super admin role');\n }\n\n for (const roleId of ids) {\n const usersCount = await getUsersCount(roleId);\n if (usersCount !== 0) {\n throw new ApplicationError('Some roles are still assigned to some users');\n }\n }\n};\n\n/**\n * Delete roles in database if they have no user assigned\n * @param ids query params to find the roles\n */\nconst deleteByIds = async (ids = [] as Data.ID[]): Promise<AdminRole[]> => {\n await checkRolesIdForDeletion(ids);\n\n await getService('permission').deleteByRolesIds(ids);\n\n const deletedRoles: AdminRole[] = [];\n for (const id of ids) {\n const deletedRole = await strapi.db.query('admin::role').delete({ where: { id } });\n\n if (deletedRole) {\n strapi.eventHub.emit('role.delete', { role: deletedRole });\n deletedRoles.push(deletedRole);\n }\n }\n\n return deletedRoles;\n};\n\n/** Count the number of users for some roles\n */\nconst getUsersCount = async (roleId: Data.ID): Promise<number> => {\n return strapi.db.query('admin::user').count({ where: { roles: { id: roleId } } });\n};\n\n/** Returns admin role\n */\nconst getSuperAdmin = (): Promise<AdminRole | undefined> => findOne({ code: SUPER_ADMIN_CODE });\n\n/** Returns admin role with userCount\n * @returns {Promise<role>}\n */\nconst getSuperAdminWithUsersCount = () => findOneWithUsersCount({ code: SUPER_ADMIN_CODE });\n\n/** Create superAdmin, Author and Editor role is no role already exist\n */\nconst createRolesIfNoneExist = async () => {\n const someRolesExist = await exists();\n if (someRolesExist) {\n return;\n }\n\n const { actionProvider } = getService('permission');\n\n const allActions = actionProvider.values();\n const contentTypesActions = allActions.filter((a) => a.section === 'contentTypes');\n\n // create 3 roles\n const superAdminRole = await create({\n name: 'Super Admin',\n code: 'strapi-super-admin',\n description: 'Super Admins can access and manage all features and settings.',\n });\n\n await getService('user').assignARoleToAll(superAdminRole.id);\n\n const editorRole = await create({\n name: 'Editor',\n code: 'strapi-editor',\n description: 'Editors can manage and publish contents including those of other users.',\n });\n\n const authorRole = await create({\n name: 'Author',\n code: 'strapi-author',\n description: 'Authors can manage the content they have created.',\n });\n\n // create content-type permissions for each role\n // Exclude non-displayed content types (e.g. plugin::users-permissions.role) from Editor/Author\n // since those types are in explorer.read subjects only for super admin relation reads.\n const nonDisplayedUids = Object.values(strapi.contentTypes as Record<string, any>)\n .filter((ct) => ct?.pluginOptions?.['content-manager']?.visible === false)\n .map((ct) => ct.uid as string);\n\n const editorPermissions = getService('content-type').getPermissionsWithNestedFields(\n contentTypesActions,\n {\n restrictedSubjects: ['plugin::users-permissions.user', ...nonDisplayedUids],\n }\n );\n\n const authorPermissions = editorPermissions\n .filter(({ action }: any) => action !== ACTIONS.publish)\n .map((permission: any) =>\n permissionDomain.create({ ...permission, conditions: ['admin::is-creator'] })\n );\n\n editorPermissions.push(...getDefaultPluginPermissions());\n authorPermissions.push(...getDefaultPluginPermissions({ isAuthor: true }));\n\n // assign permissions to roles\n await addPermissions(editorRole.id, editorPermissions);\n await addPermissions(authorRole.id, authorPermissions);\n};\n\nconst getDefaultPluginPermissions = ({ isAuthor = false } = {}) => {\n const conditions = isAuthor ? ['admin::is-creator'] : [];\n\n // add plugin permissions for each role\n return [\n { action: 'plugin::upload.read', conditions },\n { action: 'plugin::upload.configure-view' },\n { action: 'plugin::upload.assets.create' },\n { action: 'plugin::upload.assets.update', conditions },\n { action: 'plugin::upload.assets.download' },\n { action: 'plugin::upload.assets.copy-link' },\n ].map(permissionDomain.create);\n};\n\n/** Display a warning if the role superAdmin doesn't exist\n * or if the role is not assigned to at least one user\n */\nconst displayWarningIfNoSuperAdmin = async () => {\n const superAdminRole = await getSuperAdminWithUsersCount();\n const someUsersExists = await getService('user').exists();\n\n if (!superAdminRole) {\n strapi.log.warn(\"Your application doesn't have a super admin role.\");\n } else if (someUsersExists && superAdminRole.usersCount === 0) {\n strapi.log.warn(\"Your application doesn't have a super admin user.\");\n }\n};\n\n/**\n * Assign permissions to a role\n * @param roleId - role Data.ID\n * @param {Array<Permission{action,subject,fields,conditions}>} permissions - permissions to assign to the role\n */\nconst assignPermissions = async (\n roleId: Data.ID,\n permissions: Array<Pick<Permission, 'action' | 'subject' | 'conditions'>> = []\n) => {\n await validatePermissionsExist(permissions);\n\n // Internal actions are not handled by the role service, so any permission\n // with an internal action is filtered out\n const internalActions = new Set(\n getService('permission')\n .actionProvider.values()\n .filter((action) => action.section === 'internal')\n .map((action) => action.actionId)\n );\n\n const superAdmin = await getService('role').getSuperAdmin();\n const isSuperAdmin = superAdmin && superAdmin.id === roleId;\n const assignRole = <T extends object>(permission: T) => ({ ...permission, role: roleId });\n\n const permissionsWithRole = permissions\n // Add the role attribute to every permission\n .map(assignRole)\n // Transform each permission into a Permission instance\n .map(permissionDomain.create);\n\n const existingPermissions = await getService('permission').findMany({\n where: { role: { id: roleId } },\n populate: ['role'],\n });\n\n const permissionsToAdd = differenceWith(\n permissionsWithRole,\n existingPermissions,\n arePermissionsEqual\n ).filter((permission: Permission) => !internalActions.has(permission.action));\n\n const permissionsToDelete = differenceWith(\n existingPermissions,\n permissionsWithRole,\n arePermissionsEqual\n ).filter((permission: Permission) => !internalActions.has(permission.action));\n\n const permissionsToReturn = differenceBy(permissionsToDelete, existingPermissions, 'id');\n\n if (permissionsToDelete.length > 0) {\n await getService('permission').deleteByIds(\n permissionsToDelete.map((permission) => permission?.id)\n );\n }\n\n if (permissionsToAdd.length > 0) {\n const newPermissions = await addPermissions(roleId, permissionsToAdd);\n permissionsToReturn.push(...newPermissions);\n }\n\n if (!isSuperAdmin && (permissionsToAdd.length || permissionsToDelete.length)) {\n await getService('metrics').sendDidUpdateRolePermissions();\n }\n\n if (permissionsToAdd.length > 0 || permissionsToDelete.length > 0) {\n await getService('api-token-admin').syncPermissionsForRole(roleId);\n }\n\n return permissionsToReturn;\n};\n\nconst addPermissions = async (roleId: Data.ID, permissions: any) => {\n const { conditionProvider, createMany } = getService('permission');\n const { sanitizeConditions } = permissionDomain;\n\n const permissionsWithRole = permissions\n .map((permission: Permission) => ({ ...permission, role: roleId }))\n // @ts-expect-error - refactor domain/permission Condition type, as it's now expecting\n // a string but it should be a Condition interface\n .map(sanitizeConditions(conditionProvider))\n .map(permissionDomain.create);\n\n return createMany(permissionsWithRole);\n};\n\nconst isContentTypeAction = (action: Action) => action.section === CONTENT_TYPE_SECTION;\n\n/**\n * Reset super admin permissions (giving it all permissions)\n */\nconst resetSuperAdminPermissions = async () => {\n const superAdminRole = await getService('role').getSuperAdmin();\n if (!superAdminRole) {\n return;\n }\n\n const permissionService = getService('permission');\n const contentTypeService = getService('content-type');\n\n const allActions = permissionService.actionProvider.values() as Action[];\n\n const contentTypesActions = allActions.filter((action) => isContentTypeAction(action));\n const otherActions = allActions.filter((action) => !isContentTypeAction(action));\n\n // First, get the content-types permissions\n const permissions = contentTypeService.getPermissionsWithNestedFields(\n contentTypesActions\n ) as Permission[];\n\n // Then add every other permission\n const otherPermissions = otherActions.reduce((acc, action) => {\n const { actionId, subjects } = action;\n\n if (Array.isArray(subjects)) {\n acc.push(\n ...subjects.map((subject) => permissionDomain.create({ action: actionId, subject }))\n );\n } else {\n acc.push(permissionDomain.create({ action: actionId }));\n }\n\n return acc;\n }, [] as Permission[]);\n\n permissions.push(...otherPermissions);\n\n const transformedPermissions = (await hooks.willResetSuperAdminPermissions.call(\n permissions\n )) as Permission[];\n\n await assignPermissions(superAdminRole.id, transformedPermissions);\n};\n\n/**\n * Check if a user object includes the super admin role\n */\nconst hasSuperAdminRole = (user: AdminUser): boolean => {\n const roles = _.get(user, 'roles', []) as AdminRole[];\n\n return roles.map((role) => role?.code).includes(SUPER_ADMIN_CODE);\n};\n\nconst constants = {\n superAdminCode: SUPER_ADMIN_CODE,\n};\n\nexport default {\n hooks,\n sanitizeRole,\n create,\n findOne,\n findOneWithUsersCount,\n find,\n findAllWithUsersCount,\n update,\n exists,\n count,\n deleteByIds,\n getUsersCount,\n getSuperAdmin,\n getSuperAdminWithUsersCount,\n createRolesIfNoneExist,\n displayWarningIfNoSuperAdmin,\n addPermissions,\n hasSuperAdminRole,\n assignPermissions,\n resetSuperAdminPermissions,\n checkRolesIdForDeletion,\n constants,\n};\n"],"names":["SUPER_ADMIN_CODE","CONTENT_TYPE_SECTION","ROLE_TEXT_MAX_LENGTH","roleConstants","createAsyncSeriesWaterfallHook","hooksUtils","ApplicationError","errors","hooks","willResetSuperAdminPermissions","willValidateUpdatePermissions","ACTIONS","publish","sanitizeRole","role","omit","COMPARABLE_FIELDS","pickComparableFields","permission","pick","jsonClean","data","JSON","parse","stringify","arePermissionsEqual","p1","p2","action","isEqual","create","attributes","alreadyExists","exists","name","codeSuffix","dates","timestampCode","codePrefix","_","trimEnd","kebabCase","slice","length","autoGeneratedCode","rolesWithCode","code","result","strapi","db","query","eventHub","emit","findOne","params","populate","where","findOneWithUsersCount","usersCount","getUsersCount","id","find","findMany","findAllWithUsersCount","roles","get","transform","update","sanitizedAttributes","has","$ne","count","checkRolesIdForDeletion","ids","superAdminRole","getSuperAdmin","arrays","includesString","roleId","deleteByIds","getService","deleteByRolesIds","deletedRoles","deletedRole","delete","push","getSuperAdminWithUsersCount","createRolesIfNoneExist","someRolesExist","actionProvider","allActions","values","contentTypesActions","filter","a","section","description","assignARoleToAll","editorRole","authorRole","nonDisplayedUids","Object","contentTypes","ct","pluginOptions","visible","map","uid","editorPermissions","getPermissionsWithNestedFields","restrictedSubjects","authorPermissions","permissionDomain","conditions","getDefaultPluginPermissions","isAuthor","addPermissions","displayWarningIfNoSuperAdmin","someUsersExists","log","warn","assignPermissions","permissions","validatePermissionsExist","internalActions","Set","actionId","superAdmin","isSuperAdmin","assignRole","permissionsWithRole","existingPermissions","permissionsToAdd","differenceWith","permissionsToDelete","permissionsToReturn","differenceBy","newPermissions","sendDidUpdateRolePermissions","syncPermissionsForRole","conditionProvider","createMany","sanitizeConditions","isContentTypeAction","resetSuperAdminPermissions","permissionService","contentTypeService","otherActions","otherPermissions","reduce","acc","subjects","Array","isArray","subject","transformedPermissions","call","hasSuperAdminRole","user","includes","constants","superAdminCode"],"mappings":";;;;;;;AAeA,MAAM,EAAEA,gBAAgB,EAAEC,oBAAoB,EAAEC,oBAAoB,EAAE,GAAGC,WAAAA;AAEzE,MAAM,EAAEC,8BAA8B,EAAE,GAAGC,OAAAA;AAC3C,MAAM,EAAEC,gBAAgB,EAAE,GAAGC,MAAAA;AAE7B,MAAMC,KAAAA,GAAQ;IACZC,8BAAAA,EAAgCL,8BAAAA,EAAAA;IAChCM,6BAAAA,EAA+BN,8BAAAA;AACjC,CAAA;AAEA,MAAMO,OAAAA,GAAU;IACdC,OAAAA,EAAS;AACX,CAAA;AAEA,MAAMC,YAAAA,GAAe,CAAmBC,IAAAA,GACtCC,IAAAA,CAAKD,IAAAA,EAAM;AAAC,QAAA,OAAA;AAAS,QAAA;AAAc,KAAA,CAAA;AAIrC,MAAME,iBAAAA,GAAoB;AAAC,IAAA,YAAA;AAAc,IAAA,YAAA;AAAc,IAAA,SAAA;AAAW,IAAA,QAAA;AAAU,IAAA;AAAmB,CAAA;AAC/F,MAAMC,oBAAAA,GAAuB,CAACC,UAAAA,GAA2BC,IAAAA,CAAKD,UAAAA,EAAYF,iBAAAA,CAAAA;AAE1E,MAAMI,SAAAA,GAAY,CAAmBC,IAAAA,GAAeC,IAAAA,CAAKC,KAAK,CAACD,IAAAA,CAAKE,SAAS,CAACH,IAAAA,CAAAA,CAAAA;AAE9E;;IAGA,MAAMI,mBAAAA,GAAsB,CAACC,EAAAA,EAAgBC,EAAAA,GAAAA;AAC3C,IAAA,IAAID,EAAAA,CAAGE,MAAM,KAAKD,EAAAA,CAAGC,MAAM,EAAE;AAC3B,QAAA,OAAOC,OAAAA,CAAQT,SAAAA,CAAUH,oBAAAA,CAAqBS,EAAAA,CAAAA,CAAAA,EAAMN,UAAUH,oBAAAA,CAAqBU,EAAAA,CAAAA,CAAAA,CAAAA;AACrF,IAAA;IAEA,OAAO,KAAA;AACT,CAAA;AAEA;;;IAIA,MAAMG,SAAS,OAAOC,UAAAA,GAAAA;IACpB,MAAMC,aAAAA,GAAgB,MAAMC,MAAAA,CAAO;AAAEC,QAAAA,IAAAA,EAAMH,WAAWG;AAAK,KAAA,CAAA;AAE3D,IAAA,IAAIF,aAAAA,EAAe;QACjB,MAAM,IAAI1B,iBACR,CAAC,+CAA+C,EAAEyB,UAAAA,CAAWG,IAAI,CAAC,kBAAkB,CAAC,CAAA;AAEzF,IAAA;;AAEA,IAAA,MAAMC,aAAa,CAAC,CAAC,EAAEC,KAAAA,CAAMC,aAAa,EAAA,CAAA,CAAI;AAC9C,IAAA,MAAMC,aAAaC,UAAAA,CAAEC,OAAO,CAC1BD,UAAAA,CAAEE,SAAS,CAACV,UAAAA,CAAWG,IAAI,CAAA,CAAEQ,KAAK,CAAC,CAAA,EAAGxC,oBAAAA,GAAuBiC,UAAAA,CAAWQ,MAAM,CAAA,EAC9E,GAAA,CAAA;IAEF,MAAMC,iBAAAA,GAAoB,CAAA,EAAGN,UAAAA,CAAAA,EAAaH,UAAAA,CAAAA,CAAY;AAEtD,IAAA,MAAMU,aAAAA,GAAgB;AACpB,QAAA,GAAGd,UAAU;QACbe,IAAAA,EAAMf,UAAAA,CAAWe,IAAI,IAAIF;AAC3B,KAAA;IAEA,MAAMG,MAAAA,GAAS,MAAMC,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAepB,MAAM,CAAC;QAAET,IAAAA,EAAMwB;AAAc,KAAA,CAAA;AACjFG,IAAAA,MAAAA,CAAOG,QAAQ,CAACC,IAAI,CAAC,aAAA,EAAe;AAAEtC,QAAAA,IAAAA,EAAMD,YAAAA,CAAakC,MAAAA;AAAQ,KAAA,CAAA;IAEjE,OAAOA,MAAAA;AACT,CAAA;AAEA;;;;AAIC,IACD,MAAMM,OAAAA,GAAU,CAACC,MAAAA,GAAS,EAAE,EAAEC,QAAAA,GAAAA;AAC5B,IAAA,OAAOP,OAAOC,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeG,OAAO,CAAC;QAAEG,KAAAA,EAAOF,MAAAA;AAAQC,QAAAA;AAAS,KAAA,CAAA;AAC1E,CAAA;AAEA;;;;AAIC,IACD,MAAME,qBAAAA,GAAwB,OAC5BH,MAAAA,GAAS,EAAE,EACXC,QAAAA,GAAAA;IAEA,MAAMzC,IAAAA,GAAO,MAAMkC,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeG,OAAO,CAAC;QAAEG,KAAAA,EAAOF,MAAAA;AAAQC,QAAAA;AAAS,KAAA,CAAA;AAEpF,IAAA,IAAIzC,IAAAA,EAAM;AACRA,QAAAA,IAAAA,CAAK4C,UAAU,GAAG,MAAMC,aAAAA,CAAc7C,KAAK8C,EAAE,CAAA;AAC/C,IAAA;IAEA,OAAO9C,IAAAA;AACT,CAAA;AAEA;;;;AAIC,IACD,MAAM+C,IAAAA,GAAO,CAACP,MAAAA,GAAS,EAAE,EAAEC,QAAAA,GAAAA;AACzB,IAAA,OAAOP,OAAOC,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeY,QAAQ,CAAC;QAAEN,KAAAA,EAAOF,MAAAA;AAAQC,QAAAA;AAAS,KAAA,CAAA;AAC3E,CAAA;AAEA;;IAGA,MAAMQ,wBAAwB,OAAOT,MAAAA,GAAAA;AACnC,IAAA,MAAMU,QAAmC,MAAMhB,MAAAA,CAAOC,EAAE,CACrDC,KAAK,CAAC,aAAA,CAAA,CACNY,QAAQ,CAACd,OAAOiB,GAAG,CAAC,cAAA,CAAA,CAAgBC,SAAS,CAAC,aAAA,EAAeZ,MAAAA,CAAAA,CAAAA;IAEhE,KAAK,MAAMxC,QAAQkD,KAAAA,CAAO;AACxBlD,QAAAA,IAAAA,CAAK4C,UAAU,GAAG,MAAMC,aAAAA,CAAc7C,KAAK8C,EAAE,CAAA;AAC/C,IAAA;IAEA,OAAOI,KAAAA;AACT,CAAA;AAEA;;;;IAKA,MAAMG,MAAAA,GAAS,OAAOb,MAAAA,EAAavB,UAAAA,GAAAA;AACjC,IAAA,MAAMqC,mBAAAA,GAAsB7B,UAAAA,CAAExB,IAAI,CAACgB,UAAAA,EAAY;AAAC,QAAA;AAAO,KAAA,CAAA;IAEvD,IAAIQ,UAAAA,CAAE8B,GAAG,CAACf,MAAAA,EAAQ,SAASf,UAAAA,CAAE8B,GAAG,CAACD,mBAAAA,EAAqB,MAAA,CAAA,EAAS;QAC7D,MAAMpC,aAAAA,GAAgB,MAAMC,MAAAA,CAAO;AACjCC,YAAAA,IAAAA,EAAMkC,oBAAoBlC,IAAI;YAC9B0B,EAAAA,EAAI;AAAEU,gBAAAA,GAAAA,EAAKhB,OAAOM;AAAG;AACvB,SAAA,CAAA;AACA,QAAA,IAAI5B,aAAAA,EAAe;YACjB,MAAM,IAAI1B,iBACR,CAAC,+CAA+C,EAAE8D,mBAAAA,CAAoBlC,IAAI,CAAC,kBAAkB,CAAC,CAAA;AAElG,QAAA;AACF,IAAA;IAEA,MAAMa,MAAAA,GAAS,MAAMC,MAAAA,CAAOC,EAAE,CAC3BC,KAAK,CAAC,aAAA,CAAA,CACNiB,MAAM,CAAC;QAAEX,KAAAA,EAAOF,MAAAA;QAAQjC,IAAAA,EAAM+C;AAAoB,KAAA,CAAA;AAErDpB,IAAAA,MAAAA,CAAOG,QAAQ,CAACC,IAAI,CAAC,aAAA,EAAe;AAAEtC,QAAAA,IAAAA,EAAMD,YAAAA,CAAakC,MAAAA;AAAQ,KAAA,CAAA;IAEjE,OAAOA,MAAAA;AACT,CAAA;AAEA;;;AAGC,IACD,MAAMd,MAAAA,GAAS,OAAOqB,MAAAA,GAAS,EAAa,GAAA;IAC1C,MAAMiB,KAAAA,GAAQ,MAAMvB,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeqB,KAAK,CAAC;QAAEf,KAAAA,EAAOF;AAAO,KAAA,CAAA;AACzE,IAAA,OAAOiB,KAAAA,GAAQ,CAAA;AACjB,CAAA;AAEA;;;AAGC,IACD,MAAMA,KAAAA,GAAQ,OAAOjB,MAAAA,GAAS,EAAS,GAAA;AACrC,IAAA,OAAON,OAAOC,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeqB,KAAK,CAACjB,MAAAA,CAAAA;AAC9C,CAAA;AAEA;;;AAGC,IACD,MAAMkB,uBAAAA,GAA0B,OAAOC,GAAAA,GAAM,EAAE,GAAa;AAC1D,IAAA,MAAMC,iBAAiB,MAAMC,aAAAA,EAAAA;AAE7B,IAAA,IAAID,kBAAkBE,MAAAA,CAAOC,cAAc,CAACJ,GAAAA,EAAKC,cAAAA,CAAed,EAAE,CAAA,EAAG;AACnE,QAAA,MAAM,IAAItD,gBAAAA,CAAiB,wCAAA,CAAA;AAC7B,IAAA;IAEA,KAAK,MAAMwE,UAAUL,GAAAA,CAAK;QACxB,MAAMf,UAAAA,GAAa,MAAMC,aAAAA,CAAcmB,MAAAA,CAAAA;AACvC,QAAA,IAAIpB,eAAe,CAAA,EAAG;AACpB,YAAA,MAAM,IAAIpD,gBAAAA,CAAiB,6CAAA,CAAA;AAC7B,QAAA;AACF,IAAA;AACF,CAAA;AAEA;;;AAGC,IACD,MAAMyE,WAAAA,GAAc,OAAON,GAAAA,GAAM,EAAE,GAAa;AAC9C,IAAA,MAAMD,uBAAAA,CAAwBC,GAAAA,CAAAA;IAE9B,MAAMO,UAAAA,CAAW,YAAA,CAAA,CAAcC,gBAAgB,CAACR,GAAAA,CAAAA;AAEhD,IAAA,MAAMS,eAA4B,EAAE;IACpC,KAAK,MAAMtB,MAAMa,GAAAA,CAAK;QACpB,MAAMU,WAAAA,GAAc,MAAMnC,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAekC,MAAM,CAAC;YAAE5B,KAAAA,EAAO;AAAEI,gBAAAA;AAAG;AAAE,SAAA,CAAA;AAEhF,QAAA,IAAIuB,WAAAA,EAAa;AACfnC,YAAAA,MAAAA,CAAOG,QAAQ,CAACC,IAAI,CAAC,aAAA,EAAe;gBAAEtC,IAAAA,EAAMqE;AAAY,aAAA,CAAA;AACxDD,YAAAA,YAAAA,CAAaG,IAAI,CAACF,WAAAA,CAAAA;AACpB,QAAA;AACF,IAAA;IAEA,OAAOD,YAAAA;AACT,CAAA;AAEA;IAEA,MAAMvB,gBAAgB,OAAOmB,MAAAA,GAAAA;AAC3B,IAAA,OAAO9B,OAAOC,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeqB,KAAK,CAAC;QAAEf,KAAAA,EAAO;YAAEQ,KAAAA,EAAO;gBAAEJ,EAAAA,EAAIkB;AAAO;AAAE;AAAE,KAAA,CAAA;AACjF,CAAA;AAEA;IAEA,MAAMH,aAAAA,GAAgB,IAAsCtB,OAAAA,CAAQ;QAAEP,IAAAA,EAAM9C;AAAiB,KAAA,CAAA;AAE7F;;IAGA,MAAMsF,2BAAAA,GAA8B,IAAM7B,qBAAAA,CAAsB;QAAEX,IAAAA,EAAM9C;AAAiB,KAAA,CAAA;AAEzF;AACC,IACD,MAAMuF,sBAAAA,GAAyB,UAAA;AAC7B,IAAA,MAAMC,iBAAiB,MAAMvD,MAAAA,EAAAA;AAC7B,IAAA,IAAIuD,cAAAA,EAAgB;AAClB,QAAA;AACF,IAAA;AAEA,IAAA,MAAM,EAAEC,cAAc,EAAE,GAAGT,UAAAA,CAAW,YAAA,CAAA;IAEtC,MAAMU,UAAAA,GAAaD,eAAeE,MAAM,EAAA;IACxC,MAAMC,mBAAAA,GAAsBF,WAAWG,MAAM,CAAC,CAACC,CAAAA,GAAMA,CAAAA,CAAEC,OAAO,KAAK,cAAA,CAAA;;IAGnE,MAAMrB,cAAAA,GAAiB,MAAM5C,MAAAA,CAAO;QAClCI,IAAAA,EAAM,aAAA;QACNY,IAAAA,EAAM,oBAAA;QACNkD,WAAAA,EAAa;AACf,KAAA,CAAA;AAEA,IAAA,MAAMhB,UAAAA,CAAW,MAAA,CAAA,CAAQiB,gBAAgB,CAACvB,eAAed,EAAE,CAAA;IAE3D,MAAMsC,UAAAA,GAAa,MAAMpE,MAAAA,CAAO;QAC9BI,IAAAA,EAAM,QAAA;QACNY,IAAAA,EAAM,eAAA;QACNkD,WAAAA,EAAa;AACf,KAAA,CAAA;IAEA,MAAMG,UAAAA,GAAa,MAAMrE,MAAAA,CAAO;QAC9BI,IAAAA,EAAM,QAAA;QACNY,IAAAA,EAAM,eAAA;QACNkD,WAAAA,EAAa;AACf,KAAA,CAAA;;;;IAKA,MAAMI,gBAAAA,GAAmBC,OAAOV,MAAM,CAAC3C,OAAOsD,YAAY,CAAA,CACvDT,MAAM,CAAC,CAACU,EAAAA,GAAOA,IAAIC,aAAAA,GAAgB,iBAAA,CAAkB,EAAEC,OAAAA,KAAY,KAAA,CAAA,CACnEC,GAAG,CAAC,CAACH,EAAAA,GAAOA,EAAAA,CAAGI,GAAG,CAAA;AAErB,IAAA,MAAMC,iBAAAA,GAAoB5B,UAAAA,CAAW,cAAA,CAAA,CAAgB6B,8BAA8B,CACjFjB,mBAAAA,EACA;QACEkB,kBAAAA,EAAoB;AAAC,YAAA,gCAAA;AAAqCV,YAAAA,GAAAA;AAAiB;AAC7E,KAAA,CAAA;AAGF,IAAA,MAAMW,oBAAoBH,iBAAAA,CACvBf,MAAM,CAAC,CAAC,EAAEjE,MAAM,EAAO,GAAKA,WAAWjB,OAAAA,CAAQC,OAAO,EACtD8F,GAAG,CAAC,CAACxF,UAAAA,GACJ8F,gBAAAA,CAAiBlF,MAAM,CAAC;AAAE,YAAA,GAAGZ,UAAU;YAAE+F,UAAAA,EAAY;AAAC,gBAAA;AAAoB;AAAC,SAAA,CAAA,CAAA;AAG/EL,IAAAA,iBAAAA,CAAkBvB,IAAI,CAAA,GAAI6B,2BAAAA,EAAAA,CAAAA;IAC1BH,iBAAAA,CAAkB1B,IAAI,IAAI6B,2BAAAA,CAA4B;QAAEC,QAAAA,EAAU;AAAK,KAAA,CAAA,CAAA;;IAGvE,MAAMC,cAAAA,CAAelB,UAAAA,CAAWtC,EAAE,EAAEgD,iBAAAA,CAAAA;IACpC,MAAMQ,cAAAA,CAAejB,UAAAA,CAAWvC,EAAE,EAAEmD,iBAAAA,CAAAA;AACtC,CAAA;AAEA,MAAMG,2BAAAA,GAA8B,CAAC,EAAEC,QAAAA,GAAW,KAAK,EAAE,GAAG,EAAE,GAAA;AAC5D,IAAA,MAAMF,aAAaE,QAAAA,GAAW;AAAC,QAAA;AAAoB,KAAA,GAAG,EAAE;;IAGxD,OAAO;AACL,QAAA;YAAEvF,MAAAA,EAAQ,qBAAA;AAAuBqF,YAAAA;AAAW,SAAA;AAC5C,QAAA;YAAErF,MAAAA,EAAQ;AAAgC,SAAA;AAC1C,QAAA;YAAEA,MAAAA,EAAQ;AAA+B,SAAA;AACzC,QAAA;YAAEA,MAAAA,EAAQ,8BAAA;AAAgCqF,YAAAA;AAAW,SAAA;AACrD,QAAA;YAAErF,MAAAA,EAAQ;AAAiC,SAAA;AAC3C,QAAA;YAAEA,MAAAA,EAAQ;AAAkC;KAC7C,CAAC8E,GAAG,CAACM,gBAAAA,CAAiBlF,MAAM,CAAA;AAC/B,CAAA;AAEA;;AAEC,IACD,MAAMuF,4BAAAA,GAA+B,UAAA;AACnC,IAAA,MAAM3C,iBAAiB,MAAMY,2BAAAA,EAAAA;AAC7B,IAAA,MAAMgC,eAAAA,GAAkB,MAAMtC,UAAAA,CAAW,MAAA,CAAA,CAAQ/C,MAAM,EAAA;AAEvD,IAAA,IAAI,CAACyC,cAAAA,EAAgB;QACnB1B,MAAAA,CAAOuE,GAAG,CAACC,IAAI,CAAC,mDAAA,CAAA;AAClB,IAAA,CAAA,MAAO,IAAIF,eAAAA,IAAmB5C,cAAAA,CAAehB,UAAU,KAAK,CAAA,EAAG;QAC7DV,MAAAA,CAAOuE,GAAG,CAACC,IAAI,CAAC,mDAAA,CAAA;AAClB,IAAA;AACF,CAAA;AAEA;;;;AAIC,IACD,MAAMC,iBAAAA,GAAoB,OACxB3C,MAAAA,EACA4C,cAA4E,EAAE,GAAA;AAE9E,IAAA,MAAMC,wBAAAA,CAAyBD,WAAAA,CAAAA;;;IAI/B,MAAME,eAAAA,GAAkB,IAAIC,GAAAA,CAC1B7C,UAAAA,CAAW,cACRS,cAAc,CAACE,MAAM,EAAA,CACrBE,MAAM,CAAC,CAACjE,MAAAA,GAAWA,MAAAA,CAAOmE,OAAO,KAAK,UAAA,CAAA,CACtCW,GAAG,CAAC,CAAC9E,MAAAA,GAAWA,MAAAA,CAAOkG,QAAQ,CAAA,CAAA;AAGpC,IAAA,MAAMC,UAAAA,GAAa,MAAM/C,UAAAA,CAAW,MAAA,CAAA,CAAQL,aAAa,EAAA;AACzD,IAAA,MAAMqD,YAAAA,GAAeD,UAAAA,IAAcA,UAAAA,CAAWnE,EAAE,KAAKkB,MAAAA;IACrD,MAAMmD,UAAAA,GAAa,CAAmB/G,UAAAA,IAAmB;AAAE,YAAA,GAAGA,UAAU;YAAEJ,IAAAA,EAAMgE;SAAO,CAAA;IAEvF,MAAMoD,mBAAAA,GAAsBR,WAC1B;KACChB,GAAG,CAACuB,WACL;KACCvB,GAAG,CAACM,iBAAiBlF,MAAM,CAAA;AAE9B,IAAA,MAAMqG,mBAAAA,GAAsB,MAAMnD,UAAAA,CAAW,YAAA,CAAA,CAAclB,QAAQ,CAAC;QAClEN,KAAAA,EAAO;YAAE1C,IAAAA,EAAM;gBAAE8C,EAAAA,EAAIkB;AAAO;AAAE,SAAA;QAC9BvB,QAAAA,EAAU;AAAC,YAAA;AAAO;AACpB,KAAA,CAAA;AAEA,IAAA,MAAM6E,gBAAAA,GAAmBC,cAAAA,CACvBH,mBAAAA,EACAC,mBAAAA,EACA1G,qBACAoE,MAAM,CAAC,CAAC3E,UAAAA,GAA2B,CAAC0G,eAAAA,CAAgBvD,GAAG,CAACnD,WAAWU,MAAM,CAAA,CAAA;AAE3E,IAAA,MAAM0G,mBAAAA,GAAsBD,cAAAA,CAC1BF,mBAAAA,EACAD,mBAAAA,EACAzG,qBACAoE,MAAM,CAAC,CAAC3E,UAAAA,GAA2B,CAAC0G,eAAAA,CAAgBvD,GAAG,CAACnD,WAAWU,MAAM,CAAA,CAAA;IAE3E,MAAM2G,mBAAAA,GAAsBC,YAAAA,CAAaF,mBAAAA,EAAqBH,mBAAAA,EAAqB,IAAA,CAAA;IAEnF,IAAIG,mBAAAA,CAAoB3F,MAAM,GAAG,CAAA,EAAG;QAClC,MAAMqC,UAAAA,CAAW,cAAcD,WAAW,CACxCuD,oBAAoB5B,GAAG,CAAC,CAACxF,UAAAA,GAAeA,UAAAA,EAAY0C,EAAAA,CAAAA,CAAAA;AAExD,IAAA;IAEA,IAAIwE,gBAAAA,CAAiBzF,MAAM,GAAG,CAAA,EAAG;QAC/B,MAAM8F,cAAAA,GAAiB,MAAMrB,cAAAA,CAAetC,MAAAA,EAAQsD,gBAAAA,CAAAA;AACpDG,QAAAA,mBAAAA,CAAoBlD,IAAI,CAAA,GAAIoD,cAAAA,CAAAA;AAC9B,IAAA;IAEA,IAAI,CAACT,iBAAiBI,gBAAAA,CAAiBzF,MAAM,IAAI2F,mBAAAA,CAAoB3F,MAAK,CAAA,EAAI;QAC5E,MAAMqC,UAAAA,CAAW,WAAW0D,4BAA4B,EAAA;AAC1D,IAAA;AAEA,IAAA,IAAIN,iBAAiBzF,MAAM,GAAG,KAAK2F,mBAAAA,CAAoB3F,MAAM,GAAG,CAAA,EAAG;QACjE,MAAMqC,UAAAA,CAAW,iBAAA,CAAA,CAAmB2D,sBAAsB,CAAC7D,MAAAA,CAAAA;AAC7D,IAAA;IAEA,OAAOyD,mBAAAA;AACT,CAAA;AAEA,MAAMnB,cAAAA,GAAiB,OAAOtC,MAAAA,EAAiB4C,WAAAA,GAAAA;AAC7C,IAAA,MAAM,EAAEkB,iBAAiB,EAAEC,UAAU,EAAE,GAAG7D,UAAAA,CAAW,YAAA,CAAA;IACrD,MAAM,EAAE8D,kBAAkB,EAAE,GAAG9B,gBAAAA;AAE/B,IAAA,MAAMkB,sBAAsBR,WAAAA,CACzBhB,GAAG,CAAC,CAACxF,cAA4B;AAAE,YAAA,GAAGA,UAAU;YAAEJ,IAAAA,EAAMgE;AAAO,SAAA,EAChE;;AAEC4B,KAAAA,GAAG,CAACoC,kBAAAA,CAAmBF,iBAAAA,CAAAA,CAAAA,CACvBlC,GAAG,CAACM,iBAAiBlF,MAAM,CAAA;AAE9B,IAAA,OAAO+G,UAAAA,CAAWX,mBAAAA,CAAAA;AACpB,CAAA;AAEA,MAAMa,mBAAAA,GAAsB,CAACnH,MAAAA,GAAmBA,MAAAA,CAAOmE,OAAO,KAAK9F,oBAAAA;AAEnE;;AAEC,IACD,MAAM+I,0BAAAA,GAA6B,UAAA;AACjC,IAAA,MAAMtE,cAAAA,GAAiB,MAAMM,UAAAA,CAAW,MAAA,CAAA,CAAQL,aAAa,EAAA;AAC7D,IAAA,IAAI,CAACD,cAAAA,EAAgB;AACnB,QAAA;AACF,IAAA;AAEA,IAAA,MAAMuE,oBAAoBjE,UAAAA,CAAW,YAAA,CAAA;AACrC,IAAA,MAAMkE,qBAAqBlE,UAAAA,CAAW,cAAA,CAAA;AAEtC,IAAA,MAAMU,UAAAA,GAAauD,iBAAAA,CAAkBxD,cAAc,CAACE,MAAM,EAAA;AAE1D,IAAA,MAAMC,sBAAsBF,UAAAA,CAAWG,MAAM,CAAC,CAACjE,SAAWmH,mBAAAA,CAAoBnH,MAAAA,CAAAA,CAAAA;AAC9E,IAAA,MAAMuH,eAAezD,UAAAA,CAAWG,MAAM,CAAC,CAACjE,MAAAA,GAAW,CAACmH,mBAAAA,CAAoBnH,MAAAA,CAAAA,CAAAA;;IAGxE,MAAM8F,WAAAA,GAAcwB,kBAAAA,CAAmBrC,8BAA8B,CACnEjB,mBAAAA,CAAAA;;AAIF,IAAA,MAAMwD,gBAAAA,GAAmBD,YAAAA,CAAaE,MAAM,CAAC,CAACC,GAAAA,EAAK1H,MAAAA,GAAAA;AACjD,QAAA,MAAM,EAAEkG,QAAQ,EAAEyB,QAAQ,EAAE,GAAG3H,MAAAA;QAE/B,IAAI4H,KAAAA,CAAMC,OAAO,CAACF,QAAAA,CAAAA,EAAW;YAC3BD,GAAAA,CAAIjE,IAAI,IACHkE,QAAAA,CAAS7C,GAAG,CAAC,CAACgD,OAAAA,GAAY1C,gBAAAA,CAAiBlF,MAAM,CAAC;oBAAEF,MAAAA,EAAQkG,QAAAA;AAAU4B,oBAAAA;AAAQ,iBAAA,CAAA,CAAA,CAAA;QAErF,CAAA,MAAO;AACLJ,YAAAA,GAAAA,CAAIjE,IAAI,CAAC2B,gBAAAA,CAAiBlF,MAAM,CAAC;gBAAEF,MAAAA,EAAQkG;AAAS,aAAA,CAAA,CAAA;AACtD,QAAA;QAEA,OAAOwB,GAAAA;AACT,IAAA,CAAA,EAAG,EAAE,CAAA;AAEL5B,IAAAA,WAAAA,CAAYrC,IAAI,CAAA,GAAI+D,gBAAAA,CAAAA;AAEpB,IAAA,MAAMO,yBAA0B,MAAMnJ,KAAAA,CAAMC,8BAA8B,CAACmJ,IAAI,CAC7ElC,WAAAA,CAAAA;IAGF,MAAMD,iBAAAA,CAAkB/C,cAAAA,CAAed,EAAE,EAAE+F,sBAAAA,CAAAA;AAC7C,CAAA;AAEA;;IAGA,MAAME,oBAAoB,CAACC,IAAAA,GAAAA;AACzB,IAAA,MAAM9F,QAAQzB,UAAAA,CAAE0B,GAAG,CAAC6F,IAAAA,EAAM,SAAS,EAAE,CAAA;IAErC,OAAO9F,KAAAA,CAAM0C,GAAG,CAAC,CAAC5F,OAASA,IAAAA,EAAMgC,IAAAA,CAAAA,CAAMiH,QAAQ,CAAC/J,gBAAAA,CAAAA;AAClD,CAAA;AAEA,MAAMgK,SAAAA,GAAY;IAChBC,cAAAA,EAAgBjK;AAClB,CAAA;AAEA,WAAe;AACbQ,IAAAA,KAAAA;AACAK,IAAAA,YAAAA;AACAiB,IAAAA,MAAAA;AACAuB,IAAAA,OAAAA;AACAI,IAAAA,qBAAAA;AACAI,IAAAA,IAAAA;AACAE,IAAAA,qBAAAA;AACAI,IAAAA,MAAAA;AACAlC,IAAAA,MAAAA;AACAsC,IAAAA,KAAAA;AACAQ,IAAAA,WAAAA;AACApB,IAAAA,aAAAA;AACAgB,IAAAA,aAAAA;AACAW,IAAAA,2BAAAA;AACAC,IAAAA,sBAAAA;AACA8B,IAAAA,4BAAAA;AACAD,IAAAA,cAAAA;AACAyC,IAAAA,iBAAAA;AACApC,IAAAA,iBAAAA;AACAuB,IAAAA,0BAAAA;AACAxE,IAAAA,uBAAAA;AACAwF,IAAAA;AACF,CAAA;;;;"}
@@ -0,0 +1,197 @@
1
+ 'use strict';
2
+
3
+ const REDACTED = '[REDACTED]';
4
+ // Layer 1a: key names (substring match) whose value must be masked wherever they appear.
5
+ const SECRET_KEY_PATTERN = /(secret|password|passphrase|salt|token|api[_-]?key|access[_-]?key|license[_-]?key|private[_-]?key|encryption[_-]?key|credential|provider[_-]?options|connection[_-]?string|mnemonic|seed[_-]?phrase|authorization|bearer)/i;
6
+ // Layer 1b: short, ambiguous key names matched EXACTLY (case-insensitive), so they
7
+ // do not over-match as substrings (e.g. `pass` must not redact `compass`/`bypass`,
8
+ // and this still catches a nested SMTP `auth.pass`).
9
+ const SECRET_KEY_EXACT = new Set([
10
+ 'pass',
11
+ 'pwd',
12
+ 'passwd',
13
+ 'dsn'
14
+ ]);
15
+ // camelCase password suffixes (capitalized), e.g. `smtpAuthPass`, `dbPwd` — the
16
+ // capital letter distinguishes them from lowercase look-alikes (`compass`, `bypass`).
17
+ const SECRET_KEY_SUFFIX = /[a-z](Pass|Pwd|Passwd)$/;
18
+ // separator-delimited short secret names, e.g. `auth.pass`, `db_pwd`, `x-pass`.
19
+ const SECRET_KEY_DELIMITED = /(^|[._-])(pass|pwd|passwd|dsn)([._-]|$)/i;
20
+ const isSecretKey = (key)=>SECRET_KEY_PATTERN.test(key) || SECRET_KEY_EXACT.has(key.toLowerCase()) || SECRET_KEY_SUFFIX.test(key) || SECRET_KEY_DELIMITED.test(key);
21
+ // Layer 3: string values that look like secrets regardless of their key.
22
+ // Real JWTs are base64url-encoded and the header segment always begins with
23
+ // `eyJ` (the base64url encoding of `{"`), so requiring that prefix avoids
24
+ // matching arbitrary three-part dotted strings like semver versions
25
+ // (e.g. "5.50.1", "18.3.1").
26
+ const JWT_PATTERN = /^eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/;
27
+ const LONG_TOKEN_PATTERN = /^[A-Fa-f0-9]{32,}$|^[A-Za-z0-9+/]{40,}={0,2}$/;
28
+ // Credentials embedded in a URL authority: `user:pass@` or `:pass@` (empty user,
29
+ // as in `redis://:password@host`). The user part stops at the first colon, as in
30
+ // RFC 3986, so the split between user and password is fixed; letting it take colons
31
+ // made a long colon run with no `@` retry every split point, which is quadratic.
32
+ const URL_WITH_CREDENTIALS = /^[a-z][a-z0-9+.-]*:\/\/[^/@\s:]*:[^/@\s]+@/i;
33
+ // PEM private key blocks (certificates are public, so only PRIVATE KEY is masked).
34
+ const PEM_PRIVATE_KEY_PATTERN = /-----BEGIN(?: [A-Z0-9]+)* PRIVATE KEY-----/;
35
+ // URLs whose secret is carried in the host/path rather than a `user:pass@` authority:
36
+ // chat webhooks and error-tracking DSNs.
37
+ const SECRET_URL_PATTERN = /^https:\/\/hooks\.slack\.com\/services\/|^https:\/\/(?:discord|discordapp)\.com\/api\/webhooks\/|:\/\/[^/@\s]+@[^/\s]*\bsentry\.io\b/i;
38
+ // Well-known provider secret token formats, matched against the whole value. The
39
+ // prefixes are specific enough to have negligible false-positive risk, so they
40
+ // mask a value even under an innocuous key (e.g. `key: 'sk_live_...'`).
41
+ // `pk_` (publishable) keys are intentionally excluded — they are public by design.
42
+ const PROVIDER_SECRET_PATTERN = new RegExp([
43
+ '^(sk|rk)_(live|test)_[A-Za-z0-9]{8,}$',
44
+ '^whsec_[A-Za-z0-9]{16,}$',
45
+ '^(gh[posru]_|github_pat_)[A-Za-z0-9_]{20,}$',
46
+ '^xox[baprs]-[A-Za-z0-9-]{10,}$',
47
+ '^(AKIA|ASIA)[A-Z0-9]{16}$',
48
+ '^SG\\.[A-Za-z0-9_-]{16,}\\.[A-Za-z0-9_-]{16,}$',
49
+ '^AIza[A-Za-z0-9_-]{20,}$',
50
+ '^ya29\\.[A-Za-z0-9_-]{20,}$',
51
+ '^glpat-[A-Za-z0-9_-]{16,}$',
52
+ '^(shpat|shpss|shpca|shppa)_[A-Za-z0-9]{20,}$',
53
+ '^dop_v1_[a-f0-9]{40,}$',
54
+ '^re_[A-Za-z0-9_]{16,}$',
55
+ '^nfp_[A-Za-z0-9]{20,}$',
56
+ '^EAAA[A-Za-z0-9_-]{20,}$'
57
+ ].join('|'));
58
+ const looksSecret = (value)=>JWT_PATTERN.test(value) || LONG_TOKEN_PATTERN.test(value) || URL_WITH_CREDENTIALS.test(value) || PROVIDER_SECRET_PATTERN.test(value) || PEM_PRIVATE_KEY_PATTERN.test(value) || SECRET_URL_PATTERN.test(value);
59
+ const isPlainObject = (value)=>{
60
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
61
+ return false;
62
+ }
63
+ const proto = Object.getPrototypeOf(value);
64
+ return proto === Object.prototype || proto === null;
65
+ };
66
+ // Accept either separator regardless of the host platform: `os.homedir()` and the app root come
67
+ // back with backslashes on Windows, and a dump may also carry POSIX-style paths (e.g. from
68
+ // config values), so a POSIX-only prefix check would ship absolute Windows paths verbatim.
69
+ const isPathPrefix = (value, prefix)=>{
70
+ if (value === prefix) {
71
+ return true;
72
+ }
73
+ if (!value.startsWith(prefix)) {
74
+ return false;
75
+ }
76
+ const next = value.charAt(prefix.length);
77
+ return next === '/' || next === '\\';
78
+ };
79
+ const relativize = (value, appRoot, homeDir)=>{
80
+ if (appRoot && isPathPrefix(value, appRoot)) {
81
+ return `<app>${value.slice(appRoot.length)}`;
82
+ }
83
+ if (homeDir && isPathPrefix(value, homeDir)) {
84
+ return `<home>${value.slice(homeDir.length)}`;
85
+ }
86
+ return value;
87
+ };
88
+ // Characters that end a URL authority
89
+ const AUTHORITY_END = new Set([
90
+ '/',
91
+ '?',
92
+ '#',
93
+ ' ',
94
+ '\t',
95
+ '\n',
96
+ '\r',
97
+ '"',
98
+ "'",
99
+ '`'
100
+ ]);
101
+ /**
102
+ * Masks the password of every `scheme://user:password@host` inside a longer string, such as a
103
+ * package.json script that inlines a database URL. Whole-value credential URLs are already
104
+ * caught by URL_WITH_CREDENTIALS; this covers the ones in the middle of a value. It is a single
105
+ * forward scan rather than a regex, because an unanchored pattern backtracks quadratically on
106
+ * long runs (the reason URL_WITH_CREDENTIALS is anchored and colon-free in the user part).
107
+ */ const maskEmbeddedCredentials = (value)=>{
108
+ let result = '';
109
+ let copiedUpTo = 0;
110
+ let separator = value.indexOf('://');
111
+ while(separator !== -1){
112
+ const authorityStart = separator + 3;
113
+ let firstColon = -1;
114
+ let lastAt = -1;
115
+ let end = authorityStart;
116
+ while(end < value.length && !AUTHORITY_END.has(value[end])){
117
+ if (value[end] === ':' && firstColon === -1) {
118
+ firstColon = end;
119
+ } else if (value[end] === '@') {
120
+ lastAt = end;
121
+ }
122
+ end += 1;
123
+ }
124
+ // A colon before the last `@` separates user and password; one after it is a port.
125
+ if (firstColon !== -1 && lastAt > firstColon) {
126
+ result += `${value.slice(copiedUpTo, firstColon + 1)}${REDACTED}`;
127
+ copiedUpTo = lastAt;
128
+ }
129
+ separator = value.indexOf('://', end);
130
+ }
131
+ return copiedUpTo === 0 ? value : result + value.slice(copiedUpTo);
132
+ };
133
+ const deleteAtPath = (target, path)=>{
134
+ const segments = path.split('.');
135
+ let node = target;
136
+ for(let i = 0; i < segments.length - 1; i += 1){
137
+ if (!isPlainObject(node)) {
138
+ return;
139
+ }
140
+ node = node[segments[i]];
141
+ }
142
+ const lastKey = segments[segments.length - 1];
143
+ if (isPlainObject(node) && lastKey in node) {
144
+ node[lastKey] = REDACTED;
145
+ }
146
+ };
147
+ const walk = (value, appRoot, homeDir)=>{
148
+ if (typeof value === 'string') {
149
+ // Relativization is tried FIRST, and a value it rewrote is returned as-is. A string
150
+ // that starts with the app root or the home directory is a path, never a credential,
151
+ // whereas the reverse order let the secret heuristics claim one: a POSIX path made
152
+ // only of letters, digits and `/` is valid standard base64, so anything past 40
153
+ // characters matched LONG_TOKEN_PATTERN and shipped as `[REDACTED]` instead of
154
+ // `<app>/...`. Values that do not relativize still go through the full checks.
155
+ const relativized = relativize(value, appRoot, homeDir);
156
+ if (relativized !== value) {
157
+ return relativized;
158
+ }
159
+ return looksSecret(value) ? REDACTED : maskEmbeddedCredentials(value);
160
+ }
161
+ if (Array.isArray(value)) {
162
+ return value.map((item)=>walk(item, appRoot, homeDir));
163
+ }
164
+ if (isPlainObject(value)) {
165
+ const out = {};
166
+ for (const [key, val] of Object.entries(value)){
167
+ if (key === '__proto__') {
168
+ continue; // never write through the Object.prototype setter
169
+ }
170
+ // A secret-named key always collapses wholesale, regardless of the value's
171
+ // type. Recursing into it (e.g. for `apiToken: { salt, ... }`) would leak
172
+ // any inner value whose own key/value doesn't independently match a
173
+ // masking pattern (e.g. `providerOptions.auth.pass`), so there is nothing
174
+ // safe to preserve underneath a secret-named container.
175
+ out[key] = isSecretKey(key) ? REDACTED : walk(val, appRoot, homeDir);
176
+ }
177
+ return out;
178
+ }
179
+ // Any other object type — Buffer, Date, Map, Set, class instances, etc. —
180
+ // is not a plain data container we can safely walk (Object.entries on a
181
+ // Buffer leaks its bytes, a Date serializes to `{}`), so redact defensively.
182
+ if (value !== null && typeof value === 'object') {
183
+ return REDACTED;
184
+ }
185
+ return value;
186
+ };
187
+ const scrub = (value, options = {})=>{
188
+ const cloned = walk(value, options.appRoot, options.homeDir);
189
+ for (const path of options.extraPaths ?? []){
190
+ deleteAtPath(cloned, path);
191
+ }
192
+ return cloned;
193
+ };
194
+
195
+ exports.REDACTED = REDACTED;
196
+ exports.scrub = scrub;
197
+ //# sourceMappingURL=redact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.js","sources":["../../../../../../server/src/utils/debug-dump/redact.ts"],"sourcesContent":["export const REDACTED = '[REDACTED]';\n\n// Layer 1a: key names (substring match) whose value must be masked wherever they appear.\nconst SECRET_KEY_PATTERN =\n /(secret|password|passphrase|salt|token|api[_-]?key|access[_-]?key|license[_-]?key|private[_-]?key|encryption[_-]?key|credential|provider[_-]?options|connection[_-]?string|mnemonic|seed[_-]?phrase|authorization|bearer)/i;\n\n// Layer 1b: short, ambiguous key names matched EXACTLY (case-insensitive), so they\n// do not over-match as substrings (e.g. `pass` must not redact `compass`/`bypass`,\n// and this still catches a nested SMTP `auth.pass`).\nconst SECRET_KEY_EXACT = new Set(['pass', 'pwd', 'passwd', 'dsn']);\n// camelCase password suffixes (capitalized), e.g. `smtpAuthPass`, `dbPwd` — the\n// capital letter distinguishes them from lowercase look-alikes (`compass`, `bypass`).\nconst SECRET_KEY_SUFFIX = /[a-z](Pass|Pwd|Passwd)$/;\n// separator-delimited short secret names, e.g. `auth.pass`, `db_pwd`, `x-pass`.\nconst SECRET_KEY_DELIMITED = /(^|[._-])(pass|pwd|passwd|dsn)([._-]|$)/i;\n\nconst isSecretKey = (key: string): boolean =>\n SECRET_KEY_PATTERN.test(key) ||\n SECRET_KEY_EXACT.has(key.toLowerCase()) ||\n SECRET_KEY_SUFFIX.test(key) ||\n SECRET_KEY_DELIMITED.test(key);\n\n// Layer 3: string values that look like secrets regardless of their key.\n// Real JWTs are base64url-encoded and the header segment always begins with\n// `eyJ` (the base64url encoding of `{\"`), so requiring that prefix avoids\n// matching arbitrary three-part dotted strings like semver versions\n// (e.g. \"5.50.1\", \"18.3.1\").\nconst JWT_PATTERN = /^eyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+$/;\nconst LONG_TOKEN_PATTERN = /^[A-Fa-f0-9]{32,}$|^[A-Za-z0-9+/]{40,}={0,2}$/;\n// Credentials embedded in a URL authority: `user:pass@` or `:pass@` (empty user,\n// as in `redis://:password@host`). The user part stops at the first colon, as in\n// RFC 3986, so the split between user and password is fixed; letting it take colons\n// made a long colon run with no `@` retry every split point, which is quadratic.\nconst URL_WITH_CREDENTIALS = /^[a-z][a-z0-9+.-]*:\\/\\/[^/@\\s:]*:[^/@\\s]+@/i;\n// PEM private key blocks (certificates are public, so only PRIVATE KEY is masked).\nconst PEM_PRIVATE_KEY_PATTERN = /-----BEGIN(?: [A-Z0-9]+)* PRIVATE KEY-----/;\n// URLs whose secret is carried in the host/path rather than a `user:pass@` authority:\n// chat webhooks and error-tracking DSNs.\nconst SECRET_URL_PATTERN =\n /^https:\\/\\/hooks\\.slack\\.com\\/services\\/|^https:\\/\\/(?:discord|discordapp)\\.com\\/api\\/webhooks\\/|:\\/\\/[^/@\\s]+@[^/\\s]*\\bsentry\\.io\\b/i;\n\n// Well-known provider secret token formats, matched against the whole value. The\n// prefixes are specific enough to have negligible false-positive risk, so they\n// mask a value even under an innocuous key (e.g. `key: 'sk_live_...'`).\n// `pk_` (publishable) keys are intentionally excluded — they are public by design.\nconst PROVIDER_SECRET_PATTERN = new RegExp(\n [\n '^(sk|rk)_(live|test)_[A-Za-z0-9]{8,}$', // Stripe secret / restricted\n '^whsec_[A-Za-z0-9]{16,}$', // Stripe webhook signing secret\n '^(gh[posru]_|github_pat_)[A-Za-z0-9_]{20,}$', // GitHub tokens / fine-grained PAT\n '^xox[baprs]-[A-Za-z0-9-]{10,}$', // Slack tokens\n '^(AKIA|ASIA)[A-Z0-9]{16}$', // AWS access key id\n '^SG\\\\.[A-Za-z0-9_-]{16,}\\\\.[A-Za-z0-9_-]{16,}$', // SendGrid\n '^AIza[A-Za-z0-9_-]{20,}$', // Google API key\n '^ya29\\\\.[A-Za-z0-9_-]{20,}$', // Google OAuth access token\n '^glpat-[A-Za-z0-9_-]{16,}$', // GitLab personal access token\n '^(shpat|shpss|shpca|shppa)_[A-Za-z0-9]{20,}$', // Shopify\n '^dop_v1_[a-f0-9]{40,}$', // DigitalOcean\n '^re_[A-Za-z0-9_]{16,}$', // Resend\n '^nfp_[A-Za-z0-9]{20,}$', // Netlify\n '^EAAA[A-Za-z0-9_-]{20,}$', // Square\n ].join('|')\n);\n\nconst looksSecret = (value: string): boolean =>\n JWT_PATTERN.test(value) ||\n LONG_TOKEN_PATTERN.test(value) ||\n URL_WITH_CREDENTIALS.test(value) ||\n PROVIDER_SECRET_PATTERN.test(value) ||\n PEM_PRIVATE_KEY_PATTERN.test(value) ||\n SECRET_URL_PATTERN.test(value);\n\nexport interface ScrubOptions {\n appRoot?: string;\n homeDir?: string;\n extraPaths?: string[];\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n return false;\n }\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n};\n\n// Accept either separator regardless of the host platform: `os.homedir()` and the app root come\n// back with backslashes on Windows, and a dump may also carry POSIX-style paths (e.g. from\n// config values), so a POSIX-only prefix check would ship absolute Windows paths verbatim.\nconst isPathPrefix = (value: string, prefix: string): boolean => {\n if (value === prefix) {\n return true;\n }\n if (!value.startsWith(prefix)) {\n return false;\n }\n const next = value.charAt(prefix.length);\n return next === '/' || next === '\\\\';\n};\n\nconst relativize = (value: string, appRoot?: string, homeDir?: string): string => {\n if (appRoot && isPathPrefix(value, appRoot)) {\n return `<app>${value.slice(appRoot.length)}`;\n }\n if (homeDir && isPathPrefix(value, homeDir)) {\n return `<home>${value.slice(homeDir.length)}`;\n }\n return value;\n};\n\n// Characters that end a URL authority\nconst AUTHORITY_END = new Set(['/', '?', '#', ' ', '\\t', '\\n', '\\r', '\"', \"'\", '`']);\n\n/**\n * Masks the password of every `scheme://user:password@host` inside a longer string, such as a\n * package.json script that inlines a database URL. Whole-value credential URLs are already\n * caught by URL_WITH_CREDENTIALS; this covers the ones in the middle of a value. It is a single\n * forward scan rather than a regex, because an unanchored pattern backtracks quadratically on\n * long runs (the reason URL_WITH_CREDENTIALS is anchored and colon-free in the user part).\n */\nconst maskEmbeddedCredentials = (value: string): string => {\n let result = '';\n let copiedUpTo = 0;\n let separator = value.indexOf('://');\n\n while (separator !== -1) {\n const authorityStart = separator + 3;\n let firstColon = -1;\n let lastAt = -1;\n let end = authorityStart;\n\n while (end < value.length && !AUTHORITY_END.has(value[end])) {\n if (value[end] === ':' && firstColon === -1) {\n firstColon = end;\n } else if (value[end] === '@') {\n lastAt = end;\n }\n end += 1;\n }\n\n // A colon before the last `@` separates user and password; one after it is a port.\n if (firstColon !== -1 && lastAt > firstColon) {\n result += `${value.slice(copiedUpTo, firstColon + 1)}${REDACTED}`;\n copiedUpTo = lastAt;\n }\n\n separator = value.indexOf('://', end);\n }\n\n return copiedUpTo === 0 ? value : result + value.slice(copiedUpTo);\n};\n\nconst deleteAtPath = (target: unknown, path: string): void => {\n const segments = path.split('.');\n let node: unknown = target;\n for (let i = 0; i < segments.length - 1; i += 1) {\n if (!isPlainObject(node)) {\n return;\n }\n node = node[segments[i]];\n }\n const lastKey = segments[segments.length - 1];\n if (isPlainObject(node) && lastKey in node) {\n node[lastKey] = REDACTED;\n }\n};\n\nconst walk = (value: unknown, appRoot?: string, homeDir?: string): unknown => {\n if (typeof value === 'string') {\n // Relativization is tried FIRST, and a value it rewrote is returned as-is. A string\n // that starts with the app root or the home directory is a path, never a credential,\n // whereas the reverse order let the secret heuristics claim one: a POSIX path made\n // only of letters, digits and `/` is valid standard base64, so anything past 40\n // characters matched LONG_TOKEN_PATTERN and shipped as `[REDACTED]` instead of\n // `<app>/...`. Values that do not relativize still go through the full checks.\n const relativized = relativize(value, appRoot, homeDir);\n if (relativized !== value) {\n return relativized;\n }\n return looksSecret(value) ? REDACTED : maskEmbeddedCredentials(value);\n }\n if (Array.isArray(value)) {\n return value.map((item) => walk(item, appRoot, homeDir));\n }\n if (isPlainObject(value)) {\n const out: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value)) {\n if (key === '__proto__') {\n continue; // never write through the Object.prototype setter\n }\n // A secret-named key always collapses wholesale, regardless of the value's\n // type. Recursing into it (e.g. for `apiToken: { salt, ... }`) would leak\n // any inner value whose own key/value doesn't independently match a\n // masking pattern (e.g. `providerOptions.auth.pass`), so there is nothing\n // safe to preserve underneath a secret-named container.\n out[key] = isSecretKey(key) ? REDACTED : walk(val, appRoot, homeDir);\n }\n return out;\n }\n // Any other object type — Buffer, Date, Map, Set, class instances, etc. —\n // is not a plain data container we can safely walk (Object.entries on a\n // Buffer leaks its bytes, a Date serializes to `{}`), so redact defensively.\n if (value !== null && typeof value === 'object') {\n return REDACTED;\n }\n return value;\n};\n\nexport const scrub = (value: unknown, options: ScrubOptions = {}): unknown => {\n const cloned = walk(value, options.appRoot, options.homeDir);\n for (const path of options.extraPaths ?? []) {\n deleteAtPath(cloned, path);\n }\n return cloned;\n};\n"],"names":["REDACTED","SECRET_KEY_PATTERN","SECRET_KEY_EXACT","Set","SECRET_KEY_SUFFIX","SECRET_KEY_DELIMITED","isSecretKey","key","test","has","toLowerCase","JWT_PATTERN","LONG_TOKEN_PATTERN","URL_WITH_CREDENTIALS","PEM_PRIVATE_KEY_PATTERN","SECRET_URL_PATTERN","PROVIDER_SECRET_PATTERN","RegExp","join","looksSecret","value","isPlainObject","Array","isArray","proto","Object","getPrototypeOf","prototype","isPathPrefix","prefix","startsWith","next","charAt","length","relativize","appRoot","homeDir","slice","AUTHORITY_END","maskEmbeddedCredentials","result","copiedUpTo","separator","indexOf","authorityStart","firstColon","lastAt","end","deleteAtPath","target","path","segments","split","node","i","lastKey","walk","relativized","map","item","out","val","entries","scrub","options","cloned","extraPaths"],"mappings":"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"}
@@ -0,0 +1,194 @@
1
+ const REDACTED = '[REDACTED]';
2
+ // Layer 1a: key names (substring match) whose value must be masked wherever they appear.
3
+ const SECRET_KEY_PATTERN = /(secret|password|passphrase|salt|token|api[_-]?key|access[_-]?key|license[_-]?key|private[_-]?key|encryption[_-]?key|credential|provider[_-]?options|connection[_-]?string|mnemonic|seed[_-]?phrase|authorization|bearer)/i;
4
+ // Layer 1b: short, ambiguous key names matched EXACTLY (case-insensitive), so they
5
+ // do not over-match as substrings (e.g. `pass` must not redact `compass`/`bypass`,
6
+ // and this still catches a nested SMTP `auth.pass`).
7
+ const SECRET_KEY_EXACT = new Set([
8
+ 'pass',
9
+ 'pwd',
10
+ 'passwd',
11
+ 'dsn'
12
+ ]);
13
+ // camelCase password suffixes (capitalized), e.g. `smtpAuthPass`, `dbPwd` — the
14
+ // capital letter distinguishes them from lowercase look-alikes (`compass`, `bypass`).
15
+ const SECRET_KEY_SUFFIX = /[a-z](Pass|Pwd|Passwd)$/;
16
+ // separator-delimited short secret names, e.g. `auth.pass`, `db_pwd`, `x-pass`.
17
+ const SECRET_KEY_DELIMITED = /(^|[._-])(pass|pwd|passwd|dsn)([._-]|$)/i;
18
+ const isSecretKey = (key)=>SECRET_KEY_PATTERN.test(key) || SECRET_KEY_EXACT.has(key.toLowerCase()) || SECRET_KEY_SUFFIX.test(key) || SECRET_KEY_DELIMITED.test(key);
19
+ // Layer 3: string values that look like secrets regardless of their key.
20
+ // Real JWTs are base64url-encoded and the header segment always begins with
21
+ // `eyJ` (the base64url encoding of `{"`), so requiring that prefix avoids
22
+ // matching arbitrary three-part dotted strings like semver versions
23
+ // (e.g. "5.50.1", "18.3.1").
24
+ const JWT_PATTERN = /^eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/;
25
+ const LONG_TOKEN_PATTERN = /^[A-Fa-f0-9]{32,}$|^[A-Za-z0-9+/]{40,}={0,2}$/;
26
+ // Credentials embedded in a URL authority: `user:pass@` or `:pass@` (empty user,
27
+ // as in `redis://:password@host`). The user part stops at the first colon, as in
28
+ // RFC 3986, so the split between user and password is fixed; letting it take colons
29
+ // made a long colon run with no `@` retry every split point, which is quadratic.
30
+ const URL_WITH_CREDENTIALS = /^[a-z][a-z0-9+.-]*:\/\/[^/@\s:]*:[^/@\s]+@/i;
31
+ // PEM private key blocks (certificates are public, so only PRIVATE KEY is masked).
32
+ const PEM_PRIVATE_KEY_PATTERN = /-----BEGIN(?: [A-Z0-9]+)* PRIVATE KEY-----/;
33
+ // URLs whose secret is carried in the host/path rather than a `user:pass@` authority:
34
+ // chat webhooks and error-tracking DSNs.
35
+ const SECRET_URL_PATTERN = /^https:\/\/hooks\.slack\.com\/services\/|^https:\/\/(?:discord|discordapp)\.com\/api\/webhooks\/|:\/\/[^/@\s]+@[^/\s]*\bsentry\.io\b/i;
36
+ // Well-known provider secret token formats, matched against the whole value. The
37
+ // prefixes are specific enough to have negligible false-positive risk, so they
38
+ // mask a value even under an innocuous key (e.g. `key: 'sk_live_...'`).
39
+ // `pk_` (publishable) keys are intentionally excluded — they are public by design.
40
+ const PROVIDER_SECRET_PATTERN = new RegExp([
41
+ '^(sk|rk)_(live|test)_[A-Za-z0-9]{8,}$',
42
+ '^whsec_[A-Za-z0-9]{16,}$',
43
+ '^(gh[posru]_|github_pat_)[A-Za-z0-9_]{20,}$',
44
+ '^xox[baprs]-[A-Za-z0-9-]{10,}$',
45
+ '^(AKIA|ASIA)[A-Z0-9]{16}$',
46
+ '^SG\\.[A-Za-z0-9_-]{16,}\\.[A-Za-z0-9_-]{16,}$',
47
+ '^AIza[A-Za-z0-9_-]{20,}$',
48
+ '^ya29\\.[A-Za-z0-9_-]{20,}$',
49
+ '^glpat-[A-Za-z0-9_-]{16,}$',
50
+ '^(shpat|shpss|shpca|shppa)_[A-Za-z0-9]{20,}$',
51
+ '^dop_v1_[a-f0-9]{40,}$',
52
+ '^re_[A-Za-z0-9_]{16,}$',
53
+ '^nfp_[A-Za-z0-9]{20,}$',
54
+ '^EAAA[A-Za-z0-9_-]{20,}$'
55
+ ].join('|'));
56
+ const looksSecret = (value)=>JWT_PATTERN.test(value) || LONG_TOKEN_PATTERN.test(value) || URL_WITH_CREDENTIALS.test(value) || PROVIDER_SECRET_PATTERN.test(value) || PEM_PRIVATE_KEY_PATTERN.test(value) || SECRET_URL_PATTERN.test(value);
57
+ const isPlainObject = (value)=>{
58
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
59
+ return false;
60
+ }
61
+ const proto = Object.getPrototypeOf(value);
62
+ return proto === Object.prototype || proto === null;
63
+ };
64
+ // Accept either separator regardless of the host platform: `os.homedir()` and the app root come
65
+ // back with backslashes on Windows, and a dump may also carry POSIX-style paths (e.g. from
66
+ // config values), so a POSIX-only prefix check would ship absolute Windows paths verbatim.
67
+ const isPathPrefix = (value, prefix)=>{
68
+ if (value === prefix) {
69
+ return true;
70
+ }
71
+ if (!value.startsWith(prefix)) {
72
+ return false;
73
+ }
74
+ const next = value.charAt(prefix.length);
75
+ return next === '/' || next === '\\';
76
+ };
77
+ const relativize = (value, appRoot, homeDir)=>{
78
+ if (appRoot && isPathPrefix(value, appRoot)) {
79
+ return `<app>${value.slice(appRoot.length)}`;
80
+ }
81
+ if (homeDir && isPathPrefix(value, homeDir)) {
82
+ return `<home>${value.slice(homeDir.length)}`;
83
+ }
84
+ return value;
85
+ };
86
+ // Characters that end a URL authority
87
+ const AUTHORITY_END = new Set([
88
+ '/',
89
+ '?',
90
+ '#',
91
+ ' ',
92
+ '\t',
93
+ '\n',
94
+ '\r',
95
+ '"',
96
+ "'",
97
+ '`'
98
+ ]);
99
+ /**
100
+ * Masks the password of every `scheme://user:password@host` inside a longer string, such as a
101
+ * package.json script that inlines a database URL. Whole-value credential URLs are already
102
+ * caught by URL_WITH_CREDENTIALS; this covers the ones in the middle of a value. It is a single
103
+ * forward scan rather than a regex, because an unanchored pattern backtracks quadratically on
104
+ * long runs (the reason URL_WITH_CREDENTIALS is anchored and colon-free in the user part).
105
+ */ const maskEmbeddedCredentials = (value)=>{
106
+ let result = '';
107
+ let copiedUpTo = 0;
108
+ let separator = value.indexOf('://');
109
+ while(separator !== -1){
110
+ const authorityStart = separator + 3;
111
+ let firstColon = -1;
112
+ let lastAt = -1;
113
+ let end = authorityStart;
114
+ while(end < value.length && !AUTHORITY_END.has(value[end])){
115
+ if (value[end] === ':' && firstColon === -1) {
116
+ firstColon = end;
117
+ } else if (value[end] === '@') {
118
+ lastAt = end;
119
+ }
120
+ end += 1;
121
+ }
122
+ // A colon before the last `@` separates user and password; one after it is a port.
123
+ if (firstColon !== -1 && lastAt > firstColon) {
124
+ result += `${value.slice(copiedUpTo, firstColon + 1)}${REDACTED}`;
125
+ copiedUpTo = lastAt;
126
+ }
127
+ separator = value.indexOf('://', end);
128
+ }
129
+ return copiedUpTo === 0 ? value : result + value.slice(copiedUpTo);
130
+ };
131
+ const deleteAtPath = (target, path)=>{
132
+ const segments = path.split('.');
133
+ let node = target;
134
+ for(let i = 0; i < segments.length - 1; i += 1){
135
+ if (!isPlainObject(node)) {
136
+ return;
137
+ }
138
+ node = node[segments[i]];
139
+ }
140
+ const lastKey = segments[segments.length - 1];
141
+ if (isPlainObject(node) && lastKey in node) {
142
+ node[lastKey] = REDACTED;
143
+ }
144
+ };
145
+ const walk = (value, appRoot, homeDir)=>{
146
+ if (typeof value === 'string') {
147
+ // Relativization is tried FIRST, and a value it rewrote is returned as-is. A string
148
+ // that starts with the app root or the home directory is a path, never a credential,
149
+ // whereas the reverse order let the secret heuristics claim one: a POSIX path made
150
+ // only of letters, digits and `/` is valid standard base64, so anything past 40
151
+ // characters matched LONG_TOKEN_PATTERN and shipped as `[REDACTED]` instead of
152
+ // `<app>/...`. Values that do not relativize still go through the full checks.
153
+ const relativized = relativize(value, appRoot, homeDir);
154
+ if (relativized !== value) {
155
+ return relativized;
156
+ }
157
+ return looksSecret(value) ? REDACTED : maskEmbeddedCredentials(value);
158
+ }
159
+ if (Array.isArray(value)) {
160
+ return value.map((item)=>walk(item, appRoot, homeDir));
161
+ }
162
+ if (isPlainObject(value)) {
163
+ const out = {};
164
+ for (const [key, val] of Object.entries(value)){
165
+ if (key === '__proto__') {
166
+ continue; // never write through the Object.prototype setter
167
+ }
168
+ // A secret-named key always collapses wholesale, regardless of the value's
169
+ // type. Recursing into it (e.g. for `apiToken: { salt, ... }`) would leak
170
+ // any inner value whose own key/value doesn't independently match a
171
+ // masking pattern (e.g. `providerOptions.auth.pass`), so there is nothing
172
+ // safe to preserve underneath a secret-named container.
173
+ out[key] = isSecretKey(key) ? REDACTED : walk(val, appRoot, homeDir);
174
+ }
175
+ return out;
176
+ }
177
+ // Any other object type — Buffer, Date, Map, Set, class instances, etc. —
178
+ // is not a plain data container we can safely walk (Object.entries on a
179
+ // Buffer leaks its bytes, a Date serializes to `{}`), so redact defensively.
180
+ if (value !== null && typeof value === 'object') {
181
+ return REDACTED;
182
+ }
183
+ return value;
184
+ };
185
+ const scrub = (value, options = {})=>{
186
+ const cloned = walk(value, options.appRoot, options.homeDir);
187
+ for (const path of options.extraPaths ?? []){
188
+ deleteAtPath(cloned, path);
189
+ }
190
+ return cloned;
191
+ };
192
+
193
+ export { REDACTED, scrub };
194
+ //# sourceMappingURL=redact.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.mjs","sources":["../../../../../../server/src/utils/debug-dump/redact.ts"],"sourcesContent":["export const REDACTED = '[REDACTED]';\n\n// Layer 1a: key names (substring match) whose value must be masked wherever they appear.\nconst SECRET_KEY_PATTERN =\n /(secret|password|passphrase|salt|token|api[_-]?key|access[_-]?key|license[_-]?key|private[_-]?key|encryption[_-]?key|credential|provider[_-]?options|connection[_-]?string|mnemonic|seed[_-]?phrase|authorization|bearer)/i;\n\n// Layer 1b: short, ambiguous key names matched EXACTLY (case-insensitive), so they\n// do not over-match as substrings (e.g. `pass` must not redact `compass`/`bypass`,\n// and this still catches a nested SMTP `auth.pass`).\nconst SECRET_KEY_EXACT = new Set(['pass', 'pwd', 'passwd', 'dsn']);\n// camelCase password suffixes (capitalized), e.g. `smtpAuthPass`, `dbPwd` — the\n// capital letter distinguishes them from lowercase look-alikes (`compass`, `bypass`).\nconst SECRET_KEY_SUFFIX = /[a-z](Pass|Pwd|Passwd)$/;\n// separator-delimited short secret names, e.g. `auth.pass`, `db_pwd`, `x-pass`.\nconst SECRET_KEY_DELIMITED = /(^|[._-])(pass|pwd|passwd|dsn)([._-]|$)/i;\n\nconst isSecretKey = (key: string): boolean =>\n SECRET_KEY_PATTERN.test(key) ||\n SECRET_KEY_EXACT.has(key.toLowerCase()) ||\n SECRET_KEY_SUFFIX.test(key) ||\n SECRET_KEY_DELIMITED.test(key);\n\n// Layer 3: string values that look like secrets regardless of their key.\n// Real JWTs are base64url-encoded and the header segment always begins with\n// `eyJ` (the base64url encoding of `{\"`), so requiring that prefix avoids\n// matching arbitrary three-part dotted strings like semver versions\n// (e.g. \"5.50.1\", \"18.3.1\").\nconst JWT_PATTERN = /^eyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+$/;\nconst LONG_TOKEN_PATTERN = /^[A-Fa-f0-9]{32,}$|^[A-Za-z0-9+/]{40,}={0,2}$/;\n// Credentials embedded in a URL authority: `user:pass@` or `:pass@` (empty user,\n// as in `redis://:password@host`). The user part stops at the first colon, as in\n// RFC 3986, so the split between user and password is fixed; letting it take colons\n// made a long colon run with no `@` retry every split point, which is quadratic.\nconst URL_WITH_CREDENTIALS = /^[a-z][a-z0-9+.-]*:\\/\\/[^/@\\s:]*:[^/@\\s]+@/i;\n// PEM private key blocks (certificates are public, so only PRIVATE KEY is masked).\nconst PEM_PRIVATE_KEY_PATTERN = /-----BEGIN(?: [A-Z0-9]+)* PRIVATE KEY-----/;\n// URLs whose secret is carried in the host/path rather than a `user:pass@` authority:\n// chat webhooks and error-tracking DSNs.\nconst SECRET_URL_PATTERN =\n /^https:\\/\\/hooks\\.slack\\.com\\/services\\/|^https:\\/\\/(?:discord|discordapp)\\.com\\/api\\/webhooks\\/|:\\/\\/[^/@\\s]+@[^/\\s]*\\bsentry\\.io\\b/i;\n\n// Well-known provider secret token formats, matched against the whole value. The\n// prefixes are specific enough to have negligible false-positive risk, so they\n// mask a value even under an innocuous key (e.g. `key: 'sk_live_...'`).\n// `pk_` (publishable) keys are intentionally excluded — they are public by design.\nconst PROVIDER_SECRET_PATTERN = new RegExp(\n [\n '^(sk|rk)_(live|test)_[A-Za-z0-9]{8,}$', // Stripe secret / restricted\n '^whsec_[A-Za-z0-9]{16,}$', // Stripe webhook signing secret\n '^(gh[posru]_|github_pat_)[A-Za-z0-9_]{20,}$', // GitHub tokens / fine-grained PAT\n '^xox[baprs]-[A-Za-z0-9-]{10,}$', // Slack tokens\n '^(AKIA|ASIA)[A-Z0-9]{16}$', // AWS access key id\n '^SG\\\\.[A-Za-z0-9_-]{16,}\\\\.[A-Za-z0-9_-]{16,}$', // SendGrid\n '^AIza[A-Za-z0-9_-]{20,}$', // Google API key\n '^ya29\\\\.[A-Za-z0-9_-]{20,}$', // Google OAuth access token\n '^glpat-[A-Za-z0-9_-]{16,}$', // GitLab personal access token\n '^(shpat|shpss|shpca|shppa)_[A-Za-z0-9]{20,}$', // Shopify\n '^dop_v1_[a-f0-9]{40,}$', // DigitalOcean\n '^re_[A-Za-z0-9_]{16,}$', // Resend\n '^nfp_[A-Za-z0-9]{20,}$', // Netlify\n '^EAAA[A-Za-z0-9_-]{20,}$', // Square\n ].join('|')\n);\n\nconst looksSecret = (value: string): boolean =>\n JWT_PATTERN.test(value) ||\n LONG_TOKEN_PATTERN.test(value) ||\n URL_WITH_CREDENTIALS.test(value) ||\n PROVIDER_SECRET_PATTERN.test(value) ||\n PEM_PRIVATE_KEY_PATTERN.test(value) ||\n SECRET_URL_PATTERN.test(value);\n\nexport interface ScrubOptions {\n appRoot?: string;\n homeDir?: string;\n extraPaths?: string[];\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n return false;\n }\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n};\n\n// Accept either separator regardless of the host platform: `os.homedir()` and the app root come\n// back with backslashes on Windows, and a dump may also carry POSIX-style paths (e.g. from\n// config values), so a POSIX-only prefix check would ship absolute Windows paths verbatim.\nconst isPathPrefix = (value: string, prefix: string): boolean => {\n if (value === prefix) {\n return true;\n }\n if (!value.startsWith(prefix)) {\n return false;\n }\n const next = value.charAt(prefix.length);\n return next === '/' || next === '\\\\';\n};\n\nconst relativize = (value: string, appRoot?: string, homeDir?: string): string => {\n if (appRoot && isPathPrefix(value, appRoot)) {\n return `<app>${value.slice(appRoot.length)}`;\n }\n if (homeDir && isPathPrefix(value, homeDir)) {\n return `<home>${value.slice(homeDir.length)}`;\n }\n return value;\n};\n\n// Characters that end a URL authority\nconst AUTHORITY_END = new Set(['/', '?', '#', ' ', '\\t', '\\n', '\\r', '\"', \"'\", '`']);\n\n/**\n * Masks the password of every `scheme://user:password@host` inside a longer string, such as a\n * package.json script that inlines a database URL. Whole-value credential URLs are already\n * caught by URL_WITH_CREDENTIALS; this covers the ones in the middle of a value. It is a single\n * forward scan rather than a regex, because an unanchored pattern backtracks quadratically on\n * long runs (the reason URL_WITH_CREDENTIALS is anchored and colon-free in the user part).\n */\nconst maskEmbeddedCredentials = (value: string): string => {\n let result = '';\n let copiedUpTo = 0;\n let separator = value.indexOf('://');\n\n while (separator !== -1) {\n const authorityStart = separator + 3;\n let firstColon = -1;\n let lastAt = -1;\n let end = authorityStart;\n\n while (end < value.length && !AUTHORITY_END.has(value[end])) {\n if (value[end] === ':' && firstColon === -1) {\n firstColon = end;\n } else if (value[end] === '@') {\n lastAt = end;\n }\n end += 1;\n }\n\n // A colon before the last `@` separates user and password; one after it is a port.\n if (firstColon !== -1 && lastAt > firstColon) {\n result += `${value.slice(copiedUpTo, firstColon + 1)}${REDACTED}`;\n copiedUpTo = lastAt;\n }\n\n separator = value.indexOf('://', end);\n }\n\n return copiedUpTo === 0 ? value : result + value.slice(copiedUpTo);\n};\n\nconst deleteAtPath = (target: unknown, path: string): void => {\n const segments = path.split('.');\n let node: unknown = target;\n for (let i = 0; i < segments.length - 1; i += 1) {\n if (!isPlainObject(node)) {\n return;\n }\n node = node[segments[i]];\n }\n const lastKey = segments[segments.length - 1];\n if (isPlainObject(node) && lastKey in node) {\n node[lastKey] = REDACTED;\n }\n};\n\nconst walk = (value: unknown, appRoot?: string, homeDir?: string): unknown => {\n if (typeof value === 'string') {\n // Relativization is tried FIRST, and a value it rewrote is returned as-is. A string\n // that starts with the app root or the home directory is a path, never a credential,\n // whereas the reverse order let the secret heuristics claim one: a POSIX path made\n // only of letters, digits and `/` is valid standard base64, so anything past 40\n // characters matched LONG_TOKEN_PATTERN and shipped as `[REDACTED]` instead of\n // `<app>/...`. Values that do not relativize still go through the full checks.\n const relativized = relativize(value, appRoot, homeDir);\n if (relativized !== value) {\n return relativized;\n }\n return looksSecret(value) ? REDACTED : maskEmbeddedCredentials(value);\n }\n if (Array.isArray(value)) {\n return value.map((item) => walk(item, appRoot, homeDir));\n }\n if (isPlainObject(value)) {\n const out: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value)) {\n if (key === '__proto__') {\n continue; // never write through the Object.prototype setter\n }\n // A secret-named key always collapses wholesale, regardless of the value's\n // type. Recursing into it (e.g. for `apiToken: { salt, ... }`) would leak\n // any inner value whose own key/value doesn't independently match a\n // masking pattern (e.g. `providerOptions.auth.pass`), so there is nothing\n // safe to preserve underneath a secret-named container.\n out[key] = isSecretKey(key) ? REDACTED : walk(val, appRoot, homeDir);\n }\n return out;\n }\n // Any other object type — Buffer, Date, Map, Set, class instances, etc. —\n // is not a plain data container we can safely walk (Object.entries on a\n // Buffer leaks its bytes, a Date serializes to `{}`), so redact defensively.\n if (value !== null && typeof value === 'object') {\n return REDACTED;\n }\n return value;\n};\n\nexport const scrub = (value: unknown, options: ScrubOptions = {}): unknown => {\n const cloned = walk(value, options.appRoot, options.homeDir);\n for (const path of options.extraPaths ?? []) {\n deleteAtPath(cloned, path);\n }\n return cloned;\n};\n"],"names":["REDACTED","SECRET_KEY_PATTERN","SECRET_KEY_EXACT","Set","SECRET_KEY_SUFFIX","SECRET_KEY_DELIMITED","isSecretKey","key","test","has","toLowerCase","JWT_PATTERN","LONG_TOKEN_PATTERN","URL_WITH_CREDENTIALS","PEM_PRIVATE_KEY_PATTERN","SECRET_URL_PATTERN","PROVIDER_SECRET_PATTERN","RegExp","join","looksSecret","value","isPlainObject","Array","isArray","proto","Object","getPrototypeOf","prototype","isPathPrefix","prefix","startsWith","next","charAt","length","relativize","appRoot","homeDir","slice","AUTHORITY_END","maskEmbeddedCredentials","result","copiedUpTo","separator","indexOf","authorityStart","firstColon","lastAt","end","deleteAtPath","target","path","segments","split","node","i","lastKey","walk","relativized","map","item","out","val","entries","scrub","options","cloned","extraPaths"],"mappings":"AAAO,MAAMA,WAAW;AAExB;AACA,MAAMC,kBAAAA,GACJ,4NAAA;AAEF;AACA;AACA;AACA,MAAMC,gBAAAA,GAAmB,IAAIC,GAAAA,CAAI;AAAC,IAAA,MAAA;AAAQ,IAAA,KAAA;AAAO,IAAA,QAAA;AAAU,IAAA;AAAM,CAAA,CAAA;AACjE;AACA;AACA,MAAMC,iBAAAA,GAAoB,yBAAA;AAC1B;AACA,MAAMC,oBAAAA,GAAuB,0CAAA;AAE7B,MAAMC,cAAc,CAACC,GAAAA,GACnBN,mBAAmBO,IAAI,CAACD,QACxBL,gBAAAA,CAAiBO,GAAG,CAACF,GAAAA,CAAIG,WAAW,OACpCN,iBAAAA,CAAkBI,IAAI,CAACD,GAAAA,CAAAA,IACvBF,oBAAAA,CAAqBG,IAAI,CAACD,GAAAA,CAAAA;AAE5B;AACA;AACA;AACA;AACA;AACA,MAAMI,WAAAA,GAAc,qDAAA;AACpB,MAAMC,kBAAAA,GAAqB,+CAAA;AAC3B;AACA;AACA;AACA;AACA,MAAMC,oBAAAA,GAAuB,6CAAA;AAC7B;AACA,MAAMC,uBAAAA,GAA0B,4CAAA;AAChC;AACA;AACA,MAAMC,kBAAAA,GACJ,uIAAA;AAEF;AACA;AACA;AACA;AACA,MAAMC,uBAAAA,GAA0B,IAAIC,MAAAA,CAClC;AACE,IAAA,uCAAA;AACA,IAAA,0BAAA;AACA,IAAA,6CAAA;AACA,IAAA,gCAAA;AACA,IAAA,2BAAA;AACA,IAAA,gDAAA;AACA,IAAA,0BAAA;AACA,IAAA,6BAAA;AACA,IAAA,4BAAA;AACA,IAAA,8CAAA;AACA,IAAA,wBAAA;AACA,IAAA,wBAAA;AACA,IAAA,wBAAA;AACA,IAAA;AACD,CAAA,CAACC,IAAI,CAAC,GAAA,CAAA,CAAA;AAGT,MAAMC,WAAAA,GAAc,CAACC,KAAAA,GACnBT,WAAAA,CAAYH,IAAI,CAACY,KAAAA,CAAAA,IACjBR,kBAAAA,CAAmBJ,IAAI,CAACY,KAAAA,CAAAA,IACxBP,oBAAAA,CAAqBL,IAAI,CAACY,KAAAA,CAAAA,IAC1BJ,uBAAAA,CAAwBR,IAAI,CAACY,KAAAA,CAAAA,IAC7BN,uBAAAA,CAAwBN,IAAI,CAACY,KAAAA,CAAAA,IAC7BL,kBAAAA,CAAmBP,IAAI,CAACY,KAAAA,CAAAA;AAQ1B,MAAMC,gBAAgB,CAACD,KAAAA,GAAAA;IACrB,IAAIA,KAAAA,KAAU,QAAQ,OAAOA,KAAAA,KAAU,YAAYE,KAAAA,CAAMC,OAAO,CAACH,KAAAA,CAAAA,EAAQ;QACvE,OAAO,KAAA;AACT,IAAA;IACA,MAAMI,KAAAA,GAAQC,MAAAA,CAAOC,cAAc,CAACN,KAAAA,CAAAA;AACpC,IAAA,OAAOI,KAAAA,KAAUC,MAAAA,CAAOE,SAAS,IAAIH,KAAAA,KAAU,IAAA;AACjD,CAAA;AAEA;AACA;AACA;AACA,MAAMI,YAAAA,GAAe,CAACR,KAAAA,EAAeS,MAAAA,GAAAA;AACnC,IAAA,IAAIT,UAAUS,MAAAA,EAAQ;QACpB,OAAO,IAAA;AACT,IAAA;AACA,IAAA,IAAI,CAACT,KAAAA,CAAMU,UAAU,CAACD,MAAAA,CAAAA,EAAS;QAC7B,OAAO,KAAA;AACT,IAAA;AACA,IAAA,MAAME,IAAAA,GAAOX,KAAAA,CAAMY,MAAM,CAACH,OAAOI,MAAM,CAAA;IACvC,OAAOF,IAAAA,KAAS,OAAOA,IAAAA,KAAS,IAAA;AAClC,CAAA;AAEA,MAAMG,UAAAA,GAAa,CAACd,KAAAA,EAAee,OAAAA,EAAkBC,OAAAA,GAAAA;IACnD,IAAID,OAAAA,IAAWP,YAAAA,CAAaR,KAAAA,EAAOe,OAAAA,CAAAA,EAAU;QAC3C,OAAO,CAAC,KAAK,EAAEf,KAAAA,CAAMiB,KAAK,CAACF,OAAAA,CAAQF,MAAM,CAAA,CAAA,CAAG;AAC9C,IAAA;IACA,IAAIG,OAAAA,IAAWR,YAAAA,CAAaR,KAAAA,EAAOgB,OAAAA,CAAAA,EAAU;QAC3C,OAAO,CAAC,MAAM,EAAEhB,KAAAA,CAAMiB,KAAK,CAACD,OAAAA,CAAQH,MAAM,CAAA,CAAA,CAAG;AAC/C,IAAA;IACA,OAAOb,KAAAA;AACT,CAAA;AAEA;AACA,MAAMkB,aAAAA,GAAgB,IAAInC,GAAAA,CAAI;AAAC,IAAA,GAAA;AAAK,IAAA,GAAA;AAAK,IAAA,GAAA;AAAK,IAAA,GAAA;AAAK,IAAA,IAAA;AAAM,IAAA,IAAA;AAAM,IAAA,IAAA;AAAM,IAAA,GAAA;AAAK,IAAA,GAAA;AAAK,IAAA;AAAI,CAAA,CAAA;AAEnF;;;;;;IAOA,MAAMoC,0BAA0B,CAACnB,KAAAA,GAAAA;AAC/B,IAAA,IAAIoB,MAAAA,GAAS,EAAA;AACb,IAAA,IAAIC,UAAAA,GAAa,CAAA;IACjB,IAAIC,SAAAA,GAAYtB,KAAAA,CAAMuB,OAAO,CAAC,KAAA,CAAA;IAE9B,MAAOD,SAAAA,KAAc,EAAC,CAAG;AACvB,QAAA,MAAME,iBAAiBF,SAAAA,GAAY,CAAA;AACnC,QAAA,IAAIG,aAAa,EAAC;AAClB,QAAA,IAAIC,SAAS,EAAC;AACd,QAAA,IAAIC,GAAAA,GAAMH,cAAAA;QAEV,MAAOG,GAAAA,GAAM3B,KAAAA,CAAMa,MAAM,IAAI,CAACK,aAAAA,CAAc7B,GAAG,CAACW,KAAK,CAAC2B,GAAAA,CAAI,CAAA,CAAG;AAC3D,YAAA,IAAI3B,KAAK,CAAC2B,GAAAA,CAAI,KAAK,GAAA,IAAOF,UAAAA,KAAe,EAAC,EAAG;gBAC3CA,UAAAA,GAAaE,GAAAA;AACf,YAAA,CAAA,MAAO,IAAI3B,KAAK,CAAC2B,GAAAA,CAAI,KAAK,GAAA,EAAK;gBAC7BD,MAAAA,GAASC,GAAAA;AACX,YAAA;YACAA,GAAAA,IAAO,CAAA;AACT,QAAA;;AAGA,QAAA,IAAIF,UAAAA,KAAe,EAAC,IAAKC,MAAAA,GAASD,UAAAA,EAAY;AAC5CL,YAAAA,MAAAA,IAAU,GAAGpB,KAAAA,CAAMiB,KAAK,CAACI,UAAAA,EAAYI,UAAAA,GAAa,KAAK7C,QAAAA,CAAAA,CAAU;YACjEyC,UAAAA,GAAaK,MAAAA;AACf,QAAA;QAEAJ,SAAAA,GAAYtB,KAAAA,CAAMuB,OAAO,CAAC,KAAA,EAAOI,GAAAA,CAAAA;AACnC,IAAA;AAEA,IAAA,OAAON,eAAe,CAAA,GAAIrB,KAAAA,GAAQoB,MAAAA,GAASpB,KAAAA,CAAMiB,KAAK,CAACI,UAAAA,CAAAA;AACzD,CAAA;AAEA,MAAMO,YAAAA,GAAe,CAACC,MAAAA,EAAiBC,IAAAA,GAAAA;IACrC,MAAMC,QAAAA,GAAWD,IAAAA,CAAKE,KAAK,CAAC,GAAA,CAAA;AAC5B,IAAA,IAAIC,IAAAA,GAAgBJ,MAAAA;IACpB,IAAK,IAAIK,IAAI,CAAA,EAAGA,CAAAA,GAAIH,SAASlB,MAAM,GAAG,CAAA,EAAGqB,CAAAA,IAAK,CAAA,CAAG;QAC/C,IAAI,CAACjC,cAAcgC,IAAAA,CAAAA,EAAO;AACxB,YAAA;AACF,QAAA;AACAA,QAAAA,IAAAA,GAAOA,IAAI,CAACF,QAAQ,CAACG,EAAE,CAAC;AAC1B,IAAA;AACA,IAAA,MAAMC,UAAUJ,QAAQ,CAACA,QAAAA,CAASlB,MAAM,GAAG,CAAA,CAAE;IAC7C,IAAIZ,aAAAA,CAAcgC,IAAAA,CAAAA,IAASE,OAAAA,IAAWF,IAAAA,EAAM;QAC1CA,IAAI,CAACE,QAAQ,GAAGvD,QAAAA;AAClB,IAAA;AACF,CAAA;AAEA,MAAMwD,IAAAA,GAAO,CAACpC,KAAAA,EAAgBe,OAAAA,EAAkBC,OAAAA,GAAAA;IAC9C,IAAI,OAAOhB,UAAU,QAAA,EAAU;;;;;;;QAO7B,MAAMqC,WAAAA,GAAcvB,UAAAA,CAAWd,KAAAA,EAAOe,OAAAA,EAASC,OAAAA,CAAAA;AAC/C,QAAA,IAAIqB,gBAAgBrC,KAAAA,EAAO;YACzB,OAAOqC,WAAAA;AACT,QAAA;QACA,OAAOtC,WAAAA,CAAYC,KAAAA,CAAAA,GAASpB,QAAAA,GAAWuC,uBAAAA,CAAwBnB,KAAAA,CAAAA;AACjE,IAAA;IACA,IAAIE,KAAAA,CAAMC,OAAO,CAACH,KAAAA,CAAAA,EAAQ;AACxB,QAAA,OAAOA,MAAMsC,GAAG,CAAC,CAACC,IAAAA,GAASH,IAAAA,CAAKG,MAAMxB,OAAAA,EAASC,OAAAA,CAAAA,CAAAA;AACjD,IAAA;AACA,IAAA,IAAIf,cAAcD,KAAAA,CAAAA,EAAQ;AACxB,QAAA,MAAMwC,MAA+B,EAAC;QACtC,KAAK,MAAM,CAACrD,GAAAA,EAAKsD,GAAAA,CAAI,IAAIpC,MAAAA,CAAOqC,OAAO,CAAC1C,KAAAA,CAAAA,CAAQ;AAC9C,YAAA,IAAIb,QAAQ,WAAA,EAAa;AACvB,gBAAA,SAAA;AACF,YAAA;;;;;;YAMAqD,GAAG,CAACrD,IAAI,GAAGD,WAAAA,CAAYC,OAAOP,QAAAA,GAAWwD,IAAAA,CAAKK,KAAK1B,OAAAA,EAASC,OAAAA,CAAAA;AAC9D,QAAA;QACA,OAAOwB,GAAAA;AACT,IAAA;;;;AAIA,IAAA,IAAIxC,KAAAA,KAAU,IAAA,IAAQ,OAAOA,KAAAA,KAAU,QAAA,EAAU;QAC/C,OAAOpB,QAAAA;AACT,IAAA;IACA,OAAOoB,KAAAA;AACT,CAAA;MAEa2C,KAAAA,GAAQ,CAAC3C,KAAAA,EAAgB4C,OAAAA,GAAwB,EAAE,GAAA;AAC9D,IAAA,MAAMC,SAAST,IAAAA,CAAKpC,KAAAA,EAAO4C,QAAQ7B,OAAO,EAAE6B,QAAQ5B,OAAO,CAAA;AAC3D,IAAA,KAAK,MAAMc,IAAAA,IAAQc,OAAAA,CAAQE,UAAU,IAAI,EAAE,CAAE;AAC3ClB,QAAAA,YAAAA,CAAaiB,MAAAA,EAAQf,IAAAA,CAAAA;AACvB,IAAA;IACA,OAAOe,MAAAA;AACT;;;;"}