@7365admin1/core 3.139.0 → 3.140.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/CHANGELOG.md +12 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +19 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +19 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/test/e2e/service-provider-invite-email-new-company.e2e.test.mjs +25 -0
- package/test/member-entitled-list.test.mjs +60 -0
- package/test/member-lookup-honours-org.test.mjs +3 -3
- package/test/member-lookup-site.test.mjs +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @iservice365/core
|
|
2
2
|
|
|
3
|
+
## 3.140.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- ff48585: A person's memberships list (`GET /members/users/:id`) leaves out taken-away (inactive / deleted) memberships by default; `?include=removed` returns the history. One shared entitlement test (`isEntitledMembership`, `entitledMemberships`) now also drives the site/org membership lookup, notification categories and role permissions.
|
|
8
|
+
|
|
9
|
+
## 3.139.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 45755c1: Security: a membership that was taken away ("inactive" after the service-provider Repair or Finish-setup Undo, or "deleted") no longer grants organisation, site or role reach (resolveInviteActor, camera site entitlement, role-holder check).
|
|
14
|
+
|
|
3
15
|
## 3.139.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -1095,7 +1095,9 @@ declare function useMemberService(): {
|
|
|
1095
1095
|
updateSiteById: (id: string, siteId: string, siteName: string) => Promise<{
|
|
1096
1096
|
message: string;
|
|
1097
1097
|
}>;
|
|
1098
|
-
getAllByUser: (user: string
|
|
1098
|
+
getAllByUser: (user: string, { includeRemoved }?: {
|
|
1099
|
+
includeRemoved?: boolean | undefined;
|
|
1100
|
+
}) => Promise<{
|
|
1099
1101
|
items: TMember[];
|
|
1100
1102
|
total: number;
|
|
1101
1103
|
}>;
|
package/dist/index.js
CHANGED
|
@@ -4374,7 +4374,10 @@ function sameAppType(a, b) {
|
|
|
4374
4374
|
// src/utils/member-lookup.util.ts
|
|
4375
4375
|
var idOf = (v) => v == null ? "" : String(v?._id ?? v).toLowerCase();
|
|
4376
4376
|
function isLiveMembership(m) {
|
|
4377
|
-
return m
|
|
4377
|
+
return !TAKEN_AWAY_MEMBER_STATUSES.includes(String(m?.status ?? "")) && !m?.deletedAt;
|
|
4378
|
+
}
|
|
4379
|
+
function entitledMemberships(rows) {
|
|
4380
|
+
return (Array.isArray(rows) ? rows : []).filter(isLiveMembership);
|
|
4378
4381
|
}
|
|
4379
4382
|
function pickSiteMembership(rows, type, site, org = "") {
|
|
4380
4383
|
site = site.toLowerCase();
|
|
@@ -4402,6 +4405,7 @@ function pickLookupMembership(rows, type, site = "", org = "") {
|
|
|
4402
4405
|
return preferWorkingMembership(list.filter((m) => sameAppType(m.type, type)));
|
|
4403
4406
|
}
|
|
4404
4407
|
var WORKING = /* @__PURE__ */ new Set(["active", "approved"]);
|
|
4408
|
+
var TAKEN_AWAY_MEMBER_STATUSES = ["deleted", "inactive"];
|
|
4405
4409
|
function preferWorkingMembership(rows, defaultOrg = "") {
|
|
4406
4410
|
const list = Array.isArray(rows) ? rows : [];
|
|
4407
4411
|
const working = list.filter((m) => WORKING.has(String(m.status ?? "")) && !m.deletedAt);
|
|
@@ -5255,7 +5259,7 @@ function useMemberRepo() {
|
|
|
5255
5259
|
// sets it inactive, removal deletes it) must not keep the organisation
|
|
5256
5260
|
// on the person's list: latitude.sec@ still saw JLL Singapore beside its
|
|
5257
5261
|
// own company after the repair (owner report 2026-09-30).
|
|
5258
|
-
status: { $nin:
|
|
5262
|
+
status: { $nin: TAKEN_AWAY_MEMBER_STATUSES }
|
|
5259
5263
|
};
|
|
5260
5264
|
const cacheOptions = {
|
|
5261
5265
|
page: page2,
|
|
@@ -9905,7 +9909,7 @@ async function resolveInviteActor(userId) {
|
|
|
9905
9909
|
const db2 = import_node_server_utils28.useAtlas.getDb();
|
|
9906
9910
|
if (!db2)
|
|
9907
9911
|
return { ...EMPTY, id };
|
|
9908
|
-
const members = await db2.collection("members").find({ user: new import_mongodb26.ObjectId(id), status: { $
|
|
9912
|
+
const members = await db2.collection("members").find({ user: new import_mongodb26.ObjectId(id), status: { $nin: TAKEN_AWAY_MEMBER_STATUSES } }).toArray();
|
|
9909
9913
|
const adminMember = members.find((m) => m.type === "admin");
|
|
9910
9914
|
let isSuperAdmin2 = false;
|
|
9911
9915
|
let staffPermissions;
|
|
@@ -10212,7 +10216,7 @@ async function holdsRole(userId, roleId, orgId) {
|
|
|
10212
10216
|
const member = await db2.collection("members").findOne({
|
|
10213
10217
|
user: new import_mongodb26.ObjectId(id),
|
|
10214
10218
|
role: new import_mongodb26.ObjectId(role),
|
|
10215
|
-
status: { $
|
|
10219
|
+
status: { $nin: TAKEN_AWAY_MEMBER_STATUSES },
|
|
10216
10220
|
// both shapes, as `hasOrgInvitation` does for `metadata.org`
|
|
10217
10221
|
...org ? { org: { $in: [new import_mongodb26.ObjectId(org), org] } } : {}
|
|
10218
10222
|
});
|
|
@@ -23153,7 +23157,8 @@ async function getUserPermissions(params) {
|
|
|
23153
23157
|
if (!roleId || !import_mongodb51.ObjectId.isValid(roleId)) {
|
|
23154
23158
|
const memberQuery = {
|
|
23155
23159
|
user: new import_mongodb51.ObjectId(user),
|
|
23156
|
-
|
|
23160
|
+
// A taken-away (inactive) row grants no permissions either.
|
|
23161
|
+
status: { $nin: TAKEN_AWAY_MEMBER_STATUSES }
|
|
23157
23162
|
};
|
|
23158
23163
|
if (org && import_mongodb51.ObjectId.isValid(org)) {
|
|
23159
23164
|
memberQuery.org = new import_mongodb51.ObjectId(org);
|
|
@@ -23243,7 +23248,7 @@ function useCameraViewService() {
|
|
|
23243
23248
|
}
|
|
23244
23249
|
}
|
|
23245
23250
|
async function resolveSiteAccess(params) {
|
|
23246
|
-
const memberships = await params.db.collection("members").find({ user: new import_mongodb52.ObjectId(params.userId), status: { $
|
|
23251
|
+
const memberships = await params.db.collection("members").find({ user: new import_mongodb52.ObjectId(params.userId), status: { $nin: TAKEN_AWAY_MEMBER_STATUSES } }).project({ siteId: 1, org: 1, role: 1, type: 1 }).toArray();
|
|
23247
23252
|
const memberOrgIds = [
|
|
23248
23253
|
...new Map(
|
|
23249
23254
|
memberships.filter((membership) => membership.org).map((membership) => [String(membership.org), membership.org])
|
|
@@ -29441,9 +29446,10 @@ function useMemberService() {
|
|
|
29441
29446
|
throw error;
|
|
29442
29447
|
}
|
|
29443
29448
|
}
|
|
29444
|
-
async function getAllByUser(user) {
|
|
29449
|
+
async function getAllByUser(user, { includeRemoved = false } = {}) {
|
|
29445
29450
|
try {
|
|
29446
|
-
const
|
|
29451
|
+
const all = await _getAllByUserId(user);
|
|
29452
|
+
const members = includeRemoved ? all : entitledMemberships(all);
|
|
29447
29453
|
return {
|
|
29448
29454
|
items: members,
|
|
29449
29455
|
total: members.length
|
|
@@ -30004,7 +30010,9 @@ function useMemberController() {
|
|
|
30004
30010
|
return;
|
|
30005
30011
|
}
|
|
30006
30012
|
try {
|
|
30007
|
-
const data = await _getAllByUser(userId
|
|
30013
|
+
const data = await _getAllByUser(userId, {
|
|
30014
|
+
includeRemoved: req.query.include === "removed"
|
|
30015
|
+
});
|
|
30008
30016
|
const whole = await requireSelfOrPlatformStaff(req, userId, {
|
|
30009
30017
|
resource: "members",
|
|
30010
30018
|
action: "view-members"
|
|
@@ -30045,7 +30053,7 @@ function useMemberController() {
|
|
|
30045
30053
|
org
|
|
30046
30054
|
) : null;
|
|
30047
30055
|
const inOrg = org && !atSite ? await _getByUserIdTypeOrg(user, type, org).catch(() => null) : null;
|
|
30048
|
-
const liveInOrg = inOrg && inOrg
|
|
30056
|
+
const liveInOrg = inOrg && isLiveMembership(inOrg) ? inOrg : null;
|
|
30049
30057
|
const data = atSite ?? liveInOrg ?? await _getByUserIdType(user, type);
|
|
30050
30058
|
res.json(data);
|
|
30051
30059
|
return;
|
|
@@ -108074,7 +108082,7 @@ function useNotificationPreferenceService() {
|
|
|
108074
108082
|
const db2 = import_node_server_utils330.useAtlas.getDb();
|
|
108075
108083
|
if (!db2)
|
|
108076
108084
|
return [];
|
|
108077
|
-
const members = await db2.collection("members").find({ user: new import_mongodb200.ObjectId(userId), status: { $
|
|
108085
|
+
const members = await db2.collection("members").find({ user: new import_mongodb200.ObjectId(userId), status: { $nin: TAKEN_AWAY_MEMBER_STATUSES } }).toArray();
|
|
108078
108086
|
if (!members.length)
|
|
108079
108087
|
return [];
|
|
108080
108088
|
const isResident = members.some((m) => m.type === "resident");
|