@autra-io/biometrics-sdk-web
v0.1.0
Published
Web SDK for Autra's hosted biometric selfie capture with liveness proof.
Readme
@autra-io/biometrics-sdk-web
SDK web da Autra para captura biométrica de selfie com prova de vida hospedada. Seu backend cria uma sessão com as credenciais OAuth2 que você já tem; sua aplicação web abre a Hosted Page da Autra através deste SDK e recebe de volta o JWT assinado pela Unico — a prova de que a captura veio de uma selfie legítima com liveness. A Autra nunca vê, verifica ou armazena o dado biométrico.
Sumário
- Recursos
- Requisitos
- Instalação
- Como funciona
- Início rápido
- Referência de API
- Segurança
- Solução de problemas
- Licença
Recursos
- API pública tipada: ESM + CJS +
.d.ts, tree-shakeable (sideEffects: false) - Agnóstico de framework: sem React, sem dependência de runtime
- Modal (iframe) como modo primário de abertura, com um modo redirect para contextos em que a página hospedeira não pode embutir a Hosted Page
- Canal
postMessageendurecido:targetOriginsempre exato, validação deevent.origineevent.source, envelope versionado, terminal guard - API híbrida:
Promisepara o resultado terminal, eventos para os estados intermediários (ready,mode_selected,camera_requested,capture_started,capture_retry,closed) - Taxonomia de erro tipada com 17 códigos (
AutraBiometricsError) - Bundle ESM sempre ≤ 15 KB minificado+gzip (verificado no CI)
Requisitos
- Node.js >= 20 para construir/testar este pacote
- Um navegador moderno (desktop ou mobile) em tempo de execução
- Um backend capaz de chamar
POST /v1/biometrics/sessionscom suas credenciais OAuth2 existentes — este SDK nunca recebe uma credencial da API da Autra
Instalação
npm install @autra-io/biometrics-sdk-webComo funciona
Seu backend Sua app web + SDK Hosted Page da Autra
| | |
|--- sessionToken ------>| |
| |--- open() monta o iframe -->|
| |<---------- ready -----------|
| |<---- camera_requested -------|
| |<---- capture_started --------|
| |<----------- jwt -------------|
|<---------------------- jwt (POST /api/kyc) -----------|O SDK nunca conversa diretamente com a Unico e nunca persiste nada. A imagem da selfie nunca sai da Hosted Page.
Início rápido
Passo 1 — Backend: crie uma sessão
POST /v1/biometrics/sessions
Authorization: Bearer <seu access token OAuth2>
Content-Type: application/json
{ "referenceId": "customer-42", "flow": "selfie", "environment": "production" }A resposta traz sessionId, sessionToken (exibido uma única vez) e
hostedPageUrl. Repasse sessionId, sessionToken e hostedPageUrl para
sua aplicação web — nunca registre sessionToken em log.
Passo 2 — App: abra a captura
import { AutraBiometrics, AutraBiometricsError } from '@autra-io/biometrics-sdk-web';
const biometrics = AutraBiometrics.create({
environment: 'production', // ou "sandbox"
locale: 'pt-BR', // opcional
debug: false, // opcional — nunca loga sessionToken nem jwt
});
const session = biometrics.createSession({
sessionId,
sessionToken, // veio do SEU backend, nunca um segredo gerado por você
hostedPageUrl,
preferredMode: 'auto', // "auto" | "modal" | "redirect"
timeoutMs: 300_000,
});
session.on('ready', () => {});
session.on('mode_selected', ({ mode }) => {});
session.on('camera_requested', () => {});
session.on('capture_started', ({ attempt }) => {});
session.on('capture_retry', ({ attempt, code }) => {});
try {
const result = await session.open();
// { sessionId, jwt, attempts, capturedAt }
await fetch('/api/kyc', { method: 'POST', body: JSON.stringify({ jwt: result.jwt }) });
} catch (err) {
if (err instanceof AutraBiometricsError && err.code === 'cancelled_by_user') return;
showError(err instanceof AutraBiometricsError ? err.code : 'unknown_error');
} finally {
session.destroy();
}Referência de API
AutraBiometrics.create(options)
| Opção | Tipo | Obrigatório | Notas |
| ------------- | --------------------------- | ----------- | ------------------------------------------------------------ |
| environment | "production" \| "sandbox" | sim | |
| locale | string | não | |
| debug | boolean | não | Loga apenas transições de estado, nunca sessionToken/jwt |
Não faz nenhuma chamada de rede.
biometrics.createSession(options)
| Opção | Tipo | Obrigatório | Notas |
| --------------- | ------------------------------------------ | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| sessionId | string | sim | Vindo do seu backend |
| sessionToken | string | sim | Vindo do seu backend; nunca logado, nunca persistido |
| hostedPageUrl | string | sim | Deve ser HTTPS ou createSession lança erro |
| preferredMode | "auto" \| "modal" \| "redirect" | não | Padrão "auto" |
| returnUrl | string | obrigatório se preferredMode resolver para "redirect" | Deve ser HTTPS |
| timeoutMs | number | não | Teto local de UI; padrão 300000 |
| embedModes | Array<"modal" \| "iframe" \| "redirect"> | não | Vindo do embedModes do seu backend (fail-closed por origem — sem "modal" na lista, o SDK nunca tenta o modal). Omita para tentar todos os modos que a sequência resolvida incluiria. A API ainda devolve "popup" para algumas origens; o SDK aceita na lista e ignora (window.open() é bloqueado por padrão fora de um gesto direto do usuário). |
Não faz nenhuma chamada de rede. Lança um AutraBiometricsError tipado
(código configuration_error) de forma síncrona para entrada inválida.
session.open()
Resolve o modo de abertura, monta a UI e retorna
Promise<AutraBiometricsResult>:
type AutraBiometricsResult = {
sessionId: string;
jwt: string; // trate como credencial — envie ao seu backend imediatamente, nunca persista, nunca logue
attempts: number;
capturedAt: string;
};Chamar open() duas vezes na mesma sessão rejeita a segunda chamada com
invalid_session.
session.close() / session.destroy()
close() fecha a UI ativa; o open() pendente rejeita com
cancelled_by_host. destroy() remove listeners, o iframe/overlay e os
timers — idempotente, seguro para chamar múltiplas vezes.
AutraBiometricsError
class AutraBiometricsError extends Error {
readonly code: AutraBiometricsErrorCode;
readonly sessionId?: string;
readonly retryable: boolean;
}AutraBiometricsErrorCode é um de: configuration_error,
invalid_session, session_expired, session_already_used,
origin_not_allowed, feature_disabled, camera_permission_denied,
camera_unavailable, browser_unsupported, capture_failed,
attempts_exhausted, cancelled_by_user, cancelled_by_host, timeout,
network_error, message_origin_rejected, message_invalid.
AUTRA_BIOMETRICS_SDK_VERSION
A versão publicada do pacote, injetada em tempo de build.
Segurança
Veja SECURITY.md para a política completa. Em resumo:
- O SDK nunca recebe uma credencial da API da Autra — apenas o
sessionTokende vida curta emitido pelo seu backend. hostedPageUrldeve ser HTTPS; o SDK compõe o fragmento#token=…por conta própria — seu backend nunca coloca o token em uma URL que ele possa logar.- Todo
postMessageusa a origem de destino exata, nunca'*', e valida tantoevent.originquantoevent.sourceno recebimento. jwté uma credencial de TTL curto: envie ao seu backend imediatamente, nunca persista, nunca logue.
Solução de problemas
| Sintoma | Causa provável |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------- |
| configuration_error em createSession() | hostedPageUrl/returnUrl não é HTTPS, ou falta um campo obrigatório |
| open() nunca se resolve no modo redirect | Esperado — a aba navega para outra página; trate o resultado na sua returnUrl |
| browser_unsupported | Chamado fora de um navegador (SSR), ou as APIs de DOM que o modo precisa não existem |
| message_origin_rejected no console | Uma mensagem postMessage chegou de uma origem/janela inesperada — nunca da Hosted Page legítima |
