@infuro/cms-core 1.0.29 → 1.0.31

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.
Files changed (58) hide show
  1. package/README.md +17 -13
  2. package/dist/admin.cjs +8522 -3281
  3. package/dist/admin.cjs.map +1 -1
  4. package/dist/admin.d.cts +13 -2
  5. package/dist/admin.d.ts +13 -2
  6. package/dist/admin.js +8210 -2957
  7. package/dist/admin.js.map +1 -1
  8. package/dist/api.cjs +5099 -1167
  9. package/dist/api.cjs.map +1 -1
  10. package/dist/api.d.cts +2 -2
  11. package/dist/api.d.ts +2 -2
  12. package/dist/api.js +4847 -909
  13. package/dist/api.js.map +1 -1
  14. package/dist/auth.cjs +461 -62
  15. package/dist/auth.cjs.map +1 -1
  16. package/dist/auth.d.cts +73 -47
  17. package/dist/auth.d.ts +73 -47
  18. package/dist/auth.js +425 -38
  19. package/dist/auth.js.map +1 -1
  20. package/dist/cli.cjs +21 -14
  21. package/dist/cli.cjs.map +1 -1
  22. package/dist/cli.js +21 -14
  23. package/dist/cli.js.map +1 -1
  24. package/dist/{index-D9SdaDJ0.d.ts → index-BcMRGNjS.d.cts} +36 -3
  25. package/dist/{index-BPQSXgXF.d.cts → index-Bda8D1Rm.d.ts} +36 -3
  26. package/dist/index.cjs +4753 -740
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.cts +301 -36
  29. package/dist/index.d.ts +301 -36
  30. package/dist/index.js +4750 -768
  31. package/dist/index.js.map +1 -1
  32. package/dist/migrations/1775400000001-AddDiscountAndOrderAddresses.ts +274 -0
  33. package/dist/migrations/1775800000000-VendorsAndVendorUsers.ts +74 -0
  34. package/dist/migrations/1775900000000-StoreVendorIdColumns.ts +124 -0
  35. package/dist/migrations/1775910000000-VendorOwnerRbacSeed.ts +54 -0
  36. package/dist/migrations/1775920000000-VendorOwnerSettingsPermission.ts +25 -0
  37. package/dist/migrations/1775930000000-VendorGroupStorePermissions.ts +54 -0
  38. package/dist/migrations/1775940000000-VendorRls.ts +71 -0
  39. package/dist/migrations/1775950000000-VendorCustomers.ts +87 -0
  40. package/dist/migrations/1775950000001-VendorCustomersPermissions.ts +67 -0
  41. package/dist/migrations/1778652250860-CreateCurrencyTables.ts +16 -0
  42. package/dist/migrations/1778652250861-OrderAddressTables.ts +88 -0
  43. package/dist/migrations/1778652250862-UpdateDiscountandRules.ts +100 -0
  44. package/dist/migrations/1778652250863-MakeCouponCodeNullable.ts +19 -0
  45. package/dist/migrations/1778652250864-RemoveUniqueConstraintFromDiscountCouponCode.ts +22 -0
  46. package/dist/migrations/1778652250865-FixOrdersAddressForeignKeys.ts +71 -0
  47. package/dist/migrations/1778660000000-DiscountVendorId.ts +90 -0
  48. package/dist/migrations/1778660000001-FixOrdersAddressFkToOrderAddresses.ts +79 -0
  49. package/dist/migrations/1778660000002-VendorUserIdInviteStatus.ts +61 -0
  50. package/dist/theme.d.cts +2 -2
  51. package/dist/theme.d.ts +2 -2
  52. package/dist/{types-D34wmivy.d.cts → types-DCVaXlPV.d.cts} +1 -1
  53. package/dist/{types-D34wmivy.d.ts → types-DCVaXlPV.d.ts} +1 -1
  54. package/dist/vendor-scope-DTYhJk_I.d.cts +129 -0
  55. package/dist/vendor-scope-DTYhJk_I.d.ts +129 -0
  56. package/package.json +9 -2
  57. package/dist/helpers-dlrF_49e.d.cts +0 -60
  58. package/dist/helpers-dlrF_49e.d.ts +0 -60
package/dist/auth.cjs CHANGED
@@ -5,6 +5,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __esm = (fn, res) => function __init() {
9
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
+ };
8
11
  var __export = (target, all) => {
9
12
  for (var name in all)
10
13
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -27,57 +30,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
30
  ));
28
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
32
 
