@7365admin1/core 3.47.1-staging.143 → 3.47.1-staging.145
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/.changeset/person-lookup-scope.md +44 -0
- package/dist/index.d.ts +29 -29
- package/dist/index.js +124 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +124 -7
- 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 +88 -2
- package/test/e2e/person-lookup-scope.e2e.test.mjs +265 -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.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
"@7365admin1/core": minor
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Scope the single-value people lookups to a site the caller can reach.
|
|
6
|
+
|
|
7
|
+
Seven endpoints on `/api/people` carried `requireAuth` and nothing else and were
|
|
8
|
+
not scoped at all:
|
|
9
|
+
|
|
10
|
+
| Route | What it answered |
|
|
11
|
+
|---|---|
|
|
12
|
+
| `GET /nric/:nric` | a `findOne` on NRIC across the **whole platform** |
|
|
13
|
+
| `GET /contact/:contact` | the same, on contact number |
|
|
14
|
+
| `GET /plateNumber/:plateNumber` | every person with that plate, anywhere |
|
|
15
|
+
| `GET /unit/:unit` | every person at that unit id |
|
|
16
|
+
| `GET /user/:userId` | the person record behind any user id |
|
|
17
|
+
| `GET /company` | company names aggregated across every client |
|
|
18
|
+
| `GET /all-nric` | a paged NRIC list at a caller-named site |
|
|
19
|
+
|
|
20
|
+
So any signed-in account could type an NRIC or a car plate and read the matching
|
|
21
|
+
resident of any estate — name, unit, contact number, plates. #1907 scoped the
|
|
22
|
+
paged list (`GET /api/people`); these are the lookups beside it.
|
|
23
|
+
|
|
24
|
+
None of them takes a site — `layer-common usePeople.findPersonByNRIC`,
|
|
25
|
+
`searchCompanyList` and `getPeopleByUnit` pass only the value being looked up —
|
|
26
|
+
so the scope is decided **after** the read, on the record, with the same
|
|
27
|
+
site-reach rule the camera, HID and people-list already use. A record the caller
|
|
28
|
+
cannot reach is left out, which for these endpoints is exactly what "no such
|
|
29
|
+
person" already looked like: `null`, or an empty list. **No client sees a new
|
|
30
|
+
response shape or a new status code.** `entitleSite` is asked once per distinct
|
|
31
|
+
site, not once per record.
|
|
32
|
+
|
|
33
|
+
`/all-nric` requires a site in the query, so that one is checked before the read
|
|
34
|
+
and answers `404` for a site the caller cannot reach — the same answer a site
|
|
35
|
+
that does not exist gives, so ids cannot be probed.
|
|
36
|
+
|
|
37
|
+
`/company` has no site or unit to scope on, so it is narrowed to the caller's
|
|
38
|
+
own organisations — the fallback `getAll` already uses. `person.repo.getCompany`
|
|
39
|
+
gains an optional `orgs` filter; absent means no restriction, which is what
|
|
40
|
+
Seven365 staff get.
|
|
41
|
+
|
|
42
|
+
`GET /user/:userId` also always answers about **your own** record, whatever your
|
|
43
|
+
memberships say: the resident app reads it during sign-up and when resubmitting
|
|
44
|
+
a rejected registration.
|
package/dist/index.d.ts
CHANGED
|
@@ -4612,7 +4612,7 @@ declare function usePersonRepo(): {
|
|
|
4612
4612
|
type?: ("resident" | "walk-in" | "drop-off" | "contractor" | "delivery" | "pick-up" | "guest" | "tenant")[] | undefined;
|
|
4613
4613
|
unit?: string | undefined;
|
|
4614
4614
|
}, session?: ClientSession) => Promise<TPerson[]>;
|
|
4615
|
-
getCompany: (search?: string) => Promise<any[]>;
|
|
4615
|
+
getCompany: (search?: string, orgs?: string[]) => Promise<any[]>;
|
|
4616
4616
|
getPeopleByPlateNumber: (plateNumber: string) => Promise<TPerson[]>;
|
|
4617
4617
|
getPeopleByNRIC: ({ page, limit, nric, sort, site, }: {
|
|
4618
4618
|
page?: number | undefined;
|
|
@@ -6491,35 +6491,35 @@ declare function UseAccessManagementRepo(): {
|
|
|
6491
6491
|
};
|
|
6492
6492
|
|
|
6493
6493
|
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
|
|
6494
|
+
addPhysicalCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6495
|
+
addNonPhysicalCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6496
6496
|
doorAccessLevels: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
6497
6497
|
liftAccessLevels: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
6498
6498
|
accessGroups: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
6499
6499
|
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
|
|
6500
|
+
allAccessCardsCounts: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6501
|
+
availableAccessCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6502
|
+
userTypeAccessCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6503
|
+
assignedAccessCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6504
|
+
assignedAccessCardsByUnit: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6505
|
+
acknowlegdeCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6506
|
+
accessandLiftCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6507
|
+
replaceCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6508
6508
|
updateNFCStatus: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
6509
|
-
doorAndLiftDropdown: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6509
|
+
doorAndLiftDropdown: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6510
6510
|
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
|
|
6511
|
+
visitorAccessCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6512
|
+
getCardReplacement: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6513
|
+
getAccessManagementSettings: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6514
|
+
bulkPhysicalAccessCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6515
|
+
assignAccessCardToUnit: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6516
6516
|
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
|
|
6517
|
+
getCardDetails: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6518
|
+
addQrTag: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6519
|
+
allQrTag: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6520
|
+
availableCardContractors: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6521
|
+
vmsgenerateQrCodes: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6522
|
+
addVisitorAccessCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6523
6523
|
signQrCode: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
6524
6524
|
checkoutVisitor: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
6525
6525
|
removeAccessCard: ({ cardNo, staffNo, url, }: {
|
|
@@ -6527,15 +6527,15 @@ declare function useAccessManagementController(): {
|
|
|
6527
6527
|
staffNo: string;
|
|
6528
6528
|
url: string;
|
|
6529
6529
|
}) => Promise<void>;
|
|
6530
|
-
getBlockLevelAndUnitList: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
6530
|
+
getBlockLevelAndUnitList: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6531
6531
|
getTransactions: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
6532
6532
|
assignMultipleCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
6533
6533
|
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
|
|
6534
|
+
uploadTemplate: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6535
|
+
getResidents: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6536
|
+
userAccessCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6537
|
+
removeTemplate: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6538
|
+
qrCodeList: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
6539
6539
|
generateQrCodeWithExpiry: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
6540
6540
|
};
|
|
6541
6541
|
|
package/dist/index.js
CHANGED
|
@@ -17735,7 +17735,7 @@ function usePersonRepo() {
|
|
|
17735
17735
|
);
|
|
17736
17736
|
}
|
|
17737
17737
|
}
|
|
17738
|
-
async function getCompany(search) {
|
|
17738
|
+
async function getCompany(search, orgs) {
|
|
17739
17739
|
try {
|
|
17740
17740
|
const cacheKey = (0, import_node_server_utils40.makeCacheKey)(site_people_namespace_collection, {
|
|
17741
17741
|
company: search
|
|
@@ -17747,6 +17747,11 @@ function usePersonRepo() {
|
|
|
17747
17747
|
if (search) {
|
|
17748
17748
|
query2.companyName = { $regex: search, $options: "i" };
|
|
17749
17749
|
}
|
|
17750
|
+
if (orgs) {
|
|
17751
|
+
query2.org = {
|
|
17752
|
+
$in: orgs.filter(import_mongodb36.ObjectId.isValid).map((o) => new import_mongodb36.ObjectId(o))
|
|
17753
|
+
};
|
|
17754
|
+
}
|
|
17750
17755
|
let data = [];
|
|
17751
17756
|
data = await collection.aggregate([
|
|
17752
17757
|
{ $match: query2 },
|
|
@@ -50365,6 +50370,38 @@ function usePersonController() {
|
|
|
50365
50370
|
}
|
|
50366
50371
|
return actor;
|
|
50367
50372
|
}
|
|
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
|
+
}
|
|
50368
50405
|
async function add(req, res, next) {
|
|
50369
50406
|
const payload = { ...req.body };
|
|
50370
50407
|
const { error } = schemaPerson.validate(payload, {
|
|
@@ -50539,7 +50576,8 @@ function usePersonController() {
|
|
|
50539
50576
|
}
|
|
50540
50577
|
try {
|
|
50541
50578
|
const data = await _getByNRIC(nric);
|
|
50542
|
-
|
|
50579
|
+
const { canReach } = await siteReach(req);
|
|
50580
|
+
res.json(await canReach(data) ? data : null);
|
|
50543
50581
|
return;
|
|
50544
50582
|
} catch (error2) {
|
|
50545
50583
|
import_node_server_utils138.logger.log({ level: "error", message: error2.message });
|
|
@@ -50558,7 +50596,8 @@ function usePersonController() {
|
|
|
50558
50596
|
}
|
|
50559
50597
|
try {
|
|
50560
50598
|
const data = await _getPersonByPhoneNumber(contact);
|
|
50561
|
-
|
|
50599
|
+
const { canReach } = await siteReach(req);
|
|
50600
|
+
res.json(await canReach(data) ? data : null);
|
|
50562
50601
|
return;
|
|
50563
50602
|
} catch (error2) {
|
|
50564
50603
|
import_node_server_utils138.logger.log({ level: "error", message: error2.message });
|
|
@@ -50602,7 +50641,8 @@ function usePersonController() {
|
|
|
50602
50641
|
type,
|
|
50603
50642
|
unit
|
|
50604
50643
|
});
|
|
50605
|
-
|
|
50644
|
+
const { only } = await siteReach(req);
|
|
50645
|
+
res.json(await only(data));
|
|
50606
50646
|
return;
|
|
50607
50647
|
} catch (error) {
|
|
50608
50648
|
import_node_server_utils138.logger.log({ level: "error", message: error.message });
|
|
@@ -50622,7 +50662,11 @@ function usePersonController() {
|
|
|
50622
50662
|
}
|
|
50623
50663
|
const { search } = value;
|
|
50624
50664
|
try {
|
|
50625
|
-
const
|
|
50665
|
+
const { actor } = await siteReach(req);
|
|
50666
|
+
const data = await _getCompany(
|
|
50667
|
+
search,
|
|
50668
|
+
actor.isSuperAdmin ? void 0 : actor.orgIds
|
|
50669
|
+
);
|
|
50626
50670
|
res.status(200).json(data);
|
|
50627
50671
|
return;
|
|
50628
50672
|
} catch (error2) {
|
|
@@ -50642,7 +50686,8 @@ function usePersonController() {
|
|
|
50642
50686
|
}
|
|
50643
50687
|
try {
|
|
50644
50688
|
const data = await _getPeopleByPlateNumber(plateNumber);
|
|
50645
|
-
|
|
50689
|
+
const { only } = await siteReach(req);
|
|
50690
|
+
res.json({ data: await only(data) });
|
|
50646
50691
|
return;
|
|
50647
50692
|
} catch (error2) {
|
|
50648
50693
|
import_node_server_utils138.logger.log({ level: "error", message: error2.message });
|
|
@@ -50682,6 +50727,10 @@ function usePersonController() {
|
|
|
50682
50727
|
}
|
|
50683
50728
|
});
|
|
50684
50729
|
try {
|
|
50730
|
+
const { actor } = await siteReach(req);
|
|
50731
|
+
if (!actor.isSuperAdmin) {
|
|
50732
|
+
await useCameraViewService().entitleSite({ siteId: site, userId: actor.id });
|
|
50733
|
+
}
|
|
50685
50734
|
const data = await _getPeopleByNRIC({
|
|
50686
50735
|
nric,
|
|
50687
50736
|
page,
|
|
@@ -50708,7 +50757,9 @@ function usePersonController() {
|
|
|
50708
50757
|
}
|
|
50709
50758
|
try {
|
|
50710
50759
|
const data = await _getByUserId(userId);
|
|
50711
|
-
|
|
50760
|
+
const { actor, canReach } = await siteReach(req);
|
|
50761
|
+
const isSelf = Boolean(actor.id) && data?.user?.toString() === actor.id;
|
|
50762
|
+
res.json(isSelf || await canReach(data) ? data : null);
|
|
50712
50763
|
return;
|
|
50713
50764
|
} catch (error2) {
|
|
50714
50765
|
import_node_server_utils138.logger.log({ level: "error", message: error2.message });
|
|
@@ -63736,6 +63787,16 @@ function useAccessManagementSvc() {
|
|
|
63736
63787
|
|
|
63737
63788
|
// src/controllers/access-management.controller.ts
|
|
63738
63789
|
function useAccessManagementController() {
|
|
63790
|
+
const refuseUnreachableSite = async (req, res, site) => {
|
|
63791
|
+
try {
|
|
63792
|
+
await requireSiteReach(req, site);
|
|
63793
|
+
return false;
|
|
63794
|
+
} catch (error) {
|
|
63795
|
+
const status = Number(error?.statusCode) || 401;
|
|
63796
|
+
res.status(status).json({ data: null, message: error.message });
|
|
63797
|
+
return true;
|
|
63798
|
+
}
|
|
63799
|
+
};
|
|
63739
63800
|
const {
|
|
63740
63801
|
addPhysicalCardSvc,
|
|
63741
63802
|
addNonPhysicalCardSvc,
|
|
@@ -63812,6 +63873,8 @@ function useAccessManagementController() {
|
|
|
63812
63873
|
if (error) {
|
|
63813
63874
|
return res.status(400).json({ data: null, message: error.message });
|
|
63814
63875
|
}
|
|
63876
|
+
if (await refuseUnreachableSite(req, res, payload.site))
|
|
63877
|
+
return;
|
|
63815
63878
|
const result = await addPhysicalCardSvc(payload);
|
|
63816
63879
|
return res.status(201).json({
|
|
63817
63880
|
data: result,
|
|
@@ -63880,6 +63943,8 @@ function useAccessManagementController() {
|
|
|
63880
63943
|
if (error) {
|
|
63881
63944
|
throw new Error(`${error.message}`);
|
|
63882
63945
|
}
|
|
63946
|
+
if (await refuseUnreachableSite(req, res, site))
|
|
63947
|
+
return;
|
|
63883
63948
|
const result = await addNonPhysicalCardSvc({
|
|
63884
63949
|
site,
|
|
63885
63950
|
quantity,
|
|
@@ -63980,6 +64045,8 @@ function useAccessManagementController() {
|
|
|
63980
64045
|
if (error) {
|
|
63981
64046
|
throw new Error(`${error.message}`);
|
|
63982
64047
|
}
|
|
64048
|
+
if (await refuseUnreachableSite(req, res, site))
|
|
64049
|
+
return;
|
|
63983
64050
|
const result = await allAccessCardsCountsSvc({ site, userType });
|
|
63984
64051
|
return res.status(200).json({ message: "Success", data: result });
|
|
63985
64052
|
} catch (error) {
|
|
@@ -64002,6 +64069,8 @@ function useAccessManagementController() {
|
|
|
64002
64069
|
if (error) {
|
|
64003
64070
|
return res.status(400).json({ message: error.message });
|
|
64004
64071
|
}
|
|
64072
|
+
if (await refuseUnreachableSite(req, res, site))
|
|
64073
|
+
return;
|
|
64005
64074
|
const result = await availableAccessCardsSvc({ site, userType, type });
|
|
64006
64075
|
return res.status(200).json({ message: "Success", data: result });
|
|
64007
64076
|
} catch (error) {
|
|
@@ -64040,6 +64109,8 @@ function useAccessManagementController() {
|
|
|
64040
64109
|
if (error) {
|
|
64041
64110
|
return res.status(400).json({ message: error.message });
|
|
64042
64111
|
}
|
|
64112
|
+
if (await refuseUnreachableSite(req, res, site))
|
|
64113
|
+
return;
|
|
64043
64114
|
const result = await userTypeAccessCardsSvc({
|
|
64044
64115
|
page,
|
|
64045
64116
|
limit,
|
|
@@ -64085,6 +64156,8 @@ function useAccessManagementController() {
|
|
|
64085
64156
|
if (error) {
|
|
64086
64157
|
return res.status(400).json({ message: error.message });
|
|
64087
64158
|
}
|
|
64159
|
+
if (await refuseUnreachableSite(req, res, site))
|
|
64160
|
+
return;
|
|
64088
64161
|
const result = await assignedAccessCardsSvc({
|
|
64089
64162
|
site,
|
|
64090
64163
|
userType,
|
|
@@ -64127,6 +64200,8 @@ function useAccessManagementController() {
|
|
|
64127
64200
|
if (error) {
|
|
64128
64201
|
return res.status(400).json({ message: error.message });
|
|
64129
64202
|
}
|
|
64203
|
+
if (await refuseUnreachableSite(req, res, site))
|
|
64204
|
+
return;
|
|
64130
64205
|
const result = await assignedAccessCardsByUnitSvc({
|
|
64131
64206
|
site,
|
|
64132
64207
|
unitId,
|
|
@@ -64154,6 +64229,8 @@ function useAccessManagementController() {
|
|
|
64154
64229
|
if (error) {
|
|
64155
64230
|
return res.status(400).json({ message: error.message });
|
|
64156
64231
|
}
|
|
64232
|
+
if (await refuseUnreachableSite(req, res, site))
|
|
64233
|
+
return;
|
|
64157
64234
|
const result = await acknowlegdeCardSvc({ userId, cardId, site });
|
|
64158
64235
|
return res.status(200).json({ message: "Success", data: result });
|
|
64159
64236
|
} catch (error) {
|
|
@@ -64189,6 +64266,8 @@ function useAccessManagementController() {
|
|
|
64189
64266
|
if (error) {
|
|
64190
64267
|
return res.status(400).json({ message: error.message });
|
|
64191
64268
|
}
|
|
64269
|
+
if (await refuseUnreachableSite(req, res, site))
|
|
64270
|
+
return;
|
|
64192
64271
|
const result = await accessandLiftCardsSvc({
|
|
64193
64272
|
accessLevel,
|
|
64194
64273
|
liftAccessLevel,
|
|
@@ -64217,6 +64296,8 @@ function useAccessManagementController() {
|
|
|
64217
64296
|
if (error) {
|
|
64218
64297
|
return res.status(400).json({ message: error.message });
|
|
64219
64298
|
}
|
|
64299
|
+
if (await refuseUnreachableSite(req, res, site))
|
|
64300
|
+
return;
|
|
64220
64301
|
const result = await replaceCardSvc({ userId, cardId, site, acm_url });
|
|
64221
64302
|
return res.status(200).json({ message: "Success", data: result });
|
|
64222
64303
|
} catch (error) {
|
|
@@ -64263,6 +64344,8 @@ function useAccessManagementController() {
|
|
|
64263
64344
|
if (error) {
|
|
64264
64345
|
return res.status(400).json({ message: error.message });
|
|
64265
64346
|
}
|
|
64347
|
+
if (await refuseUnreachableSite(req, res, site))
|
|
64348
|
+
return;
|
|
64266
64349
|
const result = await doorAndLiftDropdownSvc({ site, type, userType });
|
|
64267
64350
|
return res.status(200).json({ message: "Success", data: result });
|
|
64268
64351
|
} catch (error) {
|
|
@@ -64327,6 +64410,8 @@ function useAccessManagementController() {
|
|
|
64327
64410
|
if (error) {
|
|
64328
64411
|
return res.status(400).json({ message: error.message });
|
|
64329
64412
|
}
|
|
64413
|
+
if (await refuseUnreachableSite(req, res, site))
|
|
64414
|
+
return;
|
|
64330
64415
|
const result = await visitorAccessCardsSvc({
|
|
64331
64416
|
site,
|
|
64332
64417
|
page,
|
|
@@ -64374,6 +64459,8 @@ function useAccessManagementController() {
|
|
|
64374
64459
|
if (error) {
|
|
64375
64460
|
return res.status(400).json({ message: error.message });
|
|
64376
64461
|
}
|
|
64462
|
+
if (await refuseUnreachableSite(req, res, site))
|
|
64463
|
+
return;
|
|
64377
64464
|
const result = await getCardReplacementSvc({
|
|
64378
64465
|
site,
|
|
64379
64466
|
page,
|
|
@@ -64401,6 +64488,8 @@ function useAccessManagementController() {
|
|
|
64401
64488
|
if (error) {
|
|
64402
64489
|
return res.status(400).json({ message: error.message });
|
|
64403
64490
|
}
|
|
64491
|
+
if (await refuseUnreachableSite(req, res, site))
|
|
64492
|
+
return;
|
|
64404
64493
|
const result = await getAccessManagementSettingsSvc({ site });
|
|
64405
64494
|
return res.status(200).json({ message: "Success", data: result });
|
|
64406
64495
|
} catch (error) {
|
|
@@ -64417,6 +64506,8 @@ function useAccessManagementController() {
|
|
|
64417
64506
|
throw new Error("File is required!");
|
|
64418
64507
|
const xlsData = await convertBufferFile(req.file.buffer);
|
|
64419
64508
|
const dataJson = JSON.stringify(xlsData);
|
|
64509
|
+
if (await refuseUnreachableSite(req, res, site))
|
|
64510
|
+
return;
|
|
64420
64511
|
const result = await bulkPhysicalAccessCardSvc({ dataJson, site });
|
|
64421
64512
|
return res.status(200).json({ message: "Success", data: result });
|
|
64422
64513
|
} catch (error) {
|
|
@@ -64458,6 +64549,8 @@ function useAccessManagementController() {
|
|
|
64458
64549
|
if (error) {
|
|
64459
64550
|
return res.status(400).json({ message: error.message });
|
|
64460
64551
|
}
|
|
64552
|
+
if (await refuseUnreachableSite(req, res, site))
|
|
64553
|
+
return;
|
|
64461
64554
|
const result = await assignAccessCardToUnitSvc({
|
|
64462
64555
|
units,
|
|
64463
64556
|
quantity,
|
|
@@ -64506,6 +64599,8 @@ function useAccessManagementController() {
|
|
|
64506
64599
|
if (error) {
|
|
64507
64600
|
return res.status(400).json({ message: error.message });
|
|
64508
64601
|
}
|
|
64602
|
+
if (await refuseUnreachableSite(req, res, siteId))
|
|
64603
|
+
return;
|
|
64509
64604
|
const result = await getCardDetailsSvc({ siteId, cardId });
|
|
64510
64605
|
return res.status(200).json({ message: "Success", data: result });
|
|
64511
64606
|
} catch (error) {
|
|
@@ -64534,6 +64629,8 @@ function useAccessManagementController() {
|
|
|
64534
64629
|
if (error) {
|
|
64535
64630
|
return res.status(400).json({ message: error.message });
|
|
64536
64631
|
}
|
|
64632
|
+
if (await refuseUnreachableSite(req, res, site))
|
|
64633
|
+
return;
|
|
64537
64634
|
const result = await addQrTagSvc({ payload, site });
|
|
64538
64635
|
return res.status(200).json({ message: "Success", data: result });
|
|
64539
64636
|
} catch (error) {
|
|
@@ -64553,6 +64650,8 @@ function useAccessManagementController() {
|
|
|
64553
64650
|
if (error) {
|
|
64554
64651
|
return res.status(400).json({ message: error.message });
|
|
64555
64652
|
}
|
|
64653
|
+
if (await refuseUnreachableSite(req, res, site))
|
|
64654
|
+
return;
|
|
64556
64655
|
const result = await allQrTagSvc({ site });
|
|
64557
64656
|
return res.status(200).json({ message: "Success", data: result });
|
|
64558
64657
|
} catch (error) {
|
|
@@ -64582,6 +64681,8 @@ function useAccessManagementController() {
|
|
|
64582
64681
|
if (error) {
|
|
64583
64682
|
return res.status(400).json({ message: error.message });
|
|
64584
64683
|
}
|
|
64684
|
+
if (await refuseUnreachableSite(req, res, siteId))
|
|
64685
|
+
return;
|
|
64585
64686
|
const result = await availableCardContractorsSvc({
|
|
64586
64687
|
siteId,
|
|
64587
64688
|
unitId,
|
|
@@ -64614,6 +64715,8 @@ function useAccessManagementController() {
|
|
|
64614
64715
|
return res.status(400).json({ message: error.message });
|
|
64615
64716
|
}
|
|
64616
64717
|
const normalizedUnitId = [unitId];
|
|
64718
|
+
if (await refuseUnreachableSite(req, res, site))
|
|
64719
|
+
return;
|
|
64617
64720
|
const result = await vmsgenerateQrCodesSvc({
|
|
64618
64721
|
site,
|
|
64619
64722
|
unitId,
|
|
@@ -64665,6 +64768,8 @@ function useAccessManagementController() {
|
|
|
64665
64768
|
if (error) {
|
|
64666
64769
|
return res.status(400).json({ message: error.message });
|
|
64667
64770
|
}
|
|
64771
|
+
if (await refuseUnreachableSite(req, res, site))
|
|
64772
|
+
return;
|
|
64668
64773
|
const result = await addVisitorAccessCardSvc({
|
|
64669
64774
|
site,
|
|
64670
64775
|
unitId,
|
|
@@ -64741,6 +64846,8 @@ function useAccessManagementController() {
|
|
|
64741
64846
|
if (!site || typeof site !== "string") {
|
|
64742
64847
|
throw new Error("Site is required");
|
|
64743
64848
|
}
|
|
64849
|
+
if (await refuseUnreachableSite(req, res, site))
|
|
64850
|
+
return;
|
|
64744
64851
|
const result = await getBlockLevelAndUnitListSvc({ site });
|
|
64745
64852
|
return res.status(200).json({ message: "Success", data: result });
|
|
64746
64853
|
} catch (error) {
|
|
@@ -64836,6 +64943,8 @@ function useAccessManagementController() {
|
|
|
64836
64943
|
if (error) {
|
|
64837
64944
|
return res.status(400).json({ message: error.message });
|
|
64838
64945
|
}
|
|
64946
|
+
if (await refuseUnreachableSite(req, res, site))
|
|
64947
|
+
return;
|
|
64839
64948
|
const result = await uploadTemplateSvc({ site, id, name });
|
|
64840
64949
|
return res.status(200).json({ message: "Success", data: result });
|
|
64841
64950
|
} catch (error) {
|
|
@@ -64857,6 +64966,8 @@ function useAccessManagementController() {
|
|
|
64857
64966
|
if (error) {
|
|
64858
64967
|
return res.status(400).json({ message: error.message });
|
|
64859
64968
|
}
|
|
64969
|
+
if (await refuseUnreachableSite(req, res, siteId))
|
|
64970
|
+
return;
|
|
64860
64971
|
const result = await getResidentsSvc({ orgId, siteId, unitId });
|
|
64861
64972
|
return res.status(200).json({ data: result });
|
|
64862
64973
|
} catch (error) {
|
|
@@ -64880,6 +64991,8 @@ function useAccessManagementController() {
|
|
|
64880
64991
|
return res.status(400).json({ message: error.message });
|
|
64881
64992
|
}
|
|
64882
64993
|
const isLiftCardBool = isLiftCard === "true";
|
|
64994
|
+
if (await refuseUnreachableSite(req, res, siteId))
|
|
64995
|
+
return;
|
|
64883
64996
|
const result = await userAccessCardsSvc({
|
|
64884
64997
|
userId,
|
|
64885
64998
|
siteId,
|
|
@@ -64904,6 +65017,8 @@ function useAccessManagementController() {
|
|
|
64904
65017
|
if (error) {
|
|
64905
65018
|
return res.status(400).json({ message: error.message });
|
|
64906
65019
|
}
|
|
65020
|
+
if (await refuseUnreachableSite(req, res, site))
|
|
65021
|
+
return;
|
|
64907
65022
|
const result = await removeTemplateSvc({ site });
|
|
64908
65023
|
return res.status(200).json({ data: result });
|
|
64909
65024
|
} catch (error) {
|
|
@@ -64937,6 +65052,8 @@ function useAccessManagementController() {
|
|
|
64937
65052
|
if (error) {
|
|
64938
65053
|
return res.status(400).json({ message: error.message });
|
|
64939
65054
|
}
|
|
65055
|
+
if (await refuseUnreachableSite(req, res, site))
|
|
65056
|
+
return;
|
|
64940
65057
|
const result = await qrCodeListSvc({
|
|
64941
65058
|
type,
|
|
64942
65059
|
site,
|