santoid-sdk 1.0.6 → 2.0.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/README.md +113 -29
- package/browser/liveness/index.js +1 -0
- package/liveness/index.d.ts +9 -0
- package/liveness/index.js +29 -0
- package/liveness/methods/livenessDetection.d.ts +6 -0
- package/{dist/esm/liveness/index.js → liveness/methods/livenessDetection.js} +2 -22
- package/liveness/methods/uploadIdentificationDocument.d.ts +91 -0
- package/liveness/methods/uploadIdentificationDocument.js +236 -0
- package/liveness/utils/index.d.ts +2 -0
- package/{dist/esm/liveness → liveness}/utils/index.js +10 -1
- package/{dist/esm/liveness → liveness}/utils/types.d.ts +2 -2
- package/{dist/node/liveness → liveness}/utils/types.js +1 -1
- package/{dist/esm/liveness → liveness}/utils/websocket.js +1 -1
- package/{dist/node → node}/auth/index.js +3 -6
- package/node/liveness/index.d.ts +9 -0
- package/node/liveness/index.js +29 -0
- package/node/liveness/methods/livenessDetection.d.ts +6 -0
- package/{dist/node/liveness/index.js → node/liveness/methods/livenessDetection.js} +2 -3
- package/node/liveness/methods/uploadIdentificationDocument.d.ts +91 -0
- package/node/liveness/methods/uploadIdentificationDocument.js +237 -0
- package/node/liveness/utils/index.d.ts +2 -0
- package/{dist/node → node}/liveness/utils/index.js +10 -1
- package/package.json +12 -29
- package/tsconfig.json +6 -2
- package/tsconfig.prod.json +26 -0
- package/{dist/utils → utils}/constants.d.ts +1 -1
- package/{dist/utils → utils}/constants.js +1 -1
- package/{dist/utils → utils}/types.d.ts +11 -8
- package/webpack.config.cjs +12 -2
- package/dist/browser/liveness/index.js +0 -1
- package/dist/esm/liveness/index.d.ts +0 -9
- package/dist/esm/liveness/utils/index.d.ts +0 -1
- package/dist/node/liveness/index.d.ts +0 -4
- package/dist/node/liveness/utils/index.d.ts +0 -1
- package/jest.config.cjs +0 -17
- package/src/esm/liveness/index.ts +0 -156
- package/src/esm/liveness/utils/getNextFrame.ts +0 -76
- package/src/esm/liveness/utils/index.ts +0 -16
- package/src/esm/liveness/utils/types.ts +0 -7
- package/src/esm/liveness/utils/websocket.ts +0 -33
- package/src/index.ts +0 -0
- package/src/node/auth/index.ts +0 -43
- package/src/node/liveness/index.ts +0 -135
- package/src/node/liveness/utils/index.ts +0 -3
- package/src/node/liveness/utils/types.ts +0 -8
- package/src/node/liveness/utils/websocket.ts +0 -35
- package/src/utils/constants.ts +0 -3
- package/src/utils/types.ts +0 -46
- /package/{dist/index.d.ts → index.d.ts} +0 -0
- /package/{dist/index.js → index.js} +0 -0
- /package/{dist/esm/liveness → liveness}/utils/getNextFrame.d.ts +0 -0
- /package/{dist/esm/liveness → liveness}/utils/getNextFrame.js +0 -0
- /package/{dist/esm/liveness → liveness}/utils/websocket.d.ts +0 -0
- /package/{dist/node → node}/auth/index.d.ts +0 -0
- /package/{dist/node → node}/liveness/utils/types.d.ts +0 -0
- /package/{dist/esm → node}/liveness/utils/types.js +0 -0
- /package/{dist/node → node}/liveness/utils/websocket.d.ts +0 -0
- /package/{dist/node → node}/liveness/utils/websocket.js +0 -0
- /package/{dist/utils → utils}/types.js +0 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.uploadIdentificationDocument = void 0;
|
|
7
|
+
const form_data_1 = __importDefault(require("form-data"));
|
|
8
|
+
const axios_1 = __importDefault(require("axios"));
|
|
9
|
+
const constants_1 = require("../../../utils/constants");
|
|
10
|
+
const utils_1 = require("../utils");
|
|
11
|
+
const livenessDetection_1 = require("./livenessDetection");
|
|
12
|
+
async function typificationPredict(options, file) {
|
|
13
|
+
var _a, _b, _c;
|
|
14
|
+
const formData = new form_data_1.default();
|
|
15
|
+
formData.append('track', options.track);
|
|
16
|
+
formData.append('imageFile', file, 'imageFile.jpg');
|
|
17
|
+
const decodedToken = (0, utils_1.tryDecodeJwt)(options.token);
|
|
18
|
+
const domain = (_a = options.domain) !== null && _a !== void 0 ? _a : (_b = decodedToken === null || decodedToken === void 0 ? void 0 : decodedToken.claims) === null || _b === void 0 ? void 0 : _b.domain;
|
|
19
|
+
const axiosConfig = {
|
|
20
|
+
headers: {
|
|
21
|
+
'Content-Type': 'multipart/form-data',
|
|
22
|
+
Authorization: `Bearer ${options.token}`,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
if (axiosConfig.headers && domain) {
|
|
26
|
+
axiosConfig.headers.Domain = domain;
|
|
27
|
+
}
|
|
28
|
+
const response = await axios_1.default.post(`${(_c = options === null || options === void 0 ? void 0 : options.customApiUrl) !== null && _c !== void 0 ? _c : constants_1.API_GATEWAY_URL}/api/v3/typification/predict`, formData, axiosConfig);
|
|
29
|
+
return response.data;
|
|
30
|
+
}
|
|
31
|
+
async function faceMatch(options, firstImage, secondImage) {
|
|
32
|
+
var _a, _b, _c;
|
|
33
|
+
const formData = new form_data_1.default();
|
|
34
|
+
formData.append('track', options.track);
|
|
35
|
+
formData.append('firstImage', firstImage, 'firstImage.jpg');
|
|
36
|
+
formData.append('secondImage', secondImage, 'secondImage.jpg');
|
|
37
|
+
const decodedToken = (0, utils_1.tryDecodeJwt)(options.token);
|
|
38
|
+
const domain = (_a = options.domain) !== null && _a !== void 0 ? _a : (_b = decodedToken === null || decodedToken === void 0 ? void 0 : decodedToken.claims) === null || _b === void 0 ? void 0 : _b.domain;
|
|
39
|
+
const axiosConfig = {
|
|
40
|
+
params: {
|
|
41
|
+
sensitive_data_compliance: true,
|
|
42
|
+
},
|
|
43
|
+
headers: {
|
|
44
|
+
'Content-Type': 'multipart/form-data',
|
|
45
|
+
Authorization: `Bearer ${options.token}`,
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
if (axiosConfig.headers && domain) {
|
|
49
|
+
axiosConfig.headers.Domain = domain;
|
|
50
|
+
}
|
|
51
|
+
const response = await axios_1.default.post(`${(_c = options === null || options === void 0 ? void 0 : options.customApiUrl) !== null && _c !== void 0 ? _c : constants_1.API_GATEWAY_URL}/api/v1/facematch/pair`, formData, axiosConfig);
|
|
52
|
+
return response.data;
|
|
53
|
+
}
|
|
54
|
+
function uploadIdentificationDocument(options) {
|
|
55
|
+
let results = {
|
|
56
|
+
uploadedDocument: null,
|
|
57
|
+
typification: {
|
|
58
|
+
status: null,
|
|
59
|
+
results: null,
|
|
60
|
+
loading: false,
|
|
61
|
+
error: null,
|
|
62
|
+
},
|
|
63
|
+
liveness: {
|
|
64
|
+
status: null,
|
|
65
|
+
results: null,
|
|
66
|
+
loading: false,
|
|
67
|
+
error: null,
|
|
68
|
+
},
|
|
69
|
+
faceMatch: {
|
|
70
|
+
status: null,
|
|
71
|
+
results: null,
|
|
72
|
+
loading: false,
|
|
73
|
+
error: null,
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
async function startFaceMatch(firstImage, secondImage) {
|
|
77
|
+
var _a, _b, _c;
|
|
78
|
+
try {
|
|
79
|
+
updateResults({
|
|
80
|
+
faceMatch: {
|
|
81
|
+
status: null,
|
|
82
|
+
results: null,
|
|
83
|
+
loading: true,
|
|
84
|
+
error: null,
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
const faceMatchResults = await faceMatch(options, firstImage, secondImage);
|
|
88
|
+
updateResults({
|
|
89
|
+
faceMatch: {
|
|
90
|
+
results: faceMatchResults,
|
|
91
|
+
status: 'success',
|
|
92
|
+
loading: false,
|
|
93
|
+
error: null,
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
await ((_a = options.errorCallback) === null || _a === void 0 ? void 0 : _a.call(options, { code: 'face-match-error', details: (_b = err === null || err === void 0 ? void 0 : err.response) === null || _b === void 0 ? void 0 : _b.data }));
|
|
99
|
+
updateResults({
|
|
100
|
+
faceMatch: {
|
|
101
|
+
results: null,
|
|
102
|
+
status: 'error',
|
|
103
|
+
loading: false,
|
|
104
|
+
error: (_c = err === null || err === void 0 ? void 0 : err.response) === null || _c === void 0 ? void 0 : _c.data,
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function tryStartFaceMatch() {
|
|
110
|
+
var _a;
|
|
111
|
+
if (results.uploadedDocument &&
|
|
112
|
+
((_a = results.liveness.results) === null || _a === void 0 ? void 0 : _a.successFrames.front) &&
|
|
113
|
+
!results.faceMatch.results &&
|
|
114
|
+
!results.faceMatch.loading) {
|
|
115
|
+
void startFaceMatch(results.uploadedDocument, results.liveness.results.successFrames.front);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function updateUploadedDocument(file) {
|
|
119
|
+
results.uploadedDocument = file;
|
|
120
|
+
tryStartFaceMatch();
|
|
121
|
+
}
|
|
122
|
+
function updateResults(updatedResults) {
|
|
123
|
+
var _a, _b, _c;
|
|
124
|
+
results = Object.assign(Object.assign({}, results), updatedResults);
|
|
125
|
+
void ((_a = options.resultChangeCallback) === null || _a === void 0 ? void 0 : _a.call(options, results));
|
|
126
|
+
if (Object.entries(results).every(([key, value]) => key === 'uploadedDocument' || !!value.results)) {
|
|
127
|
+
void ((_b = options.successCallback) === null || _b === void 0 ? void 0 : _b.call(options, results));
|
|
128
|
+
void ((_c = options.endCallback) === null || _c === void 0 ? void 0 : _c.call(options));
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
tryStartFaceMatch();
|
|
132
|
+
}
|
|
133
|
+
async function startDocumentUpload(file) {
|
|
134
|
+
var _a, _b, _c;
|
|
135
|
+
try {
|
|
136
|
+
updateResults({
|
|
137
|
+
typification: {
|
|
138
|
+
status: null,
|
|
139
|
+
results: null,
|
|
140
|
+
loading: true,
|
|
141
|
+
error: null,
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
updateUploadedDocument(file);
|
|
145
|
+
const typificationResults = await typificationPredict(options, file);
|
|
146
|
+
updateResults({
|
|
147
|
+
typification: {
|
|
148
|
+
status: 'success',
|
|
149
|
+
results: typificationResults,
|
|
150
|
+
loading: false,
|
|
151
|
+
error: null,
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
await ((_a = options.errorCallback) === null || _a === void 0 ? void 0 : _a.call(options, { code: 'typification-error', details: (_b = err === null || err === void 0 ? void 0 : err.response) === null || _b === void 0 ? void 0 : _b.data }));
|
|
157
|
+
updateResults({
|
|
158
|
+
typification: {
|
|
159
|
+
status: 'error',
|
|
160
|
+
results: null,
|
|
161
|
+
loading: false,
|
|
162
|
+
error: (_c = err === null || err === void 0 ? void 0 : err.response) === null || _c === void 0 ? void 0 : _c.data,
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
async function startLivenessDetection(startLivenessDetectionOptions) {
|
|
168
|
+
var _a, _b, _c, _d, _e;
|
|
169
|
+
const adaptedLivenessOptions = Object.assign({}, startLivenessDetectionOptions);
|
|
170
|
+
delete adaptedLivenessOptions.successCallback;
|
|
171
|
+
delete adaptedLivenessOptions.errorCallback;
|
|
172
|
+
updateResults({
|
|
173
|
+
liveness: {
|
|
174
|
+
results: null,
|
|
175
|
+
status: null,
|
|
176
|
+
loading: true,
|
|
177
|
+
error: null,
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
try {
|
|
181
|
+
return await (0, livenessDetection_1.livenessDetection)(Object.assign(Object.assign({ domain: options.domain, customId: options.customId, customWebSocketUrl: options.customWebSocketUrl, successCallback: (livenessResults) => {
|
|
182
|
+
var _a;
|
|
183
|
+
void ((_a = startLivenessDetectionOptions === null || startLivenessDetectionOptions === void 0 ? void 0 : startLivenessDetectionOptions.successCallback) === null || _a === void 0 ? void 0 : _a.call(startLivenessDetectionOptions, livenessResults));
|
|
184
|
+
updateResults({
|
|
185
|
+
liveness: {
|
|
186
|
+
status: 'success',
|
|
187
|
+
results: (livenessResults),
|
|
188
|
+
loading: false,
|
|
189
|
+
error: null,
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
}, errorCallback: async (livenessErrorDetails) => {
|
|
193
|
+
var _a, _b;
|
|
194
|
+
if ((livenessErrorDetails === null || livenessErrorDetails === void 0 ? void 0 : livenessErrorDetails.code) === 'wrong-position') {
|
|
195
|
+
void ((_a = startLivenessDetectionOptions === null || startLivenessDetectionOptions === void 0 ? void 0 : startLivenessDetectionOptions.errorCallback) === null || _a === void 0 ? void 0 : _a.call(startLivenessDetectionOptions, livenessErrorDetails));
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
void ((_b = options.errorCallback) === null || _b === void 0 ? void 0 : _b.call(options, livenessErrorDetails));
|
|
199
|
+
}
|
|
200
|
+
updateResults({
|
|
201
|
+
liveness: {
|
|
202
|
+
status: 'error',
|
|
203
|
+
results: null,
|
|
204
|
+
loading: (livenessErrorDetails === null || livenessErrorDetails === void 0 ? void 0 : livenessErrorDetails.code) === 'wrong-position',
|
|
205
|
+
error: livenessErrorDetails,
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
} }, adaptedLivenessOptions), { token: (_a = adaptedLivenessOptions.token) !== null && _a !== void 0 ? _a : options.token, track: (_b = adaptedLivenessOptions.track) !== null && _b !== void 0 ? _b : options.track }));
|
|
209
|
+
}
|
|
210
|
+
catch (err) {
|
|
211
|
+
await ((_c = options.errorCallback) === null || _c === void 0 ? void 0 : _c.call(options, { code: 'liveness-error', details: (_d = err === null || err === void 0 ? void 0 : err.response) === null || _d === void 0 ? void 0 : _d.data }));
|
|
212
|
+
updateResults({
|
|
213
|
+
liveness: {
|
|
214
|
+
status: 'error',
|
|
215
|
+
results: null,
|
|
216
|
+
loading: false,
|
|
217
|
+
error: (_e = err === null || err === void 0 ? void 0 : err.response) === null || _e === void 0 ? void 0 : _e.data,
|
|
218
|
+
},
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
function startAll(file, startLivenessDetectionOptions) {
|
|
223
|
+
void startDocumentUpload(file);
|
|
224
|
+
void startLivenessDetection(startLivenessDetectionOptions);
|
|
225
|
+
}
|
|
226
|
+
function getResults() {
|
|
227
|
+
return results;
|
|
228
|
+
}
|
|
229
|
+
return {
|
|
230
|
+
getResults,
|
|
231
|
+
startDocumentUpload,
|
|
232
|
+
startLivenessDetection,
|
|
233
|
+
startFaceComparison: tryStartFaceMatch,
|
|
234
|
+
startAll,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
exports.uploadIdentificationDocument = uploadIdentificationDocument;
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.decodeJwt = void 0;
|
|
3
|
+
exports.tryDecodeJwt = exports.decodeJwt = void 0;
|
|
4
4
|
function decodeJwt(token) {
|
|
5
5
|
return JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
|
|
6
6
|
}
|
|
7
7
|
exports.decodeJwt = decodeJwt;
|
|
8
|
+
function tryDecodeJwt(token) {
|
|
9
|
+
try {
|
|
10
|
+
return decodeJwt(token);
|
|
11
|
+
}
|
|
12
|
+
catch (_a) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.tryDecodeJwt = tryDecodeJwt;
|
package/package.json
CHANGED
|
@@ -1,36 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "santoid-sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "",
|
|
5
|
-
"main": "
|
|
6
|
-
"types": "
|
|
5
|
+
"main": "liveness/index.js",
|
|
6
|
+
"types": "liveness/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"expose:cmd": "mv -v dist/* ./",
|
|
9
|
-
"
|
|
10
|
-
"build:
|
|
11
|
-
"build:typescript": "
|
|
12
|
-
"build": "npm run build:typescript && npm run build:
|
|
13
|
-
"test": "jest",
|
|
14
|
-
"test:coverage": "jest --coverage"
|
|
15
|
-
},
|
|
16
|
-
"exports": {
|
|
17
|
-
".": "./dist/index.js",
|
|
18
|
-
"./liveness": "./dist/esm/liveness/index.js",
|
|
19
|
-
"./node/liveness": "./dist/node/liveness/index.js",
|
|
20
|
-
"./node/auth": "./dist/node/auth/index.js"
|
|
21
|
-
},
|
|
22
|
-
"typesVersions": {
|
|
23
|
-
"*": {
|
|
24
|
-
"liveness": [
|
|
25
|
-
"dist/esm/liveness/index.d.ts"
|
|
26
|
-
],
|
|
27
|
-
"node/liveness": [
|
|
28
|
-
"dist/node/liveness/index.d.ts"
|
|
29
|
-
],
|
|
30
|
-
"node/auth": [
|
|
31
|
-
"dist/node/auth/index.d.ts"
|
|
32
|
-
]
|
|
33
|
-
}
|
|
8
|
+
"expose:cmd": "mv -v dist/* ./ && rm -rf ./dist",
|
|
9
|
+
"build:clear": "rm -rf ./browser ./liveness ./node ./utils ./index.js ./index.d.ts ./dist",
|
|
10
|
+
"build:webpack": "webpack --mode=production",
|
|
11
|
+
"build:typescript": "npm run build:clear && tsc -p tsconfig.prod.json",
|
|
12
|
+
"build": "npm run build:typescript && npm run build:webpack && npm run expose:cmd",
|
|
13
|
+
"test": "jest --coverage false",
|
|
14
|
+
"test:coverage": "jest --coverage --runInBand"
|
|
34
15
|
},
|
|
35
16
|
"keywords": [],
|
|
36
17
|
"author": "SantoDigital",
|
|
@@ -58,6 +39,8 @@
|
|
|
58
39
|
"webpack-node-externals": "^3.0.0"
|
|
59
40
|
},
|
|
60
41
|
"dependencies": {
|
|
42
|
+
"axios": "^1.5.1",
|
|
43
|
+
"form-data": "^4.0.0",
|
|
61
44
|
"ws": "^8.14.2"
|
|
62
45
|
}
|
|
63
46
|
}
|
package/tsconfig.json
CHANGED
|
@@ -5,12 +5,16 @@
|
|
|
5
5
|
"target": "es2017",
|
|
6
6
|
"moduleResolution": "node",
|
|
7
7
|
"outDir": "dist",
|
|
8
|
-
"rootDir": "src",
|
|
9
8
|
"baseUrl": "./",
|
|
10
9
|
"declaration": true,
|
|
11
10
|
"esModuleInterop": true,
|
|
12
11
|
"strictNullChecks": true,
|
|
13
12
|
},
|
|
14
13
|
|
|
15
|
-
"include": [
|
|
14
|
+
"include": [
|
|
15
|
+
"./.eslintrc.js",
|
|
16
|
+
"./webpack.config.cjs",
|
|
17
|
+
"./jest.config.cjs",
|
|
18
|
+
"**/*.ts",
|
|
19
|
+
],
|
|
16
20
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"typeRoots": ["@types", "./node_modules/@types"],
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"target": "es2017",
|
|
6
|
+
"moduleResolution": "node",
|
|
7
|
+
"outDir": "dist",
|
|
8
|
+
"baseUrl": "./",
|
|
9
|
+
"declaration": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"strictNullChecks": true,
|
|
12
|
+
|
|
13
|
+
"rootDir": "src",
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
"include": [
|
|
17
|
+
"./.eslintrc.js",
|
|
18
|
+
"./webpack.config.cjs",
|
|
19
|
+
"./jest.config.cjs",
|
|
20
|
+
"src/**/*.ts",
|
|
21
|
+
],
|
|
22
|
+
|
|
23
|
+
"exclude": [
|
|
24
|
+
"__tests__/**/*.ts"
|
|
25
|
+
]
|
|
26
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export declare const WEBSOCKET_BASE_URL = "wss://santoid-liveness-w4ynos5dlq-ue.a.run.app/api/v1/liveness/ws";
|
|
2
|
-
export declare const API_GATEWAY_URL = "https://api.santoid.com.br
|
|
2
|
+
export declare const API_GATEWAY_URL = "https://api.santoid.com.br";
|
|
3
3
|
export declare const SEND_FRAMES_INTERVAL_MS = 100;
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SEND_FRAMES_INTERVAL_MS = exports.API_GATEWAY_URL = exports.WEBSOCKET_BASE_URL = void 0;
|
|
4
4
|
exports.WEBSOCKET_BASE_URL = 'wss://santoid-liveness-w4ynos5dlq-ue.a.run.app/api/v1/liveness/ws';
|
|
5
|
-
exports.API_GATEWAY_URL = 'https://api.santoid.com.br
|
|
5
|
+
exports.API_GATEWAY_URL = 'https://api.santoid.com.br';
|
|
6
6
|
exports.SEND_FRAMES_INTERVAL_MS = 100;
|
|
@@ -1,32 +1,36 @@
|
|
|
1
1
|
export type TCallbackFunction = (...args: any[]) => void | Promise<void>;
|
|
2
2
|
export type TPositions = 'front' | 'right' | 'left' | 'up' | 'bottom';
|
|
3
|
-
export type TErrorCode = 'wrong-position' | 'internal-error';
|
|
3
|
+
export type TErrorCode = 'wrong-position' | 'internal-error' | 'typification-error' | 'face-match-error' | 'liveness-error';
|
|
4
4
|
export interface IDecodedToken {
|
|
5
5
|
claims: {
|
|
6
6
|
domain: string;
|
|
7
7
|
};
|
|
8
8
|
}
|
|
9
|
-
interface ILivenessResults<FrameType> {
|
|
9
|
+
export interface ILivenessResults<FrameType> {
|
|
10
10
|
livenessId: string;
|
|
11
11
|
successFrames: Record<TPositions, FrameType>;
|
|
12
12
|
}
|
|
13
|
-
export interface
|
|
13
|
+
export interface IBaseSDKOptions {
|
|
14
14
|
token: string;
|
|
15
15
|
track: string;
|
|
16
16
|
customId?: string;
|
|
17
17
|
domain?: string;
|
|
18
|
-
|
|
18
|
+
customWebSocketUrl?: string;
|
|
19
|
+
customApiUrl?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface ISDKOptions extends IBaseSDKOptions {
|
|
22
|
+
nextStepCallback?: <TStepType = TPositions>(step: TStepType) => void | Promise<void>;
|
|
19
23
|
frontCallback?: TCallbackFunction;
|
|
20
24
|
rightCallback?: TCallbackFunction;
|
|
21
25
|
leftCallback?: TCallbackFunction;
|
|
22
26
|
upCallback?: TCallbackFunction;
|
|
23
27
|
bottomCallback?: TCallbackFunction;
|
|
24
|
-
errorCallback?: (error
|
|
28
|
+
errorCallback?: (error?: {
|
|
25
29
|
code: TErrorCode;
|
|
30
|
+
details?: any;
|
|
26
31
|
}) => void | Promise<void>;
|
|
27
|
-
successCallback?: <FrameType
|
|
32
|
+
successCallback?: <FrameType, ResultsType = ILivenessResults<FrameType>>(results?: ResultsType) => void | Promise<void>;
|
|
28
33
|
endCallback?: TCallbackFunction;
|
|
29
|
-
customWebSocketUrl?: string;
|
|
30
34
|
}
|
|
31
35
|
export interface IWebSocketMessage {
|
|
32
36
|
can_send_next_bytes?: boolean;
|
|
@@ -36,4 +40,3 @@ export interface IWebSocketMessage {
|
|
|
36
40
|
success?: boolean;
|
|
37
41
|
livenessId: string;
|
|
38
42
|
}
|
|
39
|
-
export {};
|
package/webpack.config.cjs
CHANGED
|
@@ -7,6 +7,7 @@ const generalConfig = {
|
|
|
7
7
|
aggregateTimeout: 600,
|
|
8
8
|
ignored: /node_modules/,
|
|
9
9
|
},
|
|
10
|
+
|
|
10
11
|
plugins: [
|
|
11
12
|
new CleanWebpackPlugin({
|
|
12
13
|
cleanStaleWebpackAssets: false,
|
|
@@ -15,22 +16,31 @@ const generalConfig = {
|
|
|
15
16
|
],
|
|
16
17
|
}),
|
|
17
18
|
],
|
|
19
|
+
|
|
18
20
|
module: {
|
|
19
21
|
rules: [
|
|
20
22
|
{
|
|
21
23
|
test: /\.tsx?$/,
|
|
22
|
-
use:
|
|
24
|
+
use: [
|
|
25
|
+
{
|
|
26
|
+
loader: 'ts-loader',
|
|
27
|
+
options: {
|
|
28
|
+
configFile: 'tsconfig.prod.json',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
],
|
|
23
32
|
exclude: /node_modules/,
|
|
24
33
|
},
|
|
25
34
|
],
|
|
26
35
|
},
|
|
36
|
+
|
|
27
37
|
resolve: {
|
|
28
38
|
extensions: ['.tsx', '.ts', '.js'],
|
|
29
39
|
},
|
|
30
40
|
}
|
|
31
41
|
|
|
32
42
|
const browserConfig = {
|
|
33
|
-
entry: './src/
|
|
43
|
+
entry: './src/liveness/index.ts',
|
|
34
44
|
target: 'web',
|
|
35
45
|
output: {
|
|
36
46
|
path: path.resolve(__dirname, './dist/browser/liveness'),
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("SantoiDSDK",[],t):"object"==typeof exports?exports.SantoiDSDK=t():e.SantoiDSDK=t()}(this,(()=>(()=>{"use strict";var e={401:function(e,t,o){var n=this&&this.__createBinding||(Object.create?function(e,t,o,n){void 0===n&&(n=o);var a=Object.getOwnPropertyDescriptor(t,o);a&&!("get"in a?!t.__esModule:a.writable||a.configurable)||(a={enumerable:!0,get:function(){return t[o]}}),Object.defineProperty(e,n,a)}:function(e,t,o,n){void 0===n&&(n=o),e[n]=t[o]}),a=this&&this.__exportStar||function(e,t){for(var o in e)"default"===o||Object.prototype.hasOwnProperty.call(t,o)||n(t,e,o)};Object.defineProperty(t,"__esModule",{value:!0}),t.livenessDetection=void 0;const r=o(553),i=o(793),l=o(692);async function c(e){var t,o,n;let a,c=!1,s=!1,d=!1,u=!0;const v={front:void 0,right:void 0,left:void 0,up:void 0,bottom:void 0};let p,f,_,b="front";async function m(e,t,o){var n;o&&clearInterval(o),t&&(0,l.disconnectFromWebSocket)(t),a&&a.stopGetNextFrame(),!d&&await(null===(n=e.endCallback)||void 0===n?void 0:n.call(e)),d=!0,c=!0}try{return _=await(0,l.connectToWebSocket)(e),await(null===(t=e.nextStepCallback)||void 0===t?void 0:t.call(e,"front")),await(null===(o=e.frontCallback)||void 0===o?void 0:o.call(e)),e.getNextFrame||a||(a=await(0,i.builtInGetNextFrame)()),f=setInterval((async()=>{try{if(u){let t;t=e.getNextFrame?await e.getNextFrame():await(null==a?void 0:a.getNextFrame()),t&&(null==_||_.send(t),p=t,u=!1)}}catch(t){await m(e,_,f)}}),r.SEND_FRAMES_INTERVAL_MS),_.addEventListener("message",(async t=>{var o;const n=await async function(e,t){var o,n,a;const r=t.data;let i;try{i=JSON.parse(r)}catch(e){console.error("Cannot parse API message",e)}return(null==i?void 0:i.next_step)&&!i.error&&(await(null===(o=e.nextStepCallback)||void 0===o?void 0:o.call(e,i.next_step)),await(null===(n=e[`${i.next_step}Callback`])||void 0===n?void 0:n.call(e))),(null==i?void 0:i.error)&&await(null===(a=e.errorCallback)||void 0===a?void 0:a.call(e,{code:"wrong-position"})),i}(e,t);n&&(u=!!(null==n?void 0:n.can_send_next_bytes)),(null==n?void 0:n.validation)&&b&&(v[b]=p),(null==n?void 0:n.next_step)&&(b=n.next_step),(null==n?void 0:n.success)&&(v.bottom=p,s=!0,await(null===(o=e.successCallback)||void 0===o?void 0:o.call(e,{livenessId:n.livenessId,successFrames:v})),await m(e,_,f))})),_.addEventListener("error",(async()=>{var t;!s&&(null===(t=e.errorCallback)||void 0===t||t.call(e,{code:"internal-error"})),await m(e,_,f)})),_.addEventListener("close",(async()=>{var t;c||(!s&&(null===(t=e.errorCallback)||void 0===t||t.call(e,{code:"internal-error"})),await m(e,_,f))})),{stopLivenessDetection:async()=>{await m(e,_,f)},videoStream:null==a?void 0:a.videoStream}}catch(t){throw!s&&(null===(n=e.errorCallback)||void 0===n||n.call(e,{code:"internal-error"})),await m(e,_,f),t}}a(o(722),t),t.livenessDetection=c;class s{}s.livenessDetection=c,t.default=s},793:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.builtInGetNextFrame=void 0,t.builtInGetNextFrame=async function(){let e,t,o,n;return e&&t&&o||(e=await navigator.mediaDevices.getUserMedia({video:!0}),t=document.createElement("video"),t.setAttribute("autoplay","true"),t.style.transform="scale(-1, 1)",t.style.position="absolute",t.style.left="99999px",document.body.appendChild(t),t.srcObject=e,o=document.createElement("canvas"),n=o.getContext("2d")),{getNextFrame:async function(){if(o&&t)return o.width=t.videoWidth,o.height=t.videoHeight,null==n||n.drawImage(t,0,0,o.width,o.height),await new Promise(((e,t)=>{o?o.toBlob((t=>{e(t)})):e(null)}));throw new Error("Cannot found video element")},stopGetNextFrame:function(){t&&(document.body.removeChild(t),t=void 0),o&&(o=void 0),n&&(n=void 0),null==e||e.getTracks().forEach((e=>{e.stop()})),e=void 0},videoStream:e}}},268:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.decodeJwt=void 0,t.decodeJwt=function(e){const t=e.split(".")[1].replace(/-/g,"+").replace(/_/g,"/"),o=decodeURIComponent(window.atob(t).split("").map((e=>"%"+("00"+e.charCodeAt(0).toString(16)).slice(-2))).join(""));return JSON.parse(o)}},722:function(e,t,o){var n=this&&this.__createBinding||(Object.create?function(e,t,o,n){void 0===n&&(n=o);var a=Object.getOwnPropertyDescriptor(t,o);a&&!("get"in a?!t.__esModule:a.writable||a.configurable)||(a={enumerable:!0,get:function(){return t[o]}}),Object.defineProperty(e,n,a)}:function(e,t,o,n){void 0===n&&(n=o),e[n]=t[o]}),a=this&&this.__exportStar||function(e,t){for(var o in e)"default"===o||Object.prototype.hasOwnProperty.call(t,o)||n(t,e,o)};Object.defineProperty(t,"__esModule",{value:!0}),a(o(307),t)},692:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.disconnectFromWebSocket=t.connectToWebSocket=void 0;const n=o(268),a=o(553);t.connectToWebSocket=async function(e){var t,o;const r=(0,n.decodeJwt)(e.token),i=`?x_endpoint_api_userinfo=${e.token}&domain=${null!==(t=e.domain)&&void 0!==t?t:r.claims.domain}&track=${e.track}&customerRequestId=${e.customId}`,l=new WebSocket(`${null!==(o=e.customWebSocketUrl)&&void 0!==o?o:a.WEBSOCKET_BASE_URL}${i}`);return await async function(e){if(await new Promise((t=>{const o=setInterval((()=>{[3,1].includes(e.readyState)&&(clearInterval(o),t())}),5)})),3===e.readyState)throw new Error("Cannot connect to server")}(l),l},t.disconnectFromWebSocket=function(e){var t;[2,3].includes(e.readyState)||null===(t=e.close)||void 0===t||t.call(e)}},553:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.SEND_FRAMES_INTERVAL_MS=t.API_GATEWAY_URL=t.WEBSOCKET_BASE_URL=void 0,t.WEBSOCKET_BASE_URL="wss://santoid-liveness-w4ynos5dlq-ue.a.run.app/api/v1/liveness/ws",t.API_GATEWAY_URL="https://api.santoid.com.br/api/v1/service-account/refresh-token",t.SEND_FRAMES_INTERVAL_MS=100},307:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0})}},t={},o=function o(n){var a=t[n];if(void 0!==a)return a.exports;var r=t[n]={exports:{}};return e[n].call(r.exports,r,r.exports,o),r.exports}(401);return o.default})()));
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { type TWebSDKOptions } from './utils/types';
|
|
2
|
-
export * from './utils/types';
|
|
3
|
-
export declare function livenessDetection(options: TWebSDKOptions): Promise<{
|
|
4
|
-
stopLivenessDetection: () => Promise<void>;
|
|
5
|
-
videoStream: MediaStream | undefined;
|
|
6
|
-
}>;
|
|
7
|
-
export default class SantoiDSDK {
|
|
8
|
-
static livenessDetection: typeof livenessDetection;
|
|
9
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function decodeJwt(token: string): any;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function decodeJwt(token: string): any;
|
package/jest.config.cjs
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
const config = {
|
|
2
|
-
testEnvironment: 'jsdom',
|
|
3
|
-
transform: {
|
|
4
|
-
'^.+\\.ts?$': 'ts-jest',
|
|
5
|
-
},
|
|
6
|
-
collectCoverageFrom: [
|
|
7
|
-
'<rootDir>/src/**/*.ts',
|
|
8
|
-
],
|
|
9
|
-
coveragePathIgnorePatterns: [
|
|
10
|
-
'types.ts',
|
|
11
|
-
],
|
|
12
|
-
setupFiles: [
|
|
13
|
-
'jest-canvas-mock',
|
|
14
|
-
],
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
module.exports = config
|