rez_core 1.0.48 → 1.0.50
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/data/master.xlsx +0 -0
- package/dist/constant/global.constant.d.ts +1 -0
- package/dist/constant/global.constant.js +2 -1
- package/dist/constant/global.constant.js.map +1 -1
- package/dist/module/master/service/master.service.js +14 -0
- package/dist/module/master/service/master.service.js.map +1 -1
- package/dist/module/meta/controller/entity.controller.d.ts +6 -2
- package/dist/module/meta/controller/entity.controller.js +13 -6
- package/dist/module/meta/controller/entity.controller.js.map +1 -1
- package/dist/module/meta/controller/media.controller.js +1 -4
- package/dist/module/meta/controller/media.controller.js.map +1 -1
- package/dist/module/meta/service/media-data.service.d.ts +1 -1
- package/dist/module/meta/service/media-data.service.js +4 -2
- package/dist/module/meta/service/media-data.service.js.map +1 -1
- package/dist/module/module/controller/module-access.controller.d.ts +7 -1
- package/dist/module/module/controller/module-access.controller.js +19 -8
- package/dist/module/module/controller/module-access.controller.js.map +1 -1
- package/dist/module/module/repository/module-access.repository.d.ts +3 -2
- package/dist/module/module/repository/module-access.repository.js +30 -13
- package/dist/module/module/repository/module-access.repository.js.map +1 -1
- package/dist/module/module/service/module-access.service.d.ts +6 -3
- package/dist/module/module/service/module-access.service.js +25 -13
- package/dist/module/module/service/module-access.service.js.map +1 -1
- package/dist/module/user/entity/user-role-mapping.entity.d.ts +1 -0
- package/dist/module/user/entity/user-role-mapping.entity.js +6 -0
- package/dist/module/user/entity/user-role-mapping.entity.js.map +1 -1
- package/dist/module/user/service/role.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/constant/global.constant.ts +2 -0
- package/src/module/master/service/master.service.ts +14 -0
- package/src/module/meta/controller/entity.controller.ts +14 -3
- package/src/module/meta/controller/media.controller.ts +2 -3
- package/src/module/meta/service/media-data.service.ts +5 -3
- package/src/module/module/controller/module-access.controller.ts +16 -4
- package/src/module/module/repository/module-access.repository.ts +81 -47
- package/src/module/module/service/module-access.service.ts +39 -19
- package/src/module/user/entity/user-role-mapping.entity.ts +5 -0
- package/src/module/user/service/role.service.ts +1 -0
- package/src/resources/dev.properties.yaml +0 -6
package/package.json
CHANGED
|
@@ -11,6 +11,8 @@ export const ENTITYTYPE_LISTMASTER = 'LMS';
|
|
|
11
11
|
export const ENTITYTYPE_LISTMASTERITEMS = 'LMI';
|
|
12
12
|
export const ENTITYTYPE_SECTIONMASTER = 'SEC';
|
|
13
13
|
export const ENTITYTYPE_FIELDMASTER = 'FLD';
|
|
14
|
+
export const ENTITYTYPE_USRROLMAP = 'URM';
|
|
15
|
+
|
|
14
16
|
|
|
15
17
|
export const STORAGETYPE_SINGLEJSON = 'singlejson';
|
|
16
18
|
export const STORAGETYPE_COLUMN = 'column';
|
|
@@ -48,6 +48,18 @@ export class MasterService {
|
|
|
48
48
|
];
|
|
49
49
|
|
|
50
50
|
private readonly dataSequence = [
|
|
51
|
+
{
|
|
52
|
+
table: 'cr_user',
|
|
53
|
+
unique_fields: ['code'],
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
table: 'cr_role',
|
|
57
|
+
unique_fields: ['code'],
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
table: 'cr_user_role_mapping',
|
|
61
|
+
unique_fields: ['user_id', 'role_id'],
|
|
62
|
+
},
|
|
51
63
|
{
|
|
52
64
|
table: 'eth_school',
|
|
53
65
|
unique_fields: ['code'],
|
|
@@ -127,6 +139,7 @@ export class MasterService {
|
|
|
127
139
|
entityMasterData?.mapped_entity_type,
|
|
128
140
|
);
|
|
129
141
|
|
|
142
|
+
console.log(attributes,"((((((((((((((((((((((((((")
|
|
130
143
|
for (const row of sheetData) {
|
|
131
144
|
if (row.parent_type !== undefined && row.parent_id !== undefined) {
|
|
132
145
|
this.resolveParent(row);
|
|
@@ -134,6 +147,7 @@ export class MasterService {
|
|
|
134
147
|
|
|
135
148
|
for (const attribute of attributes) {
|
|
136
149
|
if (attribute.data_source_type === 'entity') {
|
|
150
|
+
console.log(attribute.data_source_type)
|
|
137
151
|
let entityMaster = await this.entityMasterService.getEntityData(
|
|
138
152
|
attribute.datasource_list,
|
|
139
153
|
);
|
|
@@ -8,7 +8,8 @@ import {
|
|
|
8
8
|
Post,
|
|
9
9
|
Query,
|
|
10
10
|
Res,
|
|
11
|
-
|
|
11
|
+
Req,
|
|
12
|
+
UseGuards, Inject,
|
|
12
13
|
} from '@nestjs/common';
|
|
13
14
|
import { EntityServiceImpl } from '../service/entity-service-impl.service';
|
|
14
15
|
import { ReflectionHelper } from '../../../utils/service/reflection-helper.service';
|
|
@@ -18,6 +19,9 @@ import { BaseEntity } from '../entity/base-entity.entity';
|
|
|
18
19
|
import { JwtAuthGuard } from '../../auth/guards/jwt.guard';
|
|
19
20
|
import * as fs from 'fs';
|
|
20
21
|
import * as path from 'path';
|
|
22
|
+
import { UserService } from '../../user/service/user.service';
|
|
23
|
+
import { ENTITYTYPE_USER } from '../../../constant/global.constant';
|
|
24
|
+
import { UserData } from '../../user/entity/user.entity';
|
|
21
25
|
|
|
22
26
|
@UseGuards(JwtAuthGuard)
|
|
23
27
|
@Controller('entity')
|
|
@@ -58,7 +62,11 @@ export class EntityController {
|
|
|
58
62
|
@Body() entityData: BaseEntity,
|
|
59
63
|
@Query('entity_type') entityType: string,
|
|
60
64
|
@Res() res: Response,
|
|
65
|
+
@Req() req: Request & {user: any}
|
|
61
66
|
) {
|
|
67
|
+
let requestedUser = req.user;
|
|
68
|
+
let loggedInUser = await this.entityService.getEntityData(ENTITYTYPE_USER,requestedUser.id);
|
|
69
|
+
|
|
62
70
|
if (!entityType) {
|
|
63
71
|
throw new BadRequestException(
|
|
64
72
|
'Query parameter "entity_type" is required',
|
|
@@ -75,7 +83,7 @@ export class EntityController {
|
|
|
75
83
|
if (entityService) {
|
|
76
84
|
return res
|
|
77
85
|
.status(HttpStatus.OK)
|
|
78
|
-
.json(await entityService.createEntity(entityData,
|
|
86
|
+
.json(await entityService.createEntity(entityData, loggedInUser as UserData));
|
|
79
87
|
}
|
|
80
88
|
}
|
|
81
89
|
|
|
@@ -85,7 +93,10 @@ export class EntityController {
|
|
|
85
93
|
@Body() entityData: BaseEntity,
|
|
86
94
|
@Query('entity_type') entityType: string,
|
|
87
95
|
@Res() response: Response,
|
|
96
|
+
@Req() req: Request & {user: any}
|
|
88
97
|
) {
|
|
98
|
+
let requestedUser = req.user;
|
|
99
|
+
let loggedInUser = await this.entityService.getEntityData(ENTITYTYPE_USER,requestedUser.id);
|
|
89
100
|
if (!entityType) {
|
|
90
101
|
throw new BadRequestException(
|
|
91
102
|
'Query parameter "entity_type" is required',
|
|
@@ -106,7 +117,7 @@ export class EntityController {
|
|
|
106
117
|
}
|
|
107
118
|
// let mergeEntity = JsonUtil.merge(existingEntity, entityData);
|
|
108
119
|
|
|
109
|
-
entityData = await entityService.updateEntity(entityData,
|
|
120
|
+
entityData = await entityService.updateEntity(entityData, loggedInUser as UserData);
|
|
110
121
|
return response.status(HttpStatus.OK).json(entityData);
|
|
111
122
|
}
|
|
112
123
|
}
|
|
@@ -53,9 +53,8 @@ export class MediaController {
|
|
|
53
53
|
async getDownloadUrl(@Param('id') id: number, @Res() res: Response) {
|
|
54
54
|
try {
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const downloadUrl = await this.mediaDataService.getMediaDownloadUrl(mediaData.media_url);
|
|
56
|
+
|
|
57
|
+
const downloadUrl = await this.mediaDataService.getMediaDownloadUrl(id);
|
|
59
58
|
res.status(HttpStatus.OK).json({
|
|
60
59
|
message: 'Download URL fetched successfully',
|
|
61
60
|
success: true,
|
|
@@ -4,7 +4,7 @@ import { MediaDataRepository } from '../repository/media-data.repository';
|
|
|
4
4
|
import { ConfigService } from '@nestjs/config';
|
|
5
5
|
import { S3 } from 'aws-sdk';
|
|
6
6
|
import { MediaData } from '../entity/media-data.entity';
|
|
7
|
-
import { STATUS_PENDING } from '../../../constant/global.constant';
|
|
7
|
+
import { ENTITYTYPE_MEDIA, STATUS_PENDING } from '../../../constant/global.constant';
|
|
8
8
|
import { v4 as uuidv4 } from 'uuid';
|
|
9
9
|
|
|
10
10
|
@Injectable()
|
|
@@ -115,11 +115,13 @@ export class MediaDataService extends EntityServiceImpl {
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
// New method to get the signed URL for the media (download link)
|
|
118
|
-
async getMediaDownloadUrl(
|
|
118
|
+
async getMediaDownloadUrl(id: number): Promise<string> {
|
|
119
119
|
try {
|
|
120
|
+
const entityData = await this.getEntityData(ENTITYTYPE_MEDIA, id);
|
|
121
|
+
let mediaData = entityData as MediaData;
|
|
120
122
|
const signedUrl = await this.s3.getSignedUrlPromise('getObject', {
|
|
121
123
|
Bucket: this.bucketName,
|
|
122
|
-
Key:
|
|
124
|
+
Key: mediaData.media_url,
|
|
123
125
|
Expires: 60 * 5, // URL valid for 5 mins
|
|
124
126
|
});
|
|
125
127
|
return signedUrl;
|
|
@@ -1,11 +1,16 @@
|
|
|
1
|
-
import { Body, Controller, Get, Param, Post, Query, UseGuards } from '@nestjs/common';
|
|
1
|
+
import { Body, Controller, Get, Inject, Param, Post, Query, Req, UseGuards } from '@nestjs/common';
|
|
2
2
|
import { ModuleAccessService } from '../service/module-access.service';
|
|
3
3
|
import { JwtAuthGuard } from 'src/module/auth/guards/jwt.guard';
|
|
4
|
+
import { ENTITYTYPE_USER } from '../../../constant/global.constant';
|
|
5
|
+
import { UserService } from '../../user/service/user.service';
|
|
6
|
+
import { UserData } from '../../user/entity/user.entity';
|
|
4
7
|
|
|
5
8
|
@Controller('module-access')
|
|
6
9
|
@UseGuards(JwtAuthGuard)
|
|
7
10
|
export class ModuleAccessController {
|
|
8
|
-
constructor(private readonly moduleAccessService: ModuleAccessService
|
|
11
|
+
constructor(private readonly moduleAccessService: ModuleAccessService,
|
|
12
|
+
@Inject('UserService') private readonly userService: UserService,
|
|
13
|
+
) {}
|
|
9
14
|
|
|
10
15
|
@Get('roles')
|
|
11
16
|
async getRoles() {
|
|
@@ -43,8 +48,12 @@ export class ModuleAccessController {
|
|
|
43
48
|
status?: 'ACTIVE' | 'INACTIVE';
|
|
44
49
|
copyFromRoleId?: number;
|
|
45
50
|
},
|
|
51
|
+
@Req() req: Request & {user: any}
|
|
46
52
|
) {
|
|
47
|
-
|
|
53
|
+
|
|
54
|
+
let requestedUser = req.user;
|
|
55
|
+
let loggedInUser = await this.userService.getEntityData(ENTITYTYPE_USER,requestedUser.id);
|
|
56
|
+
return this.moduleAccessService.createRole(body, loggedInUser as UserData);
|
|
48
57
|
}
|
|
49
58
|
|
|
50
59
|
@Post('update-role/:id')
|
|
@@ -57,8 +66,11 @@ export class ModuleAccessController {
|
|
|
57
66
|
status?: 'ACTIVE' | 'INACTIVE';
|
|
58
67
|
copyFromRoleId?: number; // <-- ADD THIS
|
|
59
68
|
},
|
|
69
|
+
@Req() req: Request & {user: any}
|
|
60
70
|
) {
|
|
61
|
-
|
|
71
|
+
let requestedUser = req.user;
|
|
72
|
+
let loggedInUser = await this.userService.getEntityData(ENTITYTYPE_USER,requestedUser.id);
|
|
73
|
+
return this.moduleAccessService.updateRole(id, body, loggedInUser as UserData);
|
|
62
74
|
}
|
|
63
75
|
|
|
64
76
|
|
|
@@ -6,6 +6,7 @@ import { ModuleAccess } from '../entity/module-access.entity';
|
|
|
6
6
|
import { ModuleAction } from '../entity/module-action.entity';
|
|
7
7
|
import { ModuleData } from '../entity/module.entity';
|
|
8
8
|
import { ClockIDGenService } from 'src/utils/service/clockIDGenUtil.service';
|
|
9
|
+
import { UserData } from 'src/module/user/entity/user.entity';
|
|
9
10
|
|
|
10
11
|
@Injectable()
|
|
11
12
|
export class ModuleAccessRepository {
|
|
@@ -18,27 +19,26 @@ export class ModuleAccessRepository {
|
|
|
18
19
|
private readonly moduleAccessRepo: Repository<ModuleAccess>,
|
|
19
20
|
@InjectRepository(ModuleAction)
|
|
20
21
|
private readonly moduleActionRepo: Repository<ModuleAction>,
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
private readonly clockIDGenService: ClockIDGenService,
|
|
23
23
|
) {}
|
|
24
24
|
|
|
25
25
|
async getRoles() {
|
|
26
26
|
const roles = await this.roleRepo.find();
|
|
27
|
-
return roles.map(role => ({
|
|
27
|
+
return roles.map((role) => ({
|
|
28
28
|
label: role.name,
|
|
29
29
|
value: role.id,
|
|
30
30
|
}));
|
|
31
31
|
}
|
|
32
|
-
|
|
33
32
|
|
|
34
33
|
async getModules() {
|
|
35
|
-
const modules = await this.moduleRepo.find({
|
|
36
|
-
|
|
34
|
+
const modules = await this.moduleRepo.find({
|
|
35
|
+
where: { module_level: 'MAINMOD' },
|
|
36
|
+
});
|
|
37
|
+
return modules.map((mod) => ({
|
|
37
38
|
label: mod.name,
|
|
38
39
|
value: mod.id,
|
|
39
40
|
}));
|
|
40
41
|
}
|
|
41
|
-
|
|
42
42
|
|
|
43
43
|
async getAccessListing(roleIds: number[]) {
|
|
44
44
|
// Fetch roles using role IDs
|
|
@@ -68,21 +68,23 @@ export class ModuleAccessRepository {
|
|
|
68
68
|
|
|
69
69
|
async getMenuListing(mainModIds: string[]) {
|
|
70
70
|
let mainModules: ModuleData[] = [];
|
|
71
|
-
|
|
71
|
+
|
|
72
72
|
if (mainModIds.length === 1 && mainModIds[0] === '-1') {
|
|
73
73
|
// Fetch ALL MAINMOD modules if "-1" is passed
|
|
74
|
-
mainModules = await this.moduleRepo.find({
|
|
74
|
+
mainModules = await this.moduleRepo.find({
|
|
75
|
+
where: { module_level: 'MAINMOD' },
|
|
76
|
+
});
|
|
75
77
|
} else {
|
|
76
78
|
// Fetch selected MAINMOD modules
|
|
77
79
|
mainModules = await this.moduleRepo.find({
|
|
78
80
|
where: { id: In(mainModIds), module_level: 'MAINMOD' },
|
|
79
81
|
});
|
|
80
82
|
}
|
|
81
|
-
|
|
83
|
+
|
|
82
84
|
if (!mainModules.length) return [];
|
|
83
|
-
|
|
85
|
+
|
|
84
86
|
const wbsCodes = mainModules.map((mod) => mod.wbs_code);
|
|
85
|
-
|
|
87
|
+
|
|
86
88
|
const modules = await this.moduleRepo
|
|
87
89
|
.createQueryBuilder('module')
|
|
88
90
|
.where(
|
|
@@ -92,14 +94,15 @@ export class ModuleAccessRepository {
|
|
|
92
94
|
Object.fromEntries(wbsCodes.map((code) => [`code${code}`, `${code}%`])),
|
|
93
95
|
)
|
|
94
96
|
.getMany();
|
|
95
|
-
|
|
97
|
+
|
|
96
98
|
const moduleActions = await this.moduleActionRepo.find();
|
|
97
|
-
|
|
99
|
+
|
|
98
100
|
const buildHierarchy = (parentWbs: string) => {
|
|
99
101
|
return modules
|
|
100
|
-
.filter(
|
|
101
|
-
mod
|
|
102
|
-
|
|
102
|
+
.filter(
|
|
103
|
+
(mod) =>
|
|
104
|
+
mod.wbs_code.startsWith(parentWbs + '.') &&
|
|
105
|
+
mod.wbs_code.split('.').length === parentWbs.split('.').length + 1,
|
|
103
106
|
)
|
|
104
107
|
.map((mod) => ({
|
|
105
108
|
name: mod.name,
|
|
@@ -113,7 +116,7 @@ export class ModuleAccessRepository {
|
|
|
113
116
|
submod: buildHierarchy(mod.wbs_code),
|
|
114
117
|
}));
|
|
115
118
|
};
|
|
116
|
-
|
|
119
|
+
|
|
117
120
|
return mainModules.map((mod) => ({
|
|
118
121
|
name: mod.name,
|
|
119
122
|
code: mod.module_code,
|
|
@@ -126,7 +129,7 @@ export class ModuleAccessRepository {
|
|
|
126
129
|
submod: buildHierarchy(mod.wbs_code),
|
|
127
130
|
}));
|
|
128
131
|
}
|
|
129
|
-
|
|
132
|
+
|
|
130
133
|
async updateModuleAccess(moduleAccessData: any[]): Promise<boolean> {
|
|
131
134
|
try {
|
|
132
135
|
for (const access of moduleAccessData) {
|
|
@@ -157,30 +160,44 @@ export class ModuleAccessRepository {
|
|
|
157
160
|
}
|
|
158
161
|
}
|
|
159
162
|
|
|
160
|
-
async createRole(
|
|
163
|
+
async createRole(
|
|
164
|
+
body: {
|
|
165
|
+
name: string;
|
|
166
|
+
description?: string;
|
|
167
|
+
status?: 'ACTIVE' | 'INACTIVE';
|
|
168
|
+
copyFromRoleId?: number;
|
|
169
|
+
},
|
|
170
|
+
loggedInUser: UserData,
|
|
171
|
+
) {
|
|
161
172
|
const { name, description, status, copyFromRoleId } = body;
|
|
162
|
-
|
|
173
|
+
|
|
163
174
|
const nameExists = await this.isRoleNameExists(name);
|
|
164
175
|
if (nameExists) {
|
|
165
176
|
throw new BadRequestException('Role name already exists.');
|
|
166
177
|
}
|
|
167
|
-
|
|
178
|
+
|
|
168
179
|
const code = this.clockIDGenService.idGenerator('ROL');
|
|
169
180
|
const newRole = this.roleRepo.create({
|
|
170
181
|
name,
|
|
171
182
|
code,
|
|
172
183
|
description,
|
|
173
184
|
status: status || 'ACTIVE',
|
|
185
|
+
created_by: loggedInUser.id,
|
|
186
|
+
created_date: new Date(),
|
|
174
187
|
});
|
|
175
|
-
|
|
188
|
+
|
|
176
189
|
const savedRole = await this.roleRepo.save(newRole);
|
|
177
|
-
|
|
190
|
+
|
|
178
191
|
if (copyFromRoleId) {
|
|
179
|
-
const sourceRole = await this.roleRepo.findOne({
|
|
192
|
+
const sourceRole = await this.roleRepo.findOne({
|
|
193
|
+
where: { id: copyFromRoleId },
|
|
194
|
+
});
|
|
180
195
|
if (!sourceRole) {
|
|
181
196
|
throw new BadRequestException('Source role not found');
|
|
182
197
|
}
|
|
183
|
-
const sourcePermissions = await this.moduleAccessRepo.find({
|
|
198
|
+
const sourcePermissions = await this.moduleAccessRepo.find({
|
|
199
|
+
where: { role_code: sourceRole.code },
|
|
200
|
+
});
|
|
184
201
|
const clonedPermissions = sourcePermissions.map((perm) =>
|
|
185
202
|
this.moduleAccessRepo.create({
|
|
186
203
|
role_code: code,
|
|
@@ -188,11 +205,11 @@ export class ModuleAccessRepository {
|
|
|
188
205
|
action_type: perm.action_type,
|
|
189
206
|
access_flag: perm.access_flag,
|
|
190
207
|
app_code: perm.app_code,
|
|
191
|
-
})
|
|
208
|
+
}),
|
|
192
209
|
);
|
|
193
210
|
await this.moduleAccessRepo.save(clonedPermissions);
|
|
194
211
|
}
|
|
195
|
-
|
|
212
|
+
|
|
196
213
|
return {
|
|
197
214
|
success: true,
|
|
198
215
|
msg: 'Role created successfully',
|
|
@@ -204,35 +221,49 @@ export class ModuleAccessRepository {
|
|
|
204
221
|
},
|
|
205
222
|
};
|
|
206
223
|
}
|
|
207
|
-
|
|
208
224
|
|
|
209
|
-
async updateRole(
|
|
225
|
+
async updateRole(
|
|
226
|
+
roleId: number,
|
|
227
|
+
body: {
|
|
228
|
+
name: string;
|
|
229
|
+
description?: string;
|
|
230
|
+
status?: 'ACTIVE' | 'INACTIVE';
|
|
231
|
+
copyFromRoleId?: number;
|
|
232
|
+
},
|
|
233
|
+
loggedInUser: UserData,
|
|
234
|
+
) {
|
|
210
235
|
const { name, description, status, copyFromRoleId } = body;
|
|
211
|
-
|
|
236
|
+
|
|
212
237
|
const nameExists = await this.isRoleNameExists(name, roleId);
|
|
213
238
|
if (nameExists) {
|
|
214
239
|
throw new BadRequestException('Role name already exists.');
|
|
215
240
|
}
|
|
216
|
-
|
|
241
|
+
|
|
217
242
|
const role = await this.roleRepo.findOne({ where: { id: roleId } });
|
|
218
243
|
if (!role) {
|
|
219
244
|
throw new BadRequestException('Source role not found');
|
|
220
245
|
}
|
|
221
|
-
|
|
246
|
+
|
|
222
247
|
role.name = name;
|
|
223
|
-
role.description = description ||
|
|
248
|
+
role.description = description || '';
|
|
224
249
|
role.status = status || 'ACTIVE';
|
|
250
|
+
role.modified_date = new Date();
|
|
251
|
+
role.modified_by = loggedInUser.id;
|
|
225
252
|
await this.roleRepo.save(role);
|
|
226
|
-
|
|
253
|
+
|
|
227
254
|
if (copyFromRoleId) {
|
|
228
255
|
await this.moduleAccessRepo.delete({ role_code: role.code });
|
|
229
|
-
|
|
230
|
-
const sourceRole = await this.roleRepo.findOne({
|
|
256
|
+
|
|
257
|
+
const sourceRole = await this.roleRepo.findOne({
|
|
258
|
+
where: { id: copyFromRoleId },
|
|
259
|
+
});
|
|
231
260
|
if (!sourceRole) {
|
|
232
261
|
throw new BadRequestException('Source role not found');
|
|
233
262
|
}
|
|
234
|
-
|
|
235
|
-
const sourcePermissions = await this.moduleAccessRepo.find({
|
|
263
|
+
|
|
264
|
+
const sourcePermissions = await this.moduleAccessRepo.find({
|
|
265
|
+
where: { role_code: sourceRole.code },
|
|
266
|
+
});
|
|
236
267
|
const clonedPermissions = sourcePermissions.map((perm) =>
|
|
237
268
|
this.moduleAccessRepo.create({
|
|
238
269
|
role_code: role.code,
|
|
@@ -240,11 +271,11 @@ export class ModuleAccessRepository {
|
|
|
240
271
|
action_type: perm.action_type,
|
|
241
272
|
access_flag: perm.access_flag,
|
|
242
273
|
app_code: perm.app_code,
|
|
243
|
-
})
|
|
274
|
+
}),
|
|
244
275
|
);
|
|
245
276
|
await this.moduleAccessRepo.save(clonedPermissions);
|
|
246
277
|
}
|
|
247
|
-
|
|
278
|
+
|
|
248
279
|
return {
|
|
249
280
|
success: true,
|
|
250
281
|
msg: 'Role updated successfully',
|
|
@@ -256,17 +287,20 @@ export class ModuleAccessRepository {
|
|
|
256
287
|
},
|
|
257
288
|
};
|
|
258
289
|
}
|
|
259
|
-
|
|
260
|
-
async isRoleNameExists(
|
|
261
|
-
|
|
290
|
+
|
|
291
|
+
async isRoleNameExists(
|
|
292
|
+
name: string,
|
|
293
|
+
excludeRoleId?: number,
|
|
294
|
+
): Promise<boolean> {
|
|
295
|
+
const query = this.roleRepo
|
|
296
|
+
.createQueryBuilder('role')
|
|
262
297
|
.where('role.name = :name', { name });
|
|
263
|
-
|
|
298
|
+
|
|
264
299
|
if (excludeRoleId) {
|
|
265
300
|
query.andWhere('role.id != :excludeRoleId', { excludeRoleId });
|
|
266
301
|
}
|
|
267
|
-
|
|
302
|
+
|
|
268
303
|
const existingRole = await query.getOne();
|
|
269
304
|
return !!existingRole;
|
|
270
305
|
}
|
|
271
|
-
|
|
272
306
|
}
|
|
@@ -4,12 +4,15 @@ import { RoleRepository } from 'src/module/user/repository/role.repository';
|
|
|
4
4
|
import { RoleService } from '../../user/service/role.service';
|
|
5
5
|
import { ENTITYTYPE_ROLE } from '../../../constant/global.constant';
|
|
6
6
|
import { Role } from '../../user/entity/role.entity';
|
|
7
|
+
import { EntityManager } from 'typeorm';
|
|
8
|
+
import { UserData } from 'src/module/user/entity/user.entity';
|
|
7
9
|
|
|
8
10
|
@Injectable()
|
|
9
11
|
export class ModuleAccessService {
|
|
10
12
|
constructor(
|
|
11
13
|
private readonly moduleAccessRepository: ModuleAccessRepository,
|
|
12
14
|
@Inject('RoleService') private readonly roleService: RoleService,
|
|
15
|
+
private readonly entityManager: EntityManager,
|
|
13
16
|
) {}
|
|
14
17
|
|
|
15
18
|
async getRoles() {
|
|
@@ -45,13 +48,16 @@ export class ModuleAccessService {
|
|
|
45
48
|
}
|
|
46
49
|
}
|
|
47
50
|
|
|
48
|
-
async createRole(
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
async createRole(
|
|
52
|
+
body: {
|
|
53
|
+
name: string;
|
|
54
|
+
description?: string;
|
|
55
|
+
status?: 'ACTIVE' | 'INACTIVE';
|
|
56
|
+
copyFromRoleId?: number;
|
|
57
|
+
},
|
|
58
|
+
loggedInUser: UserData,
|
|
59
|
+
) {
|
|
60
|
+
return this.moduleAccessRepository.createRole(body, loggedInUser);
|
|
55
61
|
}
|
|
56
62
|
|
|
57
63
|
async updateRole(
|
|
@@ -62,30 +68,44 @@ export class ModuleAccessService {
|
|
|
62
68
|
status?: 'ACTIVE' | 'INACTIVE';
|
|
63
69
|
copyFromRoleId?: number;
|
|
64
70
|
},
|
|
71
|
+
loggedInUser: UserData,
|
|
65
72
|
) {
|
|
66
73
|
if (!body.name) {
|
|
67
74
|
throw new BadRequestException('Role name is required');
|
|
68
75
|
}
|
|
69
76
|
|
|
70
|
-
|
|
71
|
-
|
|
77
|
+
if (body.status === 'INACTIVE') {
|
|
78
|
+
//get role by id
|
|
79
|
+
const entityData = await this.roleService.getEntityData(
|
|
80
|
+
ENTITYTYPE_ROLE,
|
|
81
|
+
id,
|
|
82
|
+
);
|
|
72
83
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (body.status === 'INACTIVE' && role.is_system === 1) {
|
|
78
|
-
throw new BadRequestException('Cannot deactivate system role');
|
|
79
|
-
}
|
|
84
|
+
const associatedUsers = await this.entityManager.query(`SELECT map.*
|
|
85
|
+
FROM cr_user_role_mapping map
|
|
86
|
+
JOIN cr_user usr ON map.user_id = usr.id
|
|
87
|
+
WHERE usr.status = 'ACTIVE' and map.role_id = ${entityData?.id}`);
|
|
80
88
|
|
|
81
|
-
|
|
82
|
-
|
|
89
|
+
if (associatedUsers.length > 0) {
|
|
90
|
+
throw new BadRequestException(
|
|
91
|
+
'Cannot deactivate role as it is associated with active users',
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (!entityData) {
|
|
96
|
+
throw new BadRequestException('Role not found');
|
|
97
|
+
}
|
|
98
|
+
const role = entityData as Role;
|
|
99
|
+
if (role.is_system === 1) {
|
|
100
|
+
throw new BadRequestException('Cannot deactivate system role');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
83
103
|
|
|
84
104
|
return this.moduleAccessRepository.updateRole(id, {
|
|
85
105
|
name: body.name,
|
|
86
106
|
description: body.description,
|
|
87
107
|
status: body.status,
|
|
88
108
|
copyFromRoleId: body.copyFromRoleId,
|
|
89
|
-
});
|
|
109
|
+
}, loggedInUser);
|
|
90
110
|
}
|
|
91
111
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ENTITYTYPE_USRROLMAP } from 'src/constant/global.constant';
|
|
1
2
|
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
|
|
2
3
|
|
|
3
4
|
@Entity({ name: 'cr_user_role_mapping' })
|
|
@@ -5,11 +6,15 @@ export class UserRoleMapping {
|
|
|
5
6
|
constructor(user_id: number, role_id: number) {
|
|
6
7
|
this.user_id = user_id;
|
|
7
8
|
this.role_id = role_id;
|
|
9
|
+
this.entity_type = ENTITYTYPE_USRROLMAP;
|
|
8
10
|
}
|
|
9
11
|
|
|
10
12
|
@PrimaryGeneratedColumn()
|
|
11
13
|
id: number;
|
|
12
14
|
|
|
15
|
+
@Column({type: 'varchar'})
|
|
16
|
+
entity_type: string;
|
|
17
|
+
|
|
13
18
|
@Column({ type: 'bigint', nullable: true })
|
|
14
19
|
user_id: number;
|
|
15
20
|
|
|
@@ -13,9 +13,3 @@ OTP_EXPIRY: "10"
|
|
|
13
13
|
OTP_LENGTH: "6"
|
|
14
14
|
VERIFY_OTP: "false"
|
|
15
15
|
DEFAULT_OTP: "123456"
|
|
16
|
-
AWS:
|
|
17
|
-
S3:
|
|
18
|
-
AWS_ACCESS_KEY_ID: "AKIAYYKIBDDSQF3KILGE"
|
|
19
|
-
AWS_SECRET_KEY: "PPDMAeO2mVUY1w2f46n/dlt5l9+7NY7E9twJb9LU"
|
|
20
|
-
AWS_REGION: "ap-south-1"
|
|
21
|
-
BUCKET_NAME: "testether"
|