@7365admin1/core 3.47.1-staging.144 → 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/.changeset/access-management-site-scope.md +59 -0
- package/dist/index.d.ts +29 -28
- package/dist/index.js +150 -42
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +150 -42
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/test/e2e/access-management-scope.e2e.test.mjs +363 -0
- package/test/e2e/harness.mjs +105 -0
- package/test/e2e/vehicle-scope.e2e.test.mjs +331 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
"@7365admin1/core": minor
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Scope the access-management routes to a site the caller can reach.
|
|
6
|
+
|
|
7
|
+
Every route on `/api/access-management` carried `requireAuth` and nothing more.
|
|
8
|
+
`requireAuth` proves a session exists; it makes no organisation or site
|
|
9
|
+
decision. So any signed-in account on the platform — a resident of a different
|
|
10
|
+
estate, a cleaner, anybody with a login — could read another client's
|
|
11
|
+
access-card inventory, its card holders, the residents behind a unit and the
|
|
12
|
+
block/level/unit structure, and could ISSUE a physical NFC card into that
|
|
13
|
+
estate, generate visitor QR passes for it and stamp QR tags onto its cards.
|
|
14
|
+
These are the credentials that open that estate's doors and lifts.
|
|
15
|
+
|
|
16
|
+
Twenty-eight handlers now decide from the site the request already names,
|
|
17
|
+
before any work is done:
|
|
18
|
+
|
|
19
|
+
- from the body — `addPhysicalCard`, `addNonPhysicalCard`, `acknowlegdeCard`,
|
|
20
|
+
`replaceCard`, `assignAccessCardToUnit`, `vmsgenerateQrCodes`,
|
|
21
|
+
`addVisitorAccessCard`;
|
|
22
|
+
- from the query — `allAccessCardsCounts`, `availableAccessCards`,
|
|
23
|
+
`userTypeAccessCards`, `assignedAccessCards`, `assignedAccessCardsByUnit`,
|
|
24
|
+
`accessandLiftCards`, `doorAndLiftDropdown`, `visitorAccessCards`,
|
|
25
|
+
`bulkPhysicalAccessCard`, `getCardDetails`, `allQrTag`,
|
|
26
|
+
`availableCardContractors`, `getBlockLevelAndUnitList`, `getResidents`,
|
|
27
|
+
`userAccessCards`, `uploadTemplate`, `removeTemplate`, `qrCodeList`;
|
|
28
|
+
- from the URL — `getCardReplacement`, `getAccessManagementSettings`, `addQrTag`.
|
|
29
|
+
|
|
30
|
+
The rule is the existing one, `requireSiteReach` -> `entitleSite`: a membership
|
|
31
|
+
pinned to the site, an org-wide membership at the site's owning organisation, or
|
|
32
|
+
an ACTIVE `customer.sites` engagement. The engagement branch is required, not
|
|
33
|
+
incidental — access cards are administered from the security and
|
|
34
|
+
property-management apps, whose users hold no membership in the estate's own
|
|
35
|
+
organisation.
|
|
36
|
+
|
|
37
|
+
The guard writes its own response instead of throwing. Every handler in this
|
|
38
|
+
controller wraps its body in `try { ... } catch { res.status(400|500) }` rather
|
|
39
|
+
than calling `next(error)`, so a thrown `UnauthorizedError`/`NotFoundError`
|
|
40
|
+
would never reach the error handler and would have surfaced as a 400 with the
|
|
41
|
+
guard's message inside it. It is placed AFTER each handler's Joi validation, so
|
|
42
|
+
a malformed or missing site still answers 400 exactly as before, and only a
|
|
43
|
+
well-formed site the caller cannot reach is refused. That refusal is 404 — what
|
|
44
|
+
a site that does not exist already answers — so site ids cannot be enumerated by
|
|
45
|
+
watching the difference.
|
|
46
|
+
|
|
47
|
+
Six routes on the mount are deliberately NOT changed, because they carry no
|
|
48
|
+
site at all and need per-record resolution:
|
|
49
|
+
|
|
50
|
+
- `POST /sign-qr` and `PATCH /visitor-checkout` — both are called by shipped
|
|
51
|
+
mobile clients that cannot update in lockstep
|
|
52
|
+
(`resident-mobile-app src/actions/entrypass.ts:66`, `isecure365-mobile-app
|
|
53
|
+
src/features/visitors/entry-pass.service.ts:175` and `visitor.service.ts:194`).
|
|
54
|
+
- `PATCH /nfc-status`, `PATCH /delete-card`, `POST /card-replacement`,
|
|
55
|
+
`POST /assign-user` — each identifies a card by id and would need the card's
|
|
56
|
+
own site loaded first.
|
|
57
|
+
- `GET /door-access-levels`, `GET /lift-access-levels`, `GET /access-groups` and
|
|
58
|
+
`POST /settings` take an `acm_url` — an access-control device URL — so they
|
|
59
|
+
are a separate question from site reach and were not touched here.
|
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>>;
|
|
@@ -6491,35 +6492,35 @@ declare function UseAccessManagementRepo(): {
|
|
|
6491
6492
|
};
|
|
6492
6493
|
|
|
6493
6494
|
declare function useAccessManagementController(): {
|
|
6494
|
-
addPhysicalCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6495
|
-
addNonPhysicalCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6495
|
+
addPhysicalCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6496
|
+
addNonPhysicalCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6496
6497
|
doorAccessLevels: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
6497
6498
|
liftAccessLevels: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
6498
6499
|
accessGroups: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
6499
6500
|
accessManagementSettings: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
6500
|
-
allAccessCardsCounts: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6501
|
-
availableAccessCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6502
|
-
userTypeAccessCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6503
|
-
assignedAccessCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6504
|
-
assignedAccessCardsByUnit: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6505
|
-
acknowlegdeCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6506
|
-
accessandLiftCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6507
|
-
replaceCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6501
|
+
allAccessCardsCounts: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6502
|
+
availableAccessCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6503
|
+
userTypeAccessCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6504
|
+
assignedAccessCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6505
|
+
assignedAccessCardsByUnit: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6506
|
+
acknowlegdeCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6507
|
+
accessandLiftCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6508
|
+
replaceCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6508
6509
|
updateNFCStatus: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
6509
|
-
doorAndLiftDropdown: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6510
|
+
doorAndLiftDropdown: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6510
6511
|
cardReplacement: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
6511
|
-
visitorAccessCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6512
|
-
getCardReplacement: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6513
|
-
getAccessManagementSettings: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6514
|
-
bulkPhysicalAccessCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6515
|
-
assignAccessCardToUnit: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6512
|
+
visitorAccessCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6513
|
+
getCardReplacement: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6514
|
+
getAccessManagementSettings: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6515
|
+
bulkPhysicalAccessCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6516
|
+
assignAccessCardToUnit: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6516
6517
|
deleteCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
6517
|
-
getCardDetails: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6518
|
-
addQrTag: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6519
|
-
allQrTag: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6520
|
-
availableCardContractors: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6521
|
-
vmsgenerateQrCodes: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6522
|
-
addVisitorAccessCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6518
|
+
getCardDetails: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6519
|
+
addQrTag: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6520
|
+
allQrTag: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6521
|
+
availableCardContractors: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6522
|
+
vmsgenerateQrCodes: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6523
|
+
addVisitorAccessCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6523
6524
|
signQrCode: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
6524
6525
|
checkoutVisitor: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
6525
6526
|
removeAccessCard: ({ cardNo, staffNo, url, }: {
|
|
@@ -6527,15 +6528,15 @@ declare function useAccessManagementController(): {
|
|
|
6527
6528
|
staffNo: string;
|
|
6528
6529
|
url: string;
|
|
6529
6530
|
}) => Promise<void>;
|
|
6530
|
-
getBlockLevelAndUnitList: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6531
|
+
getBlockLevelAndUnitList: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6531
6532
|
getTransactions: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
6532
6533
|
assignMultipleCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
6533
6534
|
visitorCheckout: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
6534
|
-
uploadTemplate: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6535
|
-
getResidents: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6536
|
-
userAccessCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6537
|
-
removeTemplate: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6538
|
-
qrCodeList: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6535
|
+
uploadTemplate: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6536
|
+
getResidents: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6537
|
+
userAccessCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6538
|
+
removeTemplate: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6539
|
+
qrCodeList: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6539
6540
|
generateQrCodeWithExpiry: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
6540
6541
|
};
|
|
6541
6542
|
|