@solidstarters/solid-core 1.2.64 → 1.2.67
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/providers/list-of-values-selection-providers.service.d.ts.map +1 -1
- package/dist/providers/list-of-values-selection-providers.service.js +15 -5
- package/dist/providers/list-of-values-selection-providers.service.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +9 -51
- package/dist/services/authentication.service.d.ts +3 -1
- package/dist/services/authentication.service.d.ts.map +1 -1
- package/dist/services/authentication.service.js +12 -3
- package/dist/services/authentication.service.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/model-metadata.service.d.ts.map +1 -1
- package/dist/services/model-metadata.service.js +11 -9
- package/dist/services/model-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/services/user.service.d.ts +1 -1
- package/dist/services/user.service.d.ts.map +1 -1
- package/dist/services/user.service.js +2 -2
- package/dist/services/user.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/providers/list-of-values-selection-providers.service.ts +14 -5
- package/src/seeders/seed-data/solid-core-metadata.json +12 -56
- package/src/services/authentication.service.ts +16 -4
- 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/model-metadata.service.ts +15 -12
- package/src/services/request-context.service.ts +5 -6
- package/src/services/user.service.ts +6 -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.67",
|
|
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'
|
|
@@ -34,12 +34,21 @@ export class ListOfValuesSelectionProvider implements ISelectionProvider<ListOfV
|
|
|
34
34
|
|
|
35
35
|
async values(query: string, ctxt: ListOfValuesProviderContext): Promise<readonly ISelectionProviderValues[]> {
|
|
36
36
|
const basicFilterQuery = new BasicFilterDto(DEFAULT_LIMIT, 0);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
if (ctxt.type) {
|
|
38
|
+
basicFilterQuery.filters = {
|
|
39
|
+
type: {
|
|
40
|
+
$eq: ctxt.type
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
if (query) {
|
|
45
|
+
basicFilterQuery.filters = {
|
|
46
|
+
...basicFilterQuery.filters,
|
|
47
|
+
display: {
|
|
48
|
+
$containsi: `%${query}%`
|
|
49
|
+
}
|
|
50
|
+
};
|
|
41
51
|
}
|
|
42
|
-
|
|
43
52
|
const lovs = await this.listOfValuesService.find(basicFilterQuery);
|
|
44
53
|
const selectionValues = lovs.records.map(lov => {
|
|
45
54
|
return {
|
|
@@ -3807,7 +3807,7 @@
|
|
|
3807
3807
|
"name": "media-menu-item",
|
|
3808
3808
|
"sequenceNumber": 3,
|
|
3809
3809
|
"actionUserKey": "media-root",
|
|
3810
|
-
"moduleUserKey": "solid-core",
|
|
3810
|
+
"moduleUserKey": "solid-core",
|
|
3811
3811
|
"parentMenuItemUserKey": ""
|
|
3812
3812
|
},
|
|
3813
3813
|
{
|
|
@@ -3980,32 +3980,11 @@
|
|
|
3980
3980
|
{
|
|
3981
3981
|
"attrs": {
|
|
3982
3982
|
"className": "pi pi-cog",
|
|
3983
|
-
"label": "Generate Code"
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
"
|
|
3987
|
-
"
|
|
3988
|
-
"confirmBtnLabel": "Generate Code",
|
|
3989
|
-
"cancelBtnLabel": "Cancel",
|
|
3990
|
-
"customComponent": "GenerateModuleCodeRowAction",
|
|
3991
|
-
"customComponentIsSystem": true,
|
|
3992
|
-
"endpoint": ""
|
|
3993
|
-
}
|
|
3994
|
-
}
|
|
3995
|
-
],
|
|
3996
|
-
"headerButtons": [
|
|
3997
|
-
{
|
|
3998
|
-
"attrs": {
|
|
3999
|
-
"className": "pi pi-cog",
|
|
4000
|
-
"label": "Generate Code"
|
|
4001
|
-
},
|
|
4002
|
-
"action": {
|
|
4003
|
-
"title": "",
|
|
4004
|
-
"body": "",
|
|
4005
|
-
"confirmBtnLabel": "Generate Code",
|
|
4006
|
-
"cancelBtnLabel": "Cancel",
|
|
4007
|
-
"customComponent": "GenerateModuleCode",
|
|
4008
|
-
"endpoint": ""
|
|
3983
|
+
"label": "Generate Code",
|
|
3984
|
+
"action": "GenerateModuleCodeRowAction",
|
|
3985
|
+
"openInPopup": true,
|
|
3986
|
+
"actionInContextMenu": true,
|
|
3987
|
+
"customComponentIsSystem": true
|
|
4009
3988
|
}
|
|
4010
3989
|
}
|
|
4011
3990
|
]
|
|
@@ -4172,32 +4151,11 @@
|
|
|
4172
4151
|
{
|
|
4173
4152
|
"attrs": {
|
|
4174
4153
|
"className": "pi pi-cog",
|
|
4175
|
-
"label": "Generate Code"
|
|
4176
|
-
|
|
4177
|
-
"action": {
|
|
4178
|
-
"title": "",
|
|
4179
|
-
"body": "",
|
|
4180
|
-
"confirmBtnLabel": "Generate Code",
|
|
4181
|
-
"cancelBtnLabel": "Cancel",
|
|
4182
|
-
"customComponent": "GenerateModelCodeRowAction",
|
|
4154
|
+
"label": "Generate Code",
|
|
4155
|
+
"action": "GenerateModelCodeRowAction",
|
|
4183
4156
|
"customComponentIsSystem": true,
|
|
4184
|
-
"
|
|
4185
|
-
|
|
4186
|
-
}
|
|
4187
|
-
],
|
|
4188
|
-
"headerButtons": [
|
|
4189
|
-
{
|
|
4190
|
-
"attrs": {
|
|
4191
|
-
"className": "pi pi-cog",
|
|
4192
|
-
"label": "Generate Code"
|
|
4193
|
-
},
|
|
4194
|
-
"action": {
|
|
4195
|
-
"title": "",
|
|
4196
|
-
"body": "",
|
|
4197
|
-
"confirmBtnLabel": "Generate Code",
|
|
4198
|
-
"cancelBtnLabel": "Cancel",
|
|
4199
|
-
"customComponent": "GenerateModelCode",
|
|
4200
|
-
"endpoint": ""
|
|
4157
|
+
"actionInContextMenu": true,
|
|
4158
|
+
"openInPopup": true
|
|
4201
4159
|
}
|
|
4202
4160
|
}
|
|
4203
4161
|
]
|
|
@@ -6046,7 +6004,7 @@
|
|
|
6046
6004
|
"attrs": {
|
|
6047
6005
|
"name": "name",
|
|
6048
6006
|
"isSearchable": true
|
|
6049
|
-
|
|
6007
|
+
}
|
|
6050
6008
|
},
|
|
6051
6009
|
{
|
|
6052
6010
|
"type": "field",
|
|
@@ -6210,7 +6168,6 @@
|
|
|
6210
6168
|
]
|
|
6211
6169
|
}
|
|
6212
6170
|
},
|
|
6213
|
-
|
|
6214
6171
|
{
|
|
6215
6172
|
"name": "media-list-view",
|
|
6216
6173
|
"displayName": "Solid Media Model",
|
|
@@ -8673,6 +8630,5 @@
|
|
|
8673
8630
|
}
|
|
8674
8631
|
],
|
|
8675
8632
|
"checksums": [],
|
|
8676
|
-
"listOfValues": [
|
|
8677
|
-
]
|
|
8633
|
+
"listOfValues": []
|
|
8678
8634
|
}
|
|
@@ -41,6 +41,7 @@ import {
|
|
|
41
41
|
} from "../constants";
|
|
42
42
|
import { SettingService } from './setting.service';
|
|
43
43
|
import { CreateUserDto } from 'src/dtos/create-user.dto';
|
|
44
|
+
import { RoleMetadataService } from './role-metadata.service';
|
|
44
45
|
|
|
45
46
|
enum LoginProvider {
|
|
46
47
|
LOCAL = 'local',
|
|
@@ -73,6 +74,8 @@ export class AuthenticationService {
|
|
|
73
74
|
private readonly smsService: Msg91OTPService,
|
|
74
75
|
private readonly eventEmitter: EventEmitter2,
|
|
75
76
|
private readonly settingService: SettingService,
|
|
77
|
+
private readonly roleMetadataService: RoleMetadataService
|
|
78
|
+
|
|
76
79
|
) { }
|
|
77
80
|
|
|
78
81
|
async resolveUser(username: string, email: string) {
|
|
@@ -145,7 +148,7 @@ export class AuthenticationService {
|
|
|
145
148
|
var { user, pwd, autoGeneratedPwd } = await this.populateForSignup<T>(extensionUser, signUpDto);
|
|
146
149
|
const savedUser = await extensionUserRepo.save(user);
|
|
147
150
|
|
|
148
|
-
await this.handlePostSignup(savedUser, signUpDto.roles,
|
|
151
|
+
await this.handlePostSignup(savedUser, signUpDto.roles, pwd, autoGeneratedPwd);
|
|
149
152
|
|
|
150
153
|
return savedUser;
|
|
151
154
|
}
|
|
@@ -158,15 +161,23 @@ export class AuthenticationService {
|
|
|
158
161
|
}
|
|
159
162
|
}
|
|
160
163
|
|
|
161
|
-
|
|
164
|
+
|
|
162
165
|
private async populateForSignup<T extends User>(user: T, signUpDto: SignUpDto, isUserActive: boolean = true) {
|
|
163
166
|
// const user = new User();
|
|
167
|
+
|
|
168
|
+
if (signUpDto.roles && signUpDto.roles.length > 0) {
|
|
169
|
+
for (let i = 0; i < signUpDto.roles.length; i++) {
|
|
170
|
+
const roleName = signUpDto.roles[i];
|
|
171
|
+
await this.roleMetadataService.findRoleByName(roleName);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
164
174
|
user.username = signUpDto.username;
|
|
165
175
|
user.email = signUpDto.email;
|
|
166
176
|
user.fullName = signUpDto.fullName;
|
|
167
177
|
if (signUpDto.mobile) {
|
|
168
178
|
user.mobile = signUpDto.mobile;
|
|
169
179
|
}
|
|
180
|
+
|
|
170
181
|
// If password has been specified by the user, then we simply create & activate the user based on the configuration parameter "activateUserOnRegistration".
|
|
171
182
|
let pwd = '';
|
|
172
183
|
let autoGeneratedPwd = '';
|
|
@@ -186,8 +197,9 @@ export class AuthenticationService {
|
|
|
186
197
|
return { user, pwd, autoGeneratedPwd };
|
|
187
198
|
}
|
|
188
199
|
|
|
189
|
-
|
|
190
|
-
|
|
200
|
+
|
|
201
|
+
private async handlePostSignup(user: User, roles: string[] = [], pwd: string, autoGeneratedPwd: string) {
|
|
202
|
+
await this.userService.initializeRolesForNewUser(roles, user);
|
|
191
203
|
// Tanay: Adding user password to history table
|
|
192
204
|
const userPasswordHistory = new UserPasswordHistory();
|
|
193
205
|
userPasswordHistory.passwordHash = pwd;
|
|
@@ -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 [
|
|
@@ -184,16 +184,19 @@ export class ModelMetadataService {
|
|
|
184
184
|
relations: {},
|
|
185
185
|
});
|
|
186
186
|
createDto['module'] = resolvedModule;
|
|
187
|
+
|
|
188
|
+
if (createDto['parentModelId']) {
|
|
189
|
+
const resolvedParentModel = await this.dataSource
|
|
190
|
+
.getRepository(ModelMetadata)
|
|
191
|
+
.findOne({
|
|
192
|
+
where: {
|
|
193
|
+
id: createDto['parentModelId'],
|
|
194
|
+
},
|
|
195
|
+
relations: {},
|
|
196
|
+
});
|
|
197
|
+
createDto['parentModel'] = resolvedParentModel;
|
|
198
|
+
}
|
|
187
199
|
|
|
188
|
-
const resolvedParentModel = await this.dataSource
|
|
189
|
-
.getRepository(ModelMetadata)
|
|
190
|
-
.findOne({
|
|
191
|
-
where: {
|
|
192
|
-
id: createDto['parentModelId'],
|
|
193
|
-
},
|
|
194
|
-
relations: {},
|
|
195
|
-
});
|
|
196
|
-
createDto['parentModel'] = resolvedParentModel;
|
|
197
200
|
const { fields: fieldsMetadata, ...modelMetaDataWithoutFields } = createDto;
|
|
198
201
|
const modelMetadata = this.modelMetadataRepo.create(modelMetaDataWithoutFields);
|
|
199
202
|
let model = await manager.save(modelMetadata);
|
|
@@ -515,8 +518,8 @@ export class ModelMetadataService {
|
|
|
515
518
|
|
|
516
519
|
// Generate the code for models which are linked to fields having an inverse relation
|
|
517
520
|
const coModelSingularNames = model.fields.
|
|
518
|
-
|
|
519
|
-
|
|
521
|
+
filter(field => field.type === SolidFieldType.relation && field.relationCreateInverse === true)
|
|
522
|
+
.map(field => field.relationCoModelSingularName);
|
|
520
523
|
|
|
521
524
|
for (const singularName of coModelSingularNames) {
|
|
522
525
|
const coModel = await this.findOneBySingularName(singularName);
|
|
@@ -525,7 +528,7 @@ export class ModelMetadataService {
|
|
|
525
528
|
dryRun: options.dryRun
|
|
526
529
|
};
|
|
527
530
|
await this.generateCode(inverseOptions);
|
|
528
|
-
}
|
|
531
|
+
}
|
|
529
532
|
|
|
530
533
|
await this.generateVAMConfig(model.id);
|
|
531
534
|
|
|
@@ -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
|
}
|