29 Commits

Author SHA1 Message Date
Vladislav Hristov
0049fffc00 up the version to 0.0.8 2019-10-08 16:10:08 +03:00
Vladislav Hristov
2c9040904a chore: remove console.log statements 2019-10-08 16:09:08 +03:00
Dimitar Nanov
0f6dcf9eb2 Merge pull request #11 from yagop/fix-version
chore: readme maintenance
2019-10-03 09:32:17 +03:00
nanov
ca31edf245 chore: add yagop to contributors 2019-10-03 09:30:49 +03:00
nanov
4464349d0f chore: remove version from readme 2019-10-03 09:29:35 +03:00
Dimitar Nanov
15546df9ea Merge pull request #10 from yagop/examples
Provide examples
2019-10-03 09:20:29 +03:00
Yago Perez
40467a2c5e v0.0.35 -> v0.0.7 2019-10-03 00:20:36 +02:00
Yago Perez
eb9fbf5834 Change HBT order text 2019-10-03 00:10:52 +02:00
Yago Perez
166c61aec4 examples/send-hbt-order.js 2019-10-02 23:58:37 +02:00
Yago Perez
5a63e19aab examples/save-bank-kesy.js 2019-10-02 23:58:35 +02:00
Yago Perez
9e6c318372 keys -> passphrase 2019-10-02 23:58:33 +02:00
Yago Perez
ce6e58b3f3 examples/bankLetter.js 2019-10-02 23:58:29 +02:00
Yago Perez
7dad7c8787 initialize.js 2019-10-02 23:56:51 +02:00
Dimitar Nanov
79f17e1404 bump version 2019-08-02 10:52:48 +03:00
Dimitar Nanov
3ef32c8ce5 Merge pull request #7 from anandsahil/addCAMT53OrderType
* Add Z53 order type
* Create utils container and move dateRange functionality to there
2019-08-01 16:59:25 +03:00
anandsahil
aa761cf7ad move dateRange from constants to utils 2019-08-01 14:14:30 +02:00
anandsahil
5ff3147124 add new order type XZ53 and removed repeated dateRange to consts 2019-08-01 14:00:07 +02:00
anandsahil
01d4634d86 Merge remote-tracking branch 'src/master' 2019-08-01 13:52:51 +02:00
sahil anand
89904afa63 Merge pull request #2 from anandsahil/minorChanges
remove eCollect from constant and minor verbose error handeling
2019-07-25 17:40:29 +02:00
sahil anand
4907524259 Merge pull request #1 from anandsahil/and-XCT-order-type
add iso pain format XCT order type
2019-07-25 17:40:04 +02:00
Dimitar Nanov
c9f52d3bd9 bump 2019-07-24 09:12:06 +03:00
Dimitar Nanov
f5b05ae491 Merge pull request #4 from anandsahil/minorChanges
remove eCollect from constant and minor verbose error handaling
2019-07-24 09:05:14 +03:00
Dimitar Nanov
9f88b048d7 Merge pull request #5 from anandsahil/and-XCT-order-type
add iso pain format XCT order type
2019-07-24 09:04:22 +03:00
anandsahil
d06e92c51c add iso pain format XCT order type 2019-07-22 17:36:38 +02:00
anandsahil
cb2062ae2f remove eCollect from constant and minor verbose error handeling 2019-07-22 17:31:24 +02:00
Dimitar Nanov
07a48e9cc5 0.0.5 2019-06-28 17:12:49 +03:00
Dimitar Nanov
800002701d Merge pull request #3 from vasyas/master
Fix parsing of the bank keys in the HPB response
2019-06-28 17:09:49 +03:00
vasyas
5f0b6cd374 #2 corrected bank keys parsing 2019-06-27 00:13:44 +03:00
vasyas
c571ef181b tc for bank keys parsing error 2019-06-27 00:10:53 +03:00
21 changed files with 239 additions and 62 deletions

View File

