Skip to content

Commit

Permalink
📦 v0.1.2
Browse files Browse the repository at this point in the history
- Bugfixes
- Migrated to Aika
  • Loading branch information
sondregj authored Mar 17, 2019
2 parents 565d769 + 045ff85 commit d306e5d
Show file tree
Hide file tree
Showing 20 changed files with 349 additions and 228 deletions.
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
test
.env
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ matrix:
node_js: "11"
install: npm install
script: npm test
cache:
directories:
- $HOME/node_modules
81 changes: 68 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,44 @@
[![Travis Build Status](https://img.shields.io/travis/sondregj/dnb-api-client.svg?style=flat-square)](https://travis-ci.org/sondregj/dnb-api-client)
[![gitmoji badge](https://img.shields.io/badge/gitmoji-%20😜%20😍-FFDD67.svg?style=flat-square)](https://github.com/carloscuesta/gitmoji)
<h1 align="center">
<a href='https://developer.dnb.no' ><img src='https://svgshare.com/i/BkG.svg' width="250" title='DNB Developer' /></a>
<br>
<br>
DNB Open Banking Client
</h1>

# DNB Open Banking Client
<h4 align="center">A Node.js client for DNB's various API products. (Under development, may change)</h4>

> A client for DNB's various API products. *(Under development, may change)*

The APIs are currently under development, and only available in a sandbox. To use this API, you have to create an application on [https://developer.dnb.no](https://developer.dnb.no).
<p align="center">
<a href="https://travis-ci.org/sondregj/dnb-api">
<img alt="Travis Build Status" src="https://img.shields.io/travis/sondregj/dnb-api.svg?style=flat-square">
</a>

See examples below
<a href="https://npmjs.com/dnb-api">
<img alt="npm (latest)" src="https://img.shields.io/npm/v/dnb-api/latest.svg?style=flat-square">
</a>

<a href="https://npmjs.com/dnb-api">
<img alt="npm bundle size" src="https://img.shields.io/bundlephobia/min/dnb-api.svg?style=flat-square">
</a>

<a href="https://github.com/sondregj/dnb-api">
<img alt="GitHub contributors" src="https://img.shields.io/github/contributors/sondregj/dnb-api.svg?style=flat-square">
</a>

<a href="https://github.com/sondregj/dnb-api">
<img alt="License" src="https://img.shields.io/github/license/sondregj/dnb-api.svg?style=flat-square">
</a>

<a href="https://github.com/carloscuesta/gitmoji">
<img alt="Gitmoji" src="https://img.shields.io/badge/gitmoji-%20😜%20😍-FFDD67.svg?style=flat-square">
</a>
</p>

The APIs are currently under development, and only available in a sandbox. To use this API, you have to create an application at [https://developer.dnb.no](https://developer.dnb.no).

*NOTE: None of the POST requests work yet...*

See examples below.

## Usage

Expand All @@ -16,27 +47,51 @@ All the functions are asynchronous and return promises.
```javascript
const DNBApi = require('dnb-api-client')

const api = new DNBApi('CLIENT_ID', 'CLIENT_SECRET', 'API_KEY')
const client = new DNBApi('CLIENT_ID', 'CLIENT_SECRET', 'API_KEY')

const fetchCustomerData = async () => {
const jwt = await api.getToken('SSN', '12345678910')
const jwt = await client.getToken('SSN', '12345678910')

return await api.token(jwt).customers.getCustomerInfo()
return await client.token(jwt).customers.getCustomerInfo()
}

fetchCustomerData()
.then((customer) => console.log(`${customer.firstName} ${customer.lastName}`))
.catch((err) => console.log(err.message))
.then( customer => console.log(`${customer.firstName} ${customer.lastName}`) )
.catch( err => console.log(err.message) )
```

For more examples see below.

## Features

Each API product is subdivided from the main object.

```javascript
client.accounts // Accounts API
client.api // General
client.cards // Cards API
client.currencies // Currencies API
client.customers // Customers API
client.locations // Locations API
client.payments // Payments API
client.testCustomers // Test Customers API
client.transactions // Transactions API
```

## Examples

## Development

## Testing
First, clone the repo. You will need API keys to run the tests. Make a new app at [https://developer.dnb.no](https://developer.dnb.no), duplicate `sample.env` and paste in the keys.

Do `npm install`.

Run tests with `npm test`.

Run linter with `npm run lint`

Do not commit directly to master. Preferably, make a branch or fork out of the `development` branch and make a pull request.

## License

MIT (c) 2019 Sondre Gjellestad
MIT © 2019 Sondre Gjellestad
25 changes: 15 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dnb-api",
"version": "0.1.0",
"version": "0.1.2",
"description": "Client for DNB Open Banking platform",
"main": "index.js",
"scripts": {
Expand All @@ -24,7 +24,10 @@
"homepage": "https://github.com/sondregj/dnb-api-client#readme",
"devDependencies": {
"ava": "^1.3.1",
"dotenv": "^6.2.0",
"eslint": "^5.15.1"
"dotenv": "^7.0.0",
"eslint": "^5.15.2"
},
"dependencies": {
"aika": "^0.1.2"
}
}
93 changes: 93 additions & 0 deletions src/aika/headerbuilder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
const {HeaderBuilder} = require('aika')

const crypto = require('crypto')
const querystring = require('querystring')

module.exports = (options) => {
return new HeaderBuilder({
constants: {
apiKey: options.apiKey,
clientId: options.clientId,
clientSecret: options.clientSecret,

hostName: options.hostName,

// Reference to client JWT
token: options.token,

// Amz
algorithm: 'AWS4-HMAC-SHA256',
signedHeaders: 'host;x-amz-date',
awsRegion: options.awsRegion,
awsService: options.awsService
},

helpers: {
asv4sign: (context, options, clientId, clientSecret) => {
if (options.method === 'POST') {
options.body = '{}'
} else {
options.body = ''
}

const algorithm = 'AWS4-HMAC-SHA256'
const amzDate = context.helpers.createAmzDate()
const dateStamp = amzDate.substr(0, 8)
const queryStringMatch = options.path.match(/(.*)\?/)

let canonicalUri = options.path
if (queryStringMatch !== null) {
const firstMatchIndex = 1
canonicalUri = queryStringMatch[firstMatchIndex]
}

const canonicalQuerystring = querystring.stringify(options.query)
const canonicalHeaders = `host:${options.host}\nx-amz-date:${amzDate}\n`
const signedHeaders = 'host;x-amz-date'

const signingKey = context.helpers.getSignatureKey(
context,
clientSecret,
dateStamp,
context.constants.awsService,
context.constants.awsRegion
)

const payloadHash = context.helpers.hashHex(options.body ? JSON.stringify(options.body) : '')

const canonicalRequest = `${options.method}\n${canonicalUri}\n${canonicalQuerystring}\n${canonicalHeaders}\n${signedHeaders}\n${payloadHash}`

const credentialScope = `${dateStamp}/${context.constants.awsRegion}/${context.constants.awsService}/aws4_request`
const stringToSign = `${algorithm}\n${amzDate}\n${credentialScope}\n${context.helpers.hashHex(canonicalRequest)}`

const signature = context.helpers.signData(signingKey, stringToSign, 'hex')
const credentialHeader = `Credential=${clientId}/${credentialScope}`

return `${algorithm} ${credentialHeader}, SignedHeaders=${signedHeaders}, Signature=${signature}`
},
createAmzDate: () => new Date().toISOString().replace(/[:-]|\.\d{3}/g, ''),

hashHex: string => crypto.createHash('sha256').update(string, 'utf8').digest('hex'),

signData: (key, data, encoding) => crypto.createHmac('sha256', key).update(data, 'utf8').digest(encoding),

getSignatureKey: (context, key, dateStamp, serviceName, regionName) => {
const date = context.helpers.signData((`AWS4${key}`), dateStamp)
const region = context.helpers.signData(date, regionName)
const service = context.helpers.signData(region, serviceName)

return context.helpers.signData(service, 'aws4_request')
}
},

headerFunctions: {
Host: c => c.constants.hostName,
Accept: () => 'application/json',
'Content-type': () => 'application/json',
'x-api-key': c => c.constants.apiKey,
'x-amz-date': c => c.helpers.createAmzDate(),
'x-dnbapi-jwt': c => c.constants.token.jwt,
Authorization: (c, r) => c.helpers.asv4sign(c, r, c.constants.clientId, c.constants.clientSecret),
}
})
}
44 changes: 0 additions & 44 deletions src/http/index.js

This file was deleted.

27 changes: 0 additions & 27 deletions src/http/request.js

This file was deleted.

Loading

0 comments on commit d306e5d

Please sign in to comment.