@7365admin1/core 3.64.3-staging.290 → 3.64.3-staging.291

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.
@@ -0,0 +1,16 @@
1
+ ---
2
+ "@7365admin1/core": patch
3
+ ---
4
+
5
+ A person's role now follows the site they are on.
6
+
7
+ `GET /api/members/user/:id/app/:type` accepts an optional `?site=` (a 24-hex
8
+ site id, like `?org=`). When it is sent, the answer is the person's live
9
+ membership of that app type pinned to that site (inside `?org=` when it is also
10
+ sent); failing that, their organisation-wide membership in `?org=`; failing
11
+ that, any live membership in `?org=`. When none of these exists the route
12
+ answers exactly as before. A removed membership never wins, and a site never
13
+ turns a found membership into "not found". Callers that do not send `site`
14
+ see no change. Login, auth-v2 and verification are unchanged.
15
+
16
+ The rule is the pure `pickSiteMembership` in `utils/member-lookup.util.ts`.
package/dist/index.js CHANGED
@@ -27886,6 +27886,27 @@ async function entitledSites(req) {
27886
27886
  });
27887
27887
  }
27888
27888
 
27889
+ // src/utils/member-lookup.util.ts
27890
+ var idOf2 = (v) => v == null ? "" : String(v?._id ?? v).toLowerCase();
27891
+ function isLiveMembership(m) {
27892
+ return m.status !== "deleted" && !m.deletedAt;
27893
+ }
27894
+ function pickSiteMembership(rows, type, site, org = "") {
27895
+ site = site.toLowerCase();
27896
+ org = org.toLowerCase();
27897
+ if (!site)
27898
+ return null;
27899
+ const live = rows.filter(
27900
+ (m) => m.type === type && isLiveMembership(m) && (!org || idOf2(m.org) === org)
27901
+ );
27902
+ const atSite = live.find((m) => idOf2(m.siteId) === site);
27903
+ if (atSite)
27904
+ return atSite;
27905
+ if (!org)
27906
+ return null;
27907
+ return live.find((m) => !idOf2(m.siteId)) ?? live[0] ?? null;
27908
+ }
27909
+
27889
27910
  // src/controllers/member.controller.ts
27890
27911
  async function requireMemberOrg(req, org) {
27891
27912
  const orgId = org?.toString() ?? "";
@@ -27902,6 +27923,7 @@ function useMemberController() {
27902
27923
  getOrgsByMembership: _getOrgsByMembership,
27903
27924
  getByUserIdType: _getByUserIdType,
27904
27925
  getByUserIdTypeOrg: _getByUserIdTypeOrg,
27926
+ getAllByUserId: _getAllByUserId,
27905
27927
  getById: _getMemberById,
27906
27928
  updateMemberStatus: _updateMemberStatus,
27907
27929
  updateStatusByUserId: _updateStatusByUserId,
@@ -27987,11 +28009,18 @@ function useMemberController() {
27987
28009
  const user = req.params.id;
27988
28010
  const type = req.params.type;
27989
28011
  const org = typeof req.query.org === "string" && /^[0-9a-fA-F]{24}$/.test(req.query.org) ? req.query.org : "";
28012
+ const site = typeof req.query.site === "string" && /^[0-9a-fA-F]{24}$/.test(req.query.site) ? req.query.site : "";
27990
28013
  try {
27991
28014
  await requireSelfOrPlatformStaff(req, user, { resource: "members", action: "view-members" });
27992
- const inOrg = org ? await _getByUserIdTypeOrg(user, type, org).catch(() => null) : null;
28015
+ const atSite = site ? pickSiteMembership(
28016
+ await _getAllByUserId(user).catch(() => []),
28017
+ type,
28018
+ site,
28019
+ org
28020
+ ) : null;
28021
+ const inOrg = org && !atSite ? await _getByUserIdTypeOrg(user, type, org).catch(() => null) : null;
27993
28022
  const liveInOrg = inOrg && inOrg.status !== "deleted" && !inOrg.deletedAt ? inOrg : null;
27994
- const data = liveInOrg ?? await _getByUserIdType(user, type);
28023
+ const data = atSite ?? liveInOrg ?? await _getByUserIdType(user, type);
27995
28024
  res.json(data);
27996
28025
  return;
27997
28026
  } catch (error2) {