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,18 +1,18 @@
'use strict';
const orders = require('../orders');
const constants = require('../../consts');
const iniSerializer = require('./serializers/ini');
const downloadSerializer = require('./serializers/download');
const uploadSerializer = require('./serializers/upload');
module.exports = {
use(order) {
const { version, orderType } = order;
use(order, client) {
const operation = order.operation.toUpperCase();
if (orders.version(version).isIni(orderType)) return iniSerializer.use(order);
if (orders.version(version).isDownload(orderType)) return downloadSerializer.use(order);
if (orders.version(version).isUpload(orderType)) return uploadSerializer.use(order);
if (operation === constants.orderOperations.ini) return iniSerializer.use(order, client);
if (operation === constants.orderOperations.download) return downloadSerializer.use(order, client);
if (operation === constants.orderOperations.upload) return uploadSerializer.use(order, client);
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');
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 {
ebicsData, orderDetails, keys, productString, transactionId,
} = orderBuilder;
const {
rootName, xmlOptions, xmlSchema, receipt, transfer,
} = genericSerializer(orderBuilder);
rootName, xmlOptions, xmlSchema, receipt, transfer, productString,
} = genericSerializer(client.hostId, transactionId);
this.productString = productString;
this.rootName = rootName;
this.xmlOptions = xmlOptions;
this.xmlSchema = xmlSchema;
@@ -26,11 +31,11 @@ module.exports = {
this.xmlSchema.header = {
'@': { authenticate: true },
static: {
HostID: ebicsData.hostId,
HostID: ebicsAccount.hostId,
Nonce: Crypto.nonce(),
Timestamp: Crypto.timestamp(),
PartnerID: ebicsData.partnerId,
UserID: ebicsData.userId,
PartnerID: ebicsAccount.partnerId,
UserID: ebicsAccount.userId,
Product: {
'@': { Language: 'en' },
'#': productString,

View File

@@ -1,5 +1,7 @@
'use strict';
const constants = require('../../../consts');
const rootName = 'ebicsRequest';
const rootAttributes = {
'xmlns:ds': 'http://www.w3.org/2000/09/xmldsig#',
@@ -58,76 +60,75 @@ const xmlOptions = {
},
};
module.exports = (orderBuilder) => {
const { ebicsData, transactionId } = orderBuilder;
module.exports = (hostId, transactionId) => ({
// return {
productString: constants.productString,
rootName,
xmlOptions,
xmlSchema: {
'@': rootAttributes,
header,
AuthSignature: authSignature,
body,
},
return {
rootName,
xmlOptions,
xmlSchema: {
receipt() {
this.xmlSchema = {
'@': rootAttributes,
header,
header: {
'@': { authenticate: true },
static: {
HostID: hostId,
TransactionID: transactionId,
},
mutable: {
TransactionPhase: 'Receipt',
},
},
AuthSignature: authSignature,
body,
},
receipt() {
this.xmlSchema = {
'@': rootAttributes,
header: {
body: {
TransferReceipt: {
'@': { authenticate: true },
static: {
HostID: ebicsData.hostId,
TransactionID: transactionId,
},
mutable: {
TransactionPhase: 'Receipt',
ReceiptCode: 0,
},
},
};
return this;
},
transfer(encryptedOrderData) {
this.xmlSchema = {
'@': rootAttributes,
header: {
'@': { authenticate: true },
static: {
HostID: hostId,
TransactionID: transactionId,
},
mutable: {
TransactionPhase: 'Transfer',
SegmentNumber: {
'@': { lastSegment: true },
'#': 1,
},
},
},
AuthSignature: authSignature,
AuthSignature: authSignature,
body: {
TransferReceipt: {
'@': { authenticate: true },
ReceiptCode: 0,
},
body: {
DataTransfer: {
OrderData: encryptedOrderData,
},
};
},
};
return this;
},
transfer(encryptedOrderData) {
this.xmlSchema = {
'@': rootAttributes,
header: {
'@': { authenticate: true },
static: {
HostID: ebicsData.hostId,
TransactionID: transactionId,
},
mutable: {
TransactionPhase: 'Transfer',
SegmentNumber: {
'@': { lastSegment: true },
'#': 1,
},
},
},
AuthSignature: authSignature,
body: {
DataTransfer: {
OrderData: encryptedOrderData,
},
},
};
return this;
},
};
};
return this;
},
// };
});

View File

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

View File

@@ -9,12 +9,14 @@ const Crypto = require('../../../crypto/Crypto');
const downloadSerializer = require('./download');
const transKey = crypto.randomBytes(16);
const signatureValue = (document, key) => {
const digested = Crypto.digestWithHash(document.replace(/\n|\r/g, ''));
return Crypto.sign(key, digested);
};
const orderSignature = (ebicsData, document, key, xmlOptions) => {
const orderSignature = (ebicsAccount, document, key, xmlOptions) => {
const xmlObj = {
'@': {
xmlns: 'http://www.ebics.org/S001',
@@ -24,15 +26,15 @@ const orderSignature = (ebicsData, document, key, xmlOptions) => {
OrderSignatureData: {
SignatureVersion: 'A006',
SignatureValue: signatureValue(document, key),
PartnerID: ebicsData.partnerId,
UserID: ebicsData.userId,
PartnerID: ebicsAccount.partnerId,
UserID: ebicsAccount.userId,
},
};
return js2xmlparser.parse('UserSignatureData', xmlObj, xmlOptions);
};
const encryptedOrderSignature = (ebicsData, document, transactionKey, key, xmlOptions) => {
const dst = zlib.deflateSync(orderSignature(ebicsData, document, key, xmlOptions));
const encryptedOrderSignature = (ebicsAccount, document, transactionKey, 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);
return Buffer.concat([cipher.update(Crypto.pad(dst)), cipher.final()]).toString('base64');
@@ -45,23 +47,28 @@ const encryptedOrderData = (document, transactionKey) => {
};
module.exports = {
use(orderBuilder) {
use(order, client) {
const keys = client.keys();
const ebicsAccount = {
partnerId: client.partnerId,
userId: client.userId,
hostId: client.hostId,
};
const {
ebicsData, keys, transactionId, transactionKey, document,
} = orderBuilder;
transactionId, document,
} = order;
const {
rootName, xmlOptions, xmlSchema, transfer,
} = downloadSerializer.use(orderBuilder);
} = downloadSerializer.use(order, client);
this.rootName = rootName;
this.xmlOptions = xmlOptions;
this.xmlSchema = xmlSchema;
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.body = {
DataTransfer: {
DataEncryptionInfo: {
@@ -70,11 +77,11 @@ module.exports = {
'@': { Version: 'E002', Algorithm: 'http://www.w3.org/2001/04/xmlenc#sha256' },
'#': Crypto.digestPublicKey(keys.bankE()),
},
TransactionKey: Crypto.publicEncrypt(keys.bankE(), transactionKey).toString('base64'),
TransactionKey: Crypto.publicEncrypt(keys.bankE(), transKey).toString('base64'),
},
SignatureData: {
'@': { 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);
module.exports = {
sign(data, keys) {
const keyX = keys.x();
sign(data, keyX) {
const doc = new DOMParser().parseFromString(data, 'text/xml');
return toXML(sign(digest(doc), keyX));