@strapi/admin 5.56.0 → 5.58.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 (465) hide show
  1. package/dist/admin/admin/src/components/Filters.js +1 -1
  2. package/dist/admin/admin/src/components/Filters.js.map +1 -1
  3. package/dist/admin/admin/src/components/Filters.mjs +1 -1
  4. package/dist/admin/admin/src/components/Filters.mjs.map +1 -1
  5. package/dist/admin/admin/src/components/FormInputs/Boolean.js +3 -2
  6. package/dist/admin/admin/src/components/FormInputs/Boolean.js.map +1 -1
  7. package/dist/admin/admin/src/components/FormInputs/Boolean.mjs +3 -2
  8. package/dist/admin/admin/src/components/FormInputs/Boolean.mjs.map +1 -1
  9. package/dist/admin/admin/src/components/FormInputs/Enumeration.js +2 -2
  10. package/dist/admin/admin/src/components/FormInputs/Enumeration.js.map +1 -1
  11. package/dist/admin/admin/src/components/FormInputs/Enumeration.mjs +2 -2
  12. package/dist/admin/admin/src/components/FormInputs/Enumeration.mjs.map +1 -1
  13. package/dist/admin/admin/src/components/MediaLibraryBanner.js +38 -2
  14. package/dist/admin/admin/src/components/MediaLibraryBanner.js.map +1 -1
  15. package/dist/admin/admin/src/components/MediaLibraryBanner.mjs +18 -2
  16. package/dist/admin/admin/src/components/MediaLibraryBanner.mjs.map +1 -1
  17. package/dist/admin/admin/src/components/RelativeTime.js +9 -0
  18. package/dist/admin/admin/src/components/RelativeTime.js.map +1 -1
  19. package/dist/admin/admin/src/components/RelativeTime.mjs +10 -1
  20. package/dist/admin/admin/src/components/RelativeTime.mjs.map +1 -1
  21. package/dist/admin/admin/src/components/TopBanners.js +52 -0
  22. package/dist/admin/admin/src/components/TopBanners.js.map +1 -0
  23. package/dist/admin/admin/src/components/TopBanners.mjs +30 -0
  24. package/dist/admin/admin/src/components/TopBanners.mjs.map +1 -0
  25. package/dist/admin/admin/src/constants.js +14 -0
  26. package/dist/admin/admin/src/constants.js.map +1 -1
  27. package/dist/admin/admin/src/constants.mjs +14 -0
  28. package/dist/admin/admin/src/constants.mjs.map +1 -1
  29. package/dist/admin/admin/src/features/Tracking.js +28 -8
  30. package/dist/admin/admin/src/features/Tracking.js.map +1 -1
  31. package/dist/admin/admin/src/features/Tracking.mjs +29 -10
  32. package/dist/admin/admin/src/features/Tracking.mjs.map +1 -1
  33. package/dist/admin/admin/src/layouts/AuthenticatedLayout.js +4 -20
  34. package/dist/admin/admin/src/layouts/AuthenticatedLayout.js.map +1 -1
  35. package/dist/admin/admin/src/layouts/AuthenticatedLayout.mjs +4 -20
  36. package/dist/admin/admin/src/layouts/AuthenticatedLayout.mjs.map +1 -1
  37. package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.js +59 -0
  38. package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.js.map +1 -0
  39. package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.mjs +37 -0
  40. package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.mjs.map +1 -0
  41. package/dist/admin/admin/src/pages/Auth/components/ResetPassword.js +6 -12
  42. package/dist/admin/admin/src/pages/Auth/components/ResetPassword.js.map +1 -1
  43. package/dist/admin/admin/src/pages/Auth/components/ResetPassword.mjs +6 -12
  44. package/dist/admin/admin/src/pages/Auth/components/ResetPassword.mjs.map +1 -1
  45. package/dist/admin/admin/src/pages/Settings/components/SettingsNav.js +10 -2
  46. package/dist/admin/admin/src/pages/Settings/components/SettingsNav.js.map +1 -1
  47. package/dist/admin/admin/src/pages/Settings/components/SettingsNav.mjs +10 -2
  48. package/dist/admin/admin/src/pages/Settings/components/SettingsNav.mjs.map +1 -1
  49. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.js +6 -56
  50. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.js.map +1 -1
  51. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.mjs +6 -56
  52. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.mjs.map +1 -1
  53. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/DiagnosticSnapshotModal.js +217 -0
  54. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/DiagnosticSnapshotModal.js.map +1 -0
  55. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/DiagnosticSnapshotModal.mjs +195 -0
  56. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/DiagnosticSnapshotModal.mjs.map +1 -0
  57. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/PlanCard.js +185 -0
  58. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/PlanCard.js.map +1 -0
  59. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/PlanCard.mjs +162 -0
  60. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/PlanCard.mjs.map +1 -0
  61. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/SupportCard.js +342 -0
  62. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/SupportCard.js.map +1 -0
  63. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/SupportCard.mjs +320 -0
  64. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/SupportCard.mjs.map +1 -0
  65. package/dist/admin/admin/src/services/admin.js +11 -1
  66. package/dist/admin/admin/src/services/admin.js.map +1 -1
  67. package/dist/admin/admin/src/services/admin.mjs +11 -2
  68. package/dist/admin/admin/src/services/admin.mjs.map +1 -1
  69. package/dist/admin/admin/src/translations/en.json.js +76 -4
  70. package/dist/admin/admin/src/translations/en.json.js.map +1 -1
  71. package/dist/admin/admin/src/translations/en.json.mjs +76 -4
  72. package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
  73. package/dist/admin/admin/src/utils/browserStrapi.js +1 -1
  74. package/dist/admin/admin/src/utils/browserStrapi.js.map +1 -1
  75. package/dist/admin/admin/src/utils/browserStrapi.mjs +1 -1
  76. package/dist/admin/admin/src/utils/browserStrapi.mjs.map +1 -1
  77. package/dist/admin/admin/src/utils/getFetchClient.js +27 -3
  78. package/dist/admin/admin/src/utils/getFetchClient.js.map +1 -1
  79. package/dist/admin/admin/src/utils/getFetchClient.mjs +26 -3
  80. package/dist/admin/admin/src/utils/getFetchClient.mjs.map +1 -1
  81. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.js +52 -22
  82. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.js.map +1 -1
  83. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.mjs +53 -23
  84. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.mjs.map +1 -1
  85. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AdminSeatInfo.js +16 -29
  86. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AdminSeatInfo.js.map +1 -1
  87. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AdminSeatInfo.mjs +18 -31
  88. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AdminSeatInfo.mjs.map +1 -1
  89. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/LicenseInfo.js +473 -0
  90. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/LicenseInfo.js.map +1 -0
  91. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/LicenseInfo.mjs +471 -0
  92. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/LicenseInfo.mjs.map +1 -0
  93. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js +8 -1
  94. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js.map +1 -1
  95. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs +8 -1
  96. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs.map +1 -1
  97. package/dist/admin/index.js +1 -0
  98. package/dist/admin/index.js.map +1 -1
  99. package/dist/admin/index.mjs +1 -1
  100. package/dist/admin/shared/utils/get-project-type.js +49 -0
  101. package/dist/admin/shared/utils/get-project-type.js.map +1 -0
  102. package/dist/admin/shared/utils/get-project-type.mjs +46 -0
  103. package/dist/admin/shared/utils/get-project-type.mjs.map +1 -0
  104. package/dist/admin/src/components/MediaLibraryBanner.d.ts +10 -1
  105. package/dist/admin/src/components/TopBanners.d.ts +8 -0
  106. package/dist/admin/src/constants.d.ts +10 -0
  107. package/dist/admin/src/features/Tracking.d.ts +12 -1
  108. package/dist/admin/src/layouts/useAuthenticatedAccessTracking.d.ts +6 -0
  109. package/dist/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.d.ts +1 -1
  110. package/dist/admin/src/pages/Settings/pages/ApplicationInfo/components/DiagnosticSnapshotModal.d.ts +12 -0
  111. package/dist/admin/src/pages/Settings/pages/ApplicationInfo/components/PlanCard.d.ts +14 -0
  112. package/dist/admin/src/pages/Settings/pages/ApplicationInfo/components/SupportCard.d.ts +2 -0
  113. package/dist/admin/src/services/admin.d.ts +2 -2
  114. package/dist/admin/src/types/permissions.d.ts +1 -0
  115. package/dist/admin/src/utils/getFetchClient.d.ts +25 -0
  116. package/dist/ee/admin/src/hooks/useLicenseLimits.d.ts +29 -0
  117. package/dist/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.d.ts +6 -1
  118. package/dist/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/LicenseInfo.d.ts +2 -0
  119. package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.d.ts +7 -0
  120. package/dist/ee/server/src/audit-logs/entitlements.d.ts +8 -0
  121. package/dist/ee/server/src/audit-logs/entitlements.d.ts.map +1 -0
  122. package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts +16 -0
  123. package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts.map +1 -1
  124. package/dist/ee/server/src/controllers/admin.d.ts +36 -10
  125. package/dist/ee/server/src/controllers/admin.d.ts.map +1 -1
  126. package/dist/ee/server/src/controllers/authentication-utils/middlewares.d.ts.map +1 -1
  127. package/dist/ee/server/src/controllers/authentication-utils/utils.d.ts +8 -2
  128. package/dist/ee/server/src/controllers/authentication-utils/utils.d.ts.map +1 -1
  129. package/dist/ee/server/src/controllers/authentication.d.ts.map +1 -1
  130. package/dist/ee/server/src/controllers/index.d.ts +36 -10
  131. package/dist/ee/server/src/controllers/index.d.ts.map +1 -1
  132. package/dist/ee/server/src/controllers/user.d.ts.map +1 -1
  133. package/dist/ee/server/src/index.d.ts +40 -11
  134. package/dist/ee/server/src/index.d.ts.map +1 -1
  135. package/dist/ee/server/src/services/index.d.ts +4 -1
  136. package/dist/ee/server/src/services/index.d.ts.map +1 -1
  137. package/dist/ee/server/src/services/metrics.d.ts.map +1 -1
  138. package/dist/ee/server/src/services/persist-tables.d.ts.map +1 -1
  139. package/dist/ee/server/src/services/seat-enforcement.d.ts +3 -1
  140. package/dist/ee/server/src/services/seat-enforcement.d.ts.map +1 -1
  141. package/dist/server/ee/server/src/audit-logs/entitlements.js +25 -0
  142. package/dist/server/ee/server/src/audit-logs/entitlements.js.map +1 -0
  143. package/dist/server/ee/server/src/audit-logs/entitlements.mjs +23 -0
  144. package/dist/server/ee/server/src/audit-logs/entitlements.mjs.map +1 -0
  145. package/dist/server/ee/server/src/audit-logs/services/lifecycles.js +20 -8
  146. package/dist/server/ee/server/src/audit-logs/services/lifecycles.js.map +1 -1
  147. package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs +19 -9
  148. package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs.map +1 -1
  149. package/dist/server/ee/server/src/controllers/admin.js +79 -7
  150. package/dist/server/ee/server/src/controllers/admin.js.map +1 -1
  151. package/dist/server/ee/server/src/controllers/admin.mjs +79 -7
  152. package/dist/server/ee/server/src/controllers/admin.mjs.map +1 -1
  153. package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.js +28 -10
  154. package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.js.map +1 -1
  155. package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.mjs +28 -10
  156. package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.mjs.map +1 -1
  157. package/dist/server/ee/server/src/controllers/authentication-utils/utils.js +2 -2
  158. package/dist/server/ee/server/src/controllers/authentication-utils/utils.js.map +1 -1
  159. package/dist/server/ee/server/src/controllers/authentication-utils/utils.mjs +2 -2
  160. package/dist/server/ee/server/src/controllers/authentication-utils/utils.mjs.map +1 -1
  161. package/dist/server/ee/server/src/controllers/authentication.js +11 -11
  162. package/dist/server/ee/server/src/controllers/authentication.js.map +1 -1
  163. package/dist/server/ee/server/src/controllers/authentication.mjs +11 -11
  164. package/dist/server/ee/server/src/controllers/authentication.mjs.map +1 -1
  165. package/dist/server/ee/server/src/controllers/user.js +7 -8
  166. package/dist/server/ee/server/src/controllers/user.js.map +1 -1
  167. package/dist/server/ee/server/src/controllers/user.mjs +8 -9
  168. package/dist/server/ee/server/src/controllers/user.mjs.map +1 -1
  169. package/dist/server/ee/server/src/index.js +2 -0
  170. package/dist/server/ee/server/src/index.js.map +1 -1
  171. package/dist/server/ee/server/src/index.mjs +2 -0
  172. package/dist/server/ee/server/src/index.mjs.map +1 -1
  173. package/dist/server/ee/server/src/services/metrics.js +9 -7
  174. package/dist/server/ee/server/src/services/metrics.js.map +1 -1
  175. package/dist/server/ee/server/src/services/metrics.mjs +9 -7
  176. package/dist/server/ee/server/src/services/metrics.mjs.map +1 -1
  177. package/dist/server/ee/server/src/services/persist-tables.js +3 -4
  178. package/dist/server/ee/server/src/services/persist-tables.js.map +1 -1
  179. package/dist/server/ee/server/src/services/persist-tables.mjs +3 -4
  180. package/dist/server/ee/server/src/services/persist-tables.mjs.map +1 -1
  181. package/dist/server/ee/server/src/services/role.js +2 -2
  182. package/dist/server/ee/server/src/services/role.js.map +1 -1
  183. package/dist/server/ee/server/src/services/role.mjs +1 -1
  184. package/dist/server/ee/server/src/services/role.mjs.map +1 -1
  185. package/dist/server/ee/server/src/services/seat-enforcement.js +20 -20
  186. package/dist/server/ee/server/src/services/seat-enforcement.js.map +1 -1
  187. package/dist/server/ee/server/src/services/seat-enforcement.mjs +20 -20
  188. package/dist/server/ee/server/src/services/seat-enforcement.mjs.map +1 -1
  189. package/dist/server/ee/server/src/services/user.js +1 -2
  190. package/dist/server/ee/server/src/services/user.js.map +1 -1
  191. package/dist/server/ee/server/src/services/user.mjs +2 -3
  192. package/dist/server/ee/server/src/services/user.mjs.map +1 -1
  193. package/dist/server/ee/server/src/utils/sso-lock.js +2 -2
  194. package/dist/server/ee/server/src/utils/sso-lock.js.map +1 -1
  195. package/dist/server/ee/server/src/utils/sso-lock.mjs +1 -1
  196. package/dist/server/ee/server/src/utils/sso-lock.mjs.map +1 -1
  197. package/dist/server/server/src/audit-logs/admin-users.js +3 -3
  198. package/dist/server/server/src/audit-logs/admin-users.js.map +1 -1
  199. package/dist/server/server/src/audit-logs/admin-users.mjs +2 -2
  200. package/dist/server/server/src/audit-logs/admin-users.mjs.map +1 -1
  201. package/dist/server/server/src/audit-logs/auth.js +72 -0
  202. package/dist/server/server/src/audit-logs/auth.js.map +1 -0
  203. package/dist/server/server/src/audit-logs/auth.mjs +67 -0
  204. package/dist/server/server/src/audit-logs/auth.mjs.map +1 -0
  205. package/dist/server/server/src/audit-logs/tokens.js +3 -3
  206. package/dist/server/server/src/audit-logs/tokens.js.map +1 -1
  207. package/dist/server/server/src/audit-logs/tokens.mjs +2 -2
  208. package/dist/server/server/src/audit-logs/tokens.mjs.map +1 -1
  209. package/dist/server/server/src/audit-logs/webhooks.js +2 -2
  210. package/dist/server/server/src/audit-logs/webhooks.js.map +1 -1
  211. package/dist/server/server/src/audit-logs/webhooks.mjs +1 -1
  212. package/dist/server/server/src/audit-logs/webhooks.mjs.map +1 -1
  213. package/dist/server/server/src/bootstrap.js +6 -4
  214. package/dist/server/server/src/bootstrap.js.map +1 -1
  215. package/dist/server/server/src/bootstrap.mjs +6 -4
  216. package/dist/server/server/src/bootstrap.mjs.map +1 -1
  217. package/dist/server/server/src/config/admin-actions.js +7 -0
  218. package/dist/server/server/src/config/admin-actions.js.map +1 -1
  219. package/dist/server/server/src/config/admin-actions.mjs +7 -0
  220. package/dist/server/server/src/config/admin-actions.mjs.map +1 -1
  221. package/dist/server/server/src/controllers/admin-token.js +8 -8
  222. package/dist/server/server/src/controllers/admin-token.js.map +1 -1
  223. package/dist/server/server/src/controllers/admin-token.mjs +4 -4
  224. package/dist/server/server/src/controllers/admin-token.mjs.map +1 -1
  225. package/dist/server/server/src/controllers/admin.js +9 -5
  226. package/dist/server/server/src/controllers/admin.js.map +1 -1
  227. package/dist/server/server/src/controllers/admin.mjs +8 -4
  228. package/dist/server/server/src/controllers/admin.mjs.map +1 -1
  229. package/dist/server/server/src/controllers/api-token.js +8 -8
  230. package/dist/server/server/src/controllers/api-token.js.map +1 -1
  231. package/dist/server/server/src/controllers/api-token.mjs +4 -4
  232. package/dist/server/server/src/controllers/api-token.mjs.map +1 -1
  233. package/dist/server/server/src/controllers/authentication.js +34 -8
  234. package/dist/server/server/src/controllers/authentication.js.map +1 -1
  235. package/dist/server/server/src/controllers/authentication.mjs +34 -8
  236. package/dist/server/server/src/controllers/authentication.mjs.map +1 -1
  237. package/dist/server/server/src/controllers/formatters/conditions.js +2 -2
  238. package/dist/server/server/src/controllers/formatters/conditions.js.map +1 -1
  239. package/dist/server/server/src/controllers/formatters/conditions.mjs +2 -2
  240. package/dist/server/server/src/controllers/formatters/conditions.mjs.map +1 -1
  241. package/dist/server/server/src/controllers/transfer/index.js +2 -2
  242. package/dist/server/server/src/controllers/transfer/index.js.map +1 -1
  243. package/dist/server/server/src/controllers/transfer/index.mjs +2 -2
  244. package/dist/server/server/src/controllers/transfer/index.mjs.map +1 -1
  245. package/dist/server/server/src/controllers/transfer/token.js +8 -8
  246. package/dist/server/server/src/controllers/transfer/token.js.map +1 -1
  247. package/dist/server/server/src/controllers/transfer/token.mjs +4 -4
  248. package/dist/server/server/src/controllers/transfer/token.mjs.map +1 -1
  249. package/dist/server/server/src/domain/action/index.js +18 -16
  250. package/dist/server/server/src/domain/action/index.js.map +1 -1
  251. package/dist/server/server/src/domain/action/index.mjs +16 -14
  252. package/dist/server/server/src/domain/action/index.mjs.map +1 -1
  253. package/dist/server/server/src/domain/action/provider.mjs +4 -4
  254. package/dist/server/server/src/domain/action/provider.mjs.map +1 -1
  255. package/dist/server/server/src/domain/condition/index.js +7 -4
  256. package/dist/server/server/src/domain/condition/index.js.map +1 -1
  257. package/dist/server/server/src/domain/condition/index.mjs +7 -4
  258. package/dist/server/server/src/domain/condition/index.mjs.map +1 -1
  259. package/dist/server/server/src/domain/permission/index.js +24 -15
  260. package/dist/server/server/src/domain/permission/index.js.map +1 -1
  261. package/dist/server/server/src/domain/permission/index.mjs +21 -12
  262. package/dist/server/server/src/domain/permission/index.mjs.map +1 -1
  263. package/dist/server/server/src/middlewares/rateLimit.js +5 -5
  264. package/dist/server/server/src/middlewares/rateLimit.js.map +1 -1
  265. package/dist/server/server/src/middlewares/rateLimit.mjs +4 -4
  266. package/dist/server/server/src/middlewares/rateLimit.mjs.map +1 -1
  267. package/dist/server/server/src/register.js +10 -0
  268. package/dist/server/server/src/register.js.map +1 -1
  269. package/dist/server/server/src/register.mjs +10 -0
  270. package/dist/server/server/src/register.mjs.map +1 -1
  271. package/dist/server/server/src/routes/admin.js +18 -0
  272. package/dist/server/server/src/routes/admin.js.map +1 -1
  273. package/dist/server/server/src/routes/admin.mjs +18 -0
  274. package/dist/server/server/src/routes/admin.mjs.map +1 -1
  275. package/dist/server/server/src/services/action.js +1 -2
  276. package/dist/server/server/src/services/action.js.map +1 -1
  277. package/dist/server/server/src/services/action.mjs +1 -2
  278. package/dist/server/server/src/services/action.mjs.map +1 -1
  279. package/dist/server/server/src/services/api-token.js +61 -49
  280. package/dist/server/server/src/services/api-token.js.map +1 -1
  281. package/dist/server/server/src/services/api-token.mjs +53 -41
  282. package/dist/server/server/src/services/api-token.mjs.map +1 -1
  283. package/dist/server/server/src/services/auth.js +4 -2
  284. package/dist/server/server/src/services/auth.js.map +1 -1
  285. package/dist/server/server/src/services/auth.mjs +4 -3
  286. package/dist/server/server/src/services/auth.mjs.map +1 -1
  287. package/dist/server/server/src/services/condition.js +2 -2
  288. package/dist/server/server/src/services/condition.js.map +1 -1
  289. package/dist/server/server/src/services/condition.mjs +1 -1
  290. package/dist/server/server/src/services/condition.mjs.map +1 -1
  291. package/dist/server/server/src/services/content-type.js +5 -4
  292. package/dist/server/server/src/services/content-type.js.map +1 -1
  293. package/dist/server/server/src/services/content-type.mjs +8 -7
  294. package/dist/server/server/src/services/content-type.mjs.map +1 -1
  295. package/dist/server/server/src/services/debug-dump.js +173 -0
  296. package/dist/server/server/src/services/debug-dump.js.map +1 -0
  297. package/dist/server/server/src/services/debug-dump.mjs +166 -0
  298. package/dist/server/server/src/services/debug-dump.mjs.map +1 -0
  299. package/dist/server/server/src/services/homepage.js +2 -1
  300. package/dist/server/server/src/services/homepage.js.map +1 -1
  301. package/dist/server/server/src/services/homepage.mjs +2 -1
  302. package/dist/server/server/src/services/homepage.mjs.map +1 -1
  303. package/dist/server/server/src/services/index.js +3 -1
  304. package/dist/server/server/src/services/index.js.map +1 -1
  305. package/dist/server/server/src/services/index.mjs +3 -1
  306. package/dist/server/server/src/services/index.mjs.map +1 -1
  307. package/dist/server/server/src/services/passport/local-strategy.js +2 -2
  308. package/dist/server/server/src/services/passport/local-strategy.js.map +1 -1
  309. package/dist/server/server/src/services/passport/local-strategy.mjs +1 -1
  310. package/dist/server/server/src/services/passport/local-strategy.mjs.map +1 -1
  311. package/dist/server/server/src/services/passport.js +1 -2
  312. package/dist/server/server/src/services/passport.js.map +1 -1
  313. package/dist/server/server/src/services/passport.mjs +1 -2
  314. package/dist/server/server/src/services/passport.mjs.map +1 -1
  315. package/dist/server/server/src/services/permission/engine.js +4 -4
  316. package/dist/server/server/src/services/permission/engine.js.map +1 -1
  317. package/dist/server/server/src/services/permission/engine.mjs +2 -2
  318. package/dist/server/server/src/services/permission/engine.mjs.map +1 -1
  319. package/dist/server/server/src/services/permission/permissions-manager/index.js +2 -3
  320. package/dist/server/server/src/services/permission/permissions-manager/index.js.map +1 -1
  321. package/dist/server/server/src/services/permission/permissions-manager/index.mjs +1 -2
  322. package/dist/server/server/src/services/permission/permissions-manager/index.mjs.map +1 -1
  323. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.js +6 -6
  324. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.js.map +1 -1
  325. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.mjs +4 -4
  326. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.mjs.map +1 -1
  327. package/dist/server/server/src/services/permission/permissions-manager/sanitize.js +47 -41
  328. package/dist/server/server/src/services/permission/permissions-manager/sanitize.js.map +1 -1
  329. package/dist/server/server/src/services/permission/permissions-manager/sanitize.mjs +44 -38
  330. package/dist/server/server/src/services/permission/permissions-manager/sanitize.mjs.map +1 -1
  331. package/dist/server/server/src/services/permission/permissions-manager/validate.js +30 -26
  332. package/dist/server/server/src/services/permission/permissions-manager/validate.js.map +1 -1
  333. package/dist/server/server/src/services/permission/permissions-manager/validate.mjs +28 -24
  334. package/dist/server/server/src/services/permission/permissions-manager/validate.mjs.map +1 -1
  335. package/dist/server/server/src/services/permission/queries.js +9 -9
  336. package/dist/server/server/src/services/permission/queries.js.map +1 -1
  337. package/dist/server/server/src/services/permission/queries.mjs +9 -9
  338. package/dist/server/server/src/services/permission/queries.mjs.map +1 -1
  339. package/dist/server/server/src/services/permission/rename-fields.js +118 -0
  340. package/dist/server/server/src/services/permission/rename-fields.js.map +1 -0
  341. package/dist/server/server/src/services/permission/rename-fields.mjs +116 -0
  342. package/dist/server/server/src/services/permission/rename-fields.mjs.map +1 -0
  343. package/dist/server/server/src/services/permission/sections-builder/index.js +2 -2
  344. package/dist/server/server/src/services/permission/sections-builder/index.js.map +1 -1
  345. package/dist/server/server/src/services/permission/sections-builder/index.mjs +2 -2
  346. package/dist/server/server/src/services/permission/sections-builder/index.mjs.map +1 -1
  347. package/dist/server/server/src/services/permission/sections-builder/section.js +1 -2
  348. package/dist/server/server/src/services/permission/sections-builder/section.js.map +1 -1
  349. package/dist/server/server/src/services/permission/sections-builder/section.mjs +1 -2
  350. package/dist/server/server/src/services/permission/sections-builder/section.mjs.map +1 -1
  351. package/dist/server/server/src/services/permission/sections-builder/utils.js +6 -6
  352. package/dist/server/server/src/services/permission/sections-builder/utils.js.map +1 -1
  353. package/dist/server/server/src/services/permission/sections-builder/utils.mjs +4 -4
  354. package/dist/server/server/src/services/permission/sections-builder/utils.mjs.map +1 -1
  355. package/dist/server/server/src/services/role.js +20 -19
  356. package/dist/server/server/src/services/role.js.map +1 -1
  357. package/dist/server/server/src/services/role.mjs +20 -19
  358. package/dist/server/server/src/services/role.mjs.map +1 -1
  359. package/dist/server/server/src/services/transfer/token.js +20 -16
  360. package/dist/server/server/src/services/transfer/token.js.map +1 -1
  361. package/dist/server/server/src/services/transfer/token.mjs +14 -10
  362. package/dist/server/server/src/services/transfer/token.mjs.map +1 -1
  363. package/dist/server/server/src/services/user.js +2 -3
  364. package/dist/server/server/src/services/user.js.map +1 -1
  365. package/dist/server/server/src/services/user.mjs +3 -4
  366. package/dist/server/server/src/services/user.mjs.map +1 -1
  367. package/dist/server/server/src/strategies/api-token-utils.js +2 -3
  368. package/dist/server/server/src/strategies/api-token-utils.js.map +1 -1
  369. package/dist/server/server/src/strategies/api-token-utils.mjs +2 -3
  370. package/dist/server/server/src/strategies/api-token-utils.mjs.map +1 -1
  371. package/dist/server/server/src/strategies/content-api-token.js +3 -3
  372. package/dist/server/server/src/strategies/content-api-token.js.map +1 -1
  373. package/dist/server/server/src/strategies/content-api-token.mjs +1 -1
  374. package/dist/server/server/src/strategies/content-api-token.mjs.map +1 -1
  375. package/dist/server/server/src/strategies/data-transfer.js +4 -4
  376. package/dist/server/server/src/strategies/data-transfer.js.map +1 -1
  377. package/dist/server/server/src/strategies/data-transfer.mjs +3 -3
  378. package/dist/server/server/src/strategies/data-transfer.mjs.map +1 -1
  379. package/dist/server/server/src/utils/debug-dump/redact.js +197 -0
  380. package/dist/server/server/src/utils/debug-dump/redact.js.map +1 -0
  381. package/dist/server/server/src/utils/debug-dump/redact.mjs +194 -0
  382. package/dist/server/server/src/utils/debug-dump/redact.mjs.map +1 -0
  383. package/dist/server/server/src/validation/common-validators.js +9 -10
  384. package/dist/server/server/src/validation/common-validators.js.map +1 -1
  385. package/dist/server/server/src/validation/common-validators.mjs +13 -14
  386. package/dist/server/server/src/validation/common-validators.mjs.map +1 -1
  387. package/dist/server/server/src/validation/user.js +1 -2
  388. package/dist/server/server/src/validation/user.js.map +1 -1
  389. package/dist/server/server/src/validation/user.mjs +1 -2
  390. package/dist/server/server/src/validation/user.mjs.map +1 -1
  391. package/dist/server/shared/utils/get-project-type.js +49 -0
  392. package/dist/server/shared/utils/get-project-type.js.map +1 -0
  393. package/dist/server/shared/utils/get-project-type.mjs +46 -0
  394. package/dist/server/shared/utils/get-project-type.mjs.map +1 -0
  395. package/dist/server/src/audit-logs/auth.d.ts +72 -0
  396. package/dist/server/src/audit-logs/auth.d.ts.map +1 -0
  397. package/dist/server/src/audit-logs/tokens.d.ts.map +1 -1
  398. package/dist/server/src/bootstrap.d.ts.map +1 -1
  399. package/dist/server/src/config/admin-actions.d.ts.map +1 -1
  400. package/dist/server/src/controllers/admin-token.d.ts.map +1 -1
  401. package/dist/server/src/controllers/admin.d.ts +3 -0
  402. package/dist/server/src/controllers/admin.d.ts.map +1 -1
  403. package/dist/server/src/controllers/api-token.d.ts.map +1 -1
  404. package/dist/server/src/controllers/authentication.d.ts.map +1 -1
  405. package/dist/server/src/controllers/formatters/conditions.d.ts +1 -1
  406. package/dist/server/src/controllers/formatters/conditions.d.ts.map +1 -1
  407. package/dist/server/src/controllers/homepage.d.ts +1 -1
  408. package/dist/server/src/controllers/index.d.ts +4 -1
  409. package/dist/server/src/controllers/index.d.ts.map +1 -1
  410. package/dist/server/src/controllers/transfer/index.d.ts.map +1 -1
  411. package/dist/server/src/controllers/transfer/token.d.ts.map +1 -1
  412. package/dist/server/src/domain/action/index.d.ts +1 -0
  413. package/dist/server/src/domain/action/index.d.ts.map +1 -1
  414. package/dist/server/src/domain/condition/index.d.ts +2 -2
  415. package/dist/server/src/domain/condition/index.d.ts.map +1 -1
  416. package/dist/server/src/domain/permission/index.d.ts.map +1 -1
  417. package/dist/server/src/index.d.ts +11 -3
  418. package/dist/server/src/index.d.ts.map +1 -1
  419. package/dist/server/src/middlewares/index.d.ts.map +1 -1
  420. package/dist/server/src/middlewares/rateLimit.d.ts.map +1 -1
  421. package/dist/server/src/register.d.ts.map +1 -1
  422. package/dist/server/src/routes/admin.d.ts.map +1 -1
  423. package/dist/server/src/services/action.d.ts.map +1 -1
  424. package/dist/server/src/services/api-token.d.ts.map +1 -1
  425. package/dist/server/src/services/auth.d.ts +6 -0
  426. package/dist/server/src/services/auth.d.ts.map +1 -1
  427. package/dist/server/src/services/condition.d.ts.map +1 -1
  428. package/dist/server/src/services/content-type.d.ts.map +1 -1
  429. package/dist/server/src/services/debug-dump.d.ts +9 -0
  430. package/dist/server/src/services/debug-dump.d.ts.map +1 -0
  431. package/dist/server/src/services/homepage.d.ts +1 -1
  432. package/dist/server/src/services/homepage.d.ts.map +1 -1
  433. package/dist/server/src/services/index.d.ts +7 -2
  434. package/dist/server/src/services/index.d.ts.map +1 -1
  435. package/dist/server/src/services/passport/local-strategy.d.ts.map +1 -1
  436. package/dist/server/src/services/passport.d.ts.map +1 -1
  437. package/dist/server/src/services/permission/engine.d.ts.map +1 -1
  438. package/dist/server/src/services/permission/permissions-manager/permission-fields.d.ts.map +1 -1
  439. package/dist/server/src/services/permission/permissions-manager/sanitize.d.ts.map +1 -1
  440. package/dist/server/src/services/permission/permissions-manager/validate.d.ts.map +1 -1
  441. package/dist/server/src/services/permission/queries.d.ts.map +1 -1
  442. package/dist/server/src/services/permission/rename-fields.d.ts +21 -0
  443. package/dist/server/src/services/permission/rename-fields.d.ts.map +1 -0
  444. package/dist/server/src/services/permission/sections-builder/section.d.ts.map +1 -1
  445. package/dist/server/src/services/permission/sections-builder/utils.d.ts +1 -1
  446. package/dist/server/src/services/permission/sections-builder/utils.d.ts.map +1 -1
  447. package/dist/server/src/services/role.d.ts +1 -1
  448. package/dist/server/src/services/role.d.ts.map +1 -1
  449. package/dist/server/src/services/transfer/token.d.ts.map +1 -1
  450. package/dist/server/src/strategies/content-api-token.d.ts.map +1 -1
  451. package/dist/server/src/utils/debug-dump/redact.d.ts +8 -0
  452. package/dist/server/src/utils/debug-dump/redact.d.ts.map +1 -0
  453. package/dist/server/src/validation/user.d.ts.map +1 -1
  454. package/dist/shared/contracts/admin.d.ts +106 -0
  455. package/dist/shared/contracts/admin.d.ts.map +1 -1
  456. package/dist/shared/utils/__tests__/get-project-type.test.d.ts +1 -0
  457. package/dist/shared/utils/__tests__/get-project-type.test.d.ts.map +1 -0
  458. package/dist/shared/utils/get-project-type.d.ts +37 -0
  459. package/dist/shared/utils/get-project-type.d.ts.map +1 -0
  460. package/package.json +10 -10
  461. package/dist/admin/admin/src/utils/getProjectType.js +0 -22
  462. package/dist/admin/admin/src/utils/getProjectType.js.map +0 -1
  463. package/dist/admin/admin/src/utils/getProjectType.mjs +0 -20
  464. package/dist/admin/admin/src/utils/getProjectType.mjs.map +0 -1
  465. package/dist/admin/src/utils/getProjectType.d.ts +0 -16
