rez_core 2.0.96 → 2.0.98
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/module/filter/service/filter.service.d.ts +3 -3
- package/dist/module/filter/service/filter.service.js +4 -6
- package/dist/module/filter/service/filter.service.js.map +1 -1
- package/dist/module/master/service/master.service.js +2 -2
- package/dist/module/master/service/master.service.js.map +1 -1
- package/dist/module/meta/service/entity-service-impl.service.js +1 -1
- package/dist/module/meta/service/entity-service-impl.service.js.map +1 -1
- package/dist/module/meta/service/entity-validation.service.d.ts +2 -2
- package/dist/module/meta/service/entity-validation.service.js +8 -4
- package/dist/module/meta/service/entity-validation.service.js.map +1 -1
- package/dist/module/module/service/menu.service.js +0 -3
- package/dist/module/module/service/menu.service.js.map +1 -1
- package/dist/module/user/controller/login.controller.js +12 -0
- package/dist/module/user/controller/login.controller.js.map +1 -1
- package/dist/module/user/service/user-session.service.d.ts +3 -0
- package/dist/module/user/service/user-session.service.js +20 -0
- package/dist/module/user/service/user-session.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -2
- package/src/module/filter/service/filter.service.ts +6 -11
- package/src/module/master/service/master.service.ts +8 -8
- package/src/module/meta/service/entity-service-impl.service.ts +1 -0
- package/src/module/meta/service/entity-validation.service.ts +8 -1
- package/src/module/module/service/menu.service.ts +23 -17
- package/src/module/user/controller/login.controller.ts +30 -0
- package/src/module/user/service/user-session.service.ts +28 -0
package/package.json
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BadRequestException, Inject, Injectable } from '@nestjs/common';
|
|
2
2
|
import { AttributeMasterService } from 'src/module/meta/service/attribute-master.service';
|
|
3
3
|
import { EntityMasterService } from 'src/module/meta/service/entity-master.service';
|
|
4
|
+
import { EntityTableColumnService } from 'src/module/meta/service/entity-table-column.service';
|
|
5
|
+
import { EntityTableService } from 'src/module/meta/service/entity-table.service';
|
|
4
6
|
import { DataSource } from 'typeorm';
|
|
5
|
-
import { SavedFilterService } from './saved-filter.service';
|
|
6
7
|
import { FilterRequestDto } from '../dto/filter-request.dto';
|
|
7
|
-
import {
|
|
8
|
-
import { EntityTableColumnService } from 'src/module/meta/service/entity-table-column.service';
|
|
9
|
-
import { get } from 'http';
|
|
8
|
+
import { SavedFilterService } from './saved-filter.service';
|
|
10
9
|
|
|
11
10
|
@Injectable()
|
|
12
11
|
export class FilterService {
|
|
@@ -19,7 +18,7 @@ export class FilterService {
|
|
|
19
18
|
@Inject('SavedFilterService')
|
|
20
19
|
private readonly savedFilterService: SavedFilterService,
|
|
21
20
|
) {}
|
|
22
|
-
private readonly skipLevelFilterEntities = [
|
|
21
|
+
private readonly skipLevelFilterEntities = [];
|
|
23
22
|
|
|
24
23
|
private async gettab_value_counts(
|
|
25
24
|
tableName: string,
|
|
@@ -129,11 +128,7 @@ export class FilterService {
|
|
|
129
128
|
|
|
130
129
|
const baseWhere = this.buildWhereClauses(baseFilters, attributeMetaMap);
|
|
131
130
|
|
|
132
|
-
if (
|
|
133
|
-
level_type &&
|
|
134
|
-
level_id &&
|
|
135
|
-
!this.skipLevelFilterEntities.includes(entity_type)
|
|
136
|
-
) {
|
|
131
|
+
if (level_type && level_id) {
|
|
137
132
|
baseWhere.push({
|
|
138
133
|
query: 'e.level_type = :level_type AND e.level_id = :level_id',
|
|
139
134
|
params: {
|
|
@@ -411,11 +411,11 @@ export class MasterService {
|
|
|
411
411
|
row.entity_type = entityType;
|
|
412
412
|
row.organization_id = loggedInUser.organization_id;
|
|
413
413
|
|
|
414
|
-
const rowErrors =
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
414
|
+
const rowErrors = await this.entityValidationService.validateEntityData(
|
|
415
|
+
row,
|
|
416
|
+
entityMaster,
|
|
417
|
+
loggedInUser,
|
|
418
|
+
);
|
|
419
419
|
|
|
420
420
|
const existingError = errors.find((e) => e.row === i + 1);
|
|
421
421
|
|
|
@@ -466,13 +466,13 @@ export class MasterService {
|
|
|
466
466
|
.andWhere(`${entityMaster.db_table_name}.level_id = :levelId`, {
|
|
467
467
|
levelId: loggedInUser.level_id,
|
|
468
468
|
});
|
|
469
|
-
|
|
469
|
+
|
|
470
470
|
const existing = await qb.limit(1).getRawOne();
|
|
471
471
|
|
|
472
472
|
row.entity_type = entityType;
|
|
473
473
|
row.organization_id = loggedInUser.organization_id;
|
|
474
|
-
row.status=
|
|
475
|
-
|
|
474
|
+
row.status = 'ACTIVE';
|
|
475
|
+
|
|
476
476
|
let errors = [];
|
|
477
477
|
if (existing) {
|
|
478
478
|
if (duplicateHandling === 'skip_duplicates') continue;
|
|
@@ -49,6 +49,7 @@ export class EntityValidationService {
|
|
|
49
49
|
attributeData: AttributeMaster[],
|
|
50
50
|
entityType: string,
|
|
51
51
|
db_table_name: string,
|
|
52
|
+
loggedInUser: any,
|
|
52
53
|
): Promise<ValidationError[]> {
|
|
53
54
|
const errors: ValidationError[] = [];
|
|
54
55
|
|
|
@@ -64,12 +65,16 @@ export class EntityValidationService {
|
|
|
64
65
|
|
|
65
66
|
// Add AND condition for organization_id if present
|
|
66
67
|
const orgId = entityData.organization_id;
|
|
68
|
+
const level_type = loggedInUser.level_type;
|
|
69
|
+
const level_id = loggedInUser.level_id;
|
|
67
70
|
|
|
68
71
|
if (orgId !== undefined && orgId !== null) {
|
|
69
72
|
qb = qb.andWhere(
|
|
70
|
-
`${db_table_name}.organization_id = :organization_id`,
|
|
73
|
+
`${db_table_name}.organization_id = :organization_id AND ${db_table_name}.level_type = :level_type AND ${db_table_name}.level_id = :level_id`,
|
|
71
74
|
{
|
|
72
75
|
organization_id: orgId,
|
|
76
|
+
level_type: level_type,
|
|
77
|
+
level_id: level_id,
|
|
73
78
|
},
|
|
74
79
|
);
|
|
75
80
|
}
|
|
@@ -119,6 +124,7 @@ export class EntityValidationService {
|
|
|
119
124
|
async validateEntityData(
|
|
120
125
|
entityData: Record<string, any>,
|
|
121
126
|
entityMaster,
|
|
127
|
+
loggedInUser: any,
|
|
122
128
|
): Promise<ValidationError[]> {
|
|
123
129
|
const attributes =
|
|
124
130
|
await this.attributeMasterService.findAttributesByMappedEntityType(
|
|
@@ -131,6 +137,7 @@ export class EntityValidationService {
|
|
|
131
137
|
attributes,
|
|
132
138
|
entityData.entity_type,
|
|
133
139
|
entityMaster.db_table_name,
|
|
140
|
+
loggedInUser,
|
|
134
141
|
);
|
|
135
142
|
const regexErros = await this.validateRegexFields(entityData, attributes);
|
|
136
143
|
return [...requiredErrors, ...uniqueErrors, ...regexErros];
|
|
@@ -6,8 +6,9 @@ import { UserRoleMapping } from 'src/module/user/entity/user-role-mapping.entity
|
|
|
6
6
|
|
|
7
7
|
@Injectable()
|
|
8
8
|
export class MenuService {
|
|
9
|
-
constructor(
|
|
10
|
-
private readonly
|
|
9
|
+
constructor(
|
|
10
|
+
private readonly menuRepository: MenuRepository,
|
|
11
|
+
private readonly datasource: DataSource,
|
|
11
12
|
) {}
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -20,25 +21,34 @@ export class MenuService {
|
|
|
20
21
|
levelId: number,
|
|
21
22
|
): Promise<{ menu: any[] }> {
|
|
22
23
|
// Step 1: Resolve roles (with fallback logic inside)
|
|
23
|
-
const roleCodes = await this.menuRepository.resolveUserRoles(
|
|
24
|
-
|
|
24
|
+
const roleCodes = await this.menuRepository.resolveUserRoles(
|
|
25
|
+
userId,
|
|
26
|
+
appcode,
|
|
27
|
+
levelType,
|
|
28
|
+
levelId,
|
|
29
|
+
);
|
|
25
30
|
if (!roleCodes.length) return { menu: [] };
|
|
26
|
-
|
|
31
|
+
|
|
27
32
|
// Step 2: Get accessible modules
|
|
28
|
-
const moduleCodes = await this.menuRepository.getAccessibleModules(
|
|
29
|
-
|
|
33
|
+
const moduleCodes = await this.menuRepository.getAccessibleModules(
|
|
34
|
+
roleCodes,
|
|
35
|
+
appcode,
|
|
36
|
+
);
|
|
30
37
|
if (!moduleCodes.length) return { menu: [] };
|
|
31
|
-
|
|
38
|
+
|
|
32
39
|
// Step 3: Get menu items for the given level type
|
|
33
|
-
const menuItems = await this.menuRepository.getMenuItems(
|
|
34
|
-
|
|
35
|
-
|
|
40
|
+
const menuItems = await this.menuRepository.getMenuItems(
|
|
41
|
+
moduleCodes,
|
|
42
|
+
appcode,
|
|
43
|
+
levelType,
|
|
44
|
+
);
|
|
45
|
+
|
|
36
46
|
// Step 4: Build hierarchy
|
|
37
47
|
const menuTree = this.buildMenuHierarchy(menuItems);
|
|
38
|
-
|
|
48
|
+
|
|
39
49
|
return { menu: menuTree };
|
|
40
50
|
}
|
|
41
|
-
|
|
51
|
+
|
|
42
52
|
/**
|
|
43
53
|
* Converts a flat list of menu items into a hierarchical tree.
|
|
44
54
|
*/
|
|
@@ -69,8 +79,4 @@ export class MenuService {
|
|
|
69
79
|
async getUserRoles(userId: number, appcode: string): Promise<any> {
|
|
70
80
|
return this.menuRepository.getUserRoles(userId, appcode);
|
|
71
81
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
82
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
BadRequestException,
|
|
2
3
|
Body,
|
|
3
4
|
Controller,
|
|
4
5
|
Get,
|
|
@@ -68,6 +69,35 @@ export class LoginController {
|
|
|
68
69
|
},
|
|
69
70
|
): Promise<any> {
|
|
70
71
|
const currentUser = req.user.userData;
|
|
72
|
+
const currentAppcode = currentUser.appcode;
|
|
73
|
+
|
|
74
|
+
// If appcode is changing, validate the new level_id/level_type
|
|
75
|
+
if (data.appcode !== currentAppcode) {
|
|
76
|
+
const isValidAccess = await this.userSessionService.checkIfUserHasMapping(
|
|
77
|
+
currentUser.id,
|
|
78
|
+
data.appcode,
|
|
79
|
+
data.level_type,
|
|
80
|
+
data.level_id,
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
if (!isValidAccess) {
|
|
84
|
+
// If not valid, fetch the default one
|
|
85
|
+
const userMapping =
|
|
86
|
+
await this.userSessionService.getUserRoleMappingForApp(
|
|
87
|
+
currentUser.id,
|
|
88
|
+
data.appcode,
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
if (!userMapping) {
|
|
92
|
+
throw new BadRequestException(
|
|
93
|
+
`No mapping found for user in app ${data.appcode}`,
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
data.level_type = userMapping.level_type;
|
|
98
|
+
data.level_id = userMapping.level_id;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
71
101
|
|
|
72
102
|
return await this.userSessionService.switchCurrentLevelService(
|
|
73
103
|
currentUser,
|
|
@@ -6,6 +6,7 @@ import { JwtAuthService } from 'src/module/auth/services/jwt.service';
|
|
|
6
6
|
import { ConfigService } from '@nestjs/config';
|
|
7
7
|
import { UserRoleMappingService } from './user-role-mapping.service';
|
|
8
8
|
import { DataSource } from 'typeorm';
|
|
9
|
+
import { UserRoleMapping } from '../entity/user-role-mapping.entity';
|
|
9
10
|
|
|
10
11
|
@Injectable()
|
|
11
12
|
export class UserSessionService {
|
|
@@ -96,4 +97,31 @@ export class UserSessionService {
|
|
|
96
97
|
level_id: data.level_id,
|
|
97
98
|
};
|
|
98
99
|
}
|
|
100
|
+
|
|
101
|
+
async checkIfUserHasMapping(
|
|
102
|
+
userId: number,
|
|
103
|
+
appcode: string,
|
|
104
|
+
levelType: string,
|
|
105
|
+
levelId: string,
|
|
106
|
+
): Promise<boolean> {
|
|
107
|
+
const count = await this.dataSource
|
|
108
|
+
.getRepository(UserRoleMapping)
|
|
109
|
+
.createQueryBuilder('cr_user_role_mapping')
|
|
110
|
+
.where('cr_user_role_mapping.user_id = :userId', { userId })
|
|
111
|
+
.andWhere('cr_user_role_mapping.appcode = :appcode', { appcode })
|
|
112
|
+
.andWhere('cr_user_role_mapping.level_type = :levelType', { levelType })
|
|
113
|
+
.andWhere('cr_user_role_mapping.level_id = :levelId', { levelId })
|
|
114
|
+
.getCount();
|
|
115
|
+
|
|
116
|
+
return count > 0;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async getUserRoleMappingForApp(userId: number, appcode: string) {
|
|
120
|
+
return await this.dataSource
|
|
121
|
+
.getRepository(UserRoleMapping)
|
|
122
|
+
.createQueryBuilder('cr_user_role_mapping')
|
|
123
|
+
.where('cr_user_role_mapping.user_id = :userId', { userId })
|
|
124
|
+
.andWhere('cr_user_role_mapping.appcode = :appcode', { appcode })
|
|
125
|
+
.getOne(); // You can return .getMany() if you want to let user choose
|
|
126
|
+
}
|
|
99
127
|
}
|