shuttlepro-shared 1.2.43 → 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.
@@ -79,30 +79,6 @@ const findTemplateByFilter = async (
79
79
  ) || null
80
80
  );
81
81
  };
82
- const findAllTemplateByFilter = async (
83
- filter,
84
- bodyFilter = {},
85
- workspaceId = null
86
- ) => {
87
- const allTemplates = await getCachedAllDescriptionTemplates();
88
-
89
- // Filter by workspaceId if provided
90
- let filteredTemplates = workspaceId
91
- ? allTemplates.filter((desc) => desc.workspaceId === workspaceId)
92
- : allTemplates;
93
-
94
- return (
95
- filteredTemplates.filter(
96
- (item) =>
97
- // Check direct properties of item
98
- Object.entries(filter).every(([key, value]) => item[key] === value) &&
99
- // If bodyFilter is provided, check inside item.body
100
- Object.entries(bodyFilter).every(
101
- ([key, value]) => item.body?.[key] === value
102
- )
103
- ) || null
104
- );
105
- };
106
82
  const createOrUpdateTemplate = async (filter, data) => {
107
83
  const template = await DescriptionTemplate.findOneAndUpdate(filter, data, {
108
84
  upsert: true,
@@ -225,5 +201,4 @@ module.exports = {
225
201
  findTemplateById,
226
202
  deleteTemplatesByFilter,
227
203
  insertManyTemplates,
228
- findAllTemplateByFilter,
229
204
  };
@@ -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
+ };
@@ -1,12 +1,68 @@
1
1
  const { UserRole } = require("../../models/UserRole");
2
+ const { getRedisData, setRedisData } = require("../../config/redis");
2
3
 
3
- const createUserRole = async (data) => {
4
- const newRole = new UserRole(data);
5
- const savedRole = await newRole.save();
6
- return savedRole;
4
+ const defaultSelect =
5
+ "iconUrl thumbUrl name productsCount ordersCount contact email address websiteUrl facebookUrl twitterUrl instagramUrl members defaultModule";
6
+
7
+ // Cache keys
8
+ const CACHE_KEY_ALL_MEMBERS = "userroles_all_members";
9
+ const CACHE_KEY_USER_WORKSPACE_PREFIX = "userrole_workspace_";
10
+ const CACHE_KEY_USER_PERMISSIONS_PREFIX = "user_permissions_";
11
+
12
+ // Clear user workspace cache
13
+ const clearUserWorkspaceCache = async (userId) => {
14
+ await setRedisData(
15
+ `${CACHE_KEY_USER_WORKSPACE_PREFIX}${userId}`,
16
+ null,
17
+ null,
18
+ 0
19
+ );
7
20
  };
8
21
 
9
- const findUserRole = async (filter = {}) => {
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
+
28
+ // Get cached members
29
+ const getCachedMembers = async (filter = {}) => {
30
+ const cacheKey =
31
+ Object.keys(filter).length > 0
32
+ ? `${CACHE_KEY_ALL_MEMBERS}_${JSON.stringify(filter)}`
33
+ : CACHE_KEY_ALL_MEMBERS;
34
+
35
+ let members = await getRedisData(cacheKey);
36
+
37
+ if (!members) {
38
+ members = await UserRole.find(filter)
39
+ .select("userId role userShift roleId")
40
+ .populate({
41
+ path: "roleId",
42
+ select: "id name userId userShift permissionId modulePermissions",
43
+ populate: [{ path: "permissionId", select: "id name" }],
44
+ })
45
+ .populate({
46
+ path: "userId",
47
+ match: { isDeleted: false, suspended: false },
48
+ select: "firstName lastName role email picture userShift",
49
+ })
50
+ .lean()
51
+ .exec();
52
+
53
+ await setRedisData(cacheKey, members, null, 0);
54
+ }
55
+
56
+ return members;
57
+ };
58
+
59
+ // Update the cache for all members
60
+ const updateCachedMembers = async (filter = {}) => {
61
+ const cacheKey =
62
+ Object.keys(filter).length > 0
63
+ ? `${CACHE_KEY_ALL_MEMBERS}_${JSON.stringify(filter)}`
64
+ : CACHE_KEY_ALL_MEMBERS;
65
+
10
66
  const members = await UserRole.find(filter)
11
67
  .select("userId role userShift roleId")
12
68
  .populate({
@@ -18,28 +74,279 @@ const findUserRole = async (filter = {}) => {
18
74
  path: "userId",
19
75
  match: { isDeleted: false, suspended: false },
20
76
  select: "firstName lastName role email picture userShift",
21
- });
77
+ })
78
+ .lean()
79
+ .exec();
22
80
 
81
+ await setRedisData(cacheKey, members, null, 0);
23
82
  return members;
24
83
  };
25
84
 
85
+ const createUserRole = async (data) => {
86
+ const newRole = new UserRole(data);
87
+ const savedRole = await newRole.save();
88
+
89
+ // Update cache
90
+ await updateCachedMembers();
91
+ if (data.userId) {
92
+ await clearUserWorkspaceCache(data.userId);
93
+ // Clear permissions cache if workspaceId exists
94
+ if (data.workspaceId) {
95
+ await clearUserPermissionsCache(data.workspaceId, data.userId);
96
+ }
97
+ }
98
+
99
+ return savedRole;
100
+ };
101
+
102
+ const findUserRole = async (filter = {}) => {
103
+ return await getCachedMembers(filter);
104
+ };
105
+
26
106
  const updateUserRole = async (id, data) => {
27
107
  const updatedRole = await UserRole.findByIdAndUpdate(id, data, {
28
108
  new: true,
29
109
  }).exec();
30
110
 
111
+ if (updatedRole) {
112
+ await updateCachedMembers();
113
+ if (updatedRole.userId) {
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
+ }
122
+ }
123
+ }
124
+
31
125
  return updatedRole;
32
126
  };
33
127
 
34
128
  const deleteUserRole = async (id) => {
129
+ const role = await UserRole.findById(id).exec();
130
+ const userId = role?.userId;
131
+ const workspaceId = role?.workspaceId;
132
+
35
133
  const deletedRole = await UserRole.findByIdAndDelete(id).exec();
36
134
 
135
+ if (deletedRole) {
136
+ await updateCachedMembers();
137
+ if (userId) {
138
+ await clearUserWorkspaceCache(userId);
139
+ // Clear permissions cache if workspaceId exists
140
+ if (workspaceId) {
141
+ await clearUserPermissionsCache(workspaceId, userId);
142
+ }
143
+ }
144
+ }
145
+
37
146
  return deletedRole;
38
147
  };
39
148
 
149
+ const findUserWorkspaces = async (userId) => {
150
+ const cacheKey = `${CACHE_KEY_USER_WORKSPACE_PREFIX}${userId}`;
151
+ let userRoleWithWorkspaces = await getRedisData(cacheKey);
152
+ if (!userRoleWithWorkspaces) {
153
+ userRoleWithWorkspaces = await UserRole.find({
154
+ userId: userId,
155
+ })
156
+ .select("userId roleId workspaceId")
157
+ .populate({
158
+ path: "roleId",
159
+ select: "id name userId userShift permissionId modulePermissions",
160
+ populate: [{ path: "permissionId", select: "id name" }],
161
+ })
162
+ .populate({
163
+ path: "workspaceId",
164
+ select: defaultSelect,
165
+ match: { isDeleted: false },
166
+ })
167
+ .lean()
168
+ .exec();
169
+ userRoleWithWorkspaces = userRoleWithWorkspaces.map((ur) => {
170
+ return {
171
+ ...ur?.workspaceId,
172
+ id: ur?.workspaceId?._id?.toString(),
173
+ _id: ur?.workspaceId?._id?.toString(),
174
+ role: ur?.roleId?.name || "",
175
+ permissions: ur?.roleId?.modulePermissions?.modules || [],
176
+ };
177
+ });
178
+ if (userRoleWithWorkspaces) {
179
+ await setRedisData(cacheKey, userRoleWithWorkspaces, null, 0);
180
+ }
181
+ }
182
+ return userRoleWithWorkspaces;
183
+ };
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
+
40
343
  module.exports = {
41
344
  createUserRole,
42
345
  findUserRole,
43
346
  updateUserRole,
44
347
  deleteUserRole,
348
+ findUserWorkspaces,
349
+ getUserRoleWithPermissions,
350
+ getUserPermissions,
351
+ getChannelsPermissions,
45
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 = workspaces.find((ws) => ws._id.toString() === id) || null;
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/config/redis.js CHANGED
@@ -103,6 +103,7 @@ const addDataToRedisSet = async (key, value) => {
103
103
  return false;
104
104
  }
105
105
  };
106
+
106
107
  const removeDataFromRedisSet = async (key, value) => {
107
108
  try {
108
109
  await connectRedis();
@@ -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
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shuttlepro-shared",
3
- "version": "1.2.43",
3
+ "version": "1.2.44",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {