ec-sri-invoice-signer
Version:
Ecuador SRI invoice signer.
171 lines (170 loc) • 8.19 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.signWithholdingCertificateXml = exports.signDeliveryGuideXml = exports.signCreditNoteXml = exports.signDebitNoteXml = exports.signInvoiceXml = exports.signDocumentXml = void 0;
const c14n_1 = require("../canonicalization/c14n");
const constants_1 = require("../utils/constants");
const cryptography_1 = require("../utils/cryptography");
const Utils = __importStar(require("../utils/utils"));
const xml_1 = require("../utils/xml");
const keyInfo_1 = require("./templates/keyInfo");
const signature_1 = require("./templates/signature");
const signedInfo_1 = require("./templates/signedInfo");
const signedProperties_1 = require("./templates/signedProperties");
const insertSignatureIntoInvoiceXml = (invoiceXml, signatureXml, rootTagName) => {
const tagName = `</${rootTagName}>`;
return invoiceXml.replace(tagName, `${signatureXml}${tagName}`);
};
const signDocumentXml = (docXml, pkcs12Data, rootTagName, options) => {
const signingTime = Utils.getDate();
const { privateKey, certificate } = (0, cryptography_1.extractPrivateKeyAndCertificateFromPkcs12)(pkcs12Data, options === null || options === void 0 ? void 0 : options.pkcs12Password);
const { exponent: certificateExponent, modulus: certificateModulus } = (0, cryptography_1.extractPrivateKeyData)(privateKey);
const { issuerName: x509IssuerName, serialNumber: x509SerialNumber, content: certificateContent, contentHash: x509Hash } = (0, cryptography_1.extractX509Data)(certificate);
(0, xml_1.validateDocumentType)(docXml);
(0, xml_1.validateXmlFeatures)(docXml);
// IDs
const docTagId = 'comprobante';
const docTagRefId = `DocumentRef-${Utils.getRandomUuid()}`;
const keyInfoTagId = `Certificate-${Utils.getRandomUuid()}`;
const keyInfoRefTagId = `CertificateRef-${Utils.getRandomUuid()}`;
const signedInfoTagId = `SignedInfo-${Utils.getRandomUuid()}`;
const signedPropertiesRefTagId = `SignedPropertiesRef-${Utils.getRandomUuid()}`;
const signedPropertiesTagId = `SignedProperties-${Utils.getRandomUuid()}`;
const signatureTagId = `Signature-${Utils.getRandomUuid()}`;
const signatureObjectTagId = `SignatureObject-${Utils.getRandomUuid()}`;
const signatureValueTagId = `SignatureValue-${Utils.getRandomUuid()}`;
// XML sections, hashes and signature
const keyInfoTag = (0, keyInfo_1.buildKeyInfoTag)({
certificateContent,
certificateExponent,
certificateModulus,
keyInfoTagId
});
const signedPropertiesTag = (0, signedProperties_1.buildSignedPropertiesTag)({
invoiceTagRefId: docTagRefId,
signedPropertiesTagId,
signingTime,
x509Hash,
x509IssuerName,
x509SerialNumber
});
const docHash = (0, cryptography_1.getHash)((0, c14n_1.c14nCanonicalize)(docXml));
const signedPropertiesTagHash = (0, cryptography_1.getHash)((0, c14n_1.c14nCanonicalize)(signedPropertiesTag, { inheritedNamespaces: [{ prefix: 'xades', uri: constants_1.XmlProperties.namespaces.xades }, { prefix: 'ds', uri: constants_1.XmlProperties.namespaces.ds }] }));
const keyInfoTagHash = (0, cryptography_1.getHash)((0, c14n_1.c14nCanonicalize)(keyInfoTag, { inheritedNamespaces: [{ prefix: 'ds', uri: constants_1.XmlProperties.namespaces.ds }] }));
const signedInfoTag = (0, signedInfo_1.buildSignedInfoTag)({
invoiceHash: docHash,
invoiceTagId: docTagId,
invoiceTagRefId: docTagRefId,
keyInfoRefTagId,
keyInfoTagHash,
keyInfoTagId,
signedInfoTagId,
signedPropertiesRefTagId,
signedPropertiesTagHash,
signedPropertiesTagId
});
const signedSignedInfoTag = (0, cryptography_1.sign)((0, c14n_1.c14nCanonicalize)(signedInfoTag, { inheritedNamespaces: [{ prefix: 'ds', uri: constants_1.XmlProperties.namespaces.ds }] }), privateKey);
const signatureTag = (0, signature_1.buildSignatureTag)({
keyInfoTag,
signatureTagId,
signatureObjectTagId,
signedInfoTag,
signedSignedInfoTag,
signatureValueTagId,
signedPropertiesTag
});
return insertSignatureIntoInvoiceXml(docXml, signatureTag, rootTagName);
};
exports.signDocumentXml = signDocumentXml;
/**
*
* @param xml The invoice XML to be signed.
* @param pkcs12Data The pkcs12 file (.p12/.pfx) data expressed as a node Buffer or base64 string.
* @param options Options are:
* - **pkcs12Password**: The pkcs12 file password. Defaults to no password.
* @returns The signed invoice XML.
*/
const signInvoiceXml = (xml, pkcs12Data, options) => {
return (0, exports.signDocumentXml)(xml, pkcs12Data, 'factura', options);
};
exports.signInvoiceXml = signInvoiceXml;
/**
*
* @param xml The debit note XML to be signed.
* @param pkcs12Data The pkcs12 file (.p12/.pfx) data expressed as a node Buffer or base64 string.
* @param options Options are:
* - **pkcs12Password**: The pkcs12 file password. Defaults to no password.
* @returns The signed debit note XML.
*/
const signDebitNoteXml = (xml, pkcs12Data, options) => {
return (0, exports.signDocumentXml)(xml, pkcs12Data, 'notaDebito', options);
};
exports.signDebitNoteXml = signDebitNoteXml;
/**
*
* @param xml The credit note XML to be signed.
* @param pkcs12Data The pkcs12 file (.p12/.pfx) data expressed as a node Buffer or base64 string.
* @param options Options are:
* - **pkcs12Password**: The pkcs12 file password. Defaults to no password.
* @returns The signed credit note XML.
*/
const signCreditNoteXml = (xml, pkcs12Data, options) => {
return (0, exports.signDocumentXml)(xml, pkcs12Data, 'notaCredito', options);
};
exports.signCreditNoteXml = signCreditNoteXml;
/**
*
* @param xml The delivery guide XML to be signed.
* @param pkcs12Data The pkcs12 file (.p12/.pfx) data expressed as a node Buffer or base64 string.
* @param options Options are:
* - **pkcs12Password**: The pkcs12 file password. Defaults to no password.
* @returns The signed delivery guide XML.
*/
const signDeliveryGuideXml = (xml, pkcs12Data, options) => {
return (0, exports.signDocumentXml)(xml, pkcs12Data, 'guiaRemision', options);
};
exports.signDeliveryGuideXml = signDeliveryGuideXml;
/**
*
* @param xml The withholding certificate XML to be signed.
* @param pkcs12Data The pkcs12 file (.p12/.pfx) data expressed as a node Buffer or base64 string.
* @param options Options are:
* - **pkcs12Password**: The pkcs12 file password. Defaults to no password.
* @returns The signed withholding certificate XML.
*/
const signWithholdingCertificateXml = (xml, pkcs12Data, options) => {
return (0, exports.signDocumentXml)(xml, pkcs12Data, 'comprobanteRetencion', options);
};
exports.signWithholdingCertificateXml = signWithholdingCertificateXml;