@strapi/admin 5.55.1 → 5.56.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 (120) hide show
  1. package/dist/admin/admin/src/components/UpsellBanner.js +9 -16
  2. package/dist/admin/admin/src/components/UpsellBanner.js.map +1 -1
  3. package/dist/admin/admin/src/components/UpsellBanner.mjs +11 -18
  4. package/dist/admin/admin/src/components/UpsellBanner.mjs.map +1 -1
  5. package/dist/admin/admin/src/render.js +4 -69
  6. package/dist/admin/admin/src/render.js.map +1 -1
  7. package/dist/admin/admin/src/render.mjs +4 -69
  8. package/dist/admin/admin/src/render.mjs.map +1 -1
  9. package/dist/admin/admin/src/translations/en.json.js +10 -0
  10. package/dist/admin/admin/src/translations/en.json.js.map +1 -1
  11. package/dist/admin/admin/src/translations/en.json.mjs +10 -0
  12. package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
  13. package/dist/admin/admin/src/utils/browserStrapi.js +93 -0
  14. package/dist/admin/admin/src/utils/browserStrapi.js.map +1 -0
  15. package/dist/admin/admin/src/utils/browserStrapi.mjs +91 -0
  16. package/dist/admin/admin/src/utils/browserStrapi.mjs.map +1 -0
  17. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.js +2 -1
  18. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.js.map +1 -1
  19. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.mjs +2 -1
  20. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.mjs.map +1 -1
  21. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js +11 -1
  22. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js.map +1 -1
  23. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs +11 -1
  24. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs.map +1 -1
  25. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.js +3 -1
  26. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.js.map +1 -1
  27. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.mjs +3 -1
  28. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.mjs.map +1 -1
  29. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.js +64 -0
  30. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.js.map +1 -0
  31. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.mjs +60 -0
  32. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.mjs.map +1 -0
  33. package/dist/admin/ee/admin/src/services/auditLogs.js +2 -1
  34. package/dist/admin/ee/admin/src/services/auditLogs.js.map +1 -1
  35. package/dist/admin/ee/admin/src/services/auditLogs.mjs +2 -1
  36. package/dist/admin/ee/admin/src/services/auditLogs.mjs.map +1 -1
  37. package/dist/admin/src/components/SubNav.d.ts +2 -2
  38. package/dist/admin/src/utils/browserStrapi.d.ts +11 -0
  39. package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.d.ts +10 -0
  40. package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.d.ts +14 -0
  41. package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts +10 -1
  42. package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts.map +1 -1
  43. package/dist/ee/server/src/controllers/admin.d.ts +2 -28
  44. package/dist/ee/server/src/controllers/admin.d.ts.map +1 -1
  45. package/dist/ee/server/src/controllers/index.d.ts +1 -28
  46. package/dist/ee/server/src/controllers/index.d.ts.map +1 -1
  47. package/dist/ee/server/src/index.d.ts +2 -29
  48. package/dist/ee/server/src/index.d.ts.map +1 -1
  49. package/dist/ee/server/src/services/auth.d.ts +1 -1
  50. package/dist/ee/server/src/services/auth.d.ts.map +1 -1
  51. package/dist/ee/server/src/services/index.d.ts +1 -1
  52. package/dist/ee/server/src/services/user.d.ts.map +1 -1
  53. package/dist/server/ee/server/src/audit-logs/services/lifecycles.js +37 -21
  54. package/dist/server/ee/server/src/audit-logs/services/lifecycles.js.map +1 -1
  55. package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs +37 -21
  56. package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs.map +1 -1
  57. package/dist/server/ee/server/src/controllers/admin.js +5 -3
  58. package/dist/server/ee/server/src/controllers/admin.js.map +1 -1
  59. package/dist/server/ee/server/src/controllers/admin.mjs +5 -3
  60. package/dist/server/ee/server/src/controllers/admin.mjs.map +1 -1
  61. package/dist/server/ee/server/src/index.js +4 -0
  62. package/dist/server/ee/server/src/index.js.map +1 -1
  63. package/dist/server/ee/server/src/index.mjs +4 -0
  64. package/dist/server/ee/server/src/index.mjs.map +1 -1
  65. package/dist/server/ee/server/src/services/auth.js +1 -6
  66. package/dist/server/ee/server/src/services/auth.js.map +1 -1
  67. package/dist/server/ee/server/src/services/auth.mjs +2 -7
  68. package/dist/server/ee/server/src/services/auth.mjs.map +1 -1
  69. package/dist/server/ee/server/src/services/user.js +36 -4
  70. package/dist/server/ee/server/src/services/user.js.map +1 -1
  71. package/dist/server/ee/server/src/services/user.mjs +36 -4
  72. package/dist/server/ee/server/src/services/user.mjs.map +1 -1
  73. package/dist/server/server/src/audit-logs/admin-users.js +169 -0
  74. package/dist/server/server/src/audit-logs/admin-users.js.map +1 -0
  75. package/dist/server/server/src/audit-logs/admin-users.mjs +157 -0
  76. package/dist/server/server/src/audit-logs/admin-users.mjs.map +1 -0
  77. package/dist/server/server/src/audit-logs/webhooks.js +106 -0
  78. package/dist/server/server/src/audit-logs/webhooks.js.map +1 -0
  79. package/dist/server/server/src/audit-logs/webhooks.mjs +100 -0
  80. package/dist/server/server/src/audit-logs/webhooks.mjs.map +1 -0
  81. package/dist/server/server/src/controllers/admin.js +1 -0
  82. package/dist/server/server/src/controllers/admin.js.map +1 -1
  83. package/dist/server/server/src/controllers/admin.mjs +1 -0
  84. package/dist/server/server/src/controllers/admin.mjs.map +1 -1
  85. package/dist/server/server/src/controllers/authentication.js +8 -1
  86. package/dist/server/server/src/controllers/authentication.js.map +1 -1
  87. package/dist/server/server/src/controllers/authentication.mjs +8 -1
  88. package/dist/server/server/src/controllers/authentication.mjs.map +1 -1
  89. package/dist/server/server/src/controllers/webhooks.js +26 -0
  90. package/dist/server/server/src/controllers/webhooks.js.map +1 -1
  91. package/dist/server/server/src/controllers/webhooks.mjs +27 -1
  92. package/dist/server/server/src/controllers/webhooks.mjs.map +1 -1
  93. package/dist/server/server/src/services/auth.js +27 -6
  94. package/dist/server/server/src/services/auth.js.map +1 -1
  95. package/dist/server/server/src/services/auth.mjs +28 -8
  96. package/dist/server/server/src/services/auth.mjs.map +1 -1
  97. package/dist/server/server/src/services/user.js +48 -9
  98. package/dist/server/server/src/services/user.js.map +1 -1
  99. package/dist/server/server/src/services/user.mjs +49 -10
  100. package/dist/server/server/src/services/user.mjs.map +1 -1
  101. package/dist/server/src/audit-logs/admin-users.d.ts +119 -0
  102. package/dist/server/src/audit-logs/admin-users.d.ts.map +1 -0
  103. package/dist/server/src/audit-logs/webhooks.d.ts +59 -0
  104. package/dist/server/src/audit-logs/webhooks.d.ts.map +1 -0
  105. package/dist/server/src/controllers/admin.d.ts +2 -11
  106. package/dist/server/src/controllers/admin.d.ts.map +1 -1
  107. package/dist/server/src/controllers/authentication.d.ts.map +1 -1
  108. package/dist/server/src/controllers/index.d.ts +1 -10
  109. package/dist/server/src/controllers/index.d.ts.map +1 -1
  110. package/dist/server/src/controllers/webhooks.d.ts.map +1 -1
  111. package/dist/server/src/domain/user.d.ts +2 -2
  112. package/dist/server/src/index.d.ts +1 -10
  113. package/dist/server/src/index.d.ts.map +1 -1
  114. package/dist/server/src/services/auth.d.ts +6 -1
  115. package/dist/server/src/services/auth.d.ts.map +1 -1
  116. package/dist/server/src/services/index.d.ts.map +1 -1
  117. package/dist/server/src/services/user.d.ts.map +1 -1
  118. package/dist/shared/contracts/admin.d.ts +36 -2
  119. package/dist/shared/contracts/admin.d.ts.map +1 -1
  120. package/package.json +11 -11
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legacyActions.mjs","sources":["../../../../../../../../../../ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.ts"],"sourcesContent":["/**\n * Admin-account rows stored before the `admin-user.*` events kept their old action keys\n * and stay until retention removes them. The Action filter offers the new key only and\n * queries both, so one option covers the whole history.\n *\n * Remove together with the deprecated `user.*` event hub events.\n */\nexport const LEGACY_ACTIONS: Record<string, string> = {\n 'admin-user.create': 'user.create',\n 'admin-user.update': 'user.update',\n 'admin-user.delete': 'user.delete',\n};\n\nconst LEGACY_KEYS = new Set(Object.values(LEGACY_ACTIONS));\n\nexport const isLegacyAction = (action: string) => LEGACY_KEYS.has(action);\n\ntype Condition = Record<string, unknown>;\n\nconst expandActionCondition = (condition: Condition): Condition => {\n const { $eq, $ne, ...rest } = condition;\n\n if (typeof $eq === 'string' && LEGACY_ACTIONS[$eq]) {\n return { ...rest, $in: [$eq, LEGACY_ACTIONS[$eq]] };\n }\n\n if (typeof $ne === 'string' && LEGACY_ACTIONS[$ne]) {\n return { ...rest, $notIn: [$ne, LEGACY_ACTIONS[$ne]] };\n }\n\n return condition;\n};\n\n/**\n * Rewrites `action` equality conditions on a new key into `$in` / `$notIn` over the new\n * and the legacy key. Walks `$and`, `$or` and `$not`. Anything else is returned as is.\n */\nexport const expandLegacyActionFilters = <T>(filters: T): T => {\n if (Array.isArray(filters)) {\n return filters.map(expandLegacyActionFilters) as T;\n }\n\n if (!filters || typeof filters !== 'object') {\n return filters;\n }\n\n const expanded: Condition = {};\n\n for (const [key, value] of Object.entries(filters as Condition)) {\n if (key === 'action' && value && typeof value === 'object' && !Array.isArray(value)) {\n expanded[key] = expandActionCondition(value as Condition);\n } else if (key === '$and' || key === '$or' || key === '$not') {\n expanded[key] = expandLegacyActionFilters(value);\n } else {\n expanded[key] = value;\n }\n }\n\n return expanded as T;\n};\n"],"names":["LEGACY_ACTIONS","LEGACY_KEYS","Set","Object","values","isLegacyAction","action","has","expandActionCondition","condition","$eq","$ne","rest","$in","$notIn","expandLegacyActionFilters","filters","Array","isArray","map","expanded","key","value","entries"],"mappings":"AAAA;;;;;;UAOaA,cAAAA,GAAyC;IACpD,mBAAA,EAAqB,aAAA;IACrB,mBAAA,EAAqB,aAAA;IACrB,mBAAA,EAAqB;AACvB;AAEA,MAAMC,WAAAA,GAAc,IAAIC,GAAAA,CAAIC,MAAAA,CAAOC,MAAM,CAACJ,cAAAA,CAAAA,CAAAA;MAE7BK,cAAAA,GAAiB,CAACC,SAAmBL,WAAAA,CAAYM,GAAG,CAACD,MAAAA;AAIlE,MAAME,wBAAwB,CAACC,SAAAA,GAAAA;AAC7B,IAAA,MAAM,EAAEC,GAAG,EAAEC,GAAG,EAAE,GAAGC,MAAM,GAAGH,SAAAA;AAE9B,IAAA,IAAI,OAAOC,GAAAA,KAAQ,QAAA,IAAYV,cAAc,CAACU,IAAI,EAAE;QAClD,OAAO;AAAE,YAAA,GAAGE,IAAI;YAAEC,GAAAA,EAAK;AAACH,gBAAAA,GAAAA;AAAKV,gBAAAA,cAAc,CAACU,GAAAA;AAAK;AAAC,SAAA;AACpD,IAAA;AAEA,IAAA,IAAI,OAAOC,GAAAA,KAAQ,QAAA,IAAYX,cAAc,CAACW,IAAI,EAAE;QAClD,OAAO;AAAE,YAAA,GAAGC,IAAI;YAAEE,MAAAA,EAAQ;AAACH,gBAAAA,GAAAA;AAAKX,gBAAAA,cAAc,CAACW,GAAAA;AAAK;AAAC,SAAA;AACvD,IAAA;IAEA,OAAOF,SAAAA;AACT,CAAA;AAEA;;;IAIO,MAAMM,yBAAAA,GAA4B,CAAIC,OAAAA,GAAAA;IAC3C,IAAIC,KAAAA,CAAMC,OAAO,CAACF,OAAAA,CAAAA,EAAU;QAC1B,OAAOA,OAAAA,CAAQG,GAAG,CAACJ,yBAAAA,CAAAA;AACrB,IAAA;AAEA,IAAA,IAAI,CAACC,OAAAA,IAAW,OAAOA,OAAAA,KAAY,QAAA,EAAU;QAC3C,OAAOA,OAAAA;AACT,IAAA;AAEA,IAAA,MAAMI,WAAsB,EAAC;IAE7B,KAAK,MAAM,CAACC,GAAAA,EAAKC,KAAAA,CAAM,IAAInB,MAAAA,CAAOoB,OAAO,CAACP,OAAAA,CAAAA,CAAuB;QAC/D,IAAIK,GAAAA,KAAQ,QAAA,IAAYC,KAAAA,IAAS,OAAOA,KAAAA,KAAU,YAAY,CAACL,KAAAA,CAAMC,OAAO,CAACI,KAAAA,CAAAA,EAAQ;YACnFF,QAAQ,CAACC,GAAAA,CAAI,GAAGb,qBAAAA,CAAsBc,KAAAA,CAAAA;AACxC,QAAA,CAAA,MAAO,IAAID,GAAAA,KAAQ,MAAA,IAAUA,GAAAA,KAAQ,KAAA,IAASA,QAAQ,MAAA,EAAQ;YAC5DD,QAAQ,CAACC,GAAAA,CAAI,GAAGN,yBAAAA,CAA0BO,KAAAA,CAAAA;QAC5C,CAAA,MAAO;YACLF,QAAQ,CAACC,IAAI,GAAGC,KAAAA;AAClB,QAAA;AACF,IAAA;IAEA,OAAOF,QAAAA;AACT;;;;"}
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var api = require('../../../../admin/src/services/api.js');
4
+ var legacyActions = require('../pages/SettingsPage/pages/AuditLogs/utils/legacyActions.js');
4
5
 
