@7365admin1/core 3.8.0 → 3.9.0
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/CHANGELOG.md +6 -0
- package/dist/index.d.ts +382 -7
- package/dist/index.js +2132 -503
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1980 -373
- package/dist/index.mjs.map +1 -1
- package/docs/hid-amico-diagram.md +201 -0
- package/docs/hid-amico-integration.md +491 -0
- package/docs/hid-amico-postman-api.md +614 -0
- package/docs/hid-amico-ui-design-scope.md +441 -0
- package/package.json +1 -1
|
@@ -0,0 +1,614 @@
|
|
|
1
|
+
# HID Amico Postman API Guide
|
|
2
|
+
|
|
3
|
+
Use this guide to test the iService365 HID Amico backend with Postman.
|
|
4
|
+
|
|
5
|
+
## 1. Postman Environment
|
|
6
|
+
|
|
7
|
+
Create an environment, for example `HID`, with these variables:
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
base_url=http://localhost:5001
|
|
11
|
+
hid_base_url={{base_url}}/api/access-management/hid
|
|
12
|
+
sid=
|
|
13
|
+
siteId=
|
|
14
|
+
readerId=
|
|
15
|
+
identityId=
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Local API-core usually runs on:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
http://localhost:5001
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The HID module route is:
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
{{base_url}}/api/access-management/hid
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Do not use:
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
/api/readers
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
That route does not exist.
|
|
37
|
+
|
|
38
|
+
## 2. Login
|
|
39
|
+
|
|
40
|
+
Request:
|
|
41
|
+
|
|
42
|
+
```text
|
|
43
|
+
POST {{base_url}}/api/auth
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Body:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"email": "<admin email>",
|
|
51
|
+
"password": "<admin password>"
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Expected response:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"sid": "<session id>",
|
|
60
|
+
"user": "<user id>"
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Set environment variable:
|
|
65
|
+
|
|
66
|
+
```text
|
|
67
|
+
sid=<response.sid>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
For protected HID APIs, use:
|
|
71
|
+
|
|
72
|
+
```text
|
|
73
|
+
Authorization: Bearer {{sid}}
|
|
74
|
+
Content-Type: application/json
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## 3. Create Reader
|
|
78
|
+
|
|
79
|
+
Request:
|
|
80
|
+
|
|
81
|
+
```text
|
|
82
|
+
POST {{hid_base_url}}/readers
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Headers:
|
|
86
|
+
|
|
87
|
+
```text
|
|
88
|
+
Authorization: Bearer {{sid}}
|
|
89
|
+
Content-Type: application/json
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Body:
|
|
93
|
+
|
|
94
|
+
```json
|
|
95
|
+
{
|
|
96
|
+
"site": "{{siteId}}",
|
|
97
|
+
"name": "Philippines HID Amico",
|
|
98
|
+
"location": "Lobby",
|
|
99
|
+
"baseUrl": "http://192.168.20.123",
|
|
100
|
+
"username": "<hid username>",
|
|
101
|
+
"password": "<hid password>",
|
|
102
|
+
"deviceId": "PH-HID-01",
|
|
103
|
+
"monitorPath": "api/access-management/hid/notifications",
|
|
104
|
+
"enabled": true,
|
|
105
|
+
"status": "active"
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Copy response:
|
|
110
|
+
|
|
111
|
+
```text
|
|
112
|
+
data._id -> readerId
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Notes:
|
|
116
|
+
|
|
117
|
+
- `password` is encrypted before saving.
|
|
118
|
+
- Response will not return the password.
|
|
119
|
+
- Response includes `passwordSet`.
|
|
120
|
+
|
|
121
|
+
## 4. List Readers
|
|
122
|
+
|
|
123
|
+
Request:
|
|
124
|
+
|
|
125
|
+
```text
|
|
126
|
+
GET {{hid_base_url}}/readers?site={{siteId}}&page=1&limit=10
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Headers:
|
|
130
|
+
|
|
131
|
+
```text
|
|
132
|
+
Authorization: Bearer {{sid}}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## 5. Test Reader Connection
|
|
136
|
+
|
|
137
|
+
Request:
|
|
138
|
+
|
|
139
|
+
```text
|
|
140
|
+
POST {{hid_base_url}}/readers/{{readerId}}/test
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Headers:
|
|
144
|
+
|
|
145
|
+
```text
|
|
146
|
+
Authorization: Bearer {{sid}}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
This tests:
|
|
150
|
+
|
|
151
|
+
```text
|
|
152
|
+
/hidlogin.fcgi
|
|
153
|
+
/session_is_valid.fcgi
|
|
154
|
+
/logout.fcgi
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Expected success:
|
|
158
|
+
|
|
159
|
+
```json
|
|
160
|
+
{
|
|
161
|
+
"data": {
|
|
162
|
+
"valid": true,
|
|
163
|
+
"message": "HID Amico connection test succeeded."
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## 6. Load HID Users
|
|
169
|
+
|
|
170
|
+
Request:
|
|
171
|
+
|
|
172
|
+
```text
|
|
173
|
+
POST {{hid_base_url}}/readers/{{readerId}}/objects
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Headers:
|
|
177
|
+
|
|
178
|
+
```text
|
|
179
|
+
Authorization: Bearer {{sid}}
|
|
180
|
+
Content-Type: application/json
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Body:
|
|
184
|
+
|
|
185
|
+
```json
|
|
186
|
+
{
|
|
187
|
+
"operation": "load",
|
|
188
|
+
"object": "users",
|
|
189
|
+
"limit": 50,
|
|
190
|
+
"offset": 0
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Known response shape:
|
|
195
|
+
|
|
196
|
+
```json
|
|
197
|
+
{
|
|
198
|
+
"data": {
|
|
199
|
+
"users": [
|
|
200
|
+
{
|
|
201
|
+
"id": 3,
|
|
202
|
+
"name": "Harris",
|
|
203
|
+
"registration": "",
|
|
204
|
+
"image_timestamp": 1780498277,
|
|
205
|
+
"last_access": 1780505386
|
|
206
|
+
}
|
|
207
|
+
]
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## 7. Load Access Logs
|
|
213
|
+
|
|
214
|
+
Request:
|
|
215
|
+
|
|
216
|
+
```text
|
|
217
|
+
POST {{hid_base_url}}/readers/{{readerId}}/objects
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Body:
|
|
221
|
+
|
|
222
|
+
```json
|
|
223
|
+
{
|
|
224
|
+
"operation": "load",
|
|
225
|
+
"object": "access_logs",
|
|
226
|
+
"limit": 50,
|
|
227
|
+
"offset": 0
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Known response shape:
|
|
232
|
+
|
|
233
|
+
```json
|
|
234
|
+
{
|
|
235
|
+
"data": {
|
|
236
|
+
"access_logs": [
|
|
237
|
+
{
|
|
238
|
+
"id": 1,
|
|
239
|
+
"time": 1780561438,
|
|
240
|
+
"event": 7,
|
|
241
|
+
"device_id": 14227560204339188,
|
|
242
|
+
"identifier_id": 1717658368,
|
|
243
|
+
"user_id": 3,
|
|
244
|
+
"portal_id": 1,
|
|
245
|
+
"identification_rule_id": 1,
|
|
246
|
+
"card_value": 0,
|
|
247
|
+
"qrcode_value": "",
|
|
248
|
+
"pin_value": "",
|
|
249
|
+
"confidence": 922,
|
|
250
|
+
"mask": 0,
|
|
251
|
+
"log_type_id": -1
|
|
252
|
+
}
|
|
253
|
+
]
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
`time` is Unix seconds. Example:
|
|
259
|
+
|
|
260
|
+
```text
|
|
261
|
+
1780561438 = 2026-06-04 16:23:58 Asia/Manila
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## 8. Filter Access Logs
|
|
265
|
+
|
|
266
|
+
Some HID firmware expects `where` to be nested by object/table name.
|
|
267
|
+
|
|
268
|
+
Filter by HID `user_id`:
|
|
269
|
+
|
|
270
|
+
```json
|
|
271
|
+
{
|
|
272
|
+
"operation": "load",
|
|
273
|
+
"object": "access_logs",
|
|
274
|
+
"where": {
|
|
275
|
+
"access_logs": {
|
|
276
|
+
"user_id": 3
|
|
277
|
+
}
|
|
278
|
+
},
|
|
279
|
+
"limit": 20,
|
|
280
|
+
"offset": 0
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Filter by id:
|
|
285
|
+
|
|
286
|
+
```json
|
|
287
|
+
{
|
|
288
|
+
"operation": "load",
|
|
289
|
+
"object": "access_logs",
|
|
290
|
+
"where": {
|
|
291
|
+
"access_logs": {
|
|
292
|
+
"id": 1
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
"limit": 1
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
If HID returns:
|
|
300
|
+
|
|
301
|
+
```text
|
|
302
|
+
Invalid object (object expected)
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Check that `where` is nested correctly.
|
|
306
|
+
|
|
307
|
+
## 9. Create Identity Mapping
|
|
308
|
+
|
|
309
|
+
This maps a HID user/card to an iService365 record.
|
|
310
|
+
|
|
311
|
+
Request:
|
|
312
|
+
|
|
313
|
+
```text
|
|
314
|
+
POST {{hid_base_url}}/readers/{{readerId}}/identities
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Body:
|
|
318
|
+
|
|
319
|
+
```json
|
|
320
|
+
{
|
|
321
|
+
"hidUserId": "3",
|
|
322
|
+
"registration": "",
|
|
323
|
+
"cardNo": "",
|
|
324
|
+
"user": "<iService365 user ObjectId>",
|
|
325
|
+
"type": "staff",
|
|
326
|
+
"metadata": {
|
|
327
|
+
"source": "manual"
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
At least one is required:
|
|
333
|
+
|
|
334
|
+
```text
|
|
335
|
+
hidUserId
|
|
336
|
+
registration
|
|
337
|
+
cardNo
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
Supported `type` values:
|
|
341
|
+
|
|
342
|
+
```text
|
|
343
|
+
resident
|
|
344
|
+
staff
|
|
345
|
+
contractor
|
|
346
|
+
visitor
|
|
347
|
+
unknown
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
Copy response:
|
|
351
|
+
|
|
352
|
+
```text
|
|
353
|
+
data._id -> identityId
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
## 10. List Identity Mappings
|
|
357
|
+
|
|
358
|
+
Request:
|
|
359
|
+
|
|
360
|
+
```text
|
|
361
|
+
GET {{hid_base_url}}/readers/{{readerId}}/identities?page=1&limit=20
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
Filters:
|
|
365
|
+
|
|
366
|
+
```text
|
|
367
|
+
GET {{hid_base_url}}/readers/{{readerId}}/identities?type=staff
|
|
368
|
+
GET {{hid_base_url}}/readers/{{readerId}}/identities?status=active
|
|
369
|
+
GET {{hid_base_url}}/readers/{{readerId}}/identities?search=Harris
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
## 11. Update Identity Mapping
|
|
373
|
+
|
|
374
|
+
Request:
|
|
375
|
+
|
|
376
|
+
```text
|
|
377
|
+
PATCH {{hid_base_url}}/identities/{{identityId}}
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
Body:
|
|
381
|
+
|
|
382
|
+
```json
|
|
383
|
+
{
|
|
384
|
+
"type": "staff",
|
|
385
|
+
"metadata": {
|
|
386
|
+
"note": "Updated from Postman"
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
## 12. Delete Identity Mapping
|
|
392
|
+
|
|
393
|
+
Request:
|
|
394
|
+
|
|
395
|
+
```text
|
|
396
|
+
DELETE {{hid_base_url}}/identities/{{identityId}}
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
This marks the mapping as deleted.
|
|
400
|
+
|
|
401
|
+
## 13. Backend Event Logs
|
|
402
|
+
|
|
403
|
+
Request:
|
|
404
|
+
|
|
405
|
+
```text
|
|
406
|
+
GET {{hid_base_url}}/readers/{{readerId}}/logs?page=1&limit=20
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
Filter by event type:
|
|
410
|
+
|
|
411
|
+
```text
|
|
412
|
+
GET {{hid_base_url}}/readers/{{readerId}}/logs?page=1&limit=20&type=objects_load
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
These are iService365 backend logs, not the same as raw HID `access_logs`.
|
|
416
|
+
|
|
417
|
+
## 14. Notification Callback
|
|
418
|
+
|
|
419
|
+
This endpoint is for HID reader callbacks and does not require auth.
|
|
420
|
+
|
|
421
|
+
Request:
|
|
422
|
+
|
|
423
|
+
```text
|
|
424
|
+
POST {{hid_base_url}}/notifications/{{readerId}}/new_user_identified
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
Example test body:
|
|
428
|
+
|
|
429
|
+
```json
|
|
430
|
+
{
|
|
431
|
+
"user_id": 3,
|
|
432
|
+
"name": "Harris",
|
|
433
|
+
"time": 1780561438
|
|
434
|
+
}
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
The backend tries to resolve identity using:
|
|
438
|
+
|
|
439
|
+
```text
|
|
440
|
+
hidUserId
|
|
441
|
+
registration
|
|
442
|
+
cardNo
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
If no mapping exists, the event is still saved with:
|
|
446
|
+
|
|
447
|
+
```json
|
|
448
|
+
{
|
|
449
|
+
"identity": null,
|
|
450
|
+
"identityLookup": {
|
|
451
|
+
"hidUserId": 3
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
## 15. Sync Reader
|
|
457
|
+
|
|
458
|
+
Request:
|
|
459
|
+
|
|
460
|
+
```text
|
|
461
|
+
POST {{hid_base_url}}/readers/{{readerId}}/sync
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
Body:
|
|
465
|
+
|
|
466
|
+
```json
|
|
467
|
+
{
|
|
468
|
+
"objects": [
|
|
469
|
+
{
|
|
470
|
+
"object": "users",
|
|
471
|
+
"values": []
|
|
472
|
+
}
|
|
473
|
+
]
|
|
474
|
+
}
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
Short form:
|
|
478
|
+
|
|
479
|
+
```json
|
|
480
|
+
{
|
|
481
|
+
"users": [],
|
|
482
|
+
"cards": [],
|
|
483
|
+
"qrcodes": [],
|
|
484
|
+
"pins": []
|
|
485
|
+
}
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
Current sync is a convenience wrapper around HID `create_objects.fcgi`.
|
|
489
|
+
|
|
490
|
+
## 16. Execute Actions
|
|
491
|
+
|
|
492
|
+
Request:
|
|
493
|
+
|
|
494
|
+
```text
|
|
495
|
+
POST {{hid_base_url}}/readers/{{readerId}}/actions
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
Body:
|
|
499
|
+
|
|
500
|
+
```json
|
|
501
|
+
{
|
|
502
|
+
"actions": [
|
|
503
|
+
{
|
|
504
|
+
"action": "<hid action name>",
|
|
505
|
+
"parameters": {}
|
|
506
|
+
}
|
|
507
|
+
]
|
|
508
|
+
}
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
Action payload depends on HID firmware support.
|
|
512
|
+
|
|
513
|
+
## 17. Door State
|
|
514
|
+
|
|
515
|
+
Request:
|
|
516
|
+
|
|
517
|
+
```text
|
|
518
|
+
GET {{hid_base_url}}/readers/{{readerId}}/door-state
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
Observed response from the tested reader:
|
|
522
|
+
|
|
523
|
+
```json
|
|
524
|
+
{
|
|
525
|
+
"error": "Invalid command: door_state",
|
|
526
|
+
"code": 1
|
|
527
|
+
}
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
This means the current firmware may not support `door_state.fcgi`. Treat this API as optional.
|
|
531
|
+
|
|
532
|
+
## 18. Delete Reader
|
|
533
|
+
|
|
534
|
+
Request:
|
|
535
|
+
|
|
536
|
+
```text
|
|
537
|
+
DELETE {{hid_base_url}}/readers/{{readerId}}
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
This marks the reader as deleted and disables it.
|
|
541
|
+
|
|
542
|
+
## Troubleshooting
|
|
543
|
+
|
|
544
|
+
### `Cannot GET /api/readers`
|
|
545
|
+
|
|
546
|
+
Use:
|
|
547
|
+
|
|
548
|
+
```text
|
|
549
|
+
/api/access-management/hid/readers
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
### `ECONNREFUSED 127.0.0.1:5001`
|
|
553
|
+
|
|
554
|
+
API-core is not running on port `5001`, or Postman `base_url` is wrong.
|
|
555
|
+
|
|
556
|
+
### `"site" must be a string`
|
|
557
|
+
|
|
558
|
+
The endpoint expects `site` in query/body. Check whether you are calling the correct endpoint and passing the correct payload.
|
|
559
|
+
|
|
560
|
+
### `"user" must only contain hexadecimal characters`
|
|
561
|
+
|
|
562
|
+
Fields such as `user`, `person`, `member`, and `visitor` must be MongoDB ObjectIds. Do not put HID user names or numeric HID ids into these fields.
|
|
563
|
+
|
|
564
|
+
Use HID ids in:
|
|
565
|
+
|
|
566
|
+
```text
|
|
567
|
+
hidUserId
|
|
568
|
+
registration
|
|
569
|
+
cardNo
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
### `Invalid object (object expected)`
|
|
573
|
+
|
|
574
|
+
For HID `load_objects.fcgi`, try nested `where`:
|
|
575
|
+
|
|
576
|
+
```json
|
|
577
|
+
{
|
|
578
|
+
"where": {
|
|
579
|
+
"access_logs": {
|
|
580
|
+
"user_id": 3
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
### `Invalid table events`
|
|
587
|
+
|
|
588
|
+
The tested reader does not expose an `events` table through `load_objects.fcgi`. Use:
|
|
589
|
+
|
|
590
|
+
```text
|
|
591
|
+
access_logs
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
### `Invalid command: door_state`
|
|
595
|
+
|
|
596
|
+
The current reader/firmware may not support `door_state.fcgi`.
|
|
597
|
+
|
|
598
|
+
### `401 Unauthorized`
|
|
599
|
+
|
|
600
|
+
Login again and set:
|
|
601
|
+
|
|
602
|
+
```text
|
|
603
|
+
Authorization: Bearer {{sid}}
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
### HID web portal works but API fails
|
|
607
|
+
|
|
608
|
+
Possible causes:
|
|
609
|
+
|
|
610
|
+
- Wrong HID object name.
|
|
611
|
+
- Wrong `where` shape.
|
|
612
|
+
- Unsupported firmware endpoint.
|
|
613
|
+
- Backend cannot reach reader through VPN/network.
|
|
614
|
+
- Wrong HID username/password saved in reader config.
|