@7365admin1/core 3.64.5-staging.292 → 3.64.5-staging.294

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,5 @@
1
+ ---
2
+ "@7365admin1/core": patch
3
+ ---
4
+
5
+ POST /api/members/direct refuses (400) a role that belongs to a different organisation, unless the caller already holds that role in the organisation being joined.
@@ -0,0 +1,7 @@
1
+ ---
2
+ "@7365admin1/core": patch
3
+ ---
4
+
5
+ Site Settings saves are no longer refused because the client has one resident-app
6
+ switch turned off. A save is refused only when it would turn ON a resident-app
7
+ switch that the site has stored as off and the client has switched off.
package/dist/index.d.ts CHANGED
@@ -11138,7 +11138,9 @@ declare function hasOrgOwnership(userId?: string | ObjectId | null, orgId?: stri
11138
11138
  * `status: { $ne: "deleted" }` is the same liveness test every other membership
11139
11139
  * read in this package uses, so a revoked membership stops conferring the read.
11140
11140
  */
11141
- declare function holdsRole(userId?: string | ObjectId | null, roleId?: string | ObjectId | null): Promise<boolean>;
11141
+ declare function holdsRole(userId?: string | ObjectId | null, roleId?: string | ObjectId | null,
11142
+ /** when given, the live membership must also be in THIS organisation */
11143
+ orgId?: string | ObjectId | null): Promise<boolean>;
11142
11144
 
11143
11145
  declare function useAuthControllerV2(): {
11144
11146
  signUp: (req: Request, res: Response, next: NextFunction) => Promise<void>;
package/dist/index.js CHANGED
@@ -14627,19 +14627,24 @@ async function hasOrgOwnership(userId, orgId) {
14627
14627
  );
14628
14628
  return Boolean(found);
14629
14629
  }
14630
- async function holdsRole(userId, roleId) {
14630
+ async function holdsRole(userId, roleId, orgId) {
14631
14631
  const id = userId?.toString() ?? "";
14632
14632
  const role = roleId?.toString() ?? "";
14633
+ const org = orgId?.toString() ?? "";
14633
14634
  if (!id || !role || !import_mongodb25.ObjectId.isValid(id) || !import_mongodb25.ObjectId.isValid(role)) {
14634
14635
  return false;
14635
14636
  }
14637
+ if (orgId !== void 0 && !import_mongodb25.ObjectId.isValid(org))
14638
+ return false;
14636
14639
  const db2 = import_node_server_utils27.useAtlas.getDb();
14637
14640
  if (!db2)
14638
14641
  return false;
14639
14642
  const member = await db2.collection("members").findOne({
14640
14643
  user: new import_mongodb25.ObjectId(id),
14641
14644
  role: new import_mongodb25.ObjectId(role),
14642
- status: { $ne: "deleted" }
14645
+ status: { $ne: "deleted" },
14646
+ // both shapes, as `hasOrgInvitation` does for `metadata.org`
14647
+ ...org ? { org: { $in: [new import_mongodb25.ObjectId(org), org] } } : {}
14643
14648
  });
14644
14649
  return Boolean(member);
14645
14650
  }
@@ -20662,6 +20667,12 @@ function useMemberService() {
20662
20667
  if (targetRole?.type === PLATFORM_STAFF_MEMBER_TYPE) {
20663
20668
  await requireStaffCaller(callerId5, "assign a Seven365 staff role");
20664
20669
  }
20670
+ const roleOrg = targetRole?.org?.toString?.() ?? "";
20671
+ if (roleOrg && roleOrg !== (orgId?.toString() ?? "").toLowerCase() && !await holdsRole(callerId5, roleId, orgId)) {
20672
+ throw new import_node_server_utils50.BadRequestError(
20673
+ "That role belongs to a different organisation."
20674
+ );
20675
+ }
20665
20676
  const session = import_node_server_utils50.useAtlas.getClient()?.startSession();
20666
20677
  session?.startTransaction();
20667
20678
  try {
@@ -39318,11 +39329,12 @@ function effectiveResidentAppModules(orgModules, siteModules) {
39318
39329
  }
39319
39330
  return effective;
39320
39331
  }
39321
- function residentAppModulesAboveCeiling(orgModules, requested) {
39332
+ function residentAppModulesAboveCeiling(orgModules, requested, stored) {
39322
39333
  const org = asModules(orgModules);
39323
39334
  const wanted = asModules(requested);
39335
+ const had = asModules(stored);
39324
39336
  return residentAppModuleKeys.filter(
39325
- (key) => org[key] === false && wanted[key] === true
39337
+ (key) => org[key] === false && wanted[key] === true && had[key] === false
39326
39338
  );
39327
39339
  }
39328
39340
  function residentAppModulesAboveCeilingMessage(rejected) {
@@ -39542,7 +39554,8 @@ function useSiteController() {
39542
39554
  ) : null;
39543
39555
  const above = residentAppModulesAboveCeiling(
39544
39556
  org?.residentAppModules,
39545
- rest.metadata.residentAppModules
39557
+ rest.metadata.residentAppModules,
39558
+ existing?.metadata?.residentAppModules
39546
39559
  );
39547
39560
  if (above.length) {
39548
39561
  next(