@oneuptime/common 10.0.67 → 10.0.69

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 (88) hide show
  1. package/Models/AnalyticsModels/AuditLog.ts +370 -0
  2. package/Models/DatabaseModels/Alert.ts +2 -0
  3. package/Models/DatabaseModels/ApiKey.ts +2 -0
  4. package/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.ts +3 -0
  5. package/Models/DatabaseModels/Incident.ts +2 -0
  6. package/Models/DatabaseModels/KubernetesResource.ts +19 -0
  7. package/Models/DatabaseModels/Label.ts +2 -0
  8. package/Models/DatabaseModels/Monitor.ts +2 -0
  9. package/Models/DatabaseModels/OnCallDutyPolicy.ts +2 -0
  10. package/Models/DatabaseModels/Project.ts +80 -0
  11. package/Models/DatabaseModels/ScheduledMaintenance.ts +2 -0
  12. package/Models/DatabaseModels/StatusPage.ts +2 -0
  13. package/Models/DatabaseModels/Team.ts +2 -0
  14. package/Models/DatabaseModels/UserTelegram.ts +1 -1
  15. package/Server/API/KubernetesResourceAPI.ts +2 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1776801030808-MigrationName.ts +35 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1776865086264-MigrationName.ts +14 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
  19. package/Server/Services/AuditLogService.ts +574 -0
  20. package/Server/Services/DatabaseService.ts +103 -0
  21. package/Server/Services/Index.ts +2 -0
  22. package/Server/Services/KubernetesResourceService.ts +300 -8
  23. package/Server/Utils/VM/VMRunner.ts +39 -22
  24. package/Types/AnalyticsDatabase/AnalyticsTableName.ts +1 -0
  25. package/Types/AuditLog/AuditLogAction.ts +7 -0
  26. package/Types/BaseDatabase/EnableAuditLogOn.ts +5 -0
  27. package/Types/Database/EnableAuditLog.ts +18 -0
  28. package/Types/IsolatedVM/ReturnResult.ts +6 -0
  29. package/Types/Kubernetes/KubernetesInventoryExtractor.ts +15 -1
  30. package/Types/Permission.ts +13 -0
  31. package/build/dist/Models/AnalyticsModels/AuditLog.js +337 -0
  32. package/build/dist/Models/AnalyticsModels/AuditLog.js.map +1 -0
  33. package/build/dist/Models/DatabaseModels/Alert.js +2 -0
  34. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  35. package/build/dist/Models/DatabaseModels/ApiKey.js +2 -0
  36. package/build/dist/Models/DatabaseModels/ApiKey.js.map +1 -1
  37. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js.map +1 -1
  38. package/build/dist/Models/DatabaseModels/Incident.js +2 -0
  39. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  40. package/build/dist/Models/DatabaseModels/KubernetesResource.js +20 -0
  41. package/build/dist/Models/DatabaseModels/KubernetesResource.js.map +1 -1
  42. package/build/dist/Models/DatabaseModels/Label.js +2 -0
  43. package/build/dist/Models/DatabaseModels/Label.js.map +1 -1
  44. package/build/dist/Models/DatabaseModels/Monitor.js +2 -0
  45. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  46. package/build/dist/Models/DatabaseModels/OnCallDutyPolicy.js +2 -0
  47. package/build/dist/Models/DatabaseModels/OnCallDutyPolicy.js.map +1 -1
  48. package/build/dist/Models/DatabaseModels/Project.js +82 -0
  49. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  50. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +2 -0
  51. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  52. package/build/dist/Models/DatabaseModels/StatusPage.js +2 -0
  53. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  54. package/build/dist/Models/DatabaseModels/Team.js +2 -0
  55. package/build/dist/Models/DatabaseModels/Team.js.map +1 -1
  56. package/build/dist/Models/DatabaseModels/UserTelegram.js +1 -1
  57. package/build/dist/Models/DatabaseModels/UserTelegram.js.map +1 -1
  58. package/build/dist/Server/API/KubernetesResourceAPI.js +2 -0
  59. package/build/dist/Server/API/KubernetesResourceAPI.js.map +1 -1
  60. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776801030808-MigrationName.js +18 -0
  61. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776801030808-MigrationName.js.map +1 -0
  62. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776865086264-MigrationName.js +12 -0
  63. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776865086264-MigrationName.js.map +1 -0
  64. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
  65. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  66. package/build/dist/Server/Services/AuditLogService.js +402 -0
  67. package/build/dist/Server/Services/AuditLogService.js.map +1 -0
  68. package/build/dist/Server/Services/DatabaseService.js +79 -8
  69. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  70. package/build/dist/Server/Services/Index.js +2 -0
  71. package/build/dist/Server/Services/Index.js.map +1 -1
  72. package/build/dist/Server/Services/KubernetesResourceService.js +202 -8
  73. package/build/dist/Server/Services/KubernetesResourceService.js.map +1 -1
  74. package/build/dist/Server/Utils/VM/VMRunner.js +33 -19
  75. package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
  76. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +1 -0
  77. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
  78. package/build/dist/Types/AuditLog/AuditLogAction.js +8 -0
  79. package/build/dist/Types/AuditLog/AuditLogAction.js.map +1 -0
  80. package/build/dist/Types/BaseDatabase/EnableAuditLogOn.js +2 -0
  81. package/build/dist/Types/BaseDatabase/EnableAuditLogOn.js.map +1 -0
  82. package/build/dist/Types/Database/EnableAuditLog.js +15 -0
  83. package/build/dist/Types/Database/EnableAuditLog.js.map +1 -0
  84. package/build/dist/Types/Kubernetes/KubernetesInventoryExtractor.js +7 -1
  85. package/build/dist/Types/Kubernetes/KubernetesInventoryExtractor.js.map +1 -1
  86. package/build/dist/Types/Permission.js +11 -0
  87. package/build/dist/Types/Permission.js.map +1 -1
  88. package/package.json +1 -1
