@7365admin1/core 3.47.1-staging.145 → 3.47.1-staging.146
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/dist/index.d.ts +1 -0
- package/dist/index.js +84 -42
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +84 -42
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/test/e2e/harness.mjs +37 -0
- package/test/e2e/vehicle-scope.e2e.test.mjs +331 -0
package/dist/index.d.ts
CHANGED
|
@@ -2654,6 +2654,7 @@ declare function useVehicleRepo(): {
|
|
|
2654
2654
|
}>;
|
|
2655
2655
|
getSeasonPassTypes: (site: string | ObjectId) => Promise<bson.Document[]>;
|
|
2656
2656
|
getVehicleById: (_id: string | ObjectId) => Promise<bson.Document>;
|
|
2657
|
+
getVehicleSite: (_id: string | ObjectId) => Promise<mongodb.WithId<bson.Document> | null>;
|
|
2657
2658
|
updateVehicleById: (_id: string | ObjectId, value: TVehicleUpdate, session?: ClientSession) => Promise<number>;
|
|
2658
2659
|
deleteVehicle: (_id: string | ObjectId, session?: ClientSession) => Promise<number>;
|
|
2659
2660
|
getByPlaceNumber: (value: string) => Promise<mongodb.WithId<bson.Document>>;
|
package/dist/index.js
CHANGED
|
@@ -29008,7 +29008,10 @@ function useVehicleRepo() {
|
|
|
29008
29008
|
recNo: 1,
|
|
29009
29009
|
nric: 1,
|
|
29010
29010
|
status: 1,
|
|
29011
|
-
type: 1
|
|
29011
|
+
type: 1,
|
|
29012
|
+
// needed by the caller to drop rows on sites it cannot reach;
|
|
29013
|
+
// this lookup takes an NRIC and names no site of its own.
|
|
29014
|
+
site: 1
|
|
29012
29015
|
}
|
|
29013
29016
|
}
|
|
29014
29017
|
]).toArray();
|
|
@@ -29239,6 +29242,19 @@ function useVehicleRepo() {
|
|
|
29239
29242
|
throw error;
|
|
29240
29243
|
}
|
|
29241
29244
|
}
|
|
29245
|
+
async function getVehicleSite(_id) {
|
|
29246
|
+
let id;
|
|
29247
|
+
try {
|
|
29248
|
+
id = new import_mongodb60.ObjectId(_id);
|
|
29249
|
+
} catch (error) {
|
|
29250
|
+
throw new import_node_server_utils90.BadRequestError("Invalid vehicle ID format.");
|
|
29251
|
+
}
|
|
29252
|
+
const doc = await collection.findOne(
|
|
29253
|
+
{ _id: id },
|
|
29254
|
+
{ projection: { site: 1, org: 1 } }
|
|
29255
|
+
);
|
|
29256
|
+
return doc ?? null;
|
|
29257
|
+
}
|
|
29242
29258
|
return {
|
|
29243
29259
|
createIndex,
|
|
29244
29260
|
createTextIndex,
|
|
@@ -29246,6 +29262,7 @@ function useVehicleRepo() {
|
|
|
29246
29262
|
getVehicles,
|
|
29247
29263
|
getSeasonPassTypes,
|
|
29248
29264
|
getVehicleById,
|
|
29265
|
+
getVehicleSite,
|
|
29249
29266
|
updateVehicleById,
|
|
29250
29267
|
deleteVehicle,
|
|
29251
29268
|
getByPlaceNumber,
|
|
@@ -37327,6 +37344,38 @@ async function requireSiteReach(req, site) {
|
|
|
37327
37344
|
return;
|
|
37328
37345
|
await useCameraViewService().entitleSite({ siteId, userId: actor.id });
|
|
37329
37346
|
}
|
|
37347
|
+
async function siteReachOf(req) {
|
|
37348
|
+
const actor = await resolveInviteActor(callerId(req));
|
|
37349
|
+
const reachable = /* @__PURE__ */ new Map();
|
|
37350
|
+
function canReach(record) {
|
|
37351
|
+
if (actor.isSuperAdmin)
|
|
37352
|
+
return Promise.resolve(true);
|
|
37353
|
+
if (!record)
|
|
37354
|
+
return Promise.resolve(false);
|
|
37355
|
+
const site = record.site?.toString() ?? "";
|
|
37356
|
+
if (!site) {
|
|
37357
|
+
const org = record.org?.toString() ?? "";
|
|
37358
|
+
return Promise.resolve(Boolean(org) && actor.orgIds.includes(org));
|
|
37359
|
+
}
|
|
37360
|
+
if (!reachable.has(site)) {
|
|
37361
|
+
reachable.set(
|
|
37362
|
+
site,
|
|
37363
|
+
useCameraViewService().entitleSite({ siteId: site, userId: actor.id }).then(
|
|
37364
|
+
() => true,
|
|
37365
|
+
() => false
|
|
37366
|
+
)
|
|
37367
|
+
);
|
|
37368
|
+
}
|
|
37369
|
+
return reachable.get(site);
|
|
37370
|
+
}
|
|
37371
|
+
async function only(records) {
|
|
37372
|
+
if (actor.isSuperAdmin)
|
|
37373
|
+
return records;
|
|
37374
|
+
const verdicts = await Promise.all(records.map((r) => canReach(r)));
|
|
37375
|
+
return records.filter((_, i) => verdicts[i]);
|
|
37376
|
+
}
|
|
37377
|
+
return { actor, canReach, only };
|
|
37378
|
+
}
|
|
37330
37379
|
|
|
37331
37380
|
// src/controllers/building.controller.ts
|
|
37332
37381
|
var import_exceljs = __toESM(require("exceljs"));
|
|
@@ -38324,8 +38373,13 @@ function useVehicleController() {
|
|
|
38324
38373
|
getVehiclesByNRIC: _getVehiclesByNRIC,
|
|
38325
38374
|
getAllVehiclesByUnitId: _getAllVehiclesByUnitId,
|
|
38326
38375
|
getSpecificVehicleById: _getSpecificVehicleById,
|
|
38327
|
-
getBlocklistedVehicles: _getBlocklistedVehicles
|
|
38376
|
+
getBlocklistedVehicles: _getBlocklistedVehicles,
|
|
38377
|
+
getVehicleSite: _getVehicleSite
|
|
38328
38378
|
} = useVehicleRepo();
|
|
38379
|
+
async function requireVehicleReach(req, _id) {
|
|
38380
|
+
const vehicle = await _getVehicleSite(_id);
|
|
38381
|
+
await requireSiteReach(req, vehicle?.site);
|
|
38382
|
+
}
|
|
38329
38383
|
function normalizeRow(row) {
|
|
38330
38384
|
return Object.fromEntries(
|
|
38331
38385
|
Object.entries(row).map(([key, value]) => [
|
|
@@ -38518,6 +38572,7 @@ function useVehicleController() {
|
|
|
38518
38572
|
return;
|
|
38519
38573
|
}
|
|
38520
38574
|
try {
|
|
38575
|
+
await requireSiteReach(req, value.site);
|
|
38521
38576
|
const user = req.user?.user || req.user?._id;
|
|
38522
38577
|
const data = await _add(value, void 0, user);
|
|
38523
38578
|
res.status(201).json({
|
|
@@ -38561,6 +38616,8 @@ function useVehicleController() {
|
|
|
38561
38616
|
};
|
|
38562
38617
|
}
|
|
38563
38618
|
try {
|
|
38619
|
+
if (site)
|
|
38620
|
+
await requireSiteReach(req, site);
|
|
38564
38621
|
const data = await _getVehicles({
|
|
38565
38622
|
search,
|
|
38566
38623
|
page,
|
|
@@ -38595,6 +38652,7 @@ function useVehicleController() {
|
|
|
38595
38652
|
}
|
|
38596
38653
|
const { site } = value;
|
|
38597
38654
|
try {
|
|
38655
|
+
await requireSiteReach(req, site);
|
|
38598
38656
|
const data = await _getSeasonPassTypes(site);
|
|
38599
38657
|
res.json(data);
|
|
38600
38658
|
return;
|
|
@@ -38620,6 +38678,7 @@ function useVehicleController() {
|
|
|
38620
38678
|
}
|
|
38621
38679
|
const { _id } = value;
|
|
38622
38680
|
try {
|
|
38681
|
+
await requireVehicleReach(req, _id);
|
|
38623
38682
|
const site = await _getVehicleById(_id);
|
|
38624
38683
|
res.json(site);
|
|
38625
38684
|
return;
|
|
@@ -38645,6 +38704,7 @@ function useVehicleController() {
|
|
|
38645
38704
|
}
|
|
38646
38705
|
const { _id } = value;
|
|
38647
38706
|
try {
|
|
38707
|
+
await requireVehicleReach(req, _id);
|
|
38648
38708
|
const site = await _getSpecificVehicleById(_id);
|
|
38649
38709
|
res.json(site);
|
|
38650
38710
|
return;
|
|
@@ -38688,12 +38748,15 @@ function useVehicleController() {
|
|
|
38688
38748
|
return;
|
|
38689
38749
|
}
|
|
38690
38750
|
const { _id, ...rest } = value;
|
|
38751
|
+
await requireVehicleReach(req, _id);
|
|
38691
38752
|
await _updateVehicleById(_id, rest);
|
|
38692
38753
|
res.json({ message: "Successfully updated vehicle." });
|
|
38693
38754
|
return;
|
|
38694
38755
|
} catch (error) {
|
|
38695
38756
|
import_node_server_utils112.logger.log({ level: "error", message: error.message });
|
|
38696
|
-
if (error?.
|
|
38757
|
+
if (error?.statusCode) {
|
|
38758
|
+
next(error);
|
|
38759
|
+
} else if (error?.message) {
|
|
38697
38760
|
next(new import_node_server_utils112.BadRequestError(error?.message));
|
|
38698
38761
|
} else {
|
|
38699
38762
|
next(error);
|
|
@@ -38721,6 +38784,7 @@ function useVehicleController() {
|
|
|
38721
38784
|
}
|
|
38722
38785
|
const { recno, site, type, bypass, _id } = value;
|
|
38723
38786
|
try {
|
|
38787
|
+
await requireVehicleReach(req, _id);
|
|
38724
38788
|
const data = await _deleteVehicle(_id, recno, site, type, bypass);
|
|
38725
38789
|
res.json({
|
|
38726
38790
|
message: "Vehicle deleted successfully.",
|
|
@@ -38748,6 +38812,7 @@ function useVehicleController() {
|
|
|
38748
38812
|
return;
|
|
38749
38813
|
}
|
|
38750
38814
|
const { _id, org, site } = value;
|
|
38815
|
+
await requireVehicleReach(req, _id);
|
|
38751
38816
|
await _approveVehicleById(_id, org, site);
|
|
38752
38817
|
res.json({ message: "Successfully approved and updated vehicle." });
|
|
38753
38818
|
return;
|
|
@@ -38793,6 +38858,8 @@ function useVehicleController() {
|
|
|
38793
38858
|
limit,
|
|
38794
38859
|
sort: sortObj
|
|
38795
38860
|
});
|
|
38861
|
+
const { only } = await siteReachOf(req);
|
|
38862
|
+
data.items = await only(data.items ?? []);
|
|
38796
38863
|
res.json(data);
|
|
38797
38864
|
return;
|
|
38798
38865
|
} catch (error2) {
|
|
@@ -38818,6 +38885,7 @@ function useVehicleController() {
|
|
|
38818
38885
|
}
|
|
38819
38886
|
const { _id, org, site } = value;
|
|
38820
38887
|
try {
|
|
38888
|
+
await requireVehicleReach(req, _id);
|
|
38821
38889
|
const data = await _reactivateVehicleById(_id, org, site);
|
|
38822
38890
|
res.status(200).json({
|
|
38823
38891
|
message: data
|
|
@@ -38859,6 +38927,8 @@ function useVehicleController() {
|
|
|
38859
38927
|
limit,
|
|
38860
38928
|
sort: sortObj
|
|
38861
38929
|
});
|
|
38930
|
+
const { only } = await siteReachOf(req);
|
|
38931
|
+
data.items = await only(data.items ?? []);
|
|
38862
38932
|
res.json(data);
|
|
38863
38933
|
return;
|
|
38864
38934
|
} catch (error2) {
|
|
@@ -38885,6 +38955,8 @@ function useVehicleController() {
|
|
|
38885
38955
|
}
|
|
38886
38956
|
const { search, page, limit, site } = value;
|
|
38887
38957
|
try {
|
|
38958
|
+
if (site)
|
|
38959
|
+
await requireSiteReach(req, site);
|
|
38888
38960
|
const data = await _getBlocklistedVehicles({
|
|
38889
38961
|
search,
|
|
38890
38962
|
page,
|
|
@@ -38921,6 +38993,7 @@ function useVehicleController() {
|
|
|
38921
38993
|
return;
|
|
38922
38994
|
}
|
|
38923
38995
|
const { _id, ...rest } = value;
|
|
38996
|
+
await requireVehicleReach(req, _id);
|
|
38924
38997
|
await _blocklistVehicles(_id, rest);
|
|
38925
38998
|
res.json({ message: "Successfully blocked vehicle." });
|
|
38926
38999
|
return;
|
|
@@ -38952,6 +39025,7 @@ function useVehicleController() {
|
|
|
38952
39025
|
return;
|
|
38953
39026
|
}
|
|
38954
39027
|
const { _id, ...rest } = value;
|
|
39028
|
+
await requireVehicleReach(req, _id);
|
|
38955
39029
|
await _removeFromBlocklist(_id, rest);
|
|
38956
39030
|
res.json({ message: "Successfully removed vehicle from blocklist." });
|
|
38957
39031
|
return;
|
|
@@ -50370,38 +50444,6 @@ function usePersonController() {
|
|
|
50370
50444
|
}
|
|
50371
50445
|
return actor;
|
|
50372
50446
|
}
|
|
50373
|
-
async function siteReach(req) {
|
|
50374
|
-
const actor = await resolveInviteActor(callerId(req));
|
|
50375
|
-
const reachable = /* @__PURE__ */ new Map();
|
|
50376
|
-
function canReach(person) {
|
|
50377
|
-
if (actor.isSuperAdmin)
|
|
50378
|
-
return Promise.resolve(true);
|
|
50379
|
-
if (!person)
|
|
50380
|
-
return Promise.resolve(false);
|
|
50381
|
-
const site = person.site?.toString() ?? "";
|
|
50382
|
-
if (!site) {
|
|
50383
|
-
const org = person.org?.toString() ?? "";
|
|
50384
|
-
return Promise.resolve(Boolean(org) && actor.orgIds.includes(org));
|
|
50385
|
-
}
|
|
50386
|
-
if (!reachable.has(site)) {
|
|
50387
|
-
reachable.set(
|
|
50388
|
-
site,
|
|
50389
|
-
useCameraViewService().entitleSite({ siteId: site, userId: actor.id }).then(
|
|
50390
|
-
() => true,
|
|
50391
|
-
() => false
|
|
50392
|
-
)
|
|
50393
|
-
);
|
|
50394
|
-
}
|
|
50395
|
-
return reachable.get(site);
|
|
50396
|
-
}
|
|
50397
|
-
async function only(people) {
|
|
50398
|
-
if (actor.isSuperAdmin)
|
|
50399
|
-
return people;
|
|
50400
|
-
const verdicts = await Promise.all(people.map((p) => canReach(p)));
|
|
50401
|
-
return people.filter((_, i) => verdicts[i]);
|
|
50402
|
-
}
|
|
50403
|
-
return { actor, canReach, only };
|
|
50404
|
-
}
|
|
50405
50447
|
async function add(req, res, next) {
|
|
50406
50448
|
const payload = { ...req.body };
|
|
50407
50449
|
const { error } = schemaPerson.validate(payload, {
|
|
@@ -50576,7 +50618,7 @@ function usePersonController() {
|
|
|
50576
50618
|
}
|
|
50577
50619
|
try {
|
|
50578
50620
|
const data = await _getByNRIC(nric);
|
|
50579
|
-
const { canReach } = await
|
|
50621
|
+
const { canReach } = await siteReachOf(req);
|
|
50580
50622
|
res.json(await canReach(data) ? data : null);
|
|
50581
50623
|
return;
|
|
50582
50624
|
} catch (error2) {
|
|
@@ -50596,7 +50638,7 @@ function usePersonController() {
|
|
|
50596
50638
|
}
|
|
50597
50639
|
try {
|
|
50598
50640
|
const data = await _getPersonByPhoneNumber(contact);
|
|
50599
|
-
const { canReach } = await
|
|
50641
|
+
const { canReach } = await siteReachOf(req);
|
|
50600
50642
|
res.json(await canReach(data) ? data : null);
|
|
50601
50643
|
return;
|
|
50602
50644
|
} catch (error2) {
|
|
@@ -50641,7 +50683,7 @@ function usePersonController() {
|
|
|
50641
50683
|
type,
|
|
50642
50684
|
unit
|
|
50643
50685
|
});
|
|
50644
|
-
const { only } = await
|
|
50686
|
+
const { only } = await siteReachOf(req);
|
|
50645
50687
|
res.json(await only(data));
|
|
50646
50688
|
return;
|
|
50647
50689
|
} catch (error) {
|
|
@@ -50662,7 +50704,7 @@ function usePersonController() {
|
|
|
50662
50704
|
}
|
|
50663
50705
|
const { search } = value;
|
|
50664
50706
|
try {
|
|
50665
|
-
const { actor } = await
|
|
50707
|
+
const { actor } = await siteReachOf(req);
|
|
50666
50708
|
const data = await _getCompany(
|
|
50667
50709
|
search,
|
|
50668
50710
|
actor.isSuperAdmin ? void 0 : actor.orgIds
|
|
@@ -50686,7 +50728,7 @@ function usePersonController() {
|
|
|
50686
50728
|
}
|
|
50687
50729
|
try {
|
|
50688
50730
|
const data = await _getPeopleByPlateNumber(plateNumber);
|
|
50689
|
-
const { only } = await
|
|
50731
|
+
const { only } = await siteReachOf(req);
|
|
50690
50732
|
res.json({ data: await only(data) });
|
|
50691
50733
|
return;
|
|
50692
50734
|
} catch (error2) {
|
|
@@ -50727,7 +50769,7 @@ function usePersonController() {
|
|
|
50727
50769
|
}
|
|
50728
50770
|
});
|
|
50729
50771
|
try {
|
|
50730
|
-
const { actor } = await
|
|
50772
|
+
const { actor } = await siteReachOf(req);
|
|
50731
50773
|
if (!actor.isSuperAdmin) {
|
|
50732
50774
|
await useCameraViewService().entitleSite({ siteId: site, userId: actor.id });
|
|
50733
50775
|
}
|
|
@@ -50757,7 +50799,7 @@ function usePersonController() {
|
|
|
50757
50799
|
}
|
|
50758
50800
|
try {
|
|
50759
50801
|
const data = await _getByUserId(userId);
|
|
50760
|
-
const { actor, canReach } = await
|
|
50802
|
+
const { actor, canReach } = await siteReachOf(req);
|
|
50761
50803
|
const isSelf = Boolean(actor.id) && data?.user?.toString() === actor.id;
|
|
50762
50804
|
res.json(isSelf || await canReach(data) ? data : null);
|
|
50763
50805
|
return;
|