@7365admin1/core 3.72.1-staging.322 → 3.72.1-staging.324
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/real-estate-developer-app-type.md +5 -0
- package/.changeset/real-estate-developer-lookup-both-types.md +5 -0
- package/dist/index.js +48 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +48 -19
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/test/backfill-org-owner-roles.test.mjs +6 -1
- package/test/default-staff-role.test.mjs +1 -1
- package/test/e2e/client-invite-service365.e2e.test.mjs +99 -1
- package/test/org-default-roles.test.mjs +11 -0
- package/test/service-app-type.test.mjs +35 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
"@7365admin1/core": minor
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Real Estate Developer clients use the Property Management application: membership and role types `real_estate_developer` are stored and looked up as `property_management_agency`, so a developer's owner can open the Property Management app and the owner grant caps their roles.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
"@7365admin1/core": patch
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Membership and role lookups by type match every stored spelling of an application: a Property Management lookup finds rows stored as `real_estate_developer` (written before 3.75.0) as well as `property_management_agency`, including the module deny list and the owner-grant cap.
|
package/dist/index.js
CHANGED
|
@@ -3987,6 +3987,30 @@ function useUserRepo() {
|
|
|
3987
3987
|
var import_node_server_utils17 = require("@7365admin1/node-server-utils");
|
|
3988
3988
|
var import_uuid = require("uuid");
|
|
3989
3989
|
|
|
3990
|
+
// src/utils/service-app-type.util.ts
|
|
3991
|
+
var APP_TYPE_ALIASES = Object.freeze({
|
|
3992
|
+
real_estate_developer: "property_management_agency"
|
|
3993
|
+
});
|
|
3994
|
+
function serviceAppType(type) {
|
|
3995
|
+
if (typeof type !== "string")
|
|
3996
|
+
return type;
|
|
3997
|
+
return APP_TYPE_ALIASES[type] ?? type;
|
|
3998
|
+
}
|
|
3999
|
+
function storedAppTypes(type) {
|
|
4000
|
+
const app = serviceAppType(type);
|
|
4001
|
+
return [
|
|
4002
|
+
app,
|
|
4003
|
+
...Object.keys(APP_TYPE_ALIASES).filter((alias) => APP_TYPE_ALIASES[alias] === app)
|
|
4004
|
+
];
|
|
4005
|
+
}
|
|
4006
|
+
function appTypeQuery(type) {
|
|
4007
|
+
const types = storedAppTypes(type);
|
|
4008
|
+
return types.length === 1 ? types[0] : { $in: types };
|
|
4009
|
+
}
|
|
4010
|
+
function sameAppType(a, b) {
|
|
4011
|
+
return !!a && !!b && serviceAppType(a) === serviceAppType(b);
|
|
4012
|
+
}
|
|
4013
|
+
|
|
3990
4014
|
// src/repositories/member.repo.ts
|
|
3991
4015
|
var import_node_server_utils14 = require("@7365admin1/node-server-utils");
|
|
3992
4016
|
|
|
@@ -4139,7 +4163,7 @@ function useMemberRepo() {
|
|
|
4139
4163
|
}
|
|
4140
4164
|
async function add(value, session) {
|
|
4141
4165
|
try {
|
|
4142
|
-
value = MMember(value);
|
|
4166
|
+
value = MMember({ ...value, type: serviceAppType(value.type) });
|
|
4143
4167
|
await collection.insertOne(value, { session });
|
|
4144
4168
|
delNamespace().then(() => {
|
|
4145
4169
|
import_node_server_utils14.logger.info(`Cache cleared for namespace: ${namespace_collection3}`);
|
|
@@ -4267,6 +4291,7 @@ function useMemberRepo() {
|
|
|
4267
4291
|
}
|
|
4268
4292
|
}
|
|
4269
4293
|
async function getByUserIdType(user, type) {
|
|
4294
|
+
type = serviceAppType(type);
|
|
4270
4295
|
try {
|
|
4271
4296
|
user = new import_mongodb13.ObjectId(user);
|
|
4272
4297
|
} catch (error) {
|
|
@@ -4282,7 +4307,7 @@ function useMemberRepo() {
|
|
|
4282
4307
|
return cachedData;
|
|
4283
4308
|
}
|
|
4284
4309
|
try {
|
|
4285
|
-
const data = await collection.findOne({ user, type });
|
|
4310
|
+
const data = await collection.findOne({ user, type: appTypeQuery(type) });
|
|
4286
4311
|
if (!data) {
|
|
4287
4312
|
throw new import_node_server_utils14.NotFoundError("Member not found.");
|
|
4288
4313
|
}
|
|
@@ -4426,7 +4451,7 @@ function useMemberRepo() {
|
|
|
4426
4451
|
search = search || "";
|
|
4427
4452
|
page = page > 0 ? page - 1 : 0;
|
|
4428
4453
|
const query2 = {
|
|
4429
|
-
type,
|
|
4454
|
+
type: type ? appTypeQuery(type) : type,
|
|
4430
4455
|
status
|
|
4431
4456
|
};
|
|
4432
4457
|
const cacheOptions = {
|
|
@@ -4555,7 +4580,7 @@ function useMemberRepo() {
|
|
|
4555
4580
|
const query2 = {
|
|
4556
4581
|
user,
|
|
4557
4582
|
org: { $nin: [null, ""] },
|
|
4558
|
-
type
|
|
4583
|
+
type: appTypeQuery(type)
|
|
4559
4584
|
};
|
|
4560
4585
|
const cacheOptions = {
|
|
4561
4586
|
page,
|
|
@@ -4948,6 +4973,7 @@ function useMemberRepo() {
|
|
|
4948
4973
|
}
|
|
4949
4974
|
}
|
|
4950
4975
|
async function getByUserIdTypeOrg(user, type, org) {
|
|
4976
|
+
type = serviceAppType(type);
|
|
4951
4977
|
try {
|
|
4952
4978
|
user = new import_mongodb13.ObjectId(user);
|
|
4953
4979
|
} catch {
|
|
@@ -4971,7 +4997,7 @@ function useMemberRepo() {
|
|
|
4971
4997
|
try {
|
|
4972
4998
|
const data = await collection.findOne({
|
|
4973
4999
|
user,
|
|
4974
|
-
type,
|
|
5000
|
+
type: appTypeQuery(type),
|
|
4975
5001
|
org
|
|
4976
5002
|
});
|
|
4977
5003
|
if (!data) {
|
|
@@ -10572,7 +10598,7 @@ function pickSiteMembership(rows, type, site, org = "") {
|
|
|
10572
10598
|
if (!site)
|
|
10573
10599
|
return null;
|
|
10574
10600
|
const live = rows.filter(
|
|
10575
|
-
(m) => m.type
|
|
10601
|
+
(m) => sameAppType(m.type, type) && isLiveMembership(m) && (!org || idOf2(m.org) === org)
|
|
10576
10602
|
);
|
|
10577
10603
|
const atSite = live.find((m) => idOf2(m.siteId) === site);
|
|
10578
10604
|
if (atSite)
|
|
@@ -10586,10 +10612,10 @@ function pickLookupMembership(rows, type, site = "", org = "") {
|
|
|
10586
10612
|
const atSite = site ? pickSiteMembership(list, type, site, org) : null;
|
|
10587
10613
|
if (atSite)
|
|
10588
10614
|
return atSite;
|
|
10589
|
-
const inOrg = org ? list.find((m) => m.type
|
|
10615
|
+
const inOrg = org ? list.find((m) => sameAppType(m.type, type) && idOf2(m.org) === org.toLowerCase()) : void 0;
|
|
10590
10616
|
if (inOrg && isLiveMembership(inOrg))
|
|
10591
10617
|
return inOrg;
|
|
10592
|
-
return list.find((m) => m.type
|
|
10618
|
+
return list.find((m) => sameAppType(m.type, type)) ?? null;
|
|
10593
10619
|
}
|
|
10594
10620
|
function memberListSiteScope(memberships, org) {
|
|
10595
10621
|
const inOrg = (memberships ?? []).filter((m) => idOf2(m.org) === idOf2(org));
|
|
@@ -12515,7 +12541,7 @@ function useRoleRepo() {
|
|
|
12515
12541
|
const { delNamespace, setCache, getCache } = (0, import_node_server_utils42.useCache)(namespace_collection3);
|
|
12516
12542
|
const { delNamespace: _delDashboardNameSpace } = (0, import_node_server_utils42.useCache)("dashboard");
|
|
12517
12543
|
async function addRole(value, session) {
|
|
12518
|
-
value = new MRole(value);
|
|
12544
|
+
value = new MRole({ ...value, type: serviceAppType(value.type) });
|
|
12519
12545
|
try {
|
|
12520
12546
|
const res = await collection.insertOne(value, { session });
|
|
12521
12547
|
delNamespace().then(() => {
|
|
@@ -12579,7 +12605,7 @@ function useRoleRepo() {
|
|
|
12579
12605
|
return cachedData;
|
|
12580
12606
|
}
|
|
12581
12607
|
try {
|
|
12582
|
-
const data = await collection.find({ org, permissions: "*", type, status: "active" }).toArray();
|
|
12608
|
+
const data = await collection.find({ org, permissions: "*", type: appTypeQuery(type), status: "active" }).toArray();
|
|
12583
12609
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
12584
12610
|
import_node_server_utils42.logger.info(`Cache set for key: ${cacheKey}`);
|
|
12585
12611
|
}).catch((err) => {
|
|
@@ -12618,7 +12644,8 @@ function useRoleRepo() {
|
|
|
12618
12644
|
if (!name) {
|
|
12619
12645
|
throw new import_node_server_utils42.BadRequestError("Role name is required.");
|
|
12620
12646
|
}
|
|
12621
|
-
|
|
12647
|
+
type = serviceAppType(type);
|
|
12648
|
+
const query2 = type ? { name, type: appTypeQuery(type) } : { name };
|
|
12622
12649
|
try {
|
|
12623
12650
|
const cacheKey = (0, import_node_server_utils42.makeCacheKey)(namespace_collection3, query2);
|
|
12624
12651
|
const cachedData = await getCache(cacheKey);
|
|
@@ -12674,8 +12701,8 @@ function useRoleRepo() {
|
|
|
12674
12701
|
cacheOptions.search = search;
|
|
12675
12702
|
}
|
|
12676
12703
|
if (type) {
|
|
12677
|
-
query2.type = type;
|
|
12678
|
-
cacheOptions.type = type;
|
|
12704
|
+
query2.type = appTypeQuery(type);
|
|
12705
|
+
cacheOptions.type = serviceAppType(type);
|
|
12679
12706
|
}
|
|
12680
12707
|
const cacheKey = (0, import_node_server_utils42.makeCacheKey)(namespace_collection3, cacheOptions);
|
|
12681
12708
|
const cachedData = await getCache(cacheKey);
|
|
@@ -15470,13 +15497,14 @@ function defaultOwnerRoles(org, nature, appOwnerPermissions) {
|
|
|
15470
15497
|
{ ...owner, type: "organization" },
|
|
15471
15498
|
{ ...administrator, type: "organization" }
|
|
15472
15499
|
];
|
|
15473
|
-
|
|
15500
|
+
const appType = serviceAppType(nature);
|
|
15501
|
+
if (appType && APP_SERVICE_TYPES.has(appType)) {
|
|
15474
15502
|
roles.push({
|
|
15475
15503
|
...owner,
|
|
15476
|
-
type:
|
|
15504
|
+
type: appType,
|
|
15477
15505
|
...appOwnerPermissions?.length && { permissions: [...appOwnerPermissions] }
|
|
15478
15506
|
});
|
|
15479
|
-
roles.push({ ...administrator, type:
|
|
15507
|
+
roles.push({ ...administrator, type: appType });
|
|
15480
15508
|
}
|
|
15481
15509
|
return roles;
|
|
15482
15510
|
}
|
|
@@ -15561,15 +15589,16 @@ async function moduleCeiling(org, site) {
|
|
|
15561
15589
|
}
|
|
15562
15590
|
async function ownerGrantCeiling(org, type) {
|
|
15563
15591
|
const orgId = org?.toString() ?? "";
|
|
15592
|
+
type = serviceAppType(type);
|
|
15564
15593
|
if (!orgId || !type)
|
|
15565
15594
|
return null;
|
|
15566
15595
|
try {
|
|
15567
15596
|
const orgDoc = await useOrgRepo().getById(orgId).catch(() => null);
|
|
15568
|
-
if (!orgDoc?.invitedRole || orgDoc
|
|
15597
|
+
if (!orgDoc?.invitedRole || !sameAppType(orgDoc?.nature, type))
|
|
15569
15598
|
return null;
|
|
15570
15599
|
const role = await useRoleRepo().getRoleById(String(orgDoc.invitedRole)).catch(() => null);
|
|
15571
15600
|
const permissions = role?.permissions;
|
|
15572
|
-
const chosen = role && String(role.org ?? "") === orgId && role.default === true && role.type
|
|
15601
|
+
const chosen = role && String(role.org ?? "") === orgId && role.default === true && sameAppType(role.type, type) && Array.isArray(permissions) && permissions.length > 0 && !permissions.includes("*");
|
|
15573
15602
|
return chosen ? permissions.map(String) : null;
|
|
15574
15603
|
} catch {
|
|
15575
15604
|
return null;
|
|
@@ -26521,7 +26550,7 @@ function useOrgController() {
|
|
|
26521
26550
|
invitedModules?.permissions
|
|
26522
26551
|
);
|
|
26523
26552
|
const appOwnerRole = invitedModules?.permissions.length ? seededRoles.find(
|
|
26524
|
-
(role) => role.type
|
|
26553
|
+
(role) => sameAppType(role.type, body.nature) && role.name === "owner"
|
|
26525
26554
|
) : void 0;
|
|
26526
26555
|
if (appOwnerRole) {
|
|
26527
26556
|
try {
|