@7365admin1/core 3.64.3 → 3.64.4
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 +21 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.js +53 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +53 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/test/module-gate.test.mjs +237 -0
- package/test/org-modules.test.mjs +78 -0
- package/test/site-modules.test.mjs +84 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# @iservice365/core
|
|
2
2
|
|
|
3
|
+
## 3.64.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 3255256: Lay the groundwork for module lists becoming a gate, without narrowing anyone.
|
|
8
|
+
|
|
9
|
+
- New `utils/module-gate.util.ts`: the list of modules a client's list can
|
|
10
|
+
govern (generated from layer-common 5a96f95), the spelling groups, the
|
|
11
|
+
always-included set, and pure functions that work out which modules a
|
|
12
|
+
caller's apps must hide (`deniedModules`) and who would lose what if a list
|
|
13
|
+
changed (`moduleImpact`). Nothing calls them yet.
|
|
14
|
+
- The organisation and site module checks now treat every spelling of a module
|
|
15
|
+
as the same module (ticking `workOrder` also allows `work_orders`,
|
|
16
|
+
`work_order` and `work-orders`), and never refuse members, invitations, roles,
|
|
17
|
+
sites, customers, subscriptions, payment methods or site settings. This only
|
|
18
|
+
ever refuses less than before.
|
|
19
|
+
- A Site Settings save (`PATCH /api/sites/id/:id`) now always keeps the site's
|
|
20
|
+
stored module list. Before this, the save replaced `metadata` wholesale and
|
|
21
|
+
could wipe or overwrite that list. `PATCH /api/sites/:id/modules` is the only
|
|
22
|
+
way to change it.
|
|
23
|
+
|
|
3
24
|
## 3.64.3
|
|
4
25
|
|
|
5
26
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -11679,13 +11679,42 @@ function normaliseModules(modules) {
|
|
|
11679
11679
|
}
|
|
11680
11680
|
return out;
|
|
11681
11681
|
}
|
|
11682
|
+
var ALWAYS_ALLOWED = Object.freeze([
|
|
11683
|
+
"sites",
|
|
11684
|
+
"subscriptions",
|
|
11685
|
+
"customers",
|
|
11686
|
+
"payment-methods",
|
|
11687
|
+
"members",
|
|
11688
|
+
"invitations",
|
|
11689
|
+
"roles",
|
|
11690
|
+
"roles-and-permissions",
|
|
11691
|
+
"site-settings"
|
|
11692
|
+
]);
|
|
11693
|
+
var SPELLING_GROUPS = Object.freeze(
|
|
11694
|
+
[
|
|
11695
|
+
["work_orders", "workOrder", "work_order", "work-orders"],
|
|
11696
|
+
["visitor-mgmt", "visitorManagement"],
|
|
11697
|
+
["bulletin-board", "bulletin-board-mgmt"],
|
|
11698
|
+
["facility-booking-mgmt", "facility-booking"],
|
|
11699
|
+
["feedbacks", "feedback"],
|
|
11700
|
+
["building-mgmt", "buildingManagement"],
|
|
11701
|
+
["roles", "roles-and-permissions"],
|
|
11702
|
+
["service-provider-mgmt", "service-provider"],
|
|
11703
|
+
["online-form-configuration", "online-forms"]
|
|
11704
|
+
].map((group) => Object.freeze(group))
|
|
11705
|
+
);
|
|
11706
|
+
function moduleSpellings(key) {
|
|
11707
|
+
return SPELLING_GROUPS.find((group) => group.includes(key)) ?? [key];
|
|
11708
|
+
}
|
|
11682
11709
|
function orgAllowsModule(modules, resource) {
|
|
11683
11710
|
if (!Array.isArray(modules) || modules.length === 0)
|
|
11684
11711
|
return true;
|
|
11685
11712
|
const key = typeof resource === "string" ? resource.trim() : "";
|
|
11686
11713
|
if (!key)
|
|
11687
11714
|
return true;
|
|
11688
|
-
|
|
11715
|
+
if (ALWAYS_ALLOWED.includes(key))
|
|
11716
|
+
return true;
|
|
11717
|
+
return moduleSpellings(key).some((spelling) => modules.includes(spelling));
|
|
11689
11718
|
}
|
|
11690
11719
|
|
|
11691
11720
|
// src/models/site.model.ts
|
|
@@ -11712,7 +11741,15 @@ function rejectedSiteModules(orgModules, requested) {
|
|
|
11712
11741
|
if (!narrows(orgModules))
|
|
11713
11742
|
return [];
|
|
11714
11743
|
const org = normaliseModules(orgModules);
|
|
11715
|
-
return normaliseModules(requested).filter((key) => !org
|
|
11744
|
+
return normaliseModules(requested).filter((key) => !orgAllowsModule(org, key));
|
|
11745
|
+
}
|
|
11746
|
+
function keepStoredSiteModules(metadata, stored) {
|
|
11747
|
+
if (!metadata || typeof metadata !== "object" || Array.isArray(metadata)) {
|
|
11748
|
+
return metadata;
|
|
11749
|
+
}
|
|
11750
|
+
const { modules: _sent, ...rest } = metadata;
|
|
11751
|
+
const kept = stored && typeof stored === "object" && !Array.isArray(stored) ? stored.modules : void 0;
|
|
11752
|
+
return kept === void 0 ? rest : { ...rest, modules: kept };
|
|
11716
11753
|
}
|
|
11717
11754
|
function rejectedSiteModulesMessage(rejected) {
|
|
11718
11755
|
return `This organisation has not been given ${rejected.join(", ")}, so a site cannot offer it. Ask Seven365 to add it to the organisation first.`;
|
|
@@ -38536,8 +38573,8 @@ function useSiteController() {
|
|
|
38536
38573
|
}
|
|
38537
38574
|
const { _id, ...rest } = value;
|
|
38538
38575
|
await requireSiteWrite(req, _id);
|
|
38576
|
+
const existing = rest?.metadata ? await _getSiteById(_id) : null;
|
|
38539
38577
|
if (rest?.metadata?.residentAppModules) {
|
|
38540
|
-
const existing = await _getSiteById(_id);
|
|
38541
38578
|
const org = existing?.orgId ? await _getOrgById(existing.orgId.toString()).catch(
|
|
38542
38579
|
() => null
|
|
38543
38580
|
) : null;
|
|
@@ -38552,6 +38589,12 @@ function useSiteController() {
|
|
|
38552
38589
|
return;
|
|
38553
38590
|
}
|
|
38554
38591
|
}
|
|
38592
|
+
if (rest?.metadata) {
|
|
38593
|
+
rest.metadata = keepStoredSiteModules(
|
|
38594
|
+
rest.metadata,
|
|
38595
|
+
existing?.metadata
|
|
38596
|
+
);
|
|
38597
|
+
}
|
|
38555
38598
|
await _updateById(_id, rest);
|
|
38556
38599
|
res.json({ message: "Successfully updated site." });
|
|
38557
38600
|
return;
|
|
@@ -55505,7 +55548,6 @@ function UseAccessManagementRepo() {
|
|
|
55505
55548
|
const type = params.type;
|
|
55506
55549
|
const search = params.search;
|
|
55507
55550
|
const typeFilter = type.toLowerCase() === "all" ? [] : [{ $eq: ["$type", type] }];
|
|
55508
|
-
const userIdFilter = params.userId ? [{ $eq: ["$userId", new import_mongodb90.ObjectId(params.userId)] }] : [];
|
|
55509
55551
|
const searchFilter = search ? [
|
|
55510
55552
|
{
|
|
55511
55553
|
$or: [
|
|
@@ -55580,7 +55622,9 @@ function UseAccessManagementRepo() {
|
|
|
55580
55622
|
{ $eq: ["$isActivated", true] },
|
|
55581
55623
|
{ $eq: ["$userType", userType] },
|
|
55582
55624
|
...typeFilter,
|
|
55583
|
-
|
|
55625
|
+
// Cards actually held by a user only - a card sitting
|
|
55626
|
+
// unassigned on the unit (`userId: null`) is left out.
|
|
55627
|
+
{ $ne: ["$userId", null] }
|
|
55584
55628
|
]
|
|
55585
55629
|
},
|
|
55586
55630
|
...searchFilter[0]
|
|
@@ -70586,24 +70630,21 @@ function useAccessManagementController() {
|
|
|
70586
70630
|
unitId,
|
|
70587
70631
|
userType,
|
|
70588
70632
|
type,
|
|
70589
|
-
search = ""
|
|
70590
|
-
userId = ""
|
|
70633
|
+
search = ""
|
|
70591
70634
|
} = req.query;
|
|
70592
70635
|
const schema2 = import_joi101.default.object({
|
|
70593
70636
|
site: import_joi101.default.string().hex().required(),
|
|
70594
70637
|
unitId: import_joi101.default.string().hex().required(),
|
|
70595
70638
|
userType: import_joi101.default.string().required(),
|
|
70596
70639
|
type: import_joi101.default.string().valid("all", ...Object.values(EAccessCardTypes)).required(),
|
|
70597
|
-
search: import_joi101.default.string().optional().allow("", null)
|
|
70598
|
-
userId: import_joi101.default.string().hex().optional().allow("", null)
|
|
70640
|
+
search: import_joi101.default.string().optional().allow("", null)
|
|
70599
70641
|
});
|
|
70600
70642
|
const { error } = schema2.validate({
|
|
70601
70643
|
site,
|
|
70602
70644
|
unitId,
|
|
70603
70645
|
userType,
|
|
70604
70646
|
type,
|
|
70605
|
-
search
|
|
70606
|
-
userId
|
|
70647
|
+
search
|
|
70607
70648
|
});
|
|
70608
70649
|
if (error) {
|
|
70609
70650
|
return res.status(400).json({ message: error.message });
|
|
@@ -70615,8 +70656,7 @@ function useAccessManagementController() {
|
|
|
70615
70656
|
unitId,
|
|
70616
70657
|
userType,
|
|
70617
70658
|
type,
|
|
70618
|
-
search
|
|
70619
|
-
userId
|
|
70659
|
+
search
|
|
70620
70660
|
});
|
|
70621
70661
|
return res.status(200).json({ message: "Success", data: result });
|
|
70622
70662
|
} catch (error) {
|