@mft/moneyhub-api-client 4.15.1 → 4.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mft/moneyhub-api-client",
3
- "version": "4.15.1",
3
+ "version": "4.18.0",
4
4
  "description": "Node.JS client for the Moneyhub API",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -21,23 +21,23 @@
21
21
  "repository": "moneyhub/moneyhub-api-client",
22
22
  "license": "ISC",
23
23
  "dependencies": {
24
- "form-data": "^3.0.0",
24
+ "form-data": "^3.0.1",
25
25
  "got": "^11.8.3",
26
26
  "jose": "^2.0.5",
27
- "openid-client": "^4.2.2",
28
- "ramda": "^0.27.1"
27
+ "openid-client": "^4.9.1",
28
+ "ramda": "^0.27.2"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@mft/eslint-config-momentumft": "^4.0.0",
32
- "body-parser": "^1.19.0",
33
- "chai": "^4.2.0",
34
- "command-line-args": "^5.1.1",
32
+ "body-parser": "^1.19.2",
33
+ "chai": "^4.3.6",
34
+ "command-line-args": "^5.2.1",
35
35
  "command-line-usage": "^6.1.1",
36
- "config": "^3.3.6",
36
+ "config": "^3.3.7",
37
37
  "eslint": "^7.32.0",
38
- "express": "^4.17.1",
39
- "husky": "^7.0.2",
40
- "mocha": "^9.2.0",
38
+ "express": "^4.17.3",
39
+ "husky": "^7.0.4",
40
+ "mocha": "^9.2.2",
41
41
  "mocha-junit-reporter": "^2.0.2"
42
42
  },
