Files
cybercore-signer/docs/sdk.md
T

205 lines
6.6 KiB
Markdown

# SDK Web JavaScript (@cybercore/signer-sdk)
> **Manual de Integração de Aplicações Web Modernas com o Agente Desktop CyberCore Signer**
O **`@cybercore/signer-sdk`** é a biblioteca cliente oficial em JavaScript (TypeScript ready) desenvolvida para permitir que aplicações web modernas (React, Next.js, Vue, Angular ou JavaScript nativo) se comuniquem com o agente desktop **CyberCore Signer** através do protocolo local **CCSP/1**.
---
## 1. Instalação e Configuração
### 1.1 Instalação via Gerenciador de Pacotes
```bash
npm install @cybercore/signer-sdk
# ou
yarn add @cybercore/signer-sdk
# ou
pnpm add @cybercore/signer-sdk
```
### 1.2 Inicialização do Cliente
```javascript
import { CyberCoreSigner } from '@cybercore/signer-sdk';
const signer = new CyberCoreSigner({
applicationName: 'Portal Meu Negócio', // Nome exibido no diálogo nativo do usuário
port: 21325, // Porta padrão do agente local (opcional)
timeoutMs: 30000 // Timeout padrão para operações (opcional)
});
```
---
## 2. Métodos da API
### 2.1 Verificação de Disponibilidade e Conexão
#### `isInstalled(timeoutMs = 2000): Promise<boolean>`
Testa de forma rápida e silenciosa se o agente desktop está ativo na máquina do usuário.
```javascript
const disponivel = await signer.isInstalled();
if (!disponivel) {
alert('O CyberCore Signer não foi detectado em sua máquina. Por favor, instale o aplicativo para continuar.');
}
```
#### `connect(): Promise<boolean>`
Inicia o handshake de autorização com o agente. Se a aplicação ainda não foi homologada pelo usuário, abre um diálogo nativo na tela do computador para autorização expressa.
```javascript
const autorizado = await signer.connect();
if (!autorizado) {
console.warn('O usuário recusou a autorização da aplicação.');
}
```
---
### 2.2 Descoberta de Certificados Digitais
#### `getCertificates(): Promise<Array<CertificateInfo>>`
Retorna a lista de certificados digitais válidos e disponíveis na máquina (A1 importados e A3 conectados via USB).
```javascript
const certificados = await signer.getCertificates();
certificados.forEach(cert => {
console.log(`[${cert.type}] ${cert.common_name}`);
console.log(`Titular: ${cert.subject_dn}`);
console.log(`Validade até: ${cert.valid_to}`);
console.log(`CPF/CNPJ: ${cert.cpf || cert.cnpj}`);
});
```
---
### 2.3 Operações de Assinatura Digital
#### `sign(options): Promise<SignatureResult>`
Assina o hash SHA-256 (digest) de qualquer informação. A chave privada nunca sai do computador e apenas o digest é assinado.
```javascript
const resultado = await signer.sign({
certificateId: 'win-4340656a',
digest: '47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=', // Hash SHA-256 em Base64
documentName: 'contrato_prestacao_servicos.pdf',
documentType: 'PDF'
});
console.log('Assinatura gerada (Base64):', resultado.signature);
console.log('Certificado do signatário:', resultado.certificate);
console.log('Cadeia de certificação:', resultado.certificate_chain);
```
#### `signPdf(file, options): Promise<SignatureResult>`
Calcula o hash do documento PDF no próprio navegador e solicita a assinatura ao CyberCore Signer.
```javascript
const inputElement = document.getElementById('arquivo-pdf');
const arquivoPdf = inputElement.files[0];
const resultadoPdf = await signer.signPdf(arquivoPdf, {
certificateId: certificados[0].id
});
console.log('PDF assinado digitalmente com sucesso!');
```
#### `signXml(xmlContent, options): Promise<SignatureResult>`
Assina o hash de documentos XML ou notas fiscais eletrônicas (NF-e, CT-e, MDF-e, XAdES). Aceita `string` com o XML ou arquivo `File`/`Blob`.
```javascript
const xmlString = '<infNFe Id="NFe3524...">...</infNFe>';
const resultadoXml = await signer.signXml(xmlString, {
certificateId: certificados[0].id,
documentName: 'nfe-3524.xml'
});
```
#### `signFile(file, options): Promise<SignatureResult>`
Assina arquivos genéricos de qualquer formato (ZIP, DOCX, XLSX, imagens, binários).
```javascript
const fileInput = document.getElementById('input-qualquer-arquivo');
const resultadoArquivo = await signer.signFile(fileInput.files[0], {
certificateId: certificados[0].id
});
```
---
### 2.4 Autenticação e Login Digital (Challenge-Response)
#### `authenticate(options): Promise<AuthResult>`
Realiza o login seguro de um usuário através de seu certificado digital ICP-Brasil. O backend da sua aplicação fornece um desafio único (*challenge / nonce*) e o CyberCore assina esse desafio.
```javascript
// 1. Obter desafio único do backend da sua aplicação
const { challenge } = await fetch('/api/auth/challenge').then(res => res.json());
// 2. Solicitar assinatura do desafio ao CyberCore Signer
const authResult = await signer.authenticate({
certificateId: certificados[0].id,
challenge: challenge
});
// 3. Enviar a assinatura e o certificado para o backend validar e autenticar a sessão
const response = await fetch('/api/auth/validate-login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
challenge: authResult.challenge,
signature: authResult.signature,
certificate: authResult.certificate
})
});
if (response.ok) {
console.log(`Login aprovado para: ${authResult.subjectName} (${authResult.subjectCpfCnpj})`);
window.location.href = '/dashboard';
}
```
---
## 3. Tratamento Estruturado de Erros
O SDK expõe classes de erro dedicadas que herdam de `CyberCoreError`, permitindo tratar cenários de forma elegante na interface:
```javascript
import {
UserCancelledError,
PinIncorrectError,
TokenNotFoundError,
CertificateNotFoundError,
CertificateExpiredError
} from '@cybercore/signer-sdk/errors';
try {
const res = await signer.sign({
certificateId: certId,
digest: documentoDigest
});
} catch (error) {
if (error instanceof UserCancelledError) {
// Usuário cancelou a assinatura voluntariamente na janela nativa
console.info('Operação cancelada pelo usuário.');
} else if (error instanceof PinIncorrectError) {
// PIN do token A3 incorreto
alert('PIN incorreto! Por favor, digite o PIN correto do seu token.');
} else if (error instanceof TokenNotFoundError) {
// Token USB desconectado
alert('Token não encontrado! Por favor, conecte seu dispositivo USB para assinar.');
} else if (error instanceof CertificateExpiredError) {
// Certificado ultrapassou a data de validade
alert('O certificado selecionado expirou. Entre em contato com sua autoridade certificadora.');
} else {
// Demais falhas
console.error('Falha na operação com o CyberCore Signer:', error);
}
}
```