@7365admin1/core 3.64.3-staging.284 → 3.64.3-staging.286
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/hid-profile-qr-backend.md +31 -0
- package/.changeset/hid-reader-user-search.md +22 -0
- package/dist/index.d.ts +45 -1
- package/dist/index.js +391 -86
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +391 -86
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/test/resident-login-account.test.mjs +126 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
"@7365admin1/core": minor
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Let a signed-in member hold their own HID QR code.
|
|
6
|
+
|
|
7
|
+
`GET`, `POST` and `DELETE /readers/:readerId/profile-qr` read, issue and revoke
|
|
8
|
+
the caller's own QR credential on one reader. The caller comes from the session,
|
|
9
|
+
so there is no user id in the path to point at somebody else, and each handler
|
|
10
|
+
calls `authorizeReader` for itself rather than trusting the router - the site is
|
|
11
|
+
re-resolved from the stored reader record.
|
|
12
|
+
|
|
13
|
+
The credential is the visitor mechanism: an alphanumeric value in the reader's
|
|
14
|
+
`qrcodes` table, with the reader put into the QR-readable configuration first.
|
|
15
|
+
Unlike a visitor pass it carries no validity window, matching the member's
|
|
16
|
+
facial enrollment, which is standing until removed. Issuing replaces any earlier
|
|
17
|
+
code for that member on that reader, and the replacement is written and verified
|
|
18
|
+
before the old one is removed.
|
|
19
|
+
|
|
20
|
+
It creates no access rule, deliberately. `setProfileFacial` beside it does not
|
|
21
|
+
either: a member's door access comes from the HID permissions screen, and
|
|
22
|
+
minting a rule here would mean anyone who can press Generate admits themselves.
|
|
23
|
+
The read reports whether that screen admits them, resolved through
|
|
24
|
+
`resolvePermissionUserBindings` - the same resolver that writes the rules onto
|
|
25
|
+
the device - so the answer is the one the reader will actually be asked.
|
|
26
|
+
|
|
27
|
+
Two settings are now readable that were already writable: the QR identification
|
|
28
|
+
and legacy-mode flags `configureVisitorQrReader` sets on every issue, plus
|
|
29
|
+
`access_rule_time_zones` alongside its two sibling link tables. Whether a reader
|
|
30
|
+
was set up to accept a QR, and whether an access rule had a schedule, were
|
|
31
|
+
invisible to every screen and every diagnosis.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
"@7365admin1/core": patch
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Make the search on the HID reader user roster work.
|
|
6
|
+
|
|
7
|
+
`listReaderUsers` asked the device to filter. Amico's `where` takes a value or a
|
|
8
|
+
list of values per column and has no operator form, so the substring clause it
|
|
9
|
+
sent for a text term, `{name: {LIKE: "%x%"}}`, was answered
|
|
10
|
+
`400 Invalid value (string or array expected)`. Every search by name threw, and
|
|
11
|
+
the screen showed "Unable to load HID users from reader" with an empty table.
|
|
12
|
+
|
|
13
|
+
A numeric term took a different branch that matched the HID user id exactly.
|
|
14
|
+
That did not fail, it answered wrongly: searching a registration number like
|
|
15
|
+
`000004` resolved to `id = 4` and returned a different person.
|
|
16
|
+
|
|
17
|
+
Rows are already pulled in one page and filtered here for `userType`, so the
|
|
18
|
+
search now joins that filter as a case-insensitive substring over name, id and
|
|
19
|
+
registration - the same three fields, and the same "contains" semantics, the
|
|
20
|
+
identities search uses. Verified against a live reader: a name matches
|
|
21
|
+
partially and case-insensitively, a registration number returns its own user,
|
|
22
|
+
a full UID still works, and no match returns an empty page rather than an error.
|
package/dist/index.d.ts
CHANGED
|
@@ -4851,7 +4851,6 @@ declare function MPerson(value: TPerson): {
|
|
|
4851
4851
|
end: string | Date | undefined;
|
|
4852
4852
|
type: "resident" | "walk-in" | "drop-off" | "contractor" | "delivery" | "pick-up" | "guest" | "tenant" | undefined;
|
|
4853
4853
|
email: string | undefined;
|
|
4854
|
-
password: string;
|
|
4855
4854
|
status: string;
|
|
4856
4855
|
nric: string | undefined;
|
|
4857
4856
|
remarks: string | undefined;
|
|
@@ -12643,6 +12642,48 @@ declare function useHidAmicoService(): {
|
|
|
12643
12642
|
facialEnrolled: boolean;
|
|
12644
12643
|
facialEnrolledAt: string;
|
|
12645
12644
|
}>;
|
|
12645
|
+
getProfileQr: (readerId: string, userId: string) => Promise<{
|
|
12646
|
+
readerId: string;
|
|
12647
|
+
userId: string;
|
|
12648
|
+
memberId: string;
|
|
12649
|
+
hidUserId: string;
|
|
12650
|
+
registration: string;
|
|
12651
|
+
readerName: string;
|
|
12652
|
+
portalName: string;
|
|
12653
|
+
qrEnabled: boolean;
|
|
12654
|
+
issued: boolean;
|
|
12655
|
+
qrValue: string;
|
|
12656
|
+
issuedAt: string;
|
|
12657
|
+
assigned: boolean | null;
|
|
12658
|
+
}>;
|
|
12659
|
+
issueProfileQr: (readerId: string, userId: string) => Promise<{
|
|
12660
|
+
readerId: string;
|
|
12661
|
+
userId: string;
|
|
12662
|
+
memberId: string;
|
|
12663
|
+
hidUserId: string;
|
|
12664
|
+
registration: string;
|
|
12665
|
+
readerName: string;
|
|
12666
|
+
portalName: string;
|
|
12667
|
+
qrEnabled: boolean;
|
|
12668
|
+
issued: boolean;
|
|
12669
|
+
qrValue: string;
|
|
12670
|
+
issuedAt: string;
|
|
12671
|
+
assigned: boolean | null;
|
|
12672
|
+
}>;
|
|
12673
|
+
deleteProfileQr: (readerId: string, userId: string) => Promise<{
|
|
12674
|
+
readerId: string;
|
|
12675
|
+
userId: string;
|
|
12676
|
+
memberId: string;
|
|
12677
|
+
hidUserId: string;
|
|
12678
|
+
registration: string;
|
|
12679
|
+
readerName: string;
|
|
12680
|
+
portalName: string;
|
|
12681
|
+
qrEnabled: boolean;
|
|
12682
|
+
issued: boolean;
|
|
12683
|
+
qrValue: string;
|
|
12684
|
+
issuedAt: string;
|
|
12685
|
+
assigned: boolean | null;
|
|
12686
|
+
}>;
|
|
12646
12687
|
setProfileFacial: (readerId: string, userId: string, image: Buffer, options?: {
|
|
12647
12688
|
timestamp?: number;
|
|
12648
12689
|
match?: boolean;
|
|
@@ -12892,6 +12933,9 @@ declare function useHidAmicoController(): {
|
|
|
12892
12933
|
revokeVisitorQr: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
12893
12934
|
getProfileFacial: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
12894
12935
|
setProfileFacial: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
12936
|
+
getProfileQr: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
12937
|
+
issueProfileQr: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
12938
|
+
deleteProfileQr: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
12895
12939
|
setVisitorImage: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
12896
12940
|
deleteVisitorImage: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
12897
12941
|
getIntercomStatus: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|