@@ -0,0 +1,402 @@
1
+ import AnalyticsDatabaseService from "./AnalyticsDatabaseService";
2
+ import ProjectService from "./ProjectService";
3
+ import { IsBillingEnabled, IsEnterpriseEdition } from "../EnvironmentConfig";
4
+ import logger from "../Utils/Logger";
5
+ import AuditLog from "../../Models/AnalyticsModels/AuditLog";
6
+ import AuditLogAction from "../../Types/AuditLog/AuditLogAction";
7
+ import { PlanType } from "../../Types/Billing/SubscriptionPlan";
8
+ import { getColumnAccessControlForAllColumns } from "../../Types/Database/AccessControl/ColumnAccessControl";
9
+ import ObjectID from "../../Types/ObjectID";
10
+ import UserType from "../../Types/UserType";
11
+ import UserService from "./UserService";
12
+ import OneUptimeDate from "../../Types/Date";
13
+ const PROJECT_SETTINGS_CACHE_TTL_MS = 60 * 1000;
14
+ const USER_CACHE_TTL_MS = 5 * 60 * 1000;
15
+ const SKIPPED_FIELDS = new Set([
16
+ "_id",
17
+ "id",
18
+ "createdAt",
19
+ "updatedAt",
20
+ "deletedAt",
21
+ "version",
22
+ "slug",
23
+ ]);
24
+ const NAME_CANDIDATE_FIELDS = [
25
+ "name",
26
+ "title",
27
+ "displayName",
28
+ ];
29
+ export class AuditLogService extends AnalyticsDatabaseService {
30
+ constructor(clickhouseDatabase) {
31
+ super({ modelType: AuditLog, database: clickhouseDatabase });
32
+ this.projectSettingsCache = new Map();
33
+ this.userCache = new Map();
34
+ }
35
+ invalidateProjectSettings(projectId) {
36
+ this.projectSettingsCache.delete(projectId.toString());
37
+ }
38
+ async recordCreate(data) {
39
+ var _a;
40
+ try {
41
+ const projectId = this.resolveProjectId(data.model, data.createdItem, data.props);
42
+ if (!projectId) {
43
+ return;
44
+ }
45
+ const settings = await this.getProjectSettings(projectId);
46
+ if (!this.isEligible(settings, data.props)) {
47
+ return;
48
+ }
49
+ const redactedFields = this.getRedactedFields(data.model);
50
+ const changes = this.buildSnapshotChanges({
51
+ model: data.createdItem,
52
+ redactedFields,
53
+ valueKey: "newValue",
54
+ });
55
+ await this.insert({
56
+ projectId,
57
+ resourceType: this.getResourceType(data.model),
58
+ resourceId: (_a = data.createdItem.id) !== null && _a !== void 0 ? _a : null,
59
+ resourceName: this.getResourceName(data.createdItem),
60
+ action: AuditLogAction.Create,
61
+ changes,
62
+ props: data.props,
63
+ retentionInDays: settings.retentionInDays,
64
+ });
65
+ }
66
+ catch (err) {
67
+ logger.warn("AuditLog: failed to record create event");
68
+ logger.warn(err);
69
+ }
70
+ }
71
+ async recordUpdate(data) {
72
+ try {
73
+ const projectId = this.resolveProjectId(data.model, data.before, data.props);
74
+ if (!projectId) {
75
+ return;
76
+ }
77
+ const settings = await this.getProjectSettings(projectId);
78
+ if (!this.isEligible(settings, data.props)) {
79
+ return;
80
+ }
81
+ const redactedFields = this.getRedactedFields(data.model);
82
+ const changes = this.buildUpdateDiff({
83
+ before: data.before,
84
+ updatedFields: data.updatedFields,
85
+ redactedFields,
86
+ });
87
+ if (changes.length === 0) {
88
+ return;
89
+ }
90
+ await this.insert({
91
+ projectId,
92
+ resourceType: this.getResourceType(data.model),
93
+ resourceId: data.itemId,
94
+ resourceName: this.getResourceName(data.before),
95
+ action: AuditLogAction.Update,
96
+ changes,
97
+ props: data.props,
98
+ retentionInDays: settings.retentionInDays,
99
+ });
100
+ }
101
+ catch (err) {
102
+ logger.warn("AuditLog: failed to record update event");
103
+ logger.warn(err);
104
+ }
105
+ }
106
+ async recordDelete(data) {
107
+ try {
108
+ const projectId = this.resolveProjectId(data.model, data.deletedItem, data.props);
109
+ if (!projectId) {
110
+ return;
111
+ }
112
+ const settings = await this.getProjectSettings(projectId);
113
+ if (!this.isEligible(settings, data.props)) {
114
+ return;
115
+ }
116
+ const redactedFields = this.getRedactedFields(data.model);
117
+ const changes = this.buildSnapshotChanges({
118
+ model: data.deletedItem,
119
+ redactedFields,
120
+ valueKey: "oldValue",
121
+ });
122
+ await this.insert({
123
+ projectId,
124
+ resourceType: this.getResourceType(data.model),
125
+ resourceId: data.itemId,
126
+ resourceName: this.getResourceName(data.deletedItem),
127
+ action: AuditLogAction.Delete,
128
+ changes,
129
+ props: data.props,
130
+ retentionInDays: settings.retentionInDays,
131
+ });
132
+ }
133
+ catch (err) {
134
+ logger.warn("AuditLog: failed to record delete event");
135
+ logger.warn(err);
136
+ }
137
+ }
138
+ async insert(params) {
139
+ const auditLog = new AuditLog();
140
+ auditLog.projectId = params.projectId;
141
+ auditLog.resourceType = params.resourceType;
142
+ if (params.resourceId) {
143
+ auditLog.resourceId = params.resourceId;
144
+ }
145
+ if (params.resourceName) {
146
+ auditLog.resourceName = params.resourceName;
147
+ }
148
+ auditLog.action = params.action;
149
+ const actor = await this.resolveActor(params.props);
150
+ if (actor.userId) {
151
+ auditLog.userId = actor.userId;
152
+ }
153
+ if (actor.userName) {
154
+ auditLog.userName = actor.userName;
155
+ }
156
+ if (actor.userEmail) {
157
+ auditLog.userEmail = actor.userEmail;
158
+ }
159
+ if (actor.userType) {
160
+ auditLog.userType = actor.userType;
161
+ }
162
+ auditLog.changes = params.changes;
163
+ auditLog.retentionDate = this.computeRetentionDate(params.retentionInDays);
164
+ await this.create({
165
+ data: auditLog,
166
+ props: { isRoot: true },
167
+ });
168
+ }
169
+ computeRetentionDate(retentionInDays) {
170
+ const days = Math.max(1, Math.min(retentionInDays || 7, 180));
171
+ return OneUptimeDate.addRemoveDays(OneUptimeDate.getCurrentDate(), days);
172
+ }
173
+ isEligible(settings, _props) {
174
+ if (!settings) {
175
+ return false;
176
+ }
177
+ if (!settings.enableAuditLogs) {
178
+ return false;
179
+ }
180
+ if (IsEnterpriseEdition) {
181
+ return true;
182
+ }
183
+ if (IsBillingEnabled) {
184
+ return settings.planName === PlanType.Enterprise;
185
+ }
186
+ /*
187
+ * Neither enterprise edition nor billing is enabled — audit logs are not
188
+ * available on the free self-hosted build.
189
+ */
190
+ return false;
191
+ }
192
+ async getProjectSettings(projectId) {
193
+ var _a;
194
+ const key = projectId.toString();
195
+ const now = Date.now();
196
+ const cached = this.projectSettingsCache.get(key);
197
+ if (cached && cached.expiresAt > now) {
198
+ return cached;
199
+ }
200
+ const project = await ProjectService.findOneById({
201
+ id: projectId,
202
+ select: {
203
+ _id: true,
204
+ enableAuditLogs: true,
205
+ auditLogsRetentionInDays: true,
206
+ planName: true,
207
+ },
208
+ props: { isRoot: true },
209
+ });
210
+ if (!project) {
211
+ return null;
212
+ }
213
+ const settings = {
214
+ enableAuditLogs: Boolean(project.enableAuditLogs),
215
+ retentionInDays: (_a = project.auditLogsRetentionInDays) !== null && _a !== void 0 ? _a : 7,
216
+ planName: project.planName,
217
+ expiresAt: now + PROJECT_SETTINGS_CACHE_TTL_MS,
218
+ };
219
+ this.projectSettingsCache.set(key, settings);
220
+ return settings;
221
+ }
222
+ async resolveActor(props) {
223
+ var _a, _b;
224
+ const userType = props.userType
225
+ ? String(props.userType)
226
+ : props.isRoot
227
+ ? "System"
228
+ : null;
229
+ if (!props.userId) {
230
+ return {
231
+ userId: null,
232
+ userName: null,
233
+ userEmail: null,
234
+ userType,
235
+ };
236
+ }
237
+ // API-key actions don't have a user record to look up.
238
+ if (props.userType === UserType.API) {
239
+ return {
240
+ userId: props.userId,
241
+ userName: null,
242
+ userEmail: null,
243
+ userType,
244
+ };
245
+ }
246
+ const cached = await this.getUserInfo(props.userId);
247
+ return {
248
+ userId: props.userId,
249
+ userName: (_a = cached === null || cached === void 0 ? void 0 : cached.name) !== null && _a !== void 0 ? _a : null,
250
+ userEmail: (_b = cached === null || cached === void 0 ? void 0 : cached.email) !== null && _b !== void 0 ? _b : null,
251
+ userType,
252
+ };
253
+ }
254
+ async getUserInfo(userId) {
255
+ var _a, _b, _c, _d;
256
+ const key = userId.toString();
257
+ const now = Date.now();
258
+ const cached = this.userCache.get(key);
259
+ if (cached && cached.expiresAt > now) {
260
+ return { name: cached.name, email: cached.email };
261
+ }
262
+ const user = await UserService.findOneById({
263
+ id: userId,
264
+ select: { _id: true, name: true, email: true },
265
+ props: { isRoot: true },
266
+ });
267
+ const name = (_b = (_a = user === null || user === void 0 ? void 0 : user.name) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : null;
268
+ const email = (_d = (_c = user === null || user === void 0 ? void 0 : user.email) === null || _c === void 0 ? void 0 : _c.toString()) !== null && _d !== void 0 ? _d : null;
269
+ this.userCache.set(key, {
270
+ name,
271
+ email,
272
+ expiresAt: now + USER_CACHE_TTL_MS,
273
+ });
274
+ return { name, email };
275
+ }
276
+ resolveProjectId(model, item, props) {
277
+ if (props.tenantId) {
278
+ return props.tenantId;
279
+ }
280
+ const tenantColumn = model.getTenantColumn();
281
+ if (!tenantColumn) {
282
+ return undefined;
283
+ }
284
+ const value = item.getValue(tenantColumn);
285
+ return value !== null && value !== void 0 ? value : undefined;
286
+ }
287
+ getRedactedFields(model) {
288
+ const redacted = new Set();
289
+ const allAccessControl = getColumnAccessControlForAllColumns(model);
290
+ for (const key of Object.keys(allAccessControl)) {
291
+ const ac = allAccessControl[key];
292
+ if (ac && Array.isArray(ac.read) && ac.read.length === 0) {
293
+ redacted.add(key);
294
+ }
295
+ }
296
+ return redacted;
297
+ }
298
+ buildSnapshotChanges(data) {
299
+ const changes = [];
300
+ const columns = data.model.getTableColumns().columns;
301
+ for (const column of columns) {
302
+ if (SKIPPED_FIELDS.has(column)) {
303
+ continue;
304
+ }
305
+ if (data.redactedFields.has(column)) {
306
+ continue;
307
+ }
308
+ const value = data.model[column];
309
+ if (value === undefined) {
310
+ continue;
311
+ }
312
+ changes.push({
313
+ field: column,
314
+ [data.valueKey]: this.serializeValue(value),
315
+ });
316
+ }
317
+ return changes;
318
+ }
319
+ buildUpdateDiff(data) {
320
+ const changes = [];
321
+ for (const field of Object.keys(data.updatedFields)) {
322
+ if (SKIPPED_FIELDS.has(field)) {
323
+ continue;
324
+ }
325
+ if (data.redactedFields.has(field)) {
326
+ continue;
327
+ }
328
+ const newValue = data.updatedFields[field];
329
+ const oldValue = data.before[field];
330
+ if (this.areValuesEqual(oldValue, newValue)) {
331
+ continue;
332
+ }
333
+ changes.push({
334
+ field,
335
+ oldValue: this.serializeValue(oldValue),
336
+ newValue: this.serializeValue(newValue),
337
+ });
338
+ }
339
+ return changes;
340
+ }
341
+ areValuesEqual(a, b) {
342
+ if (a === b) {
343
+ return true;
344
+ }
345
+ if (a === null || a === undefined) {
346
+ return b === null || b === undefined;
347
+ }
348
+ if (b === null || b === undefined) {
349
+ return false;
350
+ }
351
+ try {
352
+ return JSON.stringify(a) === JSON.stringify(b);
353
+ }
354
+ catch (_a) {
355
+ return false;
356
+ }
357
+ }
358
+ serializeValue(value) {
359
+ if (value === null || value === undefined) {
360
+ return null;
361
+ }
362
+ if (value instanceof ObjectID) {
363
+ return value.toString();
364
+ }
365
+ if (value instanceof Date) {
366
+ return value.toISOString();
367
+ }
368
+ if (typeof value === "string" ||
369
+ typeof value === "number" ||
370
+ typeof value === "boolean") {
371
+ return value;
372
+ }
373
+ try {
374
+ return JSON.parse(JSON.stringify(value));
375
+ }
376
+ catch (_a) {
377
+ return String(value);
378
+ }
379
+ }
380
+ getResourceType(model) {
381
+ if (model.singularName) {
382
+ return model.singularName;
383
+ }
384
+ return model.constructor
385
+ .name;
386
+ }
387
+ getResourceName(item) {
388
+ for (const field of NAME_CANDIDATE_FIELDS) {
389
+ const columns = item.getTableColumns().columns;
390
+ if (!columns.includes(field)) {
391
+ continue;
392
+ }
393
+ const value = item[field];
394
+ if (typeof value === "string" && value.length > 0) {
395
+ return value;
396
+ }
397
+ }
398
+ return null;
399
+ }
400
+ }
401
+ export default new AuditLogService();
402
+ //# sourceMappingURL=AuditLogService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuditLogService.js","sourceRoot":"","sources":["../../../../Server/Services/AuditLogService.ts"],"names":[],"mappings":"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"}
@@ -464,7 +464,7 @@ class DatabaseService extends BaseService {
464
464
  }
465
465
  }
466
466
  async create(createBy) {
467
- var _a;
467
+ var _a, _b;
468
468
  const onCreate = createBy.props.ignoreHooks
469
469
  ? { createBy, carryForward: [] }
470
470
  : await this._onBeforeCreate(createBy);
@@ -514,6 +514,22 @@ class DatabaseService extends BaseService {
514
514
  if (tenantId) {
515
515
  await this.onTriggerRealtime(createBy.data.id, tenantId, ModelEventType.Create);
516
516
  }
517
+ if (!createBy.props.ignoreHooks &&
518
+ ((_b = this.getModel().enableAuditLogOn) === null || _b === void 0 ? void 0 : _b.create)) {
519
+ /*
520
+ * Lazy require to avoid circular dependency between DatabaseService and
521
+ * AuditLogService (which depends on ProjectService/UserService, both of
522
+ * which extend DatabaseService). A top-level import leaves
523
+ * DatabaseService undefined at class-extension time for subclasses.
524
+ */
525
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
526
+ const auditLogService = require("./AuditLogService").default;
527
+ await auditLogService.recordCreate({
528
+ model: this.getModel(),
529
+ createdItem: createBy.data,
530
+ props: createBy.props,
531
+ });
532
+ }
517
533
  return createBy.data;
518
534
  }
519
535
  catch (error) {
@@ -720,7 +736,7 @@ class DatabaseService extends BaseService {
720
736
  }
721
737
  }
722
738
  async _deleteBy(deleteBy) {
723
- var _a, _b;
739
+ var _a, _b, _c, _d;
724
740
  try {
725
741
  if (this.doNotAllowDelete && !deleteBy.props.isRoot) {
726
742
  throw new BadDataException("Delete not allowed");
@@ -741,6 +757,16 @@ class DatabaseService extends BaseService {
741
757
  if (this.getModel().getTenantColumn()) {
742
758
  select[this.getModel().getTenantColumn()] = true;
743
759
  }
760
+ /*
761
+ * If audit logging on delete is enabled, fetch all scalar columns so we
762
+ * can record a full snapshot of the record before it is deleted.
763
+ */
764
+ if ((_a = this.getModel().enableAuditLogOn) === null || _a === void 0 ? void 0 : _a.delete) {
765
+ const allColumns = this.getModel().getTableColumns().columns;
766
+ for (const columnName of allColumns) {
767
+ select[columnName] = true;
768
+ }
769
+ }
744
770
  const items = await this._findBy({
745
771
  query: beforeDeleteBy.query,
746
772
  skip: beforeDeleteBy.skip.toNumber(),
@@ -780,10 +806,10 @@ class DatabaseService extends BaseService {
780
806
  (await this.getRepository().delete(query)).affected || 0;
781
807
  }
782
808
  // hit workflow.
783
- if (((_a = this.getModel().enableWorkflowOn) === null || _a === void 0 ? void 0 : _a.delete) &&
809
+ if (((_b = this.getModel().enableWorkflowOn) === null || _b === void 0 ? void 0 : _b.delete) &&
784
810
  (deleteBy.props.tenantId || this.getModel().getTenantColumn())) {
785
811
  for (const item of items) {
786
- if ((_b = this.getModel().enableWorkflowOn) === null || _b === void 0 ? void 0 : _b.create) {
812
+ if ((_c = this.getModel().enableWorkflowOn) === null || _c === void 0 ? void 0 : _c.create) {
787
813
  let tenantId = deleteBy.props.tenantId;
788
814
  if (!tenantId && this.getModel().getTenantColumn()) {
789
815
  tenantId = item.getValue(this.getModel().getTenantColumn());
@@ -800,6 +826,20 @@ class DatabaseService extends BaseService {
800
826
  return new ObjectID(i._id);
801
827
  }));
802
828
  }
829
+ if (((_d = this.getModel().enableAuditLogOn) === null || _d === void 0 ? void 0 : _d.delete) && items.length > 0) {
830
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
831
+ const auditLogService = require("./AuditLogService").default;
832
+ for (const item of items) {
833
+ if (item.id) {
834
+ await auditLogService.recordDelete({
835
+ model: this.getModel(),
836
+ deletedItem: item,
837
+ itemId: item.id,
838
+ props: deleteBy.props,
839
+ });
840
+ }
841
+ }
842
+ }
803
843
  return numberOfDocsAffected;
804
844
  }
805
845
  catch (error) {
@@ -986,7 +1026,7 @@ class DatabaseService extends BaseService {
986
1026
  });
987
1027
  }
988
1028
  async _updateBy(updateBy) {
989
- var _a, _b, _c;
1029
+ var _a, _b, _c, _d, _e;
990
1030
  try {
991
1031
  const onUpdate = updateBy.props.ignoreHooks
992
1032
  ? { updateBy, carryForward: [] }
@@ -1018,6 +1058,24 @@ class DatabaseService extends BaseService {
1018
1058
  selectColumns[this.getModel().getTenantColumn().toString()] =
1019
1059
  true;
1020
1060
  }
1061
+ /*
1062
+ * When audit logging on update is enabled, ensure the resource's display
1063
+ * name is loaded on the `before` snapshot so the audit entry records the
1064
+ * human-readable resource name even when the update doesn't touch it.
1065
+ */
1066
+ if ((_a = this.getModel().enableAuditLogOn) === null || _a === void 0 ? void 0 : _a.update) {
1067
+ const nameCandidates = [
1068
+ "name",
1069
+ "title",
1070
+ "displayName",
1071
+ ];
1072
+ const modelColumns = this.getModel().getTableColumns().columns;
1073
+ for (const candidate of nameCandidates) {
1074
+ if (modelColumns.includes(candidate)) {
1075
+ selectColumns[candidate] = true;
1076
+ }
1077
+ }
1078
+ }
1021
1079
  const items = await this._findBy({
1022
1080
  query: beforeUpdateBy.query,
1023
1081
  skip: updateBy.skip.toNumber(),
@@ -1028,14 +1086,14 @@ class DatabaseService extends BaseService {
1028
1086
  for (const item of items) {
1029
1087
  const updatedItem = Object.assign({ _id: item._id }, data);
1030
1088
  logger.debug("Updated Item", {
1031
- projectId: (_a = updateBy.props.tenantId) === null || _a === void 0 ? void 0 : _a.toString(),
1089
+ projectId: (_b = updateBy.props.tenantId) === null || _b === void 0 ? void 0 : _b.toString(),
1032
1090
  });
1033
1091
  logger.debug(JSON.stringify(updatedItem, null, 2), {
1034
- projectId: (_b = updateBy.props.tenantId) === null || _b === void 0 ? void 0 : _b.toString(),
1092
+ projectId: (_c = updateBy.props.tenantId) === null || _c === void 0 ? void 0 : _c.toString(),
1035
1093
  });
1036
1094
  await this.getRepository().save(updatedItem);
1037
1095
  // hit workflow.
1038
- if (((_c = this.getModel().enableWorkflowOn) === null || _c === void 0 ? void 0 : _c.update) &&
1096
+ if (((_d = this.getModel().enableWorkflowOn) === null || _d === void 0 ? void 0 : _d.update) &&
1039
1097
  // Only trigger workflow if there's a change in values
1040
1098
  !this.hasSameValues({ item, updatedItem })) {
1041
1099
  let tenantId = updateBy.props.tenantId;
@@ -1049,6 +1107,19 @@ class DatabaseService extends BaseService {
1049
1107
  await this.onTriggerRealtime(item.id, tenantId, ModelEventType.Update);
1050
1108
  }
1051
1109
  }
1110
+ if (((_e = this.getModel().enableAuditLogOn) === null || _e === void 0 ? void 0 : _e.update) &&
1111
+ !this.hasSameValues({ item, updatedItem }) &&
1112
+ item.id) {
1113
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
1114
+ const auditLogService = require("./AuditLogService").default;
1115
+ await auditLogService.recordUpdate({
1116
+ model: this.getModel(),
1117
+ before: item,
1118
+ updatedFields: data,
1119
+ itemId: item.id,
1120
+ props: updateBy.props,
1121
+ });
1122
+ }
1052
1123
  }
1053
1124
  /*
1054
1125
  * Cant Update relations.