@infuro/cms-core 1.0.66 → 1.0.68
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin.cjs +214 -32
- package/dist/admin.js +214 -32
- package/dist/api.cjs +45 -42
- package/dist/api.js +12 -9
- package/dist/auth.cjs +51 -51
- package/dist/auth.js +3 -3
- package/dist/{chunk-QYRXLURF.cjs → chunk-22XKONB5.cjs} +640 -145
- package/dist/{chunk-MVHDC3XF.js → chunk-5NOZSG6J.js} +22 -11
- package/dist/{chunk-TU23GJPJ.js → chunk-7JCCPQEF.js} +1 -1
- package/dist/{chunk-WMMZZRDJ.cjs → chunk-GN4LKG4V.cjs} +1 -1
- package/dist/{chunk-KM2I6AFP.cjs → chunk-HBUV73RB.cjs} +9 -9
- package/dist/chunk-IKTBZJHT.js +16 -0
- package/dist/chunk-M5GPOPGX.cjs +49 -0
- package/dist/{chunk-T33KU5G5.js → chunk-MYUGQHU4.js} +548 -53
- package/dist/{chunk-NV5IRHI3.js → chunk-N4LBZXBG.js} +2 -2
- package/dist/{chunk-J7FMZK66.cjs → chunk-O4AFPDQ4.cjs} +22 -11
- package/dist/{chunk-4U6DATGZ.cjs → chunk-OV5TRZET.cjs} +7 -7
- package/dist/chunk-P6S4XFZO.cjs +18 -0
- package/dist/{chunk-RCE5SJBA.js → chunk-SKJH7PX4.js} +1 -1
- package/dist/{chunk-5MZFQRDW.cjs → chunk-SMHQV3WL.cjs} +4 -4
- package/dist/chunk-SUUD7OUG.cjs +455 -0
- package/dist/{chunk-XFDIIVZB.cjs → chunk-UMC7W5G3.cjs} +3 -3
- package/dist/chunk-WKDBMDUX.js +45 -0
- package/dist/{chunk-6DBDJ4VD.js → chunk-Z5G54EGD.js} +2 -2
- package/dist/chunk-Z5OB5QGN.js +465 -0
- package/dist/chunk-ZIT4IP6N.js +445 -0
- package/dist/chunk-ZX5U3VCB.cjs +471 -0
- package/dist/{chunk-NR44CK5E.js → chunk-ZY64VJMS.js} +1 -1
- package/dist/email-queue-3QBQ63F7.js +8 -0
- package/dist/{email-queue-4OY45JIU.cjs → email-queue-K4E4OFI7.cjs} +9 -6
- package/dist/{emit-order-notification-trigger-ZD5YN3JM.cjs → emit-order-notification-trigger-ROASTYQP.cjs} +3 -3
- package/dist/{emit-order-notification-trigger-EJJZ6XTS.js → emit-order-notification-trigger-YUQTPELC.js} +1 -1
- package/dist/{erp-order-invoice-YUSPZ7CE.cjs → erp-order-invoice-AZ5MX2JB.cjs} +8 -5
- package/dist/{erp-order-invoice-H6HCJ7YS.js → erp-order-invoice-XSYHAMBS.js} +4 -1
- package/dist/generate-local-invoice-pdf-BQTCL5MW.cjs +12 -0
- package/dist/generate-local-invoice-pdf-OCFG47SE.js +3 -0
- package/dist/index.cjs +337 -330
- package/dist/index.d.cts +21 -2
- package/dist/index.d.ts +21 -2
- package/dist/index.js +18 -15
- package/dist/invoice-templates-GZ33OENC.js +2 -0
- package/dist/invoice-templates-RB462AQN.cjs +19 -0
- package/dist/migrations/1783300000000-CreateOrderAssigneesTable.ts +43 -0
- package/dist/{order-assignees-handlers-NPKD64P6.cjs → order-assignees-handlers-KF7RMTV5.cjs} +77 -8
- package/dist/{order-assignees-handlers-LKMAGLG6.js → order-assignees-handlers-L3RVKUBS.js} +77 -8
- package/dist/{order-completion-otp-handlers-NK65LOLV.cjs → order-completion-otp-handlers-DDQREULW.cjs} +75 -18
- package/dist/{order-completion-otp-handlers-LFRHXWK4.js → order-completion-otp-handlers-NROWBGXN.js} +73 -16
- package/dist/{order-notification-dispatcher-LL7ETKLU.cjs → order-notification-dispatcher-6HCJ6Q75.cjs} +12 -9
- package/dist/{order-notification-dispatcher-ECPFI7CD.js → order-notification-dispatcher-KM2SY7TX.js} +7 -4
- package/dist/{rbac-debug-db-5R6XFPSV.js → rbac-debug-db-DFZWZ6GV.js} +1 -1
- package/dist/{rbac-debug-db-JKK2MCWF.cjs → rbac-debug-db-KWV7D5PQ.cjs} +2 -2
- package/dist/resolve-invoice-asset-url-JEZRENJW.cjs +11 -0
- package/dist/resolve-invoice-asset-url-QZ2FRDHI.js +2 -0
- package/package.json +1 -1
- package/dist/chunk-GLD263KW.cjs +0 -862
- package/dist/chunk-OPJEV44S.js +0 -847
- package/dist/email-queue-HGXB2FIS.js +0 -5
|
@@ -45,8 +45,39 @@ function createOrderAssigneesHandlers(dataSource, entityMap, getHydratedSessionU
|
|
|
45
45
|
const session = await getHydratedSessionUser?.() ?? null;
|
|
46
46
|
const userVendorIds = session?.vendorIds ?? [];
|
|
47
47
|
const isVendorSession = Boolean(session?.isVendorPortal || !session?.isRBACAdmin && userVendorIds.length > 0);
|
|
48
|
-
Boolean(session?.isRBACAdmin && !session?.isVendorPortal);
|
|
49
|
-
|
|
48
|
+
const isPlatformAdmin = Boolean(session?.isRBACAdmin && !session?.isVendorPortal);
|
|
49
|
+
console.log("[ORDERS-DEBUG][ELIGIBLE_ASSIGNEES] Fetching for order:", orderId, "orderVendorId:", orderVendorId, "session:", {
|
|
50
|
+
id: session?.id,
|
|
51
|
+
email: session?.email,
|
|
52
|
+
isVendorSession,
|
|
53
|
+
isPlatformAdmin,
|
|
54
|
+
userVendorIds
|
|
55
|
+
});
|
|
56
|
+
let hasVendorAccess = false;
|
|
57
|
+
if (!isVendorSession) {
|
|
58
|
+
hasVendorAccess = true;
|
|
59
|
+
} else if (orderVendorId && userVendorIds.includes(orderVendorId)) {
|
|
60
|
+
hasVendorAccess = true;
|
|
61
|
+
} else {
|
|
62
|
+
const aId = Number(order?.assignedUserId);
|
|
63
|
+
if (Number.isFinite(aId) && aId > 0 && entityMap.vendor_users) {
|
|
64
|
+
const vuRepo = dataSource.getRepository(entityMap.vendor_users);
|
|
65
|
+
for (const vId of userVendorIds) {
|
|
66
|
+
const count = await vuRepo.count({
|
|
67
|
+
where: {
|
|
68
|
+
vendorId: vId,
|
|
69
|
+
userId: aId
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
if (count > 0) {
|
|
73
|
+
hasVendorAccess = true;
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (!hasVendorAccess) {
|
|
80
|
+
console.log("[ORDERS-DEBUG][ELIGIBLE_ASSIGNEES] Forbidden: user not in orderVendorId or assignee not in team");
|
|
50
81
|
return json({
|
|
51
82
|
error: "Forbidden: Access denied to vendor order"
|
|
52
83
|
}, {
|
|
@@ -54,8 +85,9 @@ function createOrderAssigneesHandlers(dataSource, entityMap, getHydratedSessionU
|
|
|
54
85
|
});
|
|
55
86
|
}
|
|
56
87
|
const assigneesMap = /* @__PURE__ */ new Map();
|
|
88
|
+
let vendorsList = [];
|
|
57
89
|
if (isVendorSession) {
|
|
58
|
-
const targetVendorId =
|
|
90
|
+
const targetVendorId = session?.activeVendorId ?? (orderVendorId && userVendorIds.includes(orderVendorId) ? orderVendorId : userVendorIds[0]);
|
|
59
91
|
if (entityMap.vendor_users && targetVendorId) {
|
|
60
92
|
const vuRepo = dataSource.getRepository(entityMap.vendor_users);
|
|
61
93
|
const vendorUsers = await vuRepo.find({
|
|
@@ -64,42 +96,72 @@ function createOrderAssigneesHandlers(dataSource, entityMap, getHydratedSessionU
|
|
|
64
96
|
},
|
|
65
97
|
relations: [
|
|
66
98
|
"user",
|
|
67
|
-
"vendorRole"
|
|
99
|
+
"vendorRole",
|
|
100
|
+
"vendor"
|
|
68
101
|
]
|
|
69
102
|
});
|
|
70
103
|
for (const vu of vendorUsers) {
|
|
71
104
|
const u = vu.user;
|
|
72
105
|
const r = vu.vendorRole;
|
|
106
|
+
const v = vu.vendor;
|
|
73
107
|
if (u && u.id && !u.deleted && !u.blocked && u.inviteStatus === "active") {
|
|
74
108
|
const roleName = r?.name || (r?.isOwnerRole ? "Owner" : "Vendor Staff");
|
|
75
109
|
assigneesMap.set(u.id, {
|
|
76
110
|
id: u.id,
|
|
77
111
|
name: u.name || u.email?.split("@")[0] || `User #${u.id}`,
|
|
78
112
|
email: u.email || "",
|
|
79
|
-
role: roleName
|
|
113
|
+
role: roleName,
|
|
114
|
+
vendorId: targetVendorId,
|
|
115
|
+
vendorName: v?.name || `Vendor #${targetVendorId}`
|
|
80
116
|
});
|
|
81
117
|
}
|
|
82
118
|
}
|
|
83
119
|
}
|
|
84
120
|
} else {
|
|
121
|
+
if (entityMap.vendors) {
|
|
122
|
+
const vRepo = dataSource.getRepository(entityMap.vendors);
|
|
123
|
+
const allVendors = await vRepo.find({
|
|
124
|
+
where: {
|
|
125
|
+
deleted: false
|
|
126
|
+
},
|
|
127
|
+
order: {
|
|
128
|
+
name: "ASC"
|
|
129
|
+
},
|
|
130
|
+
select: [
|
|
131
|
+
"id",
|
|
132
|
+
"name",
|
|
133
|
+
"slug"
|
|
134
|
+
]
|
|
135
|
+
});
|
|
136
|
+
vendorsList = allVendors.map((v) => ({
|
|
137
|
+
id: v.id,
|
|
138
|
+
name: v.name || v.slug || `Vendor #${v.id}`,
|
|
139
|
+
slug: v.slug || ""
|
|
140
|
+
}));
|
|
141
|
+
}
|
|
85
142
|
if (entityMap.vendor_users) {
|
|
86
143
|
const vuRepo = dataSource.getRepository(entityMap.vendor_users);
|
|
87
144
|
const vendorUsers = await vuRepo.find({
|
|
88
145
|
relations: [
|
|
89
146
|
"user",
|
|
90
|
-
"vendorRole"
|
|
147
|
+
"vendorRole",
|
|
148
|
+
"vendor"
|
|
91
149
|
]
|
|
92
150
|
});
|
|
93
151
|
for (const vu of vendorUsers) {
|
|
94
152
|
const u = vu.user;
|
|
95
153
|
const r = vu.vendorRole;
|
|
154
|
+
const v = vu.vendor;
|
|
96
155
|
if (u && u.id && !u.deleted && !u.blocked && u.inviteStatus === "active") {
|
|
156
|
+
if (v && v.deleted) continue;
|
|
97
157
|
const roleName = r?.name || (r?.isOwnerRole ? "Owner" : "Vendor Staff");
|
|
98
158
|
assigneesMap.set(u.id, {
|
|
99
159
|
id: u.id,
|
|
100
160
|
name: u.name || u.email?.split("@")[0] || `User #${u.id}`,
|
|
101
161
|
email: u.email || "",
|
|
102
|
-
role: roleName
|
|
162
|
+
role: roleName,
|
|
163
|
+
vendorId: vu.vendorId,
|
|
164
|
+
vendorName: v?.name || `Vendor #${vu.vendorId}`
|
|
103
165
|
});
|
|
104
166
|
}
|
|
105
167
|
}
|
|
@@ -133,13 +195,20 @@ function createOrderAssigneesHandlers(dataSource, entityMap, getHydratedSessionU
|
|
|
133
195
|
id: u.id,
|
|
134
196
|
name: u.name || u.email?.split("@")[0] || `User #${u.id}`,
|
|
135
197
|
email: u.email || "",
|
|
136
|
-
role: roleLabel
|
|
198
|
+
role: roleLabel,
|
|
199
|
+
vendorId: null,
|
|
200
|
+
vendorName: "Platform Staff"
|
|
137
201
|
});
|
|
138
202
|
}
|
|
139
203
|
}
|
|
140
204
|
}
|
|
205
|
+
console.log("[ORDERS-DEBUG][ELIGIBLE_ASSIGNEES] Returning vendors count:", vendorsList.length, "assignees count:", assigneesMap.size, "currentVendorId:", order.vendorId, "currentAssignedUserId:", order.assignedUserId);
|
|
141
206
|
return json({
|
|
207
|
+
isPlatformAdmin,
|
|
208
|
+
isVendorSession,
|
|
209
|
+
vendors: vendorsList,
|
|
142
210
|
assignees: Array.from(assigneesMap.values()),
|
|
211
|
+
currentVendorId: order.vendorId ?? null,
|
|
143
212
|
currentAssignedUserId: order.assignedUserId ?? null
|
|
144
213
|
});
|
|
145
214
|
}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkGN4LKG4V_cjs = require('./chunk-GN4LKG4V.cjs');
|
|
4
4
|
var chunkWFMVD567_cjs = require('./chunk-WFMVD567.cjs');
|
|
5
5
|
var chunkH3IVLIPR_cjs = require('./chunk-H3IVLIPR.cjs');
|
|
6
6
|
require('./chunk-PA6YDMFZ.cjs');
|
|
7
|
-
var
|
|
8
|
-
require('./chunk-
|
|
7
|
+
var chunkUMC7W5G3_cjs = require('./chunk-UMC7W5G3.cjs');
|
|
8
|
+
require('./chunk-SUUD7OUG.cjs');
|
|
9
9
|
require('./chunk-UPLVMVRX.cjs');
|
|
10
|
+
require('./chunk-ZX5U3VCB.cjs');
|
|
11
|
+
require('./chunk-M5GPOPGX.cjs');
|
|
12
|
+
require('./chunk-P6S4XFZO.cjs');
|
|
10
13
|
require('./chunk-TZEMLHSP.cjs');
|
|
11
14
|
var chunkUSNT2KNT_cjs = require('./chunk-USNT2KNT.cjs');
|
|
12
15
|
|
|
@@ -65,7 +68,55 @@ async function getOtpChannelsConfig(dataSource, entityMap) {
|
|
|
65
68
|
};
|
|
66
69
|
}
|
|
67
70
|
chunkUSNT2KNT_cjs.__name(getOtpChannelsConfig, "getOtpChannelsConfig");
|
|
68
|
-
function createOrderCompletionOtpHandlers(dataSource, entityMap, getCms) {
|
|
71
|
+
function createOrderCompletionOtpHandlers(dataSource, entityMap, getCms, getHydratedSessionUser) {
|
|
72
|
+
async function verifyOrderAccess(order) {
|
|
73
|
+
const session = await getHydratedSessionUser?.() ?? null;
|
|
74
|
+
if (!session) return null;
|
|
75
|
+
const isPlatformAdmin = Boolean(session.isRBACAdmin && !session.isVendorPortal);
|
|
76
|
+
if (isPlatformAdmin) return null;
|
|
77
|
+
const userVendorIds = session.vendorIds ?? [];
|
|
78
|
+
const orderVendorId = Number(order.vendorId);
|
|
79
|
+
let hasVendorOrderAccess = Boolean(orderVendorId && userVendorIds.includes(orderVendorId));
|
|
80
|
+
if (!hasVendorOrderAccess) {
|
|
81
|
+
const aId = Number(order.assignedUserId);
|
|
82
|
+
if (Number.isFinite(aId) && aId > 0 && entityMap.vendor_users) {
|
|
83
|
+
const vuRepo = dataSource.getRepository(entityMap.vendor_users);
|
|
84
|
+
for (const vId of userVendorIds) {
|
|
85
|
+
const count = await vuRepo.count({
|
|
86
|
+
where: {
|
|
87
|
+
vendorId: vId,
|
|
88
|
+
userId: aId
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
if (count > 0) {
|
|
92
|
+
hasVendorOrderAccess = true;
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (!hasVendorOrderAccess) {
|
|
99
|
+
return json({
|
|
100
|
+
error: "Forbidden: Access denied to vendor order"
|
|
101
|
+
}, {
|
|
102
|
+
status: 403
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
const isVendorOwner = Boolean(session.isVendorOwner || session.isVendorRoleOwner);
|
|
106
|
+
if (!isVendorOwner) {
|
|
107
|
+
const sessionUserId = Number(session.id);
|
|
108
|
+
const assignedUserId = Number(order.assignedUserId);
|
|
109
|
+
if (!Number.isFinite(assignedUserId) || assignedUserId !== sessionUserId) {
|
|
110
|
+
return json({
|
|
111
|
+
error: "Forbidden: You can only process orders assigned directly to you"
|
|
112
|
+
}, {
|
|
113
|
+
status: 403
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
chunkUSNT2KNT_cjs.__name(verifyOrderAccess, "verifyOrderAccess");
|
|
69
120
|
return {
|
|
70
121
|
/** GET /api/orders/:id/completion-otp/channels */
|
|
71
122
|
async getChannels(req, orderId) {
|
|
@@ -93,6 +144,8 @@ function createOrderCompletionOtpHandlers(dataSource, entityMap, getCms) {
|
|
|
93
144
|
status: 404
|
|
94
145
|
});
|
|
95
146
|
}
|
|
147
|
+
const accessError = await verifyOrderAccess(order);
|
|
148
|
+
if (accessError) return accessError;
|
|
96
149
|
const o = order;
|
|
97
150
|
const cfg = await getOtpChannelsConfig(dataSource, entityMap);
|
|
98
151
|
const customerEmail = o.contact?.email?.trim();
|
|
@@ -147,6 +200,8 @@ function createOrderCompletionOtpHandlers(dataSource, entityMap, getCms) {
|
|
|
147
200
|
status: 404
|
|
148
201
|
});
|
|
149
202
|
}
|
|
203
|
+
const accessError = await verifyOrderAccess(order);
|
|
204
|
+
if (accessError) return accessError;
|
|
150
205
|
const o = order;
|
|
151
206
|
if (o.status === "completed") {
|
|
152
207
|
return json({
|
|
@@ -226,7 +281,7 @@ function createOrderCompletionOtpHandlers(dataSource, entityMap, getCms) {
|
|
|
226
281
|
<p style="color: #6b7280; font-size: 13px;">This code is valid for 10 minutes. If you did not authorize this completion, please contact support immediately.</p>
|
|
227
282
|
</div>
|
|
228
283
|
`;
|
|
229
|
-
await
|
|
284
|
+
await chunkUMC7W5G3_cjs.queueEmail(cms, {
|
|
230
285
|
to: customerEmail,
|
|
231
286
|
subject: `Completion Code ${code} for Order #${o.orderNumber}`,
|
|
232
287
|
html,
|
|
@@ -304,18 +359,6 @@ function createOrderCompletionOtpHandlers(dataSource, entityMap, getCms) {
|
|
|
304
359
|
status: 400
|
|
305
360
|
});
|
|
306
361
|
}
|
|
307
|
-
const verifyResult = await chunkWFMVD567_cjs.verifyAndConsumeOtpChallenge(dataSource, entityMap, {
|
|
308
|
-
purpose: "order_completion",
|
|
309
|
-
identifier: `order:${orderId}`,
|
|
310
|
-
code
|
|
311
|
-
});
|
|
312
|
-
if (!verifyResult.ok) {
|
|
313
|
-
return json({
|
|
314
|
-
error: verifyResult.error
|
|
315
|
-
}, {
|
|
316
|
-
status: verifyResult.status
|
|
317
|
-
});
|
|
318
|
-
}
|
|
319
362
|
const orderRepo = dataSource.getRepository(entityMap.orders);
|
|
320
363
|
const order = await orderRepo.findOne({
|
|
321
364
|
where: {
|
|
@@ -333,13 +376,27 @@ function createOrderCompletionOtpHandlers(dataSource, entityMap, getCms) {
|
|
|
333
376
|
status: 404
|
|
334
377
|
});
|
|
335
378
|
}
|
|
379
|
+
const accessError = await verifyOrderAccess(order);
|
|
380
|
+
if (accessError) return accessError;
|
|
381
|
+
const verifyResult = await chunkWFMVD567_cjs.verifyAndConsumeOtpChallenge(dataSource, entityMap, {
|
|
382
|
+
purpose: "order_completion",
|
|
383
|
+
identifier: `order:${orderId}`,
|
|
384
|
+
code
|
|
385
|
+
});
|
|
386
|
+
if (!verifyResult.ok) {
|
|
387
|
+
return json({
|
|
388
|
+
error: verifyResult.error
|
|
389
|
+
}, {
|
|
390
|
+
status: verifyResult.status
|
|
391
|
+
});
|
|
392
|
+
}
|
|
336
393
|
const now = /* @__PURE__ */ new Date();
|
|
337
394
|
order.status = "completed";
|
|
338
395
|
order.completedAt = now;
|
|
339
396
|
order.updatedAt = now;
|
|
340
397
|
await orderRepo.save(order);
|
|
341
398
|
try {
|
|
342
|
-
await
|
|
399
|
+
await chunkGN4LKG4V_cjs.fireOrderNotificationTrigger("order_completed", orderId, {
|
|
343
400
|
dataSource,
|
|
344
401
|
entityMap
|
|
345
402
|
});
|
package/dist/{order-completion-otp-handlers-LFRHXWK4.js → order-completion-otp-handlers-NROWBGXN.js}
RENAMED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import { fireOrderNotificationTrigger } from './chunk-
|
|
1
|
+
import { fireOrderNotificationTrigger } from './chunk-SKJH7PX4.js';
|
|
2
2
|
import { verifyAndConsumeOtpChallenge, generateNumericOtp, createOtpChallenge, queueSms } from './chunk-OVTOP42W.js';
|
|
3
3
|
import { queueWhatsApp } from './chunk-GWDI752Q.js';
|
|
4
4
|
import './chunk-FLUF2GZH.js';
|
|
5
|
-
import { queueEmail } from './chunk-
|
|
6
|
-
import './chunk-
|
|
5
|
+
import { queueEmail } from './chunk-7JCCPQEF.js';
|
|
6
|
+
import './chunk-ZIT4IP6N.js';
|
|
7
7
|
import './chunk-JC6DLWTE.js';
|
|
8
|
+
import './chunk-Z5OB5QGN.js';
|
|
9
|
+
import './chunk-WKDBMDUX.js';
|
|
10
|
+
import './chunk-IKTBZJHT.js';
|
|
8
11
|
import './chunk-YRCKEGL2.js';
|
|
9
12
|
import { __name } from './chunk-SHUYVCID.js';
|
|
10
13
|
|
|
@@ -63,7 +66,55 @@ async function getOtpChannelsConfig(dataSource, entityMap) {
|
|
|
63
66
|
};
|
|
64
67
|
}
|
|
65
68
|
__name(getOtpChannelsConfig, "getOtpChannelsConfig");
|
|
66
|
-
function createOrderCompletionOtpHandlers(dataSource, entityMap, getCms) {
|
|
69
|
+
function createOrderCompletionOtpHandlers(dataSource, entityMap, getCms, getHydratedSessionUser) {
|
|
70
|
+
async function verifyOrderAccess(order) {
|
|
71
|
+
const session = await getHydratedSessionUser?.() ?? null;
|
|
72
|
+
if (!session) return null;
|
|
73
|
+
const isPlatformAdmin = Boolean(session.isRBACAdmin && !session.isVendorPortal);
|
|
74
|
+
if (isPlatformAdmin) return null;
|
|
75
|
+
const userVendorIds = session.vendorIds ?? [];
|
|
76
|
+
const orderVendorId = Number(order.vendorId);
|
|
77
|
+
let hasVendorOrderAccess = Boolean(orderVendorId && userVendorIds.includes(orderVendorId));
|
|
78
|
+
if (!hasVendorOrderAccess) {
|
|
79
|
+
const aId = Number(order.assignedUserId);
|
|
80
|
+
if (Number.isFinite(aId) && aId > 0 && entityMap.vendor_users) {
|
|
81
|
+
const vuRepo = dataSource.getRepository(entityMap.vendor_users);
|
|
82
|
+
for (const vId of userVendorIds) {
|
|
83
|
+
const count = await vuRepo.count({
|
|
84
|
+
where: {
|
|
85
|
+
vendorId: vId,
|
|
86
|
+
userId: aId
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
if (count > 0) {
|
|
90
|
+
hasVendorOrderAccess = true;
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (!hasVendorOrderAccess) {
|
|
97
|
+
return json({
|
|
98
|
+
error: "Forbidden: Access denied to vendor order"
|
|
99
|
+
}, {
|
|
100
|
+
status: 403
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
const isVendorOwner = Boolean(session.isVendorOwner || session.isVendorRoleOwner);
|
|
104
|
+
if (!isVendorOwner) {
|
|
105
|
+
const sessionUserId = Number(session.id);
|
|
106
|
+
const assignedUserId = Number(order.assignedUserId);
|
|
107
|
+
if (!Number.isFinite(assignedUserId) || assignedUserId !== sessionUserId) {
|
|
108
|
+
return json({
|
|
109
|
+
error: "Forbidden: You can only process orders assigned directly to you"
|
|
110
|
+
}, {
|
|
111
|
+
status: 403
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
__name(verifyOrderAccess, "verifyOrderAccess");
|
|
67
118
|
return {
|
|
68
119
|
/** GET /api/orders/:id/completion-otp/channels */
|
|
69
120
|
async getChannels(req, orderId) {
|
|
@@ -91,6 +142,8 @@ function createOrderCompletionOtpHandlers(dataSource, entityMap, getCms) {
|
|
|
91
142
|
status: 404
|
|
92
143
|
});
|
|
93
144
|
}
|
|
145
|
+
const accessError = await verifyOrderAccess(order);
|
|
146
|
+
if (accessError) return accessError;
|
|
94
147
|
const o = order;
|
|
95
148
|
const cfg = await getOtpChannelsConfig(dataSource, entityMap);
|
|
96
149
|
const customerEmail = o.contact?.email?.trim();
|
|
@@ -145,6 +198,8 @@ function createOrderCompletionOtpHandlers(dataSource, entityMap, getCms) {
|
|
|
145
198
|
status: 404
|
|
146
199
|
});
|
|
147
200
|
}
|
|
201
|
+
const accessError = await verifyOrderAccess(order);
|
|
202
|
+
if (accessError) return accessError;
|
|
148
203
|
const o = order;
|
|
149
204
|
if (o.status === "completed") {
|
|
150
205
|
return json({
|
|
@@ -302,18 +357,6 @@ function createOrderCompletionOtpHandlers(dataSource, entityMap, getCms) {
|
|
|
302
357
|
status: 400
|
|
303
358
|
});
|
|
304
359
|
}
|
|
305
|
-
const verifyResult = await verifyAndConsumeOtpChallenge(dataSource, entityMap, {
|
|
306
|
-
purpose: "order_completion",
|
|
307
|
-
identifier: `order:${orderId}`,
|
|
308
|
-
code
|
|
309
|
-
});
|
|
310
|
-
if (!verifyResult.ok) {
|
|
311
|
-
return json({
|
|
312
|
-
error: verifyResult.error
|
|
313
|
-
}, {
|
|
314
|
-
status: verifyResult.status
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
360
|
const orderRepo = dataSource.getRepository(entityMap.orders);
|
|
318
361
|
const order = await orderRepo.findOne({
|
|
319
362
|
where: {
|
|
@@ -331,6 +374,20 @@ function createOrderCompletionOtpHandlers(dataSource, entityMap, getCms) {
|
|
|
331
374
|
status: 404
|
|
332
375
|
});
|
|
333
376
|
}
|
|
377
|
+
const accessError = await verifyOrderAccess(order);
|
|
378
|
+
if (accessError) return accessError;
|
|
379
|
+
const verifyResult = await verifyAndConsumeOtpChallenge(dataSource, entityMap, {
|
|
380
|
+
purpose: "order_completion",
|
|
381
|
+
identifier: `order:${orderId}`,
|
|
382
|
+
code
|
|
383
|
+
});
|
|
384
|
+
if (!verifyResult.ok) {
|
|
385
|
+
return json({
|
|
386
|
+
error: verifyResult.error
|
|
387
|
+
}, {
|
|
388
|
+
status: verifyResult.status
|
|
389
|
+
});
|
|
390
|
+
}
|
|
334
391
|
const now = /* @__PURE__ */ new Date();
|
|
335
392
|
order.status = "completed";
|
|
336
393
|
order.completedAt = now;
|
|
@@ -1,35 +1,38 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkSMHQV3WL_cjs = require('./chunk-SMHQV3WL.cjs');
|
|
4
4
|
require('./chunk-H3IVLIPR.cjs');
|
|
5
5
|
require('./chunk-PA6YDMFZ.cjs');
|
|
6
|
+
require('./chunk-OOTLNH63.cjs');
|
|
6
7
|
require('./chunk-VM6OVUUM.cjs');
|
|
7
|
-
require('./chunk-
|
|
8
|
-
require('./chunk-
|
|
8
|
+
require('./chunk-UMC7W5G3.cjs');
|
|
9
|
+
require('./chunk-SUUD7OUG.cjs');
|
|
9
10
|
require('./chunk-UPLVMVRX.cjs');
|
|
11
|
+
require('./chunk-ZX5U3VCB.cjs');
|
|
12
|
+
require('./chunk-M5GPOPGX.cjs');
|
|
13
|
+
require('./chunk-P6S4XFZO.cjs');
|
|
10
14
|
require('./chunk-TZEMLHSP.cjs');
|
|
11
|
-
require('./chunk-OOTLNH63.cjs');
|
|
12
15
|
require('./chunk-USNT2KNT.cjs');
|
|
13
16
|
|
|
14
17
|
|
|
15
18
|
|
|
16
19
|
Object.defineProperty(exports, "dispatchOrderNotificationDirectly", {
|
|
17
20
|
enumerable: true,
|
|
18
|
-
get: function () { return
|
|
21
|
+
get: function () { return chunkSMHQV3WL_cjs.dispatchOrderNotificationDirectly; }
|
|
19
22
|
});
|
|
20
23
|
Object.defineProperty(exports, "emitOrderNotificationTrigger", {
|
|
21
24
|
enumerable: true,
|
|
22
|
-
get: function () { return
|
|
25
|
+
get: function () { return chunkSMHQV3WL_cjs.emitOrderNotificationTrigger; }
|
|
23
26
|
});
|
|
24
27
|
Object.defineProperty(exports, "getSettingsGroup", {
|
|
25
28
|
enumerable: true,
|
|
26
|
-
get: function () { return
|
|
29
|
+
get: function () { return chunkSMHQV3WL_cjs.getSettingsGroup; }
|
|
27
30
|
});
|
|
28
31
|
Object.defineProperty(exports, "initWhatsappTriggerDispatcher", {
|
|
29
32
|
enumerable: true,
|
|
30
|
-
get: function () { return
|
|
33
|
+
get: function () { return chunkSMHQV3WL_cjs.initWhatsappTriggerDispatcher; }
|
|
31
34
|
});
|
|
32
35
|
Object.defineProperty(exports, "resendOrderNotification", {
|
|
33
36
|
enumerable: true,
|
|
34
|
-
get: function () { return
|
|
37
|
+
get: function () { return chunkSMHQV3WL_cjs.resendOrderNotification; }
|
|
35
38
|
});
|
package/dist/{order-notification-dispatcher-ECPFI7CD.js → order-notification-dispatcher-KM2SY7TX.js}
RENAMED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
export { dispatchOrderNotificationDirectly, emitOrderNotificationTrigger, getSettingsGroup, initWhatsappTriggerDispatcher, resendOrderNotification } from './chunk-
|
|
1
|
+
export { dispatchOrderNotificationDirectly, emitOrderNotificationTrigger, getSettingsGroup, initWhatsappTriggerDispatcher, resendOrderNotification } from './chunk-N4LBZXBG.js';
|
|
2
2
|
import './chunk-GWDI752Q.js';
|
|
3
3
|
import './chunk-FLUF2GZH.js';
|
|
4
|
+
import './chunk-CRFV5WJK.js';
|
|
4
5
|
import './chunk-6YOQ7G5O.js';
|
|
5
|
-
import './chunk-
|
|
6
|
-
import './chunk-
|
|
6
|
+
import './chunk-7JCCPQEF.js';
|
|
7
|
+
import './chunk-ZIT4IP6N.js';
|
|
7
8
|
import './chunk-JC6DLWTE.js';
|
|
9
|
+
import './chunk-Z5OB5QGN.js';
|
|
10
|
+
import './chunk-WKDBMDUX.js';
|
|
11
|
+
import './chunk-IKTBZJHT.js';
|
|
8
12
|
import './chunk-YRCKEGL2.js';
|
|
9
|
-
import './chunk-CRFV5WJK.js';
|
|
10
13
|
import './chunk-SHUYVCID.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkO4AFPDQ4_cjs = require('./chunk-O4AFPDQ4.cjs');
|
|
4
4
|
var chunkUSNT2KNT_cjs = require('./chunk-USNT2KNT.cjs');
|
|
5
5
|
|
|
6
6
|
// src/auth/rbac-debug-db.ts
|
|
@@ -27,7 +27,7 @@ async function loadDbPermissionsForUser(dataSource, userId) {
|
|
|
27
27
|
return {
|
|
28
28
|
groupId,
|
|
29
29
|
groupName,
|
|
30
|
-
dbEntityPerms:
|
|
30
|
+
dbEntityPerms: chunkO4AFPDQ4_cjs.summarizeEntityPerms(chunkO4AFPDQ4_cjs.permissionRowsToRecord(permRows))
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
33
|
chunkUSNT2KNT_cjs.__name(loadDbPermissionsForUser, "loadDbPermissionsForUser");
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkP6S4XFZO_cjs = require('./chunk-P6S4XFZO.cjs');
|
|
4
|
+
require('./chunk-USNT2KNT.cjs');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Object.defineProperty(exports, "resolveInvoiceAssetUrl", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function () { return chunkP6S4XFZO_cjs.resolveInvoiceAssetUrl; }
|
|
11
|
+
});
|