30
- // src/auth/index.ts
31
- var auth_exports = {};
32
- __export(auth_exports, {
33
- ADMIN_GROUP_NAME: () => ADMIN_GROUP_NAME,
34
- OPEN_ENDPOINTS: () => OPEN_ENDPOINTS,
35
- PERMISSION_REQUIRED_ENDPOINTS: () => PERMISSION_REQUIRED_ENDPOINTS,
36
- RBAC_ADMIN_ONLY_ENTITIES: () => RBAC_ADMIN_ONLY_ENTITIES,
37
- canManageRoles: () => canManageRoles,
38
- createAuthHelpers: () => createAuthHelpers,
39
- createCmsMiddleware: () => createCmsMiddleware,
40
- defaultPublicApiMethods: () => defaultPublicApiMethods,
41
- getNextAuthOptions: () => getNextAuthOptions,
42
- getPermissionableEntityKeys: () => getPermissionableEntityKeys,
43
- getRequiredPermission: () => getRequiredPermission,
44
- hasEntityPermission: () => hasEntityPermission,
45
- isOpenEndpoint: () => isOpenEndpoint,
46
- isPublicMethod: () => isPublicMethod,
47
- isSuperAdminGroupName: () => isSuperAdminGroupName,
48
- permissionRowsToRecord: () => permissionRowsToRecord,
49
- seedAdministratorPermissions: () => seedAdministratorPermissions,
50
- sessionHasEntityAccess: () => sessionHasEntityAccess
51
- });
52
- module.exports = __toCommonJS(auth_exports);
53
-
54
33
  // src/auth/permission-entities.ts
55
- var PERMISSION_ENTITY_INTERNAL_EXCLUDE = /* @__PURE__ */ new Set([
56
- "users",
57
- "password_reset_tokens",
58
- "user_groups",
59
- "permissions",
60
- "comments",
61
- "form_fields",
62
- "configs",
63
- "knowledge_base_chunks",
64
- "carts",
65
- "cart_items",
66
- "wishlists",
67
- "wishlist_items",
68
- "message_templates"
69
- ]);
70
- var PERMISSION_LOGICAL_ENTITIES = [
71
- "users",
72
- "forms",
73
- "form_submissions",
74
- "dashboard",
75
- "upload",
76
- "settings",
77
- "analytics",
78
- "chat"
79
- ];
80
- var ADMIN_GROUP_NAME = "Administrator";
81
34
  function isSuperAdminGroupName(name) {
82
35
  return name === ADMIN_GROUP_NAME;
83
36
  }
@@ -107,13 +60,358 @@ function hasEntityPermission(record, entity, action) {
107
60
  if (action === "update") return p.u;
108
61
  return p.d;
109
62
  }