@@ -1,7 +1,8 @@
{
"extends": "airbnb-base",
"env": {
"node": true
"node": true,
"mocha": true
},
"parserOptions": {
"ecmaVersion": 8,

View File

@@ -1,4 +1,4 @@
# node-ebics-client v0.0.35
# node-ebics-client
---
Pure node.js ( >=8 ) implementation of [EBICS](https://en.wikipedia.org/wiki/Electronic_Banking_Internet_Communication_Standard) ( Electronic Banking Internet Communication ).
@@ -21,4 +21,4 @@ The basic concept of this library was inspired by the [EPICS](https://github.com
## Copyright
Copyright: eCollect AG, 2018.
Copyright: eCollect AG, 2018-9.

31
examples/bankLetter.js Executable file
View File

@@ -0,0 +1,31 @@
#! /usr/bin/env node
'use strict';
const ebics = require('../index');
const path = require('path');
const fs = require('fs');
const os = require('os');
const client = new ebics.Client({
url: 'https://ebics.server',
partnerId: '',
userId: '',
hostId: '',
passphrase: 'test', // keys-test will be decrypted with this passphrase
keyStorage: ebics.fsKeysStorage('./keys-test'),
});
const bankName = 'Bank name';
const template = fs.readFileSync('./templates/ini.hbs').toString();
const letter = new ebics.BankLetter({ client, bankName, template });
const bankLetterFile = path.join(os.homedir(), 'bankLetter.html');
letter.serialize(bankLetterFile)
.then(() => {
console.log('Send your bank the letter (%s)', bankLetterFile);
})
.catch((err) => {
console.error(err);
process.exit(1);
});

32
examples/initialize.js Executable file
View File

@@ -0,0 +1,32 @@
#! /usr/bin/env node
'use strict';
const ebics = require('../index');
const client = new ebics.Client({
url: 'https://ebics.server',
partnerId: 'PARTNER',
userId: 'USER',
hostId: 'HOST',
passphrase: 'test', // keys-test will be encrypted with this passphrase
keyStorage: ebics.fsKeysStorage('./keys-test'),
});
// New keys will be generated and saved in ./keys-test
client.send(ebics.Orders.INI)
.then((resp) => {
console.log('Respose for INI order %j', resp);
return client.send(ebics.Orders.HIA);
})
.then((resp) => {
console.log('Reponse for HIA order %j', resp);
if (resp.technicalCode !== '000000')
throw new Error('Something might went wrong');
console.log('Public keys should be sent to bank now. See examples/bankLetter.js');
})
.catch((err) => {
console.error(err);
process.exit(1);
});

30
examples/save-bank-kesy.js Executable file
View File

@@ -0,0 +1,30 @@
#! /usr/bin/env node
'use strict';
const ebics = require('../index');
const client = new ebics.Client({
url: 'https://ebics.server',
partnerId: '',
userId: '',
hostId: '',
passphrase: 'test', // keys-test will be decrypted with this passphrase
keyStorage: ebics.fsKeysStorage('./keys-test'),
});
// Client keys must be already generated and send by letter.
// The bank should have enabled the user
client.send(ebics.Orders.HPB)
.then((resp) => {
console.log('Respose for HPB order %j', resp);
if (resp.technicalCode !== '000000')
throw new Error('Something went wrong');
console.log('Received bank keys: %j', resp.bankKeys);
return client.setBankKeys(resp.bankKeys);
})
.catch((err) => {
console.error(err);
process.exit(1);
});

29
examples/send-hbt-order.js Executable file
View File

@@ -0,0 +1,29 @@
#! /usr/bin/env node
'use strict';
const ebics = require('../index');
const client = new ebics.Client({
url: 'https://ebics.server',
partnerId: '',
userId: '',
hostId: '',
passphrase: 'test', // keys-test will be decrypted with this passphrase
keyStorage: ebics.fsKeysStorage('./keys-test'),
});
// The bank keys must have been already saved
client.send(ebics.Orders.HTD)
.then((resp) => {
console.log('Respose for HTD order %j', resp);
if (resp.technicalCode !== '000000')
throw new Error('Something went wrong');
const data = Buffer.from(resp.orderData);
console.log(data.toString('utf8'));
})
.catch((err) => {
console.error(err);
process.exit(1);
});

View File

@@ -63,11 +63,10 @@ module.exports = class BankLetter {
try {
fs.writeFileSync(path, letter);
console.log('Data written to file');
} catch (error) {
console.log(error);
throw error;
}
return new Promise(resolve => resolve(true));
}
};

View File

@@ -42,7 +42,7 @@ module.exports = class Client {
throw new Error('passphrase is requierd');
if (!keyStorage || typeof keyStorage.read !== 'function' || typeof keyStorage.write !== 'function')
throw new Error('keyStorage implemntation missing or wrong');
throw new Error('keyStorage implementation missing or wrong');
this.url = url;
this.partnerId = partnerId;

View File

@@ -2,7 +2,7 @@
const packageJson = require('../package.json');
const name = 'eCollect Node Ebics Client';
const name = 'Node Ebics Client';
const { version } = packageJson;
const orderOperations = {
ini: 'INI',

View File

@@ -124,8 +124,8 @@ module.exports = (xml, keys) => ({
for (let i = 0; i < keyNodes.length; i++) {
const type = lastChild(keyNodes[i].parentNode).textContent;
const modulus = xpath.select("//*[local-name(.)='Modulus']", keyNodes[i])[0].textContent;
const exponent = xpath.select("//*[local-name(.)='Exponent']", keyNodes[i])[0].textContent;
const modulus = xpath.select(".//*[local-name(.)='Modulus']", keyNodes[i])[0].textContent;
const exponent = xpath.select(".//*[local-name(.)='Exponent']", keyNodes[i])[0].textContent;
const mod = new BN(Buffer.from(modulus, 'base64'), 2).toBuffer();
const exp = new BN(Buffer.from(exponent, 'base64')).toNumber();

View File

@@ -1,23 +1,13 @@
'use strict';
const dateRange = (start, end) => {
if (start && end)
return {
DateRange: {
Start: start,
End: end,
},
};
return {};
};
const utils = require('../utils');
module.exports = (start = null, end = null) => ({
version: 'h004',
orderDetails: {
OrderType: 'HAC',
OrderAttribute: 'DZHNN',
StandardOrderParams: dateRange(start, end),
StandardOrderParams: utils.dateRange(start, end),
},
operation: 'download',
});

View File

@@ -1,23 +1,13 @@
'use strict';
const dateRange = (start, end) => {
if (start && end)
return {
DateRange: {
Start: start,
End: end,
},
};
return {};
};
const utils = require('../utils');
module.exports = (start = null, end = null) => ({
version: 'h004',
orderDetails: {
OrderType: 'PTK',
OrderAttribute: 'DZHNN',
StandardOrderParams: dateRange(start, end),
StandardOrderParams: utils.dateRange(start, end),
},
operation: 'download',
});

View File

@@ -1,23 +1,13 @@
'use strict';
const dateRange = (start, end) => {
if (start && end)
return {
DateRange: {
Start: start,
End: end,
},
};
return {};
};
const utils = require('../utils');
module.exports = (start = null, end = null) => ({
version: 'h004',
orderDetails: {
OrderType: 'STA',
OrderAttribute: 'DZHNN',
StandardOrderParams: dateRange(start, end),
StandardOrderParams: utils.dateRange(start, end),
},
operation: 'download',
});

View File

@@ -1,23 +1,13 @@
'use strict';
const dateRange = (start, end) => {
if (start && end)
return {
DateRange: {
Start: start,
End: end,
},
};
return {};
};
const utils = require('../utils');
module.exports = (start = null, end = null) => ({
version: 'h004',
orderDetails: {
OrderType: 'VMK',
OrderAttribute: 'DZHNN',
StandardOrderParams: dateRange(start, end),
StandardOrderParams: utils.dateRange(start, end),
},
operation: 'download',
});

View File

@@ -0,0 +1,8 @@
'use strict';
module.exports = document => ({
version: 'h004',
orderDetails: { OrderType: 'XCT', OrderAttribute: 'OZHNN', StandardOrderParams: {} },
operation: 'upload',
document,
});

View File

@@ -0,0 +1,13 @@
'use strict';
const utils = require('../utils');
module.exports = (start = null, end = null) => ({
version: 'h004',
orderDetails: {
OrderType: 'Z53',
OrderAttribute: 'DZHNN',
StandardOrderParams: utils.dateRange(start, end),
},
operation: 'download',
});

View File

@@ -12,6 +12,7 @@ const CDS = require('./CDS');
const CCT = require('./CCT');
const CCS = require('./CCS');
const XE3 = require('./XE3');
const XCT = require('./XCT');
const STA = require('./STA');
const VMK = require('./VMK');
@@ -21,11 +22,13 @@ const HPD = require('./HPD');
const HKD = require('./HKD');
const PTK = require('./PTK');
const HAC = require('./HAC');
const Z53 = require('./Z53');
module.exports = {
INI,
HIA,
HPB,
Z53,
AZV,
CD1,
@@ -35,7 +38,7 @@ module.exports = {
CCT,
CCS,
XE3,
XCT,
STA,
VMK,
HAA,

View File

@@ -58,9 +58,7 @@ module.exports = dir => ({
try {
fs.writeFileSync(path, this.traceData);
console.log("Data written to file");
} catch (error) {
console.log(error);
throw error;
}
},

18
lib/utils.js Normal file
View File

@@ -0,0 +1,18 @@
'use strict';
const dateRange = (start, end) => {
if (start && end)
return {
DateRange: {
Start: start,
End: end,
},
};
return {};
};
module.exports = {
dateRange,
};

View File

@@ -1,6 +1,6 @@
{
"name": "ebics-client",
"version": "0.0.4",
"version": "0.0.8",
"description": "Node.js ISO 20022 Compliant EBICS Client",
"main": "index.js",
"scripts": {
@@ -17,6 +17,16 @@
"api"
],
"author": "eCollect Sofia Tech Team",
"contributors": [
{
"name": "Vasyl Stashuk",
"url": "https://github.com/vasyas"
},
{
"name": "Yago",
"url": "https://github.com/yagop"
}
],
"license": "MIT",
"dependencies": {
"bn.js": "^4.11.8",
@@ -31,8 +41,10 @@
"xpath": "0.0.27"
},
"devDependencies": {
"chai": "^4.2.0",
"eslint": "^4.19.1",
"eslint-config-airbnb-base": "^12.1.0",
"eslint-plugin-import": "^2.12.0"
"eslint-plugin-import": "^2.12.0",
"mocha": "^6.1.4"
}
}

43
test/responseParser.js Normal file
View File

@@ -0,0 +1,43 @@
'use strict';
const { assert } = require('chai');
const H004Response = require('../lib/orders/H004/response');
describe('H004 response parsing', () => {
it('parses bank keys', () => {
const response = H004Response('<xml/>', {});
const x002mod = 'ntbX6WFjAJP5RyH4ogDG/26wZGzEJXsTudyvcgXmUdk1AExCNqArXDiSlGXpVNq4BKddUMFUmVOyvkdNckPRV2mk3uHNCE5T3tFKQI3FlwHSJHvPSpb9gtHnsK03jByMigWjhTKvsjIdfLVay5m5Bctxq9+5JMHwlNk7MlVXBQcqaFiHFFS1lPfA3Wk1bptPeeGyYcP0+U798oQWnCABKwS8hmYcp5xBtozGoRj9L/NDE68pdP8o/wTKNwT4Jo5nQKYfDsgO4R+z9vVv37Htp6bWhK8Jw3tpkcd3JnkYWx+Ylg0XBpg8LfjFhY2Jc7FqLlx0Bn0Y3PRLI1apxgC85w==';
const e002mod = '4eOGrzcJHVzbEgZTmyPYUIq9kFoua8Ure1Mvyq6XlawFgCWskfu/xSKNLIMJ7H675wl/5y0Oy16P/b6pJEhWrzOw8omW46PBDTaXw9BDYBTuBblluz1yUnzpgfblP8gkRmxAo+QMIskmwdSzuZMiJcLNSzu/bkmLHK2RdrVYMAZLlB6QXTykdenPZtNmc2z4VU6TRmGljAwg2VUNF6iQoucbzDUuca+yUo3fiXZp69nfXv81X2ND+p1ir6zQpx7tbOdfauw0sEKI/Z/lC+E4fMrMlh/ZvOxSYUMA55J4liC3aUV3mTR3dPJHWu1aD1a7EfJnNw0eHLwlB+36qfgGuw==';
response.orderData = () => `<?xml version="1.0" encoding="UTF-8"?>
<HPBResponseOrderData xmlns="urn:org:ebics:H004" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<AuthenticationPubKeyInfo>
<PubKeyValue>
<ds:RSAKeyValue>
<ds:Modulus>${x002mod}</ds:Modulus>
<ds:Exponent>AQAB</ds:Exponent>
</ds:RSAKeyValue>
<TimeStamp>2015-02-25T08:01:13.061Z</TimeStamp>
</PubKeyValue>
<AuthenticationVersion>X002</AuthenticationVersion>
</AuthenticationPubKeyInfo>
<EncryptionPubKeyInfo>
<PubKeyValue>
<ds:RSAKeyValue>
<ds:Modulus>${e002mod}</ds:Modulus>
<ds:Exponent>AQAB</ds:Exponent>
</ds:RSAKeyValue>
<TimeStamp>2015-02-25T08:01:12.344Z</TimeStamp>
</PubKeyValue>
<EncryptionVersion>E002</EncryptionVersion>
</EncryptionPubKeyInfo>
<HostID>SBKPR01</HostID>
</HPBResponseOrderData>`;
const bankKeys = response.bankKeys();
assert.equal(bankKeys.bankX002.mod.toString('base64'), x002mod);
assert.equal(bankKeys.bankE002.mod.toString('base64'), e002mod);
});
});