@neofaceid/web-sdk 1.41.1 → 1.42.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.
package/dist/index.d.ts CHANGED
@@ -30,6 +30,20 @@ export declare interface ApplicationRegistrationResult {
30
30
  message: string;
31
31
  }
32
32
 
33
+ export declare type AuthMethod = z.infer<typeof AuthMethodSchema>;
34
+
35
+ /**
36
+ * Por qual caminho a pessoa se autenticou.
37
+ *
38
+ * O console trata `password` como caminho degradado — entra, mas não executa
39
+ * operação de risco alto. Sem este campo o host não tem como distinguir, já que
40
+ * o resultado dos dois caminhos tem exatamente a mesma forma.
41
+ */
42
+ declare const AuthMethodSchema: z.ZodEnum<{
43
+ face: "face";
44
+ password: "password";
45
+ }>;
46
+
33
47
  export declare interface AuthorizationOptions {
34
48
  onProgress?: (step: number, totalSteps: number, instruction: string) => void;
35
49
  onPhotoTaken?: (photoNumber: number, blob: Blob) => void;
@@ -107,6 +121,76 @@ export declare interface AuthorizeOptions {
107
121
  autoLighting?: boolean;
108
122
  }
109
123
 
124
+ /** Ver {@link SDKInitOptions.autoFallback}. */
125
+ export declare interface AutoFallbackOptions {
126
+ /**
127
+ * Nível 1 — oferecer confirmação no celular quando o dispositivo atual não
128
+ * dá conta (sem câmera, permissão negada) ou quando o purpose exige.
129
+ *
130
+ * Default `false`. Quem decide se há aparelho é o core, na resposta: o SDK
131
+ * não consegue (e não deve) descobrir isso sozinho — um endpoint que
132
+ * respondesse "esta pessoa tem aparelho?" autenticado por `X-App-Token`,
133
+ * que é público por desenho, seria um oráculo de enumeração.
134
+ */
135
+ toPhone?: boolean;
136
+ /**
137
+ * Nível 2 — abrir o modal de e-mail e senha.
138
+ *
139
+ * Default `true`, que é o comportamento histórico de `startFaceLogin`
140
+ * quando `onFallbackRequest` não é passado. Mudá-lo para `false` por padrão
141
+ * quebraria todo integrador publicado, então a mudança fica explícita.
142
+ */
143
+ toPassword?: boolean;
144
+ }
145
+
146
+ /**
147
+ * Abre a tela "Confirme no seu celular" e aguarda a decisão pelo SSE do core.
148
+ *
149
+ * Este primitivo é avulso de propósito. Desde a NEO-427 o `authorize()` só
150
+ * **coleta** — quem submete ao core é o host, então é o host que recebe a
151
+ * resposta "exige confirmação no celular" e chama esta função com o
152
+ * `requestId` que veio de lá.
153
+ *
154
+ * O SDK nunca fala com a plataforma Push: o canal é sempre o core.
155
+ *
156
+ * @example
157
+ * ```ts
158
+ * const r = await meuBackend.submeter(frames);
159
+ * if (r.requires_push) {
160
+ * const outcome = await awaitPushApproval({
161
+ * requestId: r.request_id,
162
+ * applicationToken: TOKEN,
163
+ * expiresIn: r.expires_in,
164
+ * numericCode: r.numeric_code,
165
+ * });
166
+ * if (outcome.status === 'approved') continuar();
167
+ * else if (outcome.status === 'expired') caiParaSenha();
168
+ * // 'denied' é terminal — não oferece caminho alternativo.
169
+ * }
170
+ * ```
171
+ */
172
+ export declare function awaitPushApproval(options: AwaitPushApprovalOptions): Promise<PushApprovalOutcome>;
173
+
174
+ export declare interface AwaitPushApprovalOptions {
175
+ /**
176
+ * Identificador da solicitação, devolvido pelo core na resposta que exigiu
177
+ * confirmação no celular.
178
+ */
179
+ requestId: string;
180
+ applicationToken: string;
181
+ /** Prazo informado pelo core, em segundos. */
182
+ expiresIn: number;
183
+ /**
184
+ * Código de correspondência numérica de 2 dígitos, quando a política exigir.
185
+ * O SDK apenas **exibe**; conferir é papel do celular contra o servidor.
186
+ */
187
+ numericCode?: string;
188
+ /** Nome do integrador (fallback: `init({ appName })`). */
189
+ appName?: string;
190
+ /** Oferece "entrar de outro jeito" na tela de expiração. */
191
+ onFallback?: () => void;
192
+ }
193
+
110
194
  export declare class BiometricCaptureModal {
111
195
  private modal;
112
196
  private video;
@@ -202,6 +286,11 @@ export declare type BiometricLoginResult = z.infer<typeof BiometricLoginResultSc
202
286
  declare const BiometricLoginResultSchema: z.ZodObject<{
203
287
  success: z.ZodBoolean;
204
288
  accessToken: z.ZodOptional<z.ZodString>;
289
+ refreshToken: z.ZodOptional<z.ZodString>;
290
+ method: z.ZodOptional<z.ZodEnum<{
291
+ face: "face";
292
+ password: "password";
293
+ }>>;
205
294
  alias: z.ZodOptional<z.ZodString>;
206
295
  user: z.ZodOptional<z.ZodObject<{
207
296
  id: z.ZodString;
@@ -280,6 +369,7 @@ declare interface BiometricRegistrationResult_2 {
280
369
  /**
281
370
  * Overlay minimalista estilo FaceID para login biométrico
282
371
  * Implementação vanilla JS (sem React) para evitar conflitos de versão
372
+ * @deprecated Utilize o componente CameraOvalGuide (showCameraOvalGuideModal) para preview de câmera com guia oval.
283
373
  */
284
374
  export declare class BiometricStatusOverlay {
285
375
  private container;
@@ -495,6 +585,43 @@ export declare interface ConsentRecord {
495
585
  sdkVersion: string;
496
586
  }
497
587
 
588
+ export declare interface ConsumeSseOptions<T> {
589
+ /**
590
+ * Pede um ticket ao core. Chamado na abertura **e a cada reconexão** — o
591
+ * ticket é de uso único e expira em 60 s (`core/sse_access.py`), então
592
+ * reconectar com o mesmo valor sempre falharia na autenticação.
593
+ */
594
+ requestTicket: () => Promise<string>;
595
+ /** Monta a URL do EventSource a partir de um ticket recém-emitido. */
596
+ buildUrl: (ticket: string) => string;
597
+ /** Decide, frame a frame, se o fluxo terminou. */
598
+ classify: (frame: SseFrame) => SseVerdict<T>;
599
+ /** Teto absoluto do fluxo. Default 310 s (o core faz timeout em 300 s). */
600
+ timeoutMs?: number;
601
+ /** Máximo de reconexões antes de desistir. Default 5. */
602
+ maxReconnects?: number;
603
+ /** Cancela o fluxo de fora (ex.: usuário fechou o modal). */
604
+ signal?: AbortSignal;
605
+ /** Injeção para teste. Default: `globalThis.EventSource`. */
606
+ eventSourceFactory?: (url: string) => EventSource;
607
+ /** Notifica cada frame não-terminal (ex.: atualizar UI). */
608
+ onProgress?: (frame: SseFrame) => void;
609
+ }
610
+
611
+ /**
612
+ * Consome um stream SSE do core até um veredito terminal.
613
+ *
614
+ * Diferenças em relação ao consumidor antigo (`loginWithBiometricSSE`, que era
615
+ * código morto e nunca funcionou):
616
+ *
617
+ * 1. escuta o evento default `message`, que é o que o core de fato emite;
618
+ * 2. reconecta pedindo **ticket novo**, em vez de rejeitar no primeiro soluço
619
+ * de rede — o comentário em `api.ts` prometia isso e o código não fazia;
620
+ * 3. distingue o fechamento normal do servidor (que acontece logo após um
621
+ * status terminal) de uma queda de conexão de verdade.
622
+ */
623
+ export declare function consumeSseStream<T>(options: ConsumeSseOptions<T>): Promise<T>;
624
+
498
625
  /**
499
626
  * Compatibilidade com callers antigos que passavam `{ purpose, legalBasis }`.
500
627
  * Deprecated — remover quando US14.4 unificar tokens.
@@ -518,6 +645,15 @@ export declare interface DetectionResult {
518
645
  details?: any;
519
646
  }
520
647
 
648
+ /** Token de inscrição de aparelho, devolvido por {@link requestDeviceEnrollmentToken}. */
649
+ export declare interface DeviceEnrollmentToken {
650
+ /** JWT RS256 de uso único. Vira o conteúdo do QR. */
651
+ token: string;
652
+ /** Validade em segundos (o core emite 300). */
653
+ expiresIn: number;
654
+ purpose: string;
655
+ }
656
+
521
657
  export declare class DocumentCaptureModal {
522
658
  private overlay;
523
659
  private video;
@@ -731,6 +867,9 @@ export declare function getApplicationToken(): string | null;
731
867
  /** Retorna o nome do integrador configurado, se houver. */
732
868
  export declare function getAppName(): string | null;
733
869
 
870
+ /** Retorna a política de quedas automáticas de canal. Ver {@link AutoFallbackOptions}. */
871
+ export declare function getAutoFallback(): Required<AutoFallbackOptions>;
872
+
734
873
  /**
735
874
  * Retorna a URL base configurada para a API.
736
875
  * Se o SDK não foi inicializado, retorna o fallback para sandbox.
@@ -1227,6 +1366,25 @@ export declare interface ProofOfLifeResult {
1227
1366
  error?: string;
1228
1367
  }
1229
1368
 
1369
+ /**
1370
+ * Desfecho da confirmação no celular.
1371
+ *
1372
+ * `denied` e `expired` são desfechos, não exceções — quem chama precisa
1373
+ * distinguir os dois para dirigir a cascata de fallback: expirar pode cair
1374
+ * para senha, recusar **não pode**.
1375
+ */
1376
+ export declare type PushApprovalOutcome = {
1377
+ status: 'approved';
1378
+ data: Record<string, unknown>;
1379
+ } | {
1380
+ status: 'denied';
1381
+ reason?: string;
1382
+ } | {
1383
+ status: 'expired';
1384
+ } | {
1385
+ status: 'cancelled';
1386
+ };
1387
+
1230
1388
  declare interface RecognitionResult {
1231
1389
  success: boolean;
1232
1390
  data: {
@@ -1310,6 +1468,29 @@ export declare function recordConsent(customConsent?: Partial<{
1310
1468
  legalBasis: string;
1311
1469
  }>): Promise<ConsentRecord | null>;
1312
1470
 
1471
+ /** Par de tokens devolvido por {@link refreshSession}. */
1472
+ export declare interface RefreshedSession {
1473
+ accessToken: string;
1474
+ refreshToken: string;
1475
+ }
1476
+
1477
+ /**
1478
+ * Renova a sessão a partir de um refresh token.
1479
+ *
1480
+ * O core **rotaciona**: o refresh antigo entra na blacklist e um novo é
1481
+ * emitido junto do access. Guarde sempre o par devolvido — reenviar o refresh
1482
+ * anterior passa a dar 401.
1483
+ *
1484
+ * Existe para sessões que duram mais que a validade do access token (o console
1485
+ * administrativo é o caso motivador). Fluxos curtos não precisam chamar.
1486
+ *
1487
+ * @param refreshToken Refresh token vigente, vindo de um login anterior.
1488
+ * @param applicationToken Token da aplicação.
1489
+ * @throws NeoFaceError `INVALID_TOKEN` se o refresh expirou, já foi usado ou
1490
+ * foi revogado — nesse caso o caminho é refazer o login.
1491
+ */
1492
+ export declare const refreshSession: (refreshToken: string, applicationToken: string) => Promise<RefreshedSession>;
1493
+
1313
1494
  /**
1314
1495
  * NEO-101: Register biometric data for an existing person
1315
1496
  *
@@ -1414,7 +1595,7 @@ export declare const registerPersonWithoutFace: (personData: {
1414
1595
  /**
1415
1596
  * Data de lançamento da versão atual
1416
1597
  */
1417
- export declare const RELEASE_DATE = "2026-09-10";
1598
+ export declare const RELEASE_DATE = "2026-09-13";
1418
1599
 
1419
1600
  declare interface RequestChallengeWithSessionParams {
1420
1601
  applicationToken: string;
@@ -1432,6 +1613,21 @@ declare interface RequestChallengeWithSessionParams {
1432
1613
  */
1433
1614
  export declare function requestConsent(info?: ConsentInfo): Promise<boolean>;
1434
1615
 
1616
+ /**
1617
+ * Pede ao core um token de inscrição de aparelho.
1618
+ *
1619
+ * Exige **as duas** credenciais ao mesmo tempo: `X-App-Token` da aplicação e o
1620
+ * Bearer de um usuário DONOR autenticado (permission `IsDonorOfApplicationConsumer`
1621
+ * no core). Por isso a inscrição só existe no autosserviço, com a pessoa logada.
1622
+ *
1623
+ * O valor devolvido **não é segredo de longa duração**: é um JWT de 5 minutos,
1624
+ * de uso único. Não guarde, não reaproveite e não exiba duas vezes.
1625
+ *
1626
+ * @param userAccessToken Access token do DONOR autenticado.
1627
+ * @param applicationToken Token da aplicação.
1628
+ */
1629
+ export declare const requestDeviceEnrollmentToken: (userAccessToken: string, applicationToken: string) => Promise<DeviceEnrollmentToken>;
1630
+
1435
1631
  /**
1436
1632
  * Pede ao servidor a sequência de gestos do desafio de liveness.
1437
1633
  * O SDK apenas exibe e coleta — validação de gesto/yaw/pitch é responsabilidade
@@ -1527,6 +1723,7 @@ declare interface SDKConfig {
1527
1723
  locale: string;
1528
1724
  resolvedTheme: ResolvedTheme | null;
1529
1725
  consent: Consent;
1726
+ autoFallback: Required<AutoFallbackOptions>;
1530
1727
  }
1531
1728
 
1532
1729
  /**
@@ -1583,6 +1780,31 @@ export declare interface SDKInitOptions {
1583
1780
  * e emite `console.warn` uma única vez.
1584
1781
  */
1585
1782
  consent?: Consent;
1783
+ /**
1784
+ * Quedas automáticas de canal, em dois níveis independentes.
1785
+ *
1786
+ * O canal mudar é informação de segurança: cair sozinho esconde do usuário
1787
+ * que a verificação passou a acontecer em outro lugar. Por isso o nível 1
1788
+ * nasce desligado e precisa ser pedido.
1789
+ *
1790
+ * ```
1791
+ * nível 0 rosto no dispositivo atual
1792
+ * ├─ purpose exige push, ou câmera ausente/negada → nível 1
1793
+ * └─ ok → fim
1794
+ *
1795
+ * nível 1 confirmar no celular (toPhone, default false)
1796
+ * ├─ core diz que não há aparelho → nível 2
1797
+ * ├─ prazo expirou → nível 2
1798
+ * └─ RECUSADO no celular → falha terminal, não cascateia
1799
+ *
1800
+ * nível 2 e-mail + senha (toPassword, default true)
1801
+ * ```
1802
+ *
1803
+ * A recusa não cai para senha de propósito: se caísse, quem disparou o
1804
+ * pedido e levou "não" entraria pelo outro caminho, e o controle não valeria
1805
+ * nada. Só expiração e ausência de aparelho cascateiam.
1806
+ */
1807
+ autoFallback?: AutoFallbackOptions;
1586
1808
  }
1587
1809
 
1588
1810
  export declare type SDKRadius = 8 | 16 | 24;
@@ -1618,6 +1840,35 @@ export declare const simpleIdentification: (documentType: string, documentNumber
1618
1840
  };
1619
1841
  }>;
1620
1842
 
1843
+ /**
1844
+ * Frame SSE do core.
1845
+ *
1846
+ * O core emite `data: {json}\n\n` **sem linha `event:`**
1847
+ * (`core/sse_notification_service.py:_format_sse_message`). Pela spec SSE, um
1848
+ * frame sem `event:` é despachado como o tipo default `message` — então
1849
+ * `addEventListener('success', …)` nunca dispara. Quem discrimina é o campo
1850
+ * `status` do payload.
1851
+ */
1852
+ export declare interface SseFrame {
1853
+ task_id?: string;
1854
+ status?: string;
1855
+ timestamp?: number;
1856
+ data?: Record<string, unknown>;
1857
+ message?: string;
1858
+ error?: string;
1859
+ }
1860
+
1861
+ /** Veredito do classificador para cada frame recebido. */
1862
+ export declare type SseVerdict<T> = {
1863
+ kind: 'pending';
1864
+ } | {
1865
+ kind: 'resolve';
1866
+ value: T;
1867
+ } | {
1868
+ kind: 'reject';
1869
+ error: NeoFaceError;
1870
+ };
1871
+
1621
1872
  export declare function start(applicationToken: string, callbacks: Callbacks, options?: {
1622
1873
  appName?: string;
1623
1874
  /** NEO-410 · US14.3 — botão "Não consigo fazer esse movimento" visível desde o 1º desafio. */
@@ -1781,7 +2032,7 @@ export declare const validateToken: (applicationToken: string) => Promise<boolea
1781
2032
  * MINOR: Incrementado quando adicionamos funcionalidades mantendo compatibilidade
1782
2033
  * PATCH: Incrementado quando corrigimos bugs mantendo compatibilidade
1783
2034
  */
1784
- export declare const VERSION = "1.41.1";
2035
+ export declare const VERSION = "1.42.1";
1785
2036
 
1786
2037
  /**
1787
2038
  * Executa `fn(sessionId)`. Se o servidor devolver 410 (sessão consumida/expirada),