@richard.fadiora/liveness-detection 3.0.0 → 3.0.1
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/README.md +116 -49
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,28 +1,26 @@
|
|
|
1
|
-
# Liveness Detection
|
|
1
|
+
# Liveness Detection Component
|
|
2
2
|
|
|
3
3
|
A React-based liveness detection component that performs randomized user challenges and verifies real-user presence via a backend anti-spoofing API.
|
|
4
4
|
|
|
5
|
-
This version introduces headless mode
|
|
5
|
+
This latest version introduces **headless mode**, **render-prop customization**, and robust **challenge sequencing**, allowing developers to fully control the UI while keeping the verification logic encapsulated.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
## Overview
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
This component strengthens identity verification by combining:
|
|
12
12
|
|
|
13
13
|
- Randomized challenge-response validation
|
|
14
|
-
- Real-time gesture detection via MediaPipe
|
|
15
|
-
- Sequential verification to ensure no challenges are skipped
|
|
16
14
|
- Strict timeout enforcement
|
|
17
15
|
- Backend spoof detection
|
|
18
|
-
- Callback-based integration for
|
|
19
|
-
-
|
|
16
|
+
- Callback-based integration for easy usage
|
|
17
|
+
- Headless / fully customizable UI via render props
|
|
20
18
|
|
|
21
19
|
It protects against:
|
|
22
20
|
|
|
23
21
|
- Presentation (photo) attacks
|
|
24
22
|
- Screen glare attacks
|
|
25
|
-
- Video replay
|
|
23
|
+
- Video replay/injection attacks
|
|
26
24
|
|
|
27
25
|
---
|
|
28
26
|
|
|
@@ -30,35 +28,50 @@ It protects against:
|
|
|
30
28
|
|
|
31
29
|
### Challenge Initialization
|
|
32
30
|
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
31
|
+
- When the user starts verification, the system randomly selects **3 challenges** from a pool of 4 (`Smile`, `Blink`, `Turn_Head`, `Thumbs_Up`).
|
|
32
|
+
- A timer starts immediately (default **60 seconds**, configurable via `duration`).
|
|
33
|
+
- Each challenge is verified sequentially, with a brief pause between steps for user feedback.
|
|
34
|
+
- The next challenge only begins after the current one is successfully completed.
|
|
35
|
+
- If the timer expires, the session terminates and no frames are sent to the backend.
|
|
37
36
|
|
|
38
37
|
### Challenge Execution
|
|
39
38
|
|
|
40
|
-
-
|
|
41
|
-
- Sequential
|
|
42
|
-
-
|
|
39
|
+
- Challenges are validated in real-time using webcam input and MediaPipe models.
|
|
40
|
+
- Sequential verification ensures no steps are skipped.
|
|
41
|
+
- Developers can use **headless mode** to render a fully custom UI while leveraging the verification logic.
|
|
43
42
|
|
|
44
43
|
### Backend Liveness Verification
|
|
45
44
|
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
45
|
+
- After all challenges are completed, the component captures **5 frames** from the webcam.
|
|
46
|
+
- Frames are sent to the backend API defined by the `apiUrl` prop.
|
|
47
|
+
- The backend performs:
|
|
48
|
+
- Spoof detection
|
|
49
|
+
- Glare detection
|
|
50
|
+
- Video injection detection
|
|
49
51
|
|
|
50
52
|
---
|
|
51
53
|
|
|
52
54
|
## Success & Failure Behavior
|
|
53
55
|
|
|
54
|
-
|
|
55
|
-
- UI displays success message
|
|
56
|
-
- onComplete callback triggered with frame and skin confidence
|
|
56
|
+
### If verification succeeds
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
- The UI (or custom render-prop component) can display success feedback.
|
|
59
|
+
- The `onComplete` callback is triggered:
|
|
60
|
+
|
|
61
|
+
```js
|
|
62
|
+
onComplete({ success: true, image: frame, skinConfidence });
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### If verification fails
|
|
66
|
+
|
|
67
|
+
- The UI displays a failure message.
|
|
68
|
+
- The `onError` callback is triggered:
|
|
69
|
+
|
|
70
|
+
```js
|
|
71
|
+
onError({ success: false, reason, skinConfidence: null });
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
- The component resets, requiring the user to start a new session.
|
|
62
75
|
|
|
63
76
|
---
|
|
64
77
|
|
|
@@ -75,21 +88,62 @@ It protects against:
|
|
|
75
88
|
|
|
76
89
|
---
|
|
77
90
|
|
|
78
|
-
##
|
|
91
|
+
## Styling with `classNames`
|
|
79
92
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
93
|
+
The `classNames` object allows partial styling of the default UI without fully overriding it. Supported keys:
|
|
94
|
+
|
|
95
|
+
| Key | Element |
|
|
96
|
+
|------------|-----------------------------|
|
|
97
|
+
| `container` | The root wrapper div |
|
|
98
|
+
| `webcam` | The webcam video element |
|
|
99
|
+
| `button` | Start / Retry button |
|
|
100
|
+
| `timer` | Timer display |
|
|
101
|
+
| `error` | Error message display |
|
|
102
|
+
| `success` | Success message display |
|
|
83
103
|
|
|
104
|
+
### Example Usage
|
|
105
|
+
|
|
106
|
+
```jsx
|
|
84
107
|
<LivenessSDK
|
|
85
108
|
apiUrl="https://your-backend-api.com/liveness-check"
|
|
86
|
-
onComplete={
|
|
87
|
-
onError={
|
|
88
|
-
|
|
109
|
+
onComplete={handleComplete}
|
|
110
|
+
onError={handleError}
|
|
111
|
+
classNames={{
|
|
112
|
+
container: "my-liveness-container",
|
|
113
|
+
webcam: "my-webcam",
|
|
114
|
+
button: "my-button",
|
|
115
|
+
timer: "my-timer",
|
|
116
|
+
error: "my-error",
|
|
117
|
+
success: "my-success"
|
|
118
|
+
}}
|
|
89
119
|
/>
|
|
90
120
|
```
|
|
91
121
|
|
|
92
|
-
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Usage Examples
|
|
125
|
+
|
|
126
|
+
### Default UI
|
|
127
|
+
|
|
128
|
+
```jsx
|
|
129
|
+
import { LivenessSDK } from "@richard.fadiora/liveness-detection";
|
|
130
|
+
|
|
131
|
+
function App() {
|
|
132
|
+
return (
|
|
133
|
+
<LivenessSDK
|
|
134
|
+
apiUrl="https://your-backend-api.com/liveness-check"
|
|
135
|
+
onComplete={(result) => console.log("Verification success:", result)}
|
|
136
|
+
onError={(error) => console.log("Verification failed:", error.reason)}
|
|
137
|
+
duration={60}
|
|
138
|
+
/>
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export default App;
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Headless / Custom UI
|
|
146
|
+
|
|
93
147
|
```jsx
|
|
94
148
|
<LivenessSDK
|
|
95
149
|
apiUrl="https://your-backend-api.com/liveness-check"
|
|
@@ -98,7 +152,7 @@ import { LivenessSDK } from '@richard.fadiora/liveness-detection';
|
|
|
98
152
|
render={(sdk) => (
|
|
99
153
|
<div>
|
|
100
154
|
<video ref={sdk.webcamRef} autoPlay playsInline muted />
|
|
101
|
-
<div>Step {sdk.currentStep + 1}
|
|
155
|
+
<div>Step {sdk.currentStep + 1}: {sdk.sequence[sdk.currentStep]}</div>
|
|
102
156
|
<div>Time left: {sdk.timeLeft}s</div>
|
|
103
157
|
<button onClick={sdk.start}>Start</button>
|
|
104
158
|
</div>
|
|
@@ -110,46 +164,59 @@ import { LivenessSDK } from '@richard.fadiora/liveness-detection';
|
|
|
110
164
|
|
|
111
165
|
## Timeout Rules
|
|
112
166
|
|
|
113
|
-
-
|
|
114
|
-
-
|
|
167
|
+
- Maximum session duration: set via the `duration` property (default 60 seconds)
|
|
168
|
+
- If time expires:
|
|
169
|
+
- The challenge stops immediately
|
|
170
|
+
- Verification state resets
|
|
171
|
+
- User must click Start Challenge again
|
|
172
|
+
- Backend verification is NOT triggered
|
|
115
173
|
|
|
116
174
|
---
|
|
117
175
|
|
|
118
176
|
## Security Architecture
|
|
119
177
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
178
|
+
- **Client-side active verification**: randomized challenges, real-time gesture detection
|
|
179
|
+
- **Server-side passive verification**: frame-based spoof analysis, glare detection, video injection detection
|
|
180
|
+
- **Strict session control**: timeout enforcement, restart requirement on failure
|
|
181
|
+
|
|
182
|
+
This layered approach reduces false positives and prevents replay-based attacks.
|
|
123
183
|
|
|
124
184
|
---
|
|
125
185
|
|
|
126
186
|
## Verification Criteria
|
|
127
187
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
-
|
|
188
|
+
Verification is considered successful only if:
|
|
189
|
+
|
|
190
|
+
- All 3 randomly selected challenges are completed
|
|
191
|
+
- All 5 frames are sent to the backend
|
|
192
|
+
- Backend confirms:
|
|
193
|
+
- No spoofing detected
|
|
194
|
+
- No glare detected
|
|
195
|
+
- Skin texture is human
|
|
196
|
+
- No video injection detected
|
|
131
197
|
|
|
132
198
|
---
|
|
133
199
|
|
|
134
200
|
## Integration Notes
|
|
135
201
|
|
|
136
|
-
-
|
|
137
|
-
-
|
|
138
|
-
- apiUrl must be reachable
|
|
202
|
+
- The component assumes webcam permissions are granted.
|
|
203
|
+
- The backend must accept 5 frames in the expected format.
|
|
204
|
+
- The `apiUrl` must be reachable from the client environment.
|
|
205
|
+
- Ensure CORS is properly configured on the backend.
|
|
139
206
|
|
|
140
207
|
---
|
|
141
208
|
|
|
142
209
|
## Ideal Use Cases
|
|
143
210
|
|
|
144
211
|
- KYC verification flows
|
|
145
|
-
- Identity onboarding
|
|
146
|
-
- Account recovery
|
|
212
|
+
- Identity onboarding systems
|
|
213
|
+
- Account recovery flows
|
|
147
214
|
- Secure login systems
|
|
148
|
-
- Financial
|
|
215
|
+
- Financial or compliance-based applications
|
|
149
216
|
|
|
150
217
|
---
|
|
151
218
|
|
|
152
219
|
## Maintainer
|
|
153
220
|
|
|
154
|
-
Fadiora Richard
|
|
221
|
+
Fadiora Richard
|
|
155
222
|
|