@objectstack/core 16.0.0-rc.1 → 16.1.0

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/index.cjs CHANGED
@@ -98,6 +98,7 @@ __export(index_exports, {
98
98
  resolveAuthzContext: () => resolveAuthzContext,
99
99
  resolveLocale: () => resolveLocale,
100
100
  resolveLocalizationContext: () => resolveLocalizationContext,
101
+ resolveUserAuthzGrants: () => resolveUserAuthzGrants,
101
102
  safeExit: () => safeExit,
102
103
  shouldDenyAnonymous: () => shouldDenyAnonymous,
103
104
  signPayload: () => signPayload,
@@ -4436,6 +4437,31 @@ async function resolveAuthzContext(input) {
4436
4437
  ctx.userId = userId;
4437
4438
  if (tenantId) ctx.tenantId = tenantId;
4438
4439
  if (!ql || typeof ql.find !== "function") return ctx;
4440
+ const grants = await resolveUserAuthzGrants(ql, userId, {
4441
+ tenantId,
4442
+ nowMs: input.nowMs,
4443
+ seedPermissions: ctx.permissions,
4444
+ seedEmail: ctx.email
4445
+ });
4446
+ ctx.positions = grants.positions;
4447
+ ctx.permissions = grants.permissions;
4448
+ ctx.systemPermissions = grants.systemPermissions;
4449
+ ctx.org_user_ids = grants.org_user_ids;
4450
+ if (grants.tabPermissions) ctx.tabPermissions = grants.tabPermissions;
4451
+ if (grants.posture) ctx.posture = grants.posture;
4452
+ if (grants.email && !ctx.email) ctx.email = grants.email;
4453
+ return ctx;
4454
+ }
4455
+ async function resolveUserAuthzGrants(ql, userId, opts = {}) {
4456
+ const { tenantId } = opts;
4457
+ const grants = {
4458
+ positions: [],
4459
+ permissions: Array.isArray(opts.seedPermissions) ? [...opts.seedPermissions] : [],
4460
+ systemPermissions: [],
4461
+ org_user_ids: [userId]
4462
+ };
4463
+ if (opts.seedEmail) grants.email = opts.seedEmail;
4464
+ if (!ql || typeof ql.find !== "function") return grants;
4439
4465
  let userRowLoaded = false;
4440
4466
  let userRow;
4441
4467
  const getUserRow = async () => {
@@ -4446,9 +4472,9 @@ async function resolveAuthzContext(input) {
4446
4472
  }
4447
4473
  return userRow;
4448
4474
  };
4449
- if (!ctx.email) {
4475
+ if (!grants.email) {
4450
4476
  const u = await getUserRow();
4451
- if (u?.email) ctx.email = String(u.email);
4477
+ if (u?.email) grants.email = String(u.email);
4452
4478
  }
4453
4479
  const memberWhere = tenantId ? { user_id: userId, organization_id: tenantId } : { user_id: userId };
4454
4480
  const members = await tryFind(ql, "sys_member", memberWhere, 50);
@@ -4456,18 +4482,18 @@ async function resolveAuthzContext(input) {
4456
4482
  if (m.role && typeof m.role === "string") {
4457
4483
  for (const raw of m.role.split(",").map((s) => s.trim()).filter(Boolean)) {
4458
4484
  const r = (0, import_spec.mapMembershipRole)(raw);
4459
- if (!ctx.positions.includes(r)) ctx.positions.push(r);
4485
+ if (!grants.positions.includes(r)) grants.positions.push(r);
4460
4486
  }
4461
4487
  }
4462
4488
  }
4463
- const nowMs = input.nowMs ?? Date.now();
4489
+ const nowMs = opts.nowMs ?? Date.now();
4464
4490
  const userPositionRows = await tryFind(ql, "sys_user_position", { user_id: userId }, 200);
4465
4491
  for (const ur of userPositionRows) {
4466
4492
  const org = ur.organization_id ?? null;
4467
4493
  if (org && tenantId && org !== tenantId) continue;
4468
4494
  if (!isGrantActive(ur, nowMs)) continue;
4469
4495
  const r = ur.position;
4470
- if (typeof r === "string" && r && !ctx.positions.includes(r)) ctx.positions.push(r);
4496
+ if (typeof r === "string" && r && !grants.positions.includes(r)) grants.positions.push(r);
4471
4497
  }
4472
4498
  if (tenantId) {
4473
4499
  const orgMembers = await tryFind(ql, "sys_member", { organization_id: tenantId }, 1e3);
@@ -4475,9 +4501,7 @@ async function resolveAuthzContext(input) {
4475
4501
  orgMembers.map((m) => m.user_id ?? m.userId).filter((v) => typeof v === "string" && v.length > 0)
4476
4502
  );
4477
4503
  ids.add(userId);
4478
- ctx.org_user_ids = Array.from(ids);
4479
- } else {
4480
- ctx.org_user_ids = [userId];
4504
+ grants.org_user_ids = Array.from(ids);
4481
4505
  }
4482
4506
  const upsRowsAll = await tryFind(ql, "sys_user_permission_set", { user_id: userId }, 100);
4483
4507
  const upsRows = upsRowsAll.filter((r) => isGrantActive(r, nowMs));
@@ -4491,9 +4515,9 @@ async function resolveAuthzContext(input) {
4491
4515
  upsRows.filter((r) => (r.organization_id ?? r.organizationId ?? null) === null).map((r) => r.permission_set_id ?? r.permissionSetId).filter(Boolean)
4492
4516
  );
4493
4517
  let hasPlatformAdminGrant = false;
4494
- if (!ctx.positions.includes("everyone")) ctx.positions.push("everyone");
4495
- if (ctx.positions.length > 0) {
4496
- const positionRows = await tryFind(ql, "sys_position", { name: { $in: ctx.positions } }, 100);
4518
+ if (!grants.positions.includes("everyone")) grants.positions.push("everyone");
4519
+ if (grants.positions.length > 0) {
4520
+ const positionRows = await tryFind(ql, "sys_position", { name: { $in: grants.positions } }, 100);
4497
4521
  const positionIds = positionRows.map((r) => r.id).filter(Boolean);
4498
4522
  if (positionIds.length > 0) {
4499
4523
  const rpsRows = await tryFind(ql, "sys_position_permission_set", { position_id: { $in: positionIds } }, 500);
@@ -4508,12 +4532,12 @@ async function resolveAuthzContext(input) {
4508
4532
  const tabRank = { hidden: 0, default_off: 1, default_on: 2, visible: 3 };
4509
4533
  const mergedTabs = {};
4510
4534
  for (const ps of psRows) {
4511
- if (ps.name && !ctx.permissions.includes(ps.name)) ctx.permissions.push(ps.name);
4535
+ if (ps.name && !grants.permissions.includes(ps.name)) grants.permissions.push(ps.name);
4512
4536
  if (ps.name === import_spec.ADMIN_FULL_ACCESS && unscopedUserPsIds.has(ps.id)) hasPlatformAdminGrant = true;
4513
4537
  const sysPerms = typeof ps.system_permissions === "string" ? safeJsonParse2(ps.system_permissions, []) : ps.system_permissions ?? ps.systemPermissions;
4514
4538
  if (Array.isArray(sysPerms)) {
4515
4539
  for (const p of sysPerms) {
4516
- if (typeof p === "string" && !ctx.systemPermissions.includes(p)) ctx.systemPermissions.push(p);
4540
+ if (typeof p === "string" && !grants.systemPermissions.includes(p)) grants.systemPermissions.push(p);
4517
4541
  }
4518
4542
  }
4519
4543
  const tabs = typeof ps.tab_permissions === "string" ? safeJsonParse2(ps.tab_permissions, {}) : ps.tab_permissions ?? ps.tabPermissions;
@@ -4527,20 +4551,20 @@ async function resolveAuthzContext(input) {
4527
4551
  }
4528
4552
  }
4529
4553
  }
4530
- if (Object.keys(mergedTabs).length > 0) ctx.tabPermissions = mergedTabs;
4554
+ if (Object.keys(mergedTabs).length > 0) grants.tabPermissions = mergedTabs;
4531
4555
  }
4532
- if (hasPlatformAdminGrant && !ctx.positions.includes(import_spec.BUILTIN_IDENTITY_PLATFORM_ADMIN)) {
4533
- ctx.positions.unshift(import_spec.BUILTIN_IDENTITY_PLATFORM_ADMIN);
4556
+ if (hasPlatformAdminGrant && !grants.positions.includes(import_spec.BUILTIN_IDENTITY_PLATFORM_ADMIN)) {
4557
+ grants.positions.unshift(import_spec.BUILTIN_IDENTITY_PLATFORM_ADMIN);
4534
4558
  }
4535
- ctx.posture = derivePosture({
4559
+ grants.posture = derivePosture({
4536
4560
  isPlatformAdmin: hasPlatformAdminGrant,
4537
- isTenantAdmin: ctx.permissions.includes(import_spec.ORGANIZATION_ADMIN)
4561
+ isTenantAdmin: grants.permissions.includes(import_spec.ORGANIZATION_ADMIN)
4538
4562
  });
4539
- if (!ctx.permissions.includes("ai_seat")) {
4563
+ if (!grants.permissions.includes("ai_seat")) {
4540
4564
  const aiAccess = (await getUserRow())?.ai_access;
4541
- if (aiAccess === true || aiAccess === 1 || aiAccess === "1") ctx.permissions.push("ai_seat");
4565
+ if (aiAccess === true || aiAccess === 1 || aiAccess === "1") grants.permissions.push("ai_seat");
4542
4566
  }
4543
- return ctx;
4567
+ return grants;
4544
4568
  }
4545
4569
  function isValidTimeZone(tz) {
4546
4570
  try {
@@ -5865,6 +5889,7 @@ var NamespaceResolver = class {
5865
5889
  resolveAuthzContext,
5866
5890
  resolveLocale,
5867
5891
  resolveLocalizationContext,
5892
+ resolveUserAuthzGrants,
5868
5893
  safeExit,
5869
5894
  shouldDenyAnonymous,
5870
5895
  signPayload,