Files
cybercore-signer/docs/sdk.md
Claudecio Martins 2c1d4f359e
CI Pipeline / Build & Verify (Linux x86_64) (push) Canceled after 0s
CI Pipeline / Build & Verify (Windows) (push) Canceled after 0s
docs: harmonize documentation cross-references and validation status
2026-10-20 16:48:17 -03:00

7.0 KiB

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

npm install @cybercore/signer-sdk
# ou
yarn add @cybercore/signer-sdk
# ou
pnpm add @cybercore/signer-sdk

1.2 Inicialização do Cliente

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.

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.

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).

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.

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.

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.

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).

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.

// 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:

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);
  }
}

4. Documentação Relacionada e Recursos