UNPKG

xml-fiesta

Version:

Electronic signed document XML Protocol for Node & Browser

184 lines 7.08 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var Promise = require('promise'); var xmlCrypto = require('xml-crypto'); var select = require('xpath.js'); var Dom = require('xmldom').DOMParser; var xml2js_1 = require("xml2js"); var common_1 = require("./common"); var ExclusiveCanonicalization = xmlCrypto. SignedXml. CanonicalizationAlgorithms['http://www.w3.org/2001/10/xml-exc-c14n#']; var XML = (function () { function XML() { } XML.parse = function (string) { var xml = new XML(); return xml.parse(string); }; XML.toXML = function (eDocument, file) { var edoc = JSON.parse(JSON.stringify(eDocument)); this.removeEncrypedData(edoc); edoc.file[0]._ = file; var builder = new xml2js_1.Builder({ rootName: "electronicDocument", renderOpts: { pretty: false, }, }); return builder.buildObject(edoc); }; XML.removeEncrypedData = function (xmljs) { if (xmljs.file && xmljs.file[0]) { delete xmljs.file[0].$.encrypted; xmljs.file[0].$.name = xmljs.file[0].$.name.replace(".enc", ""); } xmljs.signers[0].signer.forEach(function (signer) { delete signer.ePass; }); }; XML.removeGeolocation = function (xmljs) { xmljs.signers[0].signer.forEach(function (signer) { if (signer.auditTrail) { signer.auditTrail[0].event.forEach(function (event, index) { if (event.$.name === "geolocation") { delete signer.auditTrail[0].event[index]; } }); } }); }; XML.removeBlockchain = function (xmljs) { delete xmljs.blockchain; }; XML.removeTransfer = function (xmljs) { delete xmljs.transfers; }; XML.prototype.parse = function (xml) { var el = this; return new Promise(function (resolve, reject) { return xml2js_1.parseString(xml, function (err, result) { var _a; var isTransfer = false; if (result.electronicDocument.transfers) { var lastNodeTransfer = result.electronicDocument.transfers[result.electronicDocument.transfers.length - 1]; if ((_a = lastNodeTransfer) === null || _a === void 0 ? void 0 : _a.electronicDocument) { isTransfer = true; result.originalElectronicDocument = result.electronicDocument; result.electronicDocument = lastNodeTransfer.electronicDocument[lastNodeTransfer.electronicDocument.length - 1]; el.originalElectronicDocument = result.originalElectronicDocument; } } if (err) { return reject(err); } el.eDocument = result.electronicDocument; var eDocumentAttrs = el.eDocument.$; el.version = eDocumentAttrs.version; el.signed = eDocumentAttrs.signed; var v = el.version.split(/\./).map(function (v) { return parseInt(v); }); el.version_int = v[0] * 100 + v[1] * 10 + v[2]; if (el.version_int < 100) { el.fileElementName = "pdf"; } else { el.fileElementName = "file"; } var pdfAttrs = el.eDocument[el.fileElementName][0].$; el.encrypted = pdfAttrs.encrypted; el.name = pdfAttrs.name; el.contentType = pdfAttrs.contentType; el.originalHash = pdfAttrs.originalHash; el.isTransfer = isTransfer; return resolve(el); }); }); }; XML.prototype.canonical = function () { var edoc = JSON.parse(JSON.stringify(this.eDocument)); if (this.isTransfer && this.originalElectronicDocument) { Object.entries(this.originalElectronicDocument.$).map(function (_a) { var key = _a[0], value = _a[1]; if (key.includes('xmlns')) { edoc.$[key] = value; } }); } delete edoc.conservancyRecord; XML.removeEncrypedData(edoc); XML.removeGeolocation(edoc); XML.removeBlockchain(edoc); XML.removeTransfer(edoc); if (this.version_int >= 100) { edoc[this.fileElementName][0]._ = ""; } var builder = new xml2js_1.Builder({ rootName: "electronicDocument", renderOpts: { pretty: false, }, }); var originalXml = builder.buildObject(edoc); var doc = new Dom().parseFromString(originalXml); var elem = select(doc, "//*")[0]; var can = new ExclusiveCanonicalization(); var canonicalString = can.process(elem).toString(); return canonicalString.replace(/&#xD;/g, ""); }; XML.prototype.getCanonicalBuffer = function () { return Buffer.from(this.canonical(), "utf-8"); }; XML.prototype.file = function () { return this.eDocument[this.fileElementName][0]._; }; XML.prototype.pdf = function () { return this.file(); }; XML.prototype.xmlSigners = function () { var parsedSigners = []; this.eDocument.signers[0].signer.forEach(function (signer) { var attrs = signer.$; var xmlSigner = { email: attrs.email, cer: common_1.b64toHex(signer.certificate[0]._), signature: common_1.b64toHex(signer.signature[0]._), signedAt: signer.signature[0].$.signedAt, }; if (signer.ePass) { xmlSigner.ePass = { content: common_1.b64toHex(signer.ePass[0]._), algorithm: signer.ePass[0].$.algorithm, iterations: signer.ePass[0].$.iterations, keySize: signer.ePass[0].$.keySize, }; } return parsedSigners.push(xmlSigner); }); return parsedSigners; }; XML.prototype.getConservancyRecord = function () { var crVersion, userCertificate; if (!this.eDocument.conservancyRecord) { return null; } var cr = this.eDocument.conservancyRecord[0]; if (!cr.$.version) { userCertificate = cr.userCertificate[0]._; } else { crVersion = cr.$.version; } return { caCert: cr.caCertificate[0]._, userCert: userCertificate, record: cr.record[0], timestamp: cr.$.timestamp, originalXmlHash: common_1.sha256(this.canonical()), version: crVersion, }; }; return XML; }()); exports.default = XML; //# sourceMappingURL=xml.js.map