63
+ var PERMISSION_ENTITY_INTERNAL_EXCLUDE, PERMISSION_LOGICAL_ENTITIES, ADMIN_GROUP_NAME;
64
+ var init_permission_entities = __esm({
65
+ "src/auth/permission-entities.ts"() {
66
+ "use strict";
67
+ PERMISSION_ENTITY_INTERNAL_EXCLUDE = /* @__PURE__ */ new Set([
68
+ "users",
69
+ "password_reset_tokens",
70
+ "user_groups",
71
+ "permissions",
72
+ "comments",
73
+ "form_fields",
74
+ "configs",
75
+ "knowledge_base_chunks",
76
+ "carts",
77
+ "cart_items",
78
+ "wishlists",
79
+ "wishlist_items",
80
+ "message_templates",
81
+ "vendor_users"
82
+ ]);
83
+ PERMISSION_LOGICAL_ENTITIES = [
84
+ "users",
85
+ "forms",
86
+ "form_submissions",
87
+ "dashboard",
88
+ "upload",
89
+ "settings",
90
+ "analytics",
91
+ "chat"
92
+ ];
93
+ ADMIN_GROUP_NAME = "Administrator";
94
+ }
95
+ });
96
+
97
+ // src/auth/vendor-scope.ts
98
+ function isVendorGroupName(name) {
99
+ if (!name?.trim()) return false;
100
+ const n = name.trim().toLowerCase();
101
+ return n === VENDOR_OWNER_GROUP_NAME.toLowerCase() || n.includes("vendor");
102
+ }
103
+ function isPlatformAdministrator(user) {
104
+ if (!user?.email) return false;
105
+ return !!(user.isRBACAdmin || isSuperAdminGroupName(user.groupName));
106
+ }
107
+ function isVendorPortalUser(user) {
108
+ if (user?.isVendorPortal === true) return true;
109
+ if (!user?.email || isPlatformAdministrator(user)) return false;
110
+ if ((user.vendorIds?.length ?? 0) > 0) return true;
111
+ return isVendorGroupName(user.groupName);
112
+ }
113
+ function isVendorStaff(user) {
114
+ return isVendorPortalUser(user);
115
+ }
116
+ function isVendorOwner(user) {
117
+ if (user?.isVendorOwner === true) return true;
118
+ if (!user?.email || isPlatformAdministrator(user)) return false;
119
+ if (user.vendorRole === "staff") return false;
120
+ if (user.vendorRole === "owner") return true;
121
+ if (!isVendorPortalUser(user)) return false;
122
+ return user.groupName?.trim().toLowerCase() === VENDOR_OWNER_GROUP_NAME.toLowerCase();
123
+ }
124
+ function canManageVendorTeam(user) {
125
+ return isPlatformAdministrator(user) || isVendorOwner(user);
126
+ }
127
+ function canManageVendorRoles(user) {
128
+ return isPlatformAdministrator(user) || isVendorOwner(user);
129
+ }
130
+ function canOnboardVendors(user) {
131
+ return isPlatformAdministrator(user);
132
+ }
133
+ function resolveVendorScopeFromSessionUser(user) {
134
+ if (!user?.email) return { type: "deny" };
135
+ if (isPlatformAdministrator(user)) return { type: "all" };
136
+ const vendorIds = user.vendorIds ?? [];
137
+ if (vendorIds.length === 0) return { type: "deny" };
138
+ const preferred = user.activeVendorId ?? vendorIds[0];
139
+ const vendorId = vendorIds.includes(preferred) ? preferred : vendorIds[0];
140
+ return { type: "vendor", vendorId, vendorIds };
141
+ }
142
+ function vendorPortalFlagsFromUser(input) {
143
+ const vendorIds = input.vendorIds ?? [];
144
+ const isVendorPortal = !input.isRBACAdmin && (vendorIds.length > 0 || isVendorGroupName(input.groupName));
145
+ const isVendorOwner2 = isVendorPortal && input.vendorRole !== "staff" && (input.vendorRole === "owner" || input.groupName?.trim().toLowerCase() === VENDOR_OWNER_GROUP_NAME.toLowerCase());
146
+ return { isVendorPortal, isVendorOwner: isVendorOwner2 };
147
+ }
148
+ var VENDOR_SCOPED_STORE_ENTITIES, VENDOR_STORE_RBAC_ENTITIES, VENDOR_OWNER_GROUP_NAME;
149
+ var init_vendor_scope = __esm({
150
+ "src/auth/vendor-scope.ts"() {
151
+ "use strict";
152
+ init_permission_entities();
153
+ VENDOR_SCOPED_STORE_ENTITIES = /* @__PURE__ */ new Set([
154
+ "products",
155
+ "collections",
156
+ "brands",
157
+ "product_categories",
158
+ "orders",
159
+ "payments",
160
+ "taxes",
161
+ "attributes",
162
+ "vendor_customers",
163
+ "discounts"
164
+ ]);
165
+ VENDOR_STORE_RBAC_ENTITIES = /* @__PURE__ */ new Set([
166
+ ...VENDOR_SCOPED_STORE_ENTITIES,
167
+ "order_discounts",
168
+ "order_addresses"
169
+ ]);
170
+ VENDOR_OWNER_GROUP_NAME = "Vendor Owner";
171
+ }
172
+ });
173
+
174
+ // src/auth/rbac-debug-db.ts
175
+ var rbac_debug_db_exports = {};
176
+ __export(rbac_debug_db_exports, {
177
+ loadDbPermissionsForUser: () => loadDbPermissionsForUser
178
+ });
179
+ async function loadDbPermissionsForUser(dataSource, userId) {
180
+ const rows = await dataSource.query(
181
+ `
182
+ SELECT u."groupId" AS "groupId", g.name AS "groupName",
183
+ p.entity, p."canCreate", p."canRead", p."canUpdate", p."canDelete"
184
+ FROM users u
185
+ LEFT JOIN user_groups g ON g.id = u."groupId" AND g.deleted = false
186
+ LEFT JOIN permissions p ON p."groupId" = g.id
187
+ WHERE u.id = $1
188
+ `,
189
+ [userId]
190
+ );
191
+ const groupId = rows[0]?.groupId ?? null;
192
+ const groupName = rows[0]?.groupName ?? null;
193
+ const permRows = rows.filter((r) => r.entity).map((r) => ({
194
+ entity: r.entity,
195
+ canCreate: !!r.canCreate,
196
+ canRead: !!r.canRead,
197
+ canUpdate: !!r.canUpdate,
198
+ canDelete: !!r.canDelete
199
+ }));
200
+ return {
201
+ groupId,
202
+ groupName,
203
+ dbEntityPerms: summarizeEntityPerms(permissionRowsToRecord(permRows))
204
+ };
205
+ }
206
+ var init_rbac_debug_db = __esm({
207
+ "src/auth/rbac-debug-db.ts"() {
208
+ "use strict";
209
+ init_permission_entities();
210
+ init_rbac_debug();
211
+ }
212
+ });
213
+
214
+ // src/auth/rbac-debug.ts
215
+ function isRbacDebugEnabled() {
216
+ const v = process.env.CMS_RBAC_DEBUG?.trim().toLowerCase();
217
+ if (v === "1" || v === "true" || v === "yes") return true;
218
+ if (v === "0" || v === "false" || v === "no") return false;
219
+ return process.env.NODE_ENV === "development";
220
+ }
221
+ function logRbac(message, data) {
222
+ if (!isRbacDebugEnabled()) return;
223
+ if (data) console.info(LOG_PREFIX, message, data);
224
+ else console.info(LOG_PREFIX, message);
225
+ }
226
+ function summarizeEntityPerms(entityPerms) {
227
+ const out = {};
228
+ if (!entityPerms) return out;
229
+ for (const [entity, p] of Object.entries(entityPerms)) {
230
+ out[entity] = { c: p.c, r: p.r, u: p.u, d: p.d };
231
+ }
232
+ return out;
233
+ }
234
+ function vendorPortalFallbackReason(user, entity, action) {
235
+ if (!isVendorPortalUser(user)) return null;
236
+ if (entity === "dashboard" && action === "read") return "vendor_portal_dashboard_fallback";
237
+ if (entity === "analytics" && action === "read") return "vendor_portal_analytics_fallback";
238
+ if (entity === "settings" && action === "read") return "vendor_portal_settings_read_fallback";
239
+ if (VENDOR_STORE_RBAC_ENTITIES.has(entity) && action === "read") return "vendor_portal_store_read_fallback";
240
+ return null;
241
+ }
242
+ function explainSessionEntityAccess(user, entity, action) {
243
+ const userSnapshot = {
244
+ email: user?.email ?? null,
245
+ id: user?.id ?? null,
246
+ groupId: user?.groupId ?? null,
247
+ groupName: user?.groupName ?? null,
248
+ isRBACAdmin: user?.isRBACAdmin ?? false,
249
+ adminAccess: user?.adminAccess ?? null,
250
+ vendorIds: user?.vendorIds ?? [],
251
+ activeVendorId: user?.activeVendorId ?? null,
252
+ vendorRole: user?.vendorRole ?? null,
253
+ isVendorPortal: user?.isVendorPortal ?? false,
254
+ isVendorOwner: user?.isVendorOwner ?? false,
255
+ isVendorPortalComputed: isVendorPortalUser(user),
256
+ isVendorOwnerComputed: isVendorOwner(user),
257
+ jwtEntityPerms: summarizeEntityPerms(user?.entityPerms),
258
+ jwtEntityPermForTarget: user?.entityPerms?.[entity] ?? null
259
+ };
260
+ if (!user?.email) {
261
+ return { allowed: false, reason: "no_session_email", userSnapshot };
262
+ }
263
+ if (user.isRBACAdmin) {
264
+ return { allowed: true, reason: "platform_administrator", userSnapshot };
265
+ }
266
+ const vendorIds = user.vendorIds ?? [];
267
+ const isStaff = user.vendorRole === "staff";
268
+ if (vendorIds.length > 0) {
269
+ if (entity === "dashboard" && action === "read") {
270
+ return { allowed: true, reason: "vendor_link_dashboard_read", userSnapshot };
271
+ }
272
+ if (entity === "analytics" && action === "read") {
273
+ return { allowed: true, reason: "vendor_link_analytics_read", userSnapshot };
274
+ }
275
+ if (entity === "settings") {
276
+ if (action === "read") {
277
+ return { allowed: true, reason: "vendor_link_settings_read", userSnapshot };
278
+ }
279
+ if (action === "update" && !isStaff) {
280
+ return { allowed: true, reason: "vendor_link_settings_update", userSnapshot };
281
+ }
282
+ }
283
+ if (VENDOR_STORE_RBAC_ENTITIES.has(entity)) {
284
+ if (isStaff && action === "read") {
285
+ return { allowed: true, reason: "vendor_staff_store_read", userSnapshot };
286
+ }
287
+ if (!isStaff) {
288
+ return { allowed: true, reason: "vendor_link_store_full", userSnapshot };
289
+ }
290
+ return {
291
+ allowed: false,
292
+ reason: "vendor_staff_store_write_denied",
293
+ userSnapshot
294
+ };
295
+ }
296
+ }
297
+ if (isVendorPortalUser(user) && isVendorOwner(user)) {
298
+ if (entity === "dashboard" && action === "read") {
299
+ return { allowed: true, reason: "vendor_owner_group_dashboard", userSnapshot };
300
+ }
301
+ if (entity === "analytics" && action === "read") {
302
+ return { allowed: true, reason: "vendor_owner_group_analytics", userSnapshot };
303
+ }
304
+ if (entity === "settings" && (action === "read" || action === "update")) {
305
+ return { allowed: true, reason: "vendor_owner_group_settings", userSnapshot };
306
+ }
307
+ if (VENDOR_STORE_RBAC_ENTITIES.has(entity)) {
308
+ return { allowed: true, reason: "vendor_owner_group_store", userSnapshot };
309
+ }
310
+ }
311
+ const vendorPortalReason = vendorPortalFallbackReason(user, entity, action);
312
+ if (vendorPortalReason) {
313
+ return { allowed: true, reason: vendorPortalReason, userSnapshot };
314
+ }
315
+ const explicit = user.entityPerms?.[entity];
316
+ if (explicit !== void 0) {
317
+ const allowed2 = hasEntityPermission(user.entityPerms, entity, action);
318
+ return {
319
+ allowed: allowed2,
320
+ reason: allowed2 ? "jwt_entity_perms_allow" : "jwt_entity_perms_deny",
321
+ userSnapshot
322
+ };
323
+ }
324
+ const allowed = hasEntityPermission(user.entityPerms, entity, action);
325
+ return {
326
+ allowed,
327
+ reason: allowed ? "entity_perms_fallback_allow" : "no_matching_rule",
328
+ userSnapshot
329
+ };
330
+ }
331
+ async function logEntityAccessDecision(dataSource, context, user, entity, action, extra) {
332
+ if (!isRbacDebugEnabled()) return;
333
+ const explanation = explainSessionEntityAccess(user, entity, action);
334
+ let dbPermissions;
335
+ if (dataSource && user?.id) {
336
+ const id = Number(user.id);
337
+ if (Number.isFinite(id)) {
338
+ try {
339
+ const { loadDbPermissionsForUser: loadDbPermissionsForUser2 } = await Promise.resolve().then(() => (init_rbac_debug_db(), rbac_debug_db_exports));
340
+ dbPermissions = await loadDbPermissionsForUser2(dataSource, id);
341
+ } catch (e) {
342
+ dbPermissions = { error: e instanceof Error ? e.message : String(e) };
343
+ }
344
+ }
345
+ }
346
+ logRbac(context, {
347
+ entity,
348
+ action,
349
+ allowed: explanation.allowed,
350
+ reason: explanation.reason,
351
+ ...explanation.userSnapshot,
352
+ dbPermissions,
353
+ ...extra
354
+ });
355
+ }
356
+ var LOG_PREFIX;
357
+ var init_rbac_debug = __esm({
358
+ "src/auth/rbac-debug.ts"() {
359
+ "use strict";
360
+ init_permission_entities();
361
+ init_vendor_scope();
362
+ LOG_PREFIX = "[cms-rbac]";
363
+ }
364
+ });
365
+
366
+ // src/auth/index.ts
367
+ var auth_exports = {};
368
+ __export(auth_exports, {
369
+ ADMIN_GROUP_NAME: () => ADMIN_GROUP_NAME,
370
+ OPEN_ENDPOINTS: () => OPEN_ENDPOINTS,
371
+ PERMISSION_REQUIRED_ENDPOINTS: () => PERMISSION_REQUIRED_ENDPOINTS,
372
+ RBAC_ADMIN_ONLY_ENTITIES: () => RBAC_ADMIN_ONLY_ENTITIES,
373
+ VENDOR_OWNER_GROUP_NAME: () => VENDOR_OWNER_GROUP_NAME,
374
+ VENDOR_SCOPED_STORE_ENTITIES: () => VENDOR_SCOPED_STORE_ENTITIES,
375
+ VENDOR_STORE_RBAC_ENTITIES: () => VENDOR_STORE_RBAC_ENTITIES,
376
+ canManageRoles: () => canManageRoles,
377
+ canManageVendorRoles: () => canManageVendorRoles,
378
+ canManageVendorTeam: () => canManageVendorTeam,
379
+ canOnboardVendors: () => canOnboardVendors,
380
+ createAuthHelpers: () => createAuthHelpers,
381
+ createCmsAuthBundle: () => createCmsAuthBundle,
382
+ createCmsMiddleware: () => createCmsMiddleware,
383
+ defaultPublicApiMethods: () => defaultPublicApiMethods,
384
+ explainSessionEntityAccess: () => explainSessionEntityAccess,
385
+ getNextAuthOptions: () => getNextAuthOptions,
386
+ getPermissionableEntityKeys: () => getPermissionableEntityKeys,
387
+ getRequiredPermission: () => getRequiredPermission,
388
+ hasEntityPermission: () => hasEntityPermission,
389
+ isOpenEndpoint: () => isOpenEndpoint,
390
+ isPlatformAdministrator: () => isPlatformAdministrator,
391
+ isPublicMethod: () => isPublicMethod,
392
+ isRbacDebugEnabled: () => isRbacDebugEnabled,
393
+ isSuperAdminGroupName: () => isSuperAdminGroupName,
394
+ isVendorGroupName: () => isVendorGroupName,
395
+ isVendorOwner: () => isVendorOwner,
396
+ isVendorPortalUser: () => isVendorPortalUser,
397
+ isVendorStaff: () => isVendorStaff,
398
+ logEntityAccessDecision: () => logEntityAccessDecision,
399
+ logRbac: () => logRbac,
400
+ permissionRowsToRecord: () => permissionRowsToRecord,
401
+ resolveVendorScopeFromSessionUser: () => resolveVendorScopeFromSessionUser,
402
+ seedAdministratorPermissions: () => seedAdministratorPermissions,
403
+ sessionHasEntityAccess: () => sessionHasEntityAccess,
404
+ summarizeEntityPerms: () => summarizeEntityPerms,
405
+ vendorPortalFlagsFromUser: () => vendorPortalFlagsFromUser
406
+ });
407
+ module.exports = __toCommonJS(auth_exports);
110
408
 
