@7365admin1/core 3.68.3-staging.315 → 3.68.3-staging.316
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/.changeset/member-list-site-scope.md +5 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +96 -67
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/test/e2e/member-list-site-scope.e2e.test.mjs +111 -0
- package/test/member-list-site-scope.test.mjs +30 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
"@7365admin1/core": minor
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
`GET /api/members?org=` lists only the sites a caller is pinned to when the caller holds no organisation-wide membership or organisation-level role there; a `siteId` outside those sites is refused. Organisation-wide members, owners/invitees and Seven365 staff are unchanged; a resident-only caller lists no staff.
|
package/dist/index.d.ts
CHANGED
|
@@ -442,13 +442,15 @@ declare function useMemberRepo(): {
|
|
|
442
442
|
getByUserIdType: (user: string | ObjectId, type: string) => Promise<TMember>;
|
|
443
443
|
getByRoleId: (role: string | ObjectId) => Promise<any>;
|
|
444
444
|
getAssignedByRoleId: (role: string | ObjectId) => Promise<TMember[]>;
|
|
445
|
-
getAll: ({ search, page, limit, user, org, siteId, type, status, }: {
|
|
445
|
+
getAll: ({ search, page, limit, user, org, siteId, siteIds, type, status, }: {
|
|
446
446
|
search?: string | undefined;
|
|
447
447
|
page?: number | undefined;
|
|
448
448
|
limit?: number | undefined;
|
|
449
449
|
user?: string | ObjectId | undefined;
|
|
450
450
|
org?: string | ObjectId | undefined;
|
|
451
451
|
siteId?: string | ObjectId | undefined;
|
|
452
|
+
/** Restrict to these sites (the caller's pinned sites); `[]` lists nothing. */
|
|
453
|
+
siteIds?: string[] | undefined;
|
|
452
454
|
type: string;
|
|
453
455
|
status: string;
|
|
454
456
|
}) => Promise<{
|
package/dist/index.js
CHANGED
|
@@ -4411,6 +4411,7 @@ function useMemberRepo() {
|
|
|
4411
4411
|
user = "",
|
|
4412
4412
|
org = "",
|
|
4413
4413
|
siteId = "",
|
|
4414
|
+
siteIds,
|
|
4414
4415
|
type = "",
|
|
4415
4416
|
status = ""
|
|
4416
4417
|
}) {
|
|
@@ -4444,6 +4445,12 @@ function useMemberRepo() {
|
|
|
4444
4445
|
throw new import_node_server_utils14.BadRequestError("Invalid site ID format.");
|
|
4445
4446
|
}
|
|
4446
4447
|
}
|
|
4448
|
+
if (siteIds) {
|
|
4449
|
+
query2.siteId = {
|
|
4450
|
+
$in: siteIds.filter((id) => import_mongodb13.ObjectId.isValid(id)).map((id) => new import_mongodb13.ObjectId(id))
|
|
4451
|
+
};
|
|
4452
|
+
cacheOptions.siteIds = [...siteIds].sort().join(",") || "no-site";
|
|
4453
|
+
}
|
|
4447
4454
|
if (user) {
|
|
4448
4455
|
try {
|
|
4449
4456
|
query2.user = new import_mongodb13.ObjectId(user);
|
|
@@ -10554,6 +10561,15 @@ function pickLookupMembership(rows, type, site = "", org = "") {
|
|
|
10554
10561
|
return inOrg;
|
|
10555
10562
|
return list.find((m) => m.type === type) ?? null;
|
|
10556
10563
|
}
|
|
10564
|
+
function memberListSiteScope(memberships, org) {
|
|
10565
|
+
const inOrg = (memberships ?? []).filter((m) => idOf2(m.org) === idOf2(org));
|
|
10566
|
+
const here = inOrg.filter((m) => m.type !== "resident");
|
|
10567
|
+
if (!inOrg.length)
|
|
10568
|
+
return null;
|
|
10569
|
+
if (here.some((m) => !idOf2(m.siteId) || m.orgLevelRole))
|
|
10570
|
+
return null;
|
|
10571
|
+
return [...new Set(here.map((m) => idOf2(m.siteId)))];
|
|
10572
|
+
}
|
|
10557
10573
|
|
|
10558
10574
|
// src/services/module-gate.service.ts
|
|
10559
10575
|
var idOf3 = (v) => v == null ? "" : String(v?._id ?? v).toLowerCase();
|
|
@@ -23958,6 +23974,18 @@ function useMemberController() {
|
|
|
23958
23974
|
await requireConsolePermission(req, "members", "view-members");
|
|
23959
23975
|
} else if (org) {
|
|
23960
23976
|
await requireOrgAccess(req, org);
|
|
23977
|
+
}
|
|
23978
|
+
let siteIds;
|
|
23979
|
+
if (org && type !== "admin") {
|
|
23980
|
+
const actor = await resolveInviteActor(callerId(req));
|
|
23981
|
+
const scope = staffMayBypass(actor) ? null : memberListSiteScope(actor.memberships, org);
|
|
23982
|
+
if (scope) {
|
|
23983
|
+
if (siteId && !scope.includes(siteId.toLowerCase())) {
|
|
23984
|
+
throw new import_node_server_utils65.UnauthorizedError("Not authorized.");
|
|
23985
|
+
}
|
|
23986
|
+
if (!siteId)
|
|
23987
|
+
siteIds = scope;
|
|
23988
|
+
}
|
|
23961
23989
|
} else if (user && user !== callerId(req)) {
|
|
23962
23990
|
await requireConsolePermission(req, "users", "see-all-users");
|
|
23963
23991
|
}
|
|
@@ -23968,6 +23996,7 @@ function useMemberController() {
|
|
|
23968
23996
|
user,
|
|
23969
23997
|
org,
|
|
23970
23998
|
siteId,
|
|
23999
|
+
siteIds,
|
|
23971
24000
|
type,
|
|
23972
24001
|
status
|
|
23973
24002
|
});
|