5
6
  const auditLogsService = api.adminApi.injectEndpoints({
6
7
  endpoints: (builder)=>({
@@ -8,7 +9,7 @@ const auditLogsService = api.adminApi.injectEndpoints({
8
9
  query: (params)=>({
9
10
  url: `/admin/audit-logs`,
10
11
  config: {
11
- params
12
+ params: legacyActions.expandLegacyActionFilters(params)
12
13
  }
13
14
  })
14
15
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"auditLogs.js","sources":["../../../../../../ee/admin/src/services/auditLogs.ts"],"sourcesContent":["import { adminApi } from '../../../../admin/src/services/api';\nimport * as AuditLogs from '../../../../shared/contracts/audit-logs';\n\nconst auditLogsService = adminApi.injectEndpoints({\n endpoints: (builder) => ({\n getAuditLogs: builder.query<AuditLogs.GetAll.Response, AuditLogs.GetAll.Request['query']>({\n query: (params) => ({\n url: `/admin/audit-logs`,\n config: {\n params,\n },\n }),\n }),\n getAuditLog: builder.query<AuditLogs.Get.Response, AuditLogs.Get.Params['id']>({\n query: (id) => `/admin/audit-logs/${id}`,\n }),\n getAuditLogUsers: builder.query<\n AuditLogs.GetUsers.Response,\n AuditLogs.GetUsers.Request['query']\n >({\n query: (params) => ({\n url: `/admin/audit-logs/users`,\n config: {\n params,\n },\n }),\n }),\n }),\n overrideExisting: false,\n});\n\nconst { useGetAuditLogsQuery, useGetAuditLogQuery, useGetAuditLogUsersQuery } = auditLogsService;\n\nexport { useGetAuditLogsQuery, useGetAuditLogQuery, useGetAuditLogUsersQuery };\n"],"names":["auditLogsService","adminApi","injectEndpoints","endpoints","builder","getAuditLogs","query","params","url","config","getAuditLog","id","getAuditLogUsers","overrideExisting","useGetAuditLogsQuery","useGetAuditLogQuery","useGetAuditLogUsersQuery"],"mappings":";;;;AAGA,MAAMA,gBAAAA,GAAmBC,YAAAA,CAASC,eAAe,CAAC;IAChDC,SAAAA,EAAW,CAACC,WAAa;YACvBC,YAAAA,EAAcD,OAAAA,CAAQE,KAAK,CAA+D;gBACxFA,KAAAA,EAAO,CAACC,UAAY;wBAClBC,GAAAA,EAAK,CAAC,iBAAiB,CAAC;wBACxBC,MAAAA,EAAQ;AACNF,4BAAAA;AACF;qBACF;AACF,aAAA,CAAA;YACAG,WAAAA,EAAaN,OAAAA,CAAQE,KAAK,CAAqD;AAC7EA,gBAAAA,KAAAA,EAAO,CAACK,EAAAA,GAAO,CAAC,kBAAkB,EAAEA,EAAAA,CAAAA;AACtC,aAAA,CAAA;YACAC,gBAAAA,EAAkBR,OAAAA,CAAQE,KAAK,CAG7B;gBACAA,KAAAA,EAAO,CAACC,UAAY;wBAClBC,GAAAA,EAAK,CAAC,uBAAuB,CAAC;wBAC9BC,MAAAA,EAAQ;AACNF,4BAAAA;AACF;qBACF;AACF,aAAA;SACF,CAAA;IACAM,gBAAAA,EAAkB;AACpB,CAAA,CAAA;AAEA,MAAM,EAAEC,oBAAoB,EAAEC,mBAAmB,EAAEC,wBAAwB,EAAE,GAAGhB;;;;;;"}
1
+ {"version":3,"file":"auditLogs.js","sources":["../../../../../../ee/admin/src/services/auditLogs.ts"],"sourcesContent":["import { adminApi } from '../../../../admin/src/services/api';\nimport * as AuditLogs from '../../../../shared/contracts/audit-logs';\nimport { expandLegacyActionFilters } from '../pages/SettingsPage/pages/AuditLogs/utils/legacyActions';\n\nconst auditLogsService = adminApi.injectEndpoints({\n endpoints: (builder) => ({\n getAuditLogs: builder.query<AuditLogs.GetAll.Response, AuditLogs.GetAll.Request['query']>({\n query: (params) => ({\n url: `/admin/audit-logs`,\n config: {\n params: expandLegacyActionFilters(params),\n },\n }),\n }),\n getAuditLog: builder.query<AuditLogs.Get.Response, AuditLogs.Get.Params['id']>({\n query: (id) => `/admin/audit-logs/${id}`,\n }),\n getAuditLogUsers: builder.query<\n AuditLogs.GetUsers.Response,\n AuditLogs.GetUsers.Request['query']\n >({\n query: (params) => ({\n url: `/admin/audit-logs/users`,\n config: {\n params,\n },\n }),\n }),\n }),\n overrideExisting: false,\n});\n\nconst { useGetAuditLogsQuery, useGetAuditLogQuery, useGetAuditLogUsersQuery } = auditLogsService;\n\nexport { useGetAuditLogsQuery, useGetAuditLogQuery, useGetAuditLogUsersQuery };\n"],"names":["auditLogsService","adminApi","injectEndpoints","endpoints","builder","getAuditLogs","query","params","url","config","expandLegacyActionFilters","getAuditLog","id","getAuditLogUsers","overrideExisting","useGetAuditLogsQuery","useGetAuditLogQuery","useGetAuditLogUsersQuery"],"mappings":";;;;;AAIA,MAAMA,gBAAAA,GAAmBC,YAAAA,CAASC,eAAe,CAAC;IAChDC,SAAAA,EAAW,CAACC,WAAa;YACvBC,YAAAA,EAAcD,OAAAA,CAAQE,KAAK,CAA+D;gBACxFA,KAAAA,EAAO,CAACC,UAAY;wBAClBC,GAAAA,EAAK,CAAC,iBAAiB,CAAC;wBACxBC,MAAAA,EAAQ;AACNF,4BAAAA,MAAAA,EAAQG,uCAAAA,CAA0BH,MAAAA;AACpC;qBACF;AACF,aAAA,CAAA;YACAI,WAAAA,EAAaP,OAAAA,CAAQE,KAAK,CAAqD;AAC7EA,gBAAAA,KAAAA,EAAO,CAACM,EAAAA,GAAO,CAAC,kBAAkB,EAAEA,EAAAA,CAAAA;AACtC,aAAA,CAAA;YACAC,gBAAAA,EAAkBT,OAAAA,CAAQE,KAAK,CAG7B;gBACAA,KAAAA,EAAO,CAACC,UAAY;wBAClBC,GAAAA,EAAK,CAAC,uBAAuB,CAAC;wBAC9BC,MAAAA,EAAQ;AACNF,4BAAAA;AACF;qBACF;AACF,aAAA;SACF,CAAA;IACAO,gBAAAA,EAAkB;AACpB,CAAA,CAAA;AAEA,MAAM,EAAEC,oBAAoB,EAAEC,mBAAmB,EAAEC,wBAAwB,EAAE,GAAGjB;;;;;;"}
@@ -1,4 +1,5 @@
1
1
  import { adminApi } from '../../../../admin/src/services/api.mjs';
2
+ import { expandLegacyActionFilters } from '../pages/SettingsPage/pages/AuditLogs/utils/legacyActions.mjs';
2
3
 
3
4
  const auditLogsService = adminApi.injectEndpoints({
4
5
  endpoints: (builder)=>({
@@ -6,7 +7,7 @@ const auditLogsService = adminApi.injectEndpoints({
6
7
  query: (params)=>({
7
8
  url: `/admin/audit-logs`,
8
9
  config: {
9
- params
10
+ params: expandLegacyActionFilters(params)
10
11
  }
11
12
  })
12
13
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"auditLogs.mjs","sources":["../../../../../../ee/admin/src/services/auditLogs.ts"],"sourcesContent":["import { adminApi } from '../../../../admin/src/services/api';\nimport * as AuditLogs from '../../../../shared/contracts/audit-logs';\n\nconst auditLogsService = adminApi.injectEndpoints({\n endpoints: (builder) => ({\n getAuditLogs: builder.query<AuditLogs.GetAll.Response, AuditLogs.GetAll.Request['query']>({\n query: (params) => ({\n url: `/admin/audit-logs`,\n config: {\n params,\n },\n }),\n }),\n getAuditLog: builder.query<AuditLogs.Get.Response, AuditLogs.Get.Params['id']>({\n query: (id) => `/admin/audit-logs/${id}`,\n }),\n getAuditLogUsers: builder.query<\n AuditLogs.GetUsers.Response,\n AuditLogs.GetUsers.Request['query']\n >({\n query: (params) => ({\n url: `/admin/audit-logs/users`,\n config: {\n params,\n },\n }),\n }),\n }),\n overrideExisting: false,\n});\n\nconst { useGetAuditLogsQuery, useGetAuditLogQuery, useGetAuditLogUsersQuery } = auditLogsService;\n\nexport { useGetAuditLogsQuery, useGetAuditLogQuery, useGetAuditLogUsersQuery };\n"],"names":["auditLogsService","adminApi","injectEndpoints","endpoints","builder","getAuditLogs","query","params","url","config","getAuditLog","id","getAuditLogUsers","overrideExisting","useGetAuditLogsQuery","useGetAuditLogQuery","useGetAuditLogUsersQuery"],"mappings":";;AAGA,MAAMA,gBAAAA,GAAmBC,QAAAA,CAASC,eAAe,CAAC;IAChDC,SAAAA,EAAW,CAACC,WAAa;YACvBC,YAAAA,EAAcD,OAAAA,CAAQE,KAAK,CAA+D;gBACxFA,KAAAA,EAAO,CAACC,UAAY;wBAClBC,GAAAA,EAAK,CAAC,iBAAiB,CAAC;wBACxBC,MAAAA,EAAQ;AACNF,4BAAAA;AACF;qBACF;AACF,aAAA,CAAA;YACAG,WAAAA,EAAaN,OAAAA,CAAQE,KAAK,CAAqD;AAC7EA,gBAAAA,KAAAA,EAAO,CAACK,EAAAA,GAAO,CAAC,kBAAkB,EAAEA,EAAAA,CAAAA;AACtC,aAAA,CAAA;YACAC,gBAAAA,EAAkBR,OAAAA,CAAQE,KAAK,CAG7B;gBACAA,KAAAA,EAAO,CAACC,UAAY;wBAClBC,GAAAA,EAAK,CAAC,uBAAuB,CAAC;wBAC9BC,MAAAA,EAAQ;AACNF,4BAAAA;AACF;qBACF;AACF,aAAA;SACF,CAAA;IACAM,gBAAAA,EAAkB;AACpB,CAAA,CAAA;AAEA,MAAM,EAAEC,oBAAoB,EAAEC,mBAAmB,EAAEC,wBAAwB,EAAE,GAAGhB;;;;"}
1
+ {"version":3,"file":"auditLogs.mjs","sources":["../../../../../../ee/admin/src/services/auditLogs.ts"],"sourcesContent":["import { adminApi } from '../../../../admin/src/services/api';\nimport * as AuditLogs from '../../../../shared/contracts/audit-logs';\nimport { expandLegacyActionFilters } from '../pages/SettingsPage/pages/AuditLogs/utils/legacyActions';\n\nconst auditLogsService = adminApi.injectEndpoints({\n endpoints: (builder) => ({\n getAuditLogs: builder.query<AuditLogs.GetAll.Response, AuditLogs.GetAll.Request['query']>({\n query: (params) => ({\n url: `/admin/audit-logs`,\n config: {\n params: expandLegacyActionFilters(params),\n },\n }),\n }),\n getAuditLog: builder.query<AuditLogs.Get.Response, AuditLogs.Get.Params['id']>({\n query: (id) => `/admin/audit-logs/${id}`,\n }),\n getAuditLogUsers: builder.query<\n AuditLogs.GetUsers.Response,\n AuditLogs.GetUsers.Request['query']\n >({\n query: (params) => ({\n url: `/admin/audit-logs/users`,\n config: {\n params,\n },\n }),\n }),\n }),\n overrideExisting: false,\n});\n\nconst { useGetAuditLogsQuery, useGetAuditLogQuery, useGetAuditLogUsersQuery } = auditLogsService;\n\nexport { useGetAuditLogsQuery, useGetAuditLogQuery, useGetAuditLogUsersQuery };\n"],"names":["auditLogsService","adminApi","injectEndpoints","endpoints","builder","getAuditLogs","query","params","url","config","expandLegacyActionFilters","getAuditLog","id","getAuditLogUsers","overrideExisting","useGetAuditLogsQuery","useGetAuditLogQuery","useGetAuditLogUsersQuery"],"mappings":";;;AAIA,MAAMA,gBAAAA,GAAmBC,QAAAA,CAASC,eAAe,CAAC;IAChDC,SAAAA,EAAW,CAACC,WAAa;YACvBC,YAAAA,EAAcD,OAAAA,CAAQE,KAAK,CAA+D;gBACxFA,KAAAA,EAAO,CAACC,UAAY;wBAClBC,GAAAA,EAAK,CAAC,iBAAiB,CAAC;wBACxBC,MAAAA,EAAQ;AACNF,4BAAAA,MAAAA,EAAQG,yBAAAA,CAA0BH,MAAAA;AACpC;qBACF;AACF,aAAA,CAAA;YACAI,WAAAA,EAAaP,OAAAA,CAAQE,KAAK,CAAqD;AAC7EA,gBAAAA,KAAAA,EAAO,CAACM,EAAAA,GAAO,CAAC,kBAAkB,EAAEA,EAAAA,CAAAA;AACtC,aAAA,CAAA;YACAC,gBAAAA,EAAkBT,OAAAA,CAAQE,KAAK,CAG7B;gBACAA,KAAAA,EAAO,CAACC,UAAY;wBAClBC,GAAAA,EAAK,CAAC,uBAAuB,CAAC;wBAC9BC,MAAAA,EAAQ;AACNF,4BAAAA;AACF;qBACF;AACF,aAAA;SACF,CAAA;IACAO,gBAAAA,EAAkB;AACpB,CAAA,CAAA;AAEA,MAAM,EAAEC,oBAAoB,EAAEC,mBAAmB,EAAEC,wBAAwB,EAAE,GAAGjB;;;;"}
@@ -58,13 +58,13 @@ export declare const SubNav: {
58
58
  Folder: ({ defaultOpen, open: openProp, isDropTarget, endAction, children, onToggle, rowRef, label, depth, }: import("./SubNavFolder").SubNavFolderProps) => import("react/jsx-runtime").JSX.Element;
59
59
  PageWrapper: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Omit<import("@strapi/design-system").TransientBoxProps & {
60
60
  children?: React.ReactNode;
61
- } & import("@strapi/design-system/dist/types").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
61
+ } & import("@strapi/design-system/dist/types.js").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types.js").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
62
62
  ref?: any;
63
63
  }, "ref"> & {
64
64
  ref?: any;
65
65
  }, never> & Partial<Pick<Omit<import("@strapi/design-system").TransientBoxProps & {
66
66
  children?: React.ReactNode;
67
- } & import("@strapi/design-system/dist/types").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
67
+ } & import("@strapi/design-system/dist/types.js").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types.js").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
68
68
  ref?: any;
69
69
  }, "ref"> & {
70
70
  ref?: any;
@@ -0,0 +1,11 @@
1
+ import type { Modules } from '@strapi/types';
2
+ /**
3
+ * Builds the `window.strapi` object: Community defaults, then the license response.
4
+ * Returned rather than assigned so the caller publishes it to `window` exactly once.
5
+ *
6
+ * Nothing here may read `window.strapi` — it does not exist yet, and the `#strapi`
7
+ * mount node shadows it as a named window property, so reads silently yield the
8
+ * element instead of throwing.
9
+ */
10
+ declare const createBrowserStrapi: (features?: Modules.Features.FeaturesService["config"]) => Promise<Window["strapi"]>;
11
+ export { createBrowserStrapi };
@@ -44,5 +44,15 @@ export declare const actionTypes: {
44
44
  'token.update': string;
45
45
  'token.delete': string;
46
46
  'token.regenerate': string;
47
+ 'admin-user.create': string;
48
+ 'admin-user.update': string;
49
+ 'admin-user.delete': string;
50
+ 'admin-user.invite.accept': string;
51
+ 'admin-user.password-reset.create': string;
52
+ 'admin-user.password-reset.confirm': string;
53
+ 'admin-user.password.update': string;
54
+ 'webhook.create': string;
55
+ 'webhook.update': string;
56
+ 'webhook.delete': string;
47
57
  };
48
58
  export declare const getDefaultMessage: (value: keyof typeof actionTypes) => string;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Admin-account rows stored before the `admin-user.*` events kept their old action keys
3
+ * and stay until retention removes them. The Action filter offers the new key only and
4
+ * queries both, so one option covers the whole history.
5
+ *
6
+ * Remove together with the deprecated `user.*` event hub events.
7
+ */
8
+ export declare const LEGACY_ACTIONS: Record<string, string>;
9
+ export declare const isLegacyAction: (action: string) => boolean;
10
+ /**
11
+ * Rewrites `action` equality conditions on a new key into `$in` / `$notIn` over the new
12
+ * and the legacy key. Walks `$and`, `$or` and `$not`. Anything else is returned as is.
13
+ */
14
+ export declare const expandLegacyActionFilters: <T>(filters: T) => T;
@@ -1,4 +1,13 @@
1
1
  import type { Core, Modules } from '@strapi/types';
2
+ export interface RegisterEventOptions {
3
+ /**
4
+ * Records the event when the request has no authenticated user, with an
5
+ * `unknown` actor and no user column. For actions taken from public admin
6
+ * forms (password reset, invitation). Off by default: an event with no user
7
+ * is dropped.
8
+ */
9
+ allowUnknownActor?: boolean;
10
+ }
2
11
  /**
3
12
  * @description
4
13
  * Manages the lifecycle of audit logs. Accessible via strapi.get('audit-logs-lifecycle')
@@ -9,7 +18,7 @@ declare const createAuditLogsLifecycleService: (strapi: Core.Strapi) => {
9
18
  * their bootstrap; the transformer builds the audited shape
10
19
  * ({resource, details, outcome}) from the arguments passed to eventHub.emit().
11
20
  */
12
- registerEvent<TDetails = unknown>(name: string, transform: Modules.AuditLogs.EventTransformer<TDetails>): void;
21
+ registerEvent<TDetails = unknown>(name: string, transform: Modules.AuditLogs.EventTransformer<TDetails>, options?: RegisterEventOptions): void;
13
22
  register(): Promise</*elided*/ any>;
14
23
  unsubscribe(): /*elided*/ any;
15
24
  destroy(): /*elided*/ any;
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycles.d.ts","sourceRoot":"","sources":["../../../../../../ee/server/src/audit-logs/services/lifecycles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAgFnD;;;GAGG;AACH,QAAA,MAAM,+BAA+B,GAAI,QAAQ,IAAI,CAAC,MAAM;IAiHxD;;;;OAIG;kBACW,QAAQ,kBACd,MAAM,aACD,OAAO,CAAC,SAAS,CAAC,gBAAgB,CAAC,QAAQ,CAAC;;;;CAyF5D,CAAC;AAEF,OAAO,EAAE,+BAA+B,EAAE,CAAC"}
1
+ {"version":3,"file":"lifecycles.d.ts","sourceRoot":"","sources":["../../../../../../ee/server/src/audit-logs/services/lifecycles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAqDnD,MAAM,WAAW,oBAAoB;IACnC;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAoDD;;;GAGG;AACH,QAAA,MAAM,+BAA+B,GAAI,QAAQ,IAAI,CAAC,MAAM;IAkHxD;;;;OAIG;kBACW,QAAQ,kBACd,MAAM,aACD,OAAO,CAAC,SAAS,CAAC,gBAAgB,CAAC,QAAQ,CAAC,YAC9C,oBAAoB;;;;CA0FlC,CAAC;AAEF,OAAO,EAAE,+BAA+B,EAAE,CAAC"}
@@ -1,32 +1,6 @@
1
+ import type { GetProjectType } from '../../../../shared/contracts/admin';
1
2
  declare const _default: {
2
- getProjectType(): Promise<{
3
- data: {
4
- isEE: boolean | undefined;
5
- isTrial: boolean;
6
- features: {
7
- [key: string]: any;
8
- name: string;
9
- }[];
10
- flags: {};
11
- type: string | null | undefined;
12
- planPriceId: string | null | undefined;
13
- ai: {
14
- enabled: boolean;
15
- };
16
- };
17
- } | {
18
- data: {
19
- isEE: boolean;
20
- features: never[];
21
- flags: {};
22
- ai: {
23
- enabled: boolean;
24
- };
25
- isTrial?: undefined;
26
- type?: undefined;
27
- planPriceId?: undefined;
28
- };
29
- }>;
3
+ getProjectType(): Promise<GetProjectType.Response>;
30
4
  licenseLimitInformation(): Promise<{
31
5
  data: {
32
6
  enforcementUserCount: any;
@@ -1 +1 @@
1
- {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../../../../ee/server/src/controllers/admin.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,wBAkEE"}
1
+ {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../../../../ee/server/src/controllers/admin.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;;sBAI/C,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC;;;;;;;;;;;;;;;;;;;AAF1D,wBAmEE"}
@@ -16,34 +16,7 @@ declare const _default: {
16
16
  isSSOLocked(ctx: import("koa").Context): Promise<void>;
17
17
  };
18
18
  admin: {
19
- getProjectType(): Promise<{
20
- data: {
21
- isEE: boolean | undefined;
22
- isTrial: boolean;
23
- features: {
24
- [key: string]: any;
25
- name: string;
26
- }[];
27
- flags: {};
28
- type: string | null | undefined;
29
- planPriceId: string | null | undefined;
30
- ai: {
31
- enabled: boolean;
32
- };
33
- };
34
- } | {
35
- data: {
36
- isEE: boolean;
37
- features: never[];
38
- flags: {};
39
- ai: {
40
- enabled: boolean;
41
- };
42
- isTrial?: undefined;
43
- type?: undefined;
44
- planPriceId?: undefined;
45
- };
46
- }>;
19
+ getProjectType(): Promise<import("../../../../shared/contracts/admin").GetProjectType.Response>;
47
20
  licenseLimitInformation(): Promise<{
48
21
  data: {
49
22
  enforcementUserCount: any;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../ee/server/src/controllers/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,wBAKE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../ee/server/src/controllers/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,wBAKE"}
@@ -24,34 +24,7 @@ declare const getAdminEE: () => {
24
24
  isSSOLocked(ctx: import("koa").Context): Promise<void>;
25
25
  };
26
26
  admin: {
27
- getProjectType(): Promise<{
28
- data: {
29
- isEE: boolean | undefined;
30
- isTrial: boolean;
31
- features: {
32
- [key: string]: any;
33
- name: string;
34
- }[];
35
- flags: {};
36
- type: string | null | undefined;
37
- planPriceId: string | null | undefined;
38
- ai: {
39
- enabled: boolean;
40
- };
41
- };
42
- } | {
43
- data: {
44
- isEE: boolean;
45
- features: never[];
46
- flags: {};
47
- ai: {
48
- enabled: boolean;
49
- };
50
- isTrial?: undefined;
51
- type?: undefined;
52
- planPriceId?: undefined;
53
- };
54
- }>;
27
+ getProjectType(): Promise<import("../../../shared/contracts/admin").GetProjectType.Response>;
55
28
  licenseLimitInformation(): Promise<{
56
29
  data: {
57
30
  enforcementUserCount: any;
@@ -180,7 +153,7 @@ declare const getAdminEE: () => {
180
153
  services: {
181
154
  auth: {
182
155
  forgotPassword: ({ email }?: any) => Promise<any>;
183
- resetPassword: ({ resetPasswordToken, password }?: any) => Promise<any>;
156
+ resetPassword: ({ resetPasswordToken, password }?: any) => Promise<import("../../../shared/contracts/shared").AdminUser>;
184
157
  };
185
158
  passport: {
186
159
  providerRegistry: Map<any, any>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../ee/server/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAgB1C,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBA4Be;QAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAA;KAAE;wBAwBxB;QAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAOpD,CAAC;AAEF,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../ee/server/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAkB1C,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBA4Be;QAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAA;KAAE;wBA0BxB;QAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAOpD,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -1,6 +1,6 @@
1
1
  declare const _default: {
2
2
  forgotPassword: ({ email }?: any) => Promise<any>;
3
- resetPassword: ({ resetPasswordToken, password }?: any) => Promise<any>;
3
+ resetPassword: ({ resetPasswordToken, password }?: any) => Promise<import("../../../../shared/contracts/shared").AdminUser>;
4
4
  };
5
5
  export default _default;
6
6
  //# sourceMappingURL=auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../../../ee/server/src/services/auth.ts"],"names":[],"mappings":";iCAiByC,GAAG;uDAwCmB,GAAG;;AAkBlE,wBAGE"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../../../ee/server/src/services/auth.ts"],"names":[],"mappings":";iCAiByC,GAAG;uDAwCmB,GAAG;;AAclE,wBAGE"}
@@ -1,7 +1,7 @@
1
1
  declare const _default: {
2
2
  auth: {
3
3
  forgotPassword: ({ email }?: any) => Promise<any>;
4
- resetPassword: ({ resetPasswordToken, password }?: any) => Promise<any>;
4
+ resetPassword: ({ resetPasswordToken, password }?: any) => Promise<import("../../../../shared/contracts/shared").AdminUser>;
5
5
  };
6
6
  passport: {
7
7
  providerRegistry: Map<any, any>;
@@ -1 +1 @@
1
- {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../../../../ee/server/src/services/user.ts"],"names":[],"mappings":";oCAmB6C,MAAM,SAAS,GAAG;yCAwBb,OAAO;;uBA8HzB,GAAG;qBAzCL,OAAO;qBAzDP,GAAG,cAAc,GAAG;;AAkLlD,wBAOE"}
1
+ {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../../../../ee/server/src/services/user.ts"],"names":[],"mappings":";oCAyB6C,MAAM,SAAS,GAAG;yCAwBb,OAAO;;uBAsIzB,GAAG;qBA1CL,OAAO;qBAhEP,GAAG,cAAc,GAAG;;AA8LlD,wBAOE"}
@@ -6,7 +6,9 @@ const DEFAULT_RETENTION_DAYS = 90;
6
6
  /**
7
7
  * Events audited before the payload standard; their stored shape is frozen for
8
8
  * compatibility. Do not add events here: new events come through registerEvent().
9
- * TODO: migrate these to the standard.
9
+ * The event hub still emits user.create, user.update and user.delete; the audit log
10
+ * records them as admin-user.* (server/src/audit-logs/admin-users.ts).
11
+ * TODO: migrate the rest to the standard.
10
12
  */ const defaultEvents = [
11
13
  'entry.create',
12
14
  'entry.update',
@@ -19,9 +21,6 @@ const DEFAULT_RETENTION_DAYS = 90;
19
21
  'media-folder.create',
20
22
  'media-folder.update',
21
23
  'media-folder.delete',
22
- 'user.create',
23
- 'user.update',
24
- 'user.delete',
25
24
  'admin.auth.success',
26
25
  'admin.logout',
27
26
  'content-type.create',
@@ -45,6 +44,28 @@ const getEventMap = (events)=>{
45
44
  return acc;
46
45
  }, {});
47
46
  };
47
+ const getActor = (systemOrigin, user)=>{
48
+ if (systemOrigin) {
49
+ return {
50
+ type: 'system'
51
+ };
52
+ }
53
+ if (!user) {
54
+ return {
55
+ type: 'unknown'
56
+ };
57
+ }
58
+ // We copy the user data into the row so the history stays unchanged if the user
59
+ // changes later
60
+ return {
61
+ type: 'admin-user',
62
+ user: {
63
+ id: user.id,
64
+ email: user.email,
65
+ name: utils.getDisplayName(user)
66
+ }
67
+ };
68
+ };
48
69
  const getRetentionDays = (strapi)=>{
49
70
  const featureConfig = strapi.ee.features.get('audit-logs');
50
71
  const licenseRetentionDays = typeof featureConfig === 'object' && featureConfig?.options?.retentionDays;
@@ -88,14 +109,19 @@ const getRetentionDays = (strapi)=>{
88
109
  const isMcpAdminAction = auditSource === 'mcp';
89
110
  const user = requestState?.user;
90
111
  const systemOrigin = auditSource && SYSTEM_ORIGINS.includes(auditSource) ? auditSource : undefined;
91
- if (!systemOrigin && (!isUsingAdminAuth && !isMcpAdminAction || !user)) {
112
+ if (!systemOrigin && !isUsingAdminAuth && !isMcpAdminAction) {
113
+ return null;
114
+ }
115
+ const allowsUnknownActor = registration.kind === 'standard' && registration.options.allowUnknownActor === true;
116
+ if (!systemOrigin && !user && !allowsUnknownActor) {
92
117
  return null;
93
118
  }
94
119
  const origin = systemOrigin ?? auditSource ?? 'admin-panel';
95
120
  const date = new Date().toISOString();
96
121
  // Scheduled actions have no user, so a null user is expected. The earlier audit
97
- // entry that set the schedule records who did it.
98
- const userId = systemOrigin ? null : user.id;
122
+ // entry that set the schedule records who did it. Events allowing an unknown actor
123
+ // have no user either.
124
+ const userId = user ? user.id : null;
99
125
  if (registration.kind === 'legacy') {
100
126
  // TODO: What does this ignore in upload? Why would we want to ignore anything?
101
127
  const ignoredUids = [
@@ -115,18 +141,7 @@ const getRetentionDays = (strapi)=>{
115
141
  userId
116
142
  };
117
143
  }
118
- const actor = systemOrigin ? {
119
- type: 'system'
120
- } : {
121
- type: 'admin-user',
122
- // We copy the user data into the row so the history stays unchanged if the
123
- // user changes later
124
- user: {
125
- id: user.id,
126
- email: user.email,
127
- name: utils.getDisplayName(user)
128
- }
129
- };
144
+ const actor = getActor(systemOrigin, user);
130
145
  let shape = null;
131
146
  try {
132
147
  shape = await registration.transform(...args);
@@ -178,7 +193,7 @@ const getRetentionDays = (strapi)=>{
178
193
  * Adds an event to the list of audited events. Plugins register their own from
179
194
  * their bootstrap; the transformer builds the audited shape
180
195
  * ({resource, details, outcome}) from the arguments passed to eventHub.emit().
181
- */ registerEvent (name, transform) {
196
+ */ registerEvent (name, transform, options = {}) {
182
197
  if (eventMap[name]?.kind === 'legacy') {
183
198
  throw new Error(`Cannot register the audit log event "${name}": it is one of the built-in events, whose stored shape is frozen.`);
184
199
  }
@@ -187,7 +202,8 @@ const getRetentionDays = (strapi)=>{
187
202
  }
188
203
  eventMap[name] = {
189
204
  kind: 'standard',
190
- transform: transform
205
+ transform: transform,
206
+ options
191
207
  };
192
208
  },
193
209
  async register () {
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycles.js","sources":["../../../../../../../ee/server/src/audit-logs/services/lifecycles.ts"],"sourcesContent":["import type { Core, Modules } from '@strapi/types';\n\nimport { getDisplayName } from '../utils';\n\nconst DEFAULT_RETENTION_DAYS = 90;\n\n/**\n * Events audited before the payload standard; their stored shape is frozen for\n * compatibility. Do not add events here: new events come through registerEvent().\n * TODO: migrate these to the standard.\n */\nconst defaultEvents = [\n 'entry.create',\n 'entry.update',\n 'entry.delete',\n 'entry.publish',\n 'entry.unpublish',\n 'media.create',\n 'media.update',\n 'media.delete',\n 'media-folder.create',\n 'media-folder.update',\n 'media-folder.delete',\n 'user.create',\n 'user.update',\n 'user.delete',\n 'admin.auth.success',\n 'admin.logout',\n 'content-type.create',\n 'content-type.update',\n 'content-type.delete',\n 'component.create',\n 'component.update',\n 'component.delete',\n 'role.create',\n 'role.update',\n 'role.delete',\n 'permission.create',\n 'permission.update',\n 'permission.delete',\n];\n\n/**\n * Legacy events store the first emitted argument as-is; registered events store the\n * standard shape built by their transformer.\n */\ntype EventRegistration =\n | { kind: 'legacy' }\n | { kind: 'standard'; transform: Modules.AuditLogs.EventTransformer };\n\nconst getEventMap = (events: string[]) => {\n return events.reduce(\n (acc, event) => {\n acc[event] = { kind: 'legacy' };\n return acc;\n },\n {} as Record<string, EventRegistration>\n );\n};\n\nconst getRetentionDays = (strapi: Core.Strapi) => {\n const featureConfig = strapi.ee.features.get('audit-logs');\n const licenseRetentionDays =\n typeof featureConfig === 'object' && featureConfig?.options?.retentionDays;\n const userRetentionDays = strapi.config.get('admin.auditLogs.retentionDays');\n\n // For enterprise plans, use 90 days by default, but allow users to override it\n if (licenseRetentionDays == null) {\n return userRetentionDays ?? DEFAULT_RETENTION_DAYS;\n }\n\n // Allow users to override the license retention days, but not to increase it\n if (userRetentionDays && userRetentionDays <= licenseRetentionDays) {\n return userRetentionDays;\n }\n\n // User didn't provide a retention days value, use the license one\n return licenseRetentionDays;\n};\n\n/**\n * @description\n * Manages the lifecycle of audit logs. Accessible via strapi.get('audit-logs-lifecycle')\n */\nconst createAuditLogsLifecycleService = (strapi: Core.Strapi) => {\n // Manage internal service state privately\n const state = {} as any;\n const auditLogsService = strapi.get('audit-logs');\n\n const eventMap = getEventMap(defaultEvents);\n\n /**\n * The system origins accepted from the execution context; anything else needs a\n * user. Keyed on the type, so extending SystemOrigin without gating it here fails\n * to compile.\n */\n const SYSTEM_ORIGIN_FLAGS: Record<Modules.AuditLogs.SystemOrigin, true> = {\n scheduler: true,\n };\n const SYSTEM_ORIGINS = Object.keys(SYSTEM_ORIGIN_FLAGS);\n\n const processEvent = async (name: string, ...args: any) => {\n const registration = eventMap[name];\n\n if (!registration) {\n return null;\n }\n\n const rawEvent = args[0];\n\n const requestState = strapi.requestContext.get()?.state;\n\n const isUsingAdminAuth = requestState?.route?.info?.type === 'admin';\n const auditSource = requestState?.auditSource;\n const isMcpAdminAction = auditSource === 'mcp';\n const user = requestState?.user;\n\n const systemOrigin =\n auditSource && SYSTEM_ORIGINS.includes(auditSource)\n ? (auditSource as Modules.AuditLogs.SystemOrigin)\n : undefined;\n\n if (!systemOrigin && ((!isUsingAdminAuth && !isMcpAdminAction) || !user)) {\n return null;\n }\n\n const origin: Modules.AuditLogs.AuditSource = systemOrigin ?? auditSource ?? 'admin-panel';\n const date = new Date().toISOString();\n // Scheduled actions have no user, so a null user is expected. The earlier audit\n // entry that set the schedule records who did it.\n const userId = systemOrigin ? null : user.id;\n\n if (registration.kind === 'legacy') {\n // TODO: What does this ignore in upload? Why would we want to ignore anything?\n const ignoredUids = ['plugin::upload.file', 'plugin::upload.folder'];\n if (ignoredUids.includes(rawEvent?.uid)) {\n return null;\n }\n\n return {\n action: name,\n date,\n payload: { ...rawEvent, origin },\n userId,\n };\n }\n\n const actor: Modules.AuditLogs.Actor = systemOrigin\n ? { type: 'system' }\n : {\n type: 'admin-user',\n // We copy the user data into the row so the history stays unchanged if the\n // user changes later\n user: { id: user.id, email: user.email, name: getDisplayName(user) },\n };\n\n let shape: Modules.AuditLogs.EventShape | null = null;\n\n try {\n shape = await registration.transform(...args);\n } catch (error) {\n // If the transformer fails, we still keep the audit event: the row is saved\n // with the subscriber's fields only.\n strapi.log.error(`Failed to build the audit log payload for ${name}`, { error });\n }\n\n const {\n action: _action,\n date: _date,\n actor: _actor,\n origin: _origin,\n ...rest\n } = (shape ?? {}) as Record<string, unknown>;\n const payload = shape\n ? ({ action: name, date, actor, origin, ...rest } as Modules.AuditLogs.StoredPayload)\n : { action: name, date, actor, origin };\n\n return { action: name, date, payload, userId };\n };\n\n const handleEvent = async (name: string, ...args: any) => {\n try {\n const processedEvent = await processEvent(name, ...args);\n\n if (processedEvent) {\n await auditLogsService.saveEvent(processedEvent);\n }\n } catch (error) {\n // Logged, not propagated: most emitters fire and forget (the document service\n // emits entry.* from an unawaited onCommit callback), and a rejection with no\n // one awaiting it takes the process down. Audit logging is therefore fail-open:\n // the entry is lost and only this line records it.\n strapi.log.error(`Failed to save the audit log entry for ${name}`, { error });\n }\n };\n\n return {\n /**\n * Adds an event to the list of audited events. Plugins register their own from\n * their bootstrap; the transformer builds the audited shape\n * ({resource, details, outcome}) from the arguments passed to eventHub.emit().\n */\n registerEvent<TDetails = unknown>(\n name: string,\n transform: Modules.AuditLogs.EventTransformer<TDetails>\n ) {\n if (eventMap[name]?.kind === 'legacy') {\n throw new Error(\n `Cannot register the audit log event \"${name}\": it is one of the built-in events, whose stored shape is frozen.`\n );\n }\n\n if (eventMap[name]) {\n strapi.log.warn(`The audit log event \"${name}\" was already registered and is replaced.`);\n }\n\n eventMap[name] = {\n kind: 'standard',\n transform: transform as Modules.AuditLogs.EventTransformer,\n };\n },\n\n async register() {\n // Handle license being enabled\n if (!state.eeEnableUnsubscribe) {\n // @ts-expect-error- update event hub to receive callback argument\n state.eeEnableUnsubscribe = strapi.eventHub.on('ee.enable', () => {\n // Recreate the service to use the new license info\n this.destroy();\n this.register();\n });\n }\n\n // Handle license being updated\n if (!state.eeUpdateUnsubscribe) {\n // @ts-expect-error- update event hub to receive callback argument\n state.eeUpdateUnsubscribe = strapi.eventHub.on('ee.update', () => {\n // Recreate the service to use the new license info\n this.destroy();\n this.register();\n });\n }\n\n // Handle license being disabled\n // @ts-expect-error- update event hub to receive callback argument\n state.eeDisableUnsubscribe = strapi.eventHub.on('ee.disable', () => {\n // Turn off service when the license gets disabled\n // Only ee.enable and ee.update listeners remain active to recreate the service\n this.destroy();\n });\n\n // Check current state of license\n if (!strapi.ee.features.isEnabled('audit-logs')) {\n return this;\n }\n\n // Start saving events\n state.eventHubUnsubscribe = strapi.eventHub.subscribe(handleEvent);\n\n // Manage audit logs auto deletion\n const retentionDays = getRetentionDays(strapi);\n\n strapi.cron.add({\n deleteExpiredAuditLogs: {\n async task() {\n const expirationDate = new Date(Date.now() - retentionDays * 24 * 60 * 60 * 1000);\n await auditLogsService.deleteExpiredEvents(expirationDate);\n },\n options: '0 0 * * *',\n },\n });\n\n return this;\n },\n\n unsubscribe() {\n if (state.eeDisableUnsubscribe) {\n state.eeDisableUnsubscribe();\n }\n\n if (state.eventHubUnsubscribe) {\n state.eventHubUnsubscribe();\n }\n\n strapi.cron.remove('deleteExpiredAuditLogs');\n\n return this;\n },\n\n destroy() {\n return this.unsubscribe();\n },\n };\n};\n\nexport { createAuditLogsLifecycleService };\n"],"names":["DEFAULT_RETENTION_DAYS","defaultEvents","getEventMap","events","reduce","acc","event","kind","getRetentionDays","strapi","featureConfig","ee","features","get","licenseRetentionDays","options","retentionDays","userRetentionDays","config","createAuditLogsLifecycleService","state","auditLogsService","eventMap","SYSTEM_ORIGIN_FLAGS","scheduler","SYSTEM_ORIGINS","Object","keys","processEvent","name","args","registration","rawEvent","requestState","requestContext","isUsingAdminAuth","route","info","type","auditSource","isMcpAdminAction","user","systemOrigin","includes","undefined","origin","date","Date","toISOString","userId","id","ignoredUids","uid","action","payload","actor","email","getDisplayName","shape","transform","error","log","_action","_date","_actor","_origin","rest","handleEvent","processedEvent","saveEvent","registerEvent","Error","warn","register","eeEnableUnsubscribe","eventHub","on","destroy","eeUpdateUnsubscribe","eeDisableUnsubscribe","isEnabled","eventHubUnsubscribe","subscribe","cron","add","deleteExpiredAuditLogs","task","expirationDate","now","deleteExpiredEvents","unsubscribe","remove"],"mappings":"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"}
1
+ {"version":3,"file":"lifecycles.js","sources":["../../../../../../../ee/server/src/audit-logs/services/lifecycles.ts"],"sourcesContent":["import type { Core, Modules } from '@strapi/types';\n\nimport { getDisplayName } from '../utils';\n\nconst DEFAULT_RETENTION_DAYS = 90;\n\n/**\n * Events audited before the payload standard; their stored shape is frozen for\n * compatibility. Do not add events here: new events come through registerEvent().\n * The event hub still emits user.create, user.update and user.delete; the audit log\n * records them as admin-user.* (server/src/audit-logs/admin-users.ts).\n * TODO: migrate the rest to the standard.\n */\nconst defaultEvents = [\n 'entry.create',\n 'entry.update',\n 'entry.delete',\n 'entry.publish',\n 'entry.unpublish',\n 'media.create',\n 'media.update',\n 'media.delete',\n 'media-folder.create',\n 'media-folder.update',\n 'media-folder.delete',\n 'admin.auth.success',\n 'admin.logout',\n 'content-type.create',\n 'content-type.update',\n 'content-type.delete',\n 'component.create',\n 'component.update',\n 'component.delete',\n 'role.create',\n 'role.update',\n 'role.delete',\n 'permission.create',\n 'permission.update',\n 'permission.delete',\n];\n\n/**\n * Legacy events store the first emitted argument as-is; registered events store the\n * standard shape built by their transformer.\n */\ntype EventRegistration =\n | { kind: 'legacy' }\n | {\n kind: 'standard';\n transform: Modules.AuditLogs.EventTransformer;\n options: RegisterEventOptions;\n };\n\nexport interface RegisterEventOptions {\n /**\n * Records the event when the request has no authenticated user, with an\n * `unknown` actor and no user column. For actions taken from public admin\n * forms (password reset, invitation). Off by default: an event with no user\n * is dropped.\n */\n allowUnknownActor?: boolean;\n}\n\nconst getEventMap = (events: string[]) => {\n return events.reduce(\n (acc, event) => {\n acc[event] = { kind: 'legacy' };\n return acc;\n },\n {} as Record<string, EventRegistration>\n );\n};\n\nconst getActor = (\n systemOrigin: Modules.AuditLogs.SystemOrigin | undefined,\n user: { id: string | number; email: string; firstname?: string; lastname?: string } | undefined\n): Modules.AuditLogs.Actor => {\n if (systemOrigin) {\n return { type: 'system' };\n }\n\n if (!user) {\n return { type: 'unknown' };\n }\n\n // We copy the user data into the row so the history stays unchanged if the user\n // changes later\n return {\n type: 'admin-user',\n user: { id: user.id, email: user.email, name: getDisplayName(user) },\n };\n};\n\nconst getRetentionDays = (strapi: Core.Strapi) => {\n const featureConfig = strapi.ee.features.get('audit-logs');\n const licenseRetentionDays =\n typeof featureConfig === 'object' && featureConfig?.options?.retentionDays;\n const userRetentionDays = strapi.config.get('admin.auditLogs.retentionDays');\n\n // For enterprise plans, use 90 days by default, but allow users to override it\n if (licenseRetentionDays == null) {\n return userRetentionDays ?? DEFAULT_RETENTION_DAYS;\n }\n\n // Allow users to override the license retention days, but not to increase it\n if (userRetentionDays && userRetentionDays <= licenseRetentionDays) {\n return userRetentionDays;\n }\n\n // User didn't provide a retention days value, use the license one\n return licenseRetentionDays;\n};\n\n/**\n * @description\n * Manages the lifecycle of audit logs. Accessible via strapi.get('audit-logs-lifecycle')\n */\nconst createAuditLogsLifecycleService = (strapi: Core.Strapi) => {\n // Manage internal service state privately\n const state = {} as any;\n const auditLogsService = strapi.get('audit-logs');\n\n const eventMap = getEventMap(defaultEvents);\n\n /**\n * The system origins accepted from the execution context; anything else needs a\n * user. Keyed on the type, so extending SystemOrigin without gating it here fails\n * to compile.\n */\n const SYSTEM_ORIGIN_FLAGS: Record<Modules.AuditLogs.SystemOrigin, true> = {\n scheduler: true,\n };\n const SYSTEM_ORIGINS = Object.keys(SYSTEM_ORIGIN_FLAGS);\n\n const processEvent = async (name: string, ...args: any) => {\n const registration = eventMap[name];\n\n if (!registration) {\n return null;\n }\n\n const rawEvent = args[0];\n\n const requestState = strapi.requestContext.get()?.state;\n\n const isUsingAdminAuth = requestState?.route?.info?.type === 'admin';\n const auditSource = requestState?.auditSource;\n const isMcpAdminAction = auditSource === 'mcp';\n const user = requestState?.user;\n\n const systemOrigin =\n auditSource && SYSTEM_ORIGINS.includes(auditSource)\n ? (auditSource as Modules.AuditLogs.SystemOrigin)\n : undefined;\n\n if (!systemOrigin && !isUsingAdminAuth && !isMcpAdminAction) {\n return null;\n }\n\n const allowsUnknownActor =\n registration.kind === 'standard' && registration.options.allowUnknownActor === true;\n\n if (!systemOrigin && !user && !allowsUnknownActor) {\n return null;\n }\n\n const origin: Modules.AuditLogs.AuditSource = systemOrigin ?? auditSource ?? 'admin-panel';\n const date = new Date().toISOString();\n // Scheduled actions have no user, so a null user is expected. The earlier audit\n // entry that set the schedule records who did it. Events allowing an unknown actor\n // have no user either.\n const userId = user ? user.id : null;\n\n if (registration.kind === 'legacy') {\n // TODO: What does this ignore in upload? Why would we want to ignore anything?\n const ignoredUids = ['plugin::upload.file', 'plugin::upload.folder'];\n if (ignoredUids.includes(rawEvent?.uid)) {\n return null;\n }\n\n return {\n action: name,\n date,\n payload: { ...rawEvent, origin },\n userId,\n };\n }\n\n const actor = getActor(systemOrigin, user);\n\n let shape: Modules.AuditLogs.EventShape | null = null;\n\n try {\n shape = await registration.transform(...args);\n } catch (error) {\n // If the transformer fails, we still keep the audit event: the row is saved\n // with the subscriber's fields only.\n strapi.log.error(`Failed to build the audit log payload for ${name}`, { error });\n }\n\n const {\n action: _action,\n date: _date,\n actor: _actor,\n origin: _origin,\n ...rest\n } = (shape ?? {}) as Record<string, unknown>;\n const payload = shape\n ? ({ action: name, date, actor, origin, ...rest } as Modules.AuditLogs.StoredPayload)\n : { action: name, date, actor, origin };\n\n return { action: name, date, payload, userId };\n };\n\n const handleEvent = async (name: string, ...args: any) => {\n try {\n const processedEvent = await processEvent(name, ...args);\n\n if (processedEvent) {\n await auditLogsService.saveEvent(processedEvent);\n }\n } catch (error) {\n // Logged, not propagated: most emitters fire and forget (the document service\n // emits entry.* from an unawaited onCommit callback), and a rejection with no\n // one awaiting it takes the process down. Audit logging is therefore fail-open:\n // the entry is lost and only this line records it.\n strapi.log.error(`Failed to save the audit log entry for ${name}`, { error });\n }\n };\n\n return {\n /**\n * Adds an event to the list of audited events. Plugins register their own from\n * their bootstrap; the transformer builds the audited shape\n * ({resource, details, outcome}) from the arguments passed to eventHub.emit().\n */\n registerEvent<TDetails = unknown>(\n name: string,\n transform: Modules.AuditLogs.EventTransformer<TDetails>,\n options: RegisterEventOptions = {}\n ) {\n if (eventMap[name]?.kind === 'legacy') {\n throw new Error(\n `Cannot register the audit log event \"${name}\": it is one of the built-in events, whose stored shape is frozen.`\n );\n }\n\n if (eventMap[name]) {\n strapi.log.warn(`The audit log event \"${name}\" was already registered and is replaced.`);\n }\n\n eventMap[name] = {\n kind: 'standard',\n transform: transform as Modules.AuditLogs.EventTransformer,\n options,\n };\n },\n\n async register() {\n // Handle license being enabled\n if (!state.eeEnableUnsubscribe) {\n // @ts-expect-error- update event hub to receive callback argument\n state.eeEnableUnsubscribe = strapi.eventHub.on('ee.enable', () => {\n // Recreate the service to use the new license info\n this.destroy();\n this.register();\n });\n }\n\n // Handle license being updated\n if (!state.eeUpdateUnsubscribe) {\n // @ts-expect-error- update event hub to receive callback argument\n state.eeUpdateUnsubscribe = strapi.eventHub.on('ee.update', () => {\n // Recreate the service to use the new license info\n this.destroy();\n this.register();\n });\n }\n\n // Handle license being disabled\n // @ts-expect-error- update event hub to receive callback argument\n state.eeDisableUnsubscribe = strapi.eventHub.on('ee.disable', () => {\n // Turn off service when the license gets disabled\n // Only ee.enable and ee.update listeners remain active to recreate the service\n this.destroy();\n });\n\n // Check current state of license\n if (!strapi.ee.features.isEnabled('audit-logs')) {\n return this;\n }\n\n // Start saving events\n state.eventHubUnsubscribe = strapi.eventHub.subscribe(handleEvent);\n\n // Manage audit logs auto deletion\n const retentionDays = getRetentionDays(strapi);\n\n strapi.cron.add({\n deleteExpiredAuditLogs: {\n async task() {\n const expirationDate = new Date(Date.now() - retentionDays * 24 * 60 * 60 * 1000);\n await auditLogsService.deleteExpiredEvents(expirationDate);\n },\n options: '0 0 * * *',\n },\n });\n\n return this;\n },\n\n unsubscribe() {\n if (state.eeDisableUnsubscribe) {\n state.eeDisableUnsubscribe();\n }\n\n if (state.eventHubUnsubscribe) {\n state.eventHubUnsubscribe();\n }\n\n strapi.cron.remove('deleteExpiredAuditLogs');\n\n return this;\n },\n\n destroy() {\n return this.unsubscribe();\n },\n };\n};\n\nexport { createAuditLogsLifecycleService };\n"],"names":["DEFAULT_RETENTION_DAYS","defaultEvents","getEventMap","events","reduce","acc","event","kind","getActor","systemOrigin","user","type","id","email","name","getDisplayName","getRetentionDays","strapi","featureConfig","ee","features","get","licenseRetentionDays","options","retentionDays","userRetentionDays","config","createAuditLogsLifecycleService","state","auditLogsService","eventMap","SYSTEM_ORIGIN_FLAGS","scheduler","SYSTEM_ORIGINS","Object","keys","processEvent","args","registration","rawEvent","requestState","requestContext","isUsingAdminAuth","route","info","auditSource","isMcpAdminAction","includes","undefined","allowsUnknownActor","allowUnknownActor","origin","date","Date","toISOString","userId","ignoredUids","uid","action","payload","actor","shape","transform","error","log","_action","_date","_actor","_origin","rest","handleEvent","processedEvent","saveEvent","registerEvent","Error","warn","register","eeEnableUnsubscribe","eventHub","on","destroy","eeUpdateUnsubscribe","eeDisableUnsubscribe","isEnabled","eventHubUnsubscribe","subscribe","cron","add","deleteExpiredAuditLogs","task","expirationDate","now","deleteExpiredEvents","unsubscribe","remove"],"mappings":"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"}