@tsocial/tvweb-sdk.vib 5.0.0 → 5.2.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/assets/ic_close_black.png +0 -0
- package/assets/ic_loading.png +0 -0
- package/assets/qr_capture_cursor.png +0 -0
- package/build/tvweb-sdk.cjs.min.js +29 -23
- package/build/tvweb-sdk.vib.standalone.min.js +29 -23
- package/examples/extract-id-info-and-liveness-detection/index.html +147 -83
- package/examples/extract-id-info-and-liveness-detection/style.css +4 -0
- package/package.json +7 -7
- package/assets/id_card_bg_land.png +0 -0
- package/assets/id_card_mask_landscape.png +0 -0
- package/assets/id_card_mask_landscape.svg +0 -23
- package/assets/id_card_mask_portrait.png +0 -0
@@ -2,8 +2,12 @@
|
|
2
2
|
<html lang="en">
|
3
3
|
<head>
|
4
4
|
<meta charset="utf-8" />
|
5
|
-
<meta name="viewport" content="width=device-width
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
|
6
6
|
<meta name="description" content="Vanilla JS demo" />
|
7
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
8
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
9
|
+
<link href="https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200;0,300;0,400;0,600;0,700;0,800;0,900;1,200;1,300;1,400;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
|
10
|
+
|
7
11
|
<link rel="stylesheet" href="./style.css" />
|
8
12
|
</head>
|
9
13
|
<body>
|
@@ -16,8 +20,9 @@
|
|
16
20
|
Keys:
|
17
21
|
<select id="select-api-key" onchange="onSelectKey()">
|
18
22
|
<option value="0" selected>Web face tracking (..a31)</option>
|
19
|
-
<option value="1">
|
20
|
-
<option value="2">Labeller test
|
23
|
+
<option value="1">QA (..217)</option>
|
24
|
+
<option value="2">Labeller test real data (..3b2)</option>
|
25
|
+
<option value="3">Labeller test fake data (..ac4)</option>
|
21
26
|
</select>
|
22
27
|
</label>
|
23
28
|
</div>
|
@@ -40,27 +45,42 @@
|
|
40
45
|
</label>
|
41
46
|
</div>
|
42
47
|
<div>
|
43
|
-
Api check
|
48
|
+
Api check
|
44
49
|
<select id="select-api-check">
|
45
50
|
<option value="false">false</option>
|
46
51
|
<option value="true" selected>true</option>
|
47
52
|
</select>
|
48
53
|
</div>
|
49
54
|
|
50
|
-
<
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
+
<div style="margin-top: 10px;">
|
56
|
+
<label>
|
57
|
+
Cached User ID
|
58
|
+
<input id="user-id" readonly style="width: 300px" />
|
59
|
+
</label>
|
60
|
+
<button onclick="clearUserId()">Clear user id (x-request-id)</button>
|
55
61
|
</div>
|
56
|
-
|
57
|
-
|
58
|
-
<
|
62
|
+
|
63
|
+
<div style="display: inline-block; margin-top: 10px;">
|
64
|
+
<div>
|
65
|
+
Tracking config
|
66
|
+
<select id="select-tracking-config-template" onchange="onSelectTrackingConfigTemplate()">
|
67
|
+
<option value="0" selected>default</option>
|
68
|
+
<option value="1">Engineering test (...9fe5)</option>
|
69
|
+
</select>
|
70
|
+
</div>
|
71
|
+
<textarea cols="55" rows="8" id="tracking-config"></textarea>
|
59
72
|
</div>
|
60
|
-
|
61
|
-
|
73
|
+
|
74
|
+
<hr />
|
75
|
+
<h4>Extract ID Info</h4>
|
76
|
+
<div style="display: inline-block; margin-right: 20px;">
|
77
|
+
<div>Settings (notice that if <strong>Api check: true</strong>, settings from api will overwrite these settings)</div>
|
62
78
|
<textarea cols="55" rows="15" id="id-card-settings"></textarea>
|
63
79
|
</div>
|
80
|
+
<div style="display: inline-block">
|
81
|
+
<div>Steps</div>
|
82
|
+
<textarea cols="55" rows="15" id="id-card-steps"></textarea>
|
83
|
+
</div>
|
64
84
|
<div style="margin-bottom: 10px">
|
65
85
|
<button onclick="runWarmUpReadIDCard()">Warm up</button>
|
66
86
|
<span id="status-warmup-read-id-card"></span>
|
@@ -98,6 +118,8 @@
|
|
98
118
|
<div class="dot-windmill"></div>
|
99
119
|
</div>
|
100
120
|
<div id="result-liveness-detection"></div>
|
121
|
+
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
|
122
|
+
<script src="https://unpkg.com/@tsocial/trustvision-sdk@2.10.1/dist/trustvision-sdk.umd.js"></script>
|
101
123
|
<script src="../../build/tvweb-sdk.vib.standalone.min.js"></script>
|
102
124
|
<script>
|
103
125
|
const keys = [
|
@@ -105,6 +127,10 @@
|
|
105
127
|
accessKey: "f051dfd3-8a6e-4a15-a4e8-7ea8cdc84a31",
|
106
128
|
secretKey: "vgiKCenoKvhPq79KABbFmxCBu6WX1tdw",
|
107
129
|
},
|
130
|
+
{
|
131
|
+
accessKey: "b96f7a1a-a7f1-46e8-9d7f-5f43d2d51217",
|
132
|
+
secretKey: "SYsUyQ792pLm7rnDRQFfIL6cgAecZCOp",
|
133
|
+
},
|
108
134
|
{
|
109
135
|
accessKey: "db3d055f-ba7b-4177-b7e8-110068bda3b2",
|
110
136
|
secretKey: "R1zjKNbTH3RkT2xgO2CarxAsFbcLCdsf",
|
@@ -126,6 +152,7 @@
|
|
126
152
|
container: document.getElementById("container"),
|
127
153
|
lang: "vi",
|
128
154
|
assetRoot: "https://unpkg.com/@tsocial/tvweb-sdk.vib@latest/assets",
|
155
|
+
enableAntiDebug: false,
|
129
156
|
});
|
130
157
|
window.tv = tv;
|
131
158
|
const resultExtractIdInfoEl = document.getElementById(
|
@@ -136,20 +163,37 @@
|
|
136
163
|
);
|
137
164
|
const selectModeEl = document.getElementById("select-mode");
|
138
165
|
const selectApiCheckEl = document.getElementById("select-api-check");
|
139
|
-
const selectCardSideEl = document.getElementById("select-card-side");
|
140
166
|
const inputAccessKey = document.getElementById("access-key");
|
141
167
|
const inputSecretKey = document.getElementById("secret-key");
|
142
168
|
const inputApiUrl = document.getElementById("api-url");
|
143
|
-
const
|
169
|
+
const userIdEl = document.getElementById("user-id");
|
170
|
+
const trackingConfigEl = document.getElementById("tracking-config");
|
144
171
|
const readIdCardLoadingEl = document.getElementById("read-id-card-loading");
|
145
172
|
const customStepTimeConstraintsEl = document.getElementById("custom-step-time-constraints");
|
146
173
|
const statusWarmupReadIDCardEl = document.getElementById("status-warmup-read-id-card");
|
147
174
|
const livenessLoadingEl = document.getElementById("liveness-loading");
|
148
175
|
const startLivenessBtn = document.getElementById("btn-start-liveness");
|
149
176
|
const idCardSettingsEl = document.getElementById("id-card-settings");
|
177
|
+
const idCardStepsEl = document.getElementById("id-card-steps");
|
150
178
|
inputAccessKey.value = "f051dfd3-8a6e-4a15-a4e8-7ea8cdc84a31";
|
151
179
|
inputSecretKey.value = "vgiKCenoKvhPq79KABbFmxCBu6WX1tdw";
|
152
180
|
inputApiUrl.value = "https://tv-testing.trustingsocial.com/api";
|
181
|
+
userIdEl.value = JSON.parse(localStorage.getItem("user-id"));
|
182
|
+
|
183
|
+
const trackingConfigTemplates = [
|
184
|
+
TVWebSDK.TrackingContext.defaultTrackingConfig,
|
185
|
+
{
|
186
|
+
"enable": true,
|
187
|
+
"accessKey": "4df5f9b9-f34d-4ffa-829f-aa4889bc9fe5",
|
188
|
+
"secretKey": "dQDfxkVYXfAxpdReqdOd1zJP4pJ088Y7",
|
189
|
+
"apiUrl": "https://tv-testing.trustingsocial.com/api",
|
190
|
+
"userId": ""
|
191
|
+
},
|
192
|
+
];
|
193
|
+
function onSelectTrackingConfigTemplate() {
|
194
|
+
const selected = document.getElementById("select-tracking-config-template").value;
|
195
|
+
trackingConfigEl.value = JSON.stringify(trackingConfigTemplates[selected], null, 2);
|
196
|
+
}
|
153
197
|
|
154
198
|
Object.keys(TVWebSDK.Constants.Mode).forEach((k) => {
|
155
199
|
const option = document.createElement("option");
|
@@ -158,58 +202,22 @@
|
|
158
202
|
selectModeEl.appendChild(option);
|
159
203
|
});
|
160
204
|
|
161
|
-
Object.keys(TVWebSDK.Constants.IDCardSide).forEach((k) => {
|
162
|
-
const option = document.createElement("option");
|
163
|
-
option.appendChild(document.createTextNode(k));
|
164
|
-
option.setAttribute("value", TVWebSDK.Constants.IDCardSide[k]);
|
165
|
-
selectCardSideEl.appendChild(option);
|
166
|
-
});
|
167
|
-
|
168
205
|
const customStepTimeConstraintsData = {
|
169
206
|
[TVWebSDK.Constants.FaceDirection.UP]: { delayTime: 1000 },
|
170
207
|
[TVWebSDK.Constants.FaceDirection.LEFT]: { delayTime: 1000 },
|
171
208
|
[TVWebSDK.Constants.FaceDirection.RIGHT]: { delayTime: 1000 },
|
172
209
|
[TVWebSDK.Constants.FaceDirection.FRONTAL]: { delayTime: 2000 },
|
173
210
|
};
|
174
|
-
|
175
|
-
data: {
|
176
|
-
settings: {
|
177
|
-
sdk_settings: {
|
178
|
-
id_detection_settings: {
|
179
|
-
auto_capture: {
|
180
|
-
enable: true,
|
181
|
-
show_capture_button: true,
|
182
|
-
wait_for_best_image_time_ms: 3000,
|
183
|
-
},
|
184
|
-
blur_check: {
|
185
|
-
enable: true,
|
186
|
-
threshold: 0.82,
|
187
|
-
},
|
188
|
-
disable_capture_button_if_alert: true,
|
189
|
-
id_detection: {
|
190
|
-
enable: true,
|
191
|
-
},
|
192
|
-
limit_time_settings: {
|
193
|
-
enable: true,
|
194
|
-
limit_time_second: 30,
|
195
|
-
video_partial_length_seconds: 15,
|
196
|
-
},
|
197
|
-
save_frame_settings: {
|
198
|
-
enable: false,
|
199
|
-
frames_interval_ms: 190,
|
200
|
-
quality_web: 80,
|
201
|
-
},
|
202
|
-
scan_qr_settings: {
|
203
|
-
enable: true,
|
204
|
-
limit_time_second: 20,
|
205
|
-
},
|
206
|
-
},
|
207
|
-
},
|
208
|
-
},
|
209
|
-
},
|
210
|
-
};
|
211
|
+
|
211
212
|
customStepTimeConstraintsEl.value = JSON.stringify(customStepTimeConstraintsData, null, 2);
|
212
|
-
idCardSettingsEl.value = JSON.stringify(
|
213
|
+
idCardSettingsEl.value = JSON.stringify(TVWebSDK.defaultClientSettings, null, 2);
|
214
|
+
idCardStepsEl.value = JSON.stringify(TVWebSDK.defaultReadIDCardSteps, null, 2);
|
215
|
+
trackingConfigEl.value = JSON.stringify(TVWebSDK.TrackingContext.defaultTrackingConfig, null, 2);
|
216
|
+
|
217
|
+
function clearUserId() {
|
218
|
+
window.localStorage.removeItem('user-id');
|
219
|
+
userIdEl.value = JSON.parse(localStorage.getItem("user-id"));
|
220
|
+
}
|
213
221
|
|
214
222
|
function runWarmUpReadIDCard() {
|
215
223
|
statusWarmupReadIDCardEl.innerHTML = "..."
|
@@ -218,37 +226,94 @@
|
|
218
226
|
})
|
219
227
|
}
|
220
228
|
|
229
|
+
function handleStepDoneIDCard ({ stepNumber, image, qrScannedResult, recordedVideos, apiResult }) {
|
230
|
+
const steps = JSON.parse(idCardStepsEl.value)
|
231
|
+
|
232
|
+
resultExtractIdInfoEl.appendChild(document.createTextNode(`\n-----------------------------------------\n`))
|
233
|
+
resultExtractIdInfoEl.appendChild(document.createTextNode(`\nSTEP NUMBER ${stepNumber}:\n`));
|
234
|
+
const imgEl = document.createElement("img");
|
235
|
+
imgEl.width = "300";
|
236
|
+
imgEl.src = URL.createObjectURL(image.blob);
|
237
|
+
resultExtractIdInfoEl.appendChild(imgEl);
|
238
|
+
resultExtractIdInfoEl.appendChild(document.createElement("br"));
|
239
|
+
resultExtractIdInfoEl.appendChild(document.createTextNode(`Recorded videos: ${recordedVideos.length}\n`));
|
240
|
+
|
241
|
+
if (qrScannedResult) {
|
242
|
+
const { result, imageBlob } = qrScannedResult
|
243
|
+
|
244
|
+
const qrImgEl = document.createElement("img");
|
245
|
+
qrImgEl.width = "200";
|
246
|
+
qrImgEl.src = URL.createObjectURL(imageBlob);
|
247
|
+
resultExtractIdInfoEl.appendChild(qrImgEl);
|
248
|
+
resultExtractIdInfoEl.appendChild(document.createTextNode(`\n${result}\n`));
|
249
|
+
}
|
250
|
+
|
251
|
+
if (apiResult) {
|
252
|
+
resultExtractIdInfoEl.appendChild(document.createTextNode("API Result:\n"));
|
253
|
+
const apiResultEl = document.createElement('textarea');
|
254
|
+
apiResultEl.value = JSON.stringify(apiResult, null, 2);
|
255
|
+
apiResultEl.cols = 55
|
256
|
+
apiResultEl.rows = 15
|
257
|
+
resultExtractIdInfoEl.appendChild(apiResultEl);
|
258
|
+
}
|
259
|
+
|
260
|
+
// all steps done
|
261
|
+
if (stepNumber === steps.length - 1) {
|
262
|
+
tv.destroyView();
|
263
|
+
readIdCardLoadingEl.style.display = 'none';
|
264
|
+
}
|
265
|
+
}
|
266
|
+
|
267
|
+
async function handleDetectIdCard (props) {
|
268
|
+
const { cardType, imageBlob, cardSide } = props
|
269
|
+
const apiClient = new trustvisionSdk.default(inputAccessKey.value, inputSecretKey.value, inputApiUrl.value);
|
270
|
+
const resultUpload = await apiClient.uploadImage({
|
271
|
+
file: imageBlob,
|
272
|
+
label: `id_card.${cardType}.${cardSide}`,
|
273
|
+
});
|
274
|
+
const imageId = resultUpload.data.image_id
|
275
|
+
const resultDetect = await apiClient.httpClient.post('/v1/detect_id_cards_sync', {
|
276
|
+
card_type: cardType,
|
277
|
+
image: {
|
278
|
+
id: imageId,
|
279
|
+
}
|
280
|
+
});
|
281
|
+
return _.get(resultDetect, 'data.image.cards.0')
|
282
|
+
}
|
283
|
+
|
221
284
|
function startExtractIDInfo() {
|
222
|
-
const cardSide = selectCardSideEl.value;
|
223
285
|
const apiCheck = selectApiCheckEl.value === "true";
|
224
286
|
resultExtractIdInfoEl.innerHTML = "";
|
225
287
|
|
226
|
-
|
227
|
-
apiCheck: apiCheck,
|
228
|
-
accessKey: inputAccessKey.value,
|
229
|
-
secretKey: inputSecretKey.value,
|
230
|
-
apiUrl: inputApiUrl.value,
|
231
|
-
frontCamera: false,
|
232
|
-
cardSide: cardSide,
|
233
|
-
frontCardId: inputFrontIdEl.value,
|
234
|
-
clientSettings: JSON.parse(idCardSettingsEl.value),
|
235
|
-
title:
|
236
|
-
cardSide === TVWebSDK.Constants.IDCardSide.FRONT
|
237
|
-
? "Mặt trước CMND/CCCD"
|
238
|
-
: "Mặt sau CMND/CCCD",
|
239
|
-
description:
|
240
|
-
cardSide === TVWebSDK.Constants.IDCardSide.FRONT
|
241
|
-
? "Căn mặt trước CMND/CCCD vào khung"
|
242
|
-
: "Căn mặt sau CMND/CCCD vào khung",
|
243
|
-
onSuccess: handleReadIDCardResult,
|
288
|
+
const commonProps = {
|
244
289
|
onError: (e) => {
|
245
290
|
resultExtractIdInfoEl.appendChild(
|
246
|
-
document.createTextNode(
|
291
|
+
document.createTextNode(`Error:\n${JSON.stringify(e, null, 2)}`)
|
247
292
|
);
|
248
293
|
tv.destroyView();
|
249
294
|
readIdCardLoadingEl.style.display = 'none';
|
250
295
|
},
|
251
|
-
|
296
|
+
clientSettings: JSON.parse(idCardSettingsEl.value),
|
297
|
+
detectIdCard: handleDetectIdCard,
|
298
|
+
onStepDone: handleStepDoneIDCard,
|
299
|
+
steps: JSON.parse(idCardStepsEl.value),
|
300
|
+
tracking: JSON.parse(trackingConfigEl.value),
|
301
|
+
}
|
302
|
+
|
303
|
+
if (apiCheck) {
|
304
|
+
console.log('With api call')
|
305
|
+
tv.readIDCardWithApiCall({
|
306
|
+
apiCredentials: {
|
307
|
+
accessKey: inputAccessKey.value,
|
308
|
+
secretKey: inputSecretKey.value,
|
309
|
+
apiUrl: inputApiUrl.value,
|
310
|
+
},
|
311
|
+
...commonProps,
|
312
|
+
})
|
313
|
+
} else {
|
314
|
+
console.log('UI only')
|
315
|
+
tv.readIDCardUIOnly(commonProps)
|
316
|
+
}
|
252
317
|
}
|
253
318
|
|
254
319
|
function startLivenessDetection() {
|
@@ -301,7 +366,6 @@
|
|
301
366
|
resultExtractIdInfoEl.appendChild(
|
302
367
|
document.createTextNode(`${JSON.stringify(apiResult, null, 2)}`)
|
303
368
|
);
|
304
|
-
const cardSide = selectCardSideEl.value;
|
305
369
|
if (cardSide === TVWebSDK.Constants.IDCardSide.FRONT) {
|
306
370
|
const frontCardId = apiResult.cardInfo.image1.id;
|
307
371
|
inputFrontIdEl.value = frontCardId;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@tsocial/tvweb-sdk.vib",
|
3
|
-
"version": "5.
|
3
|
+
"version": "5.2.0",
|
4
4
|
"description": "TV Web SDK - The Standalone VIB SDK",
|
5
5
|
"keywords": [],
|
6
6
|
"author": "Nha Hoang <nha.hoang@trustingsocial.com>, Son T. Ng <son.nguyen.thai@trustingsocial.com>",
|
@@ -19,13 +19,13 @@
|
|
19
19
|
"scripts": {
|
20
20
|
"build": "yarn run tvweb-builder --type standalone --libName TVWebSDK",
|
21
21
|
"pack": "tvweb-builder --type standalone --libName TVWebSDK --defaultAssetRoot ./assets",
|
22
|
-
"run-example": "tvweb-builder --type standalone --libName TVWebSDK
|
22
|
+
"run-example": "tvweb-builder --type standalone --libName TVWebSDK && http-server ./ -c-1",
|
23
23
|
"test": "echo \"Error: run tests from root\" && exit 1"
|
24
24
|
},
|
25
25
|
"dependencies": {
|
26
|
-
"@tsocial/trustvision-sdk": "2.10.
|
27
|
-
"@tsocial/tvweb-core": "^5.
|
28
|
-
"@tsocial/tvweb-ui": "^5.
|
26
|
+
"@tsocial/trustvision-sdk": "2.10.1",
|
27
|
+
"@tsocial/tvweb-core": "^5.2.0",
|
28
|
+
"@tsocial/tvweb-ui": "^5.2.0",
|
29
29
|
"invariant": "^2.2.4",
|
30
30
|
"react": "^16.14.0",
|
31
31
|
"react-app-polyfill": "^2.0.0",
|
@@ -33,7 +33,7 @@
|
|
33
33
|
"styled-components": "^5.2.1"
|
34
34
|
},
|
35
35
|
"devDependencies": {
|
36
|
-
"@tsocial/tvweb-builder": "^5.
|
36
|
+
"@tsocial/tvweb-builder": "^5.2.0"
|
37
37
|
},
|
38
|
-
"gitHead": "
|
38
|
+
"gitHead": "82d8bb3ef3b72d4bf645d09f37a7cd305ddf0c47"
|
39
39
|
}
|
Binary file
|
Binary file
|
@@ -1,23 +0,0 @@
|
|
1
|
-
<?xml version="1.0" encoding="utf-8"?>
|
2
|
-
<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
3
|
-
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
4
|
-
viewBox="0 0 456 306" style="enable-background:new 0 0 456 306;" xml:space="preserve">
|
5
|
-
<style type="text/css">
|
6
|
-
.st0{clip-path:url(#SVGID_2_);}
|
7
|
-
.st1{opacity:0.6;stroke:#F4F4F4;stroke-dasharray:7,4;enable-background:new ;}
|
8
|
-
</style>
|
9
|
-
<g>
|
10
|
-
<g>
|
11
|
-
<defs>
|
12
|
-
<rect id="SVGID_1_" x="-1" y="-1" width="458" height="307"/>
|
13
|
-
</defs>
|
14
|
-
<clipPath id="SVGID_2_">
|
15
|
-
<use xlink:href="#SVGID_1_" style="overflow:visible;"/>
|
16
|
-
</clipPath>
|
17
|
-
<g class="st0">
|
18
|
-
<path class="st1" d="M-11-11v327h478V-11H-11z M444,288.5c0,2.8-2.2,5-5,5H17c-2.8,0-5-2.2-5-5v-272c0-2.8,2.2-5,5-5h422
|
19
|
-
c2.8,0,5,2.2,5,5V288.5z"/>
|
20
|
-
</g>
|
21
|
-
</g>
|
22
|
-
</g>
|
23
|
-
</svg>
|
Binary file
|