UNPKG

envio-comprobantes-sri

Version:

Envia comprobantes electronicos al SRI (Ecuador). Recibe un objeto JSON. Lo convierte a XML, lo firma, lo envía al servicio web del SRI y devuelve la respuesta.

62 lines (61 loc) 3.38 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.aptoParaFirma = exports.estaVigente = exports.elegirCertificadoVigente = void 0; const node_forge_1 = __importDefault(require("node-forge")); // Un .p12 puede traer la cadena CA (sin llave) y, en certificados del Banco Central, // el historial de la persona (vencidos + vigentes). Por defecto se usa el primer bag, // igual que siempre; solo si no está vigente se busca un reemplazo vigente. function seleccionarCertificadoDeFirma(p12, fechaReferencia = new Date()) { var certBags = p12.getBags({ bagType: node_forge_1.default.pki.oids.certBag })[node_forge_1.default.pki.oids.certBag] ?? []; var llaveBags = p12.getBags({ bagType: node_forge_1.default.pki.oids.pkcs8ShroudedKeyBag })[node_forge_1.default.pki.oids.pkcs8ShroudedKeyBag] ?? []; var certBag0 = certBags[0]?.cert ?? undefined; var llave0 = llaveBags[0]?.key; var bagPorDefecto = { cert: certBag0, key: llave0 }; if (certBag0 && estaVigente(certBag0, fechaReferencia)) return bagPorDefecto; var llaves = llaveBags .map(bag => bag.key) .filter((llave) => !!llave && !!llave.n); // Empareja cada certificado con su llave por módulo RSA (descarta la cadena CA). var candidatos = []; for (var bag of certBags) { var cert = bag.cert; var moduloCert = cert?.publicKey?.n; if (!cert || !moduloCert) continue; var llave = llaves.find(llave => moduloCert.compareTo(llave.n) === 0); if (llave) candidatos.push({ cert, key: llave }); } var elegido = elegirCertificadoVigente(candidatos, fechaReferencia); return elegido && estaVigente(elegido.cert, fechaReferencia) ? elegido : bagPorDefecto; } exports.default = seleccionarCertificadoDeFirma; // Prioridad: vigentes > aptos para firma > caducidad más reciente. function elegirCertificadoVigente(candidatos, fechaReferencia = new Date()) { if (candidatos.length === 0) return undefined; var vigentes = candidatos.filter(({ cert }) => estaVigente(cert, fechaReferencia)); var elegibles = vigentes.length > 0 ? vigentes : candidatos; var aptos = elegibles.filter(({ cert }) => aptoParaFirma(cert)); var finalistas = aptos.length > 0 ? aptos : elegibles; return finalistas.reduce((mejor, actual) => actual.cert.validity.notAfter.valueOf() > mejor.cert.validity.notAfter.valueOf() ? actual : mejor); } exports.elegirCertificadoVigente = elegirCertificadoVigente; function estaVigente(cert, fechaReferencia = new Date()) { var ahora = fechaReferencia.valueOf(); return cert.validity.notBefore.valueOf() <= ahora && ahora <= cert.validity.notAfter.valueOf(); } exports.estaVigente = estaVigente; // Las CA del Ecuador emiten un cert de firma y otro de cifrado; solo el de firma sirve. // Sin keyUsage declarado no se asume restricción. function aptoParaFirma(cert) { var usoDeClave = cert.extensions?.find(extension => extension.name === "keyUsage"); if (!usoDeClave) return true; return !!(usoDeClave.digitalSignature || usoDeClave.nonRepudiation); } exports.aptoParaFirma = aptoParaFirma;