@@ -1 +1 @@
1
- {"version":3,"file":"data-transfer.js","sources":["../../../../../server/src/strategies/data-transfer.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport { differenceInHours, parseISO } from 'date-fns';\nimport { errors } from '@strapi/utils';\nimport { castArray, isNil } from 'lodash/fp';\n\nimport { getService } from '../utils';\n\nconst { UnauthorizedError, ForbiddenError } = errors;\n\nconst extractToken = (ctx: Context) => {\n if (ctx.request && ctx.request.header && ctx.request.header.authorization) {\n const parts = ctx.request.header.authorization.split(/\\s+/);\n\n if (parts[0].toLowerCase() !== 'bearer' || parts.length !== 2) {\n return null;\n }\n\n return parts[1];\n }\n\n return null;\n};\n\n/**\n * Authenticate the validity of the token\n *\n * @type {import('.').AuthenticateFunction}\n */\nexport const authenticate = async (ctx: Context) => {\n const { token: tokenService } = getService('transfer');\n const token = extractToken(ctx);\n\n if (!token) {\n return { authenticated: false };\n }\n\n const transferToken = await tokenService.getBy({ accessKey: tokenService.hash(token) });\n\n // Check if the token exists\n if (!transferToken) {\n return { authenticated: false };\n }\n\n // Check if the token has expired\n const currentDate = new Date();\n\n if (!isNil(transferToken.expiresAt)) {\n const expirationDate = new Date(transferToken.expiresAt);\n\n if (expirationDate < currentDate) {\n return { authenticated: false, error: new UnauthorizedError('Token expired') };\n }\n }\n\n // Update token metadata if the token has not been used in the last hour\n // @ts-expect-error - FIXME: verify lastUsedAt is defined\n const hoursSinceLastUsed = differenceInHours(currentDate, parseISO(transferToken.lastUsedAt));\n if (hoursSinceLastUsed >= 1) {\n await strapi.db.query('admin::api-token').update({\n where: { id: transferToken.id },\n data: { lastUsedAt: currentDate },\n });\n }\n\n // Generate an ability based on the token permissions\n const ability = await getService('transfer').permission.engine.generateAbility(\n transferToken.permissions.map((action: any) => ({ action }))\n );\n\n return { authenticated: true, ability, credentials: transferToken };\n};\n\n/**\n * Verify the token has the required abilities for the requested scope\n *\n * @type {import('.').VerifyFunction}\n */\nexport const verify = async (auth: any, config: any = {}) => {\n const { credentials: transferToken, ability } = auth;\n\n if (!transferToken) {\n throw new UnauthorizedError('Token not found');\n }\n\n const currentDate = new Date();\n\n if (!isNil(transferToken.expiresAt)) {\n const expirationDate = new Date(transferToken.expiresAt);\n // token has expired\n if (expirationDate < currentDate) {\n throw new UnauthorizedError('Token expired');\n }\n }\n\n if (!ability) {\n throw new ForbiddenError();\n }\n\n const scopes = castArray(config.scope ?? []);\n\n const isAllowed = scopes.every((scope) => ability.can(scope));\n\n if (!isAllowed) {\n throw new ForbiddenError();\n }\n};\n\nexport const name = 'data-transfer';\n\n/** @type {import('.').AuthStrategy} */\nexport default {\n name,\n authenticate,\n verify,\n};\n"],"names":["UnauthorizedError","ForbiddenError","errors","extractToken","ctx","request","header","authorization","parts","split","toLowerCase","length","authenticate","token","tokenService","getService","authenticated","transferToken","getBy","accessKey","hash","currentDate","Date","isNil","expiresAt","expirationDate","error","hoursSinceLastUsed","differenceInHours","parseISO","lastUsedAt","strapi","db","query","update","where","id","data","ability","permission","engine","generateAbility","permissions","map","action","credentials","verify","auth","config","scopes","castArray","scope","isAllowed","every","can","name"],"mappings":";;;;;;;;;AAOA,MAAM,EAAEA,iBAAiB,EAAEC,cAAc,EAAE,GAAGC,YAAAA;AAE9C,MAAMC,eAAe,CAACC,GAAAA,GAAAA;AACpB,IAAA,IAAIA,GAAAA,CAAIC,OAAO,IAAID,GAAAA,CAAIC,OAAO,CAACC,MAAM,IAAIF,GAAAA,CAAIC,OAAO,CAACC,MAAM,CAACC,aAAa,EAAE;QACzE,MAAMC,KAAAA,GAAQJ,IAAIC,OAAO,CAACC,MAAM,CAACC,aAAa,CAACE,KAAK,CAAC,KAAA,CAAA;QAErD,IAAID,KAAK,CAAC,CAAA,CAAE,CAACE,WAAW,OAAO,QAAA,IAAYF,KAAAA,CAAMG,MAAM,KAAK,CAAA,EAAG;YAC7D,OAAO,IAAA;AACT,QAAA;QAEA,OAAOH,KAAK,CAAC,CAAA,CAAE;AACjB,IAAA;IAEA,OAAO,IAAA;AACT,CAAA;AAEA;;;;IAKO,MAAMI,YAAAA,GAAe,OAAOR,GAAAA,GAAAA;AACjC,IAAA,MAAM,EAAES,KAAAA,EAAOC,YAAY,EAAE,GAAGC,gBAAAA,CAAW,UAAA,CAAA;AAC3C,IAAA,MAAMF,QAAQV,YAAAA,CAAaC,GAAAA,CAAAA;AAE3B,IAAA,IAAI,CAACS,KAAAA,EAAO;QACV,OAAO;YAAEG,aAAAA,EAAe;AAAM,SAAA;AAChC,IAAA;AAEA,IAAA,MAAMC,aAAAA,GAAgB,MAAMH,YAAAA,CAAaI,KAAK,CAAC;QAAEC,SAAAA,EAAWL,YAAAA,CAAaM,IAAI,CAACP,KAAAA;AAAO,KAAA,CAAA;;AAGrF,IAAA,IAAI,CAACI,aAAAA,EAAe;QAClB,OAAO;YAAED,aAAAA,EAAe;AAAM,SAAA;AAChC,IAAA;;AAGA,IAAA,MAAMK,cAAc,IAAIC,IAAAA,EAAAA;AAExB,IAAA,IAAI,CAACC,QAAAA,CAAMN,aAAAA,CAAcO,SAAS,CAAA,EAAG;AACnC,QAAA,MAAMC,cAAAA,GAAiB,IAAIH,IAAAA,CAAKL,aAAAA,CAAcO,SAAS,CAAA;AAEvD,QAAA,IAAIC,iBAAiBJ,WAAAA,EAAa;YAChC,OAAO;gBAAEL,aAAAA,EAAe,KAAA;AAAOU,gBAAAA,KAAAA,EAAO,IAAI1B,iBAAAA,CAAkB,eAAA;AAAiB,aAAA;AAC/E,QAAA;AACF,IAAA;;;AAIA,IAAA,MAAM2B,kBAAAA,GAAqBC,yBAAAA,CAAkBP,WAAAA,EAAaQ,gBAAAA,CAASZ,cAAca,UAAU,CAAA,CAAA;AAC3F,IAAA,IAAIH,sBAAsB,CAAA,EAAG;AAC3B,QAAA,MAAMI,OAAOC,EAAE,CAACC,KAAK,CAAC,kBAAA,CAAA,CAAoBC,MAAM,CAAC;YAC/CC,KAAAA,EAAO;AAAEC,gBAAAA,EAAAA,EAAInB,cAAcmB;AAAG,aAAA;YAC9BC,IAAAA,EAAM;gBAAEP,UAAAA,EAAYT;AAAY;AAClC,SAAA,CAAA;AACF,IAAA;;AAGA,IAAA,MAAMiB,UAAU,MAAMvB,gBAAAA,CAAW,UAAA,CAAA,CAAYwB,UAAU,CAACC,MAAM,CAACC,eAAe,CAC5ExB,cAAcyB,WAAW,CAACC,GAAG,CAAC,CAACC,UAAiB;AAAEA,YAAAA;SAAO,CAAA,CAAA,CAAA;IAG3D,OAAO;QAAE5B,aAAAA,EAAe,IAAA;AAAMsB,QAAAA,OAAAA;QAASO,WAAAA,EAAa5B;AAAc,KAAA;AACpE;AAEA;;;;AAIC,IACM,MAAM6B,MAAAA,GAAS,OAAOC,IAAAA,EAAWC,MAAAA,GAAc,EAAE,GAAA;AACtD,IAAA,MAAM,EAAEH,WAAAA,EAAa5B,aAAa,EAAEqB,OAAO,EAAE,GAAGS,IAAAA;AAEhD,IAAA,IAAI,CAAC9B,aAAAA,EAAe;AAClB,QAAA,MAAM,IAAIjB,iBAAAA,CAAkB,iBAAA,CAAA;AAC9B,IAAA;AAEA,IAAA,MAAMqB,cAAc,IAAIC,IAAAA,EAAAA;AAExB,IAAA,IAAI,CAACC,QAAAA,CAAMN,aAAAA,CAAcO,SAAS,CAAA,EAAG;AACnC,QAAA,MAAMC,cAAAA,GAAiB,IAAIH,IAAAA,CAAKL,aAAAA,CAAcO,SAAS,CAAA;;AAEvD,QAAA,IAAIC,iBAAiBJ,WAAAA,EAAa;AAChC,YAAA,MAAM,IAAIrB,iBAAAA,CAAkB,eAAA,CAAA;AAC9B,QAAA;AACF,IAAA;AAEA,IAAA,IAAI,CAACsC,OAAAA,EAAS;AACZ,QAAA,MAAM,IAAIrC,cAAAA,EAAAA;AACZ,IAAA;AAEA,IAAA,MAAMgD,MAAAA,GAASC,YAAAA,CAAUF,MAAAA,CAAOG,KAAK,IAAI,EAAE,CAAA;IAE3C,MAAMC,SAAAA,GAAYH,OAAOI,KAAK,CAAC,CAACF,KAAAA,GAAUb,OAAAA,CAAQgB,GAAG,CAACH,KAAAA,CAAAA,CAAAA;AAEtD,IAAA,IAAI,CAACC,SAAAA,EAAW;AACd,QAAA,MAAM,IAAInD,cAAAA,EAAAA;AACZ,IAAA;AACF;AAEO,MAAMsD,OAAO;AAEpB,wCACA,+BAAe;AACbA,IAAAA,IAAAA;AACA3C,IAAAA,YAAAA;AACAkC,IAAAA;AACF,CAAA;;;;;;;"}
1
+ {"version":3,"file":"data-transfer.js","sources":["../../../../../server/src/strategies/data-transfer.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport { differenceInHours, parseISO } from 'date-fns';\nimport { errors } from '@strapi/utils';\nimport { castArray } from 'lodash';\n\nimport { getService } from '../utils';\n\nconst { UnauthorizedError, ForbiddenError } = errors;\n\nconst extractToken = (ctx: Context) => {\n if (ctx.request && ctx.request.header && ctx.request.header.authorization) {\n const parts = ctx.request.header.authorization.split(/\\s+/);\n\n if (parts[0].toLowerCase() !== 'bearer' || parts.length !== 2) {\n return null;\n }\n\n return parts[1];\n }\n\n return null;\n};\n\n/**\n * Authenticate the validity of the token\n *\n * @type {import('.').AuthenticateFunction}\n */\nexport const authenticate = async (ctx: Context) => {\n const { token: tokenService } = getService('transfer');\n const token = extractToken(ctx);\n\n if (!token) {\n return { authenticated: false };\n }\n\n const transferToken = await tokenService.getBy({ accessKey: tokenService.hash(token) });\n\n // Check if the token exists\n if (!transferToken) {\n return { authenticated: false };\n }\n\n // Check if the token has expired\n const currentDate = new Date();\n\n if (transferToken.expiresAt != null) {\n const expirationDate = new Date(transferToken.expiresAt);\n\n if (expirationDate < currentDate) {\n return { authenticated: false, error: new UnauthorizedError('Token expired') };\n }\n }\n\n // Update token metadata if the token has not been used in the last hour\n // @ts-expect-error - FIXME: verify lastUsedAt is defined\n const hoursSinceLastUsed = differenceInHours(currentDate, parseISO(transferToken.lastUsedAt));\n if (hoursSinceLastUsed >= 1) {\n await strapi.db.query('admin::api-token').update({\n where: { id: transferToken.id },\n data: { lastUsedAt: currentDate },\n });\n }\n\n // Generate an ability based on the token permissions\n const ability = await getService('transfer').permission.engine.generateAbility(\n transferToken.permissions.map((action: any) => ({ action }))\n );\n\n return { authenticated: true, ability, credentials: transferToken };\n};\n\n/**\n * Verify the token has the required abilities for the requested scope\n *\n * @type {import('.').VerifyFunction}\n */\nexport const verify = async (auth: any, config: any = {}) => {\n const { credentials: transferToken, ability } = auth;\n\n if (!transferToken) {\n throw new UnauthorizedError('Token not found');\n }\n\n const currentDate = new Date();\n\n if (transferToken.expiresAt != null) {\n const expirationDate = new Date(transferToken.expiresAt);\n // token has expired\n if (expirationDate < currentDate) {\n throw new UnauthorizedError('Token expired');\n }\n }\n\n if (!ability) {\n throw new ForbiddenError();\n }\n\n const scopes = castArray(config.scope ?? []);\n\n const isAllowed = scopes.every((scope) => ability.can(scope));\n\n if (!isAllowed) {\n throw new ForbiddenError();\n }\n};\n\nexport const name = 'data-transfer';\n\n/** @type {import('.').AuthStrategy} */\nexport default {\n name,\n authenticate,\n verify,\n};\n"],"names":["UnauthorizedError","ForbiddenError","errors","extractToken","ctx","request","header","authorization","parts","split","toLowerCase","length","authenticate","token","tokenService","getService","authenticated","transferToken","getBy","accessKey","hash","currentDate","Date","expiresAt","expirationDate","error","hoursSinceLastUsed","differenceInHours","parseISO","lastUsedAt","strapi","db","query","update","where","id","data","ability","permission","engine","generateAbility","permissions","map","action","credentials","verify","auth","config","scopes","castArray","scope","isAllowed","every","can","name"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { differenceInHours, parseISO } from 'date-fns';
2
2
  import { errors } from '@strapi/utils';
3
- import { isNil, castArray } from 'lodash/fp';
3
+ import { castArray } from 'lodash';
4
4
  import { getService } from '../utils/index.mjs';
5
5
 
6
6
  const { UnauthorizedError, ForbiddenError } = errors;
@@ -37,7 +37,7 @@ const extractToken = (ctx)=>{
37
37
  }
38
38
  // Check if the token has expired
39
39
  const currentDate = new Date();
40
- if (!isNil(transferToken.expiresAt)) {
40
+ if (transferToken.expiresAt != null) {
41
41
  const expirationDate = new Date(transferToken.expiresAt);
42
42
  if (expirationDate < currentDate) {
43
43
  return {
@@ -79,7 +79,7 @@ const extractToken = (ctx)=>{
79
79
  throw new UnauthorizedError('Token not found');
80
80
  }
81
81
  const currentDate = new Date();
82
- if (!isNil(transferToken.expiresAt)) {
82
+ if (transferToken.expiresAt != null) {
83
83
  const expirationDate = new Date(transferToken.expiresAt);
84
84
  // token has expired
85
85
  if (expirationDate < currentDate) {
@@ -1 +1 @@
1
- {"version":3,"file":"data-transfer.mjs","sources":["../../../../../server/src/strategies/data-transfer.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport { differenceInHours, parseISO } from 'date-fns';\nimport { errors } from '@strapi/utils';\nimport { castArray, isNil } from 'lodash/fp';\n\nimport { getService } from '../utils';\n\nconst { UnauthorizedError, ForbiddenError } = errors;\n\nconst extractToken = (ctx: Context) => {\n if (ctx.request && ctx.request.header && ctx.request.header.authorization) {\n const parts = ctx.request.header.authorization.split(/\\s+/);\n\n if (parts[0].toLowerCase() !== 'bearer' || parts.length !== 2) {\n return null;\n }\n\n return parts[1];\n }\n\n return null;\n};\n\n/**\n * Authenticate the validity of the token\n *\n * @type {import('.').AuthenticateFunction}\n */\nexport const authenticate = async (ctx: Context) => {\n const { token: tokenService } = getService('transfer');\n const token = extractToken(ctx);\n\n if (!token) {\n return { authenticated: false };\n }\n\n const transferToken = await tokenService.getBy({ accessKey: tokenService.hash(token) });\n\n // Check if the token exists\n if (!transferToken) {\n return { authenticated: false };\n }\n\n // Check if the token has expired\n const currentDate = new Date();\n\n if (!isNil(transferToken.expiresAt)) {\n const expirationDate = new Date(transferToken.expiresAt);\n\n if (expirationDate < currentDate) {\n return { authenticated: false, error: new UnauthorizedError('Token expired') };\n }\n }\n\n // Update token metadata if the token has not been used in the last hour\n // @ts-expect-error - FIXME: verify lastUsedAt is defined\n const hoursSinceLastUsed = differenceInHours(currentDate, parseISO(transferToken.lastUsedAt));\n if (hoursSinceLastUsed >= 1) {\n await strapi.db.query('admin::api-token').update({\n where: { id: transferToken.id },\n data: { lastUsedAt: currentDate },\n });\n }\n\n // Generate an ability based on the token permissions\n const ability = await getService('transfer').permission.engine.generateAbility(\n transferToken.permissions.map((action: any) => ({ action }))\n );\n\n return { authenticated: true, ability, credentials: transferToken };\n};\n\n/**\n * Verify the token has the required abilities for the requested scope\n *\n * @type {import('.').VerifyFunction}\n */\nexport const verify = async (auth: any, config: any = {}) => {\n const { credentials: transferToken, ability } = auth;\n\n if (!transferToken) {\n throw new UnauthorizedError('Token not found');\n }\n\n const currentDate = new Date();\n\n if (!isNil(transferToken.expiresAt)) {\n const expirationDate = new Date(transferToken.expiresAt);\n // token has expired\n if (expirationDate < currentDate) {\n throw new UnauthorizedError('Token expired');\n }\n }\n\n if (!ability) {\n throw new ForbiddenError();\n }\n\n const scopes = castArray(config.scope ?? []);\n\n const isAllowed = scopes.every((scope) => ability.can(scope));\n\n if (!isAllowed) {\n throw new ForbiddenError();\n }\n};\n\nexport const name = 'data-transfer';\n\n/** @type {import('.').AuthStrategy} */\nexport default {\n name,\n authenticate,\n verify,\n};\n"],"names":["UnauthorizedError","ForbiddenError","errors","extractToken","ctx","request","header","authorization","parts","split","toLowerCase","length","authenticate","token","tokenService","getService","authenticated","transferToken","getBy","accessKey","hash","currentDate","Date","isNil","expiresAt","expirationDate","error","hoursSinceLastUsed","differenceInHours","parseISO","lastUsedAt","strapi","db","query","update","where","id","data","ability","permission","engine","generateAbility","permissions","map","action","credentials","verify","auth","config","scopes","castArray","scope","isAllowed","every","can","name"],"mappings":"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"}
1
+ {"version":3,"file":"data-transfer.mjs","sources":["../../../../../server/src/strategies/data-transfer.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport { differenceInHours, parseISO } from 'date-fns';\nimport { errors } from '@strapi/utils';\nimport { castArray } from 'lodash';\n\nimport { getService } from '../utils';\n\nconst { UnauthorizedError, ForbiddenError } = errors;\n\nconst extractToken = (ctx: Context) => {\n if (ctx.request && ctx.request.header && ctx.request.header.authorization) {\n const parts = ctx.request.header.authorization.split(/\\s+/);\n\n if (parts[0].toLowerCase() !== 'bearer' || parts.length !== 2) {\n return null;\n }\n\n return parts[1];\n }\n\n return null;\n};\n\n/**\n * Authenticate the validity of the token\n *\n * @type {import('.').AuthenticateFunction}\n */\nexport const authenticate = async (ctx: Context) => {\n const { token: tokenService } = getService('transfer');\n const token = extractToken(ctx);\n\n if (!token) {\n return { authenticated: false };\n }\n\n const transferToken = await tokenService.getBy({ accessKey: tokenService.hash(token) });\n\n // Check if the token exists\n if (!transferToken) {\n return { authenticated: false };\n }\n\n // Check if the token has expired\n const currentDate = new Date();\n\n if (transferToken.expiresAt != null) {\n const expirationDate = new Date(transferToken.expiresAt);\n\n if (expirationDate < currentDate) {\n return { authenticated: false, error: new UnauthorizedError('Token expired') };\n }\n }\n\n // Update token metadata if the token has not been used in the last hour\n // @ts-expect-error - FIXME: verify lastUsedAt is defined\n const hoursSinceLastUsed = differenceInHours(currentDate, parseISO(transferToken.lastUsedAt));\n if (hoursSinceLastUsed >= 1) {\n await strapi.db.query('admin::api-token').update({\n where: { id: transferToken.id },\n data: { lastUsedAt: currentDate },\n });\n }\n\n // Generate an ability based on the token permissions\n const ability = await getService('transfer').permission.engine.generateAbility(\n transferToken.permissions.map((action: any) => ({ action }))\n );\n\n return { authenticated: true, ability, credentials: transferToken };\n};\n\n/**\n * Verify the token has the required abilities for the requested scope\n *\n * @type {import('.').VerifyFunction}\n */\nexport const verify = async (auth: any, config: any = {}) => {\n const { credentials: transferToken, ability } = auth;\n\n if (!transferToken) {\n throw new UnauthorizedError('Token not found');\n }\n\n const currentDate = new Date();\n\n if (transferToken.expiresAt != null) {\n const expirationDate = new Date(transferToken.expiresAt);\n // token has expired\n if (expirationDate < currentDate) {\n throw new UnauthorizedError('Token expired');\n }\n }\n\n if (!ability) {\n throw new ForbiddenError();\n }\n\n const scopes = castArray(config.scope ?? []);\n\n const isAllowed = scopes.every((scope) => ability.can(scope));\n\n if (!isAllowed) {\n throw new ForbiddenError();\n }\n};\n\nexport const name = 'data-transfer';\n\n/** @type {import('.').AuthStrategy} */\nexport default {\n name,\n authenticate,\n verify,\n};\n"],"names":["UnauthorizedError","ForbiddenError","errors","extractToken","ctx","request","header","authorization","parts","split","toLowerCase","length","authenticate","token","tokenService","getService","authenticated","transferToken","getBy","accessKey","hash","currentDate","Date","expiresAt","expirationDate","error","hoursSinceLastUsed","differenceInHours","parseISO","lastUsedAt","strapi","db","query","update","where","id","data","ability","permission","engine","generateAbility","permissions","map","action","credentials","verify","auth","config","scopes","castArray","scope","isAllowed","every","can","name"],"mappings":"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"}
@@ -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":"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"}