diff --git a/lib/Client.js b/lib/Client.js index 5b9aa03..daff0ee 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -1,72 +1,17 @@ 'use strict'; -// const fs = require('fs'); -// const path = require('path'); - const $request = require('request'); const XMLSign = require('./middleware/XMLSign'); const ParseResponse = require('./middleware/ParseResponse'); -// const BankLetter = require('./BankLetter'); - -const OrderSerializer = require('./orders/H004/OrderSerializer'); - - -/* const defaultIniTemplatePath = path.join(__dirname, '../templates/ini.hbs'); - -const utils = { - mapObject: (o = {}, predicate = v => v) => Object.entries(o).reduce((r, [key, value]) => { r[key] = value; return r; }, o), - exponent: { - // str = 65537 => AQAB - toBase64(str) { - return new BN(str).toBuffer().toString('base64'); - }, - // str = AQAB => 65537 - fromBase64(str) { - return new BN(Buffer.from(str, 'base64'), 2).toNumber(); - }, - }, -}; */ module.exports = class Client { - /* constructor({ - url, - hostId, - userId, - partnerId, - keyManager = new FsKeyManager({ path: './keys.ebics', passphrase: 'node-ebics' }), - }) { - this.url = url; - this.hostId = hostId; - this.userId = userId; - this.partnerId = partnerId; - this.keyManager = keyManager; - } */ - constructor({ url }) { this.url = url; } - /* - - saveIniLetter(bankName, target, template) { - const letter = new BankLetter({ - client: this, - bankName, - template: template || fs.readFileSync(defaultIniTemplatePath, { encoding: 'utf8' }), - }); - - try { - fs.writeFileSync(target, letter.generate()); - } catch (error) { - throw error; - } - } - */ - - async initialization(order) { - const res = await this.ebicsRequest(OrderSerializer.serialize(order)); + const res = await this.ebicsRequest(order); const xml = res.orderData(); return { @@ -79,12 +24,12 @@ module.exports = class Client { } async download(order) { - const res = await this.ebicsRequest(OrderSerializer.serialize(order)); + const res = await this.ebicsRequest(order); order.transactionId = res.transactionId(); if (res.isSegmented() && res.isLastSegment()) - await this.ebicsRequest(OrderSerializer.serialize(order)); + await this.ebicsRequest(order); // return res.orderData(); return { @@ -96,13 +41,13 @@ module.exports = class Client { } async upload(order) { - let res = await this.ebicsRequest(OrderSerializer.serialize(order)); + let res = await this.ebicsRequest(order); const transactionId = res.transactionId(); const orderId = res.orderId(); order.transactionId = transactionId; - res = await this.ebicsRequest(OrderSerializer.serialize(order)); + res = await this.ebicsRequest(order); return [transactionId, orderId]; } @@ -111,16 +56,13 @@ module.exports = class Client { } - ebicsRequest(serializedOrder) { - const { keys } = serializedOrder; - + ebicsRequest(order) { return new Promise((resolve, reject) => { - const s = XMLSign.go(keys, serializedOrder.toXML()); $request.post({ url: this.url, - body: s, // XMLSign.go(this, serializedOrder), + body: XMLSign.sign(order), headers: { 'content-type': 'text/xml;charset=UTF-8' }, - }, (err, res, data) => (err ? reject(err) : resolve(ParseResponse.go(keys, data)))); + }, (err, res, data) => (err ? reject(err) : resolve(ParseResponse.parse(data, order.keys, order.version)))); }); } diff --git a/lib/orders/H004/OrderBuilder.js b/lib/OrderBuilder.js similarity index 70% rename from lib/orders/H004/OrderBuilder.js rename to lib/OrderBuilder.js index ece3330..3643090 100644 --- a/lib/orders/H004/OrderBuilder.js +++ b/lib/OrderBuilder.js @@ -7,15 +7,7 @@ const crypto = require('crypto'); module.exports = class OrderBuilder { constructor() { this._transactionKey = crypto.randomBytes(16); - this._root = { - nodeName: 'ebicsRequest', - nodeAttributes: { - 'xmlns:ds': 'http://www.w3.org/2000/09/xmldsig#', - xmlns: 'urn:org:ebics:H004', - Version: 'H004', - Revision: '1', - }, - }; + this._root = {}; this._body = {}; } @@ -26,27 +18,36 @@ module.exports = class OrderBuilder { return this; } - static payment() { - const builder = new OrderBuilder(); + payment() { + this._type = 'payment'; - builder._type = 'payment'; - - return builder; + return this; } - static status() { - const builder = new OrderBuilder(); + status() { + this._type = 'status'; - builder._type = 'status'; - - return builder; + return this; } - static ini() { + ini() { + this._type = 'ini'; + this._root.nodeName = 'ebicsUnsecuredRequest'; + + return this; + } + + static h004() { const builder = new OrderBuilder(); - builder._type = 'ini'; - builder._root.nodeName = 'ebicsUnsecuredRequest'; + builder._version = 'H004'; + builder._root.nodeName = 'ebicsRequest'; + builder._root.nodeAttributes = { + 'xmlns:ds': 'http://www.w3.org/2000/09/xmldsig#', + xmlns: 'urn:org:ebics:H004', + Version: 'H004', + Revision: '1', + }; return builder; } @@ -67,6 +68,7 @@ module.exports = class OrderBuilder { get partnerId() { return this._data.ebicsData.partnerId; } get userId() { return this._data.ebicsData.userId; } get keys() { return this._data.ebicsData.keysManager.keys(); } + get version() { return this._version; } set transactionId(tid) { this._data.transactionId = tid === '' ? null : tid; diff --git a/lib/middleware/ParseResponse.js b/lib/middleware/ParseResponse.js index 60d59d9..8521377 100644 --- a/lib/middleware/ParseResponse.js +++ b/lib/middleware/ParseResponse.js @@ -1,16 +1,11 @@ 'use strict'; -const Response = require('../Response'); +const H004Response = require('../versions/H004/Response'); module.exports = class ParseResponse { - static go(keys, data) { - const response = new Response(keys, data); + static parse(data, keys, version) { + if (version.toUpperCase() === 'H004') return new H004Response(data, keys); - // TODO: - // raise error if any - - this.data = response.doc; - - return response; + throw Error('Unknow EBICS response version'); } }; diff --git a/lib/middleware/XMLSign.js b/lib/middleware/XMLSign.js index 0827516..7d0195e 100644 --- a/lib/middleware/XMLSign.js +++ b/lib/middleware/XMLSign.js @@ -1,16 +1,15 @@ 'use strict'; -const Signer = require('../Signer'); +const H004Signer = require('../versions/H004/Signer'); + +const H004Serializer = require('../versions/H004/OrderSerializer'); module.exports = class XMLSign { - static go(keys, xml) { - const signer = new Signer(keys, xml); + static sign(order) { + const { keys } = order; - signer.digest(); - signer.sign(); + if (order.version.toUpperCase() === 'H004') return new H004Signer(H004Serializer.serialize(order).toXML(), keys).digest().sign().toXML(); - this.data = signer.toXML(); - - return this.data; + throw Error('Error from XMLSign class: Invalid version number'); } }; diff --git a/lib/orders/H004/OrderSerializer.js b/lib/versions/H004/OrderSerializer.js similarity index 63% rename from lib/orders/H004/OrderSerializer.js rename to lib/versions/H004/OrderSerializer.js index bfce565..6cdaf0f 100644 --- a/lib/orders/H004/OrderSerializer.js +++ b/lib/versions/H004/OrderSerializer.js @@ -1,8 +1,8 @@ 'use strict'; -const InitializationSerializer = require('./InitializationSerializer'); -const StatusSerializer = require('./StatusSerializer'); -const PaymentSerializer = require('./PaymentSerializer'); +const InitializationSerializer = require('./serializers/InitializationSerializer'); +const StatusSerializer = require('./serializers/StatusSerializer'); +const PaymentSerializer = require('./serializers/PaymentSerializer'); module.exports = class OrderSerializer { static serialize(order) { diff --git a/lib/Response.js b/lib/versions/H004/Response.js similarity index 97% rename from lib/Response.js rename to lib/versions/H004/Response.js index 075ef4d..cf2367b 100644 --- a/lib/Response.js +++ b/lib/versions/H004/Response.js @@ -4,7 +4,7 @@ const zlib = require('zlib'); const crypto = require('crypto'); const BN = require('bn.js'); -const Crypto = require('./crypto/Crypto'); +const Crypto = require('../../crypto/Crypto'); const { DOMParser, XMLSerializer } = require('xmldom'); const xpath = require('xpath'); @@ -20,7 +20,7 @@ const lastChild = (node) => { }; module.exports = class Response { - constructor(keys, data) { + constructor(data, keys) { this.keys = keys; this.doc = new DOMParser().parseFromString(data, 'text/xml'); } diff --git a/lib/Signer.js b/lib/versions/H004/Signer.js similarity index 94% rename from lib/Signer.js rename to lib/versions/H004/Signer.js index dca7226..d535a03 100644 --- a/lib/Signer.js +++ b/lib/versions/H004/Signer.js @@ -1,7 +1,7 @@ 'use strict'; // const crypto = require('crypto'); -const Crypto = require('./crypto/Crypto'); +const Crypto = require('../../crypto/Crypto'); const { DOMParser, XMLSerializer } = require('xmldom'); const xpath = require('xpath'); @@ -15,7 +15,7 @@ module.exports = class Signer { * @param {Keys} keys * @param {String} data */ - constructor(keys, data) { + constructor(data, keys) { /** * Keys to operate with * @@ -44,6 +44,8 @@ module.exports = class Signer { if (nodeDigestValue) nodeDigestValue.textContent = Crypto.digestWithHash(fixedContent).toString('base64').trim(); + + return this; } sign() { @@ -55,6 +57,8 @@ module.exports = class Signer { nodeSignatureValue.textContent = Crypto.privateSign(this.keys.x(), contentToSign); // this.keys.x().key.sign(contentToSign, 'base64'); } + + return this; } toXML() { diff --git a/lib/orders/H004/GenericSerializer.js b/lib/versions/H004/serializers/GenericSerializer.js similarity index 100% rename from lib/orders/H004/GenericSerializer.js rename to lib/versions/H004/serializers/GenericSerializer.js diff --git a/lib/orders/H004/InitializationSerializer.js b/lib/versions/H004/serializers/InitializationSerializer.js similarity index 97% rename from lib/orders/H004/InitializationSerializer.js rename to lib/versions/H004/serializers/InitializationSerializer.js index 6fb880e..f5dc57d 100644 --- a/lib/orders/H004/InitializationSerializer.js +++ b/lib/versions/H004/serializers/InitializationSerializer.js @@ -3,8 +3,8 @@ const zlib = require('zlib'); const js2xmlparser = require('js2xmlparser'); -const consts = require('../../consts'); -const Crypto = require('../../crypto/Crypto'); +const consts = require('../../../consts'); +const Crypto = require('../../../crypto/Crypto'); const GenericSerializer = require('./GenericSerializer'); diff --git a/lib/orders/H004/PaymentSerializer.js b/lib/versions/H004/serializers/PaymentSerializer.js similarity index 97% rename from lib/orders/H004/PaymentSerializer.js rename to lib/versions/H004/serializers/PaymentSerializer.js index cc61487..3ee4f33 100644 --- a/lib/orders/H004/PaymentSerializer.js +++ b/lib/versions/H004/serializers/PaymentSerializer.js @@ -5,8 +5,8 @@ const crypto = require('crypto'); const js2xmlparser = require('js2xmlparser'); -const consts = require('../../consts'); -const Crypto = require('../../crypto/Crypto'); +const consts = require('../../../consts'); +const Crypto = require('../../../crypto/Crypto'); const GenericSerializer = require('./GenericSerializer'); diff --git a/lib/orders/H004/StatusSerializer.js b/lib/versions/H004/serializers/StatusSerializer.js similarity index 94% rename from lib/orders/H004/StatusSerializer.js rename to lib/versions/H004/serializers/StatusSerializer.js index a1bc521..baab03e 100644 --- a/lib/orders/H004/StatusSerializer.js +++ b/lib/versions/H004/serializers/StatusSerializer.js @@ -1,7 +1,7 @@ 'use strict'; -const consts = require('../../consts'); -const Crypto = require('../../crypto/Crypto'); +const consts = require('../../../consts'); +const Crypto = require('../../../crypto/Crypto'); const GenericSerializer = require('./GenericSerializer');