client and order optimization

This commit is contained in:
Vladislav Hristov 2018-06-20 12:20:03 +03:00
parent 187636019c
commit 945499290a
15 changed files with 259 additions and 194 deletions

View File

@ -1,15 +1,9 @@
'use strict'; 'use strict';
const Client = require('./lib/Client'); const Client = require('./lib/Client');
const OrderBuilder = require('./lib/OrderBuilder'); const fsKeysStorage = require('./lib/storages/fsKeysStorage');
const ISO20022Builder = require('./lib/ISO20022OrderBuilder');
const keysManager = require('./lib/keymanagers/keysManager');
const fsKeysStorage = require('./lib/keymanagers/fsKeysStorage');
module.exports = { module.exports = {
Client, Client,
OrderBuilder,
ISO20022Builder,
keysManager,
fsKeysStorage, fsKeysStorage,
}; };

View File

@ -2,13 +2,55 @@
const $request = require('request'); const $request = require('request');
const constants = require('./consts');
const Keys = require('./keymanagers/Keys');
const defaultKeyEncryptor = require('./keymanagers/defaultKeyEncryptor');
const signer = require('./middleware/signer'); const signer = require('./middleware/signer');
const serializer = require('./middleware/serializer'); const serializer = require('./middleware/serializer');
const response = require('./middleware/response'); const response = require('./middleware/response');
module.exports = class Client { module.exports = class Client {
constructor(url) { constructor({
url,
partnerId,
userId,
hostId,
passphrase,
keyStorage,
}) {
if (!url)
throw new Error('EBICS URL is requierd');
if (!partnerId)
throw new Error('partnerId is requierd');
if (!userId)
throw new Error('userId is requierd');
if (!hostId)
throw new Error('hostId is requierd');
if (!passphrase)
throw new Error('passphrase is requierd');
if (!keyStorage || typeof keyStorage.read !== 'function' || typeof keyStorage.write !== 'function')
throw new Error('keyStorage implemntation missing or wrong');
this.url = url; this.url = url;
this.partnerId = partnerId;
this.userId = userId;
this.hostId = hostId;
this.keyStorage = keyStorage;
this.keyEncryptor = defaultKeyEncryptor({ passphrase });
}
send(order) {
const isInObject = ('operation' in order);
if (!isInObject) throw new Error('Operation for the order needed');
if (order.operation.toUpperCase() === constants.orderOperations.ini) return this.initialization(order);
if (order.operation.toUpperCase() === constants.orderOperations.upload) return this.upload(order);
if (order.operation.toUpperCase() === constants.orderOperations.download) return this.download(order);
throw new Error('Wrong order operation provided');
} }
async initialization(order) { async initialization(order) {
@ -32,7 +74,6 @@ module.exports = class Client {
if (res.isSegmented() && res.isLastSegment()) if (res.isSegmented() && res.isLastSegment())
await this.ebicsRequest(order); await this.ebicsRequest(order);
// return res.orderData();
return { return {
orderData: res.orderData(), orderData: res.orderData(),
orderId: res.orderId(), orderId: res.orderId(),
@ -55,11 +96,12 @@ module.exports = class Client {
ebicsRequest(order) { ebicsRequest(order) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const { version, keys } = order; const { version } = order;
// const s = signer.version(version).use(serializer.use(order).toXML(), keys).digest().sign().toXML(); // new (signer.version(version))(serializer.use(order).toXML(), keys).digest().sign().toXML(); const keys = this.keys();
$request.post({ $request.post({
url: this.url, url: this.url,
body: signer.version(version).sign(serializer.use(order).toXML(), keys), // s, // new (signer.version(version))(serializer.use(order).toXML(), keys).digest().sign().toXML(), body: signer.version(version).sign(serializer.use(order, this).toXML(), keys.x()), // s, // new (signer.version(version))(serializer.use(order).toXML(), keys).digest().sign().toXML(),
headers: { 'content-type': 'text/xml;charset=UTF-8' }, headers: { 'content-type': 'text/xml;charset=UTF-8' },
}, (err, res, data) => (err ? reject(err) : resolve(response.version(version)(data, keys)))); }, (err, res, data) => (err ? reject(err) : resolve(response.version(version)(data, keys))));
}); });
@ -80,4 +122,25 @@ module.exports = class Client {
status(order) { status(order) {
return this.download(order); return this.download(order);
} }
keys() {
const keysString = this.keyStorage.read();
return new Keys(JSON.parse(this.keyEncryptor.decrypt(keysString)));
}
setBankKeys(bankKeys) {
const keysObject = this.keys();
keysObject.setBankKeys(bankKeys);
const { keys } = keysObject;
Object.keys(keys).map((key) => {
keys[key] = keys[key] === null ? null : keys[key].toPem();
return key;
});
this.keyStorage.write(this.keyEncryptor.encrypt(JSON.stringify(keys)));
}
}; };

View File

@ -4,9 +4,15 @@ const packageJson = require('../package.json');
const name = 'eCollect Node Ebics Client'; const name = 'eCollect Node Ebics Client';
const { version } = packageJson; const { version } = packageJson;
const orderOperations = {
ini: 'INI',
upload: 'UPLOAD',
download: 'DOWNLOAD',
};
module.exports = { module.exports = {
name, name,
version, version,
orderOperations,
productString: `${name} ${version}`, productString: `${name} ${version}`,
}; };

View File

@ -3,26 +3,22 @@
const BN = require('bn.js'); const BN = require('bn.js');
const NodeRSA = require('node-rsa'); const NodeRSA = require('node-rsa');
module.exports = class Key { const keyOrNull = (encodedKey) => {
constructor(encodedKey/* , passphrase = null */) { if (encodedKey === null) return new NodeRSA();
this._key = (encodedKey instanceof NodeRSA) ? encodedKey : new NodeRSA(encodedKey);
}
static generate(keysize = 2048) { return (encodedKey instanceof NodeRSA) ? encodedKey : new NodeRSA(encodedKey);
return new NodeRSA({ b: keysize }); };
}
static importKey({ mod, exp }) { module.exports = encodedKey => ({
const key = new NodeRSA(); key: keyOrNull(encodedKey),
key.importKey({ n: mod, e: exp }, 'components-public'); generate(keySize = 2048) {
return new NodeRSA({ b: keySize });
},
return new Key(key); importKey({ mod, exp }) {
} this.key.importKey({ n: mod, e: exp }, 'components-public');
},
get key() {
return this._key;
}
n(to = 'buff') { n(to = 'buff') {
const keyN = Buffer.from(this.key.exportKey('components-public').n); const keyN = Buffer.from(this.key.exportKey('components-public').n);
@ -30,7 +26,7 @@ module.exports = class Key {
return to === 'hex' return to === 'hex'
? keyN.toString('hex', 1) ? keyN.toString('hex', 1)
: keyN; : keyN;
} },
e(to = 'buff') { e(to = 'buff') {
const eKey = new BN(this.key.exportKey('components-public').e).toBuffer(); const eKey = new BN(this.key.exportKey('components-public').e).toBuffer();
@ -38,13 +34,13 @@ module.exports = class Key {
return to === 'hex' return to === 'hex'
? eKey.toString('hex') ? eKey.toString('hex')
: eKey; : eKey;
} },
d() { d() {
return this.key.keyPair.d.toBuffer(); return this.key.keyPair.d.toBuffer();
} },
toPem() { toPem() {
return this.key.isPrivate() ? this.key.exportKey('pkcs1-private-pem') : this.key.exportKey('pkcs8-public-pem'); return this.key.isPrivate() ? this.key.exportKey('pkcs1-private-pem') : this.key.exportKey('pkcs8-public-pem');
} },
}; });

View File

@ -1,8 +1,8 @@
'use strict'; 'use strict';
const Key = require('./Key'); const Key = require('./key');
const keyOrNull = key => (key ? new Key(key) : null); const keyOrNull = key => (key ? Key(key) : null);
module.exports = class Keys { module.exports = class Keys {
constructor({ constructor({
@ -32,8 +32,8 @@ module.exports = class Keys {
} }
setBankKeys(bankKeys) { setBankKeys(bankKeys) {
this.keys.bankX002 = Key.importKey(bankKeys.bankX002); this.keys.bankX002.importKey(bankKeys.bankX002);
this.keys.bankE002 = Key.importKey(bankKeys.bankE002); this.keys.bankE002.importKey(bankKeys.bankE002);
} }
a() { a() {

View File

@ -0,0 +1,24 @@
'use strict';
const crypto = require('crypto');
const encrypt = (data, algorithm, passphrase) => {
const cipher = crypto.createCipher(algorithm, passphrase);
const encrypted = cipher.update(data, 'utf8', 'hex') + cipher.final('hex');
return Buffer.from(encrypted).toString('base64');
};
const decrypt = (data, algorithm, passphrase) => {
data = (Buffer.from(data, 'base64')).toString();
const decipher = crypto.createDecipher(algorithm, passphrase);
const decrypted = decipher.update(data, 'hex', 'utf8') + decipher.final('utf8');
return decrypted;
};
module.exports = ({
passphrase,
algorithm = 'aes-256-cbc',
}) => ({
encrypt: data => encrypt(data, algorithm, passphrase),
decrypt: data => decrypt(data, algorithm, passphrase),
});

View File

@ -3,10 +3,10 @@
const H004Serializer = require('../orders/H004/serializer'); const H004Serializer = require('../orders/H004/serializer');
module.exports = { module.exports = {
use(order) { use(order, client) {
const { version } = order; const { version } = order;
if (version.toUpperCase() === 'H004') return H004Serializer.use(order); if (version.toUpperCase() === 'H004') return H004Serializer.use(order, client);
throw Error('Error middleware/serializer.js: Invalid version number'); throw Error('Error middleware/serializer.js: Invalid version number');
}, },

View File

@ -1,18 +1,18 @@
'use strict'; 'use strict';
const orders = require('../orders'); const constants = require('../../consts');
const iniSerializer = require('./serializers/ini'); const iniSerializer = require('./serializers/ini');
const downloadSerializer = require('./serializers/download'); const downloadSerializer = require('./serializers/download');
const uploadSerializer = require('./serializers/upload'); const uploadSerializer = require('./serializers/upload');
module.exports = { module.exports = {
use(order) { use(order, client) {
const { version, orderType } = order; const operation = order.operation.toUpperCase();
if (orders.version(version).isIni(orderType)) return iniSerializer.use(order); if (operation === constants.orderOperations.ini) return iniSerializer.use(order, client);
if (orders.version(version).isDownload(orderType)) return downloadSerializer.use(order); if (operation === constants.orderOperations.download) return downloadSerializer.use(order, client);
if (orders.version(version).isUpload(orderType)) return uploadSerializer.use(order); if (operation === constants.orderOperations.upload) return uploadSerializer.use(order, client);
throw Error('Error from orders/orders.js: Wrong order version/type.'); throw Error('Error from orders/orders.js: Wrong order version/type.');
}, },

View File

@ -7,14 +7,19 @@ const Crypto = require('../../../crypto/Crypto');
const genericSerializer = require('./generic'); const genericSerializer = require('./generic');
module.exports = { module.exports = {
use(orderBuilder) { use(order, client) {
const keys = client.keys();
const ebicsAccount = {
partnerId: client.partnerId,
userId: client.userId,
hostId: client.hostId,
};
const { orderDetails, transactionId } = order;
const { const {
ebicsData, orderDetails, keys, productString, transactionId, rootName, xmlOptions, xmlSchema, receipt, transfer, productString,
} = orderBuilder; } = genericSerializer(client.hostId, transactionId);
const {
rootName, xmlOptions, xmlSchema, receipt, transfer,
} = genericSerializer(orderBuilder);
this.productString = productString;
this.rootName = rootName; this.rootName = rootName;
this.xmlOptions = xmlOptions; this.xmlOptions = xmlOptions;
this.xmlSchema = xmlSchema; this.xmlSchema = xmlSchema;
@ -26,11 +31,11 @@ module.exports = {
this.xmlSchema.header = { this.xmlSchema.header = {
'@': { authenticate: true }, '@': { authenticate: true },
static: { static: {
HostID: ebicsData.hostId, HostID: ebicsAccount.hostId,
Nonce: Crypto.nonce(), Nonce: Crypto.nonce(),
Timestamp: Crypto.timestamp(), Timestamp: Crypto.timestamp(),
PartnerID: ebicsData.partnerId, PartnerID: ebicsAccount.partnerId,
UserID: ebicsData.userId, UserID: ebicsAccount.userId,
Product: { Product: {
'@': { Language: 'en' }, '@': { Language: 'en' },
'#': productString, '#': productString,

View File

@ -1,5 +1,7 @@
'use strict'; 'use strict';
const constants = require('../../../consts');
const rootName = 'ebicsRequest'; const rootName = 'ebicsRequest';
const rootAttributes = { const rootAttributes = {
'xmlns:ds': 'http://www.w3.org/2000/09/xmldsig#', 'xmlns:ds': 'http://www.w3.org/2000/09/xmldsig#',
@ -58,10 +60,9 @@ const xmlOptions = {
}, },
}; };
module.exports = (orderBuilder) => { module.exports = (hostId, transactionId) => ({
const { ebicsData, transactionId } = orderBuilder; // return {
productString: constants.productString,
return {
rootName, rootName,
xmlOptions, xmlOptions,
xmlSchema: { xmlSchema: {
@ -78,7 +79,7 @@ module.exports = (orderBuilder) => {
header: { header: {
'@': { authenticate: true }, '@': { authenticate: true },
static: { static: {
HostID: ebicsData.hostId, HostID: hostId,
TransactionID: transactionId, TransactionID: transactionId,
}, },
mutable: { mutable: {
@ -106,7 +107,7 @@ module.exports = (orderBuilder) => {
header: { header: {
'@': { authenticate: true }, '@': { authenticate: true },
static: { static: {
HostID: ebicsData.hostId, HostID: hostId,
TransactionID: transactionId, TransactionID: transactionId,
}, },
mutable: { mutable: {
@ -129,5 +130,5 @@ module.exports = (orderBuilder) => {
return this; return this;
}, },
}; // };
}; });

View File

@ -8,7 +8,7 @@ const Crypto = require('../../../crypto/Crypto');
const genericSerializer = require('./generic'); const genericSerializer = require('./generic');
const keySignature = (ebicsData, key, xmlOptions) => { const keySignature = (ebicsAccount, key, xmlOptions) => {
const xmlOrderData = { const xmlOrderData = {
'@': { '@': {
'xmlns:ds': 'http://www.w3.org/2000/09/xmldsig#', 'xmlns:ds': 'http://www.w3.org/2000/09/xmldsig#',
@ -24,13 +24,13 @@ const keySignature = (ebicsData, key, xmlOptions) => {
}, },
SignatureVersion: 'A006', SignatureVersion: 'A006',
}, },
PartnerID: ebicsData.partnerId, PartnerID: ebicsAccount.partnerId,
UserID: ebicsData.userId, UserID: ebicsAccount.userId,
}; };
return js2xmlparser.parse('SignaturePubKeyOrderData', xmlOrderData, xmlOptions); return js2xmlparser.parse('SignaturePubKeyOrderData', xmlOrderData, xmlOptions);
}; };
const orderData = (ebicsData, keys, xmlOptions) => { const orderData = (ebicsAccount, keys, xmlOptions) => {
const xmlOrderData = { const xmlOrderData = {
'@': { '@': {
'xmlns:ds': 'http://www.w3.org/2000/09/xmldsig#', 'xmlns:ds': 'http://www.w3.org/2000/09/xmldsig#',
@ -54,20 +54,20 @@ const orderData = (ebicsData, keys, xmlOptions) => {
}, },
EncryptionVersion: 'E002', EncryptionVersion: 'E002',
}, },
PartnerID: ebicsData.partnerId, PartnerID: ebicsAccount.partnerId,
UserID: ebicsData.userId, UserID: ebicsAccount.userId,
}; };
return js2xmlparser.parse('HIARequestOrderData', xmlOrderData, xmlOptions); return js2xmlparser.parse('HIARequestOrderData', xmlOrderData, xmlOptions);
}; };
const commonHeader = (ebicsData, orderDetails, productString) => ({ const commonHeader = (ebicsAccount, orderDetails, productString) => ({
'@': { authenticate: true }, '@': { authenticate: true },
static: { static: {
HostID: ebicsData.hostId, HostID: ebicsAccount.hostId,
Nonce: Crypto.nonce(), Nonce: Crypto.nonce(),
Timestamp: Crypto.timestamp(), Timestamp: Crypto.timestamp(),
PartnerID: ebicsData.partnerId, PartnerID: ebicsAccount.partnerId,
UserID: ebicsData.userId, UserID: ebicsAccount.userId,
Product: { Product: {
'@': { Language: 'en' }, '@': { Language: 'en' },
'#': productString, '#': productString,
@ -80,57 +80,61 @@ const commonHeader = (ebicsData, orderDetails, productString) => ({
const process = { const process = {
INI: { INI: {
rootName: 'ebicsUnsecuredRequest', rootName: 'ebicsUnsecuredRequest',
header: (ebicsData, orderDetails, productString) => { header: (ebicsAccount, orderDetails, productString) => {
const ch = commonHeader(ebicsData, orderDetails, productString); const ch = commonHeader(ebicsAccount, orderDetails, productString);
delete ch.static.Nonce; delete ch.static.Nonce;
delete ch.static.Timestamp; delete ch.static.Timestamp;
return ch; return ch;
}, },
body: (ebicsData, keys, xmlOptions) => ({ body: (ebicsAccount, keys, xmlOptions) => ({
DataTransfer: { DataTransfer: {
OrderData: Buffer.from(zlib.deflateSync(keySignature(ebicsData, keys.a(), xmlOptions))).toString('base64'), OrderData: Buffer.from(zlib.deflateSync(keySignature(ebicsAccount, keys.a(), xmlOptions))).toString('base64'),
}, },
}), }),
}, },
HIA: { HIA: {
rootName: 'ebicsUnsecuredRequest', rootName: 'ebicsUnsecuredRequest',
header: (ebicsData, orderDetails, productString) => { header: (ebicsAccount, orderDetails, productString) => {
const ch = commonHeader(ebicsData, orderDetails, productString); const ch = commonHeader(ebicsAccount, orderDetails, productString);
delete ch.static.Nonce; delete ch.static.Nonce;
delete ch.static.Timestamp; delete ch.static.Timestamp;
return ch; return ch;
}, },
body: (ebicsData, keys, xmlOptions) => ({ body: (ebicsAccount, keys, xmlOptions) => ({
DataTransfer: { DataTransfer: {
OrderData: Buffer.from(zlib.deflateSync(orderData(ebicsData, keys, xmlOptions))).toString('base64'), OrderData: Buffer.from(zlib.deflateSync(orderData(ebicsAccount, keys, xmlOptions))).toString('base64'),
}, },
}), }),
}, },
HPB: { HPB: {
rootName: 'ebicsNoPubKeyDigestsRequest', rootName: 'ebicsNoPubKeyDigestsRequest',
header: (ebicsData, orderDetails, productString) => commonHeader(ebicsData, orderDetails, productString), header: (ebicsAccount, orderDetails, productString) => commonHeader(ebicsAccount, orderDetails, productString),
body: () => ({}), body: () => ({}),
}, },
}; };
module.exports = { module.exports = {
use(orderBuilder) { use(order, client) {
const { xmlOptions, xmlSchema } = genericSerializer(orderBuilder); const keys = client.keys();
const { const { orderDetails, transactionId } = order;
ebicsData, orderDetails, keys, productString, const { xmlOptions, xmlSchema, productString } = genericSerializer(client.host, transactionId);
} = orderBuilder;
const orderType = orderDetails.OrderType.toUpperCase(); const orderType = orderDetails.OrderType.toUpperCase();
const ebicsAccount = {
partnerId: client.partnerId,
userId: client.userId,
hostId: client.hostId,
};
this.rootName = process[orderType].rootName; this.rootName = process[orderType].rootName;
this.xmlOptions = xmlOptions; this.xmlOptions = xmlOptions;
this.xmlSchema = xmlSchema; this.xmlSchema = xmlSchema;
this.xmlSchema.header = process[orderType].header(ebicsData, orderDetails, productString); this.xmlSchema.header = process[orderType].header(ebicsAccount, orderDetails, productString);
this.xmlSchema.body = process[orderType].body(ebicsData, keys, this.xmlOptions); this.xmlSchema.body = process[orderType].body(ebicsAccount, keys, this.xmlOptions);
if (orderType !== 'HPB' && Object.prototype.hasOwnProperty.call(this.xmlSchema, 'AuthSignature')) if (orderType !== 'HPB' && Object.prototype.hasOwnProperty.call(this.xmlSchema, 'AuthSignature'))
delete this.xmlSchema.AuthSignature; delete this.xmlSchema.AuthSignature;

View File

@ -9,12 +9,14 @@ const Crypto = require('../../../crypto/Crypto');
const downloadSerializer = require('./download'); const downloadSerializer = require('./download');
const transKey = crypto.randomBytes(16);
const signatureValue = (document, key) => { const signatureValue = (document, key) => {
const digested = Crypto.digestWithHash(document.replace(/\n|\r/g, '')); const digested = Crypto.digestWithHash(document.replace(/\n|\r/g, ''));
return Crypto.sign(key, digested); return Crypto.sign(key, digested);
}; };
const orderSignature = (ebicsData, document, key, xmlOptions) => { const orderSignature = (ebicsAccount, document, key, xmlOptions) => {
const xmlObj = { const xmlObj = {
'@': { '@': {
xmlns: 'http://www.ebics.org/S001', xmlns: 'http://www.ebics.org/S001',
@ -24,15 +26,15 @@ const orderSignature = (ebicsData, document, key, xmlOptions) => {
OrderSignatureData: { OrderSignatureData: {
SignatureVersion: 'A006', SignatureVersion: 'A006',
SignatureValue: signatureValue(document, key), SignatureValue: signatureValue(document, key),
PartnerID: ebicsData.partnerId, PartnerID: ebicsAccount.partnerId,
UserID: ebicsData.userId, UserID: ebicsAccount.userId,
}, },
}; };
return js2xmlparser.parse('UserSignatureData', xmlObj, xmlOptions); return js2xmlparser.parse('UserSignatureData', xmlObj, xmlOptions);
}; };
const encryptedOrderSignature = (ebicsData, document, transactionKey, key, xmlOptions) => { const encryptedOrderSignature = (ebicsAccount, document, transactionKey, key, xmlOptions) => {
const dst = zlib.deflateSync(orderSignature(ebicsData, document, key, xmlOptions)); const dst = zlib.deflateSync(orderSignature(ebicsAccount, document, key, xmlOptions));
const cipher = crypto.createCipheriv('aes-128-cbc', transactionKey, Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])).setAutoPadding(false); const cipher = crypto.createCipheriv('aes-128-cbc', transactionKey, Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])).setAutoPadding(false);
return Buffer.concat([cipher.update(Crypto.pad(dst)), cipher.final()]).toString('base64'); return Buffer.concat([cipher.update(Crypto.pad(dst)), cipher.final()]).toString('base64');
@ -45,23 +47,28 @@ const encryptedOrderData = (document, transactionKey) => {
}; };
module.exports = { module.exports = {
use(orderBuilder) { use(order, client) {
const keys = client.keys();
const ebicsAccount = {
partnerId: client.partnerId,
userId: client.userId,
hostId: client.hostId,
};
const { const {
ebicsData, keys, transactionId, transactionKey, document, transactionId, document,
} = orderBuilder; } = order;
const { const {
rootName, xmlOptions, xmlSchema, transfer, rootName, xmlOptions, xmlSchema, transfer,
} = downloadSerializer.use(orderBuilder); } = downloadSerializer.use(order, client);
this.rootName = rootName; this.rootName = rootName;
this.xmlOptions = xmlOptions; this.xmlOptions = xmlOptions;
this.xmlSchema = xmlSchema; this.xmlSchema = xmlSchema;
this.transfer = transfer; this.transfer = transfer;
if (transactionId) return this.transfer(encryptedOrderData(document, transactionKey)); if (transactionId) return this.transfer(encryptedOrderData(document, transKey));
this.xmlSchema.header.static.NumSegments = 1; this.xmlSchema.header.static.NumSegments = 1;
this.xmlSchema.body = { this.xmlSchema.body = {
DataTransfer: { DataTransfer: {
DataEncryptionInfo: { DataEncryptionInfo: {
@ -70,11 +77,11 @@ module.exports = {
'@': { Version: 'E002', Algorithm: 'http://www.w3.org/2001/04/xmlenc#sha256' }, '@': { Version: 'E002', Algorithm: 'http://www.w3.org/2001/04/xmlenc#sha256' },
'#': Crypto.digestPublicKey(keys.bankE()), '#': Crypto.digestPublicKey(keys.bankE()),
}, },
TransactionKey: Crypto.publicEncrypt(keys.bankE(), transactionKey).toString('base64'), TransactionKey: Crypto.publicEncrypt(keys.bankE(), transKey).toString('base64'),
}, },
SignatureData: { SignatureData: {
'@': { authenticate: true }, '@': { authenticate: true },
'#': encryptedOrderSignature(ebicsData, document, transactionKey, keys.a(), this.xmlOptions), '#': encryptedOrderSignature(ebicsAccount, document, transKey, keys.a(), this.xmlOptions),
}, },
}, },
}; };

View File

@ -41,8 +41,7 @@ const sign = (doc, key) => {
const toXML = doc => new XMLSerializer().serializeToString(doc); const toXML = doc => new XMLSerializer().serializeToString(doc);
module.exports = { module.exports = {
sign(data, keys) { sign(data, keyX) {
const keyX = keys.x();
const doc = new DOMParser().parseFromString(data, 'text/xml'); const doc = new DOMParser().parseFromString(data, 'text/xml');
return toXML(sign(digest(doc), keyX)); return toXML(sign(digest(doc), keyX));

View File

@ -1,35 +0,0 @@
'use strict';
const orders = {
H004: {
ini: ['INI', 'HIA', 'HPB'],
download: ['HAA', 'HTD', 'XTD', 'HPD', 'HKD', 'PTK', 'HAC', 'STA', 'VMK', 'C52', 'C53', 'C54', 'Z01'],
upload: ['AZV', 'CD1', 'CDB', 'CDD', 'CDS', 'CCT', 'CCS', 'XE3'],
},
};
module.exports = {
version(v) {
this.orders = orders[v.toUpperCase()];
return this;
},
isIni(orderType) {
const { ini } = this.orders;
return ini.includes(orderType.toUpperCase());
},
isDownload(orderType) {
const { download } = this.orders;
return download.includes(orderType.toUpperCase());
},
isUpload(orderType) {
const { upload } = this.orders;
return upload.includes(orderType.toUpperCase());
},
};

View File

@ -7,12 +7,13 @@ module.exports = (pathToFile) => {
return { return {
read() { read() {
if (!fs.existsSync(path))
return null;
return fs.readFileSync(path, { encoding: 'utf8' }); return fs.readFileSync(path, { encoding: 'utf8' });
}, },
save(data) { write(data) {
fs.writeFileSync(path, data, { encoding: 'utf8' }); fs.writeFileSync(path, data, { encoding: 'utf8' });
return this; return this;
}, },