@7365admin1/core 3.62.1-staging.280 → 3.62.1-staging.282
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/customer-sites-one-row-per-site.md +19 -0
- package/.changeset/role-v2-platform-grant.md +14 -0
- package/dist/index.js +18 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +18 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/test/customer-sites-one-row-per-site.test.mjs +107 -0
- package/test/role-scope.test.mjs +26 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
"@7365admin1/core": patch
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Return one row per site from `/api/customer-sites`, named by the site.
|
|
6
|
+
|
|
7
|
+
`getAll` grouped by `{ name, site }`. A customer-sites row is an ENGAGEMENT and
|
|
8
|
+
one site can carry more than one, so two rows for the same site with different
|
|
9
|
+
names both survived as "distinct" — a provider's site list showed four entries
|
|
10
|
+
for three sites, and the site switcher ticked two at once.
|
|
11
|
+
|
|
12
|
+
`name` is also a snapshot from when the engagement was created and goes stale
|
|
13
|
+
when the site is renamed; recency is no guide, since the newer row held the
|
|
14
|
+
staler name. The site is now looked up and its live name projected over the
|
|
15
|
+
snapshot, with the stored name kept as a fallback.
|
|
16
|
+
|
|
17
|
+
The search and the sort both run after the rename, so a site is found and
|
|
18
|
+
ordered by the name it actually has, and the count is derived from the same
|
|
19
|
+
pipeline.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
"@7365admin1/core": patch
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Stop `/api/roles/v2` minting a role that holds the console's own resources.
|
|
6
|
+
|
|
7
|
+
`role.controller createRole` has carried `requireNoPlatformGrant` for a while;
|
|
8
|
+
`role-v2.controller createRole` did not. It is a separate controller behind a
|
|
9
|
+
separate route and accepts any permission string, so the hole was reachable by
|
|
10
|
+
adding `/v2` to the URL.
|
|
11
|
+
|
|
12
|
+
Measured on production before adding: no site-scoped role holds a platform-only
|
|
13
|
+
string, and this mount requires a `site`, so the check refuses nothing that
|
|
14
|
+
exists today. It only ever refuses a NEW grant regardless.
|
package/dist/index.js
CHANGED
|
@@ -14147,7 +14147,6 @@ function useCustomerSiteRepo() {
|
|
|
14147
14147
|
cacheOptions.siteScope = scoped.length ? [...scoped].sort().join(",") : "no-site";
|
|
14148
14148
|
}
|
|
14149
14149
|
if (search) {
|
|
14150
|
-
query2.$or = [{ name: { $regex: search, $options: "i" } }];
|
|
14151
14150
|
cacheOptions.search = search;
|
|
14152
14151
|
}
|
|
14153
14152
|
const cacheKey = (0, import_node_server_utils26.makeCacheKey)(namespace_collection2, cacheOptions);
|
|
@@ -14160,8 +14159,20 @@ function useCustomerSiteRepo() {
|
|
|
14160
14159
|
const distinctPipeline = [
|
|
14161
14160
|
{ $match: query2 },
|
|
14162
14161
|
{ $sort: sort },
|
|
14163
|
-
{ $group: { _id:
|
|
14162
|
+
{ $group: { _id: "$site", doc: { $first: "$$ROOT" } } },
|
|
14164
14163
|
{ $replaceRoot: { newRoot: "$doc" } },
|
|
14164
|
+
{
|
|
14165
|
+
$lookup: {
|
|
14166
|
+
from: "sites",
|
|
14167
|
+
localField: "site",
|
|
14168
|
+
foreignField: "_id",
|
|
14169
|
+
as: "_liveSite"
|
|
14170
|
+
}
|
|
14171
|
+
},
|
|
14172
|
+
{ $unwind: { path: "$_liveSite", preserveNullAndEmptyArrays: true } },
|
|
14173
|
+
{ $set: { name: { $ifNull: ["$_liveSite.name", "$name"] } } },
|
|
14174
|
+
{ $unset: "_liveSite" },
|
|
14175
|
+
...search ? [{ $match: { name: { $regex: search, $options: "i" } } }] : [],
|
|
14165
14176
|
{ $sort: sort }
|
|
14166
14177
|
];
|
|
14167
14178
|
const items = await collection.aggregate(
|
|
@@ -14172,14 +14183,7 @@ function useCustomerSiteRepo() {
|
|
|
14172
14183
|
],
|
|
14173
14184
|
{ session }
|
|
14174
14185
|
).toArray();
|
|
14175
|
-
const countResult = await collection.aggregate(
|
|
14176
|
-
[
|
|
14177
|
-
{ $match: query2 },
|
|
14178
|
-
{ $group: { _id: { name: "$name", site: "$site" } } },
|
|
14179
|
-
{ $count: "total" }
|
|
14180
|
-
],
|
|
14181
|
-
{ session }
|
|
14182
|
-
).toArray();
|
|
14186
|
+
const countResult = await collection.aggregate([...distinctPipeline, { $count: "total" }], { session }).toArray();
|
|
14183
14187
|
const length = countResult[0]?.total ?? 0;
|
|
14184
14188
|
const data = (0, import_node_server_utils26.paginate)(items, page, limit, length);
|
|
14185
14189
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
@@ -88940,6 +88944,10 @@ function useRoleControllerV2() {
|
|
|
88940
88944
|
if (value.org) {
|
|
88941
88945
|
await requireOrgReach(req, value.org);
|
|
88942
88946
|
}
|
|
88947
|
+
requireNoPlatformGrant(
|
|
88948
|
+
{ type: value.type, org: value.org, permissions: [] },
|
|
88949
|
+
value.permissions
|
|
88950
|
+
);
|
|
88943
88951
|
requireWithinModules(
|
|
88944
88952
|
await moduleCeiling(value.org, value.site),
|
|
88945
88953
|
value.permissions
|