@7365admin1/core 3.48.1-staging.206 → 3.48.1-staging.208
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-record-scope.md +48 -0
- package/.changeset/organization-and-promo-list-scope.md +39 -0
- package/dist/index.d.ts +14 -8
- package/dist/index.js +107 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +107 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/test/e2e/access-management-scope.e2e.test.mjs +550 -13
- package/test/e2e/harness.mjs +27 -2
- package/test/e2e/org-and-promo-list-scope.e2e.test.mjs +387 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
"@7365admin1/core": minor
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Scope the access-management routes that name a card, not a site.
|
|
6
|
+
|
|
7
|
+
`access-management-site-scope` closed the routes whose request already carries
|
|
8
|
+
an estate. Seven routes on the same mount carry none — they reach an access card
|
|
9
|
+
(or a unit) by `_id` and nothing else — so there was nothing for that rule to
|
|
10
|
+
read and they were left carrying `requireAuth` alone:
|
|
11
|
+
|
|
12
|
+
- `POST /sign-qr` — mints a working door credential. The card number is
|
|
13
|
+
RSA-encrypted into a QR payload the reader accepts for up to 24 hours when
|
|
14
|
+
`purpose` is `"vms"`. Any signed-in account could hand itself a valid pass for
|
|
15
|
+
any card in any estate on the platform.
|
|
16
|
+
- `PATCH /delete-card` — deactivates a card, which is what stops it opening a
|
|
17
|
+
door.
|
|
18
|
+
- `PATCH /nfc-status` — flips a card's status and activation.
|
|
19
|
+
- `PATCH /visitor-checkout` — releases a visitor's card and writes its history.
|
|
20
|
+
- `POST /card-replacement` — retires a card and hands its replacement to a unit.
|
|
21
|
+
- `POST /assign-user` — hands the cards on a unit to a list of people.
|
|
22
|
+
- `POST /settings` — rewrites an estate's access-management settings, including
|
|
23
|
+
the address of the Entrypass controller it talks to. This one DOES carry the
|
|
24
|
+
estate, in the body, and the repository upserts on it; it was simply never
|
|
25
|
+
checked.
|
|
26
|
+
|
|
27
|
+
For the six that name a record, the scope is now decided on the STORED row via
|
|
28
|
+
`siteReachOf` — the same rule `requireBulletinVideoReach` and
|
|
29
|
+
`requireEntryPassReach` already apply, and the same underlying `entitleSite`
|
|
30
|
+
verdict as `requireSiteReach`. `POST /settings` uses `requireSiteReach` on the
|
|
31
|
+
body's site, exactly as `GET /settings/:site` already does. No new mechanism and
|
|
32
|
+
no new permission string: reaching the estate is the whole rule, so the
|
|
33
|
+
contracted agency at the guardhouse, the org-wide manager and a resident reading
|
|
34
|
+
their own pass are all unaffected.
|
|
35
|
+
|
|
36
|
+
Where a write MOVES a card onto a unit (`card-replacement`, `assign-user`) the
|
|
37
|
+
destination unit is checked as well as the card, so a card cannot be re-parented
|
|
38
|
+
into an estate the caller cannot reach.
|
|
39
|
+
|
|
40
|
+
"Not yours" and "does not exist" answer identically (404), so card ids cannot be
|
|
41
|
+
enumerated. An id matching no row is refused rather than waved through, and a
|
|
42
|
+
row naming no estate fails closed. The guards sit after each handler's Joi
|
|
43
|
+
validation, so malformed input still answers 400 exactly as before.
|
|
44
|
+
|
|
45
|
+
`GET /door-access-levels`, `GET /lift-access-levels` and `GET /access-groups`
|
|
46
|
+
are deliberately NOT changed: they carry no estate and no record, only a
|
|
47
|
+
caller-supplied `acm_url`, so there is nothing to scope against without changing
|
|
48
|
+
their request contract. They are recorded as a separate piece of work.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
"@7365admin1/core": minor
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Scope the organisation list to the caller, and put the promo-code list behind the staff gate.
|
|
6
|
+
|
|
7
|
+
`GET /api/organizations` and `GET /api/promo-codes` performed no authorization
|
|
8
|
+
at all — `requireAuth` and nothing more — while every sibling handler in the
|
|
9
|
+
same two files guarded. So any signed-in account on the platform, a resident or
|
|
10
|
+
a cleaner included, could page through the name, e-mail, nature and status of
|
|
11
|
+
**every Seven365 client**, and read off **every discount code** we have ever
|
|
12
|
+
minted, with its rate and its expiry, and then redeem whichever is worth most.
|
|
13
|
+
|
|
14
|
+
The two rules are different, because the callers are different.
|
|
15
|
+
|
|
16
|
+
**`GET /api/organizations` is now a SCOPE, not a refusal.** Seven365 staff see
|
|
17
|
+
every organisation exactly as before; anybody else sees the organisations they
|
|
18
|
+
hold a live membership of, plus any registered under their own verified account
|
|
19
|
+
e-mail. The e-mail half is not decoration: `web-app-main
|
|
20
|
+
pages/verify/email/index.vue:322` — the org-owner self-signup — lists
|
|
21
|
+
organisations to find the one it created a line earlier, at which point that
|
|
22
|
+
brand-new client owner is a member of nothing. Refusing them would have traded
|
|
23
|
+
the leak for a broken signup. The comparison is the one
|
|
24
|
+
`getOrgsByEmail` already makes, against the address on the caller's own `users`
|
|
25
|
+
row; nothing the caller sends takes part in it. It also removes a real bug from
|
|
26
|
+
that flow: the page takes `items[0]` of a newest-first list, so two client
|
|
27
|
+
owners signing up in the same moment could be handed each other's organisation
|
|
28
|
+
as their `defaultOrg`.
|
|
29
|
+
|
|
30
|
+
The scope is part of the Redis cache key as well as the query, so one caller's
|
|
31
|
+
narrowed page is never replayed to the next, and `countDocuments` runs the
|
|
32
|
+
scoped query so pagination cannot walk past the scope.
|
|
33
|
+
|
|
34
|
+
**`GET /api/promo-codes` is Seven365 staff only,** together with
|
|
35
|
+
`GET /api/promo-codes/id/:id`, which is the same disclosure one record at a
|
|
36
|
+
time. Both are read solely by the staff console. A client at checkout is
|
|
37
|
+
unaffected: `web-app-org pages/checkout.vue` and
|
|
38
|
+
`subscription/manage-seats.vue` type a code and validate it through
|
|
39
|
+
`GET /api/promo-codes/code`, which stays signed-in-only and is untouched.
|
package/dist/index.d.ts
CHANGED
|
@@ -702,13 +702,17 @@ declare function useOrgRepo(): {
|
|
|
702
702
|
createUniqueIndex: () => Promise<void>;
|
|
703
703
|
add: (value: TOrg, session?: ClientSession) => Promise<ObjectId>;
|
|
704
704
|
update: (id: string, value: Partial<TOrg>, session?: ClientSession) => Promise<string>;
|
|
705
|
-
getAll: ({ search, page, limit, sort, status, nature, }: {
|
|
705
|
+
getAll: ({ search, page, limit, sort, status, nature, scope, }: {
|
|
706
706
|
search?: string | undefined;
|
|
707
707
|
page?: number | undefined;
|
|
708
708
|
limit?: number | undefined;
|
|
709
709
|
sort?: Record<string, number> | undefined;
|
|
710
710
|
status?: string | undefined;
|
|
711
711
|
nature?: string | undefined;
|
|
712
|
+
scope?: {
|
|
713
|
+
orgIds?: string[] | undefined;
|
|
714
|
+
email?: string | undefined;
|
|
715
|
+
} | undefined;
|
|
712
716
|
}) => Promise<{
|
|
713
717
|
items: any[];
|
|
714
718
|
pages: number;
|
|
@@ -6854,6 +6858,8 @@ declare function UseAccessManagementRepo(): {
|
|
|
6854
6858
|
insertedCount: number;
|
|
6855
6859
|
insertedIds: Record<number, ObjectId>;
|
|
6856
6860
|
}>;
|
|
6861
|
+
cardSitesRepo: (cardIds: Array<string | ObjectId>) => Promise<mongodb.WithId<bson.Document>[]>;
|
|
6862
|
+
unitSiteRepo: (unitId: string | ObjectId) => Promise<mongodb.WithId<bson.Document> | null>;
|
|
6857
6863
|
accessManagementSettingsRepo: (params: TAccessMngmntSettings) => Promise<mongodb.UpdateResult<bson.Document>>;
|
|
6858
6864
|
allAccessCardsCountsRepo: (params: {
|
|
6859
6865
|
site: string;
|
|
@@ -7121,7 +7127,7 @@ declare function useAccessManagementController(): {
|
|
|
7121
7127
|
doorAccessLevels: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
7122
7128
|
liftAccessLevels: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
7123
7129
|
accessGroups: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
7124
|
-
accessManagementSettings: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
7130
|
+
accessManagementSettings: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7125
7131
|
allAccessCardsCounts: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7126
7132
|
availableAccessCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7127
7133
|
userTypeAccessCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
@@ -7130,23 +7136,23 @@ declare function useAccessManagementController(): {
|
|
|
7130
7136
|
acknowlegdeCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7131
7137
|
accessandLiftCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7132
7138
|
replaceCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7133
|
-
updateNFCStatus: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
7139
|
+
updateNFCStatus: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7134
7140
|
doorAndLiftDropdown: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7135
|
-
cardReplacement: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
7141
|
+
cardReplacement: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7136
7142
|
visitorAccessCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7137
7143
|
getCardReplacement: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7138
7144
|
getAccessManagementSettings: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7139
7145
|
bulkPhysicalAccessCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7140
7146
|
assignAccessCardToUnit: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7141
|
-
deleteCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
7147
|
+
deleteCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7142
7148
|
getCardDetails: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7143
7149
|
addQrTag: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7144
7150
|
allQrTag: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7145
7151
|
availableCardContractors: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7146
7152
|
vmsgenerateQrCodes: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7147
7153
|
addVisitorAccessCard: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7148
|
-
signQrCode: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
7149
|
-
checkoutVisitor: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
7154
|
+
signQrCode: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7155
|
+
checkoutVisitor: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7150
7156
|
removeAccessCard: ({ cardNo, staffNo, url, }: {
|
|
7151
7157
|
cardNo: string;
|
|
7152
7158
|
staffNo: string;
|
|
@@ -7154,7 +7160,7 @@ declare function useAccessManagementController(): {
|
|
|
7154
7160
|
}) => Promise<void>;
|
|
7155
7161
|
getBlockLevelAndUnitList: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7156
7162
|
getTransactions: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
7157
|
-
assignMultipleCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any
|
|
7163
|
+
assignMultipleCards: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7158
7164
|
visitorCheckout: (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
|
|
7159
7165
|
uploadTemplate: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
7160
7166
|
getResidents: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
|
package/dist/index.js
CHANGED
|
@@ -11739,7 +11739,8 @@ function useOrgRepo() {
|
|
|
11739
11739
|
limit = 10,
|
|
11740
11740
|
sort = {},
|
|
11741
11741
|
status = "active",
|
|
11742
|
-
nature = ""
|
|
11742
|
+
nature = "",
|
|
11743
|
+
scope
|
|
11743
11744
|
}) {
|
|
11744
11745
|
const query2 = { status };
|
|
11745
11746
|
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
@@ -11749,6 +11750,22 @@ function useOrgRepo() {
|
|
|
11749
11750
|
page,
|
|
11750
11751
|
limit
|
|
11751
11752
|
};
|
|
11753
|
+
if (scope) {
|
|
11754
|
+
const ids2 = Array.from(
|
|
11755
|
+
new Set((scope.orgIds ?? []).filter((id) => import_mongodb19.ObjectId.isValid(id)))
|
|
11756
|
+
).sort();
|
|
11757
|
+
const email = (scope.email ?? "").trim();
|
|
11758
|
+
const reach = [];
|
|
11759
|
+
if (ids2.length)
|
|
11760
|
+
reach.push({ _id: { $in: ids2.map((id) => new import_mongodb19.ObjectId(id)) } });
|
|
11761
|
+
if (email)
|
|
11762
|
+
reach.push({ email });
|
|
11763
|
+
if (!reach.length) {
|
|
11764
|
+
return (0, import_node_server_utils21.paginate)([], page > 0 ? page - 1 : 0, limit, 0);
|
|
11765
|
+
}
|
|
11766
|
+
query2.$or = reach;
|
|
11767
|
+
cacheOptions.scope = `${ids2.join(",")}|${email.toLowerCase()}`;
|
|
11768
|
+
}
|
|
11752
11769
|
if (search) {
|
|
11753
11770
|
query2.$text = { $search: search };
|
|
11754
11771
|
cacheOptions.search = search;
|
|
@@ -27890,11 +27907,19 @@ function useOrgController() {
|
|
|
27890
27907
|
const limit = parseInt(req.query.limit ?? "10");
|
|
27891
27908
|
const nature = req.query.nature ?? "";
|
|
27892
27909
|
try {
|
|
27910
|
+
const id = callerId(req);
|
|
27911
|
+
const actor = await resolveInviteActor(id);
|
|
27912
|
+
let scope;
|
|
27913
|
+
if (!actor.isSuperAdmin) {
|
|
27914
|
+
const self = await _getUserById(id).catch(() => null);
|
|
27915
|
+
scope = { orgIds: actor.orgIds, email: self?.email ?? "" };
|
|
27916
|
+
}
|
|
27893
27917
|
const data = await _getAll({
|
|
27894
27918
|
search,
|
|
27895
27919
|
page,
|
|
27896
27920
|
limit,
|
|
27897
|
-
nature
|
|
27921
|
+
nature,
|
|
27922
|
+
scope
|
|
27898
27923
|
});
|
|
27899
27924
|
res.json(data);
|
|
27900
27925
|
return;
|
|
@@ -31336,6 +31361,7 @@ function usePromoCodeController() {
|
|
|
31336
31361
|
return;
|
|
31337
31362
|
}
|
|
31338
31363
|
try {
|
|
31364
|
+
await requirePlatformStaff(req);
|
|
31339
31365
|
const data = await _getById(_id);
|
|
31340
31366
|
res.json(data);
|
|
31341
31367
|
return;
|
|
@@ -31364,6 +31390,7 @@ function usePromoCodeController() {
|
|
|
31364
31390
|
const limit = parseInt(req.query.limit ?? "10");
|
|
31365
31391
|
const status = req.query.status ?? "active";
|
|
31366
31392
|
try {
|
|
31393
|
+
await requirePlatformStaff(req);
|
|
31367
31394
|
const data = await _getPromoCodes({
|
|
31368
31395
|
search,
|
|
31369
31396
|
page,
|
|
@@ -62014,6 +62041,24 @@ function UseAccessManagementRepo() {
|
|
|
62014
62041
|
throw new Error(error.message);
|
|
62015
62042
|
}
|
|
62016
62043
|
}
|
|
62044
|
+
async function cardSitesRepo(cardIds) {
|
|
62045
|
+
try {
|
|
62046
|
+
const ids2 = cardIds.map((id) => new import_mongodb121.ObjectId(id));
|
|
62047
|
+
return await collection().find({ _id: { $in: ids2 } }, { projection: { site: 1, org: 1 } }).toArray();
|
|
62048
|
+
} catch (error) {
|
|
62049
|
+
throw new Error(error.message);
|
|
62050
|
+
}
|
|
62051
|
+
}
|
|
62052
|
+
async function unitSiteRepo(unitId) {
|
|
62053
|
+
try {
|
|
62054
|
+
return await collectionName("building-units").findOne(
|
|
62055
|
+
{ _id: new import_mongodb121.ObjectId(unitId) },
|
|
62056
|
+
{ projection: { site: 1, org: 1 } }
|
|
62057
|
+
);
|
|
62058
|
+
} catch (error) {
|
|
62059
|
+
throw new Error(error.message);
|
|
62060
|
+
}
|
|
62061
|
+
}
|
|
62017
62062
|
async function accessManagementSettingsRepo(params) {
|
|
62018
62063
|
try {
|
|
62019
62064
|
params.site = new import_mongodb121.ObjectId(params.site);
|
|
@@ -64696,6 +64741,8 @@ function UseAccessManagementRepo() {
|
|
|
64696
64741
|
createIndexForEntrypass,
|
|
64697
64742
|
addPhysicalCardRepo,
|
|
64698
64743
|
addNonPhysicalCardRepo,
|
|
64744
|
+
cardSitesRepo,
|
|
64745
|
+
unitSiteRepo,
|
|
64699
64746
|
accessManagementSettingsRepo,
|
|
64700
64747
|
allAccessCardsCountsRepo,
|
|
64701
64748
|
availableAccessCardsRepo,
|
|
@@ -64748,6 +64795,8 @@ function useAccessManagementSvc() {
|
|
|
64748
64795
|
const {
|
|
64749
64796
|
addPhysicalCardRepo,
|
|
64750
64797
|
addNonPhysicalCardRepo,
|
|
64798
|
+
cardSitesRepo,
|
|
64799
|
+
unitSiteRepo,
|
|
64751
64800
|
accessManagementSettingsRepo,
|
|
64752
64801
|
allAccessCardsCountsRepo,
|
|
64753
64802
|
availableAccessCardsRepo,
|
|
@@ -64888,6 +64937,20 @@ function useAccessManagementSvc() {
|
|
|
64888
64937
|
throw new Error(err.message);
|
|
64889
64938
|
}
|
|
64890
64939
|
};
|
|
64940
|
+
const cardSitesSvc = async (cardIds) => {
|
|
64941
|
+
try {
|
|
64942
|
+
return await cardSitesRepo(cardIds);
|
|
64943
|
+
} catch (err) {
|
|
64944
|
+
throw new Error(err.message);
|
|
64945
|
+
}
|
|
64946
|
+
};
|
|
64947
|
+
const unitSiteSvc = async (unitId) => {
|
|
64948
|
+
try {
|
|
64949
|
+
return await unitSiteRepo(unitId);
|
|
64950
|
+
} catch (err) {
|
|
64951
|
+
throw new Error(err.message);
|
|
64952
|
+
}
|
|
64953
|
+
};
|
|
64891
64954
|
const accessManagementSettingsSvc = async (settings) => {
|
|
64892
64955
|
try {
|
|
64893
64956
|
const response = await accessManagementSettingsRepo({ ...settings });
|
|
@@ -65249,6 +65312,8 @@ function useAccessManagementSvc() {
|
|
|
65249
65312
|
accessGroupsSvc,
|
|
65250
65313
|
setCache,
|
|
65251
65314
|
getCache,
|
|
65315
|
+
cardSitesSvc,
|
|
65316
|
+
unitSiteSvc,
|
|
65252
65317
|
accessManagementSettingsSvc,
|
|
65253
65318
|
allAccessCardsCountsSvc,
|
|
65254
65319
|
availableAccessCardsSvc,
|
|
@@ -65301,6 +65366,26 @@ function useAccessManagementController() {
|
|
|
65301
65366
|
return true;
|
|
65302
65367
|
}
|
|
65303
65368
|
};
|
|
65369
|
+
const refuseUnreachableCards = async (req, res, cardIds) => {
|
|
65370
|
+
const ids2 = [...new Set(cardIds.map((id) => String(id)))];
|
|
65371
|
+
const cards = await cardSitesSvc(ids2);
|
|
65372
|
+
const { canReach } = await siteReachOf(req);
|
|
65373
|
+
const reached = await Promise.all(cards.map((card) => canReach(card)));
|
|
65374
|
+
if (cards.length !== ids2.length || reached.includes(false)) {
|
|
65375
|
+
res.status(404).json({ data: null, message: "Card not found." });
|
|
65376
|
+
return true;
|
|
65377
|
+
}
|
|
65378
|
+
return false;
|
|
65379
|
+
};
|
|
65380
|
+
const refuseUnreachableUnit = async (req, res, unitId) => {
|
|
65381
|
+
const unit = await unitSiteSvc(unitId);
|
|
65382
|
+
const { canReach } = await siteReachOf(req);
|
|
65383
|
+
if (!await canReach(unit)) {
|
|
65384
|
+
res.status(404).json({ data: null, message: "Unit not found." });
|
|
65385
|
+
return true;
|
|
65386
|
+
}
|
|
65387
|
+
return false;
|
|
65388
|
+
};
|
|
65304
65389
|
const {
|
|
65305
65390
|
addPhysicalCardSvc,
|
|
65306
65391
|
addNonPhysicalCardSvc,
|
|
@@ -65309,6 +65394,8 @@ function useAccessManagementController() {
|
|
|
65309
65394
|
accessGroupsSvc,
|
|
65310
65395
|
setCache,
|
|
65311
65396
|
getCache,
|
|
65397
|
+
cardSitesSvc,
|
|
65398
|
+
unitSiteSvc,
|
|
65312
65399
|
accessManagementSettingsSvc,
|
|
65313
65400
|
allAccessCardsCountsSvc,
|
|
65314
65401
|
availableAccessCardsSvc,
|
|
@@ -65528,6 +65615,8 @@ function useAccessManagementController() {
|
|
|
65528
65615
|
const accessManagementSettings = async (req, res) => {
|
|
65529
65616
|
try {
|
|
65530
65617
|
const settings = req.body;
|
|
65618
|
+
if (await refuseUnreachableSite(req, res, settings?.site))
|
|
65619
|
+
return;
|
|
65531
65620
|
const result = await accessManagementSettingsSvc(settings);
|
|
65532
65621
|
return res.status(201).json({ message: "Success", data: result });
|
|
65533
65622
|
} catch (error) {
|
|
@@ -65827,6 +65916,8 @@ function useAccessManagementController() {
|
|
|
65827
65916
|
if (error) {
|
|
65828
65917
|
return res.status(400).json({ message: error.message });
|
|
65829
65918
|
}
|
|
65919
|
+
if (await refuseUnreachableCards(req, res, nfcList.map((nfc) => nfc._id)))
|
|
65920
|
+
return;
|
|
65830
65921
|
const result = await updateNFCStatusSvc({ nfcList, visitorId });
|
|
65831
65922
|
return res.status(200).json({ message: "Success", data: result });
|
|
65832
65923
|
} catch (error) {
|
|
@@ -65879,6 +65970,10 @@ function useAccessManagementController() {
|
|
|
65879
65970
|
if (error) {
|
|
65880
65971
|
return res.status(400).json({ message: error.message });
|
|
65881
65972
|
}
|
|
65973
|
+
if (await refuseUnreachableCards(req, res, [cardId, issuedCardId]))
|
|
65974
|
+
return;
|
|
65975
|
+
if (await refuseUnreachableUnit(req, res, unitId))
|
|
65976
|
+
return;
|
|
65882
65977
|
const result = await cardReplacementSvc({
|
|
65883
65978
|
cardId,
|
|
65884
65979
|
remarks,
|
|
@@ -66083,6 +66178,8 @@ function useAccessManagementController() {
|
|
|
66083
66178
|
if (error) {
|
|
66084
66179
|
return res.status(400).json({ message: error.message });
|
|
66085
66180
|
}
|
|
66181
|
+
if (await refuseUnreachableCards(req, res, [cardId]))
|
|
66182
|
+
return;
|
|
66086
66183
|
const result = await deleteCardSvc({ cardId, remarks });
|
|
66087
66184
|
return res.status(200).json({ message: "Success", data: result });
|
|
66088
66185
|
} catch (error) {
|
|
@@ -66302,6 +66399,8 @@ function useAccessManagementController() {
|
|
|
66302
66399
|
if (error) {
|
|
66303
66400
|
return res.status(400).json({ message: error.message });
|
|
66304
66401
|
}
|
|
66402
|
+
if (await refuseUnreachableCards(req, res, [cardId]))
|
|
66403
|
+
return;
|
|
66305
66404
|
const result = await signQrCodeSvc({ cardId, purpose });
|
|
66306
66405
|
return res.status(200).json({ message: "Success", data: result });
|
|
66307
66406
|
} catch (error) {
|
|
@@ -66328,6 +66427,8 @@ function useAccessManagementController() {
|
|
|
66328
66427
|
if (error) {
|
|
66329
66428
|
return res.status(400).json({ message: error.message });
|
|
66330
66429
|
}
|
|
66430
|
+
if (await refuseUnreachableCards(req, res, cards.map((card) => card.cardId)))
|
|
66431
|
+
return;
|
|
66331
66432
|
const result = await checkoutVisitorSvc({ cards });
|
|
66332
66433
|
return res.status(200).json({ message: "Success", data: result });
|
|
66333
66434
|
} catch (error) {
|
|
@@ -66407,6 +66508,10 @@ function useAccessManagementController() {
|
|
|
66407
66508
|
if (error) {
|
|
66408
66509
|
throw new Error(`${error.message}`);
|
|
66409
66510
|
}
|
|
66511
|
+
if (await refuseUnreachableUnit(req, res, unit))
|
|
66512
|
+
return;
|
|
66513
|
+
if (id && await refuseUnreachableCards(req, res, [id]))
|
|
66514
|
+
return;
|
|
66410
66515
|
const result = await assignMultipleCardsSvc({
|
|
66411
66516
|
assignees,
|
|
66412
66517
|
unit,
|