@7365admin1/core 3.48.1-staging.176 → 3.48.1-staging.177
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/visitor-guest-scope.md +12 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +23 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +23 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/test/e2e/harness.mjs +13 -0
- package/test/e2e/visitor-guest-scope.e2e.test.mjs +420 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
"@7365admin1/core": patch
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Scope the visitor guest routes to the estate
|
|
6
|
+
|
|
7
|
+
`/api/visitor-guests` carried `requireAuth` and nothing more on all four
|
|
8
|
+
routes, so any signed-in account could add, read, edit or delete another
|
|
9
|
+
estate's expected-visitor list. `site` was optional on the list query and the
|
|
10
|
+
repository only applies it when valid, so omitting it returned every estate's
|
|
11
|
+
visitor records at once. All four handlers now ask the existing site-reach
|
|
12
|
+
rule, and `site` is required on the list query.
|
package/dist/index.d.ts
CHANGED
|
@@ -4693,6 +4693,7 @@ declare function useGuestManagementRepo(): {
|
|
|
4693
4693
|
org?: string | undefined;
|
|
4694
4694
|
site?: string | undefined;
|
|
4695
4695
|
}, session?: ClientSession) => Promise<{}>;
|
|
4696
|
+
getById: (_id: string | ObjectId, session?: ClientSession) => Promise<mongodb.WithId<bson.Document> | null>;
|
|
4696
4697
|
updateVisitorGuestById: (_id: string | ObjectId, value: Partial<TGuestManagement>, session?: ClientSession) => Promise<mongodb.UpdateResult<bson.Document>>;
|
|
4697
4698
|
deleteVisitorGuest: (_id: string | ObjectId) => Promise<number>;
|
|
4698
4699
|
createTextIndex: () => Promise<void>;
|
|
@@ -4703,6 +4704,25 @@ declare function useGuestManagementService(): {
|
|
|
4703
4704
|
updateVisitorGuestById: (id: string | ObjectId, value: TGuestManagement) => Promise<string>;
|
|
4704
4705
|
};
|
|
4705
4706
|
|
|
4707
|
+
/**
|
|
4708
|
+
* A visitor guest is a named person an estate expects at its gate: name,
|
|
4709
|
+
* contact, NRIC, vehicle plate, and the block/level/unit they are visiting.
|
|
4710
|
+
*
|
|
4711
|
+
* All four routes carried `requireAuth` and nothing more, and this controller
|
|
4712
|
+
* held no authorization identifier of any kind. `site` and `org` were read
|
|
4713
|
+
* straight off the caller — the body on `POST`, the query on `GET` — and never
|
|
4714
|
+
* compared to anything, and `PUT`/`DELETE` reached the row by id alone. Being
|
|
4715
|
+
* signed in ANYWHERE on the platform was therefore enough to read, edit or
|
|
4716
|
+
* delete any estate's guest list.
|
|
4717
|
+
*
|
|
4718
|
+
* The `GET` was the worst of the four: `site` and `org` were OPTIONAL, and the
|
|
4719
|
+
* repository only applies them `ObjectId.isValid(...)`. Omitting both left the
|
|
4720
|
+
* `$match` with no tenancy term at all, so one request returned every estate's
|
|
4721
|
+
* visitor records on the platform — names, NRIC, contact numbers and plates.
|
|
4722
|
+
*
|
|
4723
|
+
* The rule is the existing one, `requireSiteReach` (i.e. `entitleSite`), not a
|
|
4724
|
+
* second competing mechanism.
|
|
4725
|
+
*/
|
|
4706
4726
|
declare function useGuestManagementController(): {
|
|
4707
4727
|
add: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
4708
4728
|
getAll: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -50372,6 +50372,14 @@ function useGuestManagementRepo() {
|
|
|
50372
50372
|
throw error;
|
|
50373
50373
|
}
|
|
50374
50374
|
}
|
|
50375
|
+
async function getById(_id, session) {
|
|
50376
|
+
try {
|
|
50377
|
+
_id = new import_mongodb86.ObjectId(_id);
|
|
50378
|
+
} catch (error) {
|
|
50379
|
+
throw new import_node_server_utils135.BadRequestError("Invalid visitor guest ID format.");
|
|
50380
|
+
}
|
|
50381
|
+
return await collection.findOne({ _id }, { session });
|
|
50382
|
+
}
|
|
50375
50383
|
async function updateVisitorGuestById(_id, value, session) {
|
|
50376
50384
|
try {
|
|
50377
50385
|
_id = new import_mongodb86.ObjectId(_id);
|
|
@@ -50434,6 +50442,7 @@ function useGuestManagementRepo() {
|
|
|
50434
50442
|
return {
|
|
50435
50443
|
add,
|
|
50436
50444
|
getAll,
|
|
50445
|
+
getById,
|
|
50437
50446
|
updateVisitorGuestById,
|
|
50438
50447
|
deleteVisitorGuest,
|
|
50439
50448
|
createTextIndex
|
|
@@ -50483,7 +50492,11 @@ var import_joi67 = __toESM(require("joi"));
|
|
|
50483
50492
|
var import_node_server_utils137 = require("@7365admin1/node-server-utils");
|
|
50484
50493
|
function useGuestManagementController() {
|
|
50485
50494
|
const { add: _add, updateVisitorGuestById: _updateVisitorGuestById } = useGuestManagementService();
|
|
50486
|
-
const {
|
|
50495
|
+
const {
|
|
50496
|
+
getAll: _getAll,
|
|
50497
|
+
getById: _getById,
|
|
50498
|
+
deleteVisitorGuest: _deleteVisitorGuest
|
|
50499
|
+
} = useGuestManagementRepo();
|
|
50487
50500
|
async function add(req, res, next) {
|
|
50488
50501
|
const payload = { ...req.body };
|
|
50489
50502
|
const { error } = schemaGuestManagement.validate(payload, {
|
|
@@ -50496,6 +50509,7 @@ function useGuestManagementController() {
|
|
|
50496
50509
|
return;
|
|
50497
50510
|
}
|
|
50498
50511
|
try {
|
|
50512
|
+
await requireSiteReach(req, payload.site);
|
|
50499
50513
|
const data = await _add(payload);
|
|
50500
50514
|
res.status(201).json({ message: data });
|
|
50501
50515
|
return;
|
|
@@ -50516,7 +50530,9 @@ function useGuestManagementController() {
|
|
|
50516
50530
|
dateFrom: import_joi67.default.date().iso().optional().allow(null, ""),
|
|
50517
50531
|
dateTo: import_joi67.default.date().iso().optional().allow(null, ""),
|
|
50518
50532
|
org: import_joi67.default.string().optional().allow(null, ""),
|
|
50519
|
-
|
|
50533
|
+
// required, so the repository can never build a `$match` with no
|
|
50534
|
+
// tenancy term and return the whole platform's guest list
|
|
50535
|
+
site: import_joi67.default.string().hex().length(24).required()
|
|
50520
50536
|
});
|
|
50521
50537
|
const query2 = { ...req.query };
|
|
50522
50538
|
const { error } = validation.validate(query2, {
|
|
@@ -50546,6 +50562,7 @@ function useGuestManagementController() {
|
|
|
50546
50562
|
}
|
|
50547
50563
|
});
|
|
50548
50564
|
try {
|
|
50565
|
+
await requireSiteReach(req, site);
|
|
50549
50566
|
const data = await _getAll({
|
|
50550
50567
|
search,
|
|
50551
50568
|
page,
|
|
@@ -50578,6 +50595,8 @@ function useGuestManagementController() {
|
|
|
50578
50595
|
return;
|
|
50579
50596
|
}
|
|
50580
50597
|
try {
|
|
50598
|
+
const current = await _getById(_id);
|
|
50599
|
+
await requireSiteReach(req, current?.site);
|
|
50581
50600
|
const result = await _updateVisitorGuestById(_id, req.body);
|
|
50582
50601
|
res.status(200).json({ message: result });
|
|
50583
50602
|
return;
|
|
@@ -50597,6 +50616,8 @@ function useGuestManagementController() {
|
|
|
50597
50616
|
return;
|
|
50598
50617
|
}
|
|
50599
50618
|
try {
|
|
50619
|
+
const current = await _getById(_id);
|
|
50620
|
+
await requireSiteReach(req, current?.site);
|
|
50600
50621
|
await _deleteVisitorGuest(_id);
|
|
50601
50622
|
res.status(200).json({ message: "Successfully deleted visitor guest." });
|
|
50602
50623
|
return;
|