111
409
  // src/auth/helpers.ts
410
+ init_rbac_debug();
411
+ init_vendor_scope();
112
412
  var RBAC_ADMIN_ONLY_ENTITIES = /* @__PURE__ */ new Set(["users", "user_groups", "permissions"]);
113
413
  function sessionHasEntityAccess(user, entity, action) {
114
- if (!user?.email) return false;
115
- if (user.isRBACAdmin && RBAC_ADMIN_ONLY_ENTITIES.has(entity)) return true;
116
- return hasEntityPermission(user.entityPerms, entity, action);
414
+ return explainSessionEntityAccess(user, entity, action).allowed;
117
415
  }
118
416
  function canManageRoles(user) {
119
417
  return !!(user?.email && user.isRBACAdmin);
@@ -138,6 +436,19 @@ function isPublicMethod(pathname, method) {
138
436
  return false;
139
437
  }
140
438
  function createAuthHelpers(getSession, NextResponse) {
439
+ return createAuthHelpersFromGetSession(getSession, NextResponse);
440
+ }
441
+ function createCmsAuthBundle(getSession, NextResponse) {
442
+ const auth = createAuthHelpers(getSession, NextResponse);
443
+ return {
444
+ requireAuth: auth.requireAuth,
445
+ requireAdminAccess: auth.requireAdminAccess,
446
+ requireEntityPermission: auth.requireEntityPermission,
447
+ getSessionUser: auth.getAuthenticatedUser,
448
+ getAuthenticatedUser: auth.getAuthenticatedUser
449
+ };
450
+ }
451
+ function createAuthHelpersFromGetSession(getSession, NextResponse) {
141
452
  return {
142
453
  async requireAuth() {
143
454
  const session = await getSession();
@@ -159,8 +470,21 @@ function createAuthHelpers(getSession, NextResponse) {
159
470
  return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
160
471
  }
161
472
  const u = session.user;
162
- if (sessionHasEntityAccess(u, entity, action)) return null;
163
- return NextResponse.json({ error: "Forbidden", entity, action }, { status: 403 });
473
+ const allowed = sessionHasEntityAccess(u, entity, action);
474
+ const { reason } = explainSessionEntityAccess(u, entity, action);
475
+ logRbac("authHelpers.requireEntityPermission", {
476
+ entity,
477
+ action,
478
+ allowed,
479
+ reason,
480
+ email: u.email,
481
+ groupName: u.groupName,
482
+ vendorIds: u.vendorIds,
483
+ isVendorPortal: u.isVendorPortal,
484
+ isVendorOwner: u.isVendorOwner
485
+ });
486
+ if (allowed) return null;
487
+ return NextResponse.json({ error: "Forbidden", entity, action, reason }, { status: 403 });
164
488
  },
165
489
  async requireAdminAccess() {
166
490
  const session = await getSession();
@@ -169,8 +493,23 @@ function createAuthHelpers(getSession, NextResponse) {
169
493
  }
170
494
  const u = session.user;
171
495
  if (u.isRBACAdmin) return null;
172
- if (u.adminAccess === false) return NextResponse.json({ error: "Forbidden", reason: "admin_access" }, { status: 403 });
173
- return null;
496
+ if (isVendorPortalUser(u)) return null;
497
+ if (u.adminAccess === true) return null;
498
+ if (u.adminAccess === false) {
499
+ logRbac("requireAdminAccess denied (adminAccess:false)", {
500
+ email: u.email,
501
+ groupName: u.groupName,
502
+ isVendorPortal: u.isVendorPortal
503
+ });
504
+ return NextResponse.json({ error: "Forbidden", reason: "admin_access" }, { status: 403 });
505
+ }
506
+ logRbac("requireAdminAccess denied (no matching rule)", {
507
+ email: u.email,
508
+ adminAccess: u.adminAccess,
509
+ groupName: u.groupName,
510
+ isVendorPortal: u.isVendorPortal
511
+ });
512
+ return NextResponse.json({ error: "Forbidden", reason: "admin_access" }, { status: 403 });
174
513
  },
175
514
  async getAuthenticatedUser() {
176
515
  const session = await getSession();
@@ -179,18 +518,26 @@ function createAuthHelpers(getSession, NextResponse) {
179
518
  };
180
519
  }
181
520
 
521
+ // src/auth/index.ts
522
+ init_rbac_debug();
523
+ init_vendor_scope();
524
+ init_permission_entities();
525
+
182
526
  // src/auth/seed-permissions.ts
527
+ init_permission_entities();
183
528
  async function seedAdministratorPermissions(dataSource, entityMap) {
184
529
  const entities = getPermissionableEntityKeys(entityMap);
185
530
  const groupRepo = dataSource.getRepository(entityMap.user_groups);
186
531
  const permRepo = dataSource.getRepository(entityMap.permissions);
187
532
  const adminGroup = await groupRepo.findOne({ where: { name: ADMIN_GROUP_NAME, deleted: false } });
533
+ console.log("ADMIN GROUP", adminGroup);
188
534
  if (!adminGroup) return;
189
535
  const fullCrud = { canCreate: true, canRead: true, canUpdate: true, canDelete: true };
190
536
  for (const entity of entities) {
191
537
  const existing = await permRepo.findOne({
192
538
  where: { groupId: adminGroup.id, entity }
193
539
  });
540
+ console.log("EXISTING", existing);
194
541
  if (existing) {
195
542
  existing.canCreate = true;
196
543
  existing.canRead = true;
@@ -264,20 +611,38 @@ function createCmsMiddleware(config = {}) {
264
611
 
265
612
  // src/auth/nextauth-options.ts
266
613
  var import_credentials = __toESM(require("next-auth/providers/credentials"), 1);
614
+ init_permission_entities();
615
+ init_vendor_scope();
267
616
  var CredentialsProvider = import_credentials.default.default ?? import_credentials.default;
268
617
  function sessionUserFromNextAuthUser(user) {
269
618
  const g = user.group;
270
619
  const isRBACAdmin = isSuperAdminGroupName(g?.name);
271
620
  const entityPerms = permissionRowsToRecord(g?.permissions);
272
- const adminAccess = user.adminAccess === true;
621
+ const rawAdminAccess = user.adminAccess;
622
+ const adminAccess = rawAdminAccess === true ? true : rawAdminAccess === false ? false : void 0;
623
+ const vendorIds = user.vendorIds ?? [];
624
+ const vendorRole = user.vendorRole ?? null;
625
+ const { isVendorPortal, isVendorOwner: isVendorOwner2 } = vendorPortalFlagsFromUser({
626
+ email: user.email,
627
+ isRBACAdmin,
628
+ groupName: g?.name,
629
+ vendorIds,
630
+ vendorRole
631
+ });
273
632
  return {
274
633
  id: user.id.toString(),
275
634
  email: user.email,
276
635
  name: user.name,
277
636
  groupId: user.groupId ?? void 0,
637
+ groupName: g?.name ?? void 0,
278
638
  isRBACAdmin,
279
639
  entityPerms,
280
- adminAccess
640
+ adminAccess,
641
+ vendorIds,
642
+ activeVendorId: user.activeVendorId ?? vendorIds[0] ?? null,
643
+ vendorRole,
644
+ isVendorPortal,
645
+ isVendorOwner: isVendorOwner2
281
646
  };
282
647
  }
283
648
  function getNextAuthOptions(config) {
@@ -308,7 +673,8 @@ function getNextAuthOptions(config) {
308
673
  const valid = await comparePassword(credentials.password, user.password);
309
674
  if (!valid) return null;
310
675
  return sessionUserFromNextAuthUser(user);
311
- } catch {
676
+ } catch (err) {
677
+ console.error("[cms-auth] authorize error (credentials):", err instanceof Error ? err.message : err);
312
678
  return null;
313
679
  }
314
680
  }
@@ -334,7 +700,8 @@ function getNextAuthOptions(config) {
334
700
  const user = await authorizeOtp({ identifier, channel: ch, code });
335
701
  if (!user || user.blocked || user.deleted) return null;
336
702
  return sessionUserFromNextAuthUser(user);
337
- } catch {
703
+ } catch (err) {
704
+ console.error("[cms-auth] authorize error (otp):", err instanceof Error ? err.message : err);
338
705
  return null;
339
706
  }
340
707
  }
@@ -363,15 +730,22 @@ function getNextAuthOptions(config) {
363
730
  const u = user;
364
731
  token.id = u.id;
365
732
  token.groupId = u.groupId;
733
+ token.groupName = u.groupName;
366
734
  token.isRBACAdmin = u.isRBACAdmin;
367
735
  token.entityPerms = u.entityPerms;
368
736
  token.adminAccess = u.adminAccess;
737
+ token.vendorIds = u.vendorIds;
738
+ token.activeVendorId = u.activeVendorId;
739
+ token.vendorRole = u.vendorRole;
740
+ token.isVendorPortal = u.isVendorPortal;
741
+ token.isVendorOwner = u.isVendorOwner;
369
742
  }
370
743
  if (trigger === "update" && session && typeof session === "object") {
371
744
  const s = session;
372
745
  const t = token;
373
746
  if (typeof s.name === "string") t.name = s.name;
374
747
  if (typeof s.email === "string") t.email = s.email;
748
+ if (typeof s.activeVendorId === "number") t.activeVendorId = s.activeVendorId;
375
749
  }
376
750
  return token;
377
751
  },
@@ -382,9 +756,15 @@ function getNextAuthOptions(config) {
382
756
  if (typeof t.email === "string") session.user.email = t.email;
383
757
  session.user.id = t.id;
384
758
  session.user.groupId = t.groupId;
759
+ session.user.groupName = t.groupName;
385
760
  session.user.isRBACAdmin = t.isRBACAdmin;
386
761
  session.user.entityPerms = t.entityPerms;
387
762
  session.user.adminAccess = t.adminAccess;
763
+ session.user.vendorIds = t.vendorIds;
764
+ session.user.activeVendorId = t.activeVendorId;
765
+ session.user.vendorRole = t.vendorRole;
766
+ session.user.isVendorPortal = t.isVendorPortal;
767
+ session.user.isVendorOwner = t.isVendorOwner;
388
768
  }
389
769
  return session;
390
770
  }
@@ -398,19 +778,38 @@ function getNextAuthOptions(config) {
398
778
  OPEN_ENDPOINTS,
399
779
  PERMISSION_REQUIRED_ENDPOINTS,
400
780
  RBAC_ADMIN_ONLY_ENTITIES,
781
+ VENDOR_OWNER_GROUP_NAME,
782
+ VENDOR_SCOPED_STORE_ENTITIES,
783
+ VENDOR_STORE_RBAC_ENTITIES,
401
784
  canManageRoles,
785
+ canManageVendorRoles,
786
+ canManageVendorTeam,
787
+ canOnboardVendors,
402
788
  createAuthHelpers,
789
+ createCmsAuthBundle,
403
790
  createCmsMiddleware,
404
791
  defaultPublicApiMethods,
792
+ explainSessionEntityAccess,
405
793
  getNextAuthOptions,
406
794
  getPermissionableEntityKeys,
407
795
  getRequiredPermission,
408
796
  hasEntityPermission,
409
797
  isOpenEndpoint,
798
+ isPlatformAdministrator,
410
799
  isPublicMethod,
800
+ isRbacDebugEnabled,
411
801
  isSuperAdminGroupName,
802
+ isVendorGroupName,
803
+ isVendorOwner,
804
+ isVendorPortalUser,
805
+ isVendorStaff,
806
+ logEntityAccessDecision,
807
+ logRbac,
412
808
  permissionRowsToRecord,
809
+ resolveVendorScopeFromSessionUser,
413
810
  seedAdministratorPermissions,
414
- sessionHasEntityAccess
811
+ sessionHasEntityAccess,
812
+ summarizeEntityPerms,
813
+ vendorPortalFlagsFromUser
415
814
  });
416
815
  //# sourceMappingURL=auth.cjs.map