@neofaceid/web-sdk 1.14.0 → 1.15.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.
@@ -5134,6 +5134,7 @@ class EmailPasswordModal {
5134
5134
  <div class="neoface-email-modal-content">
5135
5135
  <h2>${this.options.title || "Login com Email e Senha"}</h2>
5136
5136
  <p>${this.options.subtitle || "Informe seus dados para login."}</p>
5137
+ <div id="login-error" class="neoface-email-error" style="display:none"></div>
5137
5138
  <form id="email-password-form">
5138
5139
  <input type="email" id="email" placeholder="Email" required />
5139
5140
  <input type="password" id="password" placeholder="Senha" required />
@@ -5335,6 +5336,18 @@ class EmailPasswordModal {
5335
5336
  letter-spacing: 0.3px;
5336
5337
  }
5337
5338
 
5339
+ .neoface-email-error {
5340
+ background: rgba(239, 68, 68, 0.15);
5341
+ border: 1px solid rgba(239, 68, 68, 0.4);
5342
+ border-radius: 10px;
5343
+ color: #fca5a5;
5344
+ font-size: 14px;
5345
+ padding: 12px 16px;
5346
+ margin-bottom: 16px;
5347
+ text-align: center;
5348
+ animation: fadeIn 0.2s ease-out;
5349
+ }
5350
+
5338
5351
  @media (max-width: 640px) {
5339
5352
  .neoface-email-modal-content {
5340
5353
  padding: 24px;
@@ -5352,20 +5365,40 @@ class EmailPasswordModal {
5352
5365
  event.preventDefault();
5353
5366
  const emailInput = this.modalElement.querySelector("#email");
5354
5367
  const passwordInput = this.modalElement.querySelector("#password");
5368
+ const submitBtn = this.modalElement.querySelector(
5369
+ ".neoface-email-submit-btn"
5370
+ );
5371
+ const errorDiv = this.modalElement.querySelector("#login-error");
5372
+ const showError = (msg) => {
5373
+ errorDiv.textContent = msg;
5374
+ errorDiv.style.display = "block";
5375
+ };
5376
+ errorDiv.style.display = "none";
5377
+ errorDiv.textContent = "";
5355
5378
  const email = emailInput.value.trim();
5356
5379
  const password = passwordInput.value.trim();
5357
5380
  if (!email || !password) {
5358
- this.options.onError(
5359
- new NeoFaceError("Email e senha são obrigatórios", ErrorType.VALIDATION_ERROR)
5360
- );
5381
+ showError("Preencha o email e a senha para continuar.");
5361
5382
  return;
5362
5383
  }
5384
+ submitBtn.disabled = true;
5385
+ submitBtn.textContent = "Entrando...";
5363
5386
  try {
5364
5387
  const result = await loginWithEmail(email, password, this.options.applicationToken);
5365
5388
  this.options.onSuccess(result);
5366
5389
  this.close();
5367
5390
  } catch (error) {
5368
- this.options.onError(error);
5391
+ submitBtn.disabled = false;
5392
+ submitBtn.textContent = "Entrar";
5393
+ const isCredentialError = error instanceof NeoFaceError && (error.type === ErrorType.INVALID_TOKEN || error.type === ErrorType.API_ERROR && error.message.includes("400"));
5394
+ if (isCredentialError) {
5395
+ showError("Email ou senha incorretos. Verifique seus dados e tente novamente.");
5396
+ passwordInput.value = "";
5397
+ passwordInput.focus();
5398
+ } else {
5399
+ showError("Ocorreu um erro inesperado. Tente novamente mais tarde.");
5400
+ this.options.onError(error);
5401
+ }
5369
5402
  }
5370
5403
  }
5371
5404
  }
@@ -5507,7 +5540,12 @@ async function captureFaceSilently() {
5507
5540
  }
5508
5541
  }).catch((err) => {
5509
5542
  cleanup();
5510
- reject(new NeoFaceError("Erro ao reproduzir câmera: " + err.message, ErrorType.CAMERA_ERROR));
5543
+ reject(
5544
+ new NeoFaceError(
5545
+ "Erro ao reproduzir câmera: " + err.message,
5546
+ ErrorType.CAMERA_ERROR
5547
+ )
5548
+ );
5511
5549
  });
