@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.
@@ -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>;