26 Commits

Author SHA1 Message Date
nanov
d482b1dde1 chore: update readme 2019-11-07 11:53:09 +02:00
nanov
ecf51680c5 chore: add logo 2019-11-07 11:49:22 +02:00
nanov
9a748fa2bc chore: changelog and files settings 2019-11-07 11:42:37 +02:00
nanov
7355096dfd v0.1.2 2019-11-07 11:37:34 +02:00
nanov
25eedd5071 chore: update package.json 2019-11-07 11:36:04 +02:00
Dimitar Nanov
4182e7956a Merge pull request #22 from eCollect/release-it
chore: add changelog configoration
2019-11-07 11:35:34 +02:00
nanov
fee2aa4681 chore: add version script 2019-11-07 11:35:11 +02:00
nanov
1f34dcbfb6 add changelog configoration 2019-11-07 11:20:34 +02:00
nanov
3a64d95eb5 chore: add tags 2019-11-07 10:58:38 +02:00
Dimitar Nanov
926d1bca18 Merge pull request #21 from eCollect/feat/drop-bn.js
Closes #17 and #13
2019-11-07 10:52:01 +02:00
nanov
6d601f4186 chore: fix package json syntax 2019-11-07 10:42:11 +02:00
nanov
2d05bf88f9 chore: add contributors to package json 2019-11-07 10:41:43 +02:00
nanov
10e0d602bd chore: update license expression in package.json 2019-11-07 10:38:01 +02:00
nanov
eea0a49130 feat: drop bn.js 2019-11-07 10:37:31 +02:00
nanov
3e95478b3b feat: add nyc and cleanup .gitignore 2019-11-07 10:35:31 +02:00
nanov
4496cbf560 feat: remove toBuffer from number 2019-11-07 10:30:03 +02:00
nanov
0efc46b014 feat add BigNumber tests 2019-11-07 10:27:20 +02:00
nanov
eafe2f9f55 chore: restructure BigNumber 2019-11-07 10:27:08 +02:00
nanov
24afdeb257 chroe: import consts 2019-11-07 10:26:53 +02:00
nanov
34051f0a9f feat: migrate Crypto to own BigNumber 2019-11-07 08:58:52 +02:00
nanov
14779088f1 chore: lint 2019-11-07 08:57:54 +02:00
nanov
aad0bd97c8 feat: implement all needed BigNumber methods 2019-11-07 08:57:44 +02:00
nanov
429e807994 fix number generarion 2019-11-06 17:27:48 +02:00
nanov
bb8d1cfaa0 wip: migrate MFG1 to BigNumber 2019-11-06 17:16:56 +02:00
nanov
cda36bfcb3 wip: implement BigNumber wrapper 2019-11-06 17:16:15 +02:00
Dimitar Nanov
d21d89fb36 Merge pull request #20 from eCollect/feat/drop-moment
Drop moment dependency
2019-11-06 16:55:15 +02:00
13 changed files with 4114 additions and 34 deletions

26
.gitignore vendored
View File

@@ -1,13 +1,19 @@
npm-debug.log
node_modules
# mac shit
.DS_Store
*.local.json5
yarn.lock
/project.sublime-workspace
/public/css/style.css.map
/.idea
# nyc test coverage
.nyc_output
# Dependency directories
node_modules/
# Optional npm cache directory
.npm
npm-debug.log
# Optional eslint cache
.eslintcache
# vscode
/.vscode
*.pid
/coverage
package-lock.json
*.html

101
CHANGELOG.md Normal file
View File

