@7365admin1/core 3.64.5-staging.293 → 3.64.5-staging.295
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-direct-role-org.md +5 -0
- package/.changeset/user-field-self-allowlist.md +5 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +40 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +40 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/test/e2e/member-direct-role-org.e2e.test.mjs +255 -0
- package/test/e2e/user-field-self-allowlist.e2e.test.mjs +172 -0
- package/test/member-direct-role-org.test.mjs +33 -0
- package/test/user-field-self-allowlist.test.mjs +39 -0
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
|
|
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
|
}
|
|
@@ -16122,11 +16127,32 @@ async function requireInviteReach(req, org, app, role) {
|
|
|
16122
16127
|
await requireOrgReach(req, org);
|
|
16123
16128
|
await requireRoleInvitable(role, org, apps);
|
|
16124
16129
|
}
|
|
16125
|
-
async function requireUserFieldWrite(req, userId, field, grant) {
|
|
16126
|
-
if (field
|
|
16127
|
-
return await
|
|
16128
|
-
|
|
16130
|
+
async function requireUserFieldWrite(req, userId, field, grant, value) {
|
|
16131
|
+
if (field && SELF_EDITABLE_USER_FIELDS.includes(field)) {
|
|
16132
|
+
return await requireSelfOrPlatformStaff(req, userId, grant);
|
|
16133
|
+
}
|
|
16134
|
+
if (field === "defaultOrg") {
|
|
16135
|
+
const id = callerId(req);
|
|
16136
|
+
const org = value?.toString?.() ?? "";
|
|
16137
|
+
if (id && userId?.toString() === id && org) {
|
|
16138
|
+
const reaches = await requireOrgReach(req, org).then(
|
|
16139
|
+
() => true,
|
|
16140
|
+
() => false
|
|
16141
|
+
);
|
|
16142
|
+
if (reaches)
|
|
16143
|
+
return id;
|
|
16144
|
+
}
|
|
16145
|
+
}
|
|
16146
|
+
return await requirePlatformStaff(req, grant);
|
|
16129
16147
|
}
|
|
16148
|
+
var SELF_EDITABLE_USER_FIELDS = [
|
|
16149
|
+
"name",
|
|
16150
|
+
"contact",
|
|
16151
|
+
"nric",
|
|
16152
|
+
"dateOfBirth",
|
|
16153
|
+
"profile",
|
|
16154
|
+
"gender"
|
|
16155
|
+
];
|
|
16130
16156
|
async function requireVerificationListReach(req, orgId) {
|
|
16131
16157
|
if (orgId) {
|
|
16132
16158
|
await requireOrgReach(req, orgId);
|
|
@@ -19791,7 +19817,7 @@ function useUserController() {
|
|
|
19791
19817
|
return;
|
|
19792
19818
|
}
|
|
19793
19819
|
try {
|
|
19794
|
-
await requireUserFieldWrite(req, _id, payload.field, { resource: "users" });
|
|
19820
|
+
await requireUserFieldWrite(req, _id, payload.field, { resource: "users" }, payload.value);
|
|
19795
19821
|
let message;
|
|
19796
19822
|
if (payload.field === "plateNumber") {
|
|
19797
19823
|
message = await updatePlateNumberByUserId(
|
|
@@ -20662,6 +20688,12 @@ function useMemberService() {
|
|
|
20662
20688
|
if (targetRole?.type === PLATFORM_STAFF_MEMBER_TYPE) {
|
|
20663
20689
|
await requireStaffCaller(callerId5, "assign a Seven365 staff role");
|
|
20664
20690
|
}
|
|
20691
|
+
const roleOrg = targetRole?.org?.toString?.() ?? "";
|
|
20692
|
+
if (roleOrg && roleOrg !== (orgId?.toString() ?? "").toLowerCase() && !await holdsRole(callerId5, roleId, orgId)) {
|
|
20693
|
+
throw new import_node_server_utils50.BadRequestError(
|
|
20694
|
+
"That role belongs to a different organisation."
|
|
20695
|
+
);
|
|
20696
|
+
}
|
|
20665
20697
|
const session = import_node_server_utils50.useAtlas.getClient()?.startSession();
|
|
20666
20698
|
session?.startTransaction();
|
|
20667
20699
|
try {
|
|
@@ -90210,7 +90242,7 @@ function useUserControllerV2() {
|
|
|
90210
90242
|
return;
|
|
90211
90243
|
}
|
|
90212
90244
|
try {
|
|
90213
|
-
await requireUserFieldWrite(req, _id, payload.field, { resource: "users" });
|
|
90245
|
+
await requireUserFieldWrite(req, _id, payload.field, { resource: "users" }, payload.value);
|
|
90214
90246
|
const message = await _updateUserFieldById({ _id, ...payload });
|
|
90215
90247
|
res.json({ message });
|
|
90216
90248
|
return;
|