@solidstarters/solid-core 1.2.64 → 1.2.66
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/controllers/chatter-message.controller.d.ts +1 -2
- package/dist/controllers/chatter-message.controller.d.ts.map +1 -1
- package/dist/controllers/chatter-message.controller.js +3 -7
- package/dist/controllers/chatter-message.controller.js.map +1 -1
- package/dist/decorators/active-user.decorator.d.ts.map +1 -1
- package/dist/decorators/active-user.decorator.js.map +1 -1
- package/dist/decorators/solid-request-context.decorator.d.ts.map +1 -1
- package/dist/decorators/solid-request-context.decorator.js.map +1 -1
- package/dist/guards/access-token.guard.d.ts +3 -1
- package/dist/guards/access-token.guard.d.ts.map +1 -1
- package/dist/guards/access-token.guard.js +6 -2
- package/dist/guards/access-token.guard.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/services/chatter-message-details.service.d.ts +1 -3
- package/dist/services/chatter-message-details.service.d.ts.map +1 -1
- package/dist/services/chatter-message-details.service.js +3 -6
- package/dist/services/chatter-message-details.service.js.map +1 -1
- package/dist/services/chatter-message.service.d.ts +7 -8
- package/dist/services/chatter-message.service.d.ts.map +1 -1
- package/dist/services/chatter-message.service.js +28 -19
- package/dist/services/chatter-message.service.js.map +1 -1
- package/dist/services/crud.service.d.ts +1 -3
- package/dist/services/crud.service.d.ts.map +1 -1
- package/dist/services/crud.service.js +3 -42
- package/dist/services/crud.service.js.map +1 -1
- package/dist/services/field-metadata.service.d.ts.map +1 -1
- package/dist/services/field-metadata.service.js +23 -11
- package/dist/services/field-metadata.service.js.map +1 -1
- package/dist/services/request-context.service.d.ts +4 -4
- package/dist/services/request-context.service.d.ts.map +1 -1
- package/dist/services/request-context.service.js +6 -10
- package/dist/services/request-context.service.js.map +1 -1
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +6 -2
- package/dist/solid-core.module.js.map +1 -1
- package/dist/subscribers/audit.subscriber.d.ts +1 -3
- package/dist/subscribers/audit.subscriber.d.ts.map +1 -1
- package/dist/subscribers/audit.subscriber.js +7 -12
- package/dist/subscribers/audit.subscriber.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -1
- package/src/controllers/chatter-message.controller.ts +1 -2
- package/src/decorators/active-user.decorator.ts +1 -0
- package/src/decorators/solid-request-context.decorator.ts +2 -1
- package/src/guards/access-token.guard.ts +3 -0
- package/src/index.ts +0 -1
- package/src/services/chatter-message-details.service.ts +1 -3
- package/src/services/chatter-message.service.ts +29 -20
- package/src/services/crud.service.ts +0 -8
- package/src/services/field-metadata.service.ts +23 -12
- package/src/services/request-context.service.ts +5 -6
- package/src/solid-core.module.ts +5 -2
- package/src/subscribers/audit.subscriber.ts +5 -9
- package/dist/services/user-context.service.d.ts +0 -10
- package/dist/services/user-context.service.d.ts.map +0 -1
- package/dist/services/user-context.service.js +0 -42
- package/dist/services/user-context.service.js.map +0 -1
- package/src/services/user-context.service.ts +0 -31
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidstarters/solid-core",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.66",
|
|
4
4
|
"description": "This module is a NestJS module containing all the required core providers required by a Solid application",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"mailgen": "^2.0.28",
|
|
52
52
|
"mongoose": "^8.7.0",
|
|
53
53
|
"mysql2": "^3.13.0",
|
|
54
|
+
"nestjs-cls": "^5.4.3",
|
|
54
55
|
"nodemailer": "^6.9.13",
|
|
55
56
|
"passport": "^0.7.0",
|
|
56
57
|
"passport-google-oauth2": "^0.2.0",
|
|
@@ -98,8 +98,7 @@ export class ChatterMessageController {
|
|
|
98
98
|
async postMessage(
|
|
99
99
|
@Body() postDto: PostChatterMessageDto,
|
|
100
100
|
@UploadedFiles() files: Array<Express.Multer.File>,
|
|
101
|
-
@SolidRequestContextDecorator() solidRequestContext: SolidRequestContextDto
|
|
102
101
|
) {
|
|
103
|
-
return this.service.postMessage(postDto,
|
|
102
|
+
return this.service.postMessage(postDto, files);
|
|
104
103
|
}
|
|
105
104
|
}
|
|
@@ -5,6 +5,7 @@ import { REQUEST_USER_KEY } from "../constants";
|
|
|
5
5
|
export const ActiveUser = createParamDecorator(
|
|
6
6
|
(field: keyof ActiveUserData | undefined, ctx: ExecutionContext) => {
|
|
7
7
|
const request = ctx.switchToHttp().getRequest();
|
|
8
|
+
// TODO idealiy we should use RequestContextService and getActiveUser method. (Works for async scenarios too)
|
|
8
9
|
const user: ActiveUserData | undefined = request[REQUEST_USER_KEY];
|
|
9
10
|
return field ? user?.[field] : user;
|
|
10
11
|
},
|
|
@@ -6,7 +6,8 @@ import { SolidRequestContextDto } from 'src/dtos/solid-request-context.dto';
|
|
|
6
6
|
export const SolidRequestContextDecorator = createParamDecorator(
|
|
7
7
|
(data: unknown, ctx: ExecutionContext): SolidRequestContextDto => {
|
|
8
8
|
const request = ctx.switchToHttp().getRequest();
|
|
9
|
-
|
|
9
|
+
// TODO idealiy we should use RequestContextService and getActiveUser method. (Works for async scenarios too)
|
|
10
|
+
const activeUser: ActiveUserData | undefined = request[REQUEST_USER_KEY];
|
|
10
11
|
|
|
11
12
|
// Create a new instance of SolidRequestContextDto and stamp user data
|
|
12
13
|
const solidRequestContext = new SolidRequestContextDto();
|
|
@@ -12,6 +12,7 @@ import { ActiveUserData } from '../interfaces/active-user-data.interface';
|
|
|
12
12
|
import { jwtConfig } from '../config/iam.config';
|
|
13
13
|
import { REQUEST_USER_KEY } from "../constants";
|
|
14
14
|
import { PermissionMetadataService } from '../services/permission-metadata.service';
|
|
15
|
+
import { ClsService } from 'nestjs-cls';
|
|
15
16
|
|
|
16
17
|
@Injectable()
|
|
17
18
|
export class AccessTokenGuard implements CanActivate {
|
|
@@ -20,6 +21,7 @@ export class AccessTokenGuard implements CanActivate {
|
|
|
20
21
|
@Inject(jwtConfig.KEY)
|
|
21
22
|
private readonly jwtConfiguration: ConfigType<typeof jwtConfig>,
|
|
22
23
|
private readonly permissionsService: PermissionMetadataService,
|
|
24
|
+
private readonly cls: ClsService
|
|
23
25
|
) { }
|
|
24
26
|
|
|
25
27
|
async canActivate(context: ExecutionContext): Promise<boolean> {
|
|
@@ -40,6 +42,7 @@ export class AccessTokenGuard implements CanActivate {
|
|
|
40
42
|
payload.permissions = permissions.map((permission) => permission.name);
|
|
41
43
|
|
|
42
44
|
request[REQUEST_USER_KEY] = payload;
|
|
45
|
+
this.cls.set(REQUEST_USER_KEY, payload);
|
|
43
46
|
// console.log(`About to set payload in the request user key:`);
|
|
44
47
|
// console.log(payload);
|
|
45
48
|
} catch {
|
package/src/index.ts
CHANGED
|
@@ -228,7 +228,6 @@ export * from './services/security-rule.service'
|
|
|
228
228
|
export * from './services/request-context.service'
|
|
229
229
|
export * from './services/chatter-message.service'
|
|
230
230
|
export * from './services/chatter-message-details.service'
|
|
231
|
-
export * from './services/user-context.service'
|
|
232
231
|
// Repositories
|
|
233
232
|
export * from './repository/solid-base.repository'
|
|
234
233
|
export * from './repository/security-rule.repository'
|
|
@@ -11,7 +11,6 @@ import { FileService } from 'src/services/file.service';
|
|
|
11
11
|
import { CrudHelperService } from 'src/services/crud-helper.service';
|
|
12
12
|
|
|
13
13
|
import { ChatterMessageDetails } from '../entities/chatter-message-details.entity';
|
|
14
|
-
import { UserContextService } from './user-context.service';
|
|
15
14
|
|
|
16
15
|
@Injectable()
|
|
17
16
|
export class ChatterMessageDetailsService extends CRUDService<ChatterMessageDetails>{
|
|
@@ -27,8 +26,7 @@ export class ChatterMessageDetailsService extends CRUDService<ChatterMessageDeta
|
|
|
27
26
|
@InjectRepository(ChatterMessageDetails, 'default')
|
|
28
27
|
readonly repo: Repository<ChatterMessageDetails>,
|
|
29
28
|
readonly moduleRef: ModuleRef,
|
|
30
|
-
readonly userContextService: UserContextService
|
|
31
29
|
) {
|
|
32
|
-
super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService, entityManager, repo, 'chatterMessageDetails', 'solid-core', moduleRef
|
|
30
|
+
super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService, entityManager, repo, 'chatterMessageDetails', 'solid-core', moduleRef);
|
|
33
31
|
}
|
|
34
32
|
}
|
|
@@ -16,7 +16,7 @@ import { getMediaStorageProvider } from './mediaStorageProviders';
|
|
|
16
16
|
import { MediaStorageProviderType } from '../dtos/create-media-storage-provider-metadata.dto';
|
|
17
17
|
import { ChatterMessageDetails } from '../entities/chatter-message-details.entity';
|
|
18
18
|
import { ModelMetadata } from 'src/entities/model-metadata.entity';
|
|
19
|
-
import {
|
|
19
|
+
import { RequestContextService } from './request-context.service';
|
|
20
20
|
@Injectable()
|
|
21
21
|
export class ChatterMessageService extends CRUDService<ChatterMessage>{
|
|
22
22
|
constructor(
|
|
@@ -35,24 +35,27 @@ export class ChatterMessageService extends CRUDService<ChatterMessage>{
|
|
|
35
35
|
readonly moduleRef: ModuleRef,
|
|
36
36
|
@InjectRepository(ModelMetadata)
|
|
37
37
|
private readonly modelMetadataRepo: Repository<ModelMetadata>,
|
|
38
|
-
readonly
|
|
38
|
+
readonly requestContextService: RequestContextService
|
|
39
39
|
) {
|
|
40
|
-
super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService,entityManager, repo, 'chatterMessage', 'solid-core', moduleRef
|
|
40
|
+
super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService,entityManager, repo, 'chatterMessage', 'solid-core', moduleRef);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
async postMessage(postDto: PostChatterMessageDto,
|
|
43
|
+
async postMessage(postDto: PostChatterMessageDto, files: Express.Multer.File[] = []) {
|
|
44
44
|
const chatterMessage = new ChatterMessage();
|
|
45
45
|
chatterMessage.messageType = 'custom';
|
|
46
|
-
chatterMessage.messageSubType = postDto.messageSubType || '
|
|
46
|
+
chatterMessage.messageSubType = postDto.messageSubType || 'post_message';
|
|
47
47
|
chatterMessage.messageBody = postDto.messageBody;
|
|
48
48
|
chatterMessage.coModelEntityId = postDto.coModelEntityId;
|
|
49
49
|
chatterMessage.coModelName = postDto.coModelName;
|
|
50
50
|
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
const activeUser = this.requestContextService.getActiveUser();
|
|
52
|
+
|
|
53
|
+
if (activeUser) {
|
|
54
|
+
const userId = activeUser?.sub;
|
|
55
|
+
chatterMessage.user = { id: userId } as any;
|
|
56
|
+
} else {
|
|
57
|
+
chatterMessage.user = null;
|
|
58
|
+
}
|
|
56
59
|
|
|
57
60
|
const savedMessage = await this.repo.save(chatterMessage);
|
|
58
61
|
|
|
@@ -81,7 +84,7 @@ export class ChatterMessageService extends CRUDService<ChatterMessage>{
|
|
|
81
84
|
return savedMessage;
|
|
82
85
|
}
|
|
83
86
|
|
|
84
|
-
async postAuditMessageOnInsert(entity: any, metadata: EntityMetadata,
|
|
87
|
+
async postAuditMessageOnInsert(entity: any, metadata: EntityMetadata, messageQueue: boolean = false) {
|
|
85
88
|
const model = await this.modelMetadataRepo.findOne({
|
|
86
89
|
where: {
|
|
87
90
|
displayName: metadata.name
|
|
@@ -98,9 +101,12 @@ export class ChatterMessageService extends CRUDService<ChatterMessage>{
|
|
|
98
101
|
|
|
99
102
|
const auditFields = model.fields.filter(field =>
|
|
100
103
|
field.enableAuditTracking &&
|
|
101
|
-
!['
|
|
104
|
+
!['mediaSingle', 'mediaMultiple', 'computed', 'richText', 'json'].includes(field.type) &&
|
|
105
|
+
!(field.type === 'relation' && field.relationType === 'one-to-many')
|
|
102
106
|
);
|
|
103
107
|
|
|
108
|
+
const activeUser = this.requestContextService.getActiveUser();
|
|
109
|
+
|
|
104
110
|
const chatterMessage = new ChatterMessage();
|
|
105
111
|
chatterMessage.messageType = 'audit';
|
|
106
112
|
chatterMessage.messageSubType = 'insert';
|
|
@@ -109,7 +115,7 @@ export class ChatterMessageService extends CRUDService<ChatterMessage>{
|
|
|
109
115
|
chatterMessage.messageBody = `New ${model.displayName} created`;
|
|
110
116
|
|
|
111
117
|
if (activeUser) {
|
|
112
|
-
const userId =
|
|
118
|
+
const userId = activeUser?.sub;
|
|
113
119
|
chatterMessage.user = { id: userId } as any;
|
|
114
120
|
} else {
|
|
115
121
|
chatterMessage.user = null;
|
|
@@ -132,7 +138,7 @@ export class ChatterMessageService extends CRUDService<ChatterMessage>{
|
|
|
132
138
|
}
|
|
133
139
|
}
|
|
134
140
|
|
|
135
|
-
async postAuditMessageOnUpdate(entity: any, metadata: EntityMetadata, databaseEntity: any,
|
|
141
|
+
async postAuditMessageOnUpdate(entity: any, metadata: EntityMetadata, databaseEntity: any, messageQueue: boolean = false) {
|
|
136
142
|
const model = await this.modelMetadataRepo.findOne({
|
|
137
143
|
where: {
|
|
138
144
|
displayName: metadata.name
|
|
@@ -149,7 +155,8 @@ async postAuditMessageOnUpdate(entity: any, metadata: EntityMetadata, databaseEn
|
|
|
149
155
|
|
|
150
156
|
const auditFields = model.fields.filter(field =>
|
|
151
157
|
field.enableAuditTracking &&
|
|
152
|
-
!['
|
|
158
|
+
!['mediaSingle', 'mediaMultiple', 'computed', 'richText', 'json'].includes(field.type) &&
|
|
159
|
+
!(field.type === 'relation' && field.relationType === 'one-to-many')
|
|
153
160
|
);
|
|
154
161
|
|
|
155
162
|
const relationFields = auditFields.filter(field =>
|
|
@@ -164,16 +171,16 @@ async postAuditMessageOnUpdate(entity: any, metadata: EntityMetadata, databaseEn
|
|
|
164
171
|
databaseEntity = populatedEntity;
|
|
165
172
|
}
|
|
166
173
|
}
|
|
167
|
-
|
|
168
174
|
const changedFields = auditFields.filter(field => {
|
|
169
175
|
const newValue = entity[field.name];
|
|
170
176
|
const oldValue = databaseEntity[field.name];
|
|
171
177
|
return this.hasValueChanged(newValue, oldValue);
|
|
172
178
|
});
|
|
173
|
-
|
|
179
|
+
|
|
174
180
|
if (changedFields.length === 0) {
|
|
175
181
|
return;
|
|
176
182
|
}
|
|
183
|
+
const activeUser = this.requestContextService.getActiveUser();
|
|
177
184
|
|
|
178
185
|
const chatterMessage = new ChatterMessage();
|
|
179
186
|
chatterMessage.messageType = 'audit';
|
|
@@ -183,7 +190,7 @@ async postAuditMessageOnUpdate(entity: any, metadata: EntityMetadata, databaseEn
|
|
|
183
190
|
chatterMessage.messageBody = `${model.displayName} updated`;
|
|
184
191
|
|
|
185
192
|
if (activeUser) {
|
|
186
|
-
const userId =
|
|
193
|
+
const userId = activeUser?.sub;
|
|
187
194
|
chatterMessage.user = { id: userId } as any;
|
|
188
195
|
} else {
|
|
189
196
|
chatterMessage.user = null;
|
|
@@ -203,7 +210,7 @@ async postAuditMessageOnUpdate(entity: any, metadata: EntityMetadata, databaseEn
|
|
|
203
210
|
}
|
|
204
211
|
}
|
|
205
212
|
|
|
206
|
-
async postAuditMessageOnDelete(entity: any, metadata: EntityMetadata, databaseEntity: any,
|
|
213
|
+
async postAuditMessageOnDelete(entity: any, metadata: EntityMetadata, databaseEntity: any, messageQueue: boolean = false) {
|
|
207
214
|
const model = await this.modelMetadataRepo.findOne({
|
|
208
215
|
where: {
|
|
209
216
|
displayName: metadata.name
|
|
@@ -225,8 +232,10 @@ async postAuditMessageOnDelete(entity: any, metadata: EntityMetadata, databaseEn
|
|
|
225
232
|
chatterMessage.coModelName = model.singularName;
|
|
226
233
|
chatterMessage.messageBody = `${model.displayName} deleted`;
|
|
227
234
|
|
|
235
|
+
const activeUser = this.requestContextService.getActiveUser();
|
|
236
|
+
|
|
228
237
|
if (activeUser) {
|
|
229
|
-
const userId =
|
|
238
|
+
const userId = activeUser?.sub;
|
|
230
239
|
chatterMessage.user = { id: userId } as any;
|
|
231
240
|
} else {
|
|
232
241
|
chatterMessage.user = null;
|
|
@@ -34,7 +34,6 @@ import { FileService } from "./file.service";
|
|
|
34
34
|
import { getMediaStorageProvider } from "./mediaStorageProviders";
|
|
35
35
|
import { ModelMetadataService } from "./model-metadata.service";
|
|
36
36
|
import { ModuleMetadataService } from "./module-metadata.service";
|
|
37
|
-
import { UserContextService } from "./user-context.service";
|
|
38
37
|
const DEFAULT_LIMIT = 10;
|
|
39
38
|
const DEFAULT_OFFSET = 0;
|
|
40
39
|
export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDto, so we get the proper types in our service
|
|
@@ -51,7 +50,6 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
51
50
|
readonly modelName: string,
|
|
52
51
|
readonly moduleName: string,
|
|
53
52
|
readonly moduleRef: ModuleRef,
|
|
54
|
-
@Optional() readonly userContextService?: UserContextService
|
|
55
53
|
//We can just have the Model Entity here
|
|
56
54
|
) { }
|
|
57
55
|
|
|
@@ -67,9 +65,6 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
67
65
|
// Check wheather user has create permission for model
|
|
68
66
|
if (solidRequestContext.activeUser) {
|
|
69
67
|
const hasPermission = this.crudHelperService.hasCreatePermissionOnModel(solidRequestContext.activeUser, model.singularName);
|
|
70
|
-
if (this.userContextService) {
|
|
71
|
-
this.userContextService.setUser(solidRequestContext.activeUser);
|
|
72
|
-
}
|
|
73
68
|
if (!hasPermission) {
|
|
74
69
|
throw new BadRequestException('Forbidden');
|
|
75
70
|
}
|
|
@@ -164,9 +159,6 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
164
159
|
// Check wheather user has update permission for model
|
|
165
160
|
if (solidRequestContext.activeUser) {
|
|
166
161
|
const hasPermission = this.crudHelperService.hasUpdatePermissionOnModel(solidRequestContext.activeUser, model.singularName);
|
|
167
|
-
if (this.userContextService) {
|
|
168
|
-
this.userContextService.setUser(solidRequestContext.activeUser);
|
|
169
|
-
}
|
|
170
162
|
if (!hasPermission) {
|
|
171
163
|
throw new BadRequestException('Forbidden');
|
|
172
164
|
}
|
|
@@ -503,6 +503,7 @@ export class FieldMetadataService {
|
|
|
503
503
|
"encryptionType",
|
|
504
504
|
"decryptWhen",
|
|
505
505
|
"columnName",
|
|
506
|
+
"enableAuditTracking"
|
|
506
507
|
];
|
|
507
508
|
|
|
508
509
|
case SolidFieldType.bigint:
|
|
@@ -521,7 +522,8 @@ export class FieldMetadataService {
|
|
|
521
522
|
"encrypt",
|
|
522
523
|
"encryptionType",
|
|
523
524
|
"decryptWhen",
|
|
524
|
-
"columnName"
|
|
525
|
+
"columnName",
|
|
526
|
+
"enableAuditTracking"
|
|
525
527
|
];
|
|
526
528
|
|
|
527
529
|
// case SolidFieldType.float:
|
|
@@ -560,7 +562,8 @@ export class FieldMetadataService {
|
|
|
560
562
|
"encrypt",
|
|
561
563
|
"encryptionType",
|
|
562
564
|
"decryptWhen",
|
|
563
|
-
"columnName"
|
|
565
|
+
"columnName",
|
|
566
|
+
"enableAuditTracking"
|
|
564
567
|
];
|
|
565
568
|
|
|
566
569
|
case SolidFieldType.shortText:
|
|
@@ -582,7 +585,8 @@ export class FieldMetadataService {
|
|
|
582
585
|
"encryptionType",
|
|
583
586
|
"decryptWhen",
|
|
584
587
|
"columnName",
|
|
585
|
-
"isUserKey"
|
|
588
|
+
"isUserKey",
|
|
589
|
+
"enableAuditTracking"
|
|
586
590
|
];
|
|
587
591
|
|
|
588
592
|
case SolidFieldType.longtext:
|
|
@@ -665,7 +669,8 @@ export class FieldMetadataService {
|
|
|
665
669
|
"encrypt",
|
|
666
670
|
"encryptionType",
|
|
667
671
|
"decryptWhen",
|
|
668
|
-
"columnName"
|
|
672
|
+
"columnName",
|
|
673
|
+
"enableAuditTracking"
|
|
669
674
|
];
|
|
670
675
|
|
|
671
676
|
case SolidFieldType.date:
|
|
@@ -684,7 +689,8 @@ export class FieldMetadataService {
|
|
|
684
689
|
"encrypt",
|
|
685
690
|
"encryptionType",
|
|
686
691
|
"decryptWhen",
|
|
687
|
-
"columnName"
|
|
692
|
+
"columnName",
|
|
693
|
+
"enableAuditTracking"
|
|
688
694
|
];
|
|
689
695
|
|
|
690
696
|
case SolidFieldType.datetime:
|
|
@@ -703,7 +709,8 @@ export class FieldMetadataService {
|
|
|
703
709
|
"encrypt",
|
|
704
710
|
"encryptionType",
|
|
705
711
|
"decryptWhen",
|
|
706
|
-
"columnName"
|
|
712
|
+
"columnName",
|
|
713
|
+
"enableAuditTracking"
|
|
707
714
|
];
|
|
708
715
|
|
|
709
716
|
case SolidFieldType.time:
|
|
@@ -722,7 +729,8 @@ export class FieldMetadataService {
|
|
|
722
729
|
"encrypt",
|
|
723
730
|
"encryptionType",
|
|
724
731
|
"decryptWhen",
|
|
725
|
-
"columnName"
|
|
732
|
+
"columnName",
|
|
733
|
+
"enableAuditTracking"
|
|
726
734
|
];
|
|
727
735
|
|
|
728
736
|
case SolidFieldType.relation:
|
|
@@ -750,7 +758,8 @@ export class FieldMetadataService {
|
|
|
750
758
|
"columnName",
|
|
751
759
|
"relationJoinTableName",
|
|
752
760
|
"isRelationManyToManyOwner",
|
|
753
|
-
"relationFieldFixedFilter"
|
|
761
|
+
"relationFieldFixedFilter",
|
|
762
|
+
"enableAuditTracking"
|
|
754
763
|
];
|
|
755
764
|
|
|
756
765
|
case SolidFieldType.mediaSingle:
|
|
@@ -812,7 +821,8 @@ export class FieldMetadataService {
|
|
|
812
821
|
"encrypt",
|
|
813
822
|
"encryptionType",
|
|
814
823
|
"decryptWhen",
|
|
815
|
-
"columnName"
|
|
824
|
+
"columnName",
|
|
825
|
+
"enableAuditTracking"
|
|
816
826
|
];
|
|
817
827
|
|
|
818
828
|
case SolidFieldType.password:
|
|
@@ -855,7 +865,8 @@ export class FieldMetadataService {
|
|
|
855
865
|
"encrypt",
|
|
856
866
|
"encryptionType",
|
|
857
867
|
"decryptWhen",
|
|
858
|
-
"columnName"
|
|
868
|
+
"columnName",
|
|
869
|
+
"enableAuditTracking"
|
|
859
870
|
];
|
|
860
871
|
|
|
861
872
|
case SolidFieldType.selectionDynamic:
|
|
@@ -877,8 +888,8 @@ export class FieldMetadataService {
|
|
|
877
888
|
"encryptionType",
|
|
878
889
|
"decryptWhen",
|
|
879
890
|
"columnName",
|
|
880
|
-
"isUserKey"
|
|
881
|
-
|
|
891
|
+
"isUserKey",
|
|
892
|
+
"enableAuditTracking"
|
|
882
893
|
];
|
|
883
894
|
case SolidFieldType.computed:
|
|
884
895
|
return [
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Injectable } from "@nestjs/common";
|
|
2
|
+
import { ClsService } from "nestjs-cls";
|
|
3
3
|
import { REQUEST_USER_KEY } from "src/constants";
|
|
4
|
-
import { ActiveUserData } from "src/interfaces/active-user-data.interface";
|
|
5
4
|
|
|
6
|
-
@Injectable(
|
|
5
|
+
@Injectable()
|
|
7
6
|
export class RequestContextService {
|
|
8
|
-
constructor(
|
|
7
|
+
constructor(private readonly cls: ClsService) {
|
|
9
8
|
}
|
|
10
9
|
|
|
11
10
|
// This method i.e getActiveUser() will fetch the user from the request object in the context
|
|
12
11
|
getActiveUser() {
|
|
13
|
-
return this.
|
|
12
|
+
return this.cls.get(REQUEST_USER_KEY);
|
|
14
13
|
}
|
|
15
14
|
|
|
16
15
|
}
|
package/src/solid-core.module.ts
CHANGED
|
@@ -161,7 +161,7 @@ import { ChatterMessageDetails } from './entities/chatter-message-details.entity
|
|
|
161
161
|
import { ChatterMessageDetailsService } from './services/chatter-message-details.service';
|
|
162
162
|
import { ChatterMessageDetailsController } from './controllers/chatter-message-details.controller';
|
|
163
163
|
import { AuditSubscriber } from './subscribers/audit.subscriber';
|
|
164
|
-
import {
|
|
164
|
+
import { ClsModule } from 'nestjs-cls';
|
|
165
165
|
|
|
166
166
|
@Global()
|
|
167
167
|
@Module({
|
|
@@ -213,6 +213,10 @@ import { UserContextService } from './services/user-context.service';
|
|
|
213
213
|
TypeOrmModule.forFeature([ChatterMessage]),
|
|
214
214
|
TypeOrmModule.forFeature([ChatterMessageDetails]),
|
|
215
215
|
// TypeOrmModule.forFeature([User]),
|
|
216
|
+
ClsModule.forRoot({
|
|
217
|
+
middleware: {
|
|
218
|
+
mount: true,
|
|
219
|
+
}}),
|
|
216
220
|
],
|
|
217
221
|
controllers: [
|
|
218
222
|
ModuleMetadataController,
|
|
@@ -348,7 +352,6 @@ import { UserContextService } from './services/user-context.service';
|
|
|
348
352
|
ChatterMessageService,
|
|
349
353
|
ChatterMessageDetailsService,
|
|
350
354
|
AuditSubscriber,
|
|
351
|
-
UserContextService,
|
|
352
355
|
],
|
|
353
356
|
exports: [
|
|
354
357
|
ModuleMetadataService,
|
|
@@ -5,7 +5,6 @@ import { InjectRepository } from '@nestjs/typeorm';
|
|
|
5
5
|
import { ModelMetadata } from '../entities/model-metadata.entity';
|
|
6
6
|
import { Repository } from 'typeorm';
|
|
7
7
|
import { Injectable } from '@nestjs/common';
|
|
8
|
-
import { UserContextService } from '../services/user-context.service';
|
|
9
8
|
@Injectable()
|
|
10
9
|
@EventSubscriber()
|
|
11
10
|
export class AuditSubscriber implements EntitySubscriberInterface {
|
|
@@ -15,7 +14,6 @@ export class AuditSubscriber implements EntitySubscriberInterface {
|
|
|
15
14
|
private readonly chatterMessageService: ChatterMessageService,
|
|
16
15
|
@InjectRepository(ModelMetadata)
|
|
17
16
|
private readonly modelMetadataRepo: Repository<ModelMetadata>,
|
|
18
|
-
private readonly userContextService: UserContextService
|
|
19
17
|
) {
|
|
20
18
|
connection.subscribers.push(this);
|
|
21
19
|
}
|
|
@@ -37,7 +35,8 @@ export class AuditSubscriber implements EntitySubscriberInterface {
|
|
|
37
35
|
|
|
38
36
|
const auditFields = model.fields.filter(field =>
|
|
39
37
|
field.enableAuditTracking &&
|
|
40
|
-
!['
|
|
38
|
+
!['mediaSingle', 'mediaMultiple', 'computed', 'richText', 'json'].includes(field.type) &&
|
|
39
|
+
!(field.type === 'relation' && field.relationType === 'one-to-many')
|
|
41
40
|
);
|
|
42
41
|
|
|
43
42
|
if (auditFields.length === 0) {
|
|
@@ -52,22 +51,19 @@ export class AuditSubscriber implements EntitySubscriberInterface {
|
|
|
52
51
|
|
|
53
52
|
async afterInsert(event: InsertEvent<any>) {
|
|
54
53
|
if (await this.shouldTrackAudit(event.entity, event.metadata)) {
|
|
55
|
-
|
|
56
|
-
await this.chatterMessageService.postAuditMessageOnInsert(event.entity, event.metadata, activeUser);
|
|
54
|
+
await this.chatterMessageService.postAuditMessageOnInsert(event.entity, event.metadata);
|
|
57
55
|
}
|
|
58
56
|
}
|
|
59
57
|
|
|
60
58
|
async afterUpdate(event: UpdateEvent<any>) {
|
|
61
59
|
if (await this.shouldTrackAudit(event.entity, event.metadata)) {
|
|
62
|
-
|
|
63
|
-
await this.chatterMessageService.postAuditMessageOnUpdate(event.entity, event.metadata, event.databaseEntity, activeUser);
|
|
60
|
+
await this.chatterMessageService.postAuditMessageOnUpdate(event.entity, event.metadata, event.databaseEntity);
|
|
64
61
|
}
|
|
65
62
|
}
|
|
66
63
|
|
|
67
64
|
async afterRemove(event: RemoveEvent<any>) {
|
|
68
65
|
if (await this.shouldTrackAudit(event.entity, event.metadata)) {
|
|
69
|
-
|
|
70
|
-
await this.chatterMessageService.postAuditMessageOnDelete(event.entity, event.metadata, event.databaseEntity, activeUser);
|
|
66
|
+
await this.chatterMessageService.postAuditMessageOnDelete(event.entity, event.metadata, event.databaseEntity);
|
|
71
67
|
}
|
|
72
68
|
}
|
|
73
69
|
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { ActiveUserData } from '../interfaces/active-user-data.interface';
|
|
2
|
-
export declare class UserContextService {
|
|
3
|
-
private readonly logger;
|
|
4
|
-
private static currentUser;
|
|
5
|
-
setUser(user: any): void;
|
|
6
|
-
getUser(): any;
|
|
7
|
-
runWithUser<T>(user: any, callback: () => T): T;
|
|
8
|
-
getCurrentUser(): ActiveUserData | null;
|
|
9
|
-
}
|
|
10
|
-
//# sourceMappingURL=user-context.service.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"user-context.service.d.ts","sourceRoot":"","sources":["../../src/services/user-context.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAE1E,qBACa,kBAAkB;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,OAAO,CAAC,MAAM,CAAC,WAAW,CAAa;IAEvC,OAAO,CAAC,IAAI,EAAE,GAAG;IAKjB,OAAO;IAIP,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC;IAU/C,cAAc,IAAI,cAAc,GAAG,IAAI;CAG1C"}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var UserContextService_1;
|
|
9
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.UserContextService = void 0;
|
|
11
|
-
const common_1 = require("@nestjs/common");
|
|
12
|
-
let UserContextService = UserContextService_1 = class UserContextService {
|
|
13
|
-
constructor() {
|
|
14
|
-
this.logger = new common_1.Logger(UserContextService_1.name);
|
|
15
|
-
}
|
|
16
|
-
setUser(user) {
|
|
17
|
-
this.logger.debug(`Setting user: ${JSON.stringify(user)}`);
|
|
18
|
-
UserContextService_1.currentUser = user;
|
|
19
|
-
}
|
|
20
|
-
getUser() {
|
|
21
|
-
return UserContextService_1.currentUser;
|
|
22
|
-
}
|
|
23
|
-
runWithUser(user, callback) {
|
|
24
|
-
const previousUser = this.getUser();
|
|
25
|
-
try {
|
|
26
|
-
this.setUser(user);
|
|
27
|
-
return callback();
|
|
28
|
-
}
|
|
29
|
-
finally {
|
|
30
|
-
this.setUser(previousUser);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
getCurrentUser() {
|
|
34
|
-
return this.getUser();
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
exports.UserContextService = UserContextService;
|
|
38
|
-
UserContextService.currentUser = null;
|
|
39
|
-
exports.UserContextService = UserContextService = UserContextService_1 = __decorate([
|
|
40
|
-
(0, common_1.Injectable)()
|
|
41
|
-
], UserContextService);
|
|
42
|
-
//# sourceMappingURL=user-context.service.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"user-context.service.js","sourceRoot":"","sources":["../../src/services/user-context.service.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAoD;AAI7C,IAAM,kBAAkB,0BAAxB,MAAM,kBAAkB;IAAxB;QACc,WAAM,GAAG,IAAI,eAAM,CAAC,oBAAkB,CAAC,IAAI,CAAC,CAAC;IAyBlE,CAAC;IAtBG,OAAO,CAAC,IAAS;QACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3D,oBAAkB,CAAC,WAAW,GAAG,IAAI,CAAC;IAC1C,CAAC;IAED,OAAO;QACH,OAAO,oBAAkB,CAAC,WAAW,CAAC;IAC1C,CAAC;IAED,WAAW,CAAI,IAAS,EAAE,QAAiB;QACvC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QACpC,IAAI,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACnB,OAAO,QAAQ,EAAE,CAAC;QACtB,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAC/B,CAAC;IACL,CAAC;IAED,cAAc;QACV,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;IAC1B,CAAC;;AAzBQ,gDAAkB;AAEZ,8BAAW,GAAQ,IAAI,AAAZ,CAAa;6BAF9B,kBAAkB;IAD9B,IAAA,mBAAU,GAAE;GACA,kBAAkB,CA0B9B"}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { Injectable, Logger } from '@nestjs/common';
|
|
2
|
-
import { ActiveUserData } from '../interfaces/active-user-data.interface';
|
|
3
|
-
|
|
4
|
-
@Injectable()
|
|
5
|
-
export class UserContextService {
|
|
6
|
-
private readonly logger = new Logger(UserContextService.name);
|
|
7
|
-
private static currentUser: any = null;
|
|
8
|
-
|
|
9
|
-
setUser(user: any) {
|
|
10
|
-
this.logger.debug(`Setting user: ${JSON.stringify(user)}`);
|
|
11
|
-
UserContextService.currentUser = user;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
getUser() {
|
|
15
|
-
return UserContextService.currentUser;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
runWithUser<T>(user: any, callback: () => T): T {
|
|
19
|
-
const previousUser = this.getUser();
|
|
20
|
-
try {
|
|
21
|
-
this.setUser(user);
|
|
22
|
-
return callback();
|
|
23
|
-
} finally {
|
|
24
|
-
this.setUser(previousUser);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
getCurrentUser(): ActiveUserData | null {
|
|
29
|
-
return this.getUser();
|
|
30
|
-
}
|
|
31
|
-
}
|