@neofaceid/web-sdk 1.4.0 → 1.4.2

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.
@@ -4,6 +4,7 @@ var __publicField = (obj, key, value) => {
4
4
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
5
  return value;
6
6
  };
7
+ var _a;
7
8
  import require$$0$1, { useRef, useState, useCallback, useReducer, useEffect } from "react";
8
9
  import require$$0 from "react-dom";
9
10
  import * as faceapi from "face-api.js";
@@ -1006,7 +1007,7 @@ const useCamera = () => {
1006
1007
  };
1007
1008
  const startCamera = useCallback(
1008
1009
  async (constraints) => {
1009
- var _a;
1010
+ var _a2;
1010
1011
  console.log("🎬 [useCamera] startCamera chamado", {
1011
1012
  hasExistingStream: !!streamRef.current,
1012
1013
  isInitializing: isInitializingRef.current
@@ -1048,7 +1049,7 @@ const useCamera = () => {
1048
1049
  console.log("📋 [useCamera] Detalhes do erro:", {
1049
1050
  name: error.name,
1050
1051
  message: error.message,
1051
- stack: (_a = error.stack) == null ? void 0 : _a.substring(0, 200)
1052
+ stack: (_a2 = error.stack) == null ? void 0 : _a2.substring(0, 200)
1052
1053
  });
1053
1054
  if (error.name === "NotAllowedError" || error.name === "PermissionDeniedError") {
1054
1055
  throw new CameraPermissionDenied(
@@ -1135,10 +1136,11 @@ class NeoFaceError extends Error {
1135
1136
  this.type = type;
1136
1137
  }
1137
1138
  }
1138
- const API_BASE_URL = "https://core.neofaceid.com.br";
1139
+ const API_BASE_URL = ((_a = { "BASE_URL": "/", "MODE": "production", "DEV": false, "PROD": true, "SSR": false }) == null ? void 0 : _a.VITE_API_BASE_URL) || "http://localhost:8000";
1139
1140
  const REQUEST_TIMEOUT = 1e4;
1140
1141
  const ensureSecureContext = () => {
1141
- if (!window.isSecureContext) {
1142
+ const isLocalhost = window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1" || window.location.hostname === "";
1143
+ if (!window.isSecureContext && !isLocalhost) {
1142
1144
  throw new NeoFaceError(
1143
1145
  "Secure context (HTTPS) is required for this operation",
1144
1146
  ErrorType.NETWORK
@@ -1184,7 +1186,7 @@ const validateToken = async (applicationToken) => {
1184
1186
  ensureSecureContext();
1185
1187
  const controller = createTimeoutController();
1186
1188
  try {
1187
- const response = await fetch(`${API_BASE_URL}/api/v1/external/auth/validate-token/`, {
1189
+ const response = await fetch(`${API_BASE_URL}/api/v1/auth/application/validate_token/`, {
1188
1190
  method: "POST",
1189
1191
  headers: {
1190
1192
  "Content-Type": "application/json",
@@ -1444,7 +1446,7 @@ const recognize = async (image, applicationToken) => {
1444
1446
  }
1445
1447
  };
1446
1448
  const loginWithBiometric$1 = async (image, applicationToken) => {
1447
- var _a, _b, _c, _d, _e;
1449
+ var _a2, _b, _c, _d, _e;
1448
1450
  ensureSecureContext();
1449
1451
  const controller = createTimeoutController();
1450
1452
  const compressedImage = await compressImage(image);
@@ -1474,7 +1476,7 @@ const loginWithBiometric$1 = async (image, applicationToken) => {
1474
1476
  accessToken: data.accessToken,
1475
1477
  alias: data.alias,
1476
1478
  user: {
1477
- id: ((_a = data.user) == null ? void 0 : _a.id) || "",
1479
+ id: ((_a2 = data.user) == null ? void 0 : _a2.id) || "",
1478
1480
  email: ((_b = data.user) == null ? void 0 : _b.email) || "",
1479
1481
  role: ((_c = data.user) == null ? void 0 : _c.role) || "",
1480
1482
  validated: ((_d = data.user) == null ? void 0 : _d.validated) || false,
@@ -1687,6 +1689,7 @@ const registerPersonWithoutFace = async (personData, applicationToken) => {
1687
1689
  }
1688
1690
  };
1689
1691
  const registerPersonWithBiometric = async (personData, facePhotos, applicationToken) => {
1692
+ var _a2, _b, _c, _d, _e, _f, _g, _h;
1690
1693
  ensureSecureContext();
1691
1694
  if (!facePhotos || facePhotos.length === 0) {
1692
1695
  throw new NeoFaceError("At least one face photo is required for biometric registration", ErrorType.VALIDATION_ERROR);
@@ -1733,29 +1736,56 @@ const registerPersonWithBiometric = async (personData, facePhotos, applicationTo
1733
1736
  }
1734
1737
  try {
1735
1738
  const errorData = await response.json();
1739
+ if (errorData.errors) {
1740
+ const errorMessages = Object.entries(errorData.errors).map(([field, messages]) => {
1741
+ const fieldName = field === "password" ? "senha" : field === "password_confirm" ? "confirmação de senha" : field;
1742
+ const messageList = Array.isArray(messages) ? messages.join(", ") : String(messages);
1743
+ return `${fieldName}: ${messageList}`;
1744
+ }).join("; ");
1745
+ throw new NeoFaceError(`Erro de validação: ${errorMessages}`, ErrorType.VALIDATION_ERROR);
1746
+ }
1736
1747
  if (errorData.error === "fraud_detected") {
1737
1748
  throw new NeoFaceError("Fraud detected in biometric images. Registration blocked.", ErrorType.VALIDATION_ERROR);
1738
1749
  }
1739
- if (errorData.error === "user_exists") {
1750
+ if (errorData.error === "user_exists" || errorData.error_code === "ALREADY_EXISTS") {
1740
1751
  throw new NeoFaceError("User with this email already exists", ErrorType.VALIDATION_ERROR);
1741
1752
  }
1742
1753
  if (errorData.error === "person_exists") {
1743
1754
  throw new NeoFaceError("Person with this CPF already exists", ErrorType.VALIDATION_ERROR);
1744
1755
  }
1745
- throw new NeoFaceError(errorData.message || `Server returned status ${response.status}`, ErrorType.NETWORK);
1756
+ const errorMessage = errorData.message || errorData.error || `Server returned status ${response.status}`;
1757
+ throw new NeoFaceError(errorMessage, ErrorType.VALIDATION_ERROR);
1746
1758
  } catch (parseError) {
1759
+ if (parseError instanceof NeoFaceError) {
1760
+ throw parseError;
1761
+ }
1747
1762
  throw new NeoFaceError(`Server returned status ${response.status}`, ErrorType.NETWORK);
1748
1763
  }
1749
1764
  }
1750
1765
  const data = await response.json();
1766
+ if (response.status === 202 && ((_a2 = data.data) == null ? void 0 : _a2.task_id)) {
1767
+ return {
1768
+ success: data.success,
1769
+ message: data.message || "Registration is being processed. You will receive an email when completed.",
1770
+ task_id: data.data.task_id,
1771
+ status: data.data.status || "processing",
1772
+ person_id: void 0,
1773
+ user_id: void 0,
1774
+ person_validated: void 0,
1775
+ face_processing: void 0,
1776
+ onboarding_link: void 0
1777
+ };
1778
+ }
1751
1779
  return {
1752
1780
  success: data.success,
1753
1781
  message: data.message,
1754
- person_id: data.person_id,
1755
- user_id: data.user_id,
1756
- person_validated: data.person_validated,
1757
- face_processing: data.face_processing,
1758
- onboarding_link: data.onboarding_link
1782
+ person_id: ((_b = data.data) == null ? void 0 : _b.person_id) || data.person_id,
1783
+ user_id: ((_c = data.data) == null ? void 0 : _c.user_id) || data.user_id,
1784
+ person_validated: ((_d = data.data) == null ? void 0 : _d.person_validated) || data.person_validated,
1785
+ face_processing: ((_e = data.data) == null ? void 0 : _e.face_processing) || data.face_processing,
1786
+ onboarding_link: ((_f = data.data) == null ? void 0 : _f.onboarding_link) || data.onboarding_link,
1787
+ task_id: (_g = data.data) == null ? void 0 : _g.task_id,
1788
+ status: (_h = data.data) == null ? void 0 : _h.status
1759
1789
  };
1760
1790
  } catch (error) {
1761
1791
  if (error instanceof Error) {
@@ -1817,7 +1847,7 @@ const loginWithEmail = async (email, password, applicationToken) => {
1817
1847
  }
1818
1848
  };
1819
1849
  const identifyPerson = async (image, applicationToken) => {
1820
- var _a, _b;
1850
+ var _a2, _b;
1821
1851
  ensureSecureContext();
1822
1852
  const controller = createTimeoutController();
1823
1853
  const compressedImage = await compressImage(image);
@@ -1853,7 +1883,7 @@ const identifyPerson = async (image, applicationToken) => {
1853
1883
  if (!data.success) {
1854
1884
  throw new NeoFaceError(data.message || "Person identification failed", ErrorType.RECOGNITION_FAILED);
1855
1885
  }
1856
- const personName = ((_a = data.person) == null ? void 0 : _a.name) || "";
1886
+ const personName = ((_a2 = data.person) == null ? void 0 : _a2.name) || "";
1857
1887
  const birthDateStr = (_b = data.person) == null ? void 0 : _b.birth_date;
1858
1888
  if (!personName) {
1859
1889
  throw new NeoFaceError("Person name not found in response", ErrorType.PERSON_NOT_FOUND);
@@ -2129,8 +2159,8 @@ function FaceCaptureModal({ accessToken, onClose, onSuccess }) {
2129
2159
  canvasRef.current.height = videoRef.current.videoHeight;
2130
2160
  context.drawImage(videoRef.current, 0, 0, canvasRef.current.width, canvasRef.current.height);
2131
2161
  const blob = await new Promise((resolve, reject) => {
2132
- var _a;
2133
- (_a = canvasRef.current) == null ? void 0 : _a.toBlob(
2162
+ var _a2;
2163
+ (_a2 = canvasRef.current) == null ? void 0 : _a2.toBlob(
2134
2164
  (b) => {
2135
2165
  if (b)
2136
2166
  resolve(b);
@@ -2267,8 +2297,8 @@ function BiometricRegistrationModal({
2267
2297
  onClose,
2268
2298
  onSuccess,
2269
2299
  onError,
2270
- useRealApi = false
2271
- // 🚀 Por padrão, modo simulado
2300
+ useRealApi = true
2301
+ // Sempre usa API real em produção
2272
2302
  }) {
2273
2303
  const videoRef = useRef(null);
2274
2304
  const canvasRef = useRef(null);
@@ -2530,8 +2560,8 @@ function BiometricRegistrationModal({
2530
2560
  }
2531
2561
  };
2532
2562
  const startTimer = setTimeout(() => {
2533
- var _a;
2534
- if (isRunning && ((_a = videoRef.current) == null ? void 0 : _a.readyState) === 4) {
2563
+ var _a2;
2564
+ if (isRunning && ((_a2 = videoRef.current) == null ? void 0 : _a2.readyState) === 4) {
2535
2565
  detectFace2();
2536
2566
  }
2537
2567
  }, 1e3);
@@ -2592,60 +2622,19 @@ function BiometricRegistrationModal({
2592
2622
  };
2593
2623
  const processRegistration = async (photos) => {
2594
2624
  try {
2595
- if (useRealApi) {
2596
- console.log("🚀 Fazendo requisição REAL ao backend de produção...");
2597
- const result2 = await registerPersonWithBiometric(personData, photos, applicationToken);
2598
- const adaptedResult = {
2599
- success: result2.success,
2600
- message: result2.message,
2601
- person_id: result2.person_id,
2602
- user_id: result2.user_id,
2603
- person_validated: result2.person_validated,
2604
- face_processing: result2.face_processing,
2605
- onboarding_link: result2.onboarding_link
2606
- };
2607
- dispatch({ type: "SUCCESS" });
2608
- onSuccess(adaptedResult);
2609
- return;
2610
- }
2611
- console.log("🎭 Usando modo SIMULADO para testes...");
2612
- const facePhotosBase64 = await Promise.all(
2613
- photos.map(async (photo) => {
2614
- return new Promise((resolve, reject) => {
2615
- const reader = new FileReader();
2616
- reader.onload = () => {
2617
- const result2 = reader.result;
2618
- resolve(result2);
2619
- };
2620
- reader.onerror = reject;
2621
- reader.readAsDataURL(photo);
2622
- });
2623
- })
2624
- );
2625
- await new Promise((resolve) => setTimeout(resolve, 2e3));
2626
- const result = {
2627
- success: true,
2628
- message: "Registro biométrico realizado com sucesso",
2629
- person_id: "test-person-123",
2630
- user_id: "test-user-456",
2631
- person_validated: true,
2632
- face_processing: {
2633
- total_photos_captured: photos.length,
2634
- photo_sizes: photos.map((p, i) => ({
2635
- photo_index: i + 1,
2636
- size_kb: Math.round(p.size / 1024)
2637
- })),
2638
- // Mostra apenas preview dos primeiros 50 caracteres de cada foto em base64
2639
- photos_preview: facePhotosBase64.map((b64, i) => ({
2640
- photo_index: i + 1,
2641
- format: "data:image/jpeg;base64,...",
2642
- preview: b64.substring(0, 50) + "...",
2643
- full_length: b64.length
2644
- }))
2645
- }
2625
+ console.log("🚀 Fazendo requisição ao backend...");
2626
+ const result = await registerPersonWithBiometric(personData, photos, applicationToken);
2627
+ const adaptedResult = {
2628
+ success: result.success,
2629
+ message: result.message,
2630
+ person_id: result.person_id,
2631
+ user_id: result.user_id,
2632
+ person_validated: result.person_validated,
2633
+ face_processing: result.face_processing,
2634
+ onboarding_link: result.onboarding_link
2646
2635
  };
2647
2636
  dispatch({ type: "SUCCESS" });
2648
- onSuccess(result);
2637
+ onSuccess(adaptedResult);
2649
2638
  } catch (error) {
2650
2639
  const errorMessage = error instanceof Error ? error.message : "Erro desconhecido";
2651
2640
  dispatch({ type: "ERROR", message: errorMessage });
@@ -3529,21 +3518,21 @@ let BiometricCaptureModal$1 = class BiometricCaptureModal2 {
3529
3518
  const cancelBtn = this.modal.querySelector(".neofaceid-cancel-btn");
3530
3519
  const captureBtn = this.modal.querySelector(".neofaceid-capture-btn");
3531
3520
  closeBtn == null ? void 0 : closeBtn.addEventListener("click", () => {
3532
- var _a, _b;
3521
+ var _a2, _b;
3533
3522
  this.close();
3534
- (_b = (_a = this.options).onCancel) == null ? void 0 : _b.call(_a);
3523
+ (_b = (_a2 = this.options).onCancel) == null ? void 0 : _b.call(_a2);
3535
3524
  });
3536
3525
  cancelBtn == null ? void 0 : cancelBtn.addEventListener("click", () => {
3537
- var _a, _b;
3526
+ var _a2, _b;
3538
3527
  this.close();
3539
- (_b = (_a = this.options).onCancel) == null ? void 0 : _b.call(_a);
3528
+ (_b = (_a2 = this.options).onCancel) == null ? void 0 : _b.call(_a2);
3540
3529
  });
3541
3530
  captureBtn == null ? void 0 : captureBtn.addEventListener("click", () => {
3542
3531
  this.captureImage();
3543
3532
  });
3544
3533
  this.modal.addEventListener("click", (e) => {
3545
- var _a, _b, _c;
3546
- if (e.target === ((_a = this.modal) == null ? void 0 : _a.querySelector(".neofaceid-modal-overlay"))) {
3534
+ var _a2, _b, _c;
3535
+ if (e.target === ((_a2 = this.modal) == null ? void 0 : _a2.querySelector(".neofaceid-modal-overlay"))) {
3547
3536
  this.close();
3548
3537
  (_c = (_b = this.options).onCancel) == null ? void 0 : _c.call(_b);
3549
3538
  }
@@ -4000,7 +3989,7 @@ function BiometricStatusOverlayComponent({ status, onClose }) {
4000
3989
  alt: "NeoFaceId",
4001
3990
  className: `neofaceid-logo ${status === "verifying" ? "pulsing" : ""}`,
4002
3991
  onError: (e) => {
4003
- var _a;
3992
+ var _a2;
4004
3993
  const img = e.target;
4005
3994
  img.style.display = "none";
4006
3995
  const fallback = document.createElement("div");
@@ -4011,7 +4000,7 @@ function BiometricStatusOverlayComponent({ status, onClose }) {
4011
4000
  </svg>
4012
4001
  `;
4013
4002
  fallback.style.cssText = "width: 80px; height: 80px; display: flex; align-items: center; justify-content: center;";
4014
- (_a = img.parentElement) == null ? void 0 : _a.appendChild(fallback);
4003
+ (_a2 = img.parentElement) == null ? void 0 : _a2.appendChild(fallback);
4015
4004
  }
4016
4005
  }
4017
4006
  ) }),
@@ -5229,7 +5218,7 @@ const biometricDetection = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.
5229
5218
  initializeBiometricDetection,
5230
5219
  isAdvancedDetectionAvailable
5231
5220
  }, Symbol.toStringTag, { value: "Module" }));
5232
- const VERSION = "1.4.0";
5221
+ const VERSION = "1.4.2";
5233
5222
  const RELEASE_DATE = "2025-11-23";
5234
5223
  class OnboardingCaptureModal {
5235
5224
  constructor(options) {
@@ -5496,8 +5485,8 @@ function startBiometricRegistration(personData, applicationToken, callbacks, opt
5496
5485
  const modalElement = require$$0$1.createElement(BiometricRegistrationModal, {
5497
5486
  personData,
5498
5487
  applicationToken,
5499
- useRealApi: (options == null ? void 0 : options.useRealApi) || false,
5500
- // 🚀 Passa a flag para o modal
5488
+ useRealApi: (options == null ? void 0 : options.useRealApi) ?? true,
5489
+ // Sempre usa API real em produção
5501
5490
  onClose: cleanup,
5502
5491
  onSuccess: (result) => {
5503
5492
  cleanup();