@neofaceid/web-sdk 1.27.0 → 1.28.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.
@@ -6101,7 +6101,12 @@ const keyframes = `
6101
6101
  100% { transform: translate(-50%, -50%) rotate(360deg); }
6102
6102
  }
6103
6103
  `;
6104
- function FaceCaptureModal({ accessToken, onClose, onSuccess }) {
6104
+ function FaceCaptureModal({
6105
+ accessToken,
6106
+ onClose,
6107
+ onSuccess,
6108
+ onCannotGesture
6109
+ }) {
6105
6110
  const videoRef = useRef(null);
6106
6111
  const canvasRef = useRef(null);
6107
6112
  const streamRef = useRef(null);
@@ -6246,8 +6251,39 @@ function FaceCaptureModal({ accessToken, onClose, onSuccess }) {
6246
6251
  /* @__PURE__ */ jsx("video", { ref: videoRef, style: styles.video, autoPlay: true, playsInline: true, muted: true }),
6247
6252
  /* @__PURE__ */ jsx("canvas", { ref: canvasRef, style: styles.canvas }),
6248
6253
  /* @__PURE__ */ jsx("div", { style: styles.guide }),
6249
- state.status === "ready" && !faceDetected && /* @__PURE__ */ jsx("div", { style: styles.message, children: "Centralize seu rosto no círculo" }),
6250
- state.status === "capturing" && /* @__PURE__ */ jsx("div", { style: styles.message, children: "Por favor, pisque os olhos" }),
6254
+ state.status === "ready" && !faceDetected && /* @__PURE__ */ jsx("div", { style: styles.message, "aria-live": "assertive", children: "Centralize seu rosto no círculo" }),
6255
+ state.status === "capturing" && /* @__PURE__ */ jsx("div", { style: styles.message, "aria-live": "assertive", children: "Por favor, pisque os olhos" }),
6256
+ (state.status === "ready" || state.status === "capturing") && /* @__PURE__ */ jsx(
6257
+ "button",
6258
+ {
6259
+ type: "button",
6260
+ className: "neofaceid-face-cannot-gesture",
6261
+ onClick: () => {
6262
+ if (onCannotGesture) onCannotGesture();
6263
+ else onClose();
6264
+ },
6265
+ "aria-label": "Não consigo fazer esse movimento — buscar alternativa",
6266
+ style: {
6267
+ position: "absolute",
6268
+ bottom: 100,
6269
+ left: "50%",
6270
+ transform: "translateX(-50%)",
6271
+ minHeight: 44,
6272
+ minWidth: 44,
6273
+ padding: "10px 20px",
6274
+ background: "transparent",
6275
+ border: "1px solid rgba(255, 255, 255, 0.32)",
6276
+ borderRadius: 22,
6277
+ color: "rgba(255, 255, 255, 0.9)",
6278
+ fontSize: 14,
6279
+ fontWeight: 500,
6280
+ fontFamily: "inherit",
6281
+ cursor: "pointer",
6282
+ zIndex: 10
6283
+ },
6284
+ children: "Não consigo fazer esse movimento"
6285
+ }
6286
+ ),
6251
6287
  state.status === "uploading" && /* @__PURE__ */ jsx("div", { style: styles.spinner }),
6252
6288
  state.status === "success" && /* @__PURE__ */ jsx("div", { style: styles.message, children: "Autenticado!" }),
6253
6289
  state.status === "error" && /* @__PURE__ */ jsx("div", { style: styles.message, children: state.message }),
@@ -6694,7 +6730,8 @@ function BiometricRegistrationModal({
6694
6730
  onClose,
6695
6731
  onSuccess,
6696
6732
  onPhotosCaptured,
6697
- onError
6733
+ onError,
6734
+ onCannotGesture
6698
6735
  }) {
6699
6736
  const videoRef = useRef(null);
6700
6737
  const canvasRef = useRef(null);
@@ -7236,9 +7273,22 @@ function BiometricRegistrationModal({
7236
7273
  }
7237
7274
  ) }),
7238
7275
  /* @__PURE__ */ jsxs("div", { className: "instruction-box", children: [
7239
- /* @__PURE__ */ jsx("p", { className: "instruction-text", children: livenessInstructions[state.step] }),
7276
+ /* @__PURE__ */ jsx("p", { className: "instruction-text", "aria-live": "assertive", children: livenessInstructions[state.step] }),
7240
7277
  stepProgress > 0 && /* @__PURE__ */ jsx("div", { className: "progress-bar", children: /* @__PURE__ */ jsx("div", { className: "progress-fill", style: { width: `${stepProgress}%` } }) })
7241
7278
  ] }),
7279
+ /* @__PURE__ */ jsx(
7280
+ "button",
7281
+ {
7282
+ type: "button",
7283
+ className: "cannot-gesture-button",
7284
+ onClick: () => {
7285
+ if (onCannotGesture) onCannotGesture();
7286
+ else onClose();
7287
+ },
7288
+ "aria-label": "Não consigo fazer esse movimento — buscar alternativa",
7289
+ children: "Não consigo fazer esse movimento"
7290
+ }
7291
+ ),
7242
7292
  /* @__PURE__ */ jsxs("div", { className: "branding-small", children: [
7243
7293
  /* @__PURE__ */ jsx(
7244
7294
  "span",
@@ -7811,6 +7861,31 @@ function BiometricRegistrationModal({
7811
7861
  transition: width 0.05s linear;
7812
7862
  }
7813
7863
 
7864
+ /* NEO-410 · US14.3 — botão "Não consigo fazer esse movimento" */
7865
+ .cannot-gesture-button {
7866
+ margin-top: 16px;
7867
+ min-height: 44px;
7868
+ min-width: 44px;
7869
+ padding: 10px 20px;
7870
+ background: transparent;
7871
+ border: 1px solid rgba(255, 255, 255, 0.28);
7872
+ border-radius: 22px;
7873
+ color: rgba(255, 255, 255, 0.85);
7874
+ font-size: 14px;
7875
+ font-weight: 500;
7876
+ font-family: inherit;
7877
+ cursor: pointer;
7878
+ transition: background 120ms ease-out, border-color 120ms ease-out;
7879
+ }
7880
+ .cannot-gesture-button:hover {
7881
+ background: rgba(255, 255, 255, 0.08);
7882
+ border-color: rgba(255, 255, 255, 0.42);
7883
+ }
7884
+ .cannot-gesture-button:focus-visible {
7885
+ outline: 2px solid #0059C4;
7886
+ outline-offset: 2px;
7887
+ }
7888
+
7814
7889
  .branding-small {
7815
7890
  position: absolute;
7816
7891
  bottom: 24px;
@@ -8064,156 +8139,289 @@ function BiometricRegistrationModal({
8064
8139
  /* @__PURE__ */ jsx("canvas", { ref: canvasRef })
8065
8140
  ] });
8066
8141
  }
8142
+ const DEFAULT_PRIVACY_URL = "https://neofaceid.com/privacidade";
8143
+ const DEFAULT_RETENTION_DAYS = 90;
8144
+ const COPY = {
8145
+ verification: {
8146
+ title: "Vamos confirmar que é você",
8147
+ duration: "Leva cerca de 20 segundos e usa a câmera do seu dispositivo.",
8148
+ bullet1Title: "Sua câmera liga agora",
8149
+ bullet1Body: "Você vê a imagem o tempo todo e pode encerrar quando quiser.",
8150
+ bullet2Title: "Pediremos dois movimentos simples",
8151
+ bullet2Body: "Virar o rosto ou piscar — é assim que sabemos que há alguém ali.",
8152
+ bullet3Title: "A imagem não fica guardada",
8153
+ bullet3Body: "Ela é usada para a verificação e descartada em seguida.",
8154
+ primary: "Começar verificação"
8155
+ },
8156
+ registration: {
8157
+ title: "Vamos cadastrar seu rosto",
8158
+ duration: "Leva cerca de 20 segundos e usa a câmera do seu dispositivo.",
8159
+ bullet1Title: "Sua câmera liga agora",
8160
+ bullet1Body: "Você vê a imagem o tempo todo e pode encerrar quando quiser.",
8161
+ bullet2Title: "Pediremos dois movimentos simples",
8162
+ bullet2Body: "Virar o rosto ou piscar — é assim que sabemos que há alguém ali.",
8163
+ bullet3Title: "Guardamos um vetor matemático do seu rosto",
8164
+ bullet3Body: "Não a foto. A imagem é descartada.",
8165
+ primary: "Começar cadastro"
8166
+ }
8167
+ };
8168
+ const IconCamera = () => /* @__PURE__ */ jsxs(
8169
+ "svg",
8170
+ {
8171
+ width: "24",
8172
+ height: "24",
8173
+ viewBox: "0 0 24 24",
8174
+ fill: "none",
8175
+ stroke: "currentColor",
8176
+ strokeWidth: "1.75",
8177
+ strokeLinecap: "round",
8178
+ strokeLinejoin: "round",
8179
+ "aria-hidden": "true",
8180
+ children: [
8181
+ /* @__PURE__ */ jsx("path", { d: "M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3Z" }),
8182
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "13", r: "4" })
8183
+ ]
8184
+ }
8185
+ );
8186
+ const IconGesture = () => /* @__PURE__ */ jsxs(
8187
+ "svg",
8188
+ {
8189
+ width: "24",
8190
+ height: "24",
8191
+ viewBox: "0 0 24 24",
8192
+ fill: "none",
8193
+ stroke: "currentColor",
8194
+ strokeWidth: "1.75",
8195
+ strokeLinecap: "round",
8196
+ strokeLinejoin: "round",
8197
+ "aria-hidden": "true",
8198
+ children: [
8199
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "9" }),
8200
+ /* @__PURE__ */ jsx("path", { d: "M4 12h16" }),
8201
+ /* @__PURE__ */ jsx("path", { d: "M15 8l4 4-4 4" })
8202
+ ]
8203
+ }
8204
+ );
8205
+ const IconShield = () => /* @__PURE__ */ jsxs(
8206
+ "svg",
8207
+ {
8208
+ width: "24",
8209
+ height: "24",
8210
+ viewBox: "0 0 24 24",
8211
+ fill: "none",
8212
+ stroke: "currentColor",
8213
+ strokeWidth: "1.75",
8214
+ strokeLinecap: "round",
8215
+ strokeLinejoin: "round",
8216
+ "aria-hidden": "true",
8217
+ children: [
8218
+ /* @__PURE__ */ jsx("path", { d: "M12 2 4 5v7c0 5 3.5 8.5 8 10 4.5-1.5 8-5 8-10V5l-8-3Z" }),
8219
+ /* @__PURE__ */ jsx("path", { d: "m9 12 2 2 4-4" })
8220
+ ]
8221
+ }
8222
+ );
8067
8223
  function ConsentModalComponent({
8068
- purpose,
8069
- legalBasis,
8070
- privacyPolicyUrl,
8071
- retentionDays,
8224
+ appName,
8225
+ flow,
8226
+ privacyPolicyUrl = DEFAULT_PRIVACY_URL,
8227
+ retentionDays = DEFAULT_RETENTION_DAYS,
8072
8228
  onAccept,
8073
8229
  onDecline
8074
8230
  }) {
8231
+ const copy = COPY[flow];
8075
8232
  return /* @__PURE__ */ jsxs(Fragment, { children: [
8076
8233
  /* @__PURE__ */ jsx("style", { children: `
8077
- @keyframes neofaceidConsentFadeIn {
8078
- from { opacity: 0; }
8079
- to { opacity: 1; }
8080
- }
8081
-
8234
+ @keyframes neofaceidConsentFadeIn { from { opacity: 0 } to { opacity: 1 } }
8082
8235
  @keyframes neofaceidConsentSlideUp {
8083
- from {
8084
- opacity: 0;
8085
- transform: translateY(20px);
8086
- }
8087
- to {
8088
- opacity: 1;
8089
- transform: translateY(0);
8090
- }
8236
+ from { opacity: 0; transform: translateY(12px) }
8237
+ to { opacity: 1; transform: translateY(0) }
8091
8238
  }
8092
-
8093
8239
  .neofaceid-consent-overlay {
8094
- position: fixed;
8095
- inset: 0;
8096
- background: rgba(0, 0, 0, 0.6);
8097
- backdrop-filter: blur(8px);
8098
- display: flex;
8099
- align-items: center;
8100
- justify-content: center;
8101
- z-index: 10001;
8102
- padding: 20px;
8103
- animation: neofaceidConsentFadeIn 0.3s ease-out;
8104
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
8240
+ position: fixed; inset: 0;
8241
+ background: rgba(10, 19, 32, 0.55);
8242
+ backdrop-filter: blur(3px);
8243
+ -webkit-backdrop-filter: blur(3px);
8244
+ display: flex; align-items: center; justify-content: center;
8245
+ z-index: 10001; padding: 20px;
8246
+ animation: neofaceidConsentFadeIn 200ms ease-out;
8247
+ font-family: inherit;
8248
+ color: #0A1320;
8105
8249
  }
8106
-
8107
8250
  .neofaceid-consent-modal {
8108
- background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
8109
- border-radius: 20px;
8110
- padding: 32px;
8111
- max-width: 420px;
8251
+ background: #FFFFFF;
8252
+ border-radius: 16px;
8253
+ padding: 28px;
8254
+ max-width: 440px;
8112
8255
  width: 100%;
8113
- box-shadow: 0 24px 48px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.1);
8114
- animation: neofaceidConsentSlideUp 0.4s ease-out;
8256
+ box-shadow: 0 1px 3px rgba(10, 19, 32, 0.08);
8257
+ animation: neofaceidConsentSlideUp 320ms cubic-bezier(.2,0,0,1);
8258
+ box-sizing: border-box;
8259
+ }
8260
+ .neofaceid-consent-header {
8261
+ display: flex;
8262
+ align-items: baseline;
8263
+ gap: 10px;
8264
+ margin-bottom: 20px;
8265
+ }
8266
+ .neofaceid-consent-appname {
8267
+ font-size: 17px;
8268
+ font-weight: 700;
8269
+ color: #0A1320;
8270
+ line-height: 1.2;
8271
+ }
8272
+ .neofaceid-consent-brand-caption {
8273
+ font-size: 11px;
8274
+ font-weight: 700;
8275
+ letter-spacing: 0.09em;
8276
+ text-transform: uppercase;
8277
+ color: #617489;
8115
8278
  }
8116
-
8117
8279
  .neofaceid-consent-title {
8118
- font-size: 20px;
8280
+ font-size: 22px;
8119
8281
  font-weight: 700;
8120
- color: white;
8121
- margin: 0 0 12px 0;
8282
+ color: #0A1320;
8283
+ margin: 0 0 8px;
8284
+ line-height: 1.25;
8285
+ letter-spacing: -0.015em;
8122
8286
  }
8123
-
8124
- .neofaceid-consent-message {
8287
+ .neofaceid-consent-duration {
8125
8288
  font-size: 14px;
8126
- color: rgba(255, 255, 255, 0.7);
8127
- margin: 0 0 16px 0;
8289
+ color: #48586B;
8290
+ margin: 0 0 20px;
8128
8291
  line-height: 1.5;
8129
8292
  }
8130
-
8293
+ .neofaceid-consent-bullets {
8294
+ display: flex;
8295
+ flex-direction: column;
8296
+ gap: 14px;
8297
+ margin-bottom: 20px;
8298
+ }
8299
+ .neofaceid-consent-bullet {
8300
+ display: flex;
8301
+ gap: 12px;
8302
+ align-items: flex-start;
8303
+ }
8304
+ .neofaceid-consent-bullet-icon {
8305
+ flex-shrink: 0;
8306
+ color: #0059C4;
8307
+ margin-top: 2px;
8308
+ }
8309
+ .neofaceid-consent-bullet-title {
8310
+ font-size: 14px;
8311
+ font-weight: 600;
8312
+ color: #0A1320;
8313
+ margin: 0 0 2px;
8314
+ line-height: 1.35;
8315
+ }
8316
+ .neofaceid-consent-bullet-body {
8317
+ font-size: 13px;
8318
+ color: #48586B;
8319
+ margin: 0;
8320
+ line-height: 1.45;
8321
+ }
8131
8322
  .neofaceid-consent-link {
8132
8323
  display: inline-block;
8133
- font-size: 14px;
8134
- color: #a78bfa;
8324
+ font-size: 13px;
8325
+ color: #0059C4;
8135
8326
  text-decoration: underline;
8136
- margin-bottom: 24px;
8137
- }
8138
-
8139
- .neofaceid-consent-link:hover {
8140
- color: #c4b5fd;
8327
+ margin-bottom: 20px;
8141
8328
  }
8142
-
8329
+ .neofaceid-consent-link:hover { color: #00449A; }
8143
8330
  .neofaceid-consent-actions {
8144
8331
  display: flex;
8145
8332
  flex-direction: column;
8146
- gap: 12px;
8333
+ gap: 10px;
8147
8334
  }
8148
-
8149
8335
  .neofaceid-consent-button {
8150
- padding: 14px 24px;
8151
- border-radius: 12px;
8336
+ min-height: 44px;
8337
+ padding: 12px 20px;
8338
+ border-radius: 16px;
8152
8339
  border: none;
8153
- font-size: 16px;
8340
+ font-size: 15px;
8154
8341
  font-weight: 600;
8155
8342
  cursor: pointer;
8156
- transition: all 0.2s;
8343
+ transition: background 120ms ease-out, transform 120ms ease-out;
8157
8344
  font-family: inherit;
8158
8345
  }
8159
-
8160
8346
  .neofaceid-consent-button-primary {
8161
- background: linear-gradient(135deg, #7c3aed 0%, #6d28d9 100%);
8162
- color: white;
8163
- box-shadow: 0 4px 16px rgba(124, 58, 237, 0.3);
8347
+ background: #0059C4;
8348
+ color: #FFFFFF;
8164
8349
  }
8165
-
8166
- .neofaceid-consent-button-primary:hover {
8167
- transform: translateY(-2px);
8168
- box-shadow: 0 8px 24px rgba(124, 58, 237, 0.4);
8350
+ .neofaceid-consent-button-primary:hover { background: #00449A; }
8351
+ .neofaceid-consent-button-primary:focus-visible {
8352
+ outline: 2px solid #0059C4;
8353
+ outline-offset: 2px;
8169
8354
  }
8170
-
8171
- .neofaceid-consent-button-primary:active {
8172
- transform: translateY(0);
8355
+ .neofaceid-consent-button-ghost {
8356
+ background: transparent;
8357
+ color: #334255;
8173
8358
  }
8174
-
8175
- .neofaceid-consent-button-secondary {
8176
- background: rgba(255, 255, 255, 0.1);
8177
- color: white;
8178
- border: 1px solid rgba(255, 255, 255, 0.2);
8359
+ .neofaceid-consent-button-ghost:hover { background: #F1F5FA; }
8360
+ .neofaceid-consent-footer {
8361
+ display: flex;
8362
+ justify-content: center;
8363
+ margin-top: 20px;
8364
+ padding-top: 16px;
8365
+ border-top: 1px solid #E6ECF4;
8179
8366
  }
8180
-
8181
- .neofaceid-consent-button-secondary:hover {
8182
- background: rgba(255, 255, 255, 0.15);
8183
- border-color: rgba(255, 255, 255, 0.3);
8367
+ .neofaceid-consent-seal {
8368
+ font-size: 11px;
8369
+ font-weight: 700;
8370
+ letter-spacing: 0.09em;
8371
+ text-transform: uppercase;
8372
+ color: #617489;
8184
8373
  }
8185
-
8186
8374
  @media (max-width: 640px) {
8187
- .neofaceid-consent-modal {
8188
- padding: 24px;
8189
- border-radius: 16px;
8190
- }
8191
-
8192
- .neofaceid-consent-title {
8193
- font-size: 18px;
8194
- }
8375
+ .neofaceid-consent-modal { padding: 22px; border-radius: 16px; }
8376
+ .neofaceid-consent-title { font-size: 20px; }
8377
+ }
8378
+ @media (prefers-reduced-motion: reduce) {
8379
+ .neofaceid-consent-overlay,
8380
+ .neofaceid-consent-modal { animation: none; }
8195
8381
  }
8196
8382
  ` }),
8197
- /* @__PURE__ */ jsx("div", { className: "neofaceid-consent-overlay", children: /* @__PURE__ */ jsxs("div", { className: "neofaceid-consent-modal", children: [
8198
- /* @__PURE__ */ jsxs("h3", { className: "neofaceid-consent-title", children: [
8199
- "Uso do seu rosto para ",
8200
- purpose
8383
+ /* @__PURE__ */ jsx("div", { className: "neofaceid-consent-overlay", role: "dialog", "aria-modal": "true", "aria-labelledby": "neofaceid-consent-title", children: /* @__PURE__ */ jsxs("div", { className: "neofaceid-consent-modal", children: [
8384
+ /* @__PURE__ */ jsxs("div", { className: "neofaceid-consent-header", children: [
8385
+ /* @__PURE__ */ jsx("span", { className: "neofaceid-consent-appname", children: appName }),
8386
+ /* @__PURE__ */ jsx("span", { className: "neofaceid-consent-brand-caption", children: "NeoFaceID" })
8201
8387
  ] }),
8202
- /* @__PURE__ */ jsxs("p", { className: "neofaceid-consent-message", children: [
8203
- "Esta captura é realizada com base em ",
8204
- legalBasis,
8205
- ". Os dados biométricos coletados são retidos por até ",
8206
- retentionDays,
8207
- " dias, conforme a finalidade informada."
8388
+ /* @__PURE__ */ jsx("h1", { id: "neofaceid-consent-title", className: "neofaceid-consent-title", children: copy.title }),
8389
+ /* @__PURE__ */ jsx("p", { className: "neofaceid-consent-duration", children: copy.duration }),
8390
+ /* @__PURE__ */ jsxs("div", { className: "neofaceid-consent-bullets", children: [
8391
+ /* @__PURE__ */ jsxs("div", { className: "neofaceid-consent-bullet", children: [
8392
+ /* @__PURE__ */ jsx("div", { className: "neofaceid-consent-bullet-icon", children: /* @__PURE__ */ jsx(IconCamera, {}) }),
8393
+ /* @__PURE__ */ jsxs("div", { children: [
8394
+ /* @__PURE__ */ jsx("p", { className: "neofaceid-consent-bullet-title", children: copy.bullet1Title }),
8395
+ /* @__PURE__ */ jsx("p", { className: "neofaceid-consent-bullet-body", children: copy.bullet1Body })
8396
+ ] })
8397
+ ] }),
8398
+ /* @__PURE__ */ jsxs("div", { className: "neofaceid-consent-bullet", children: [
8399
+ /* @__PURE__ */ jsx("div", { className: "neofaceid-consent-bullet-icon", children: /* @__PURE__ */ jsx(IconGesture, {}) }),
8400
+ /* @__PURE__ */ jsxs("div", { children: [
8401
+ /* @__PURE__ */ jsx("p", { className: "neofaceid-consent-bullet-title", children: copy.bullet2Title }),
8402
+ /* @__PURE__ */ jsx("p", { className: "neofaceid-consent-bullet-body", children: copy.bullet2Body })
8403
+ ] })
8404
+ ] }),
8405
+ /* @__PURE__ */ jsxs("div", { className: "neofaceid-consent-bullet", children: [
8406
+ /* @__PURE__ */ jsx("div", { className: "neofaceid-consent-bullet-icon", children: /* @__PURE__ */ jsx(IconShield, {}) }),
8407
+ /* @__PURE__ */ jsxs("div", { children: [
8408
+ /* @__PURE__ */ jsx("p", { className: "neofaceid-consent-bullet-title", children: copy.bullet3Title }),
8409
+ /* @__PURE__ */ jsx("p", { className: "neofaceid-consent-bullet-body", children: copy.bullet3Body })
8410
+ ] })
8411
+ ] })
8208
8412
  ] }),
8209
- /* @__PURE__ */ jsx(
8413
+ /* @__PURE__ */ jsxs(
8210
8414
  "a",
8211
8415
  {
8212
8416
  href: privacyPolicyUrl,
8213
8417
  target: "_blank",
8214
8418
  rel: "noopener noreferrer",
8215
8419
  className: "neofaceid-consent-link",
8216
- children: "Ver política de privacidade"
8420
+ children: [
8421
+ "Ver política de privacidade (retenção de até ",
8422
+ retentionDays,
8423
+ " dias)"
8424
+ ]
8217
8425
  }
8218
8426
  ),
8219
8427
  /* @__PURE__ */ jsxs("div", { className: "neofaceid-consent-actions", children: [
@@ -8223,19 +8431,20 @@ function ConsentModalComponent({
8223
8431
  type: "button",
8224
8432
  className: "neofaceid-consent-button neofaceid-consent-button-primary",
8225
8433
  onClick: onAccept,
8226
- children: "Aceito e continuar"
8434
+ children: copy.primary
8227
8435
  }
8228
8436
  ),
8229
8437
  /* @__PURE__ */ jsx(
8230
8438
  "button",
8231
8439
  {
8232
8440
  type: "button",
8233
- className: "neofaceid-consent-button neofaceid-consent-button-secondary",
8441
+ className: "neofaceid-consent-button neofaceid-consent-button-ghost",
8234
8442
  onClick: onDecline,
8235
- children: "Recusar"
8443
+ children: "Agora não"
8236
8444
  }
8237
8445
  )
8238
- ] })
8446
+ ] }),
8447
+ /* @__PURE__ */ jsx("div", { className: "neofaceid-consent-footer", children: /* @__PURE__ */ jsx("span", { className: "neofaceid-consent-seal", children: "Protegido por NeoFaceID" }) })
8239
8448
  ] }) })
8240
8449
  ] });
8241
8450
  }
@@ -8245,9 +8454,7 @@ class ConsentModal {
8245
8454
  __publicField(this, "root", null);
8246
8455
  }
8247
8456
  show(props) {
8248
- if (this.container) {
8249
- return;
8250
- }
8457
+ if (this.container) return;
8251
8458
  this.container = document.createElement("div");
8252
8459
  this.container.id = "neofaceid-consent-modal-container";
8253
8460
  document.body.appendChild(this.container);
@@ -8271,32 +8478,39 @@ class ConsentModal {
8271
8478
  }
8272
8479
  close() {
8273
8480
  if (this.container && document.body.contains(this.container)) {
8274
- if (this.root) {
8275
- this.root.unmount();
8276
- }
8481
+ if (this.root) this.root.unmount();
8277
8482
  document.body.removeChild(this.container);
8278
8483
  this.container = null;
8279
8484
  this.root = null;
8280
8485
  }
8281
8486
  }
8282
8487
  }
8283
- const DEFAULT_CONSENT_INFO = {
8284
- purpose: "autenticação facial",
8285
- legalBasis: "seu consentimento explícito (Art. 7º, I da LGPD)",
8286
- privacyPolicyUrl: "https://neofaceid.com/privacidade",
8287
- retentionDays: 90
8288
- };
8488
+ const DEFAULT_APP_NAME = "sua aplicação";
8289
8489
  function requestConsent(info = {}) {
8490
+ const appName = info.appName ?? DEFAULT_APP_NAME;
8491
+ if (!info.appName) {
8492
+ console.warn(
8493
+ '[NeoFaceID SDK] requestConsent chamado sem appName — usando fallback "sua aplicação". Passe o nome do integrador via NeoFaceSDK.init({ appName }).'
8494
+ );
8495
+ }
8496
+ const flow = info.flow ?? "verification";
8290
8497
  return new Promise((resolve) => {
8291
8498
  const modal = new ConsentModal();
8292
8499
  modal.show({
8293
- ...DEFAULT_CONSENT_INFO,
8294
- ...info,
8500
+ appName,
8501
+ flow,
8502
+ privacyPolicyUrl: info.privacyPolicyUrl ?? DEFAULT_PRIVACY_URL,
8503
+ retentionDays: info.retentionDays ?? DEFAULT_RETENTION_DAYS,
8295
8504
  onAccept: () => resolve(true),
8296
8505
  onDecline: () => resolve(false)
8297
8506
  });
8298
8507
  });
8299
8508
  }
8509
+ const DEFAULT_CONSENT_INFO = {
8510
+ flow: "verification",
8511
+ privacyPolicyUrl: DEFAULT_PRIVACY_URL,
8512
+ retentionDays: DEFAULT_RETENTION_DAYS
8513
+ };
8300
8514
  class BiometricCaptureModal {
8301
8515
  constructor(options) {
8302
8516
  __publicField(this, "modal", null);
@@ -10088,7 +10302,10 @@ const biometricLoginFlow = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.
10088
10302
  }, Symbol.toStringTag, { value: "Module" }));
10089
10303
  const CONSENT_DENIED_MESSAGE$1 = "Consentimento recusado pelo usuário.";
10090
10304
  async function startFaceLogin(options) {
10091
- const consentAccepted = await requestConsent();
10305
+ const consentAccepted = await requestConsent({
10306
+ appName: options.appName,
10307
+ flow: "verification"
10308
+ });
10092
10309
  if (!consentAccepted) {
10093
10310
  options.onError(new NeoFaceError(CONSENT_DENIED_MESSAGE$1, ErrorType.CONSENT_DENIED));
10094
10311
  return;
@@ -10121,7 +10338,10 @@ async function startFaceLogin(options) {
10121
10338
  }
10122
10339
  }
10123
10340
  async function startHandLogin(options) {
10124
- const consentAccepted = await requestConsent();
10341
+ const consentAccepted = await requestConsent({
10342
+ appName: options.appName,
10343
+ flow: "verification"
10344
+ });
10125
10345
  if (!consentAccepted) {
10126
10346
  options.onError(new NeoFaceError(CONSENT_DENIED_MESSAGE$1, ErrorType.CONSENT_DENIED));
10127
10347
  return;
@@ -10156,7 +10376,10 @@ async function startHandLogin(options) {
10156
10376
  }
10157
10377
  }
10158
10378
  async function startAutoLogin(options) {
10159
- const consentAccepted = await requestConsent();
10379
+ const consentAccepted = await requestConsent({
10380
+ appName: options.appName,
10381
+ flow: "verification"
10382
+ });
10160
10383
  if (!consentAccepted) {
10161
10384
  options.onError(new NeoFaceError(CONSENT_DENIED_MESSAGE$1, ErrorType.CONSENT_DENIED));
10162
10385
  return;
@@ -10417,7 +10640,7 @@ const biometricDetection = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.
10417
10640
  initializeBiometricDetection,
10418
10641
  isAdvancedDetectionAvailable
10419
10642
  }, Symbol.toStringTag, { value: "Module" }));
10420
- const VERSION = "1.27.0";
10643
+ const VERSION = "1.28.1";
10421
10644
  const RELEASE_DATE = "2026-09-01";
10422
10645
  let cachedSession = null;
10423
10646
  function getCachedCaptureSession() {
@@ -10882,7 +11105,10 @@ class OnboardingCaptureModal {
10882
11105
  const startOnboarding = async (options) => {
10883
11106
  const { applicationToken, onboardingToken, countdown, title, subtitle, onSuccess, onError } = options;
10884
11107
  try {
10885
- const consentAccepted = await requestConsent();
11108
+ const consentAccepted = await requestConsent({
11109
+ appName: options.appName,
11110
+ flow: "registration"
11111
+ });
10886
11112
  if (!consentAccepted) {
10887
11113
  onError(new NeoFaceError("Consentimento recusado pelo usuário.", ErrorType.CONSENT_DENIED));
10888
11114
  return;
@@ -11261,7 +11487,10 @@ const authorizeOperation = async (applicationToken, cpf, options) => {
11261
11487
  }
11262
11488
  const capturedPhotos = [];
11263
11489
  const captureDelay = (options == null ? void 0 : options.captureDelay) || 2e3;
11264
- const consentAccepted = await requestConsent();
11490
+ const consentAccepted = await requestConsent({
11491
+ appName: options == null ? void 0 : options.appName,
11492
+ flow: "verification"
11493
+ });
11265
11494
  if (!consentAccepted) {
11266
11495
  throw new NeoFaceError("Consentimento recusado pelo usuário.", ErrorType.CONSENT_DENIED);
11267
11496
  }
@@ -11408,6 +11637,18 @@ class DocumentCaptureModal {
11408
11637
  };
11409
11638
  }
11410
11639
  async open() {
11640
+ if (!this.options.skipConsent) {
11641
+ const consentAccepted = await requestConsent({
11642
+ appName: this.options.appName,
11643
+ flow: "verification"
11644
+ });
11645
+ if (!consentAccepted) {
11646
+ throw new NeoFaceError(
11647
+ "Consentimento recusado pelo usuário.",
11648
+ ErrorType.CONSENT_DENIED
11649
+ );
11650
+ }
11651
+ }
11411
11652
  return new Promise((resolve) => {
11412
11653
  this.resolvePromise = resolve;
11413
11654
  if (this.options.preSelectedDocument) {
@@ -12370,8 +12611,8 @@ const DocumentCaptureModal$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Obj
12370
12611
  startDocumentCapture
12371
12612
  }, Symbol.toStringTag, { value: "Module" }));
12372
12613
  const CONSENT_DENIED_MESSAGE = "Consentimento recusado pelo usuário.";
12373
- function start(applicationToken, callbacks) {
12374
- requestConsent().then((accepted) => {
12614
+ function start(applicationToken, callbacks, options) {
12615
+ requestConsent({ appName: options == null ? void 0 : options.appName, flow: "verification" }).then((accepted) => {
12375
12616
  if (!accepted) {
12376
12617
  callbacks.onError("CONSENT_DENIED", CONSENT_DENIED_MESSAGE);
12377
12618
  return;
@@ -12395,7 +12636,8 @@ function start(applicationToken, callbacks) {
12395
12636
  email: result.data.faceId,
12396
12637
  documentId: result.data.faceId
12397
12638
  });
12398
- }
12639
+ },
12640
+ onCannotGesture: options == null ? void 0 : options.onCannotGesture
12399
12641
  });
12400
12642
  const root = createRoot(container);
12401
12643
  root.render(modalElement);
@@ -12406,7 +12648,7 @@ function start(applicationToken, callbacks) {
12406
12648
  });
12407
12649
  }
12408
12650
  function startBiometricRegistration(personData, applicationToken, callbacks, options) {
12409
- requestConsent().then((accepted) => {
12651
+ requestConsent({ appName: options == null ? void 0 : options.appName, flow: "registration" }).then((accepted) => {
12410
12652
  if (!accepted) {
12411
12653
  callbacks.onError("CONSENT_DENIED", CONSENT_DENIED_MESSAGE);
12412
12654
  return;
@@ -12437,7 +12679,8 @@ function startBiometricRegistration(personData, applicationToken, callbacks, opt
12437
12679
  onError: (error) => {
12438
12680
  cleanup();
12439
12681
  callbacks.onError("BIOMETRIC_REGISTRATION_ERROR", error);
12440
- }
12682
+ },
12683
+ onCannotGesture: options == null ? void 0 : options.onCannotGesture
12441
12684
  });
12442
12685
  rootRef = createRoot(container);
12443
12686
  rootRef.render(modalElement);
@@ -12447,8 +12690,8 @@ function startBiometricRegistration(personData, applicationToken, callbacks, opt
12447
12690
  });
12448
12691
  });
12449
12692
  }
12450
- function startLivenessCapture(applicationToken, callbacks) {
12451
- requestConsent().then((accepted) => {
12693
+ function startLivenessCapture(applicationToken, callbacks, options) {
12694
+ requestConsent({ appName: options == null ? void 0 : options.appName, flow: "verification" }).then((accepted) => {
12452
12695
  if (!accepted) {
12453
12696
  callbacks.onError("CONSENT_DENIED", CONSENT_DENIED_MESSAGE);
12454
12697
  return;
@@ -12484,7 +12727,8 @@ function startLivenessCapture(applicationToken, callbacks) {
12484
12727
  onError: (error) => {
12485
12728
  cleanup();
12486
12729
  callbacks.onError("LIVENESS_CAPTURE_ERROR", error);
12487
- }
12730
+ },
12731
+ onCannotGesture: options == null ? void 0 : options.onCannotGesture
12488
12732
  });
12489
12733
  rootRef = createRoot(container);
12490
12734
  rootRef.render(modalElement);