> ## Documentation Index
> Fetch the complete documentation index at: https://docs.campeaosec.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Widget Auth

> SDK JavaScript que gerencia selfie e liveness para autenticação biométrica facial.

## Visão Geral

O Widget Auth é servido pelo mesmo script do KYC (`widget.js`), mas opera em modo de autenticação: **não há captura de documento**. O fluxo é apenas selfie com verificação de liveness, tornando a experiência muito mais rápida (\< 4 segundos em média).

O widget compara a selfie capturada contra o embedding facial armazenado no KYC do `external_id` informado.

***

## Carregar o Script

```html theme={null}
<script src="https://api-kyc.campeaosec.com/widget.js"></script>
```

O mesmo arquivo serve tanto KYC quanto Auth — o modo é determinado pelo tipo de token passado em `init()`.

***

## Inicializar

Após obter o `session_token` do seu servidor (via `POST /v1/auth/session`), inicialize o widget:

```javascript theme={null}
CampeaoSec.init({
  sessionToken: 'token_obtido_do_seu_servidor',
  onSuccess: (result) => {
    // result.authenticated → true se autenticado, false se rejeitado
    // result.auth_id       → UUID do registro de autenticação
    // result.status        → 'authenticated' | 'rejected'
    console.log('Auth concluído', result.authenticated, result.auth_id)
  },
  onCancel: () => {
    console.log('Usuário cancelou')
  },
  onError: (err) => {
    console.error('Erro:', err.code, err.message)
  },
})
```

<Note>
  Não tome decisões de segurança baseado apenas no `onSuccess`. Use o **webhook** como fonte de verdade — ele chega com scores completos e assinatura HMAC verificável.
</Note>

***

## Diferenças em relação ao Widget KYC

| Característica        | KYC                       | Auth 1:1                |
| --------------------- | ------------------------- | ----------------------- |
| Captura de documento  | Sim                       | **Não**                 |
| Selfie + liveness     | Sim                       | **Sim**                 |
| Tempo médio           | 60–90s                    | **\< 4s**               |
| Crédito consumido     | KYC                       | Auth                    |
| Token de sessão       | `POST /v1/verify/session` | `POST /v1/auth/session` |
| Callback de resultado | `result.status`           | `result.authenticated`  |

***

## Opções

| Opção          | Tipo     | Obrigatório | Descrição                                                     |
| -------------- | -------- | ----------- | ------------------------------------------------------------- |
| `sessionToken` | string   | **Sim**     | Token obtido de `POST /v1/auth/session`                       |
| `onSuccess`    | function | **Sim**     | Callback ao concluir (qualquer resultado)                     |
| `onCancel`     | function | **Sim**     | Callback quando usuário fecha o widget                        |
| `onError`      | function | **Sim**     | Callback em erro técnico                                      |
| `locale`       | string   | Não         | Idioma: `'pt'`, `'en'`, `'es'`. Auto-detectado                |
| `containerId`  | string   | Não         | ID de elemento HTML para embed. Se omitido, abre como overlay |
| `apiUrl`       | string   | Não         | URL base da API. Default: `https://api-kyc.campeaosec.com`    |

***

## Fluxo do Widget

```
[Consentimento]
      ↓
[Selfie com liveness]
  • Desafio aleatório: piscar, sorrir, virar, acenar
  • ~3–4 segundos
      ↓
[Processamento]
  • Extração de embedding
  • Comparação com embedding KYC armazenado
      ↓
[onSuccess chamado]
  • authenticated: true / false
```

***

## Callbacks

### `onSuccess(result)`

```javascript theme={null}
onSuccess: (result) => {
  // result.auth_id        → string UUID do registro
  // result.authenticated  → boolean
  // result.status         → 'authenticated' | 'rejected' | 'expired'
  // result.score_liveness → número (0–1) ou null
  // result.score_facial   → número (0–1) ou null
}
```

### `onError({ code, message })`

| `code`           | Causa                                                      |
| ---------------- | ---------------------------------------------------------- |
| `LIVENESS_ERROR` | Falha no desafio de liveness (câmera bloqueada, pouca luz) |
| `NO_EMBEDDING`   | Embedding KYC não encontrado para o usuário                |
| `STATUS_TIMEOUT` | Timeout ao aguardar resultado do servidor                  |
| `WIDGET_ERROR`   | Erro técnico genérico                                      |

***

## Embed em Container

```html theme={null}
<div id="auth-container" style="width: 360px; margin: 0 auto;"></div>

<script>
CampeaoSec.init({
  sessionToken: 'token_aqui',
  containerId: 'auth-container',
  onSuccess: (result) => { /* ... */ },
  onCancel: () => { /* ... */ },
  onError: (err) => { /* ... */ },
})
</script>
```

***

## Fechar Programaticamente

```javascript theme={null}
CampeaoSec.destroy()
```

***

## Exemplo Completo

```html theme={null}
<!DOCTYPE html>
<html>
<head>
  <script src="https://api-kyc.campeaosec.com/widget.js"></script>
</head>
<body>
  <button id="btn-autenticar">Confirmar identidade</button>

  <script>
    document.getElementById('btn-autenticar').addEventListener('click', async () => {
      // 1. Buscar session_token do seu servidor
      const res = await fetch('/api/auth/session', { method: 'POST' })
      const { session_token } = await res.json()

      // 2. Inicializar o widget de autenticação
      CampeaoSec.init({
        sessionToken: session_token,
        locale: 'pt',
        onSuccess: (result) => {
          if (result.authenticated) {
            // Usuário autenticado — prosseguir com a operação sensível
            window.location.href = '/confirmar-transacao'
          } else {
            alert('Autenticação não confirmada. Tente novamente.')
          }
        },
        onCancel: () => {
          console.log('Usuário cancelou a autenticação')
        },
        onError: (err) => {
          console.error('Erro na autenticação:', err.code)
        },
      })
    })
  </script>
</body>
</html>
```

***

## Apps Nativos (React Native / Flutter)

Para apps nativos, use `redirect_uri` ao criar a sessão e abra a `widget_url` retornada em um WebView ou browser externo. O app é retomado via deep link após a autenticação.

```javascript theme={null}
// Criar sessão no seu servidor com redirect_uri
const { widget_url } = await criarSessaoAuth({
  external_id: userId,
  redirect_uri: 'meuapp://auth-complete',
})

// Abrir widget_url no browser do dispositivo
Linking.openURL(widget_url)

// Capturar retorno via deep link
// meuapp://auth-complete?auth_id=abc123&status=authenticated
```