@@ -0,0 +1,101 @@
### Changelog
#### [v0.1.2](https://github.com/eCollect/node-ebics-client/compare/v0.1.1...v0.1.2)
> 7 November 2019
- chore: add changelog configoration [`#22`](https://github.com/eCollect/node-ebics-client/pull/22)
- Closes #17 and #13 [`#21`](https://github.com/eCollect/node-ebics-client/pull/21)
- Drop moment dependency [`#20`](https://github.com/eCollect/node-ebics-client/pull/20)
- feat: add nyc and cleanup .gitignore [`3e95478`](https://github.com/eCollect/node-ebics-client/commit/3e95478b3be719c86f32c7df10c42e46b7518669)
- feat: drop bn.js [`eea0a49`](https://github.com/eCollect/node-ebics-client/commit/eea0a49130e30c123b110120c69d7b7c19fd12ba)
- add changelog configoration [`1f34dcb`](https://github.com/eCollect/node-ebics-client/commit/1f34dcbfb6e0febbb93d5356fa36ac57d697a990)
#### [v0.1.1](https://github.com/eCollect/node-ebics-client/compare/v0.1.0...v0.1.1)
> 5 November 2019
- chore: update license [`9aabe93`](https://github.com/eCollect/node-ebics-client/commit/9aabe933e91b506ea38820b952ce8e5e58b4c2ff)
#### [v0.1.0](https://github.com/eCollect/node-ebics-client/compare/v0.0.8...v0.1.0)
> 5 November 2019
- Feat: handle unsual exponent migrate to node-forge [`#16`](https://github.com/eCollect/node-ebics-client/pull/16)
- Add order generation tests and fix linting [`#15`](https://github.com/eCollect/node-ebics-client/pull/15)
- test script run mocha [`#14`](https://github.com/eCollect/node-ebics-client/pull/14)
- feat: prepare order generation tests [`e40f79c`](https://github.com/eCollect/node-ebics-client/commit/e40f79cee68a194272c93f07e763175b213a77a1)
- chore: cleanup [`0c01420`](https://github.com/eCollect/node-ebics-client/commit/0c01420c1e14992a4169098ccd47cd196b899f06)
#### [v0.0.36](https://github.com/eCollect/node-ebics-client/compare/v0.0.35...v0.0.36)
> 1 June 2018
- various modular fixes [`8492d94`](https://github.com/eCollect/node-ebics-client/commit/8492d940542f61b17aa3a2da7de23f6539ffaad5)
#### [v0.0.35](https://github.com/eCollect/node-ebics-client/compare/v0.0.3...v0.0.35)
> 31 May 2018
- update License to GPL v3 [`babcf76`](https://github.com/eCollect/node-ebics-client/commit/babcf76b61af6eb737ab291a301e71bb84621820)
- Add MGF1.js file - mask generation utility class [`7e6e2ff`](https://github.com/eCollect/node-ebics-client/commit/7e6e2ff142688b0c453369fa7137b49e8b89cd81)
- Add sign, _emsaPSS and _modPowe methods in Key.js file [`5ace213`](https://github.com/eCollect/node-ebics-client/commit/5ace2137231af9a3563ab31fa0f70fbdf4b148cb)
#### [v0.0.8](https://github.com/eCollect/node-ebics-client/compare/v0.0.7...v0.0.8)
> 8 October 2019
- chore: readme maintenance [`#11`](https://github.com/eCollect/node-ebics-client/pull/11)
- Provide examples [`#10`](https://github.com/eCollect/node-ebics-client/pull/10)
- initialize.js [`7dad7c8`](https://github.com/eCollect/node-ebics-client/commit/7dad7c878722be94e03808cef3af38d34019c623)
- examples/bankLetter.js [`ce6e58b`](https://github.com/eCollect/node-ebics-client/commit/ce6e58b3f33017967e5b26fe15a2c435012b8af6)
- examples/send-hbt-order.js [`166c61a`](https://github.com/eCollect/node-ebics-client/commit/166c61aec4a247d923de82278271ec02cbef815f)
#### [v0.0.7](https://github.com/eCollect/node-ebics-client/compare/v0.0.6...v0.0.7)
> 2 August 2019
- * Add Z53 order type [`#7`](https://github.com/eCollect/node-ebics-client/pull/7)
- remove eCollect from constant and minor verbose error handeling [`#2`](https://github.com/eCollect/node-ebics-client/pull/2)
- add iso pain format XCT order type [`#1`](https://github.com/eCollect/node-ebics-client/pull/1)
- add new order type XZ53 and removed repeated dateRange to consts [`5ff3147`](https://github.com/eCollect/node-ebics-client/commit/5ff314712443c4c8465f46292b010cfedfed8c2e)
- move dateRange from constants to utils [`aa761cf`](https://github.com/eCollect/node-ebics-client/commit/aa761cf7ad87a271d6e6d9eed40e04eb4376f6c5)
- bump version [`79f17e1`](https://github.com/eCollect/node-ebics-client/commit/79f17e14045d121c9505eb3118967f5f88ae79e2)
#### [v0.0.6](https://github.com/eCollect/node-ebics-client/compare/v0.0.5...v0.0.6)
> 24 July 2019
- remove eCollect from constant and minor verbose error handaling [`#4`](https://github.com/eCollect/node-ebics-client/pull/4)
- add iso pain format XCT order type [`#5`](https://github.com/eCollect/node-ebics-client/pull/5)
- remove eCollect from constant and minor verbose error handeling [`cb2062a`](https://github.com/eCollect/node-ebics-client/commit/cb2062ae2fbd8e8881de26561efddad1f272e065)
- bump [`c9f52d3`](https://github.com/eCollect/node-ebics-client/commit/c9f52d3bd99b9f8761652365b217d9580fa34632)
#### [v0.0.5](https://github.com/eCollect/node-ebics-client/compare/v0.0.4...v0.0.5)
> 28 June 2019
- Fix parsing of the bank keys in the HPB response [`#3`](https://github.com/eCollect/node-ebics-client/pull/3)
- tc for bank keys parsing error [`c571ef1`](https://github.com/eCollect/node-ebics-client/commit/c571ef181bca2e0cbec70bc6df53c706acd6c829)
- #2 corrected bank keys parsing [`5f0b6cd`](https://github.com/eCollect/node-ebics-client/commit/5f0b6cd3747c4613920d2f71f3c04ce13225d397)
#### [v0.0.4](https://github.com/eCollect/node-ebics-client/compare/v0.0.36...v0.0.4)
> 3 September 2018
- Major changes. Separating responsibilities. Orders builder, serializer. [`ff9a3a1`](https://github.com/eCollect/node-ebics-client/commit/ff9a3a16b47d0a25674134c875bfd651995837e4)
- code optimization [`1876360`](https://github.com/eCollect/node-ebics-client/commit/187636019c290d757aca77d4c14fb4f2519acd38)
- client and order optimization [`9454992`](https://github.com/eCollect/node-ebics-client/commit/945499290a8698aed504b573019de2c23148006a)
#### v0.0.3
> 17 May 2018
- initial commit [`1f947ff`](https://github.com/eCollect/node-ebics-client/commit/1f947ff1480c522f89fa1f547581b55e2378d920)
- Initial commit [`cd37de3`](https://github.com/eCollect/node-ebics-client/commit/cd37de3895e32a61798c79ce3a6447e2f269019d)

View File

@@ -1,4 +1,8 @@
# node-ebics-client
<p align="center">
<img src="assets/logo.png" width="300px" height="auto"/>
</p>
<h1 align="center">node-ebics-client</h1>
<p align="center">
<a href="https://travis-ci.org/eCollect/node-ebics-client" title="Build Status"><img src="https://travis-ci.org/eCollect/node-ebics-client.svg?branch=master" alt="Build Status" /></a>
<a href="https://www.npmjs.com/package/ebics-client" title="Build Status">

BIN
assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

25
changelog-template.hbs Normal file
View File

@@ -0,0 +1,25 @@
### Changelog
{{#each releases}}
{{#if href}}
###{{#unless major}}#{{/unless}} [{{title}}]({{href}})
{{else}}
#### {{title}}
{{/if}}
{{#if tag}}
> {{niceDate}}
{{/if}}
{{#if summary}}
{{summary}}
{{/if}}
{{#each merges}}
- {{message}}{{#if href}} [`#{{id}}`]({{href}}){{/if}}
{{/each}}
{{#commit-list commits heading='' message='' exclude='wip: '}}
- {{#if breaking}}**Breaking change:** {{/if}}{{subject}}{{#if href}} [`{{shorthash}}`]({{href}}){{/if}}
{{/commit-list}}
{{/each}}

View File

@@ -5,7 +5,6 @@ const fs = require('fs');
const handlebars = require('handlebars');
const Crypto = require('./crypto/Crypto');
const { date } = require('./utils.js');
// const BN = require('bn.js');
const registerHelpers = () => {
handlebars.registerHelper('today', () => date.toISODate(Date.now(), false));

View File

@@ -1,9 +1,8 @@
'use strict';
const packageJson = require('../package.json');
const { version } = require('../package.json');
const name = 'Node Ebics Client';
const { version } = packageJson;
const orderOperations = {
ini: 'INI',
upload: 'UPLOAD',

66
lib/crypto/BigNumber.js Normal file
View File

@@ -0,0 +1,66 @@
'use strict';
const { jsbn: { BigInteger } } = require('node-forge');
class BigNumber {
constructor(value, radix = 10) {
if (value === null || value === undefined)
throw new Error('value is missing.');
this._n = new BigInteger(null);
if (value instanceof BigNumber)
this._n = value._n;
else if (value instanceof BigInteger)
this._n = value;
else if (typeof value === 'number')
this._n.fromInt(value);
else if (typeof value === 'string')
this._n.fromString(value, radix);
else if (Buffer.isBuffer(value))
this._n.fromString(value.toString('hex'), 16);
else if (Array.isArray(value))
this._n.fromString(Buffer.from(value).toString('hex'), 16);
else
throw new TypeError('Unsupported value type.');
}
toBEBuffer(length) {
const arr = this._n.toByteArray();
if (length === undefined)
return Buffer.from(arr);
if (arr.length > length)
throw new Error('Number out of range.');
while (arr.length < length)
arr.unshift(0);
return Buffer.from(arr);
}
toString(radix = 10) {
const result = this._n.toString(radix);
if (radix === 16)
return result.padStart(2, '0');
return result;
}
and(num) {
return new BigNumber(this._n.and(new BigNumber(num)._n));
}
mul(num) {
return new BigNumber(this._n.multiply(new BigNumber(num)._n));
}
mod(num) {
return new BigNumber(this._n.mod(new BigNumber(num)._n));
}
shrn(num) {
return new BigNumber(this._n.shiftRight(new BigNumber(num)._n));
}
}
module.exports = BigNumber;

View File

@@ -2,15 +2,14 @@
const crypto = require('crypto');
const BN = require('bn.js');
const BigNumber = require('./BigNumber.js');
const mgf1 = require('./MGF1');
const modPow = (base, power, mod) => {
let result = new BN(1);
let result = new BigNumber(1);
while (power > 0) {
result = power.and(new BN(1)) == 1 ? (result.mul(base)).mod(mod) : result; // eslint-disable-line
result = power.and(new BigNumber(1)) == 1 ? (result.mul(base)).mod(mod) : result; // eslint-disable-line
base = (base.mul(base)).mod(mod);
power = power.shrn(1);
}
@@ -28,10 +27,13 @@ const emsaPSS = (msg, salt) => {
const dbMask = mgf1.generate(mTickHash, db.length);
const maskedDb = mgf1.xor(db, dbMask);
let maskedDbMsb = mgf1.rjust(new BN(maskedDb.slice(0, 1), 2).toString(2), 8, '0');
let maskedDbMsb = mgf1.rjust(new BigNumber(maskedDb.slice(0, 1)).toString(2), 8, '0');
maskedDbMsb = `0${maskedDbMsb.substr(1)}`;
maskedDb[0] = (new BN(maskedDbMsb, 2).toBuffer())[0]; // eslint-disable-line
// console.log((new BN(maskedDbMsb, 2).toBuffer())[0], new BigNumber(maskedDbMsb, 2).toBuffer()[0]);
// maskedDb[0] = (new BN(maskedDbMsb, 2).toBuffer())[0]; // eslint-disable-line
maskedDb[0] = new BigNumber(maskedDbMsb, 2).toBEBuffer()[0]; // eslint-disable-line
return Buffer.concat([maskedDb, mTickHash, Buffer.from('BC', 'hex')]);
};
@@ -65,11 +67,12 @@ module.exports = class Crypto {
}
static sign(key, msg, salt = crypto.randomBytes(32)) {
const base = new BN(emsaPSS(msg, salt));
const power = new BN(key.d());
const mod = new BN(key.n());
// console.log(key.d());
const base = new BigNumber(emsaPSS(msg, salt));
const power = new BigNumber(key.d());
const mod = new BigNumber(key.n());
return (modPow(base, power, mod)).toBuffer().toString('base64');
return (modPow(base, power, mod)).toBEBuffer().toString('base64');
}
static pad(d) {

View File

@@ -1,13 +1,13 @@
'use strict';
const crypto = require('crypto');
const BN = require('bn.js');
const BigNumber = require('./BigNumber.js');
const MFG_LEN = 32;
const divceil = (a, b) => ~~(((a + b) - 1) / b); // eslint-disable-line no-bitwise
const rjust = (string, width, padding) => {
padding = padding || ' ';
const rjust = (string, width, padding = ' ') => {
padding = padding.substr(0, 1);
if (string.length < width)
return padding.repeat(width - string.length) + string;
@@ -26,7 +26,7 @@ const i2osp = (x, len) => {
if (x >= 256 ** len)
throw new Error('Integer too large');
return Buffer.from(rjust((Buffer.from((new BN(x)).toArray('be', 4)).toString()).replace(/\x00/gi, ''), len, '\x00')); // eslint-disable-line no-control-regex
return Buffer.from(rjust(new BigNumber(x).toBEBuffer(4).toString().replace(/\x00/gi, ''), len, '\x00')); // eslint-disable-line no-control-regex
};
module.exports = {

3813
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,16 @@
{
"name": "ebics-client",
"version": "0.1.1",
"version": "0.1.2",
"description": "Node.js ISO 20022 Compliant EBICS Client",
"main": "index.js",
"files": [
"lib/**/*",
"templates/**/*"
],
"scripts": {
"lint": "eslint .",
"test": "mocha test/**/*.js"
"test": "nyc mocha test/**/*.js",
"version": "auto-changelog -p -t changelog-template.hbs && git add CHANGELOG.md"
},
"repository": {
"type": "git",
@@ -15,10 +20,21 @@
"EBICS",
"ISO20022",
"nodejs",
"api"
"api",
"banking"
],
"author": "eCollect Sofia Tech Team",
"contributors": [
{
"name": "Dimitar Nanov",
"url": "https://nanov.io",
"email": "dimitar@nanov.io"
},
{
"name": "Vladislav Hristov",
"url": "https://github.com/vladhristov",
"email": "vlad.s.ch@gmail.com"
},
{
"name": "Vasyl Stashuk",
"url": "https://github.com/vasyas"
@@ -28,9 +44,9 @@
"url": "https://github.com/yagop"
}
],
"license": "GPLv3",
"license": "GPL-3.0-only",
"dependencies": {
"bn.js": "^5.0.0",
"auto-changelog": "^1.16.2",
"handlebars": "^4.4.3",
"js2xmlparser": "^4.0.0",
"node-forge": "^0.9.1",
@@ -46,6 +62,7 @@
"eslint-config-ecollect-base": "^0.1.2",
"eslint-plugin-import": "^2.18.2",
"libxmljs": "^0.19.7",
"mocha": "^6.2.2"
"mocha": "^6.2.2",
"nyc": "^14.1.1"
}
}

47
test/unit/BigNumber.js Normal file
View File

@@ -0,0 +1,47 @@
'use strict';
/* eslint-env node, mocha */
const { assert } = require('chai');
const { jsbn: { BigInteger } } = require('node-forge');
const BigNumber = require('../../lib/crypto/BigNumber');
const types = [
{ name: 'BigNumber', value: new BigNumber(11) },
{ name: 'BigInteger', value: new BigInteger('11') },
{ name: 'string with default radix', value: '11' },
{ name: 'string with radix 16', value: '0b', radix: 16 },
{ name: 'Buffer', value: Buffer.from('0b', 'hex') },
{ name: 'Array', value: [11] },
];
describe('BigNumber', () => {
describe('creating an instance', () => {
it('should throw with no value given', () => assert.throws(() => new BigNumber()));
it('should throw wrong value type', () => assert.throws(() => new BigNumber({})));
for (const { name, value, radix } of types) {
let instance;
describe(`out of ${name}`, () => {
it('create instance', () => assert.doesNotThrow(() => {
instance = new BigNumber(value, radix);
}));
it('toString with radix 10', () => assert.equal(instance.toString(), '11'));
it('toString with radix 16', () => assert.equal(instance.toString(16), '0b'));
it('toBEBuffer without length', () => assert.equal(instance.toBEBuffer().toString('hex'), '0b'));
it('toBEBuffer with length', () => assert.equal(instance.toBEBuffer(4).toString('hex'), '0000000b'));
});
}
});
describe('exports', () => {
it('toBEBuffer with too short length should throw', () => assert.throw(() => new BigNumber(837462187362).toBEBuffer(1)));
});
describe('operators', () => {
const num = new BigNumber(1);
it('and', () => assert.equal(num.and(1), 1));
it('mul', () => assert.equal(num.mul(2), 2));
it('mod', () => assert.equal(num.mod(1), 0));
it('shrn', () => assert.equal(num.shrn(1), 0));
});
});