# 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` 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` 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>` 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` 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` 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` 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 = '...'; const resultadoXml = await signer.signXml(xmlString, { certificateId: certificados[0].id, documentName: 'nfe-3524.xml' }); ``` #### `signFile(file, options): Promise` 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` 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); } } ```