5512
5550
  } else {
5513
5551
  video.onloadedmetadata = () => setTimeout(tryCapture, CAMERA_READY_DELAY);
@@ -5649,7 +5687,10 @@ async function attemptLogin(applicationToken, overlay, fastMode = false, isRetry
5649
5687
  if (video.parentElement) {
5650
5688
  video.parentElement.removeChild(video);
5651
5689
  }
5652
- throw new NeoFaceError("Rosto não detectado. Posicione seu rosto na frente da câmera.", ErrorType.VALIDATION_ERROR);
5690
+ throw new NeoFaceError(
5691
+ "Rosto não detectado. Posicione seu rosto na frente da câmera.",
5692
+ ErrorType.VALIDATION_ERROR
5693
+ );
5653
5694
  }
5654
5695
  overlay.updateStatus("capturing");
5655
5696
  const canvas = document.createElement("canvas");
@@ -5709,7 +5750,14 @@ async function attemptLogin(applicationToken, overlay, fastMode = false, isRetry
5709
5750
  }
5710
5751
  }
5711
5752
  async function executeBiometricLoginFlow(options) {
5712
- const { applicationToken, onSuccess, onError, onFallbackRequest, onCancel, fastMode = false } = options;
5753
+ const {
5754
+ applicationToken,
5755
+ onSuccess,
5756
+ onError,
5757
+ onFallbackRequest,
5758
+ onCancel,
5759
+ fastMode = false
5760
+ } = options;
5713
5761
  const overlay = new BiometricStatusOverlay();
5714
5762
  const fallbackPrompt = new FallbackPrompt();
5715
5763
  let attempts = 0;
@@ -5778,11 +5826,6 @@ const biometricLoginFlow = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.
5778
5826
  }, Symbol.toStringTag, { value: "Module" }));
5779
5827
  async function startFaceLogin(options) {
5780
5828
  try {
5781
- const isValidToken = await validateToken(options.applicationToken);
5782
- if (!isValidToken) {
5783
- options.onError(new NeoFaceError("Token de aplicação inválido", ErrorType.INVALID_TOKEN));
5784
- return;
5785
- }
5786
5829
  await executeBiometricLoginFlow({
5787
5830
  applicationToken: options.applicationToken,
5788
5831
  onSuccess: options.onSuccess,
@@ -5811,11 +5854,6 @@ async function startFaceLogin(options) {
5811
5854
  }
5812
5855
  async function startHandLogin(options) {
5813
5856
  try {
5814
- const isValidToken = await validateToken(options.applicationToken);
5815
- if (!isValidToken) {
5816
- options.onError(new NeoFaceError("Token de aplicação inválido", ErrorType.INVALID_TOKEN));
5817
- return;
5818
- }
5819
5857
  const captureOptions = {
5820
5858
  mode: "hand",
5821
5859
  onSuccess: async (imageData, _detectedType) => {
@@ -5846,11 +5884,6 @@ async function startHandLogin(options) {
5846
5884
  }
5847
5885
  async function startAutoLogin(options) {
5848
5886
  try {
5849
- const isValidToken = await validateToken(options.applicationToken);
5850
- if (!isValidToken) {
5851
- options.onError(new NeoFaceError("Token de aplicação inválido", ErrorType.INVALID_TOKEN));
5852
- return;
5853
- }
5854
5887
  const captureOptions = {
5855
5888
  mode: "auto",
5856
5889
  onSuccess: async (imageData, _detectedType) => {
@@ -6103,7 +6136,7 @@ const biometricDetection = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.
6103
6136
  initializeBiometricDetection,
6104
6137
  isAdvancedDetectionAvailable
6105
6138
  }, Symbol.toStringTag, { value: "Module" }));
6106
- const VERSION = "1.14.0";
6139
+ const VERSION = "1.15.2";
6107
6140
  const RELEASE_DATE = "2026-03-04";
6108
6141
  class OnboardingCaptureModal {
6109
6142
  constructor(options) {