shuttlepro-shared 1.2.41 → 1.2.44
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.
|
@@ -9,6 +9,7 @@ const settingRepository = require("./settings.repository");
|
|
|
9
9
|
const socialMediaSettingRepository = require("./socialMediaSetting.repository");
|
|
10
10
|
const notificationSettingRepository = require("./notificationSetting.repository");
|
|
11
11
|
const chatMemberRepository = require("./chatMember.repository");
|
|
12
|
+
const roleRepository = require("./role.repository");
|
|
12
13
|
|
|
13
14
|
exports.module = {
|
|
14
15
|
workspaceRepository,
|
|
@@ -22,4 +23,5 @@ exports.module = {
|
|
|
22
23
|
socialMediaSettingRepository,
|
|
23
24
|
notificationSettingRepository,
|
|
24
25
|
chatMemberRepository,
|
|
26
|
+
roleRepository,
|
|
25
27
|
};
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
const Role = require("../models/Role");
|
|
2
|
+
const { utils } = require("shuttlepro-utils");
|
|
3
|
+
const { getRedisData, setRedisData } = require("../config/redis");
|
|
4
|
+
|
|
5
|
+
const CACHE_KEY_ALL = "roles_all";
|
|
6
|
+
const CACHE_KEY_DEFAULT = "roles_default";
|
|
7
|
+
|
|
8
|
+
const getCachedRoles = async () => {
|
|
9
|
+
let roles = await getRedisData(CACHE_KEY_ALL);
|
|
10
|
+
if (!roles) {
|
|
11
|
+
roles = await Role.find().populate("permissionId").lean().exec();
|
|
12
|
+
await setRedisData(CACHE_KEY_ALL, roles);
|
|
13
|
+
} else {
|
|
14
|
+
roles = roles;
|
|
15
|
+
}
|
|
16
|
+
return roles;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const updateCachedRoles = async () => {
|
|
20
|
+
const roles = await Role.find().populate("permissionId").lean().exec();
|
|
21
|
+
await setRedisData(CACHE_KEY_ALL, roles);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const getCachedDefaultRoles = async () => {
|
|
25
|
+
let defaultRoles = await getRedisData(CACHE_KEY_DEFAULT);
|
|
26
|
+
if (!defaultRoles) {
|
|
27
|
+
const data = await Role.find({ name: { $ne: "super" }, workspaceId: null })
|
|
28
|
+
.select("name")
|
|
29
|
+
.sort({ _id: -1 })
|
|
30
|
+
.lean()
|
|
31
|
+
.exec();
|
|
32
|
+
|
|
33
|
+
defaultRoles = data.map((d) => {
|
|
34
|
+
return {
|
|
35
|
+
id: d?._id,
|
|
36
|
+
name: utils.capitalize(d?.name),
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
await setRedisData(CACHE_KEY_DEFAULT, defaultRoles);
|
|
41
|
+
}
|
|
42
|
+
return defaultRoles;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const updateCachedDefaultRoles = async () => {
|
|
46
|
+
const data = await Role.find({ name: { $ne: "super" }, workspaceId: null })
|
|
47
|
+
.select("name")
|
|
48
|
+
.sort({ _id: -1 })
|
|
49
|
+
.lean()
|
|
50
|
+
.exec();
|
|
51
|
+
|
|
52
|
+
const defaultRoles = data.map((d) => {
|
|
53
|
+
return {
|
|
54
|
+
id: d?._id,
|
|
55
|
+
name: utils.capitalize(d?.name),
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
await setRedisData(CACHE_KEY_DEFAULT, defaultRoles);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const createRole = async (roleData) => {
|
|
63
|
+
const newRole = await Role.create(roleData);
|
|
64
|
+
const createdRole = await Role.findById(newRole._id)
|
|
65
|
+
.populate("permissionId")
|
|
66
|
+
.lean()
|
|
67
|
+
.exec();
|
|
68
|
+
await updateCachedRoles();
|
|
69
|
+
return createdRole;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const findRoleById = async (id) => {
|
|
73
|
+
const roles = await getCachedRoles();
|
|
74
|
+
const role = roles.find((r) => r._id.toString() === id) || null;
|
|
75
|
+
|
|
76
|
+
if (role) return role;
|
|
77
|
+
|
|
78
|
+
// If not found in cache, query directly
|
|
79
|
+
return await Role.findById(id).populate("permissionId").lean().exec();
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const findSingleRole = async (filter) => {
|
|
83
|
+
const roles = await getCachedRoles();
|
|
84
|
+
const role =
|
|
85
|
+
roles.find((r) =>
|
|
86
|
+
Object.entries(filter).every(([key, value]) => r[key] === value)
|
|
87
|
+
) || null;
|
|
88
|
+
|
|
89
|
+
if (role) return role;
|
|
90
|
+
|
|
91
|
+
// If not found in cache, query directly
|
|
92
|
+
return await Role.findOne(filter).populate("permissionId").lean().exec();
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const findRolesByPagination = async (body) => {
|
|
96
|
+
let { page, limit, workspaceId, query, status } = body;
|
|
97
|
+
|
|
98
|
+
page = parseInt(page, 10) || 1;
|
|
99
|
+
limit = parseInt(limit, 10) || 10;
|
|
100
|
+
|
|
101
|
+
const skip = (page - 1) * limit;
|
|
102
|
+
|
|
103
|
+
let obj = { workspaceId };
|
|
104
|
+
if (query) {
|
|
105
|
+
obj.name = { $regex: query, $options: "i" };
|
|
106
|
+
}
|
|
107
|
+
if (status) {
|
|
108
|
+
obj.status = status;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const totalRoles = await Role.countDocuments(obj);
|
|
112
|
+
const totalPages = Math.ceil(totalRoles / limit);
|
|
113
|
+
|
|
114
|
+
const roles = await Role.find(obj)
|
|
115
|
+
.sort({ _id: -1 })
|
|
116
|
+
.skip(skip)
|
|
117
|
+
.limit(limit)
|
|
118
|
+
.populate("permissionId")
|
|
119
|
+
.lean()
|
|
120
|
+
.exec();
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
totalPages,
|
|
124
|
+
currentPage: page,
|
|
125
|
+
roles,
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const findRoles = async (workspaceId) => {
|
|
130
|
+
const roles = await getCachedRoles();
|
|
131
|
+
return roles.filter((r) => r.workspaceId === workspaceId);
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const findDefaultRoles = async () => {
|
|
135
|
+
return await getCachedDefaultRoles();
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const updateRoleById = async (id, updateData) => {
|
|
139
|
+
const updateQuery = {
|
|
140
|
+
...updateData,
|
|
141
|
+
...(Array.isArray(updateData.logs) && {
|
|
142
|
+
$push: { logs: { $each: updateData.logs } },
|
|
143
|
+
}),
|
|
144
|
+
};
|
|
145
|
+
delete updateQuery.logs;
|
|
146
|
+
|
|
147
|
+
const updatedRole = await Role.findByIdAndUpdate(id, updateQuery, {
|
|
148
|
+
new: true,
|
|
149
|
+
})
|
|
150
|
+
.populate("permissionId")
|
|
151
|
+
.lean()
|
|
152
|
+
.exec();
|
|
153
|
+
|
|
154
|
+
if (updatedRole) {
|
|
155
|
+
await updateCachedRoles();
|
|
156
|
+
// Update default roles cache if needed
|
|
157
|
+
if (!updatedRole.workspaceId) {
|
|
158
|
+
await updateCachedDefaultRoles();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return updatedRole;
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
const updateRoleByFilter = async (filter, updateData) => {
|
|
166
|
+
const updatedRole = await Role.findOneAndUpdate(filter, updateData, {
|
|
167
|
+
new: true,
|
|
168
|
+
})
|
|
169
|
+
.populate("permissionId")
|
|
170
|
+
.lean()
|
|
171
|
+
.exec();
|
|
172
|
+
|
|
173
|
+
if (updatedRole) {
|
|
174
|
+
await updateCachedRoles();
|
|
175
|
+
// Update default roles cache if needed
|
|
176
|
+
if (!updatedRole.workspaceId) {
|
|
177
|
+
await updateCachedDefaultRoles();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return updatedRole;
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
const updateRolesByFilter = async (filter, updateData) => {
|
|
185
|
+
const result = await Role.updateMany(filter, updateData, { new: true });
|
|
186
|
+
|
|
187
|
+
if (result.matchedCount > 0) {
|
|
188
|
+
await updateCachedRoles();
|
|
189
|
+
|
|
190
|
+
// Check if we need to update default roles cache
|
|
191
|
+
if (!filter.workspaceId || filter.workspaceId === null) {
|
|
192
|
+
await updateCachedDefaultRoles();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return result;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
const addLogToRole = async (id, logData) => {
|
|
200
|
+
const updatedRole = await Role.findByIdAndUpdate(
|
|
201
|
+
id,
|
|
202
|
+
{ $push: { logs: logData } },
|
|
203
|
+
{ new: true }
|
|
204
|
+
)
|
|
205
|
+
.populate("permissionId")
|
|
206
|
+
.lean()
|
|
207
|
+
.exec();
|
|
208
|
+
|
|
209
|
+
if (updatedRole) {
|
|
210
|
+
await updateCachedRoles();
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return updatedRole;
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
const clearRoleLogs = async (id) => {
|
|
217
|
+
const updatedRole = await Role.findByIdAndUpdate(
|
|
218
|
+
id,
|
|
219
|
+
{ $set: { logs: [] } },
|
|
220
|
+
{ new: true }
|
|
221
|
+
)
|
|
222
|
+
.populate("permissionId")
|
|
223
|
+
.lean()
|
|
224
|
+
.exec();
|
|
225
|
+
|
|
226
|
+
if (updatedRole) {
|
|
227
|
+
await updateCachedRoles();
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return updatedRole;
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
const addPermissionToRole = async (id, permission) => {
|
|
234
|
+
const updatedRole = await Role.findByIdAndUpdate(
|
|
235
|
+
id,
|
|
236
|
+
{ $push: { permissions: permission } },
|
|
237
|
+
{ new: true }
|
|
238
|
+
)
|
|
239
|
+
.populate("permissionId")
|
|
240
|
+
.lean()
|
|
241
|
+
.exec();
|
|
242
|
+
|
|
243
|
+
if (updatedRole) {
|
|
244
|
+
await updateCachedRoles();
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return updatedRole;
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const removePermissionFromRole = async (id, permission) => {
|
|
251
|
+
const updatedRole = await Role.findByIdAndUpdate(
|
|
252
|
+
id,
|
|
253
|
+
{ $pull: { permissions: permission } },
|
|
254
|
+
{ new: true }
|
|
255
|
+
)
|
|
256
|
+
.populate("permissionId")
|
|
257
|
+
.lean()
|
|
258
|
+
.exec();
|
|
259
|
+
|
|
260
|
+
if (updatedRole) {
|
|
261
|
+
await updateCachedRoles();
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return updatedRole;
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
const deleteRoleById = async (id) => {
|
|
268
|
+
const deletedRole = await Role.findByIdAndDelete(id).lean().exec();
|
|
269
|
+
|
|
270
|
+
if (deletedRole) {
|
|
271
|
+
await updateCachedRoles();
|
|
272
|
+
// Update default roles cache if needed
|
|
273
|
+
if (!deletedRole.workspaceId) {
|
|
274
|
+
await updateCachedDefaultRoles();
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return deletedRole;
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
const deleteSingleRole = async (filter) => {
|
|
282
|
+
const deletedRole = await Role.findOneAndDelete(filter).lean().exec();
|
|
283
|
+
|
|
284
|
+
if (deletedRole) {
|
|
285
|
+
await updateCachedRoles();
|
|
286
|
+
// Update default roles cache if needed
|
|
287
|
+
if (!deletedRole.workspaceId) {
|
|
288
|
+
await updateCachedDefaultRoles();
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return deletedRole;
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
const deleteManyRoles = async (filter) => {
|
|
296
|
+
// Check if we need to update default roles cache
|
|
297
|
+
const includesDefaultRoles =
|
|
298
|
+
!filter.workspaceId || filter.workspaceId === null;
|
|
299
|
+
|
|
300
|
+
const result = await Role.deleteMany(filter);
|
|
301
|
+
|
|
302
|
+
if (result.deletedCount > 0) {
|
|
303
|
+
await updateCachedRoles();
|
|
304
|
+
if (includesDefaultRoles) {
|
|
305
|
+
await updateCachedDefaultRoles();
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return result;
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
module.exports = {
|
|
313
|
+
createRole,
|
|
314
|
+
findRoleById,
|
|
315
|
+
findSingleRole,
|
|
316
|
+
findRoles,
|
|
317
|
+
updateRoleById,
|
|
318
|
+
updateRoleByFilter,
|
|
319
|
+
updateRolesByFilter,
|
|
320
|
+
addLogToRole,
|
|
321
|
+
clearRoleLogs,
|
|
322
|
+
addPermissionToRole,
|
|
323
|
+
removePermissionFromRole,
|
|
324
|
+
deleteRoleById,
|
|
325
|
+
deleteSingleRole,
|
|
326
|
+
deleteManyRoles,
|
|
327
|
+
findRolesByPagination,
|
|
328
|
+
findDefaultRoles,
|
|
329
|
+
};
|
|
@@ -7,6 +7,7 @@ const defaultSelect =
|
|
|
7
7
|
// Cache keys
|
|
8
8
|
const CACHE_KEY_ALL_MEMBERS = "userroles_all_members";
|
|
9
9
|
const CACHE_KEY_USER_WORKSPACE_PREFIX = "userrole_workspace_";
|
|
10
|
+
const CACHE_KEY_USER_PERMISSIONS_PREFIX = "user_permissions_";
|
|
10
11
|
|
|
11
12
|
// Clear user workspace cache
|
|
12
13
|
const clearUserWorkspaceCache = async (userId) => {
|
|
@@ -18,6 +19,12 @@ const clearUserWorkspaceCache = async (userId) => {
|
|
|
18
19
|
);
|
|
19
20
|
};
|
|
20
21
|
|
|
22
|
+
// Clear user permissions cache
|
|
23
|
+
const clearUserPermissionsCache = async (workspaceId, userId) => {
|
|
24
|
+
const cacheKey = `${CACHE_KEY_USER_PERMISSIONS_PREFIX}${workspaceId}_${userId}`;
|
|
25
|
+
await setRedisData(cacheKey, null, null, 0);
|
|
26
|
+
};
|
|
27
|
+
|
|
21
28
|
// Get cached members
|
|
22
29
|
const getCachedMembers = async (filter = {}) => {
|
|
23
30
|
const cacheKey =
|
|
@@ -83,6 +90,10 @@ const createUserRole = async (data) => {
|
|
|
83
90
|
await updateCachedMembers();
|
|
84
91
|
if (data.userId) {
|
|
85
92
|
await clearUserWorkspaceCache(data.userId);
|
|
93
|
+
// Clear permissions cache if workspaceId exists
|
|
94
|
+
if (data.workspaceId) {
|
|
95
|
+
await clearUserPermissionsCache(data.workspaceId, data.userId);
|
|
96
|
+
}
|
|
86
97
|
}
|
|
87
98
|
|
|
88
99
|
return savedRole;
|
|
@@ -101,6 +112,13 @@ const updateUserRole = async (id, data) => {
|
|
|
101
112
|
await updateCachedMembers();
|
|
102
113
|
if (updatedRole.userId) {
|
|
103
114
|
await clearUserWorkspaceCache(updatedRole.userId);
|
|
115
|
+
// Clear permissions cache if workspaceId exists
|
|
116
|
+
if (updatedRole.workspaceId) {
|
|
117
|
+
await clearUserPermissionsCache(
|
|
118
|
+
updatedRole.workspaceId,
|
|
119
|
+
updatedRole.userId
|
|
120
|
+
);
|
|
121
|
+
}
|
|
104
122
|
}
|
|
105
123
|
}
|
|
106
124
|
|
|
@@ -110,6 +128,7 @@ const updateUserRole = async (id, data) => {
|
|
|
110
128
|
const deleteUserRole = async (id) => {
|
|
111
129
|
const role = await UserRole.findById(id).exec();
|
|
112
130
|
const userId = role?.userId;
|
|
131
|
+
const workspaceId = role?.workspaceId;
|
|
113
132
|
|
|
114
133
|
const deletedRole = await UserRole.findByIdAndDelete(id).exec();
|
|
115
134
|
|
|
@@ -117,6 +136,10 @@ const deleteUserRole = async (id) => {
|
|
|
117
136
|
await updateCachedMembers();
|
|
118
137
|
if (userId) {
|
|
119
138
|
await clearUserWorkspaceCache(userId);
|
|
139
|
+
// Clear permissions cache if workspaceId exists
|
|
140
|
+
if (workspaceId) {
|
|
141
|
+
await clearUserPermissionsCache(workspaceId, userId);
|
|
142
|
+
}
|
|
120
143
|
}
|
|
121
144
|
}
|
|
122
145
|
|
|
@@ -159,10 +182,171 @@ const findUserWorkspaces = async (userId) => {
|
|
|
159
182
|
return userRoleWithWorkspaces;
|
|
160
183
|
};
|
|
161
184
|
|
|
185
|
+
const convertPermissionsArrayToObject = (originalArray) => {
|
|
186
|
+
return originalArray?.reduce((acc, item) => {
|
|
187
|
+
const { id, actions, integrationPermissions, ...extras } = item;
|
|
188
|
+
const formattedExtras = {};
|
|
189
|
+
if (extras.deletable !== undefined) {
|
|
190
|
+
formattedExtras.deletable = extras.deletable;
|
|
191
|
+
}
|
|
192
|
+
if (extras.createUpdateable !== undefined) {
|
|
193
|
+
formattedExtras.createUpdateable = extras.createUpdateable;
|
|
194
|
+
}
|
|
195
|
+
acc[id] = {
|
|
196
|
+
actions: Object.keys(actions).filter((action) => actions[action]),
|
|
197
|
+
...formattedExtras,
|
|
198
|
+
...(integrationPermissions && {
|
|
199
|
+
integrationPermissions: Object.entries(integrationPermissions)
|
|
200
|
+
.filter(([_, allowed]) => allowed)
|
|
201
|
+
.map(([key]) => key),
|
|
202
|
+
}),
|
|
203
|
+
};
|
|
204
|
+
return acc;
|
|
205
|
+
}, {});
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
const getUserRoleWithPermissions = async (workspaceId, userId) => {
|
|
209
|
+
const cacheKey = `${CACHE_KEY_USER_PERMISSIONS_PREFIX}${workspaceId}_${userId}`;
|
|
210
|
+
let cachedData = await getRedisData(cacheKey);
|
|
211
|
+
|
|
212
|
+
if (cachedData && cachedData.roleWithPermissions) {
|
|
213
|
+
return cachedData.roleWithPermissions;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
try {
|
|
217
|
+
let data = await UserRole.findOne({
|
|
218
|
+
workspaceId: workspaceId,
|
|
219
|
+
userId: userId,
|
|
220
|
+
})
|
|
221
|
+
.populate({
|
|
222
|
+
path: "roleId",
|
|
223
|
+
select:
|
|
224
|
+
"id name userId userShift permissionId modulePermissions defaultModule",
|
|
225
|
+
populate: [{ path: "permissionId", select: "id name" }],
|
|
226
|
+
})
|
|
227
|
+
.lean()
|
|
228
|
+
.exec();
|
|
229
|
+
|
|
230
|
+
if (!data) {
|
|
231
|
+
return null;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const roleWithPermissions = {
|
|
235
|
+
...data,
|
|
236
|
+
roleId: data?.roleId?._id?.toString() || "",
|
|
237
|
+
role: data?.roleId?.name || "",
|
|
238
|
+
permissions:
|
|
239
|
+
convertPermissionsArrayToObject(
|
|
240
|
+
data?.roleId?.modulePermissions?.modules
|
|
241
|
+
) || [],
|
|
242
|
+
parentRole: data?.roleId?.permissionId?.name || "",
|
|
243
|
+
parentRoleId: data?.roleId?.permissionId?._id?.toString() || "",
|
|
244
|
+
defaultModule: data?.roleId?.defaultModule || "",
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
// Store in cache with other permission data
|
|
248
|
+
const permissionsData = cachedData || {};
|
|
249
|
+
permissionsData.roleWithPermissions = roleWithPermissions;
|
|
250
|
+
await setRedisData(cacheKey, permissionsData, null, 0);
|
|
251
|
+
|
|
252
|
+
return roleWithPermissions;
|
|
253
|
+
} catch (err) {
|
|
254
|
+
console.error("Error in getUserRoleWithPermissions:", err);
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
const getUserPermissions = async (workspaceId, userId) => {
|
|
260
|
+
const cacheKey = `${CACHE_KEY_USER_PERMISSIONS_PREFIX}${workspaceId}_${userId}`;
|
|
261
|
+
let cachedData = await getRedisData(cacheKey);
|
|
262
|
+
|
|
263
|
+
if (cachedData && cachedData.permissions) {
|
|
264
|
+
return cachedData.permissions;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
try {
|
|
268
|
+
let data = await UserRole.findOne({
|
|
269
|
+
workspaceId: workspaceId,
|
|
270
|
+
userId: userId,
|
|
271
|
+
})
|
|
272
|
+
.select("roleId userId")
|
|
273
|
+
.populate({
|
|
274
|
+
path: "roleId",
|
|
275
|
+
select: "modulePermissions",
|
|
276
|
+
})
|
|
277
|
+
.lean()
|
|
278
|
+
.exec();
|
|
279
|
+
|
|
280
|
+
if (!data) {
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const permissions =
|
|
285
|
+
convertPermissionsArrayToObject(
|
|
286
|
+
data?.roleId?.modulePermissions?.modules
|
|
287
|
+
) || null;
|
|
288
|
+
|
|
289
|
+
// Store in cache with other permission data
|
|
290
|
+
const permissionsData = cachedData || {};
|
|
291
|
+
permissionsData.permissions = permissions;
|
|
292
|
+
await setRedisData(cacheKey, permissionsData, null, 0);
|
|
293
|
+
|
|
294
|
+
return permissions;
|
|
295
|
+
} catch (err) {
|
|
296
|
+
console.error("Error in getUserPermissions:", err);
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
const getChannelsPermissions = async (workspaceId, userId) => {
|
|
302
|
+
const cacheKey = `${CACHE_KEY_USER_PERMISSIONS_PREFIX}${workspaceId}_${userId}`;
|
|
303
|
+
let cachedData = await getRedisData(cacheKey);
|
|
304
|
+
|
|
305
|
+
if (cachedData && cachedData.channelsPermissions) {
|
|
306
|
+
return cachedData.channelsPermissions;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
try {
|
|
310
|
+
let data = await UserRole.findOne({
|
|
311
|
+
workspaceId: workspaceId,
|
|
312
|
+
userId: userId,
|
|
313
|
+
})
|
|
314
|
+
.select("roleId userId")
|
|
315
|
+
.populate({
|
|
316
|
+
path: "roleId",
|
|
317
|
+
select: "modulePermissions",
|
|
318
|
+
})
|
|
319
|
+
.lean()
|
|
320
|
+
.exec();
|
|
321
|
+
|
|
322
|
+
if (!data) {
|
|
323
|
+
return [];
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
const channelsPermissions =
|
|
327
|
+
convertPermissionsArrayToObject(
|
|
328
|
+
data?.roleId?.modulePermissions?.modules
|
|
329
|
+
)?.["conversations"]?.["integrationPermissions"] || [];
|
|
330
|
+
|
|
331
|
+
// Store in cache with other permission data
|
|
332
|
+
const permissionsData = cachedData || {};
|
|
333
|
+
permissionsData.channelsPermissions = channelsPermissions;
|
|
334
|
+
await setRedisData(cacheKey, permissionsData, null, 0);
|
|
335
|
+
|
|
336
|
+
return channelsPermissions;
|
|
337
|
+
} catch (err) {
|
|
338
|
+
console.error("Error in getChannelsPermissions:", err);
|
|
339
|
+
return [];
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
|
|
162
343
|
module.exports = {
|
|
163
344
|
createUserRole,
|
|
164
345
|
findUserRole,
|
|
165
346
|
updateUserRole,
|
|
166
347
|
deleteUserRole,
|
|
167
348
|
findUserWorkspaces,
|
|
349
|
+
getUserRoleWithPermissions,
|
|
350
|
+
getUserPermissions,
|
|
351
|
+
getChannelsPermissions,
|
|
168
352
|
};
|
|
@@ -28,7 +28,8 @@ const createWorkspace = async (data) => {
|
|
|
28
28
|
|
|
29
29
|
const findWorkspaceById = async (id, select = []) => {
|
|
30
30
|
const workspaces = await getCachedWorkspaces();
|
|
31
|
-
const workspace =
|
|
31
|
+
const workspace =
|
|
32
|
+
workspaces.find((ws) => ws._id.toString() === id && !ws?.isDeleted) || null;
|
|
32
33
|
if (workspace && select.length > 0) {
|
|
33
34
|
return select.reduce((result, field) => {
|
|
34
35
|
if (workspace[field] !== undefined) {
|
|
@@ -49,6 +50,16 @@ const findWorkspace = async (filter) => {
|
|
|
49
50
|
);
|
|
50
51
|
};
|
|
51
52
|
|
|
53
|
+
const findSingleWorkspace = async (filter) => {
|
|
54
|
+
const cachedWorkspaces = await getCachedWorkspaces();
|
|
55
|
+
const cachedWorkspace = cachedWorkspaces.find((ws) =>
|
|
56
|
+
Object.entries(filter).every(([key, value]) => ws[key] === value)
|
|
57
|
+
);
|
|
58
|
+
if (cachedWorkspace) return cachedWorkspace;
|
|
59
|
+
const workspace = await Workspace.findOne(filter).lean().exec();
|
|
60
|
+
return workspace;
|
|
61
|
+
};
|
|
62
|
+
|
|
52
63
|
const findWorkspaceByIdAndQueueTracking = async (id) => {
|
|
53
64
|
const workspaces = await getCachedWorkspaces();
|
|
54
65
|
return (
|
|
@@ -75,6 +86,38 @@ const updateWorkspace = async (id, data) => {
|
|
|
75
86
|
return updatedWorkspace;
|
|
76
87
|
};
|
|
77
88
|
|
|
89
|
+
const updateOneWorkspace = async (filter, update, options = {}) => {
|
|
90
|
+
const result = await Workspace.updateOne(filter, update, options).exec();
|
|
91
|
+
if (result.matchedCount > 0) {
|
|
92
|
+
await updateCachedWorkspaces();
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const updateManyWorkspaces = async (filter, update, options = {}) => {
|
|
98
|
+
const result = await Workspace.updateMany(filter, update, options).exec();
|
|
99
|
+
if (result.matchedCount > 0) {
|
|
100
|
+
await updateCachedWorkspaces();
|
|
101
|
+
}
|
|
102
|
+
return result;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const findOneAndUpdateWorkspace = async (
|
|
106
|
+
filter,
|
|
107
|
+
update,
|
|
108
|
+
options = { new: true }
|
|
109
|
+
) => {
|
|
110
|
+
const updatedWorkspace = await Workspace.findOneAndUpdate(
|
|
111
|
+
filter,
|
|
112
|
+
update,
|
|
113
|
+
options
|
|
114
|
+
).exec();
|
|
115
|
+
if (updatedWorkspace) {
|
|
116
|
+
await updateCachedWorkspaces();
|
|
117
|
+
}
|
|
118
|
+
return updatedWorkspace;
|
|
119
|
+
};
|
|
120
|
+
|
|
78
121
|
const deleteWorkspace = async (id) => {
|
|
79
122
|
const deletedWorkspace = await Workspace.findByIdAndDelete(id).exec();
|
|
80
123
|
if (deletedWorkspace) {
|
|
@@ -85,10 +128,14 @@ const deleteWorkspace = async (id) => {
|
|
|
85
128
|
|
|
86
129
|
module.exports = {
|
|
87
130
|
createWorkspace,
|
|
88
|
-
findWorkspaceById,
|
|
89
131
|
findWorkspace,
|
|
132
|
+
findSingleWorkspace,
|
|
133
|
+
findWorkspaceById,
|
|
90
134
|
findWorkspaceByIdAndQueueTracking,
|
|
91
135
|
findAllWorkspaces,
|
|
136
|
+
findOneAndUpdateWorkspace,
|
|
92
137
|
updateWorkspace,
|
|
138
|
+
updateOneWorkspace,
|
|
139
|
+
updateManyWorkspaces,
|
|
93
140
|
deleteWorkspace,
|
|
94
141
|
};
|
package/models/UserRole.js
CHANGED
|
@@ -52,112 +52,6 @@ const userRoleSchema = new Schema(
|
|
|
52
52
|
|
|
53
53
|
const UserRole = mongoose.model("UserRole", userRoleSchema);
|
|
54
54
|
|
|
55
|
-
const convertPermissionsArrayToObject = (originalArray) => {
|
|
56
|
-
return originalArray?.reduce((acc, item) => {
|
|
57
|
-
const { id, actions, integrationPermissions, ...extras } = item;
|
|
58
|
-
const formattedExtras = {};
|
|
59
|
-
if (extras.deletable !== undefined) {
|
|
60
|
-
formattedExtras.deletable = extras.deletable;
|
|
61
|
-
}
|
|
62
|
-
if (extras.createUpdateable !== undefined) {
|
|
63
|
-
formattedExtras.createUpdateable = extras.createUpdateable;
|
|
64
|
-
}
|
|
65
|
-
acc[id] = {
|
|
66
|
-
actions: Object.keys(actions).filter((action) => actions[action]),
|
|
67
|
-
...formattedExtras,
|
|
68
|
-
...(integrationPermissions && {
|
|
69
|
-
integrationPermissions: Object.entries(integrationPermissions)
|
|
70
|
-
.filter(([_, allowed]) => allowed)
|
|
71
|
-
.map(([key]) => key),
|
|
72
|
-
}),
|
|
73
|
-
};
|
|
74
|
-
return acc;
|
|
75
|
-
}, {});
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
const getUserRoleWithPermissions = async (workspaceId, userId) => {
|
|
79
|
-
try {
|
|
80
|
-
let data = await UserRole.findOne({
|
|
81
|
-
workspaceId: workspaceId,
|
|
82
|
-
userId: userId,
|
|
83
|
-
})
|
|
84
|
-
.populate({
|
|
85
|
-
path: "roleId",
|
|
86
|
-
select:
|
|
87
|
-
"id name userId userShift permissionId modulePermissions defaultModule",
|
|
88
|
-
populate: [{ path: "permissionId", select: "id name" }],
|
|
89
|
-
})
|
|
90
|
-
.lean()
|
|
91
|
-
.exec();
|
|
92
|
-
return {
|
|
93
|
-
...data,
|
|
94
|
-
roleId: data?.roleId?._id?.toString() || "",
|
|
95
|
-
role: data?.roleId?.name || "",
|
|
96
|
-
permissions:
|
|
97
|
-
convertPermissionsArrayToObject(
|
|
98
|
-
data?.roleId?.modulePermissions?.modules
|
|
99
|
-
) || [],
|
|
100
|
-
parentRole: data?.roleId?.permissionId?.name || "",
|
|
101
|
-
parentRoleId: data?.roleId?.permissionId?._id?.toString() || "",
|
|
102
|
-
defaultModule: data?.roleId?.defaultModule || "",
|
|
103
|
-
};
|
|
104
|
-
} catch (err) {
|
|
105
|
-
console.error("Error in getUserRole:", err);
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
const getUserPermissions = async (workspaceId, userId) => {
|
|
111
|
-
try {
|
|
112
|
-
let data = await UserRole.findOne({
|
|
113
|
-
workspaceId: workspaceId,
|
|
114
|
-
userId: userId,
|
|
115
|
-
})
|
|
116
|
-
.select("roleId userId")
|
|
117
|
-
.populate({
|
|
118
|
-
path: "roleId",
|
|
119
|
-
select: "modulePermissions",
|
|
120
|
-
})
|
|
121
|
-
.lean()
|
|
122
|
-
.exec();
|
|
123
|
-
return (
|
|
124
|
-
convertPermissionsArrayToObject(
|
|
125
|
-
data?.roleId?.modulePermissions?.modules
|
|
126
|
-
) || null
|
|
127
|
-
);
|
|
128
|
-
} catch (err) {
|
|
129
|
-
console.error("Error in getUserRole:", err);
|
|
130
|
-
return null;
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
const getChannelsPermissions = async (workspaceId, userId) => {
|
|
135
|
-
try {
|
|
136
|
-
let data = await UserRole.findOne({
|
|
137
|
-
workspaceId: workspaceId,
|
|
138
|
-
userId: userId,
|
|
139
|
-
})
|
|
140
|
-
.select("roleId userId")
|
|
141
|
-
.populate({
|
|
142
|
-
path: "roleId",
|
|
143
|
-
select: "modulePermissions",
|
|
144
|
-
})
|
|
145
|
-
.lean()
|
|
146
|
-
.exec();
|
|
147
|
-
return (
|
|
148
|
-
convertPermissionsArrayToObject(
|
|
149
|
-
data?.roleId?.modulePermissions?.modules
|
|
150
|
-
)?.["conversations"]?.["integrationPermissions"] || []
|
|
151
|
-
);
|
|
152
|
-
} catch (err) {
|
|
153
|
-
console.error("Error in getUserRole:", err);
|
|
154
|
-
return null;
|
|
155
|
-
}
|
|
156
|
-
};
|
|
157
|
-
|
|
158
55
|
module.exports = {
|
|
159
56
|
UserRole,
|
|
160
|
-
getChannelsPermissions,
|
|
161
|
-
getUserPermissions,
|
|
162
|
-
getUserRoleWithPermissions,
|
|
163
57
|
};
|