@7365admin1/core 3.142.0 → 3.143.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@7365admin1/core",
3
3
  "license": "MIT",
4
- "version": "3.142.0",
4
+ "version": "3.143.0",
5
5
  "author": "7365admin1",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.mjs",
@@ -164,6 +164,19 @@ describe("Seven365 staff access", { concurrency: 1 }, () => {
164
164
  assert.equal((await audit("staff-view.write")).length, before);
165
165
  });
166
166
 
167
+ record("9b. inside a client, staff reach its cameras and vehicles like its owner; an outsider still cannot", async () => {
168
+ // Owner 2026-10-01 "no missed out": the camera wall (entitleSite) and every
169
+ // getUserPermissions(org) check (cameras, ANPR, vehicles) honour staff.
170
+ const { getSiteWall } = h.core.useCameraViewService();
171
+ const wall = await getSiteWall({ siteId: id.ownSite.toString(), userId: id.staff.toString() });
172
+ assert.ok(wall, "staff got the wall");
173
+ await assert.rejects(
174
+ getSiteWall({ siteId: id.ownSite.toString(), userId: id.otherOwner.toString() }),
175
+ /not found/i,
176
+ "another client's owner is still refused",
177
+ );
178
+ });
179
+
167
180
  record("10. support@ preview lists every membership, named, with the cross-client site", async () => {
168
181
  const res = await h.api(`${B}/memberships?email=${SUPPORT}`, { sid: staffSid });
169
182
  assert.equal(res.status, 200, JSON.stringify(res.body));
@@ -264,5 +277,5 @@ async function seed(h) {
264
277
  { _id: supportClientMember, user: support, org: agency, siteId: strangerSite, siteName: "Stranger Condo", role: agencyRole, type: "security_agency", status: "active", createdBy: staff, createdAt: now },
265
278
  ]);
266
279
 
267
- return { client, agency, ownSite, servedSite, strangerSite, staff, supportClientMember, supportStaffMember };
280
+ return { client, agency, ownSite, servedSite, strangerSite, staff, otherOwner: other, supportClientMember, supportStaffMember };
268
281
  }
@@ -111,14 +111,13 @@ test("add and delete gained nothing - staff still cannot create or destroy a cam
111
111
  }
112
112
  });
113
113
 
114
- test("staff have NOT gained a cross-organisation camera list", () => {
115
- // The whole reason the bypass is in the controller: entitleSite is the
116
- // tenant boundary for every camera READ, and it is untouched.
117
- assert.equal(
118
- /isSuperAdmin|super-admin\.util/.test(CAMERA_SERVICE),
119
- false,
120
- "entitleSite/authorizeSite now knows about staff - reads are widened",
121
- );
114
+ test("staff reach a client's cameras ONLY through the explicit staff rule (Open as staff, 2026-10-01)", () => {
115
+ // Owner decision 2026-10-01 ("no missed out"): Seven365 staff working inside
116
+ // a client see and set up its cameras like the owner. The only door is
117
+ // `staffReachesEveryClient` (live staff membership + cross-client tick), taken
118
+ // when no membership grants the site - never a bare isSuperAdmin.
119
+ assert.equal(/isSuperAdmin/.test(CAMERA_SERVICE), false, "a bare isSuperAdmin bypass appeared");
120
+ assert.match(CAMERA_SERVICE, /if \(!grant && \(await staffReachesEveryClient\(params\.userId\)\)\)/);
122
121
  const list = handler("getAll");
123
122
  assert.match(list, /entitleSite\(\{ siteId: site, userId: callerId\(req\) \}\)/);
124
123
  assert.equal(/staffStatusChange|isSuperAdmin/.test(list), false);