@getyoti/react-face-capture 0.5.0 → 1.0.0-beta.3
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 +63 -0
- package/README.md +99 -31
- package/index.css +1 -1
- package/index.js +1 -1
- package/index.js.LICENSE.txt +0 -23
- package/package.json +38 -37
- package/vanilla/index.css +1 -1
- package/vanilla/index.js +1 -1
- package/vanilla/index.js.LICENSE.txt +3 -3
- package/vanilla/index.js.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,68 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## v1.0.0-beta.3
|
|
4
|
+
|
|
5
|
+
Fix a package install error which cause `yarn` and older `npm` versions to fail.
|
|
6
|
+
|
|
7
|
+
## v1.0.0-beta.2
|
|
8
|
+
|
|
9
|
+
### New features
|
|
10
|
+
|
|
11
|
+
- Capture secure mode.
|
|
12
|
+
- Vanilla version reload.
|
|
13
|
+
- New FCM Design.
|
|
14
|
+
- New optional "consent" button.
|
|
15
|
+
- Default captureMethod changed from "Manual" to "Auto".
|
|
16
|
+
|
|
17
|
+
### Breaking changes
|
|
18
|
+
|
|
19
|
+
Now the `onSuccess` callback returns the image in the `img` field instead for
|
|
20
|
+
`image`.
|
|
21
|
+
|
|
22
|
+
- Before:
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{
|
|
26
|
+
"image": "<base64_img>"
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
- After:
|
|
31
|
+
|
|
32
|
+
- No secure:
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"img": "<base64_img>"
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
- Secure:
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"img": "<base64_img>",
|
|
45
|
+
"secure": {
|
|
46
|
+
"version": "<fcm_version>",
|
|
47
|
+
"token": "<session_token>",
|
|
48
|
+
"signature": "<result_signature>"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Now the `CustomButton` has been splited in `CustomManualButton` and `CustomConsentButton` because
|
|
54
|
+
of the implementation of the new consent mode. Each of the properties has the same definitions as
|
|
55
|
+
the old `CustomButton`, funtions using `onClick` and `disabled` as props that returns a button
|
|
56
|
+
component.
|
|
57
|
+
|
|
58
|
+
## v0.6.0
|
|
59
|
+
|
|
60
|
+
### New features
|
|
61
|
+
|
|
62
|
+
- Implemented localisation languages
|
|
63
|
+
- `ar`: Arabic
|
|
64
|
+
- `lv`: Latvian
|
|
65
|
+
|
|
3
66
|
## v0.5.0
|
|
4
67
|
|
|
5
68
|
### New features
|
package/README.md
CHANGED
|
@@ -9,8 +9,8 @@ The purpose of this module is to capture a face and return the output image.
|
|
|
9
9
|
The package depends on the following peer dependencies
|
|
10
10
|
|
|
11
11
|
```
|
|
12
|
-
"react": "16.12.0",
|
|
13
|
-
"react-dom": "16.12.0"
|
|
12
|
+
"react": ">=16.12.0 <18",
|
|
13
|
+
"react-dom": ">=16.12.0 <18"
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
### Browser support
|
|
@@ -19,12 +19,12 @@ The package depends on the following peer dependencies
|
|
|
19
19
|
|
|
20
20
|
| Browser | Versions |
|
|
21
21
|
| ------- | ----------------------------- |
|
|
22
|
-
| and_chr |
|
|
23
|
-
| chrome | 96,95
|
|
24
|
-
| edge |
|
|
25
|
-
| firefox | 95,94
|
|
26
|
-
| ios_saf | 15.0-15.1,14.5-14.8
|
|
27
|
-
| safari | 15.1,15,14.1
|
|
22
|
+
| and_chr | 98 |
|
|
23
|
+
| chrome | 98,97,96,95 |
|
|
24
|
+
| edge | 98,97 |
|
|
25
|
+
| firefox | 97,96,95,94 |
|
|
26
|
+
| ios_saf | 15.2-15.3,15.0-15.1,14.5-14.8 |
|
|
27
|
+
| safari | 15.2-15.3,15.1,15,14.1 |
|
|
28
28
|
|
|
29
29
|
</browserSupportTable>
|
|
30
30
|
|
|
@@ -34,7 +34,9 @@ _Note: Non-Safari browsers on iOS are not supported because of an iOS limitation
|
|
|
34
34
|
|
|
35
35
|
Finally, some devices might experience poor performance when attempting to detect a face. This is because the underlying library TensorFlow.js can still be too demanding for older less performant devices.
|
|
36
36
|
|
|
37
|
-
##
|
|
37
|
+
## React face capture module
|
|
38
|
+
|
|
39
|
+
### Install dependency
|
|
38
40
|
|
|
39
41
|
```
|
|
40
42
|
npm i @getyoti/react-face-capture -S
|
|
@@ -47,7 +49,7 @@ import FaceCapture from "@getyoti/react-face-capture"
|
|
|
47
49
|
import "@getyoti/react-face-capture/index.css"
|
|
48
50
|
```
|
|
49
51
|
|
|
50
|
-
|
|
52
|
+
### Copy assets
|
|
51
53
|
|
|
52
54
|
**Assets** are not included in the javascript bundle. To have the components to work correctly, you will need to copy library assets from `@getyoti/react-face-capture/assets` folder into your assets folder.
|
|
53
55
|
|
|
@@ -62,28 +64,33 @@ new CopyPlugin([
|
|
|
62
64
|
]),
|
|
63
65
|
```
|
|
64
66
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
| Property name | Type | Default | Mand | Description
|
|
68
|
-
| -------------------- | -------------------------- | ------------- | ---- |
|
|
69
|
-
| captureMethod | String `manual/auto` | `
|
|
70
|
-
|
|
|
71
|
-
|
|
|
72
|
-
|
|
|
73
|
-
|
|
|
74
|
-
|
|
|
75
|
-
|
|
|
76
|
-
|
|
|
77
|
-
|
|
|
78
|
-
|
|
|
79
|
-
|
|
|
80
|
-
|
|
|
81
|
-
|
|
|
67
|
+
### Props
|
|
68
|
+
|
|
69
|
+
| Property name | Type | Default | Mand | Description |
|
|
70
|
+
| -------------------- | -------------------------- | ------------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
71
|
+
| captureMethod | String `manual/auto` | `auto` | - | The way you capture the photo, either with the button of auto-capture |
|
|
72
|
+
| secure | Boolean | false | - | If `true`, the face capture module will use the [secure mode](#secure-mode) |
|
|
73
|
+
| onSuccess | Function({ img, secure }) | - | Y | Callback which will be called once the result (capture) is complete. The field `secure` is only returned in secure mode (See [secure mode section](#secure-mode)) |
|
|
74
|
+
| onError | Function | - | - | Callback which will be called when there is an error. See Appendix for the list of error codes we currently support. |
|
|
75
|
+
| showOverlay | Boolean | `true` | - | Use a face overlay |
|
|
76
|
+
| widthMinConstraint | Number | `1024` | - | Video min width constraint passed to `getUserMedia` |
|
|
77
|
+
| widthIdealConstraint | Number | `1280` | - | Video ideal width constraint passed to `getUserMedia` |
|
|
78
|
+
| format | String | `jpeg` | - | Image format |
|
|
79
|
+
| CustomManualButton | Function | simple button | - | Custom UI of the manual capture button. It uses `onClick` and `disabled` as props |
|
|
80
|
+
| CustomConsentButton | Function | simple button | - | Custom UI of the consent button. It uses `onClick` and `disabled` as props |
|
|
81
|
+
| countdownMode | String `auto/never/always` | `never` | - | Note: `auto` means it will be hidden on mobile and shown on desktop |
|
|
82
|
+
| imageType | String `original/cropped` | `original` | - | Cropped image to improve performance on processing from the API |
|
|
83
|
+
| isDebug | Boolean | false | - | If `true`, display useful information |
|
|
84
|
+
| qualityType | String `high/medium/low` | `high` | - | The quality of the image taken for jpeg format only. High (1) - Medium (0.96) - Low (0.90) |
|
|
85
|
+
| language | Language code (\*) | `en` | - | The language code to set the language of the feedback messages |
|
|
86
|
+
| a11yLiveRegionMode | String `assertive/polite` | `polite` | - | Determines the [politeness setting of the live region](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions#live_regions) used to read out prompts for screen reader users |
|
|
87
|
+
| isConsentRequired | Boolean | `false` | - | Makes sure that the user gives consent to the tool to analyse their face. If it is `true`, a button will appear on the bottom section of the module, asking the user for their consent, and not analysing the user face until the consent is given. After this, the button disappears. |
|
|
82
88
|
|
|
83
89
|
**(\*)**
|
|
84
90
|
Current languages supported:
|
|
85
91
|
|
|
86
92
|
- `en`: English
|
|
93
|
+
- `ar`: Arabic
|
|
87
94
|
- `cs`: Czech
|
|
88
95
|
- `da`: Danish
|
|
89
96
|
- `de`: German
|
|
@@ -98,6 +105,7 @@ Current languages supported:
|
|
|
98
105
|
- `ja`: Japanese
|
|
99
106
|
- `ko`: Korean
|
|
100
107
|
- `lt`: Lithuanian
|
|
108
|
+
- `lv`: Latvian
|
|
101
109
|
- `ms`: Malay
|
|
102
110
|
- `nb`: Norwegian
|
|
103
111
|
- `nl`: Dutch
|
|
@@ -111,7 +119,7 @@ Current languages supported:
|
|
|
111
119
|
- `uk`: Ukranian
|
|
112
120
|
- `vi`: Vietnamese
|
|
113
121
|
|
|
114
|
-
|
|
122
|
+
#### Language fallback
|
|
115
123
|
|
|
116
124
|
Mechanisnm used for the prop `language` to avoid issues when the value passed is wrong. Example: first try exact match (es-es or es-ES, ignore case):
|
|
117
125
|
|
|
@@ -119,7 +127,7 @@ Mechanisnm used for the prop `language` to avoid issues when the value passed is
|
|
|
119
127
|
- If no mainstream, try any other available es-[region] sibling (example: es-419).
|
|
120
128
|
- If no regional sibling, use the default language: en.
|
|
121
129
|
|
|
122
|
-
|
|
130
|
+
#### Supported error codes
|
|
123
131
|
|
|
124
132
|
| Error code | Description |
|
|
125
133
|
| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
@@ -130,6 +138,7 @@ Mechanisnm used for the prop `language` to avoid issues when the value passed is
|
|
|
130
138
|
| `OVERCONSTRAINED` | The camera constraints are not compatible with any camera device. `Note: One recovery option is to lower the widthMinConstraint value.` |
|
|
131
139
|
| `FACE_DETECTION_INIT_ERROR` | The face detection has failed to initialise. This usually means that the required model assets are missing from the host application. |
|
|
132
140
|
| `INTERNAL_ERROR` | Internal error. This can be due to a programming error, or the user using an old unsupported browser. |
|
|
141
|
+
| `CAPTURE_LOAD_ERROR` | The secure module could not be loaded. This usually means your token is not updated, or there is an error on the module provider. |
|
|
133
142
|
|
|
134
143
|
The error codes can be imported as follow:
|
|
135
144
|
|
|
@@ -137,7 +146,58 @@ The error codes can be imported as follow:
|
|
|
137
146
|
import { ERROR_CODE } from '@getyoti/react-face-capture';
|
|
138
147
|
```
|
|
139
148
|
|
|
140
|
-
|
|
149
|
+
#### Secure mode
|
|
150
|
+
|
|
151
|
+
The secure mode allows [Yoti back-end
|
|
152
|
+
service](https://developers.yoti.com/age-estimation/integration-guide)
|
|
153
|
+
verifying the image captured on the client-side browser with the FCM hasn't been
|
|
154
|
+
modified in any form. Note the Secure mode of Yoti FCM will request Yoti
|
|
155
|
+
back-end in order to download the encrypted capture package that takes the
|
|
156
|
+
photos and create the secure result request. The secure result information will
|
|
157
|
+
be returned in `onSuccess` callback:
|
|
158
|
+
|
|
159
|
+
```json
|
|
160
|
+
{
|
|
161
|
+
"img": "<base64_img>",
|
|
162
|
+
"secure": {
|
|
163
|
+
"version": "<fcm_version>",
|
|
164
|
+
"token": "<session_token>",
|
|
165
|
+
"signature": "<result_signature>"
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
The flow for the secure mode is the following:
|
|
171
|
+
|
|
172
|
+
1. Request for a session -> `(GET) https://api.yoti.com/ai/sm/v1/secure-fcm/<version>/token`
|
|
173
|
+
2. Request for the encrypted javascript module -> `(GET) https://api.yoti.com/ai/sm/v1/secure-fcm/<version>/module?s=<token>`
|
|
174
|
+
|
|
175
|
+
Where `<version>` is the current version of the FCM (It is embedded in the
|
|
176
|
+
module) and the `<token>` is the session token the first request returns.
|
|
177
|
+
|
|
178
|
+
```mermaid
|
|
179
|
+
sequenceDiagram
|
|
180
|
+
participant A as Browser (FCM)
|
|
181
|
+
participant B as Secure Module Server
|
|
182
|
+
participant C as Integrator back-end
|
|
183
|
+
participant D as Yoti Anti Spoofing Service
|
|
184
|
+
A->>B: Request for a session
|
|
185
|
+
B->>A: New session response
|
|
186
|
+
A->>B: Request for the secure capture module
|
|
187
|
+
B->>A: Secure capture module result
|
|
188
|
+
A->>A: Take picture
|
|
189
|
+
A->>C: Send capture result
|
|
190
|
+
C->>D: Propagate request to the Anti Spoofing service
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
##### Possible issues
|
|
194
|
+
|
|
195
|
+
The secure mode requests Yoti back-end in order to download the encrypted module
|
|
196
|
+
on demand so the front-end must be able to handle that requests. Keep in mind if
|
|
197
|
+
your front-end uses any mechanism to prevent data injection attacks or
|
|
198
|
+
cross-site scripting like SCP you will need to allow the FCM requests.
|
|
199
|
+
|
|
200
|
+
### Example
|
|
141
201
|
|
|
142
202
|
```js
|
|
143
203
|
import FaceCapture from '@getyoti/react-face-capture';
|
|
@@ -186,7 +246,15 @@ Our scripts will give you access to `Yoti.FaceCaptureModule.render` you can pass
|
|
|
186
246
|
faceCaptureAssetsRootUrl: '/@getyoti/react-face-capture/vanilla/assets/';
|
|
187
247
|
};
|
|
188
248
|
|
|
189
|
-
Yoti.FaceCaptureModule.render(props, document.getElementById('face-capture-module-root'));
|
|
249
|
+
const fcm = Yoti.FaceCaptureModule.render(props, document.getElementById('face-capture-module-root'));
|
|
250
|
+
|
|
251
|
+
function reload() {
|
|
252
|
+
fcm.reload()
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function unmount() {
|
|
256
|
+
fcm.unmount()
|
|
257
|
+
}
|
|
190
258
|
</script>
|
|
191
259
|
|
|
192
260
|
<div id="face-capture-module-root"></div>
|
package/index.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.
|
|
1
|
+
._2_U2DYHedfGUyvS1oS5{display:flex;flex-direction:column;overflow:hidden;position:relative}.mteIzegCA0cNMXt96BYN{position:relative}.Ds2gos19dHtdm4Aer1pq,.Va8swWS5S29Uvou7UNnc{height:100%;position:absolute;width:100%}.Ds2gos19dHtdm4Aer1pq{display:flex;justify-content:center;top:0}.x_r8eQXclQHy5Jjno7pU{display:block;height:100%;margin:auto;position:absolute}.HPEPfcUpwWOVOJSPP9R_{box-sizing:border-box;color:#67717f;height:100%;left:0;position:absolute;right:0}.HPEPfcUpwWOVOJSPP9R_._0fft05LhDRetV8QdNSI{color:#39c48e}.HPEPfcUpwWOVOJSPP9R_.JHe4OqVjOOuBZXJn_axE{color:#ffba37}.xsnSbKRs6MZbpP2odJGk{box-sizing:border-box;position:absolute;width:100%}.xsnSbKRs6MZbpP2odJGk.lSsJ_kvBTJOO0shULKLn{height:43.5%;top:28.3%}.xsnSbKRs6MZbpP2odJGk._6X0Zl0a0b8R2wCqGS_K{height:71.7%;top:11.5%}.IpX4dJbHat9i3luoCwef{align-items:start;background-color:#fff;border-radius:.3em;box-shadow:0 8px 15px #333b401a;box-sizing:border-box;color:#333b40;display:flex;font-family:sans-serif;font-size:16px;font-size:var(--message-font-size);font-weight:900;justify-content:start;left:50%;padding:.4em 0;position:absolute;text-align:center}.a_0VmnisbKCGWfubHrmj{margin-bottom:50px;top:4.6%;transform:translate(-50%);width:90%}.CqNtyAmFAcDIeu8mRGPD{top:5.5%;transform:translate(-50%);width:51.25%}.rlF15FcuMGotbEHYe5KW{align-items:start;font-size:calc(var(--message-font-size) + 3px)}._CvVxyqwMB2D7fkKx_NZ{display:flex;justify-content:center;order:1;width:14%}._znJxLRvhRnuCU0KBY3_{order:2;width:72%}.aM6UBOeSFg8vwirw8BEs{position:absolute}.RxkomAqHmrdu47_oGii4{bottom:-8px;box-sizing:border-box;display:grid;font-size:40px;grid-template-columns:repeat(3,80px) 50px;justify-content:center;padding:16px;position:absolute;text-align:center;width:100%}.ZSTtG9h6K6_0_axlDNnV,.__OOQVMtxL3v8uCw9eKy,.hwSkw4zQBundKmrqIwqC{color:#333b40;font-family:sans-serif;font-size:40px;font-weight:700;height:50px;line-height:55px;text-align:center;width:51px}.__OOQVMtxL3v8uCw9eKy{opacity:.5}.Gf_S7QnzULbIZZZ7roY2,.OZI1jG8pdtaOfb2ZsB2n,.XOix2SeWtEFksSSmLt9v{fill:#333b40}.Gf_S7QnzULbIZZZ7roY2 use,.OZI1jG8pdtaOfb2ZsB2n use,.XOix2SeWtEFksSSmLt9v use{fill:inherit}.ZSTtG9h6K6_0_axlDNnV svg,.__OOQVMtxL3v8uCw9eKy svg,.hwSkw4zQBundKmrqIwqC svg{font-size:50px}.Gf_S7QnzULbIZZZ7roY2{opacity:.5}._XKP_3EMO0LKJr53EW21{box-shadow:0 0 3px 1px #0000001c;height:auto;transform:scaleX(-1);width:100%}@keyframes TgYAVlLOGfJ_hl3TBdkC{0%{transform:rotate(0)}to{transform:rotate(1turn)}}.X_Bq5FImnGbO6TLe3Len{align-items:center;display:flex;height:100%;justify-content:center;line-height:0;text-align:center}.WPX6_jcjLpB6aH420ZCd{animation:TgYAVlLOGfJ_hl3TBdkC 1.5s infinite}.bPwt8l_jKvlB2llQ7azY{height:35.71px;width:35.71px}.bPwt8l_jKvlB2llQ7azY use{fill:#333b40}.mtcvKOHbFdRFpAH7ZHwW{align-items:center;background-color:#229dff;border:none;border-radius:5px;color:#fff;cursor:pointer;display:block;display:flex;font-size:14px;font-weight:500;justify-content:center;letter-spacing:.5px;margin:auto;min-width:134px;outline:none;padding:12px 20px;text-transform:uppercase;transition:background-color .15s ease-out 0s;width:100%}.mtcvKOHbFdRFpAH7ZHwW.kYH4ilWb5sFtCcwqD29n{max-width:350px;width:45%}.mtcvKOHbFdRFpAH7ZHwW:hover{background-color:#007ee8}.mtcvKOHbFdRFpAH7ZHwW:disabled{background-color:#88caff}.GusgiqC_1nbmjyHkruu0 use{fill:currentColor}.dDcfK_agfQV9XSYSuuxR{align-items:center;bottom:-8px;box-sizing:border-box;display:inline-block;justify-content:center;padding:16px;position:absolute;text-align:center;width:100%}
|