@7365admin1/core 3.52.11-staging.259 → 3.52.12-staging.260
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/building-estate-site-scope.md +17 -0
- package/CHANGELOG.md +6 -0
- package/dist/index.d.ts +9 -6
- package/dist/index.js +64 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +64 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/test/building-estate-site-scope.test.mjs +157 -0
- package/.changeset/visitor-document-site-scope.md +0 -5
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
"@7365admin1/core": patch
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Scope the building, unit and level lists to the caller's own sites
|
|
6
|
+
|
|
7
|
+
`GET /api/buildings`, `GET /api/building-units` and `GET /api/building-levels`
|
|
8
|
+
took an optional `site` and applied it as a plain filter, so a request that
|
|
9
|
+
named none was answered from the whole collection — every client's estate. An
|
|
10
|
+
explicit site was never authorised either. `GET /api/building-units/site/:site`,
|
|
11
|
+
which returns units together with their owners, took the site from the URL and
|
|
12
|
+
checked nothing.
|
|
13
|
+
|
|
14
|
+
All four now use the same rule the vehicle, visitor, document and camera lists
|
|
15
|
+
use: an explicit site goes through `requireSiteReach`, and no site falls back to
|
|
16
|
+
`entitledSites`. The restriction is part of the Redis cache key as well as the
|
|
17
|
+
query, so one caller's page is not served to another.
|
package/CHANGELOG.md
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -2379,13 +2379,14 @@ declare const buildings_namespace_collection = "buildings";
|
|
|
2379
2379
|
declare function useBuildingRepo(): {
|
|
2380
2380
|
createIndexes: () => Promise<void>;
|
|
2381
2381
|
add: (value: TBuilding, session?: ClientSession) => Promise<ObjectId>;
|
|
2382
|
-
getAll: ({ search, page, limit, sort, site, status, }?: {
|
|
2382
|
+
getAll: ({ search, page, limit, sort, site, status, siteScope, }?: {
|
|
2383
2383
|
search?: string | undefined;
|
|
2384
2384
|
page?: number | undefined;
|
|
2385
2385
|
limit?: number | undefined;
|
|
2386
|
-
sort?:
|
|
2386
|
+
sort?: Record<string, any> | undefined;
|
|
2387
2387
|
site?: string | undefined;
|
|
2388
2388
|
status?: BuildingStatus | undefined;
|
|
2389
|
+
siteScope?: string[] | null | undefined;
|
|
2389
2390
|
}) => Promise<Record<string, any>>;
|
|
2390
2391
|
getAllBuildingForResident: ({ search, page, limit, sort, site, status, }?: {
|
|
2391
2392
|
search?: string | undefined;
|
|
@@ -2454,14 +2455,15 @@ declare const building_units_namespace_collection = "building-units";
|
|
|
2454
2455
|
declare function useBuildingUnitRepo(): {
|
|
2455
2456
|
createIndexes: () => Promise<void>;
|
|
2456
2457
|
add: (value: TBuildingUnit, session?: ClientSession) => Promise<ObjectId>;
|
|
2457
|
-
getAll: ({ search, page, limit, sort, site, building, status, }?: {
|
|
2458
|
+
getAll: ({ search, page, limit, sort, site, building, status, siteScope, }?: {
|
|
2458
2459
|
search?: string | undefined;
|
|
2459
2460
|
page?: number | undefined;
|
|
2460
2461
|
limit?: number | undefined;
|
|
2461
|
-
sort?:
|
|
2462
|
+
sort?: Record<string, any> | undefined;
|
|
2462
2463
|
site?: string | undefined;
|
|
2463
2464
|
building?: string | undefined;
|
|
2464
2465
|
status?: string | undefined;
|
|
2466
|
+
siteScope?: string[] | null | undefined;
|
|
2465
2467
|
}) => Promise<Record<string, any>>;
|
|
2466
2468
|
getById: (_id: string | ObjectId, session?: ClientSession) => Promise<TBuildingUnit>;
|
|
2467
2469
|
getByBuildingLevel: (building: string | ObjectId, level: string) => Promise<TBuildingUnit | null>;
|
|
@@ -11331,13 +11333,14 @@ declare const building_level_namespace_collection = "building-levels";
|
|
|
11331
11333
|
declare function useBuildingLevelRepo(): {
|
|
11332
11334
|
createIndexes: () => Promise<void>;
|
|
11333
11335
|
add: (value: TBuildingLevel, session?: ClientSession) => Promise<ObjectId>;
|
|
11334
|
-
getAll: ({ search, page, limit, sort, site, status, }?: {
|
|
11336
|
+
getAll: ({ search, page, limit, sort, site, status, siteScope, }?: {
|
|
11335
11337
|
search?: string | undefined;
|
|
11336
11338
|
page?: number | undefined;
|
|
11337
11339
|
limit?: number | undefined;
|
|
11338
|
-
sort?:
|
|
11340
|
+
sort?: Record<string, any> | undefined;
|
|
11339
11341
|
site?: string | undefined;
|
|
11340
11342
|
status?: string | undefined;
|
|
11343
|
+
siteScope?: string[] | null | undefined;
|
|
11341
11344
|
}) => Promise<Record<string, any>>;
|
|
11342
11345
|
getById: (_id: string | ObjectId, session?: ClientSession) => Promise<TBuildingLevel>;
|
|
11343
11346
|
updateLevelById: (_id: string | ObjectId, value: TBuildingLevel, session?: ClientSession) => Promise<mongodb.UpdateResult<bson.Document>>;
|
package/dist/index.js
CHANGED
|
@@ -34878,7 +34878,17 @@ function useBuildingUnitRepo() {
|
|
|
34878
34878
|
sort = {},
|
|
34879
34879
|
site = "",
|
|
34880
34880
|
building = "",
|
|
34881
|
-
status = "active"
|
|
34881
|
+
status = "active",
|
|
34882
|
+
/**
|
|
34883
|
+
* The sites this caller may be shown, or `null` for no restriction. Set only
|
|
34884
|
+
* when the request named NO site — see `entitledSites`. Applied inside the
|
|
34885
|
+
* query so the page counts describe what the caller can actually see, and
|
|
34886
|
+
* folded into the cache key so one caller's page is never served to another.
|
|
34887
|
+
*
|
|
34888
|
+
* An EMPTY array means "this caller reaches no site" and must still be
|
|
34889
|
+
* applied: `$in: []` matches nothing, which is the fail-closed answer.
|
|
34890
|
+
*/
|
|
34891
|
+
siteScope = null
|
|
34882
34892
|
} = {}) {
|
|
34883
34893
|
page = page > 0 ? page - 1 : 0;
|
|
34884
34894
|
const searchText = search.trim();
|
|
@@ -34903,6 +34913,11 @@ function useBuildingUnitRepo() {
|
|
|
34903
34913
|
building_units_namespace_collection,
|
|
34904
34914
|
cacheParams
|
|
34905
34915
|
);
|
|
34916
|
+
if (siteScope) {
|
|
34917
|
+
const scoped = siteScope.filter((id) => import_mongodb67.ObjectId.isValid(id));
|
|
34918
|
+
query2.site = { $in: scoped.map((id) => new import_mongodb67.ObjectId(id)) };
|
|
34919
|
+
cacheParams.siteScope = scoped.length ? [...scoped].sort().join(",") : "no-site";
|
|
34920
|
+
}
|
|
34906
34921
|
import_node_server_utils98.logger.log({
|
|
34907
34922
|
level: "info",
|
|
34908
34923
|
message: `Cache key for getAll building units: ${cacheKey}`
|
|
@@ -37682,7 +37697,17 @@ function useBuildingRepo() {
|
|
|
37682
37697
|
limit = 10,
|
|
37683
37698
|
sort = {},
|
|
37684
37699
|
site = "",
|
|
37685
|
-
status = "active" /* ACTIVE
|
|
37700
|
+
status = "active" /* ACTIVE */,
|
|
37701
|
+
/**
|
|
37702
|
+
* The sites this caller may be shown, or `null` for no restriction. Set only
|
|
37703
|
+
* when the request named NO site — see `entitledSites`. Applied inside the
|
|
37704
|
+
* query so the page counts describe what the caller can actually see, and
|
|
37705
|
+
* folded into the cache key so one caller's page is never served to another.
|
|
37706
|
+
*
|
|
37707
|
+
* An EMPTY array means "this caller reaches no site" and must still be
|
|
37708
|
+
* applied: `$in: []` matches nothing, which is the fail-closed answer.
|
|
37709
|
+
*/
|
|
37710
|
+
siteScope = null
|
|
37686
37711
|
} = {}) {
|
|
37687
37712
|
page = page > 0 ? page - 1 : 0;
|
|
37688
37713
|
let siteId;
|
|
@@ -37716,6 +37741,11 @@ function useBuildingRepo() {
|
|
|
37716
37741
|
...status && { status }
|
|
37717
37742
|
};
|
|
37718
37743
|
const cacheKey = (0, import_node_server_utils105.makeCacheKey)(buildings_namespace_collection, cacheParams);
|
|
37744
|
+
if (siteScope) {
|
|
37745
|
+
const scoped = siteScope.filter((id) => import_mongodb70.ObjectId.isValid(id));
|
|
37746
|
+
query2.site = { $in: scoped.map((id) => new import_mongodb70.ObjectId(id)) };
|
|
37747
|
+
cacheParams.siteScope = scoped.length ? [...scoped].sort().join(",") : "no-site";
|
|
37748
|
+
}
|
|
37719
37749
|
import_node_server_utils105.logger.log({
|
|
37720
37750
|
level: "info",
|
|
37721
37751
|
message: `Cache key for getAll buildings: ${cacheKey}`
|
|
@@ -38375,7 +38405,17 @@ function useBuildingLevelRepo() {
|
|
|
38375
38405
|
limit = 10,
|
|
38376
38406
|
sort = {},
|
|
38377
38407
|
site = "",
|
|
38378
|
-
status = "active"
|
|
38408
|
+
status = "active",
|
|
38409
|
+
/**
|
|
38410
|
+
* The sites this caller may be shown, or `null` for no restriction. Set only
|
|
38411
|
+
* when the request named NO site — see `entitledSites`. Applied inside the
|
|
38412
|
+
* query so the page counts describe what the caller can actually see, and
|
|
38413
|
+
* folded into the cache key so one caller's page is never served to another.
|
|
38414
|
+
*
|
|
38415
|
+
* An EMPTY array means "this caller reaches no site" and must still be
|
|
38416
|
+
* applied: `$in: []` matches nothing, which is the fail-closed answer.
|
|
38417
|
+
*/
|
|
38418
|
+
siteScope = null
|
|
38379
38419
|
} = {}) {
|
|
38380
38420
|
page = page > 0 ? page - 1 : 0;
|
|
38381
38421
|
const query2 = {
|
|
@@ -38395,6 +38435,11 @@ function useBuildingLevelRepo() {
|
|
|
38395
38435
|
building_level_namespace_collection,
|
|
38396
38436
|
cacheParams
|
|
38397
38437
|
);
|
|
38438
|
+
if (siteScope) {
|
|
38439
|
+
const scoped = siteScope.filter((id) => import_mongodb72.ObjectId.isValid(id));
|
|
38440
|
+
query2.site = { $in: scoped.map((id) => new import_mongodb72.ObjectId(id)) };
|
|
38441
|
+
cacheParams.siteScope = scoped.length ? [...scoped].sort().join(",") : "no-site";
|
|
38442
|
+
}
|
|
38398
38443
|
import_node_server_utils108.logger.log({
|
|
38399
38444
|
level: "info",
|
|
38400
38445
|
message: `Cache key for getAll building levels: ${cacheKey}`
|
|
@@ -39372,13 +39417,17 @@ function useBuildingController() {
|
|
|
39372
39417
|
const search = value.search ?? "";
|
|
39373
39418
|
const sortObj = sort ? { [sort]: order === "asc" /* ASC */ ? 1 : -1 } : {};
|
|
39374
39419
|
try {
|
|
39420
|
+
const siteScope = site ? null : await entitledSites(req);
|
|
39421
|
+
if (site)
|
|
39422
|
+
await requireSiteReach(req, site);
|
|
39375
39423
|
const buildings = await _getAll({
|
|
39376
39424
|
page,
|
|
39377
39425
|
limit,
|
|
39378
39426
|
sort: sortObj,
|
|
39379
39427
|
status,
|
|
39380
39428
|
site,
|
|
39381
|
-
search
|
|
39429
|
+
search,
|
|
39430
|
+
siteScope
|
|
39382
39431
|
});
|
|
39383
39432
|
res.json(buildings);
|
|
39384
39433
|
return;
|
|
@@ -40010,6 +40059,9 @@ function useBuildingUnitController() {
|
|
|
40010
40059
|
const site = value.site;
|
|
40011
40060
|
const building = value.building;
|
|
40012
40061
|
const search = value.search;
|
|
40062
|
+
const siteScope = site ? null : await entitledSites(req);
|
|
40063
|
+
if (site)
|
|
40064
|
+
await requireSiteReach(req, site);
|
|
40013
40065
|
const buildings = await _getAll({
|
|
40014
40066
|
page,
|
|
40015
40067
|
limit,
|
|
@@ -40017,7 +40069,8 @@ function useBuildingUnitController() {
|
|
|
40017
40069
|
status,
|
|
40018
40070
|
site,
|
|
40019
40071
|
search,
|
|
40020
|
-
building
|
|
40072
|
+
building,
|
|
40073
|
+
siteScope
|
|
40021
40074
|
});
|
|
40022
40075
|
res.json(buildings);
|
|
40023
40076
|
return;
|
|
@@ -40131,6 +40184,7 @@ function useBuildingUnitController() {
|
|
|
40131
40184
|
}
|
|
40132
40185
|
const site = req.params.site;
|
|
40133
40186
|
try {
|
|
40187
|
+
await requireSiteReach(req, site);
|
|
40134
40188
|
const data = await _getBuildingUnitsWithOwner(site);
|
|
40135
40189
|
res.json(data);
|
|
40136
40190
|
return;
|
|
@@ -89908,12 +89962,16 @@ function useBuildingLevelController() {
|
|
|
89908
89962
|
return;
|
|
89909
89963
|
}
|
|
89910
89964
|
const { page, limit, status, site, search } = value;
|
|
89965
|
+
const siteScope = site ? null : await entitledSites(req);
|
|
89966
|
+
if (site)
|
|
89967
|
+
await requireSiteReach(req, site);
|
|
89911
89968
|
const result = await _getAll({
|
|
89912
89969
|
page,
|
|
89913
89970
|
limit,
|
|
89914
89971
|
status,
|
|
89915
89972
|
site,
|
|
89916
|
-
search
|
|
89973
|
+
search,
|
|
89974
|
+
siteScope
|
|
89917
89975
|
});
|
|
89918
89976
|
res.json(result);
|
|
89919
89977
|
return;
|