@strapi/admin 5.52.3 → 5.53.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.
- package/dist/admin/admin/src/translations/en.json.js +18 -0
- package/dist/admin/admin/src/translations/en.json.js.map +1 -1
- package/dist/admin/admin/src/translations/en.json.mjs +18 -0
- package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
- package/dist/admin/admin/src/utils/getFetchClient.js +118 -43
- package/dist/admin/admin/src/utils/getFetchClient.js.map +1 -1
- package/dist/admin/admin/src/utils/getFetchClient.mjs +118 -45
- package/dist/admin/admin/src/utils/getFetchClient.mjs.map +1 -1
- package/dist/admin/ee/admin/src/constants.js +6 -0
- package/dist/admin/ee/admin/src/constants.js.map +1 -1
- package/dist/admin/ee/admin/src/constants.mjs +6 -0
- package/dist/admin/ee/admin/src/constants.mjs.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.js +31 -3
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.js.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.mjs +33 -5
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.mjs.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.js +177 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.js.map +1 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.mjs +175 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.mjs.map +1 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.js +173 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.js.map +1 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.mjs +151 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.mjs.map +1 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js +10 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs +10 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs.map +1 -1
- package/dist/admin/index.js +2 -0
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/shared/utils/audit-log-export.js +16 -0
- package/dist/admin/shared/utils/audit-log-export.js.map +1 -0
- package/dist/admin/shared/utils/audit-log-export.mjs +9 -0
- package/dist/admin/shared/utils/audit-log-export.mjs.map +1 -0
- package/dist/admin/src/utils/getFetchClient.d.ts +9 -2
- package/dist/admin/tests/store.d.ts +4 -0
- package/dist/admin/tests/utils.d.ts +4 -0
- package/dist/ee/admin/src/constants.d.ts +4 -0
- package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.d.ts +10 -0
- package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.d.ts +18 -0
- package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.d.ts +9 -0
- package/dist/ee/server/src/audit-logs/controllers/audit-logs.d.ts +1 -0
- package/dist/ee/server/src/audit-logs/controllers/audit-logs.d.ts.map +1 -1
- package/dist/ee/server/src/audit-logs/routes/audit-logs.d.ts.map +1 -1
- package/dist/ee/server/src/audit-logs/services/audit-logs.d.ts +24 -3
- package/dist/ee/server/src/audit-logs/services/audit-logs.d.ts.map +1 -1
- package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts +8 -2
- package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts.map +1 -1
- package/dist/ee/server/src/audit-logs/utils/csv.d.ts +5 -0
- package/dist/ee/server/src/audit-logs/utils/csv.d.ts.map +1 -0
- package/dist/ee/server/src/audit-logs/utils/export-token.d.ts +5 -0
- package/dist/ee/server/src/audit-logs/utils/export-token.d.ts.map +1 -0
- package/dist/ee/server/src/audit-logs/utils.d.ts +10 -0
- package/dist/ee/server/src/audit-logs/utils.d.ts.map +1 -0
- package/dist/ee/server/src/audit-logs/validation/audit-logs.d.ts +2 -0
- package/dist/ee/server/src/audit-logs/validation/audit-logs.d.ts.map +1 -1
- package/dist/ee/server/src/config/admin-actions.d.ts.map +1 -1
- package/dist/ee/server/src/index.d.ts +1 -0
- package/dist/ee/server/src/index.d.ts.map +1 -1
- package/dist/server/ee/server/src/audit-logs/controllers/audit-logs.js +50 -0
- package/dist/server/ee/server/src/audit-logs/controllers/audit-logs.js.map +1 -1
- package/dist/server/ee/server/src/audit-logs/controllers/audit-logs.mjs +51 -1
- package/dist/server/ee/server/src/audit-logs/controllers/audit-logs.mjs.map +1 -1
- package/dist/server/ee/server/src/audit-logs/routes/audit-logs.js +13 -4
- package/dist/server/ee/server/src/audit-logs/routes/audit-logs.js.map +1 -1
- package/dist/server/ee/server/src/audit-logs/routes/audit-logs.mjs +13 -4
- package/dist/server/ee/server/src/audit-logs/routes/audit-logs.mjs.map +1 -1
- package/dist/server/ee/server/src/audit-logs/services/audit-logs.js +201 -7
- package/dist/server/ee/server/src/audit-logs/services/audit-logs.js.map +1 -1
- package/dist/server/ee/server/src/audit-logs/services/audit-logs.mjs +201 -8
- package/dist/server/ee/server/src/audit-logs/services/audit-logs.mjs.map +1 -1
- package/dist/server/ee/server/src/audit-logs/services/lifecycles.js +119 -34
- package/dist/server/ee/server/src/audit-logs/services/lifecycles.js.map +1 -1
- package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs +119 -34
- package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs.map +1 -1
- package/dist/server/ee/server/src/audit-logs/utils/csv.js +33 -0
- package/dist/server/ee/server/src/audit-logs/utils/csv.js.map +1 -0
- package/dist/server/ee/server/src/audit-logs/utils/csv.mjs +29 -0
- package/dist/server/ee/server/src/audit-logs/utils/csv.mjs.map +1 -0
- package/dist/server/ee/server/src/audit-logs/utils/export-token.js +33 -0
- package/dist/server/ee/server/src/audit-logs/utils/export-token.js.map +1 -0
- package/dist/server/ee/server/src/audit-logs/utils/export-token.mjs +29 -0
- package/dist/server/ee/server/src/audit-logs/utils/export-token.mjs.map +1 -0
- package/dist/server/ee/server/src/audit-logs/utils.js +14 -0
- package/dist/server/ee/server/src/audit-logs/utils.js.map +1 -0
- package/dist/server/ee/server/src/audit-logs/utils.mjs +12 -0
- package/dist/server/ee/server/src/audit-logs/utils.mjs.map +1 -0
- package/dist/server/ee/server/src/audit-logs/validation/audit-logs.js +11 -0
- package/dist/server/ee/server/src/audit-logs/validation/audit-logs.js.map +1 -1
- package/dist/server/ee/server/src/audit-logs/validation/audit-logs.mjs +11 -1
- package/dist/server/ee/server/src/audit-logs/validation/audit-logs.mjs.map +1 -1
- package/dist/server/ee/server/src/config/admin-actions.js +8 -0
- package/dist/server/ee/server/src/config/admin-actions.js.map +1 -1
- package/dist/server/ee/server/src/config/admin-actions.mjs +8 -0
- package/dist/server/ee/server/src/config/admin-actions.mjs.map +1 -1
- package/dist/server/ee/server/src/index.js +10 -0
- package/dist/server/ee/server/src/index.js.map +1 -1
- package/dist/server/ee/server/src/index.mjs +10 -0
- package/dist/server/ee/server/src/index.mjs.map +1 -1
- package/dist/server/shared/utils/audit-log-export.js +22 -0
- package/dist/server/shared/utils/audit-log-export.js.map +1 -0
- package/dist/server/shared/utils/audit-log-export.mjs +12 -0
- package/dist/server/shared/utils/audit-log-export.mjs.map +1 -0
- package/dist/shared/contracts/audit-logs.d.ts +15 -1
- package/dist/shared/contracts/audit-logs.d.ts.map +1 -1
- package/dist/shared/utils/audit-log-export.d.ts +9 -0
- package/dist/shared/utils/audit-log-export.d.ts.map +1 -0
- package/package.json +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit-logs.mjs","sources":["../../../../../../../ee/server/src/audit-logs/services/audit-logs.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\ninterface Event {\n action: string;\n date: Date;\n userId: string | number;\n payload: Record<string, unknown>;\n}\n\ninterface Log extends Omit<Event, 'userId'> {\n user: string | number;\n}\n\nconst getSanitizedUser = (user: any) => {\n let displayName = user.email;\n\n if (user.username) {\n displayName = user.username;\n } else if (user.firstname && user.lastname) {\n displayName = `${user.firstname} ${user.lastname}`;\n }\n\n return {\n id: user.id,\n email: user.email,\n displayName,\n };\n};\n\n/**\n * @description\n * Manages audit logs interaction with the database. Accessible via strapi.get('audit-logs')\n */\nconst createAuditLogsService = (strapi: Core.Strapi) => {\n return {\n async saveEvent(event: Event) {\n const { userId, ...rest } = event;\n\n const auditLog: Log = { ...rest, user: userId };\n\n // Save to database\n await strapi.db.query('admin::audit-log').create({ data: auditLog });\n\n return this;\n },\n\n async findMany(query: unknown) {\n // NOTE: We get the IDs first because sorting full rows runs MySQL/MariaDB out of sort memory\n // See: https://github.com/strapi/strapi/issues/27399\n const { results: logRows, pagination } = await strapi.db.query('admin::audit-log').findPage({\n ...strapi.get('query-params').transform('admin::audit-log', query),\n select: ['id'],\n });\n\n const ids = logRows.map((log) => log.id);\n const logs = ids.length\n ? await strapi.db.query('admin::audit-log').findMany({\n where: { id: { $in: ids } },\n populate: ['user'],\n select: ['action', 'date', 'payload'],\n })\n : [];\n const logsById = new Map(logs.map((log) => [log.id, log]));\n const results = ids.map((id) => logsById.get(id)).filter(Boolean);\n\n const sanitizedResults = results.map((result: any) => {\n const { user, ...rest } = result;\n return {\n ...rest,\n user: user ? getSanitizedUser(user) : null,\n };\n });\n\n return {\n results: sanitizedResults,\n pagination,\n };\n },\n\n async findManyUsers(query: { page?: number | string; pageSize?: number | string }) {\n const { page = 1, pageSize = 10 } = query;\n\n const userAttribute = strapi.db.metadata.get('admin::audit-log').attributes.user;\n\n if (\n userAttribute?.type !== 'relation' ||\n !('joinTable' in userAttribute) ||\n !userAttribute.joinTable ||\n !('inverseJoinColumn' in userAttribute.joinTable)\n ) {\n throw new Error('The audit log user relation is expected to use a join table');\n }\n\n const { joinTable } = userAttribute;\n\n const authorIds = await strapi.db\n .connection(joinTable.name)\n .distinct(joinTable.inverseJoinColumn.name)\n .pluck(joinTable.inverseJoinColumn.name);\n\n const { results, pagination } = await strapi.db.query('admin::user').findPage({\n select: ['id', 'email', 'username', 'firstname', 'lastname'],\n where: { id: { $in: authorIds } },\n orderBy: { id: 'asc' },\n page: Number(page),\n pageSize: Number(pageSize),\n });\n\n return {\n results: results.map(getSanitizedUser),\n pagination,\n };\n },\n\n async findOne(id: unknown) {\n const result: any = await strapi.db.query('admin::audit-log').findOne({\n where: { id },\n populate: ['user'],\n select: ['action', 'date', 'payload'],\n });\n\n if (!result) {\n return null;\n }\n\n const { user, ...rest } = result;\n return {\n ...rest,\n user: user ? getSanitizedUser(user) : null,\n };\n },\n\n deleteExpiredEvents(expirationDate: Date) {\n return strapi.db.query('admin::audit-log').deleteMany({\n where: {\n date: {\n $lt: expirationDate.toISOString(),\n },\n },\n });\n },\n };\n};\n\nexport { createAuditLogsService };\n"],"names":["getSanitizedUser","user","displayName","email","username","firstname","lastname","id","createAuditLogsService","strapi","saveEvent","event","userId","rest","auditLog","db","query","create","data","findMany","results","logRows","pagination","findPage","get","transform","select","ids","map","log","logs","length","where","$in","populate","logsById","Map","filter","Boolean","sanitizedResults","result","findManyUsers","page","pageSize","userAttribute","metadata","attributes","type","joinTable","Error","authorIds","connection","name","distinct","inverseJoinColumn","pluck","orderBy","Number","findOne","deleteExpiredEvents","expirationDate","deleteMany","date","$lt","toISOString"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"audit-logs.mjs","sources":["../../../../../../../ee/server/src/audit-logs/services/audit-logs.ts"],"sourcesContent":["import { Readable } from 'stream';\n\nimport type { Core } from '@strapi/types';\n\nimport {\n AUDIT_LOG_EXPORT_EVENT,\n AUDIT_LOGS_EXPORT_DEFAULT_MAX_ROWS,\n AUDIT_LOGS_EXPORT_PART_MAX_ROWS,\n AUDIT_LOGS_EXPORT_PART_ROWS,\n} from '../../../../../shared/utils/audit-log-export';\nimport { getDisplayName } from '../utils';\nimport { CSV_BOM, serializeCsvLine } from '../utils/csv';\nimport { signExportToken, verifyExportToken } from '../utils/export-token';\n\nconst EXPORT_CSV_COLUMNS = [\n 'id',\n 'action',\n 'date',\n 'user_id',\n 'user_email',\n 'user_display_name',\n 'origin',\n 'payload',\n];\nconst EXPORT_USER_COLUMNS = ['id', 'email', 'username', 'firstname', 'lastname'];\nconst EXPORT_BATCH_SIZE = 5000;\n\ninterface Event {\n action: string;\n date: Date;\n // Null for actions no person performed, such as a scheduled job\n userId: string | number | null;\n payload: Record<string, unknown>;\n}\n\ninterface Log extends Omit<Event, 'userId'> {\n user: string | number | null;\n}\n\nconst getSanitizedUser = (user: any) => {\n return {\n id: user.id,\n email: user.email,\n displayName: getDisplayName(user),\n };\n};\n\nconst serializeCsvPayload = (payload: unknown) => {\n if (payload === null || payload === undefined) {\n return null;\n }\n\n return typeof payload === 'string' ? payload : JSON.stringify(payload);\n};\n\nconst parseCsvPayload = (payload: unknown): Record<string, unknown> | null => {\n if (typeof payload === 'string') {\n try {\n return JSON.parse(payload);\n } catch {\n return null;\n }\n }\n\n return typeof payload === 'object' ? (payload as Record<string, unknown> | null) : null;\n};\n\ninterface ExportQuery {\n cursor?: number;\n pageSize?: number;\n until?: number;\n token?: string;\n [key: string]: unknown;\n}\n\nconst getExportSecret = (strapi: Core.Strapi): string => {\n const secret = strapi.config.get('admin.auth.secret');\n\n if (typeof secret !== 'string' || secret.length === 0) {\n throw new Error(\n 'The audit logs export requires admin.auth.secret to be set in config/admin.js.'\n );\n }\n\n return secret;\n};\n\nconst isTrustedExportContinuation = (strapi: Core.Strapi, query: ExportQuery) => {\n return (\n query.cursor !== undefined &&\n query.until !== undefined &&\n verifyExportToken(getExportSecret(strapi), query.token, query.until, query.filters)\n );\n};\n\nconst buildExportWhere = (filtersWhere: unknown, untilId: number, afterId: number) => ({\n $and: [\n filtersWhere ?? {},\n { id: { $lte: untilId } },\n ...(afterId > 0 ? [{ id: { $gt: afterId } }] : []),\n ],\n});\n\nconst toCsvLine = (row: any) => {\n const user = row.user ? getSanitizedUser(row.user) : null;\n const { payload } = row;\n\n return serializeCsvLine([\n row.id,\n row.action,\n row.date instanceof Date ? row.date.toISOString() : row.date,\n user?.id ?? null,\n user?.email ?? null,\n user?.displayName ?? null,\n parseCsvPayload(payload)?.origin ?? null,\n serializeCsvPayload(payload),\n ]);\n};\n\n/**\n * @description\n * Manages audit logs interaction with the database. Accessible via strapi.get('audit-logs')\n */\nconst createAuditLogsService = (strapi: Core.Strapi) => {\n return {\n async saveEvent(event: Event) {\n const { userId, ...rest } = event;\n\n const auditLog: Log = { ...rest, user: userId };\n\n // Save to database\n await strapi.db.query('admin::audit-log').create({ data: auditLog });\n\n return this;\n },\n\n async findMany(query: unknown) {\n // NOTE: We get the IDs first because sorting full rows runs MySQL/MariaDB out of sort memory\n // See: https://github.com/strapi/strapi/issues/27399\n const { results: logRows, pagination } = await strapi.db.query('admin::audit-log').findPage({\n ...strapi.get('query-params').transform('admin::audit-log', query),\n select: ['id'],\n });\n\n const ids = logRows.map((log) => log.id);\n const logs = ids.length\n ? await strapi.db.query('admin::audit-log').findMany({\n where: { id: { $in: ids } },\n populate: ['user'],\n select: ['action', 'date', 'payload'],\n })\n : [];\n const logsById = new Map(logs.map((log) => [log.id, log]));\n const results = ids.map((id) => logsById.get(id)).filter(Boolean);\n\n const sanitizedResults = results.map((result: any) => {\n const { user, ...rest } = result;\n return {\n ...rest,\n user: user ? getSanitizedUser(user) : null,\n };\n });\n\n return {\n results: sanitizedResults,\n pagination,\n };\n },\n\n async isExportTooLarge(query: { filters?: unknown }) {\n const maxRows = strapi.config.get(\n 'admin.auditLogs.exportMaxRows',\n AUDIT_LOGS_EXPORT_DEFAULT_MAX_ROWS\n );\n const { where } = strapi\n .get('query-params')\n .transform('admin::audit-log', { filters: query.filters ?? undefined });\n\n const beyondCap = await strapi.db.query('admin::audit-log').findMany({\n select: ['id'],\n where: where ?? {},\n orderBy: { id: 'asc' },\n offset: maxRows,\n limit: 1,\n });\n\n return beyondCap.length > 0;\n },\n\n isTrustedContinuation(query: ExportQuery) {\n return isTrustedExportContinuation(strapi, query);\n },\n\n async createExportStream(query: ExportQuery) {\n getExportSecret(strapi);\n\n const { cursor, pageSize, until, token, page: _page, sort: _sort, ...filtersQuery } = query;\n\n const configuredPartSize = strapi.config.get(\n 'admin.auditLogs.exportPartRows',\n AUDIT_LOGS_EXPORT_PART_ROWS\n );\n const partSize = Math.max(\n 1,\n Math.min(pageSize ?? configuredPartSize, AUDIT_LOGS_EXPORT_PART_MAX_ROWS)\n );\n\n const { where: filtersWhere } = strapi\n .get('query-params')\n .transform('admin::audit-log', filtersQuery);\n\n const isNewExport = !isTrustedExportContinuation(strapi, query);\n if (isNewExport) {\n await strapi.eventHub.emit(AUDIT_LOG_EXPORT_EVENT, {\n filters: filtersQuery.filters ?? null,\n });\n }\n\n let frozenUntil = isNewExport ? undefined : until;\n if (frozenUntil === undefined) {\n const [lastRow] = await strapi.db.query('admin::audit-log').findMany({\n select: ['id'],\n orderBy: { id: 'desc' },\n limit: 1,\n });\n\n frozenUntil = lastRow?.id ?? 0;\n }\n\n const untilId = frozenUntil ?? 0;\n const getWhere = (afterId: number) => buildExportWhere(filtersWhere, untilId, afterId);\n\n const boundary: Array<{ id: number }> = await strapi.db.query('admin::audit-log').findMany({\n select: ['id'],\n where: getWhere(cursor ?? 0),\n orderBy: { id: 'asc' },\n offset: partSize - 1,\n limit: 2,\n });\n\n const nextCursor = boundary.length > 1 ? boundary[0].id : null;\n\n const partUpperBound = nextCursor ?? untilId;\n\n async function* csvChunks() {\n if (isNewExport) {\n yield CSV_BOM + serializeCsvLine(EXPORT_CSV_COLUMNS);\n }\n\n let lastId = cursor ?? 0;\n let remaining = partSize;\n\n while (remaining > 0) {\n const batchLimit = Math.min(EXPORT_BATCH_SIZE, remaining);\n const rows: any[] = await strapi.db.query('admin::audit-log').findMany({\n select: ['id', 'action', 'date', 'payload'],\n populate: { user: { select: EXPORT_USER_COLUMNS } },\n where: buildExportWhere(filtersWhere, partUpperBound, lastId),\n orderBy: { id: 'asc' },\n limit: batchLimit,\n });\n\n if (rows.length === 0) {\n break;\n }\n\n yield rows.map(toCsvLine).join('');\n\n lastId = rows[rows.length - 1].id;\n remaining -= rows.length;\n\n if (rows.length < batchLimit) {\n break;\n }\n }\n }\n\n async function* loggedCsvChunks() {\n try {\n yield* csvChunks();\n } catch (error) {\n strapi.log.error(\n `Audit logs export failed after the response started, the CSV part is truncated: ${error}`\n );\n throw error;\n }\n }\n\n return {\n stream: Readable.from(loggedCsvChunks(), { objectMode: false, highWaterMark: 64 * 1024 }),\n nextCursor,\n until: untilId,\n isNewExport,\n partSize,\n exportToken: isNewExport\n ? signExportToken(getExportSecret(strapi), untilId, filtersQuery.filters)\n : (token as string),\n };\n },\n\n async findManyUsers(query: { page?: number | string; pageSize?: number | string }) {\n const { page = 1, pageSize = 10 } = query;\n\n const userAttribute = strapi.db.metadata.get('admin::audit-log').attributes.user;\n\n if (\n userAttribute?.type !== 'relation' ||\n !('joinTable' in userAttribute) ||\n !userAttribute.joinTable ||\n !('inverseJoinColumn' in userAttribute.joinTable)\n ) {\n throw new Error('The audit log user relation is expected to use a join table');\n }\n\n const { joinTable } = userAttribute;\n\n const authorIds = await strapi.db\n .connection(joinTable.name)\n .distinct(joinTable.inverseJoinColumn.name)\n .pluck(joinTable.inverseJoinColumn.name);\n\n const { results, pagination } = await strapi.db.query('admin::user').findPage({\n select: ['id', 'email', 'username', 'firstname', 'lastname'],\n where: { id: { $in: authorIds } },\n orderBy: { id: 'asc' },\n page: Number(page),\n pageSize: Number(pageSize),\n });\n\n return {\n results: results.map(getSanitizedUser),\n pagination,\n };\n },\n\n async findOne(id: unknown) {\n const result: any = await strapi.db.query('admin::audit-log').findOne({\n where: { id },\n populate: ['user'],\n select: ['action', 'date', 'payload'],\n });\n\n if (!result) {\n return null;\n }\n\n const { user, ...rest } = result;\n return {\n ...rest,\n user: user ? getSanitizedUser(user) : null,\n };\n },\n\n deleteExpiredEvents(expirationDate: Date) {\n return strapi.db.query('admin::audit-log').deleteMany({\n where: {\n date: {\n $lt: expirationDate.toISOString(),\n },\n },\n });\n },\n };\n};\n\nexport { createAuditLogsService, toCsvLine };\n"],"names":["EXPORT_CSV_COLUMNS","EXPORT_USER_COLUMNS","EXPORT_BATCH_SIZE","getSanitizedUser","user","id","email","displayName","getDisplayName","serializeCsvPayload","payload","undefined","JSON","stringify","parseCsvPayload","parse","getExportSecret","strapi","secret","config","get","length","Error","isTrustedExportContinuation","query","cursor","until","verifyExportToken","token","filters","buildExportWhere","filtersWhere","untilId","afterId","$and","$lte","$gt","toCsvLine","row","serializeCsvLine","action","date","Date","toISOString","origin","createAuditLogsService","saveEvent","event","userId","rest","auditLog","db","create","data","findMany","results","logRows","pagination","findPage","transform","select","ids","map","log","logs","where","$in","populate","logsById","Map","filter","Boolean","sanitizedResults","result","isExportTooLarge","maxRows","AUDIT_LOGS_EXPORT_DEFAULT_MAX_ROWS","beyondCap","orderBy","offset","limit","isTrustedContinuation","createExportStream","pageSize","page","_page","sort","_sort","filtersQuery","configuredPartSize","AUDIT_LOGS_EXPORT_PART_ROWS","partSize","Math","max","min","AUDIT_LOGS_EXPORT_PART_MAX_ROWS","isNewExport","eventHub","emit","AUDIT_LOG_EXPORT_EVENT","frozenUntil","lastRow","getWhere","boundary","nextCursor","partUpperBound","csvChunks","CSV_BOM","lastId","remaining","batchLimit","rows","join","loggedCsvChunks","error","stream","Readable","from","objectMode","highWaterMark","exportToken","signExportToken","findManyUsers","userAttribute","metadata","attributes","type","joinTable","authorIds","connection","name","distinct","inverseJoinColumn","pluck","Number","findOne","deleteExpiredEvents","expirationDate","deleteMany","$lt"],"mappings":";;;;;;AAcA,MAAMA,kBAAAA,GAAqB;AACzB,IAAA,IAAA;AACA,IAAA,QAAA;AACA,IAAA,MAAA;AACA,IAAA,SAAA;AACA,IAAA,YAAA;AACA,IAAA,mBAAA;AACA,IAAA,QAAA;AACA,IAAA;AACD,CAAA;AACD,MAAMC,mBAAAA,GAAsB;AAAC,IAAA,IAAA;AAAM,IAAA,OAAA;AAAS,IAAA,UAAA;AAAY,IAAA,WAAA;AAAa,IAAA;AAAW,CAAA;AAChF,MAAMC,iBAAAA,GAAoB,IAAA;AAc1B,MAAMC,mBAAmB,CAACC,IAAAA,GAAAA;IACxB,OAAO;AACLC,QAAAA,EAAAA,EAAID,KAAKC,EAAE;AACXC,QAAAA,KAAAA,EAAOF,KAAKE,KAAK;AACjBC,QAAAA,WAAAA,EAAaC,cAAAA,CAAeJ,IAAAA;AAC9B,KAAA;AACF,CAAA;AAEA,MAAMK,sBAAsB,CAACC,OAAAA,GAAAA;IAC3B,IAAIA,OAAAA,KAAY,IAAA,IAAQA,OAAAA,KAAYC,SAAAA,EAAW;QAC7C,OAAO,IAAA;AACT,IAAA;AAEA,IAAA,OAAO,OAAOD,OAAAA,KAAY,QAAA,GAAWA,OAAAA,GAAUE,IAAAA,CAAKC,SAAS,CAACH,OAAAA,CAAAA;AAChE,CAAA;AAEA,MAAMI,kBAAkB,CAACJ,OAAAA,GAAAA;IACvB,IAAI,OAAOA,YAAY,QAAA,EAAU;QAC/B,IAAI;YACF,OAAOE,IAAAA,CAAKG,KAAK,CAACL,OAAAA,CAAAA;AACpB,QAAA,CAAA,CAAE,OAAM;YACN,OAAO,IAAA;AACT,QAAA;AACF,IAAA;IAEA,OAAO,OAAOA,OAAAA,KAAY,QAAA,GAAYA,OAAAA,GAA6C,IAAA;AACrF,CAAA;AAUA,MAAMM,kBAAkB,CAACC,MAAAA,GAAAA;AACvB,IAAA,MAAMC,MAAAA,GAASD,MAAAA,CAAOE,MAAM,CAACC,GAAG,CAAC,mBAAA,CAAA;AAEjC,IAAA,IAAI,OAAOF,MAAAA,KAAW,QAAA,IAAYA,MAAAA,CAAOG,MAAM,KAAK,CAAA,EAAG;AACrD,QAAA,MAAM,IAAIC,KAAAA,CACR,gFAAA,CAAA;AAEJ,IAAA;IAEA,OAAOJ,MAAAA;AACT,CAAA;AAEA,MAAMK,2BAAAA,GAA8B,CAACN,MAAAA,EAAqBO,KAAAA,GAAAA;AACxD,IAAA,OACEA,MAAMC,MAAM,KAAKd,aACjBa,KAAAA,CAAME,KAAK,KAAKf,SAAAA,IAChBgB,iBAAAA,CAAkBX,eAAAA,CAAgBC,MAAAA,CAAAA,EAASO,MAAMI,KAAK,EAAEJ,MAAME,KAAK,EAAEF,MAAMK,OAAO,CAAA;AAEtF,CAAA;AAEA,MAAMC,gBAAAA,GAAmB,CAACC,YAAAA,EAAuBC,OAAAA,EAAiBC,WAAqB;QACrFC,IAAAA,EAAM;AACJH,YAAAA,YAAAA,IAAgB,EAAC;AACjB,YAAA;gBAAE1B,EAAAA,EAAI;oBAAE8B,IAAAA,EAAMH;AAAQ;AAAE,aAAA;AACpBC,YAAAA,GAAAA,OAAAA,GAAU,CAAA,GAAI;AAAC,gBAAA;oBAAE5B,EAAAA,EAAI;wBAAE+B,GAAAA,EAAKH;AAAQ;AAAE;AAAE,aAAA,GAAG;AAChD;KACH,CAAA;AAEA,MAAMI,YAAY,CAACC,GAAAA,GAAAA;AACjB,IAAA,MAAMlC,OAAOkC,GAAAA,CAAIlC,IAAI,GAAGD,gBAAAA,CAAiBmC,GAAAA,CAAIlC,IAAI,CAAA,GAAI,IAAA;IACrD,MAAM,EAAEM,OAAO,EAAE,GAAG4B,GAAAA;AAEpB,IAAA,OAAOC,gBAAAA,CAAiB;AACtBD,QAAAA,GAAAA,CAAIjC,EAAE;AACNiC,QAAAA,GAAAA,CAAIE,MAAM;QACVF,GAAAA,CAAIG,IAAI,YAAYC,IAAAA,GAAOJ,GAAAA,CAAIG,IAAI,CAACE,WAAW,EAAA,GAAKL,GAAAA,CAAIG,IAAI;AAC5DrC,QAAAA,IAAAA,EAAMC,EAAAA,IAAM,IAAA;AACZD,QAAAA,IAAAA,EAAME,KAAAA,IAAS,IAAA;AACfF,QAAAA,IAAAA,EAAMG,WAAAA,IAAe,IAAA;AACrBO,QAAAA,eAAAA,CAAgBJ,UAAUkC,MAAAA,IAAU,IAAA;QACpCnC,mBAAAA,CAAoBC,OAAAA;AACrB,KAAA,CAAA;AACH;AAEA;;;IAIA,MAAMmC,yBAAyB,CAAC5B,MAAAA,GAAAA;IAC9B,OAAO;AACL,QAAA,MAAM6B,WAAUC,KAAY,EAAA;AAC1B,YAAA,MAAM,EAAEC,MAAM,EAAE,GAAGC,MAAM,GAAGF,KAAAA;AAE5B,YAAA,MAAMG,QAAAA,GAAgB;AAAE,gBAAA,GAAGD,IAAI;gBAAE7C,IAAAA,EAAM4C;AAAO,aAAA;;AAG9C,YAAA,MAAM/B,OAAOkC,EAAE,CAAC3B,KAAK,CAAC,kBAAA,CAAA,CAAoB4B,MAAM,CAAC;gBAAEC,IAAAA,EAAMH;AAAS,aAAA,CAAA;AAElE,YAAA,OAAO,IAAI;AACb,QAAA,CAAA;AAEA,QAAA,MAAMI,UAAS9B,KAAc,EAAA;;;AAG3B,YAAA,MAAM,EAAE+B,OAAAA,EAASC,OAAO,EAAEC,UAAU,EAAE,GAAG,MAAMxC,MAAAA,CAAOkC,EAAE,CAAC3B,KAAK,CAAC,kBAAA,CAAA,CAAoBkC,QAAQ,CAAC;AAC1F,gBAAA,GAAGzC,OAAOG,GAAG,CAAC,gBAAgBuC,SAAS,CAAC,oBAAoBnC,KAAAA,CAAM;gBAClEoC,MAAAA,EAAQ;AAAC,oBAAA;AAAK;AAChB,aAAA,CAAA;AAEA,YAAA,MAAMC,MAAML,OAAAA,CAAQM,GAAG,CAAC,CAACC,GAAAA,GAAQA,IAAI1D,EAAE,CAAA;AACvC,YAAA,MAAM2D,IAAAA,GAAOH,GAAAA,CAAIxC,MAAM,GACnB,MAAMJ,MAAAA,CAAOkC,EAAE,CAAC3B,KAAK,CAAC,kBAAA,CAAA,CAAoB8B,QAAQ,CAAC;gBACjDW,KAAAA,EAAO;oBAAE5D,EAAAA,EAAI;wBAAE6D,GAAAA,EAAKL;AAAI;AAAE,iBAAA;gBAC1BM,QAAAA,EAAU;AAAC,oBAAA;AAAO,iBAAA;gBAClBP,MAAAA,EAAQ;AAAC,oBAAA,QAAA;AAAU,oBAAA,MAAA;AAAQ,oBAAA;AAAU;AACvC,aAAA,CAAA,GACA,EAAE;AACN,YAAA,MAAMQ,WAAW,IAAIC,GAAAA,CAAIL,KAAKF,GAAG,CAAC,CAACC,GAAAA,GAAQ;AAACA,oBAAAA,GAAAA,CAAI1D,EAAE;AAAE0D,oBAAAA;AAAI,iBAAA,CAAA,CAAA;YACxD,MAAMR,OAAAA,GAAUM,GAAAA,CAAIC,GAAG,CAAC,CAACzD,EAAAA,GAAO+D,QAAAA,CAAShD,GAAG,CAACf,EAAAA,CAAAA,CAAAA,CAAKiE,MAAM,CAACC,OAAAA,CAAAA;AAEzD,YAAA,MAAMC,gBAAAA,GAAmBjB,OAAAA,CAAQO,GAAG,CAAC,CAACW,MAAAA,GAAAA;AACpC,gBAAA,MAAM,EAAErE,IAAI,EAAE,GAAG6C,MAAM,GAAGwB,MAAAA;gBAC1B,OAAO;AACL,oBAAA,GAAGxB,IAAI;oBACP7C,IAAAA,EAAMA,IAAAA,GAAOD,iBAAiBC,IAAAA,CAAAA,GAAQ;AACxC,iBAAA;AACF,YAAA,CAAA,CAAA;YAEA,OAAO;gBACLmD,OAAAA,EAASiB,gBAAAA;AACTf,gBAAAA;AACF,aAAA;AACF,QAAA,CAAA;AAEA,QAAA,MAAMiB,kBAAiBlD,KAA4B,EAAA;AACjD,YAAA,MAAMmD,UAAU1D,MAAAA,CAAOE,MAAM,CAACC,GAAG,CAC/B,+BAAA,EACAwD,kCAAAA,CAAAA;YAEF,MAAM,EAAEX,KAAK,EAAE,GAAGhD,MAAAA,CACfG,GAAG,CAAC,cAAA,CAAA,CACJuC,SAAS,CAAC,kBAAA,EAAoB;gBAAE9B,OAAAA,EAASL,KAAAA,CAAMK,OAAO,IAAIlB;AAAU,aAAA,CAAA;YAEvE,MAAMkE,SAAAA,GAAY,MAAM5D,MAAAA,CAAOkC,EAAE,CAAC3B,KAAK,CAAC,kBAAA,CAAA,CAAoB8B,QAAQ,CAAC;gBACnEM,MAAAA,EAAQ;AAAC,oBAAA;AAAK,iBAAA;AACdK,gBAAAA,KAAAA,EAAOA,SAAS,EAAC;gBACjBa,OAAAA,EAAS;oBAAEzE,EAAAA,EAAI;AAAM,iBAAA;gBACrB0E,MAAAA,EAAQJ,OAAAA;gBACRK,KAAAA,EAAO;AACT,aAAA,CAAA;YAEA,OAAOH,SAAAA,CAAUxD,MAAM,GAAG,CAAA;AAC5B,QAAA,CAAA;AAEA4D,QAAAA,qBAAAA,CAAAA,CAAsBzD,KAAkB,EAAA;AACtC,YAAA,OAAOD,4BAA4BN,MAAAA,EAAQO,KAAAA,CAAAA;AAC7C,QAAA,CAAA;AAEA,QAAA,MAAM0D,oBAAmB1D,KAAkB,EAAA;YACzCR,eAAAA,CAAgBC,MAAAA,CAAAA;AAEhB,YAAA,MAAM,EAAEQ,MAAM,EAAE0D,QAAQ,EAAEzD,KAAK,EAAEE,KAAK,EAAEwD,IAAAA,EAAMC,KAAK,EAAEC,IAAAA,EAAMC,KAAK,EAAE,GAAGC,cAAc,GAAGhE,KAAAA;AAEtF,YAAA,MAAMiE,qBAAqBxE,MAAAA,CAAOE,MAAM,CAACC,GAAG,CAC1C,gCAAA,EACAsE,2BAAAA,CAAAA;YAEF,MAAMC,QAAAA,GAAWC,KAAKC,GAAG,CACvB,GACAD,IAAAA,CAAKE,GAAG,CAACX,QAAAA,IAAYM,kBAAAA,EAAoBM,+BAAAA,CAAAA,CAAAA;YAG3C,MAAM,EAAE9B,KAAAA,EAAOlC,YAAY,EAAE,GAAGd,MAAAA,CAC7BG,GAAG,CAAC,cAAA,CAAA,CACJuC,SAAS,CAAC,kBAAA,EAAoB6B,YAAAA,CAAAA;YAEjC,MAAMQ,WAAAA,GAAc,CAACzE,2BAAAA,CAA4BN,MAAAA,EAAQO,KAAAA,CAAAA;AACzD,YAAA,IAAIwE,WAAAA,EAAa;AACf,gBAAA,MAAM/E,MAAAA,CAAOgF,QAAQ,CAACC,IAAI,CAACC,sBAAAA,EAAwB;oBACjDtE,OAAAA,EAAS2D,YAAAA,CAAa3D,OAAO,IAAI;AACnC,iBAAA,CAAA;AACF,YAAA;YAEA,IAAIuE,WAAAA,GAAcJ,cAAcrF,SAAAA,GAAYe,KAAAA;AAC5C,YAAA,IAAI0E,gBAAgBzF,SAAAA,EAAW;gBAC7B,MAAM,CAAC0F,OAAAA,CAAQ,GAAG,MAAMpF,MAAAA,CAAOkC,EAAE,CAAC3B,KAAK,CAAC,kBAAA,CAAA,CAAoB8B,QAAQ,CAAC;oBACnEM,MAAAA,EAAQ;AAAC,wBAAA;AAAK,qBAAA;oBACdkB,OAAAA,EAAS;wBAAEzE,EAAAA,EAAI;AAAO,qBAAA;oBACtB2E,KAAAA,EAAO;AACT,iBAAA,CAAA;AAEAoB,gBAAAA,WAAAA,GAAcC,SAAShG,EAAAA,IAAM,CAAA;AAC/B,YAAA;AAEA,YAAA,MAAM2B,UAAUoE,WAAAA,IAAe,CAAA;AAC/B,YAAA,MAAME,QAAAA,GAAW,CAACrE,OAAAA,GAAoBH,gBAAAA,CAAiBC,cAAcC,OAAAA,EAASC,OAAAA,CAAAA;YAE9E,MAAMsE,QAAAA,GAAkC,MAAMtF,MAAAA,CAAOkC,EAAE,CAAC3B,KAAK,CAAC,kBAAA,CAAA,CAAoB8B,QAAQ,CAAC;gBACzFM,MAAAA,EAAQ;AAAC,oBAAA;AAAK,iBAAA;AACdK,gBAAAA,KAAAA,EAAOqC,SAAS7E,MAAAA,IAAU,CAAA,CAAA;gBAC1BqD,OAAAA,EAAS;oBAAEzE,EAAAA,EAAI;AAAM,iBAAA;AACrB0E,gBAAAA,MAAAA,EAAQY,QAAAA,GAAW,CAAA;gBACnBX,KAAAA,EAAO;AACT,aAAA,CAAA;YAEA,MAAMwB,UAAAA,GAAaD,QAAAA,CAASlF,MAAM,GAAG,CAAA,GAAIkF,QAAQ,CAAC,CAAA,CAAE,CAAClG,EAAE,GAAG,IAAA;AAE1D,YAAA,MAAMoG,iBAAiBD,UAAAA,IAAcxE,OAAAA;YAErC,gBAAgB0E,SAAAA,GAAAA;AACd,gBAAA,IAAIV,WAAAA,EAAa;AACf,oBAAA,MAAMW,UAAUpE,gBAAAA,CAAiBvC,kBAAAA,CAAAA;AACnC,gBAAA;AAEA,gBAAA,IAAI4G,SAASnF,MAAAA,IAAU,CAAA;AACvB,gBAAA,IAAIoF,SAAAA,GAAYlB,QAAAA;AAEhB,gBAAA,MAAOkB,YAAY,CAAA,CAAG;AACpB,oBAAA,MAAMC,UAAAA,GAAalB,IAAAA,CAAKE,GAAG,CAAC5F,iBAAAA,EAAmB2G,SAAAA,CAAAA;oBAC/C,MAAME,IAAAA,GAAc,MAAM9F,MAAAA,CAAOkC,EAAE,CAAC3B,KAAK,CAAC,kBAAA,CAAA,CAAoB8B,QAAQ,CAAC;wBACrEM,MAAAA,EAAQ;AAAC,4BAAA,IAAA;AAAM,4BAAA,QAAA;AAAU,4BAAA,MAAA;AAAQ,4BAAA;AAAU,yBAAA;wBAC3CO,QAAAA,EAAU;4BAAE/D,IAAAA,EAAM;gCAAEwD,MAAAA,EAAQ3D;AAAoB;AAAE,yBAAA;wBAClDgE,KAAAA,EAAOnC,gBAAAA,CAAiBC,cAAc0E,cAAAA,EAAgBG,MAAAA,CAAAA;wBACtD9B,OAAAA,EAAS;4BAAEzE,EAAAA,EAAI;AAAM,yBAAA;wBACrB2E,KAAAA,EAAO8B;AACT,qBAAA,CAAA;oBAEA,IAAIC,IAAAA,CAAK1F,MAAM,KAAK,CAAA,EAAG;AACrB,wBAAA;AACF,oBAAA;AAEA,oBAAA,MAAM0F,IAAAA,CAAKjD,GAAG,CAACzB,SAAAA,CAAAA,CAAW2E,IAAI,CAAC,EAAA,CAAA;AAE/BJ,oBAAAA,MAAAA,GAASG,IAAI,CAACA,IAAAA,CAAK1F,MAAM,GAAG,CAAA,CAAE,CAAChB,EAAE;AACjCwG,oBAAAA,SAAAA,IAAaE,KAAK1F,MAAM;oBAExB,IAAI0F,IAAAA,CAAK1F,MAAM,GAAGyF,UAAAA,EAAY;AAC5B,wBAAA;AACF,oBAAA;AACF,gBAAA;AACF,YAAA;YAEA,gBAAgBG,eAAAA,GAAAA;gBACd,IAAI;oBACF,OAAOP,SAAAA,EAAAA;AACT,gBAAA,CAAA,CAAE,OAAOQ,KAAAA,EAAO;AACdjG,oBAAAA,MAAAA,CAAO8C,GAAG,CAACmD,KAAK,CACd,CAAC,gFAAgF,EAAEA,KAAAA,CAAAA,CAAO,CAAA;oBAE5F,MAAMA,KAAAA;AACR,gBAAA;AACF,YAAA;YAEA,OAAO;gBACLC,MAAAA,EAAQC,QAAAA,CAASC,IAAI,CAACJ,eAAAA,EAAAA,EAAmB;oBAAEK,UAAAA,EAAY,KAAA;AAAOC,oBAAAA,aAAAA,EAAe,EAAA,GAAK;AAAK,iBAAA,CAAA;AACvFf,gBAAAA,UAAAA;gBACA9E,KAAAA,EAAOM,OAAAA;AACPgE,gBAAAA,WAAAA;AACAL,gBAAAA,QAAAA;AACA6B,gBAAAA,WAAAA,EAAaxB,cACTyB,eAAAA,CAAgBzG,eAAAA,CAAgBC,SAASe,OAAAA,EAASwD,YAAAA,CAAa3D,OAAO,CAAA,GACrED;AACP,aAAA;AACF,QAAA,CAAA;AAEA,QAAA,MAAM8F,eAAclG,KAA6D,EAAA;AAC/E,YAAA,MAAM,EAAE4D,IAAAA,GAAO,CAAC,EAAED,QAAAA,GAAW,EAAE,EAAE,GAAG3D,KAAAA;YAEpC,MAAMmG,aAAAA,GAAgB1G,MAAAA,CAAOkC,EAAE,CAACyE,QAAQ,CAACxG,GAAG,CAAC,kBAAA,CAAA,CAAoByG,UAAU,CAACzH,IAAI;AAEhF,YAAA,IACEuH,eAAeG,IAAAA,KAAS,UAAA,IACxB,EAAE,WAAA,IAAeH,aAAY,CAAA,IAC7B,CAACA,aAAAA,CAAcI,SAAS,IACxB,EAAE,uBAAuBJ,aAAAA,CAAcI,SAAS,CAAD,EAC/C;AACA,gBAAA,MAAM,IAAIzG,KAAAA,CAAM,6DAAA,CAAA;AAClB,YAAA;YAEA,MAAM,EAAEyG,SAAS,EAAE,GAAGJ,aAAAA;YAEtB,MAAMK,SAAAA,GAAY,MAAM/G,MAAAA,CAAOkC,EAAE,CAC9B8E,UAAU,CAACF,SAAAA,CAAUG,IAAI,CAAA,CACzBC,QAAQ,CAACJ,SAAAA,CAAUK,iBAAiB,CAACF,IAAI,CAAA,CACzCG,KAAK,CAACN,SAAAA,CAAUK,iBAAiB,CAACF,IAAI,CAAA;AAEzC,YAAA,MAAM,EAAE3E,OAAO,EAAEE,UAAU,EAAE,GAAG,MAAMxC,MAAAA,CAAOkC,EAAE,CAAC3B,KAAK,CAAC,aAAA,CAAA,CAAekC,QAAQ,CAAC;gBAC5EE,MAAAA,EAAQ;AAAC,oBAAA,IAAA;AAAM,oBAAA,OAAA;AAAS,oBAAA,UAAA;AAAY,oBAAA,WAAA;AAAa,oBAAA;AAAW,iBAAA;gBAC5DK,KAAAA,EAAO;oBAAE5D,EAAAA,EAAI;wBAAE6D,GAAAA,EAAK8D;AAAU;AAAE,iBAAA;gBAChClD,OAAAA,EAAS;oBAAEzE,EAAAA,EAAI;AAAM,iBAAA;AACrB+E,gBAAAA,IAAAA,EAAMkD,MAAAA,CAAOlD,IAAAA,CAAAA;AACbD,gBAAAA,QAAAA,EAAUmD,MAAAA,CAAOnD,QAAAA;AACnB,aAAA,CAAA;YAEA,OAAO;gBACL5B,OAAAA,EAASA,OAAAA,CAAQO,GAAG,CAAC3D,gBAAAA,CAAAA;AACrBsD,gBAAAA;AACF,aAAA;AACF,QAAA,CAAA;AAEA,QAAA,MAAM8E,SAAQlI,EAAW,EAAA;YACvB,MAAMoE,MAAAA,GAAc,MAAMxD,MAAAA,CAAOkC,EAAE,CAAC3B,KAAK,CAAC,kBAAA,CAAA,CAAoB+G,OAAO,CAAC;gBACpEtE,KAAAA,EAAO;AAAE5D,oBAAAA;AAAG,iBAAA;gBACZ8D,QAAAA,EAAU;AAAC,oBAAA;AAAO,iBAAA;gBAClBP,MAAAA,EAAQ;AAAC,oBAAA,QAAA;AAAU,oBAAA,MAAA;AAAQ,oBAAA;AAAU;AACvC,aAAA,CAAA;AAEA,YAAA,IAAI,CAACa,MAAAA,EAAQ;gBACX,OAAO,IAAA;AACT,YAAA;AAEA,YAAA,MAAM,EAAErE,IAAI,EAAE,GAAG6C,MAAM,GAAGwB,MAAAA;YAC1B,OAAO;AACL,gBAAA,GAAGxB,IAAI;gBACP7C,IAAAA,EAAMA,IAAAA,GAAOD,iBAAiBC,IAAAA,CAAAA,GAAQ;AACxC,aAAA;AACF,QAAA,CAAA;AAEAoI,QAAAA,mBAAAA,CAAAA,CAAoBC,cAAoB,EAAA;AACtC,YAAA,OAAOxH,OAAOkC,EAAE,CAAC3B,KAAK,CAAC,kBAAA,CAAA,CAAoBkH,UAAU,CAAC;gBACpDzE,KAAAA,EAAO;oBACLxB,IAAAA,EAAM;AACJkG,wBAAAA,GAAAA,EAAKF,eAAe9F,WAAW;AACjC;AACF;AACF,aAAA,CAAA;AACF,QAAA;AACF,KAAA;AACF;;;;"}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var utils = require('../utils.js');
|
|
4
|
+
|
|
3
5
|
const DEFAULT_RETENTION_DAYS = 90;
|
|
4
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Events audited before the payload standard; their stored shape is frozen for
|
|
8
|
+
* compatibility. Do not add events here: new events come through registerEvent().
|
|
9
|
+
* TODO: migrate these to the standard.
|
|
10
|
+
*/ const defaultEvents = [
|
|
5
11
|
'entry.create',
|
|
6
12
|
'entry.update',
|
|
7
13
|
'entry.delete',
|
|
@@ -31,11 +37,11 @@ const defaultEvents = [
|
|
|
31
37
|
'permission.update',
|
|
32
38
|
'permission.delete'
|
|
33
39
|
];
|
|
34
|
-
const getEventMap = (
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
const getEventMap = (events)=>{
|
|
41
|
+
return events.reduce((acc, event)=>{
|
|
42
|
+
acc[event] = {
|
|
43
|
+
kind: 'legacy'
|
|
44
|
+
};
|
|
39
45
|
return acc;
|
|
40
46
|
}, {});
|
|
41
47
|
};
|
|
@@ -56,55 +62,134 @@ const getRetentionDays = (strapi)=>{
|
|
|
56
62
|
};
|
|
57
63
|
/**
|
|
58
64
|
* @description
|
|
59
|
-
* Manages the lifecycle of audit logs. Accessible via strapi.get('audit-logs-
|
|
65
|
+
* Manages the lifecycle of audit logs. Accessible via strapi.get('audit-logs-lifecycle')
|
|
60
66
|
*/ const createAuditLogsLifecycleService = (strapi)=>{
|
|
61
67
|
// Manage internal service state privately
|
|
62
68
|
const state = {};
|
|
63
69
|
const auditLogsService = strapi.get('audit-logs');
|
|
64
|
-
// NOTE: providers should be able to replace getEventMap to add or remove events
|
|
65
70
|
const eventMap = getEventMap(defaultEvents);
|
|
66
|
-
|
|
71
|
+
/**
|
|
72
|
+
* The system origins accepted from the execution context; anything else needs a
|
|
73
|
+
* user. Keyed on the type, so extending SystemOrigin without gating it here fails
|
|
74
|
+
* to compile.
|
|
75
|
+
*/ const SYSTEM_ORIGIN_FLAGS = {
|
|
76
|
+
scheduler: true
|
|
77
|
+
};
|
|
78
|
+
const SYSTEM_ORIGINS = Object.keys(SYSTEM_ORIGIN_FLAGS);
|
|
79
|
+
const processEvent = async (name, ...args)=>{
|
|
80
|
+
const registration = eventMap[name];
|
|
81
|
+
if (!registration) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
const rawEvent = args[0];
|
|
67
85
|
const requestState = strapi.requestContext.get()?.state;
|
|
68
|
-
|
|
69
|
-
const isUsingAdminAuth = requestState?.route.info.type === 'admin';
|
|
86
|
+
const isUsingAdminAuth = requestState?.route?.info?.type === 'admin';
|
|
70
87
|
const auditSource = requestState?.auditSource;
|
|
71
88
|
const isMcpAdminAction = auditSource === 'mcp';
|
|
72
89
|
const user = requestState?.user;
|
|
73
|
-
|
|
90
|
+
const systemOrigin = auditSource && SYSTEM_ORIGINS.includes(auditSource) ? auditSource : undefined;
|
|
91
|
+
if (!systemOrigin && (!isUsingAdminAuth && !isMcpAdminAction || !user)) {
|
|
74
92
|
return null;
|
|
75
93
|
}
|
|
76
|
-
const origin = auditSource ?? 'admin';
|
|
77
|
-
const
|
|
78
|
-
//
|
|
79
|
-
|
|
80
|
-
|
|
94
|
+
const origin = systemOrigin ?? auditSource ?? 'admin-panel';
|
|
95
|
+
const date = new Date().toISOString();
|
|
96
|
+
// 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;
|
|
99
|
+
if (registration.kind === 'legacy') {
|
|
100
|
+
// TODO: What does this ignore in upload? Why would we want to ignore anything?
|
|
101
|
+
const ignoredUids = [
|
|
102
|
+
'plugin::upload.file',
|
|
103
|
+
'plugin::upload.folder'
|
|
104
|
+
];
|
|
105
|
+
if (ignoredUids.includes(rawEvent?.uid)) {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
action: name,
|
|
110
|
+
date,
|
|
111
|
+
payload: {
|
|
112
|
+
...rawEvent,
|
|
113
|
+
origin
|
|
114
|
+
},
|
|
115
|
+
userId
|
|
116
|
+
};
|
|
81
117
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
'
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
+
};
|
|
130
|
+
let shape = null;
|
|
131
|
+
try {
|
|
132
|
+
shape = await registration.transform(...args);
|
|
133
|
+
} catch (error) {
|
|
134
|
+
// If the transformer fails, we still keep the audit event: the row is saved
|
|
135
|
+
// with the subscriber's fields only.
|
|
136
|
+
strapi.log.error(`Failed to build the audit log payload for ${name}`, {
|
|
137
|
+
error
|
|
138
|
+
});
|
|
90
139
|
}
|
|
140
|
+
const { action: _action, date: _date, actor: _actor, origin: _origin, ...rest } = shape ?? {};
|
|
141
|
+
const payload = shape ? {
|
|
142
|
+
action: name,
|
|
143
|
+
date,
|
|
144
|
+
actor,
|
|
145
|
+
origin,
|
|
146
|
+
...rest
|
|
147
|
+
} : {
|
|
148
|
+
action: name,
|
|
149
|
+
date,
|
|
150
|
+
actor,
|
|
151
|
+
origin
|
|
152
|
+
};
|
|
91
153
|
return {
|
|
92
154
|
action: name,
|
|
93
|
-
date
|
|
94
|
-
payload
|
|
95
|
-
|
|
96
|
-
origin
|
|
97
|
-
},
|
|
98
|
-
userId: user.id
|
|
155
|
+
date,
|
|
156
|
+
payload,
|
|
157
|
+
userId
|
|
99
158
|
};
|
|
100
159
|
};
|
|
101
160
|
const handleEvent = async (name, ...args)=>{
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
161
|
+
try {
|
|
162
|
+
const processedEvent = await processEvent(name, ...args);
|
|
163
|
+
if (processedEvent) {
|
|
164
|
+
await auditLogsService.saveEvent(processedEvent);
|
|
165
|
+
}
|
|
166
|
+
} catch (error) {
|
|
167
|
+
// Logged, not propagated: most emitters fire and forget (the document service
|
|
168
|
+
// emits entry.* from an unawaited onCommit callback), and a rejection with no
|
|
169
|
+
// one awaiting it takes the process down. Audit logging is therefore fail-open:
|
|
170
|
+
// the entry is lost and only this line records it.
|
|
171
|
+
strapi.log.error(`Failed to save the audit log entry for ${name}`, {
|
|
172
|
+
error
|
|
173
|
+
});
|
|
105
174
|
}
|
|
106
175
|
};
|
|
107
176
|
return {
|
|
177
|
+
/**
|
|
178
|
+
* Adds an event to the list of audited events. Plugins register their own from
|
|
179
|
+
* their bootstrap; the transformer builds the audited shape
|
|
180
|
+
* ({resource, details, outcome}) from the arguments passed to eventHub.emit().
|
|
181
|
+
*/ registerEvent (name, transform) {
|
|
182
|
+
if (eventMap[name]?.kind === 'legacy') {
|
|
183
|
+
throw new Error(`Cannot register the audit log event "${name}": it is one of the built-in events, whose stored shape is frozen.`);
|
|
184
|
+
}
|
|
185
|
+
if (eventMap[name]) {
|
|
186
|
+
strapi.log.warn(`The audit log event "${name}" was already registered and is replaced.`);
|
|
187
|
+
}
|
|
188
|
+
eventMap[name] = {
|
|
189
|
+
kind: 'standard',
|
|
190
|
+
transform: transform
|
|
191
|
+
};
|
|
192
|
+
},
|
|
108
193
|
async register () {
|
|
109
194
|
// Handle license being enabled
|
|
110
195
|
if (!state.eeEnableUnsubscribe) {
|
|
@@ -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\nconst DEFAULT_RETENTION_DAYS = 90;\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\nconst getEventMap = (defaultEvents: any) => {\n const getDefaultPayload = (...args: any) => args[0];\n\n // Use the default payload for all default events\n return defaultEvents.reduce((acc: any, event: any) => {\n acc[event] = getDefaultPayload;\n return acc;\n }, {} as any);\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-lifecycles')\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 // NOTE: providers should be able to replace getEventMap to add or remove events\n const eventMap = getEventMap(defaultEvents);\n\n const processEvent = (name: string, ...args: any) => {\n const requestState = strapi.requestContext.get()?.state;\n\n // Only audit admin-authenticated actions, plus MCP actions flagged via auditSource.\n const isUsingAdminAuth = requestState?.route.info.type === 'admin';\n const auditSource = requestState?.auditSource;\n const isMcpAdminAction = auditSource === 'mcp';\n const user = requestState?.user;\n if ((!isUsingAdminAuth && !isMcpAdminAction) || !user) {\n return null;\n }\n\n const origin: Modules.AuditLogs.AuditSource = auditSource ?? 'admin';\n\n const getPayload = eventMap[name];\n\n // Ignore the event if it's not in the map\n if (!getPayload) {\n return null;\n }\n\n // Ignore some events based on payload\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(args[0]?.uid)) {\n return null;\n }\n\n return {\n action: name,\n date: new Date().toISOString(),\n payload: { ...getPayload(...args), origin },\n userId: user.id,\n };\n };\n\n const handleEvent = async (name: string, ...args: any) => {\n const processedEvent = processEvent(name, ...args);\n\n if (processedEvent) {\n await auditLogsService.saveEvent(processedEvent);\n }\n };\n\n return {\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","getDefaultPayload","args","reduce","acc","event","getRetentionDays","strapi","featureConfig","ee","features","get","licenseRetentionDays","options","retentionDays","userRetentionDays","config","createAuditLogsLifecycleService","state","auditLogsService","eventMap","processEvent","name","requestState","requestContext","isUsingAdminAuth","route","info","type","auditSource","isMcpAdminAction","user","origin","getPayload","ignoredUids","includes","uid","action","date","Date","toISOString","payload","userId","id","handleEvent","processedEvent","saveEvent","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 * 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,5 +1,11 @@
|
|
|
1
|
+
import { getDisplayName } from '../utils.mjs';
|
|
2
|
+
|
|
1
3
|
const DEFAULT_RETENTION_DAYS = 90;
|
|
2
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Events audited before the payload standard; their stored shape is frozen for
|
|
6
|
+
* compatibility. Do not add events here: new events come through registerEvent().
|
|
7
|
+
* TODO: migrate these to the standard.
|
|
8
|
+
*/ const defaultEvents = [
|
|
3
9
|
'entry.create',
|
|
4
10
|
'entry.update',
|
|
5
11
|
'entry.delete',
|
|
@@ -29,11 +35,11 @@ const defaultEvents = [
|
|
|
29
35
|
'permission.update',
|
|
30
36
|
'permission.delete'
|
|
31
37
|
];
|
|
32
|
-
const getEventMap = (
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
const getEventMap = (events)=>{
|
|
39
|
+
return events.reduce((acc, event)=>{
|
|
40
|
+
acc[event] = {
|
|
41
|
+
kind: 'legacy'
|
|
42
|
+
};
|
|
37
43
|
return acc;
|
|
38
44
|
}, {});
|
|
39
45
|
};
|
|
@@ -54,55 +60,134 @@ const getRetentionDays = (strapi)=>{
|
|
|
54
60
|
};
|
|
55
61
|
/**
|
|
56
62
|
* @description
|
|
57
|
-
* Manages the lifecycle of audit logs. Accessible via strapi.get('audit-logs-
|
|
63
|
+
* Manages the lifecycle of audit logs. Accessible via strapi.get('audit-logs-lifecycle')
|
|
58
64
|
*/ const createAuditLogsLifecycleService = (strapi)=>{
|
|
59
65
|
// Manage internal service state privately
|
|
60
66
|
const state = {};
|
|
61
67
|
const auditLogsService = strapi.get('audit-logs');
|
|
62
|
-
// NOTE: providers should be able to replace getEventMap to add or remove events
|
|
63
68
|
const eventMap = getEventMap(defaultEvents);
|
|
64
|
-
|
|
69
|
+
/**
|
|
70
|
+
* The system origins accepted from the execution context; anything else needs a
|
|
71
|
+
* user. Keyed on the type, so extending SystemOrigin without gating it here fails
|
|
72
|
+
* to compile.
|
|
73
|
+
*/ const SYSTEM_ORIGIN_FLAGS = {
|
|
74
|
+
scheduler: true
|
|
75
|
+
};
|
|
76
|
+
const SYSTEM_ORIGINS = Object.keys(SYSTEM_ORIGIN_FLAGS);
|
|
77
|
+
const processEvent = async (name, ...args)=>{
|
|
78
|
+
const registration = eventMap[name];
|
|
79
|
+
if (!registration) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
const rawEvent = args[0];
|
|
65
83
|
const requestState = strapi.requestContext.get()?.state;
|
|
66
|
-
|
|
67
|
-
const isUsingAdminAuth = requestState?.route.info.type === 'admin';
|
|
84
|
+
const isUsingAdminAuth = requestState?.route?.info?.type === 'admin';
|
|
68
85
|
const auditSource = requestState?.auditSource;
|
|
69
86
|
const isMcpAdminAction = auditSource === 'mcp';
|
|
70
87
|
const user = requestState?.user;
|
|
71
|
-
|
|
88
|
+
const systemOrigin = auditSource && SYSTEM_ORIGINS.includes(auditSource) ? auditSource : undefined;
|
|
89
|
+
if (!systemOrigin && (!isUsingAdminAuth && !isMcpAdminAction || !user)) {
|
|
72
90
|
return null;
|
|
73
91
|
}
|
|
74
|
-
const origin = auditSource ?? 'admin';
|
|
75
|
-
const
|
|
76
|
-
//
|
|
77
|
-
|
|
78
|
-
|
|
92
|
+
const origin = systemOrigin ?? auditSource ?? 'admin-panel';
|
|
93
|
+
const date = new Date().toISOString();
|
|
94
|
+
// Scheduled actions have no user, so a null user is expected. The earlier audit
|
|
95
|
+
// entry that set the schedule records who did it.
|
|
96
|
+
const userId = systemOrigin ? null : user.id;
|
|
97
|
+
if (registration.kind === 'legacy') {
|
|
98
|
+
// TODO: What does this ignore in upload? Why would we want to ignore anything?
|
|
99
|
+
const ignoredUids = [
|
|
100
|
+
'plugin::upload.file',
|
|
101
|
+
'plugin::upload.folder'
|
|
102
|
+
];
|
|
103
|
+
if (ignoredUids.includes(rawEvent?.uid)) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
action: name,
|
|
108
|
+
date,
|
|
109
|
+
payload: {
|
|
110
|
+
...rawEvent,
|
|
111
|
+
origin
|
|
112
|
+
},
|
|
113
|
+
userId
|
|
114
|
+
};
|
|
79
115
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
'
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
116
|
+
const actor = systemOrigin ? {
|
|
117
|
+
type: 'system'
|
|
118
|
+
} : {
|
|
119
|
+
type: 'admin-user',
|
|
120
|
+
// We copy the user data into the row so the history stays unchanged if the
|
|
121
|
+
// user changes later
|
|
122
|
+
user: {
|
|
123
|
+
id: user.id,
|
|
124
|
+
email: user.email,
|
|
125
|
+
name: getDisplayName(user)
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
let shape = null;
|
|
129
|
+
try {
|
|
130
|
+
shape = await registration.transform(...args);
|
|
131
|
+
} catch (error) {
|
|
132
|
+
// If the transformer fails, we still keep the audit event: the row is saved
|
|
133
|
+
// with the subscriber's fields only.
|
|
134
|
+
strapi.log.error(`Failed to build the audit log payload for ${name}`, {
|
|
135
|
+
error
|
|
136
|
+
});
|
|
88
137
|
}
|
|
138
|
+
const { action: _action, date: _date, actor: _actor, origin: _origin, ...rest } = shape ?? {};
|
|
139
|
+
const payload = shape ? {
|
|
140
|
+
action: name,
|
|
141
|
+
date,
|
|
142
|
+
actor,
|
|
143
|
+
origin,
|
|
144
|
+
...rest
|
|
145
|
+
} : {
|
|
146
|
+
action: name,
|
|
147
|
+
date,
|
|
148
|
+
actor,
|
|
149
|
+
origin
|
|
150
|
+
};
|
|
89
151
|
return {
|
|
90
152
|
action: name,
|
|
91
|
-
date
|
|
92
|
-
payload
|
|
93
|
-
|
|
94
|
-
origin
|
|
95
|
-
},
|
|
96
|
-
userId: user.id
|
|
153
|
+
date,
|
|
154
|
+
payload,
|
|
155
|
+
userId
|
|
97
156
|
};
|
|
98
157
|
};
|
|
99
158
|
const handleEvent = async (name, ...args)=>{
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
159
|
+
try {
|
|
160
|
+
const processedEvent = await processEvent(name, ...args);
|
|
161
|
+
if (processedEvent) {
|
|
162
|
+
await auditLogsService.saveEvent(processedEvent);
|
|
163
|
+
}
|
|
164
|
+
} catch (error) {
|
|
165
|
+
// Logged, not propagated: most emitters fire and forget (the document service
|
|
166
|
+
// emits entry.* from an unawaited onCommit callback), and a rejection with no
|
|
167
|
+
// one awaiting it takes the process down. Audit logging is therefore fail-open:
|
|
168
|
+
// the entry is lost and only this line records it.
|
|
169
|
+
strapi.log.error(`Failed to save the audit log entry for ${name}`, {
|
|
170
|
+
error
|
|
171
|
+
});
|
|
103
172
|
}
|
|
104
173
|
};
|
|
105
174
|
return {
|
|
175
|
+
/**
|
|
176
|
+
* Adds an event to the list of audited events. Plugins register their own from
|
|
177
|
+
* their bootstrap; the transformer builds the audited shape
|
|
178
|
+
* ({resource, details, outcome}) from the arguments passed to eventHub.emit().
|
|
179
|
+
*/ registerEvent (name, transform) {
|
|
180
|
+
if (eventMap[name]?.kind === 'legacy') {
|
|
181
|
+
throw new Error(`Cannot register the audit log event "${name}": it is one of the built-in events, whose stored shape is frozen.`);
|
|
182
|
+
}
|
|
183
|
+
if (eventMap[name]) {
|
|
184
|
+
strapi.log.warn(`The audit log event "${name}" was already registered and is replaced.`);
|
|
185
|
+
}
|
|
186
|
+
eventMap[name] = {
|
|
187
|
+
kind: 'standard',
|
|
188
|
+
transform: transform
|
|
189
|
+
};
|
|
190
|
+
},
|
|
106
191
|
async register () {
|
|
107
192
|
// Handle license being enabled
|
|
108
193
|
if (!state.eeEnableUnsubscribe) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycles.mjs","sources":["../../../../../../../ee/server/src/audit-logs/services/lifecycles.ts"],"sourcesContent":["import type { Core, Modules } from '@strapi/types';\n\nconst DEFAULT_RETENTION_DAYS = 90;\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\nconst getEventMap = (defaultEvents: any) => {\n const getDefaultPayload = (...args: any) => args[0];\n\n // Use the default payload for all default events\n return defaultEvents.reduce((acc: any, event: any) => {\n acc[event] = getDefaultPayload;\n return acc;\n }, {} as any);\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-lifecycles')\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 // NOTE: providers should be able to replace getEventMap to add or remove events\n const eventMap = getEventMap(defaultEvents);\n\n const processEvent = (name: string, ...args: any) => {\n const requestState = strapi.requestContext.get()?.state;\n\n // Only audit admin-authenticated actions, plus MCP actions flagged via auditSource.\n const isUsingAdminAuth = requestState?.route.info.type === 'admin';\n const auditSource = requestState?.auditSource;\n const isMcpAdminAction = auditSource === 'mcp';\n const user = requestState?.user;\n if ((!isUsingAdminAuth && !isMcpAdminAction) || !user) {\n return null;\n }\n\n const origin: Modules.AuditLogs.AuditSource = auditSource ?? 'admin';\n\n const getPayload = eventMap[name];\n\n // Ignore the event if it's not in the map\n if (!getPayload) {\n return null;\n }\n\n // Ignore some events based on payload\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(args[0]?.uid)) {\n return null;\n }\n\n return {\n action: name,\n date: new Date().toISOString(),\n payload: { ...getPayload(...args), origin },\n userId: user.id,\n };\n };\n\n const handleEvent = async (name: string, ...args: any) => {\n const processedEvent = processEvent(name, ...args);\n\n if (processedEvent) {\n await auditLogsService.saveEvent(processedEvent);\n }\n };\n\n return {\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","getDefaultPayload","args","reduce","acc","event","getRetentionDays","strapi","featureConfig","ee","features","get","licenseRetentionDays","options","retentionDays","userRetentionDays","config","createAuditLogsLifecycleService","state","auditLogsService","eventMap","processEvent","name","requestState","requestContext","isUsingAdminAuth","route","info","type","auditSource","isMcpAdminAction","user","origin","getPayload","ignoredUids","includes","uid","action","date","Date","toISOString","payload","userId","id","handleEvent","processedEvent","saveEvent","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.mjs","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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"}
|