@neofaceid/web-sdk 1.25.5 → 1.25.7
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/dist/index.d.ts +2 -1
- package/dist/neoface-id-sdk.es.js +141 -99
- package/dist/neoface-id-sdk.umd.js +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -496,6 +496,7 @@ export declare const ENVIRONMENT_URLS: Record<Environment, string>;
|
|
|
496
496
|
*/
|
|
497
497
|
export declare enum ErrorType {
|
|
498
498
|
NETWORK = "NetworkError",
|
|
499
|
+
/** @deprecated Use `ErrorType.NETWORK`. Mantido para compatibilidade com consumidores existentes do SDK. */
|
|
499
500
|
NETWORK_ERROR = "NetworkError",
|
|
500
501
|
INVALID_TOKEN = "InvalidTokenError",
|
|
501
502
|
RECOGNITION_FAILED = "RecognitionFailedError",
|
|
@@ -1362,6 +1363,6 @@ export declare const validateToken: (applicationToken: string) => Promise<boolea
|
|
|
1362
1363
|
* MINOR: Incrementado quando adicionamos funcionalidades mantendo compatibilidade
|
|
1363
1364
|
* PATCH: Incrementado quando corrigimos bugs mantendo compatibilidade
|
|
1364
1365
|
*/
|
|
1365
|
-
export declare const VERSION = "1.25.
|
|
1366
|
+
export declare const VERSION = "1.25.7";
|
|
1366
1367
|
|
|
1367
1368
|
export { }
|
|
@@ -5337,10 +5337,14 @@ function init(options = {}) {
|
|
|
5337
5337
|
if (applicationToken) {
|
|
5338
5338
|
globalConfig.applicationToken = applicationToken;
|
|
5339
5339
|
} else if (applicationToken === "") {
|
|
5340
|
-
console.warn(
|
|
5340
|
+
console.warn(
|
|
5341
|
+
"[NeoFaceID SDK] applicationToken vazio em init() — 401 esperado em chamadas autenticadas."
|
|
5342
|
+
);
|
|
5341
5343
|
}
|
|
5342
5344
|
globalConfig.initialized = true;
|
|
5343
|
-
console.log(
|
|
5345
|
+
console.log(
|
|
5346
|
+
`[NeoFaceID SDK] Inicializado - Ambiente: ${globalConfig.environment}, URL: ${globalConfig.baseUrl}`
|
|
5347
|
+
);
|
|
5344
5348
|
}
|
|
5345
5349
|
function getBaseUrl() {
|
|
5346
5350
|
if (!globalConfig.initialized) {
|
|
@@ -5410,8 +5414,8 @@ const compressDocumentImage = async (imageBlob) => new Promise((resolve, reject)
|
|
|
5410
5414
|
const img = new Image();
|
|
5411
5415
|
img.onload = () => {
|
|
5412
5416
|
const MAX_SIZE = 1280;
|
|
5413
|
-
let width = img
|
|
5414
|
-
let height = img
|
|
5417
|
+
let { width } = img;
|
|
5418
|
+
let { height } = img;
|
|
5415
5419
|
if (width > height && width > MAX_SIZE) {
|
|
5416
5420
|
height = height * MAX_SIZE / width;
|
|
5417
5421
|
width = MAX_SIZE;
|
|
@@ -6030,7 +6034,9 @@ const registerPersonWithoutFace = async (personData, applicationToken, options)
|
|
|
6030
6034
|
];
|
|
6031
6035
|
}
|
|
6032
6036
|
if (!applicationToken) {
|
|
6033
|
-
console.warn(
|
|
6037
|
+
console.warn(
|
|
6038
|
+
"[NeoFaceID SDK] registerPersonWithoutFace sem applicationToken — 401 esperado."
|
|
6039
|
+
);
|
|
6034
6040
|
}
|
|
6035
6041
|
const response = await fetch(`${getApiBaseUrl()}/api/v1/signup/donor/`, {
|
|
6036
6042
|
method: "POST",
|
|
@@ -6167,7 +6173,9 @@ const registerPersonWithBiometric = async (personData, facePhotos, applicationTo
|
|
|
6167
6173
|
];
|
|
6168
6174
|
}
|
|
6169
6175
|
if (!applicationToken) {
|
|
6170
|
-
console.warn(
|
|
6176
|
+
console.warn(
|
|
6177
|
+
"[NeoFaceID SDK] registerPersonWithBiometric sem applicationToken — 401 esperado."
|
|
6178
|
+
);
|
|
6171
6179
|
}
|
|
6172
6180
|
const response = await fetch(`${getApiBaseUrl()}/api/v1/signup/donor/`, {
|
|
6173
6181
|
method: "POST",
|
|
@@ -6709,18 +6717,16 @@ const startProofOfLife = async (videoBase64, applicationToken) => {
|
|
|
6709
6717
|
throw new NeoFaceError("Unknown error occurred", ErrorType.NETWORK_ERROR);
|
|
6710
6718
|
}
|
|
6711
6719
|
};
|
|
6712
|
-
const videoToBase64 = async (videoBlob) => {
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
|
|
6717
|
-
|
|
6718
|
-
|
|
6719
|
-
|
|
6720
|
-
|
|
6721
|
-
|
|
6722
|
-
});
|
|
6723
|
-
};
|
|
6720
|
+
const videoToBase64 = async (videoBlob) => new Promise((resolve, reject) => {
|
|
6721
|
+
const reader = new FileReader();
|
|
6722
|
+
reader.onload = () => {
|
|
6723
|
+
const result = reader.result;
|
|
6724
|
+
const base642 = result.includes(",") ? result.split(",")[1] : result;
|
|
6725
|
+
resolve(base642);
|
|
6726
|
+
};
|
|
6727
|
+
reader.onerror = () => reject(new NeoFaceError("Failed to convert video to base64", ErrorType.CAPTURE_ERROR));
|
|
6728
|
+
reader.readAsDataURL(videoBlob);
|
|
6729
|
+
});
|
|
6724
6730
|
const blobToBase64 = (blob) => new Promise((resolve, reject) => {
|
|
6725
6731
|
const reader = new FileReader();
|
|
6726
6732
|
reader.onload = () => {
|
|
@@ -6786,7 +6792,9 @@ const registerDocumentByImage = async (personId, jwtToken, images) => {
|
|
|
6786
6792
|
const getTaskStatus = async (taskId, applicationToken) => {
|
|
6787
6793
|
const controller = createTimeoutController();
|
|
6788
6794
|
{
|
|
6789
|
-
console.warn(
|
|
6795
|
+
console.warn(
|
|
6796
|
+
"[NeoFaceID SDK] getTaskStatus sem applicationToken — /tasks/status/ vai responder 401."
|
|
6797
|
+
);
|
|
6790
6798
|
}
|
|
6791
6799
|
try {
|
|
6792
6800
|
const response = await fetch(`${getApiBaseUrl()}/api/v1/tasks/status/?task_id=${taskId}`, {
|
|
@@ -6825,7 +6833,7 @@ const identifyPersonAsync = async (image, applicationToken, options = {}) => {
|
|
|
6825
6833
|
person: initialResponse.person
|
|
6826
6834
|
};
|
|
6827
6835
|
}
|
|
6828
|
-
const taskId = initialResponse
|
|
6836
|
+
const { taskId } = initialResponse;
|
|
6829
6837
|
if (!taskId) {
|
|
6830
6838
|
return { personFound: false };
|
|
6831
6839
|
}
|
|
@@ -7659,7 +7667,9 @@ function BiometricRegistrationModal({
|
|
|
7659
7667
|
const captureStateRef = useRef(null);
|
|
7660
7668
|
const [state, dispatch] = useReducer(modalReducer, void 0, createInitialState);
|
|
7661
7669
|
const [faceDetected, setFaceDetected] = useState(false);
|
|
7662
|
-
const [faceDistance, setFaceDistance] = useState(
|
|
7670
|
+
const [faceDistance, setFaceDistance] = useState(
|
|
7671
|
+
"ok"
|
|
7672
|
+
);
|
|
7663
7673
|
const [cameraReady, setCameraReady] = useState(false);
|
|
7664
7674
|
useEffect(() => {
|
|
7665
7675
|
if (state.status === "liveness") {
|
|
@@ -7790,15 +7800,13 @@ function BiometricRegistrationModal({
|
|
|
7790
7800
|
}
|
|
7791
7801
|
}, 50);
|
|
7792
7802
|
}
|
|
7793
|
-
} else {
|
|
7794
|
-
|
|
7795
|
-
|
|
7796
|
-
|
|
7797
|
-
|
|
7798
|
-
progressIntervalRef.current = null;
|
|
7799
|
-
}
|
|
7800
|
-
dispatch({ type: "UPDATE_PROGRESS", progress: 0 });
|
|
7803
|
+
} else if (holdStartTimeRef.current) {
|
|
7804
|
+
holdStartTimeRef.current = null;
|
|
7805
|
+
if (progressIntervalRef.current) {
|
|
7806
|
+
clearInterval(progressIntervalRef.current);
|
|
7807
|
+
progressIntervalRef.current = null;
|
|
7801
7808
|
}
|
|
7809
|
+
dispatch({ type: "UPDATE_PROGRESS", progress: 0 });
|
|
7802
7810
|
}
|
|
7803
7811
|
};
|
|
7804
7812
|
useEffect(() => {
|
|
@@ -7825,8 +7833,8 @@ function BiometricRegistrationModal({
|
|
|
7825
7833
|
};
|
|
7826
7834
|
loadModels();
|
|
7827
7835
|
}, []);
|
|
7828
|
-
useEffect(
|
|
7829
|
-
|
|
7836
|
+
useEffect(
|
|
7837
|
+
() => () => {
|
|
7830
7838
|
if (streamRef.current) {
|
|
7831
7839
|
streamRef.current.getTracks().forEach((track) => {
|
|
7832
7840
|
track.stop();
|
|
@@ -7848,8 +7856,9 @@ function BiometricRegistrationModal({
|
|
|
7848
7856
|
clearTimeout(stepTimeoutTimerRef.current);
|
|
7849
7857
|
stepTimeoutTimerRef.current = null;
|
|
7850
7858
|
}
|
|
7851
|
-
}
|
|
7852
|
-
|
|
7859
|
+
},
|
|
7860
|
+
[]
|
|
7861
|
+
);
|
|
7853
7862
|
useEffect(() => {
|
|
7854
7863
|
let mounted = true;
|
|
7855
7864
|
const initCamera = async () => {
|
|
@@ -7991,15 +8000,13 @@ function BiometricRegistrationModal({
|
|
|
7991
8000
|
);
|
|
7992
8001
|
manageHoldAndCapture(positionCorrect);
|
|
7993
8002
|
}
|
|
7994
|
-
} else {
|
|
7995
|
-
|
|
7996
|
-
|
|
7997
|
-
|
|
7998
|
-
|
|
7999
|
-
progressIntervalRef.current = null;
|
|
8000
|
-
}
|
|
8001
|
-
dispatch({ type: "UPDATE_PROGRESS", progress: 0 });
|
|
8003
|
+
} else if (holdStartTimeRef.current) {
|
|
8004
|
+
holdStartTimeRef.current = null;
|
|
8005
|
+
if (progressIntervalRef.current) {
|
|
8006
|
+
clearInterval(progressIntervalRef.current);
|
|
8007
|
+
progressIntervalRef.current = null;
|
|
8002
8008
|
}
|
|
8009
|
+
dispatch({ type: "UPDATE_PROGRESS", progress: 0 });
|
|
8003
8010
|
}
|
|
8004
8011
|
} catch (error) {
|
|
8005
8012
|
}
|
|
@@ -8028,38 +8035,37 @@ function BiometricRegistrationModal({
|
|
|
8028
8035
|
}
|
|
8029
8036
|
holdStartTimeRef.current = null;
|
|
8030
8037
|
};
|
|
8031
|
-
} else {
|
|
8032
|
-
const onCanPlay = () => {
|
|
8033
|
-
if (isRunning) startDetection();
|
|
8034
|
-
};
|
|
8035
|
-
let pollCount = 0;
|
|
8036
|
-
const MAX_POLLS = 50;
|
|
8037
|
-
const pollTimer = window.setInterval(() => {
|
|
8038
|
-
pollCount++;
|
|
8039
|
-
if (!isRunning) {
|
|
8040
|
-
clearInterval(pollTimer);
|
|
8041
|
-
return;
|
|
8042
|
-
}
|
|
8043
|
-
if (videoRef.current && videoRef.current.readyState >= 2) {
|
|
8044
|
-
clearInterval(pollTimer);
|
|
8045
|
-
videoRef.current.removeEventListener("canplay", onCanPlay);
|
|
8046
|
-
startDetection();
|
|
8047
|
-
} else if (pollCount >= MAX_POLLS) {
|
|
8048
|
-
clearInterval(pollTimer);
|
|
8049
|
-
}
|
|
8050
|
-
}, 300);
|
|
8051
|
-
video == null ? void 0 : video.addEventListener("canplay", onCanPlay, { once: true });
|
|
8052
|
-
return () => {
|
|
8053
|
-
isRunning = false;
|
|
8054
|
-
clearInterval(pollTimer);
|
|
8055
|
-
video == null ? void 0 : video.removeEventListener("canplay", onCanPlay);
|
|
8056
|
-
if (progressIntervalRef.current) {
|
|
8057
|
-
clearInterval(progressIntervalRef.current);
|
|
8058
|
-
progressIntervalRef.current = null;
|
|
8059
|
-
}
|
|
8060
|
-
holdStartTimeRef.current = null;
|
|
8061
|
-
};
|
|
8062
8038
|
}
|
|
8039
|
+
const onCanPlay = () => {
|
|
8040
|
+
if (isRunning) startDetection();
|
|
8041
|
+
};
|
|
8042
|
+
let pollCount = 0;
|
|
8043
|
+
const MAX_POLLS = 50;
|
|
8044
|
+
const pollTimer = window.setInterval(() => {
|
|
8045
|
+
pollCount++;
|
|
8046
|
+
if (!isRunning) {
|
|
8047
|
+
clearInterval(pollTimer);
|
|
8048
|
+
return;
|
|
8049
|
+
}
|
|
8050
|
+
if (videoRef.current && videoRef.current.readyState >= 2) {
|
|
8051
|
+
clearInterval(pollTimer);
|
|
8052
|
+
videoRef.current.removeEventListener("canplay", onCanPlay);
|
|
8053
|
+
startDetection();
|
|
8054
|
+
} else if (pollCount >= MAX_POLLS) {
|
|
8055
|
+
clearInterval(pollTimer);
|
|
8056
|
+
}
|
|
8057
|
+
}, 300);
|
|
8058
|
+
video == null ? void 0 : video.addEventListener("canplay", onCanPlay, { once: true });
|
|
8059
|
+
return () => {
|
|
8060
|
+
isRunning = false;
|
|
8061
|
+
clearInterval(pollTimer);
|
|
8062
|
+
video == null ? void 0 : video.removeEventListener("canplay", onCanPlay);
|
|
8063
|
+
if (progressIntervalRef.current) {
|
|
8064
|
+
clearInterval(progressIntervalRef.current);
|
|
8065
|
+
progressIntervalRef.current = null;
|
|
8066
|
+
}
|
|
8067
|
+
holdStartTimeRef.current = null;
|
|
8068
|
+
};
|
|
8063
8069
|
}, [state.status]);
|
|
8064
8070
|
const capturePhoto = async () => {
|
|
8065
8071
|
if (!videoRef.current || !canvasRef.current || isCapturingRef.current) {
|
|
@@ -8163,7 +8169,7 @@ function BiometricRegistrationModal({
|
|
|
8163
8169
|
const renderLivenessDetection = () => {
|
|
8164
8170
|
if (state.status !== "liveness") return null;
|
|
8165
8171
|
const progress = `${state.currentStepIndex + 1}/${state.stepSequence.length - 1}`;
|
|
8166
|
-
const stepProgress = state
|
|
8172
|
+
const { stepProgress } = state;
|
|
8167
8173
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "liveness-container", children: [
|
|
8168
8174
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "progress-indicator", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "progress-text", children: progress }) }),
|
|
8169
8175
|
faceDetected && faceDistance !== "ok" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `status-badge ${faceDistance === "not-centered" ? "warning" : "error"}`, children: [
|
|
@@ -8192,7 +8198,14 @@ function BiometricRegistrationModal({
|
|
|
8192
8198
|
stepProgress > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "progress-bar", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "progress-fill", style: { width: `${stepProgress}%` } }) })
|
|
8193
8199
|
] }),
|
|
8194
8200
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "branding-small", children: [
|
|
8195
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
8201
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
8202
|
+
"span",
|
|
8203
|
+
{
|
|
8204
|
+
className: "brand-logo-small",
|
|
8205
|
+
style: { display: "inline-flex", width: 18, height: 18, color: "currentColor" },
|
|
8206
|
+
dangerouslySetInnerHTML: { __html: NEOFACEID_MARK_MONO_SVG }
|
|
8207
|
+
}
|
|
8208
|
+
),
|
|
8196
8209
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "NeoFaceId by" }),
|
|
8197
8210
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "brand-name", children: "OCTA" })
|
|
8198
8211
|
] })
|
|
@@ -8239,8 +8252,16 @@ function BiometricRegistrationModal({
|
|
|
8239
8252
|
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { children: "Não foi possível processar" }),
|
|
8240
8253
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: state.message }),
|
|
8241
8254
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "button-group", children: [
|
|
8242
|
-
state.retryable && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
8243
|
-
|
|
8255
|
+
state.retryable && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
8256
|
+
"button",
|
|
8257
|
+
{
|
|
8258
|
+
type: "button",
|
|
8259
|
+
className: "secondary-button",
|
|
8260
|
+
onClick: () => dispatch({ type: "RESET" }),
|
|
8261
|
+
children: "Tentar Novamente"
|
|
8262
|
+
}
|
|
8263
|
+
),
|
|
8264
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "ghost-button", onClick: onClose, children: "Cancelar" })
|
|
8244
8265
|
] })
|
|
8245
8266
|
] });
|
|
8246
8267
|
};
|
|
@@ -8283,7 +8304,7 @@ function BiometricRegistrationModal({
|
|
|
8283
8304
|
] }) }),
|
|
8284
8305
|
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { children: onPhotosCaptured ? "Captura concluída!" : "Verificação concluída!" }),
|
|
8285
8306
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: onPhotosCaptured ? "Suas capturas faciais foram realizadas" : "Sua biometria foi registrada com sucesso" }),
|
|
8286
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "primary-button", onClick: onClose, children: "Continuar" })
|
|
8307
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "primary-button", onClick: onClose, children: "Continuar" })
|
|
8287
8308
|
] });
|
|
8288
8309
|
const renderDuplicate = () => {
|
|
8289
8310
|
if (state.status !== "duplicate") return null;
|
|
@@ -8295,6 +8316,7 @@ function BiometricRegistrationModal({
|
|
|
8295
8316
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
8296
8317
|
"button",
|
|
8297
8318
|
{
|
|
8319
|
+
type: "button",
|
|
8298
8320
|
className: "primary-button",
|
|
8299
8321
|
onClick: () => {
|
|
8300
8322
|
onClose();
|
|
@@ -8306,6 +8328,7 @@ function BiometricRegistrationModal({
|
|
|
8306
8328
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
8307
8329
|
"button",
|
|
8308
8330
|
{
|
|
8331
|
+
type: "button",
|
|
8309
8332
|
className: "secondary-button",
|
|
8310
8333
|
style: { marginTop: "12px" },
|
|
8311
8334
|
onClick: () => {
|
|
@@ -8320,6 +8343,7 @@ function BiometricRegistrationModal({
|
|
|
8320
8343
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
8321
8344
|
"button",
|
|
8322
8345
|
{
|
|
8346
|
+
type: "button",
|
|
8323
8347
|
className: "ghost-button",
|
|
8324
8348
|
onClick: () => window.open("https://support.neofaceid.com", "_blank"),
|
|
8325
8349
|
children: "Falar com Suporte"
|
|
@@ -8987,7 +9011,7 @@ function BiometricRegistrationModal({
|
|
|
8987
9011
|
}
|
|
8988
9012
|
` }),
|
|
8989
9013
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "modal-overlay", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "modal-content", children: [
|
|
8990
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "close-button", onClick: onClose, children: "×" }),
|
|
9014
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "close-button", onClick: onClose, children: "×" }),
|
|
8991
9015
|
state.status === "liveness" && renderLivenessDetection(),
|
|
8992
9016
|
state.status === "camera-loading" && renderCameraLoading(),
|
|
8993
9017
|
state.status === "processing" && renderProcessing(),
|
|
@@ -9253,7 +9277,7 @@ class BiometricCaptureModal {
|
|
|
9253
9277
|
} catch (error) {
|
|
9254
9278
|
this.options.onError(
|
|
9255
9279
|
new NeoFaceError(
|
|
9256
|
-
|
|
9280
|
+
`Erro ao inicializar câmera: ${error.message}`,
|
|
9257
9281
|
ErrorType.CAMERA_ERROR
|
|
9258
9282
|
)
|
|
9259
9283
|
);
|
|
@@ -9335,7 +9359,7 @@ class BiometricCaptureModal {
|
|
|
9335
9359
|
this.canvas.width = this.video.videoWidth;
|
|
9336
9360
|
this.canvas.height = this.video.videoHeight;
|
|
9337
9361
|
} catch (error) {
|
|
9338
|
-
throw new Error(
|
|
9362
|
+
throw new Error(`Não foi possível acessar a câmera: ${error.message}`);
|
|
9339
9363
|
}
|
|
9340
9364
|
}
|
|
9341
9365
|
/**
|
|
@@ -9389,13 +9413,13 @@ class BiometricCaptureModal {
|
|
|
9389
9413
|
const imageData = this.canvas.toDataURL("image/jpeg", 0.8);
|
|
9390
9414
|
const base64Data = imageData.split(",")[1];
|
|
9391
9415
|
const dataUrl = `data:image/jpeg;base64,${base64Data}`;
|
|
9392
|
-
|
|
9416
|
+
const detectedType = this.options.mode === "auto" ? await this.detectBiometricType(base64Data) : this.options.mode;
|
|
9393
9417
|
this.close();
|
|
9394
9418
|
this.options.onSuccess(dataUrl, detectedType);
|
|
9395
9419
|
} catch (error) {
|
|
9396
9420
|
this.options.onError(
|
|
9397
9421
|
new NeoFaceError(
|
|
9398
|
-
|
|
9422
|
+
`Erro ao capturar imagem: ${error.message}`,
|
|
9399
9423
|
ErrorType.CAPTURE_ERROR
|
|
9400
9424
|
)
|
|
9401
9425
|
);
|
|
@@ -10699,7 +10723,7 @@ async function captureFaceSilently() {
|
|
|
10699
10723
|
cleanup();
|
|
10700
10724
|
reject(
|
|
10701
10725
|
new NeoFaceError(
|
|
10702
|
-
|
|
10726
|
+
`Erro ao reproduzir câmera: ${err.message}`,
|
|
10703
10727
|
ErrorType.CAMERA_ERROR
|
|
10704
10728
|
)
|
|
10705
10729
|
);
|
|
@@ -10715,7 +10739,7 @@ async function captureFaceSilently() {
|
|
|
10715
10739
|
cleanup();
|
|
10716
10740
|
reject(
|
|
10717
10741
|
new NeoFaceError(
|
|
10718
|
-
|
|
10742
|
+
`Não foi possível acessar a câmera: ${error.message}`,
|
|
10719
10743
|
ErrorType.CAMERA_ERROR
|
|
10720
10744
|
)
|
|
10721
10745
|
);
|
|
@@ -11216,9 +11240,12 @@ async function detectBiometricType(imageData) {
|
|
|
11216
11240
|
async function detectFace(img) {
|
|
11217
11241
|
try {
|
|
11218
11242
|
if (typeof window !== "undefined" && window.faceapi) {
|
|
11219
|
-
const faceapi2 = window
|
|
11243
|
+
const { faceapi: faceapi2 } = window;
|
|
11220
11244
|
await loadFaceApiModels();
|
|
11221
|
-
const tinyOptions = new faceapi2.TinyFaceDetectorOptions({
|
|
11245
|
+
const tinyOptions = new faceapi2.TinyFaceDetectorOptions({
|
|
11246
|
+
inputSize: 320,
|
|
11247
|
+
scoreThreshold: 0.5
|
|
11248
|
+
});
|
|
11222
11249
|
const detections = await faceapi2.detectAllFaces(img, tinyOptions).withFaceLandmarks();
|
|
11223
11250
|
if (detections && detections.length > 0) {
|
|
11224
11251
|
const bestDetection = detections.reduce(
|
|
@@ -11317,7 +11344,7 @@ async function loadFaceApiModels() {
|
|
|
11317
11344
|
if (typeof window === "undefined" || !window.faceapi) {
|
|
11318
11345
|
return;
|
|
11319
11346
|
}
|
|
11320
|
-
const faceapi2 = window
|
|
11347
|
+
const { faceapi: faceapi2 } = window;
|
|
11321
11348
|
if (faceapi2.nets.tinyFaceDetector.isLoaded) {
|
|
11322
11349
|
return;
|
|
11323
11350
|
}
|
|
@@ -11348,7 +11375,7 @@ const biometricDetection = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.
|
|
|
11348
11375
|
initializeBiometricDetection,
|
|
11349
11376
|
isAdvancedDetectionAvailable
|
|
11350
11377
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
11351
|
-
const VERSION = "1.25.
|
|
11378
|
+
const VERSION = "1.25.7";
|
|
11352
11379
|
const RELEASE_DATE = "2026-08-29";
|
|
11353
11380
|
class OnboardingCaptureModal {
|
|
11354
11381
|
constructor(options) {
|
|
@@ -11376,7 +11403,10 @@ class OnboardingCaptureModal {
|
|
|
11376
11403
|
await this.runFaceCaptureCountdown();
|
|
11377
11404
|
this.faceBlob = await this.captureFrame();
|
|
11378
11405
|
this.step = "document";
|
|
11379
|
-
this.updateTexts(
|
|
11406
|
+
this.updateTexts(
|
|
11407
|
+
"Captura do Documento",
|
|
11408
|
+
'Posicione seu documento visível e clique em "Capturar"'
|
|
11409
|
+
);
|
|
11380
11410
|
await this.waitForUserCaptureClick();
|
|
11381
11411
|
this.documentBlob = await this.captureFrame();
|
|
11382
11412
|
await this.close();
|
|
@@ -11474,7 +11504,9 @@ class OnboardingCaptureModal {
|
|
|
11474
11504
|
async runFaceCaptureCountdown() {
|
|
11475
11505
|
if (!this.overlay) return;
|
|
11476
11506
|
const countdownEl = this.overlay.querySelector(".neofaceid-countdown");
|
|
11477
|
-
const countdownNumberEl = this.overlay.querySelector(
|
|
11507
|
+
const countdownNumberEl = this.overlay.querySelector(
|
|
11508
|
+
".neofaceid-countdown-number"
|
|
11509
|
+
);
|
|
11478
11510
|
const statusText = this.overlay.querySelector(".neofaceid-status-text");
|
|
11479
11511
|
countdownEl.style.display = "flex";
|
|
11480
11512
|
statusText.textContent = "Prepare-se! Capturando seu rosto...";
|
|
@@ -11521,7 +11553,11 @@ class OnboardingCaptureModal {
|
|
|
11521
11553
|
this.canvas.height = this.video.videoHeight;
|
|
11522
11554
|
ctx.drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height);
|
|
11523
11555
|
const blob = await new Promise((resolve, reject) => {
|
|
11524
|
-
this.canvas.toBlob(
|
|
11556
|
+
this.canvas.toBlob(
|
|
11557
|
+
(b) => b ? resolve(b) : reject(new Error("Falha ao gerar imagem")),
|
|
11558
|
+
"image/jpeg",
|
|
11559
|
+
0.92
|
|
11560
|
+
);
|
|
11525
11561
|
});
|
|
11526
11562
|
return blob;
|
|
11527
11563
|
}
|
|
@@ -12151,13 +12187,15 @@ class DocumentCaptureModal {
|
|
|
12151
12187
|
|
|
12152
12188
|
<div class="neoface-doc-body">
|
|
12153
12189
|
<div class="neoface-doc-select-grid">
|
|
12154
|
-
${Object.entries(DOCUMENT_INFO).filter(([type]) => type !== "CPF").map(
|
|
12190
|
+
${Object.entries(DOCUMENT_INFO).filter(([type]) => type !== "CPF").map(
|
|
12191
|
+
([type, info]) => `
|
|
12155
12192
|
<button class="neoface-doc-select-option" data-type="${type}">
|
|
12156
12193
|
<span class="neoface-doc-select-icon">${info.icon}</span>
|
|
12157
12194
|
<span class="neoface-doc-select-name">${info.name}</span>
|
|
12158
12195
|
<svg class="neoface-doc-select-arrow" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 18l6-6-6-6"/></svg>
|
|
12159
12196
|
</button>
|
|
12160
|
-
`
|
|
12197
|
+
`
|
|
12198
|
+
).join("")}
|
|
12161
12199
|
</div>
|
|
12162
12200
|
|
|
12163
12201
|
<div class="neoface-doc-tips">
|
|
@@ -12375,8 +12413,8 @@ class DocumentCaptureModal {
|
|
|
12375
12413
|
const img = new Image();
|
|
12376
12414
|
img.onload = () => {
|
|
12377
12415
|
const MAX_SIZE = 1280;
|
|
12378
|
-
let width = img
|
|
12379
|
-
let height = img
|
|
12416
|
+
let { width } = img;
|
|
12417
|
+
let { height } = img;
|
|
12380
12418
|
if (width > height && width > MAX_SIZE) {
|
|
12381
12419
|
height = height * MAX_SIZE / width;
|
|
12382
12420
|
width = MAX_SIZE;
|
|
@@ -12396,7 +12434,9 @@ class DocumentCaptureModal {
|
|
|
12396
12434
|
canvas.toBlob(
|
|
12397
12435
|
(blob) => {
|
|
12398
12436
|
if (blob) {
|
|
12399
|
-
console.log(
|
|
12437
|
+
console.log(
|
|
12438
|
+
`[DocumentCapture] Compressed image from ${(file.size / 1024).toFixed(0)}KB to ${(blob.size / 1024).toFixed(0)}KB`
|
|
12439
|
+
);
|
|
12400
12440
|
resolve(blob);
|
|
12401
12441
|
} else {
|
|
12402
12442
|
reject(new Error("Failed to compress image"));
|
|
@@ -12417,7 +12457,9 @@ class DocumentCaptureModal {
|
|
|
12417
12457
|
const retakeBtn = (_b = this.overlay) == null ? void 0 : _b.querySelector(".neoface-doc-retake-btn");
|
|
12418
12458
|
confirmBtn == null ? void 0 : confirmBtn.addEventListener("click", () => this.handleConfirm());
|
|
12419
12459
|
retakeBtn == null ? void 0 : retakeBtn.addEventListener("click", () => this.handleRetake());
|
|
12420
|
-
const previewImg = (_c = this.overlay) == null ? void 0 : _c.querySelector(
|
|
12460
|
+
const previewImg = (_c = this.overlay) == null ? void 0 : _c.querySelector(
|
|
12461
|
+
".neoface-doc-preview-current"
|
|
12462
|
+
);
|
|
12421
12463
|
if (previewImg) {
|
|
12422
12464
|
const blob = this.currentStep === "preview-front" ? this.frontBlob : this.backBlob;
|
|
12423
12465
|
if (blob) previewImg.src = URL.createObjectURL(blob);
|
|
@@ -12486,8 +12528,8 @@ class DocumentCaptureModal {
|
|
|
12486
12528
|
if (loading) loading.style.display = "flex";
|
|
12487
12529
|
const ctx = this.canvas.getContext("2d");
|
|
12488
12530
|
if (!ctx) return;
|
|
12489
|
-
const videoWidth = this.video
|
|
12490
|
-
const videoHeight = this.video
|
|
12531
|
+
const { videoWidth } = this.video;
|
|
12532
|
+
const { videoHeight } = this.video;
|
|
12491
12533
|
const frameWidthPercent = 0.75;
|
|
12492
12534
|
const frameHeightPercent = 0.65;
|
|
12493
12535
|
const cropWidth = Math.floor(videoWidth * frameWidthPercent);
|