shuttlepro-shared 1.3.26 → 1.3.27
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/common/repositories/customerProfile.repository.js +5 -1
- package/common/repositories/userRole.repository.js +2 -5
- package/config/redis.js +73 -72
- package/middlewares/checkPermission/index.js +23 -36
- package/models/Customer.js +0 -1
- package/models/Order.js +0 -11
- package/models/Workspace.js +0 -10
- package/package.json +1 -1
|
@@ -133,7 +133,10 @@ const deleteAllCustomerProfilesByWorkspace = async (workspaceId) => {
|
|
|
133
133
|
await CustomerProfile.deleteMany({ workspaceId }).exec();
|
|
134
134
|
await updateCachedAllCustomerProfiles();
|
|
135
135
|
};
|
|
136
|
-
|
|
136
|
+
const findAllCustomerProfilesByFilterFromDb = async (filter = {}) => {
|
|
137
|
+
const profiles = await CustomerProfile.find(filter).lean().exec();
|
|
138
|
+
return profiles ?? [];
|
|
139
|
+
};
|
|
137
140
|
module.exports = {
|
|
138
141
|
createCustomerProfile,
|
|
139
142
|
findCustomerProfilesByWorkspaceId,
|
|
@@ -144,4 +147,5 @@ module.exports = {
|
|
|
144
147
|
deleteCustomerProfile,
|
|
145
148
|
deleteAllCustomerProfilesByWorkspace,
|
|
146
149
|
findAllCustomerProfilesByFilter,
|
|
150
|
+
findAllCustomerProfilesByFilterFromDb,
|
|
147
151
|
};
|
|
@@ -2,7 +2,7 @@ const { UserRole } = require("../../models/UserRole");
|
|
|
2
2
|
const { getRedisData, setRedisData } = require("../../config/redis");
|
|
3
3
|
|
|
4
4
|
const defaultSelect =
|
|
5
|
-
"iconUrl thumbUrl name productsCount ordersCount contact email address websiteUrl facebookUrl twitterUrl instagramUrl members defaultModule
|
|
5
|
+
"iconUrl thumbUrl name productsCount ordersCount contact email address websiteUrl facebookUrl twitterUrl instagramUrl members defaultModule";
|
|
6
6
|
|
|
7
7
|
// Cache keys
|
|
8
8
|
const MEMBERS = "members";
|
|
@@ -35,7 +35,6 @@ const updateCachedMembers = async (workspaceId) => {
|
|
|
35
35
|
|
|
36
36
|
const getMembers = async (workspaceId) => {
|
|
37
37
|
let members = await getRedisData(workspaceId, MEMBERS);
|
|
38
|
-
console.log(members, "inside members");
|
|
39
38
|
if (!members || members?.length === 0) {
|
|
40
39
|
members = await UserRole.find({ workspaceId })
|
|
41
40
|
.select("userId role userShift roleId isOwner workspaceId")
|
|
@@ -54,7 +53,6 @@ const getMembers = async (workspaceId) => {
|
|
|
54
53
|
.exec();
|
|
55
54
|
await setRedisData(workspaceId, members, MEMBERS, 3600);
|
|
56
55
|
}
|
|
57
|
-
console.log(members, "inside after members");
|
|
58
56
|
return members;
|
|
59
57
|
};
|
|
60
58
|
|
|
@@ -63,8 +61,7 @@ const getMemberByWorkspaceIdAndUserId = async (workspaceId, userId) => {
|
|
|
63
61
|
return (
|
|
64
62
|
members?.find(
|
|
65
63
|
(member) =>
|
|
66
|
-
member?.workspaceId
|
|
67
|
-
member?.userId?._id?.toString() === userId?.toString()
|
|
64
|
+
member?.workspaceId === workspaceId && member?.userId?._id === userId
|
|
68
65
|
) || null
|
|
69
66
|
);
|
|
70
67
|
};
|
package/config/redis.js
CHANGED
|
@@ -8,51 +8,53 @@ const client = createClient({
|
|
|
8
8
|
url: REDIS_URL,
|
|
9
9
|
socket: { reconnectStrategy: (retries) => Math.min(retries * 50, 1000) }, // Exponential backoff
|
|
10
10
|
});
|
|
11
|
+
|
|
12
|
+
// ✅ Create separate Pub/Sub clients
|
|
11
13
|
const publisher = client.duplicate();
|
|
12
14
|
const subscriber = client.duplicate();
|
|
13
15
|
|
|
14
|
-
// ✅ Redis Events
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
client.on("end", () => console.log(`❗ ${label} Connection Closed`));
|
|
20
|
-
client.on("reconnecting", () => console.warn(`🔄 ${label} Reconnecting...`));
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
handleEvents(client, "Main Redis");
|
|
24
|
-
handleEvents(publisher, "Publisher Redis");
|
|
25
|
-
handleEvents(subscriber, "Subscriber Redis");
|
|
16
|
+
// ✅ Handle Redis Connection Events
|
|
17
|
+
client.on("error", (err) => console.error("❌ Redis Error:", err));
|
|
18
|
+
client.on("connect", () => console.log("✅ Redis Connected"));
|
|
19
|
+
client.on("ready", () => console.log("🚀 Redis Ready to use"));
|
|
20
|
+
client.on("end", () => console.log("❗ Redis Connection Closed"));
|
|
26
21
|
|
|
27
|
-
// ✅ Ensure Redis is connected
|
|
22
|
+
// ✅ Ensure Redis is connected before performing operations
|
|
28
23
|
const connectRedis = async () => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (!config["notify-keyspace-events"]?.includes("Ex")) {
|
|
37
|
-
await client.configSet("notify-keyspace-events", "Ex");
|
|
24
|
+
if (!client.isOpen) {
|
|
25
|
+
try {
|
|
26
|
+
await client.connect();
|
|
27
|
+
await publisher.connect();
|
|
28
|
+
await subscriber.connect();
|
|
29
|
+
} catch (err) {
|
|
30
|
+
console.error("❌ Failed to connect to Redis:", err);
|
|
38
31
|
}
|
|
39
|
-
} catch (err) {
|
|
40
|
-
console.error("❌ Failed to connect to Redis:", err);
|
|
41
32
|
}
|
|
33
|
+
await client.configSet("notify-keyspace-events", "Ex");
|
|
42
34
|
};
|
|
43
35
|
|
|
44
|
-
|
|
36
|
+
/**
|
|
37
|
+
* ✅ Publish Data to a Channel
|
|
38
|
+
* @param {string} channel - The Redis Pub/Sub channel
|
|
39
|
+
* @param {any} message - The message to send
|
|
40
|
+
*/
|
|
45
41
|
const publishToChannel = async (channel, message) => {
|
|
46
42
|
try {
|
|
43
|
+
await connectRedis();
|
|
47
44
|
await publisher.publish(channel, JSON.stringify(message));
|
|
48
45
|
} catch (err) {
|
|
49
46
|
console.error("❌ Error publishing message:", err);
|
|
50
47
|
}
|
|
51
48
|
};
|
|
52
49
|
|
|
53
|
-
|
|
50
|
+
/**
|
|
51
|
+
* ✅ Subscribe & Listen for Messages
|
|
52
|
+
* @param {string} channel - The Redis Pub/Sub channel
|
|
53
|
+
* @param {function} callback - Callback function to handle messages
|
|
54
|
+
*/
|
|
54
55
|
const subscribeToChannel = async (channel, callback, expiry = false) => {
|
|
55
56
|
try {
|
|
57
|
+
await connectRedis();
|
|
56
58
|
await subscriber.subscribe(channel, (message) => {
|
|
57
59
|
if (expiry) callback(message);
|
|
58
60
|
else callback(JSON.parse(message));
|
|
@@ -62,7 +64,13 @@ const subscribeToChannel = async (channel, callback, expiry = false) => {
|
|
|
62
64
|
}
|
|
63
65
|
};
|
|
64
66
|
|
|
65
|
-
|
|
67
|
+
/**
|
|
68
|
+
* ✅ Set Data in Redis (Supports String & Hash)
|
|
69
|
+
* @param {string} key - The Redis key
|
|
70
|
+
* @param {any} value - The value to store
|
|
71
|
+
* @param {string|null} field - Optional field for Hash storage
|
|
72
|
+
* @param {number} expiryInSeconds - Expiry time in seconds (default: 3600)
|
|
73
|
+
*/
|
|
66
74
|
const setRedisData = async (
|
|
67
75
|
key,
|
|
68
76
|
value,
|
|
@@ -70,6 +78,7 @@ const setRedisData = async (
|
|
|
70
78
|
expiryInSeconds = 3600
|
|
71
79
|
) => {
|
|
72
80
|
try {
|
|
81
|
+
await connectRedis();
|
|
73
82
|
const stringifiedValue = JSON.stringify(value);
|
|
74
83
|
let result;
|
|
75
84
|
|
|
@@ -90,27 +99,43 @@ const setRedisData = async (
|
|
|
90
99
|
}
|
|
91
100
|
};
|
|
92
101
|
|
|
93
|
-
|
|
94
|
-
const getRedisData = async (key, field = null) => {
|
|
102
|
+
const addDataToRedisSet = async (key, value) => {
|
|
95
103
|
try {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
return result ? JSON.parse(result) : null;
|
|
104
|
+
await connectRedis();
|
|
105
|
+
await client.sAdd(key, value);
|
|
106
|
+
return true;
|
|
100
107
|
} catch (err) {
|
|
101
|
-
|
|
102
|
-
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const removeDataFromRedisSet = async (key, value) => {
|
|
113
|
+
try {
|
|
114
|
+
await connectRedis();
|
|
115
|
+
await client.sRem(key, value);
|
|
116
|
+
return true;
|
|
117
|
+
} catch (err) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
const isMemberOfRedisSet = async (key, value) => {
|
|
122
|
+
try {
|
|
123
|
+
await connectRedis();
|
|
124
|
+
return await client.sIsMember(key, value);
|
|
125
|
+
} catch (err) {
|
|
126
|
+
console.log(err, "err");
|
|
127
|
+
return false;
|
|
103
128
|
}
|
|
104
129
|
};
|
|
105
130
|
/**
|
|
106
|
-
* ✅ Get
|
|
131
|
+
* ✅ Get Data from Redis (Supports String & Hash)
|
|
107
132
|
* @param {string} key - The Redis key
|
|
108
133
|
* @param {string|null} field - Optional field for Hash retrieval
|
|
109
134
|
*/
|
|
110
|
-
const
|
|
135
|
+
const getRedisData = async (key, field = null) => {
|
|
111
136
|
try {
|
|
112
137
|
await connectRedis();
|
|
113
|
-
let result = await client.
|
|
138
|
+
let result = field ? await client.hGet(key, field) : await client.get(key);
|
|
114
139
|
return result ? JSON.parse(result) : null;
|
|
115
140
|
} catch (err) {
|
|
116
141
|
console.error("❌ Error getting Redis data:", err);
|
|
@@ -118,9 +143,14 @@ const getRedisDataTime = async (key) => {
|
|
|
118
143
|
}
|
|
119
144
|
};
|
|
120
145
|
|
|
121
|
-
|
|
146
|
+
/**
|
|
147
|
+
* ✅ Delete Data from Redis (Supports String & Hash)
|
|
148
|
+
* @param {string} key - The Redis key
|
|
149
|
+
* @param {string|null} field - Optional field for Hash deletion
|
|
150
|
+
*/
|
|
122
151
|
const deleteRedisData = async (key, field = null) => {
|
|
123
152
|
try {
|
|
153
|
+
await connectRedis();
|
|
124
154
|
return field ? await client.hDel(key, field) : await client.del(key);
|
|
125
155
|
} catch (err) {
|
|
126
156
|
console.error("❌ Error deleting Redis data:", err);
|
|
@@ -128,37 +158,9 @@ const deleteRedisData = async (key, field = null) => {
|
|
|
128
158
|
}
|
|
129
159
|
};
|
|
130
160
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
await client.sAdd(key, value);
|
|
135
|
-
return true;
|
|
136
|
-
} catch (err) {
|
|
137
|
-
console.error("❌ Error adding to Redis set:", err);
|
|
138
|
-
return false;
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
const removeDataFromRedisSet = async (key, value) => {
|
|
143
|
-
try {
|
|
144
|
-
await client.sRem(key, value);
|
|
145
|
-
return true;
|
|
146
|
-
} catch (err) {
|
|
147
|
-
console.error("❌ Error removing from Redis set:", err);
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
const isMemberOfRedisSet = async (key, value) => {
|
|
153
|
-
try {
|
|
154
|
-
return await client.sIsMember(key, value);
|
|
155
|
-
} catch (err) {
|
|
156
|
-
console.error("❌ Error checking membership in Redis set:", err);
|
|
157
|
-
return false;
|
|
158
|
-
}
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
// ✅ Graceful Shutdown
|
|
161
|
+
/**
|
|
162
|
+
* ✅ Graceful Shutdown Handling
|
|
163
|
+
*/
|
|
162
164
|
const closeClients = async () => {
|
|
163
165
|
if (client.isOpen) await client.quit();
|
|
164
166
|
if (publisher.isOpen) await publisher.quit();
|
|
@@ -182,13 +184,12 @@ module.exports = {
|
|
|
182
184
|
client,
|
|
183
185
|
publisher,
|
|
184
186
|
subscriber,
|
|
185
|
-
connectRedis,
|
|
186
187
|
setRedisData,
|
|
187
|
-
getRedisDataTime,
|
|
188
188
|
getRedisData,
|
|
189
189
|
deleteRedisData,
|
|
190
190
|
publishToChannel,
|
|
191
191
|
subscribeToChannel,
|
|
192
|
+
connectRedis,
|
|
192
193
|
addDataToRedisSet,
|
|
193
194
|
removeDataFromRedisSet,
|
|
194
195
|
isMemberOfRedisSet,
|
|
@@ -31,42 +31,29 @@ exports.checkPermission = async (req, res, next, values) => {
|
|
|
31
31
|
const accessToken = token.split(" ")[1];
|
|
32
32
|
const body = getBodyFromDecodeToken(accessToken);
|
|
33
33
|
if (body) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
// isVerified: body.isVerified,
|
|
58
|
-
// role: body.role,
|
|
59
|
-
// isMember: body.isMember,
|
|
60
|
-
// uuid: body.uuid,
|
|
61
|
-
// };
|
|
62
|
-
// req.currentModulePermission = moduleObj;
|
|
63
|
-
// return next();
|
|
64
|
-
// } else {
|
|
65
|
-
// return res.status(HttpStatusCode.UNAUTHORIZED).json({
|
|
66
|
-
// code: HttpStatusCode.UNAUTHORIZED,
|
|
67
|
-
// message: GenericMessages.PERMISSION_DENIED,
|
|
68
|
-
// });
|
|
69
|
-
// }
|
|
34
|
+
const { module, action } = values;
|
|
35
|
+
const moduleObj = getModule(body, module);
|
|
36
|
+
if (moduleObj && moduleObj.includes(action)) {
|
|
37
|
+
req.user = {
|
|
38
|
+
id: body.id,
|
|
39
|
+
type: body.type,
|
|
40
|
+
email: body.email,
|
|
41
|
+
firstName: body.firstName,
|
|
42
|
+
lastName: body.lastName,
|
|
43
|
+
suspended: body.suspended,
|
|
44
|
+
isVerified: body.isVerified,
|
|
45
|
+
role: body.role,
|
|
46
|
+
isMember: body.isMember,
|
|
47
|
+
uuid: body.uuid,
|
|
48
|
+
};
|
|
49
|
+
req.currentModulePermission = moduleObj;
|
|
50
|
+
return next();
|
|
51
|
+
} else {
|
|
52
|
+
return res.status(HttpStatusCode.UNAUTHORIZED).json({
|
|
53
|
+
code: HttpStatusCode.UNAUTHORIZED,
|
|
54
|
+
message: GenericMessages.PERMISSION_DENIED,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
70
57
|
}
|
|
71
58
|
return res.status(HttpStatusCode.UNAUTHORIZED).json({
|
|
72
59
|
code: HttpStatusCode.UNAUTHORIZED,
|
package/models/Customer.js
CHANGED
package/models/Order.js
CHANGED
|
@@ -136,14 +136,6 @@ const OrderSchema = new Schema(
|
|
|
136
136
|
paymentDate: { type: String, default: "" },
|
|
137
137
|
paymentDetails: {},
|
|
138
138
|
},
|
|
139
|
-
merged: {
|
|
140
|
-
status: { type: String, default: "open" },
|
|
141
|
-
webOrderNumbers: [],
|
|
142
|
-
orderNumbers: [],
|
|
143
|
-
localOrderIds: [],
|
|
144
|
-
webOrderIds: [],
|
|
145
|
-
details: [],
|
|
146
|
-
},
|
|
147
139
|
credentials: {},
|
|
148
140
|
ticketId: { type: String, default: "" },
|
|
149
141
|
sender: { type: String, default: "" },
|
|
@@ -167,9 +159,6 @@ const OrderSchema = new Schema(
|
|
|
167
159
|
},
|
|
168
160
|
orderName: { type: String, default: "" },
|
|
169
161
|
totalWeight: { type: String, default: "" },
|
|
170
|
-
currency: {},
|
|
171
|
-
presentedCurrency: {},
|
|
172
|
-
exchangeRate: { type: Number, default: 0 },
|
|
173
162
|
},
|
|
174
163
|
{ timestamps: true, toJSON: { virtuals: true }, toObject: { virtuals: true } }
|
|
175
164
|
);
|
package/models/Workspace.js
CHANGED
|
@@ -292,16 +292,6 @@ const workspaceSchema = new mongoose.Schema(
|
|
|
292
292
|
default: "everyone",
|
|
293
293
|
},
|
|
294
294
|
defaultShift: { type: String, default: "" },
|
|
295
|
-
automationManager: {
|
|
296
|
-
delayThreshold: {
|
|
297
|
-
type: Number,
|
|
298
|
-
default: 5,
|
|
299
|
-
},
|
|
300
|
-
messageCount: {
|
|
301
|
-
type: Number,
|
|
302
|
-
default: 3,
|
|
303
|
-
},
|
|
304
|
-
},
|
|
305
295
|
},
|
|
306
296
|
{ timestamps: true, toJSON: { virtuals: true }, toObject: { virtuals: true } }
|
|
307
297
|
);
|