mongodb-dynamic-api 4.6.0 → 4.6.1
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/CHANGELOG.md +2 -0
- package/package.json +1 -1
- package/src/interfaces/dynamic-api-service-before-save-callback.interface.d.ts +1 -1
- package/src/version.json +1 -1
- package/test/for-feature/callbacks-user.e2e-spec.js +122 -274
- package/test/for-feature/callbacks-user.e2e-spec.js.map +1 -1
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -36,7 +36,7 @@ type BeforeSaveCallback<Entity extends BaseEntity, Context = Record<string, unkn
|
|
|
36
36
|
type BeforeSaveListCallback<Entity extends BaseEntity, Context = Record<string, unknown>, User = unknown> = (entities: Entity[] | undefined, context: Context, methods: CallbackMethods, user?: User) => Promise<Partial<Entity>[]>;
|
|
37
37
|
type BeforeSaveDeleteCallback<Entity extends BaseEntity, Context = Record<string, unknown>, User = unknown> = (entity: Entity | undefined, context: Context, methods: CallbackMethods, user?: User) => Promise<void>;
|
|
38
38
|
type BeforeSaveDeleteManyCallback<Entity extends BaseEntity, Context = Record<string, unknown>, User = unknown> = (entities: Entity[], context: Context, methods: CallbackMethods, user?: User) => Promise<void>;
|
|
39
|
-
type AnyBeforeSaveCallback<Entity extends BaseEntity, User = unknown> = BeforeSaveCallback<Entity,
|
|
39
|
+
type AnyBeforeSaveCallback<Entity extends BaseEntity, User = unknown> = BeforeSaveCallback<Entity, unknown, User> | BeforeSaveListCallback<Entity, unknown, User> | BeforeSaveDeleteCallback<Entity, unknown, User> | BeforeSaveDeleteManyCallback<Entity, unknown, User>;
|
|
40
40
|
type DynamicApiServiceBeforeSaveCreateContext<Entity extends BaseEntity> = BeforeSaveCreateContext<Entity>;
|
|
41
41
|
type DynamicApiServiceBeforeSaveCreateManyContext<Entity extends BaseEntity> = BeforeSaveCreateManyContext<Entity>;
|
|
42
42
|
type DynamicApiServiceBeforeSaveUpdateContext<Entity extends BaseEntity> = BeforeSaveUpdateContext<Entity>;
|
package/src/version.json
CHANGED
|
@@ -15,7 +15,7 @@ const mongoose_2 = require("mongoose");
|
|
|
15
15
|
const src_1 = require("../../src");
|
|
16
16
|
const e2e_setup_1 = require("../e2e.setup");
|
|
17
17
|
require("dotenv/config");
|
|
18
|
-
|
|
18
|
+
function buildEntities(collectionSuffix) {
|
|
19
19
|
let UserEntity = class UserEntity extends src_1.BaseEntity {
|
|
20
20
|
};
|
|
21
21
|
__decorate([
|
|
@@ -27,7 +27,7 @@ describe('Callbacks receive authenticated user (e2e)', () => {
|
|
|
27
27
|
__metadata("design:type", String)
|
|
28
28
|
], UserEntity.prototype, "password", void 0);
|
|
29
29
|
UserEntity = __decorate([
|
|
30
|
-
(0, mongoose_1.Schema)({ collection:
|
|
30
|
+
(0, mongoose_1.Schema)({ collection: `users-${collectionSuffix}` })
|
|
31
31
|
], UserEntity);
|
|
32
32
|
let ItemEntity = class ItemEntity extends src_1.BaseEntity {
|
|
33
33
|
};
|
|
@@ -44,7 +44,7 @@ describe('Callbacks receive authenticated user (e2e)', () => {
|
|
|
44
44
|
__metadata("design:type", String)
|
|
45
45
|
], ItemEntity.prototype, "updatedBy", void 0);
|
|
46
46
|
ItemEntity = __decorate([
|
|
47
|
-
(0, mongoose_1.Schema)({ collection:
|
|
47
|
+
(0, mongoose_1.Schema)({ collection: `items-${collectionSuffix}` })
|
|
48
48
|
], ItemEntity);
|
|
49
49
|
let AuditLogEntity = class AuditLogEntity extends src_1.BaseEntity {
|
|
50
50
|
};
|
|
@@ -61,161 +61,177 @@ describe('Callbacks receive authenticated user (e2e)', () => {
|
|
|
61
61
|
__metadata("design:type", String)
|
|
62
62
|
], AuditLogEntity.prototype, "performedBy", void 0);
|
|
63
63
|
AuditLogEntity = __decorate([
|
|
64
|
-
(0, mongoose_1.Schema)({ collection:
|
|
64
|
+
(0, mongoose_1.Schema)({ collection: `audit-logs-${collectionSuffix}` })
|
|
65
65
|
], AuditLogEntity);
|
|
66
|
+
return { UserEntity, ItemEntity, AuditLogEntity };
|
|
67
|
+
}
|
|
68
|
+
class ItemAggregateQuery {
|
|
69
|
+
static toPipeline(query) {
|
|
70
|
+
return [{ $match: query.name ? { name: query.name } : {} }];
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function buildCallbacks(AuditLogEntity, actionPrefix) {
|
|
74
|
+
const email = (user) => user?.email ?? 'anonymous';
|
|
66
75
|
const createOneBeforeSave = async (_entity, context, _methods, user) => {
|
|
67
|
-
|
|
68
|
-
return { ...context.toCreate, createdBy: u?.email ?? 'anonymous' };
|
|
76
|
+
return { ...context.toCreate, createdBy: email(user) };
|
|
69
77
|
};
|
|
70
78
|
const createOneAfterSave = async (entity, methods, user) => {
|
|
71
|
-
const u = user;
|
|
72
79
|
await methods.createOneDocument(AuditLogEntity, {
|
|
73
|
-
action:
|
|
80
|
+
action: `${actionPrefix}CreateOne`,
|
|
74
81
|
entityId: entity.id,
|
|
75
|
-
performedBy:
|
|
82
|
+
performedBy: email(user),
|
|
76
83
|
});
|
|
77
84
|
};
|
|
78
85
|
const createManyBeforeSave = async (_entities, context, _methods, user) => {
|
|
79
|
-
|
|
80
|
-
return context.toCreate.map((item) => ({ ...item, createdBy: u?.email ?? 'anonymous' }));
|
|
86
|
+
return context.toCreate.map((item) => ({ ...item, createdBy: email(user) }));
|
|
81
87
|
};
|
|
82
88
|
const createManyAfterSave = async (entity, methods, user) => {
|
|
83
|
-
const u = user;
|
|
84
89
|
await methods.createOneDocument(AuditLogEntity, {
|
|
85
|
-
action:
|
|
90
|
+
action: `${actionPrefix}CreateMany`,
|
|
86
91
|
entityId: entity.id,
|
|
87
|
-
performedBy:
|
|
92
|
+
performedBy: email(user),
|
|
88
93
|
});
|
|
89
94
|
};
|
|
90
95
|
const updateOneBeforeSave = async (_entity, context, _methods, user) => {
|
|
91
|
-
|
|
92
|
-
return { ...context.update, updatedBy: u?.email ?? 'anonymous' };
|
|
96
|
+
return { ...context.update, updatedBy: email(user) };
|
|
93
97
|
};
|
|
94
98
|
const updateOneAfterSave = async (entity, methods, user) => {
|
|
95
|
-
const u = user;
|
|
96
99
|
await methods.createOneDocument(AuditLogEntity, {
|
|
97
|
-
action:
|
|
100
|
+
action: `${actionPrefix}UpdateOne`,
|
|
98
101
|
entityId: entity.id,
|
|
99
|
-
performedBy:
|
|
102
|
+
performedBy: email(user),
|
|
100
103
|
});
|
|
101
104
|
};
|
|
102
105
|
const updateManyBeforeSave = async (entities, context, _methods, user) => {
|
|
103
|
-
|
|
104
|
-
return entities.map(() => ({ ...context.update, updatedBy: u?.email ?? 'anonymous' }));
|
|
106
|
+
return entities.map(() => ({ ...context.update, updatedBy: email(user) }));
|
|
105
107
|
};
|
|
106
108
|
const updateManyAfterSave = async (entity, methods, user) => {
|
|
107
|
-
const u = user;
|
|
108
109
|
await methods.createOneDocument(AuditLogEntity, {
|
|
109
|
-
action:
|
|
110
|
+
action: `${actionPrefix}UpdateMany`,
|
|
110
111
|
entityId: entity.id,
|
|
111
|
-
performedBy:
|
|
112
|
+
performedBy: email(user),
|
|
112
113
|
});
|
|
113
114
|
};
|
|
114
115
|
const replaceOneBeforeSave = async (_entity, context, _methods, user) => {
|
|
115
|
-
|
|
116
|
-
return { ...context.replacement, updatedBy: u?.email ?? 'anonymous' };
|
|
116
|
+
return { ...context.replacement, updatedBy: email(user) };
|
|
117
117
|
};
|
|
118
118
|
const replaceOneAfterSave = async (entity, methods, user) => {
|
|
119
|
-
const u = user;
|
|
120
119
|
await methods.createOneDocument(AuditLogEntity, {
|
|
121
|
-
action:
|
|
120
|
+
action: `${actionPrefix}ReplaceOne`,
|
|
122
121
|
entityId: entity.id,
|
|
123
|
-
performedBy:
|
|
122
|
+
performedBy: email(user),
|
|
124
123
|
});
|
|
125
124
|
};
|
|
126
125
|
const duplicateOneBeforeSave = async (_entity, context, _methods, user) => {
|
|
127
|
-
|
|
128
|
-
return { ...(context.override ?? {}), createdBy: u?.email ?? 'anonymous' };
|
|
126
|
+
return { ...(context.override ?? {}), createdBy: email(user) };
|
|
129
127
|
};
|
|
130
128
|
const duplicateOneAfterSave = async (entity, methods, user) => {
|
|
131
|
-
const u = user;
|
|
132
129
|
await methods.createOneDocument(AuditLogEntity, {
|
|
133
|
-
action:
|
|
130
|
+
action: `${actionPrefix}DuplicateOne`,
|
|
134
131
|
entityId: entity.id,
|
|
135
|
-
performedBy:
|
|
132
|
+
performedBy: email(user),
|
|
136
133
|
});
|
|
137
134
|
};
|
|
138
135
|
const duplicateManyBeforeSave = async (entities, context, _methods, user) => {
|
|
139
|
-
const u = user;
|
|
140
136
|
return entities.map((e) => ({
|
|
141
137
|
name: e.name,
|
|
142
138
|
...(context.override ?? {}),
|
|
143
|
-
createdBy:
|
|
139
|
+
createdBy: email(user),
|
|
144
140
|
}));
|
|
145
141
|
};
|
|
146
142
|
const duplicateManyAfterSave = async (entity, methods, user) => {
|
|
147
|
-
const u = user;
|
|
148
143
|
await methods.createOneDocument(AuditLogEntity, {
|
|
149
|
-
action:
|
|
144
|
+
action: `${actionPrefix}DuplicateMany`,
|
|
150
145
|
entityId: entity.id,
|
|
151
|
-
performedBy:
|
|
146
|
+
performedBy: email(user),
|
|
152
147
|
});
|
|
153
148
|
};
|
|
154
149
|
const deleteOneBeforeSave = async (entity, _context, methods, user) => {
|
|
155
|
-
const u = user;
|
|
156
150
|
if (entity) {
|
|
157
151
|
await methods.createOneDocument(AuditLogEntity, {
|
|
158
|
-
action:
|
|
152
|
+
action: `${actionPrefix}DeleteOne-before`,
|
|
159
153
|
entityId: entity.id,
|
|
160
|
-
performedBy:
|
|
154
|
+
performedBy: email(user),
|
|
161
155
|
});
|
|
162
156
|
}
|
|
163
157
|
};
|
|
164
158
|
const deleteOneAfterSave = async (entity, methods, user) => {
|
|
165
|
-
const u = user;
|
|
166
159
|
await methods.createOneDocument(AuditLogEntity, {
|
|
167
|
-
action:
|
|
160
|
+
action: `${actionPrefix}DeleteOne`,
|
|
168
161
|
entityId: entity.id,
|
|
169
|
-
performedBy:
|
|
162
|
+
performedBy: email(user),
|
|
170
163
|
});
|
|
171
164
|
};
|
|
172
165
|
const deleteManyBeforeSave = async (entities, _context, methods, user) => {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
performedBy: u?.email ?? 'anonymous',
|
|
179
|
-
});
|
|
180
|
-
}
|
|
166
|
+
await Promise.all(entities.map((entity) => methods.createOneDocument(AuditLogEntity, {
|
|
167
|
+
action: `${actionPrefix}DeleteMany-before`,
|
|
168
|
+
entityId: entity._id?.toString() ?? entity.id,
|
|
169
|
+
performedBy: email(user),
|
|
170
|
+
})));
|
|
181
171
|
};
|
|
182
172
|
const deleteManyAfterSave = async (entity, methods, user) => {
|
|
183
|
-
const u = user;
|
|
184
173
|
await methods.createOneDocument(AuditLogEntity, {
|
|
185
|
-
action:
|
|
174
|
+
action: `${actionPrefix}DeleteMany`,
|
|
186
175
|
entityId: entity.id,
|
|
187
|
-
performedBy:
|
|
176
|
+
performedBy: email(user),
|
|
188
177
|
});
|
|
189
178
|
};
|
|
190
179
|
const getOneAfterSave = async (entity, methods, user) => {
|
|
191
|
-
const u = user;
|
|
192
180
|
await methods.createOneDocument(AuditLogEntity, {
|
|
193
|
-
action:
|
|
181
|
+
action: `${actionPrefix}GetOne`,
|
|
194
182
|
entityId: entity.id,
|
|
195
|
-
performedBy:
|
|
183
|
+
performedBy: email(user),
|
|
196
184
|
});
|
|
197
185
|
};
|
|
198
186
|
const getManyAfterSave = async (entity, methods, user) => {
|
|
199
|
-
const u = user;
|
|
200
187
|
await methods.createOneDocument(AuditLogEntity, {
|
|
201
|
-
action:
|
|
188
|
+
action: `${actionPrefix}GetMany`,
|
|
202
189
|
entityId: entity.id,
|
|
203
|
-
performedBy:
|
|
190
|
+
performedBy: email(user),
|
|
204
191
|
});
|
|
205
192
|
};
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
193
|
+
const aggregateAfterSave = async (entity, methods, user) => {
|
|
194
|
+
await methods.createOneDocument(AuditLogEntity, {
|
|
195
|
+
action: `${actionPrefix}Aggregate`,
|
|
196
|
+
entityId: entity.id,
|
|
197
|
+
performedBy: email(user),
|
|
198
|
+
});
|
|
199
|
+
};
|
|
200
|
+
return {
|
|
201
|
+
createOneBeforeSave, createOneAfterSave,
|
|
202
|
+
createManyBeforeSave, createManyAfterSave,
|
|
203
|
+
updateOneBeforeSave, updateOneAfterSave,
|
|
204
|
+
updateManyBeforeSave, updateManyAfterSave,
|
|
205
|
+
replaceOneBeforeSave, replaceOneAfterSave,
|
|
206
|
+
duplicateOneBeforeSave, duplicateOneAfterSave,
|
|
207
|
+
duplicateManyBeforeSave, duplicateManyAfterSave,
|
|
208
|
+
deleteOneBeforeSave, deleteOneAfterSave,
|
|
209
|
+
deleteManyBeforeSave, deleteManyAfterSave,
|
|
210
|
+
getOneAfterSave, getManyAfterSave,
|
|
211
|
+
aggregateAfterSave,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function buildRoutes(cb, opts) {
|
|
215
|
+
const ws = opts?.webSocket ? { webSocket: true } : {};
|
|
216
|
+
return [
|
|
217
|
+
{ type: 'CreateOne', ...ws, callback: cb.createOneAfterSave, beforeSaveCallback: cb.createOneBeforeSave },
|
|
218
|
+
{ type: 'CreateMany', ...ws, callback: cb.createManyAfterSave, beforeSaveCallback: cb.createManyBeforeSave },
|
|
219
|
+
{ type: 'UpdateOne', ...ws, callback: cb.updateOneAfterSave, beforeSaveCallback: cb.updateOneBeforeSave },
|
|
220
|
+
{ type: 'UpdateMany', ...ws, callback: cb.updateManyAfterSave, beforeSaveCallback: cb.updateManyBeforeSave },
|
|
221
|
+
{ type: 'ReplaceOne', ...ws, callback: cb.replaceOneAfterSave, beforeSaveCallback: cb.replaceOneBeforeSave },
|
|
222
|
+
{ type: 'DuplicateOne', ...ws, callback: cb.duplicateOneAfterSave, beforeSaveCallback: cb.duplicateOneBeforeSave },
|
|
223
|
+
{ type: 'DuplicateMany', ...ws, callback: cb.duplicateManyAfterSave, beforeSaveCallback: cb.duplicateManyBeforeSave },
|
|
224
|
+
{ type: 'DeleteOne', ...ws, callback: cb.deleteOneAfterSave, beforeSaveCallback: cb.deleteOneBeforeSave },
|
|
225
|
+
{ type: 'DeleteMany', ...ws, callback: cb.deleteManyAfterSave, beforeSaveCallback: cb.deleteManyBeforeSave },
|
|
226
|
+
{ type: 'GetOne', ...ws, callback: cb.getOneAfterSave },
|
|
227
|
+
{ type: 'GetMany', ...ws, callback: cb.getManyAfterSave },
|
|
228
|
+
{ type: 'Aggregate', ...ws, subPath: 'aggregate', dTOs: { query: ItemAggregateQuery }, callback: cb.aggregateAfterSave },
|
|
218
229
|
];
|
|
230
|
+
}
|
|
231
|
+
describe('Callbacks receive authenticated user (e2e)', () => {
|
|
232
|
+
const { UserEntity, ItemEntity, AuditLogEntity } = buildEntities('cb');
|
|
233
|
+
const callbacks = buildCallbacks(AuditLogEntity, '');
|
|
234
|
+
const routes = buildRoutes(callbacks);
|
|
219
235
|
let accessToken;
|
|
220
236
|
const userEmail = 'cb-test@test.co';
|
|
221
237
|
const userPassword = 'test';
|
|
@@ -394,208 +410,26 @@ describe('Callbacks receive authenticated user (e2e)', () => {
|
|
|
394
410
|
expect(logs.every((l) => l.performedBy === userEmail)).toBe(true);
|
|
395
411
|
});
|
|
396
412
|
});
|
|
413
|
+
describe('Aggregate', () => {
|
|
414
|
+
it('afterSave callback should create audit logs with user for each aggregated entity', async () => {
|
|
415
|
+
await e2e_setup_1.server.post('/items/many', { list: [{ name: 'agg-1' }, { name: 'agg-2' }] }, auth());
|
|
416
|
+
const { body: items, status } = await e2e_setup_1.server.get('/items/aggregate', { ...auth(), query: { name: 'agg-1' } });
|
|
417
|
+
expect(status).toBe(200);
|
|
418
|
+
expect(items).toHaveLength(1);
|
|
419
|
+
expect(items[0].name).toBe('agg-1');
|
|
420
|
+
const logs = await getAuditLogs('Aggregate');
|
|
421
|
+
expect(logs).toHaveLength(1);
|
|
422
|
+
expect(logs[0]).toEqual(expect.objectContaining({
|
|
423
|
+
entityId: items[0].id,
|
|
424
|
+
performedBy: userEmail,
|
|
425
|
+
}));
|
|
426
|
+
});
|
|
427
|
+
});
|
|
397
428
|
});
|
|
398
429
|
describe('Callbacks receive authenticated user via WebSocket (e2e)', () => {
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
(0, mongoose_1.Prop)({ type: String, required: true }),
|
|
403
|
-
__metadata("design:type", String)
|
|
404
|
-
], UserEntity.prototype, "email", void 0);
|
|
405
|
-
__decorate([
|
|
406
|
-
(0, mongoose_1.Prop)({ type: String, required: true }),
|
|
407
|
-
__metadata("design:type", String)
|
|
408
|
-
], UserEntity.prototype, "password", void 0);
|
|
409
|
-
UserEntity = __decorate([
|
|
410
|
-
(0, mongoose_1.Schema)({ collection: 'users-cb-ws' })
|
|
411
|
-
], UserEntity);
|
|
412
|
-
let ItemEntity = class ItemEntity extends src_1.BaseEntity {
|
|
413
|
-
};
|
|
414
|
-
__decorate([
|
|
415
|
-
(0, mongoose_1.Prop)({ type: String, required: true }),
|
|
416
|
-
__metadata("design:type", String)
|
|
417
|
-
], ItemEntity.prototype, "name", void 0);
|
|
418
|
-
__decorate([
|
|
419
|
-
(0, mongoose_1.Prop)({ type: String }),
|
|
420
|
-
__metadata("design:type", String)
|
|
421
|
-
], ItemEntity.prototype, "createdBy", void 0);
|
|
422
|
-
__decorate([
|
|
423
|
-
(0, mongoose_1.Prop)({ type: String }),
|
|
424
|
-
__metadata("design:type", String)
|
|
425
|
-
], ItemEntity.prototype, "updatedBy", void 0);
|
|
426
|
-
ItemEntity = __decorate([
|
|
427
|
-
(0, mongoose_1.Schema)({ collection: 'items-cb-ws' })
|
|
428
|
-
], ItemEntity);
|
|
429
|
-
let AuditLogEntity = class AuditLogEntity extends src_1.BaseEntity {
|
|
430
|
-
};
|
|
431
|
-
__decorate([
|
|
432
|
-
(0, mongoose_1.Prop)({ type: String, required: true }),
|
|
433
|
-
__metadata("design:type", String)
|
|
434
|
-
], AuditLogEntity.prototype, "action", void 0);
|
|
435
|
-
__decorate([
|
|
436
|
-
(0, mongoose_1.Prop)({ type: String, required: true }),
|
|
437
|
-
__metadata("design:type", String)
|
|
438
|
-
], AuditLogEntity.prototype, "entityId", void 0);
|
|
439
|
-
__decorate([
|
|
440
|
-
(0, mongoose_1.Prop)({ type: String }),
|
|
441
|
-
__metadata("design:type", String)
|
|
442
|
-
], AuditLogEntity.prototype, "performedBy", void 0);
|
|
443
|
-
AuditLogEntity = __decorate([
|
|
444
|
-
(0, mongoose_1.Schema)({ collection: 'audit-logs-cb-ws' })
|
|
445
|
-
], AuditLogEntity);
|
|
446
|
-
const createOneBeforeSave = async (_entity, context, _methods, user) => {
|
|
447
|
-
const u = user;
|
|
448
|
-
return { ...context.toCreate, createdBy: u?.email ?? 'anonymous' };
|
|
449
|
-
};
|
|
450
|
-
const createOneAfterSave = async (entity, methods, user) => {
|
|
451
|
-
const u = user;
|
|
452
|
-
await methods.createOneDocument(AuditLogEntity, {
|
|
453
|
-
action: 'WS-CreateOne',
|
|
454
|
-
entityId: entity.id,
|
|
455
|
-
performedBy: u?.email ?? 'anonymous',
|
|
456
|
-
});
|
|
457
|
-
};
|
|
458
|
-
const createManyBeforeSave = async (_entities, context, _methods, user) => {
|
|
459
|
-
const u = user;
|
|
460
|
-
return context.toCreate.map((item) => ({ ...item, createdBy: u?.email ?? 'anonymous' }));
|
|
461
|
-
};
|
|
462
|
-
const createManyAfterSave = async (entity, methods, user) => {
|
|
463
|
-
const u = user;
|
|
464
|
-
await methods.createOneDocument(AuditLogEntity, {
|
|
465
|
-
action: 'WS-CreateMany',
|
|
466
|
-
entityId: entity.id,
|
|
467
|
-
performedBy: u?.email ?? 'anonymous',
|
|
468
|
-
});
|
|
469
|
-
};
|
|
470
|
-
const updateOneBeforeSave = async (_entity, context, _methods, user) => {
|
|
471
|
-
const u = user;
|
|
472
|
-
return { ...context.update, updatedBy: u?.email ?? 'anonymous' };
|
|
473
|
-
};
|
|
474
|
-
const updateOneAfterSave = async (entity, methods, user) => {
|
|
475
|
-
const u = user;
|
|
476
|
-
await methods.createOneDocument(AuditLogEntity, {
|
|
477
|
-
action: 'WS-UpdateOne',
|
|
478
|
-
entityId: entity.id,
|
|
479
|
-
performedBy: u?.email ?? 'anonymous',
|
|
480
|
-
});
|
|
481
|
-
};
|
|
482
|
-
const updateManyBeforeSave = async (entities, context, _methods, user) => {
|
|
483
|
-
const u = user;
|
|
484
|
-
return entities.map(() => ({ ...context.update, updatedBy: u?.email ?? 'anonymous' }));
|
|
485
|
-
};
|
|
486
|
-
const updateManyAfterSave = async (entity, methods, user) => {
|
|
487
|
-
const u = user;
|
|
488
|
-
await methods.createOneDocument(AuditLogEntity, {
|
|
489
|
-
action: 'WS-UpdateMany',
|
|
490
|
-
entityId: entity.id,
|
|
491
|
-
performedBy: u?.email ?? 'anonymous',
|
|
492
|
-
});
|
|
493
|
-
};
|
|
494
|
-
const replaceOneBeforeSave = async (_entity, context, _methods, user) => {
|
|
495
|
-
const u = user;
|
|
496
|
-
return { ...context.replacement, updatedBy: u?.email ?? 'anonymous' };
|
|
497
|
-
};
|
|
498
|
-
const replaceOneAfterSave = async (entity, methods, user) => {
|
|
499
|
-
const u = user;
|
|
500
|
-
await methods.createOneDocument(AuditLogEntity, {
|
|
501
|
-
action: 'WS-ReplaceOne',
|
|
502
|
-
entityId: entity.id,
|
|
503
|
-
performedBy: u?.email ?? 'anonymous',
|
|
504
|
-
});
|
|
505
|
-
};
|
|
506
|
-
const duplicateOneBeforeSave = async (_entity, context, _methods, user) => {
|
|
507
|
-
const u = user;
|
|
508
|
-
return { ...(context.override ?? {}), createdBy: u?.email ?? 'anonymous' };
|
|
509
|
-
};
|
|
510
|
-
const duplicateOneAfterSave = async (entity, methods, user) => {
|
|
511
|
-
const u = user;
|
|
512
|
-
await methods.createOneDocument(AuditLogEntity, {
|
|
513
|
-
action: 'WS-DuplicateOne',
|
|
514
|
-
entityId: entity.id,
|
|
515
|
-
performedBy: u?.email ?? 'anonymous',
|
|
516
|
-
});
|
|
517
|
-
};
|
|
518
|
-
const duplicateManyBeforeSave = async (entities, context, _methods, user) => {
|
|
519
|
-
const u = user;
|
|
520
|
-
return entities.map((e) => ({
|
|
521
|
-
name: e.name,
|
|
522
|
-
...(context.override ?? {}),
|
|
523
|
-
createdBy: u?.email ?? 'anonymous',
|
|
524
|
-
}));
|
|
525
|
-
};
|
|
526
|
-
const duplicateManyAfterSave = async (entity, methods, user) => {
|
|
527
|
-
const u = user;
|
|
528
|
-
await methods.createOneDocument(AuditLogEntity, {
|
|
529
|
-
action: 'WS-DuplicateMany',
|
|
530
|
-
entityId: entity.id,
|
|
531
|
-
performedBy: u?.email ?? 'anonymous',
|
|
532
|
-
});
|
|
533
|
-
};
|
|
534
|
-
const deleteOneBeforeSave = async (entity, _context, methods, user) => {
|
|
535
|
-
const u = user;
|
|
536
|
-
if (entity) {
|
|
537
|
-
await methods.createOneDocument(AuditLogEntity, {
|
|
538
|
-
action: 'WS-DeleteOne-before',
|
|
539
|
-
entityId: entity.id,
|
|
540
|
-
performedBy: u?.email ?? 'anonymous',
|
|
541
|
-
});
|
|
542
|
-
}
|
|
543
|
-
};
|
|
544
|
-
const deleteOneAfterSave = async (entity, methods, user) => {
|
|
545
|
-
const u = user;
|
|
546
|
-
await methods.createOneDocument(AuditLogEntity, {
|
|
547
|
-
action: 'WS-DeleteOne',
|
|
548
|
-
entityId: entity.id,
|
|
549
|
-
performedBy: u?.email ?? 'anonymous',
|
|
550
|
-
});
|
|
551
|
-
};
|
|
552
|
-
const deleteManyBeforeSave = async (entities, _context, methods, user) => {
|
|
553
|
-
const u = user;
|
|
554
|
-
for (const entity of entities) {
|
|
555
|
-
await methods.createOneDocument(AuditLogEntity, {
|
|
556
|
-
action: 'WS-DeleteMany-before',
|
|
557
|
-
entityId: entity._id?.toString() ?? entity.id,
|
|
558
|
-
performedBy: u?.email ?? 'anonymous',
|
|
559
|
-
});
|
|
560
|
-
}
|
|
561
|
-
};
|
|
562
|
-
const deleteManyAfterSave = async (entity, methods, user) => {
|
|
563
|
-
const u = user;
|
|
564
|
-
await methods.createOneDocument(AuditLogEntity, {
|
|
565
|
-
action: 'WS-DeleteMany',
|
|
566
|
-
entityId: entity.id,
|
|
567
|
-
performedBy: u?.email ?? 'anonymous',
|
|
568
|
-
});
|
|
569
|
-
};
|
|
570
|
-
const getOneAfterSave = async (entity, methods, user) => {
|
|
571
|
-
const u = user;
|
|
572
|
-
await methods.createOneDocument(AuditLogEntity, {
|
|
573
|
-
action: 'WS-GetOne',
|
|
574
|
-
entityId: entity.id,
|
|
575
|
-
performedBy: u?.email ?? 'anonymous',
|
|
576
|
-
});
|
|
577
|
-
};
|
|
578
|
-
const getManyAfterSave = async (entity, methods, user) => {
|
|
579
|
-
const u = user;
|
|
580
|
-
await methods.createOneDocument(AuditLogEntity, {
|
|
581
|
-
action: 'WS-GetMany',
|
|
582
|
-
entityId: entity.id,
|
|
583
|
-
performedBy: u?.email ?? 'anonymous',
|
|
584
|
-
});
|
|
585
|
-
};
|
|
586
|
-
const wsRoutes = [
|
|
587
|
-
{ type: 'CreateOne', webSocket: true, callback: createOneAfterSave, beforeSaveCallback: createOneBeforeSave },
|
|
588
|
-
{ type: 'CreateMany', webSocket: true, callback: createManyAfterSave, beforeSaveCallback: createManyBeforeSave },
|
|
589
|
-
{ type: 'UpdateOne', webSocket: true, callback: updateOneAfterSave, beforeSaveCallback: updateOneBeforeSave },
|
|
590
|
-
{ type: 'UpdateMany', webSocket: true, callback: updateManyAfterSave, beforeSaveCallback: updateManyBeforeSave },
|
|
591
|
-
{ type: 'ReplaceOne', webSocket: true, callback: replaceOneAfterSave, beforeSaveCallback: replaceOneBeforeSave },
|
|
592
|
-
{ type: 'DuplicateOne', webSocket: true, callback: duplicateOneAfterSave, beforeSaveCallback: duplicateOneBeforeSave },
|
|
593
|
-
{ type: 'DuplicateMany', webSocket: true, callback: duplicateManyAfterSave, beforeSaveCallback: duplicateManyBeforeSave },
|
|
594
|
-
{ type: 'DeleteOne', webSocket: true, callback: deleteOneAfterSave, beforeSaveCallback: deleteOneBeforeSave },
|
|
595
|
-
{ type: 'DeleteMany', webSocket: true, callback: deleteManyAfterSave, beforeSaveCallback: deleteManyBeforeSave },
|
|
596
|
-
{ type: 'GetOne', webSocket: true, callback: getOneAfterSave },
|
|
597
|
-
{ type: 'GetMany', webSocket: true, callback: getManyAfterSave },
|
|
598
|
-
];
|
|
430
|
+
const { UserEntity, ItemEntity, AuditLogEntity } = buildEntities('cb-ws');
|
|
431
|
+
const callbacks = buildCallbacks(AuditLogEntity, 'WS-');
|
|
432
|
+
const wsRoutes = buildRoutes(callbacks, { webSocket: true });
|
|
599
433
|
let accessToken;
|
|
600
434
|
const userEmail = 'ws-cb-test@test.co';
|
|
601
435
|
const userPassword = 'test';
|
|
@@ -768,5 +602,19 @@ describe('Callbacks receive authenticated user via WebSocket (e2e)', () => {
|
|
|
768
602
|
expect(logs.every((l) => l.performedBy === userEmail)).toBe(true);
|
|
769
603
|
});
|
|
770
604
|
});
|
|
605
|
+
describe('Aggregate', () => {
|
|
606
|
+
it('afterSave callback should create audit logs with socket user for each aggregated entity', async () => {
|
|
607
|
+
await e2e_setup_1.server.emit('create-many-item-entity', { list: [{ name: 'ws-agg-1' }, { name: 'ws-agg-2' }] }, wsAuth());
|
|
608
|
+
const result = await e2e_setup_1.server.emit('aggregate-aggregate-item-entity', { name: 'ws-agg-1' }, wsAuth());
|
|
609
|
+
expect(result).toHaveLength(1);
|
|
610
|
+
expect(result[0].name).toBe('ws-agg-1');
|
|
611
|
+
const logs = await getAuditLogs('WS-Aggregate');
|
|
612
|
+
expect(logs).toHaveLength(1);
|
|
613
|
+
expect(logs[0]).toEqual(expect.objectContaining({
|
|
614
|
+
entityId: result[0].id,
|
|
615
|
+
performedBy: userEmail,
|
|
616
|
+
}));
|
|
617
|
+
});
|
|
618
|
+
});
|
|
771
619
|
});
|
|
772
620
|
//# sourceMappingURL=callbacks-user.e2e-spec.js.map
|