43
43
  "husky": {
package/readme.md CHANGED
@@ -89,10 +89,18 @@ const moneyhub = await Moneyhub({
89
89
  Once the api client has been initialised it provides a simple promise based interface with the following methods:
90
90
 
91
91
  ### Auth API
92
+ The options below can be set on the following URL generating methods:
93
+ - `getAuthorizeUrl`
94
+ - `getAuthorizeUrlForCreatedUser`
95
+ - `getReauthAuthorizeUrlForCreatedUser`
96
+ - `getRefreshAuthorizeUrlForCreatedUser`
92
97
 
98
+ The `expirationDateTime` and `transactionFromDateTime` options can be set according to the [AIS Consents documentation](https://docs.moneyhubenterprise.com/docs/ais-consents)
99
+
100
+ Set `enableAsync` to true if you wish to make an AIS connection that won't wait for accounts and transactions to be fetched.
93
101
  #### `getAuthorizeUrl`
94
102
 
95
- This method returns an authorize url for your API client. You can redirect a user to this url, after which they will be redirected back to your `redirect_uri`.
103
+ This method returns an authorize url for your API client. You can redirect a user to this url, after which they will be redirected back to your `redirect_uri`.
96
104
 
97
105
  [Financial institutions](https://docs.moneyhubenterprise.com/docs/bank-connections)
98
106
 
@@ -100,13 +108,17 @@ This method returns an authorize url for your API client. You can redirect a use
100
108
 
101
109
  [Claims](https://docs.moneyhubenterprise.com/docs/claims)
102
110
 
111
+
103
112
  ```javascript
104
113
  const url = await moneyhub.getAuthorizeUrl({
105
114
  scope: "openid bank-id-scope other-data-scopes",
106
115
  state: " your state value", // optional
107
116
  nonce: "your nonce value", //optional
108
117
  claims: claimsObject, // optional
109
- permissions: ["ReadBeneficiariesDetail"] // optional - set of extra permissions to set for auth URL
118
+ permissions: ["ReadBeneficiariesDetail"], // optional - set of extra permissions to set for auth URL
119
+ expirationDateTime: "2022-09-01T00:00:00.000Z", // optional
120
+ transactionFromDateTime: "2020-09-01T00:00:00.000Z", // optional,
121
+ enableAsync: false // optional
110
122
  })
111
123
 
112
124
  // Default claims if none are provided
@@ -139,7 +151,8 @@ const url = await moneyhub.getAuthorizeUrlForCreatedUser({
139
151
  state: "your state value", // optional
140
152
  nonce: "your nonce value", // optional
141
153
  claims: claimsObject, // optional
142
- permissions: ["ReadBeneficiariesDetail"] // optional - set of extra permissions to set for auth URL
154
+ permissions: ["ReadBeneficiariesDetail"], // optional - set of extra permissions to set for auth URL
155
+ enableAsync: false // optional
143
156
  })
144
157
 
145
158
  // Scope used with the bankId provided
@@ -170,6 +183,7 @@ const url = await moneyhub.getReauthAuthorizeUrlForCreatedUser({
170
183
  state: "your state value", // optional
171
184
  nonce: "your nonce value", // optional
172
185
  claims: claimsObject, // optional
186
+ enableAsync: false // optional
173
187
  })
174
188
 
175
189
  // Default claims if none are provided
@@ -198,6 +212,7 @@ const url = await moneyhub.getRefreshAuthorizeUrlForCreatedUser({
198
212
  state: "your state value", // optional
199
213
  nonce: "your nonce value", // optional
200
214
  claims: claimsObject, // optional
215
+ enableAsync: false // optional
201
216
  })
202
217
 
203
218
  // Default claims if none are provided
@@ -511,6 +526,30 @@ const user = await moneyhub.deleteUserConnection({
511
526
  })
512
527
  ```
513
528
 
529
+ #### `getConnectionSyncs`
530
+
531
+ Retrieve the syncs for a given connection ID.
532
+ ```javascript
533
+ const syncs = await moneyhub.getConnectionSyncs({
534
+ userId: "user-id",
535
+ connectionId: "connection-id",
536
+ params: {
537
+ limit: 10,
538
+ offset: 0
539
+ }
540
+ })
541
+ ```
542
+
543
+ #### `getSync`
544
+
545
+ Retrieve the syncs for the given sync ID.
546
+ ```javascript
547
+ const syncs = await moneyhub.getSync({
548
+ userId: "user-id",
549
+ syncId: "sync-id"
550
+ })
551
+ ```
552
+
514
553
  ### Data API
515
554
 
516
555
  #### `getAccounts`
@@ -80,6 +80,8 @@ describe("API client", () => {
80
80
  "getUserConnections",
81
81
  "deleteUserConnection",
82
82
  "deleteUser",
83
+ "getConnectionSyncs",
84
+ "getSync",
83
85
  "getCategories",
84
86
  "getStandardCategories",
85
87
  "getCategory",
@@ -67,7 +67,7 @@ describe("Transaction Splits", () => {
67
67
  transactionId,
68
68
  })
69
69
  expect(splits).to.have.length(2)
70
- expect(R.path([0, "amount"], splits)).to.be.oneOf([-1500, -800])
70
+ expect(R.path([0, "amount", "value"], splits)).to.be.oneOf([-1500, -800])
71
71
  expect(R.path([0, "description"], splits)).to.be.oneOf(["Split 1", "Split 2"])
72
72
  })
73
73
 
@@ -30,7 +30,16 @@ module.exports = ({client, config}) => {
30
30
  return claims
31
31
  }
32
32
 
33
- const getAuthorizeUrl = ({state, scope, nonce, claims = {}, permissions}) => {
33
+ const getAuthorizeUrl = ({
34
+ state,
35
+ scope,
36
+ nonce,
37
+ claims = {},
38
+ permissions,
39
+ enableAsync,
40
+ expirationDateTime,
41
+ transactionFromDateTime,
42
+ }) => {
34
43
  const defaultClaims = {
35
44
  id_token: {
36
45
  sub: {
@@ -39,6 +48,21 @@ module.exports = ({client, config}) => {
39
48
  "mh:con_id": {
40
49
  essential: true,
41
50
  },
51
+ ...(expirationDateTime || transactionFromDateTime) && {
52
+ "mh:consent": {
53
+ "essential": true,
54
+ "value": {
55
+ ...expirationDateTime && {expirationDateTime},
56
+ ...transactionFromDateTime && {transactionFromDateTime},
57
+ }
58
+ }
59
+ },
60
+ ...enableAsync && {
61
+ "mh:sync": {
62
+ "essential": true,
63
+ "value": {"enableAsync": true}
64
+ }
65
+ }
42
66
  },
43
67
  }
44
68
 
@@ -116,7 +140,10 @@ module.exports = ({client, config}) => {
116
140
  nonce,
117
141
  userId,
118
142
  claims = {},
119
- permissions
143
+ permissions,
144
+ expirationDateTime,
145
+ transactionFromDateTime,
146
+ enableAsync,
120
147
  }) => {
121
148
  const scope = `id:${bankId} openid`
122
149
  const defaultClaims = {
@@ -140,6 +167,9 @@ module.exports = ({client, config}) => {
140
167
  nonce,
141
168
  scope,
142
169
  claims: _claims,
170
+ expirationDateTime,
171
+ transactionFromDateTime,
172
+ enableAsync,
143
173
  })
144
174
  return url
145
175
  },
@@ -150,6 +180,9 @@ module.exports = ({client, config}) => {
150
180
  state,
151
181
  nonce,
152
182
  claims = {},
183
+ expirationDateTime,
184
+ transactionFromDateTime,
185
+ enableAsync,
153
186
  }) => {
154
187
  const scope = "openid reauth"
155
188
  const defaultClaims = {
@@ -171,6 +204,9 @@ module.exports = ({client, config}) => {
171
204
  nonce,
172
205
  scope,
173
206
  claims: _claims,
207
+ expirationDateTime,
208
+ transactionFromDateTime,
209
+ enableAsync,
174
210
  })
175
211
  return url
176
212
  },
@@ -181,6 +217,9 @@ module.exports = ({client, config}) => {
181
217
  state,
182
218
  nonce,
183
219
  claims = {},
220
+ expirationDateTime,
221
+ transactionFromDateTime,
222
+ enableAsync
184
223
  }) => {
185
224
  const scope = "openid refresh"
186
225
  const defaultClaims = {
@@ -202,6 +241,9 @@ module.exports = ({client, config}) => {
202
241
  scope,
203
242
  nonce,
204
243
  claims: _claims,
244
+ expirationDateTime,
245
+ transactionFromDateTime,
246
+ enableAsync
205
247
  })
206
248
  return url
207
249
  },
package/src/request.js CHANGED
@@ -1,4 +1,26 @@
1
1
  const got = require("got")
2
+ const R = require("ramda")
3
+
4
+ const getResponseBody = err => {
5
+ let body = {}
6
+ try {
7
+ const {code, message, details} = JSON.parse(R.pathOr("{}", ["response", "body"], err))
8
+ body = {code, message, details: typeof details === "object" ? JSON.stringify(details) : details}
9
+ // eslint-disable-next-line no-empty
10
+ } catch (e) {
11
+ body = {}
12
+ }
13
+
14
+ return body
15
+ }
16
+
17
+ const attachErrorDetails = err => {
18
+ const {code, message, details} = getResponseBody(err)
19
+ err.error = code
20
+ err.error_description = message
21
+ err.error_details = details
22
+ throw err
23
+ }
2
24
 
3
25
  module.exports = ({client, options: {timeout}}) => async (url, opts = {}) => {
4
26
  const gotOpts = {
@@ -28,7 +50,9 @@ module.exports = ({client, options: {timeout}}) => async (url, opts = {}) => {
28
50
  const req = got(url, gotOpts)
29
51
  if (opts.returnStatus) {
30
52
  return req.then(res => res.statusCode)
53
+ .catch(attachErrorDetails)
31
54
  }
32
55
 
33
56
  return req.json()
57
+ .catch(attachErrorDetails)
34
58
  }
@@ -1,8 +1,10 @@
1
1
  module.exports = ({config, request}) => {
2
2
  const {resourceServerUrl, identityServiceUrl} = config
3
3
  return {
4
- getGlobalCounterparties: () =>
5
- request(resourceServerUrl + "/global-counterparties"),
4
+ getGlobalCounterparties: (params = {}) =>
5
+ request(resourceServerUrl + "/global-counterparties", {
6
+ searchParams: params,
7
+ }),
6
8
  listConnections: () =>
7
9
  request(identityServiceUrl + "/oidc/.well-known/all-connections"),
8
10
  listAPIConnections: () =>
@@ -60,5 +60,20 @@ module.exports = ({config, request}) => {
60
60
  scope: "user:delete",
61
61
  },
62
62
  }),
63
+
64
+ getConnectionSyncs: async ({userId, connectionId, params = {}}) =>
65
+ request(`${usersEndpoint}/${userId}/connections/${connectionId}/syncs`, {
66
+ searchParams: params,
67
+ cc: {
68
+ scope: "user:read"
69
+ }
70
+ }),
71
+
72
+ getSync: async ({userId, syncId}) =>
73
+ request(`${usersEndpoint}/${userId}/syncs/${syncId}`, {
74
+ cc: {
75
+ scope: "user:read"
76
+ }
77
+ })
63
78
  }
64
79
  }