cozy-harvest-lib 9.4.0 → 9.5.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/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [9.5.0](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@9.4.0...cozy-harvest-lib@9.5.0) (2022-05-23)
7
+
8
+
9
+ ### Features
10
+
11
+ * Handle banks with mulitple bank ids ([a944201](https://github.com/cozy/cozy-libs/commit/a944201ca5752766a49689f42531c84f03798002))
12
+
13
+
14
+
15
+
16
+
6
17
  # [9.4.0](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@9.3.0...cozy-harvest-lib@9.4.0) (2022-05-18)
7
18
 
8
19
 
@@ -18,8 +18,11 @@ import { getBIConnection } from './bi-http';
18
18
  import assert from '../assert';
19
19
  import logger from '../logger';
20
20
  import flag from 'cozy-flags';
21
- import { fetchExtraOAuthUrlParams, createTemporaryToken, setBIConnectionId, saveBIConfig, findAccountWithBiConnection, convertBIErrortoKonnectorJobError, isBudgetInsightConnector } from './budget-insight';
21
+ import { setBIConnectionId, saveBIConfig, findAccountWithBiConnection, convertBIErrortoKonnectorJobError, isBudgetInsightConnector } from './budget-insight';
22
22
  import { KonnectorJobError } from '../helpers/konnectors';
23
+ import { waitForRealtimeEvent } from './jobUtils';
24
+ import '../types';
25
+ var TEMP_TOKEN_TIMOUT_S = 60;
23
26
  export var isBiWebViewConnector = function isBiWebViewConnector(konnector) {
24
27
  return flag('harvest.bi.webview') && isBudgetInsightConnector(konnector);
25
28
  };
@@ -116,19 +119,19 @@ export var checkBIConnection = /*#__PURE__*/function () {
116
119
 
117
120
  export var handleOAuthAccount = /*#__PURE__*/function () {
118
121
  var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(_ref3) {
119
- var account, flow, konnector, client, t, cozyBankId, biWebviewAccount, connectionId;
122
+ var account, flow, konnector, client, t, cozyBankIds, biWebviewAccount, connectionId;
120
123
  return _regeneratorRuntime.wrap(function _callee2$(_context2) {
121
124
  while (1) {
122
125
  switch (_context2.prev = _context2.next) {
123
126
  case 0:
124
127
  account = _ref3.account, flow = _ref3.flow, konnector = _ref3.konnector, client = _ref3.client, t = _ref3.t;
125
- cozyBankId = getCozyBankId({
128
+ cozyBankIds = getCozyBankIds({
126
129
  konnector: konnector,
127
130
  account: account
128
131
  });
129
- biWebviewAccount = _objectSpread(_objectSpread({}, account), cozyBankId ? {
132
+ biWebviewAccount = _objectSpread(_objectSpread({}, account), cozyBankIds ? {
130
133
  auth: {
131
- bankId: cozyBankId
134
+ bankIds: cozyBankIds
132
135
  }
133
136
  } : {});
134
137
  connectionId = getWebviewBIConnectionId(biWebviewAccount);
@@ -240,26 +243,125 @@ export var onBIAccountCreation = /*#__PURE__*/function () {
240
243
  return _ref6.apply(this, arguments);
241
244
  };
242
245
  }();
246
+ export var fetchExtraOAuthUrlParams = /*#__PURE__*/function () {
247
+ var _ref8 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4(_ref7) {
248
+ var client, konnector, account, _yield$createTemporar, token, biBankId, biBankIds;
249
+
250
+ return _regeneratorRuntime.wrap(function _callee4$(_context4) {
251
+ while (1) {
252
+ switch (_context4.prev = _context4.next) {
253
+ case 0:
254
+ client = _ref7.client, konnector = _ref7.konnector, account = _ref7.account;
255
+ _context4.next = 3;
256
+ return createTemporaryToken({
257
+ client: client,
258
+ konnector: konnector,
259
+ account: account
260
+ });
261
+
262
+ case 3:
263
+ _yield$createTemporar = _context4.sent;
264
+ token = _yield$createTemporar.code;
265
+ biBankId = _yield$createTemporar.biBankId;
266
+ biBankIds = _yield$createTemporar.biBankIds;
267
+ return _context4.abrupt("return", {
268
+ id_connector: biBankId || biBankIds,
269
+ token: token
270
+ });
271
+
272
+ case 8:
273
+ case "end":
274
+ return _context4.stop();
275
+ }
276
+ }
277
+ }, _callee4);
278
+ }));
279
+
280
+ return function fetchExtraOAuthUrlParams(_x4) {
281
+ return _ref8.apply(this, arguments);
282
+ };
283
+ }();
243
284
  /**
244
285
  * Finds the current bankIid in a given konnector or account
245
286
  *
246
287
  * @param {io.cozy.accounts} options.account The account content
247
288
  * @param {io.cozy.konnectors} options.konnector connector manifest content
289
+ * @return {Array<String>} - list of bank ids
248
290
  */
249
291
 
250
- export var getCozyBankId = function getCozyBankId(_ref7) {
251
- var _konnector$parameters, _account$auth;
292
+ export var getCozyBankIds = function getCozyBankIds(_ref9) {
293
+ var _konnector$parameters, _account$auth, _konnector$fields, _konnector$fields$ban;
252
294
 
253
- var konnector = _ref7.konnector,
254
- account = _ref7.account;
295
+ var konnector = _ref9.konnector,
296
+ account = _ref9.account;
255
297
  var cozyBankId = (konnector === null || konnector === void 0 ? void 0 : (_konnector$parameters = konnector.parameters) === null || _konnector$parameters === void 0 ? void 0 : _konnector$parameters.bankId) || (account === null || account === void 0 ? void 0 : (_account$auth = account.auth) === null || _account$auth === void 0 ? void 0 : _account$auth.bankId);
256
298
 
257
- if (!cozyBankId) {
299
+ if (cozyBankId) {
300
+ return [cozyBankId];
301
+ }
302
+
303
+ var cozyBankIds = konnector === null || konnector === void 0 ? void 0 : (_konnector$fields = konnector.fields) === null || _konnector$fields === void 0 ? void 0 : (_konnector$fields$ban = _konnector$fields.bankId) === null || _konnector$fields$ban === void 0 ? void 0 : _konnector$fields$ban.options.map(function (opt) {
304
+ return opt === null || opt === void 0 ? void 0 : opt.value;
305
+ });
306
+
307
+ if (!(cozyBankIds !== null && cozyBankIds !== void 0 && cozyBankIds.length)) {
258
308
  logger.error('Could not find any bank id');
259
309
  }
260
310
 
261
- return cozyBankId;
311
+ return cozyBankIds;
262
312
  };
313
+ /**
314
+ * Gets a temporary token corresponding to the current BI user
315
+ *
316
+ * @param {CozyClient} options.client - CozyClient instance
317
+ * @param {io.cozy.konnectors} options.konnector connector manifest content
318
+ * @param {io.cozy.accounts} options.account The account content
319
+ *
320
+ * @returns {createTemporaryTokenResponse}
321
+ */
322
+
323
+ export var createTemporaryToken = /*#__PURE__*/function () {
324
+ var _ref11 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5(_ref10) {
325
+ var client, konnector, account, cozyBankIds, jobResponse, event;
326
+ return _regeneratorRuntime.wrap(function _callee5$(_context5) {
327
+ while (1) {
328
+ switch (_context5.prev = _context5.next) {
329
+ case 0:
330
+ client = _ref10.client, konnector = _ref10.konnector, account = _ref10.account;
331
+ assert(konnector.slug, 'createTemporaryToken: konnector passed in options has no slug');
332
+ cozyBankIds = getCozyBankIds({
333
+ konnector: konnector,
334
+ account: account
335
+ });
336
+ assert(cozyBankIds.length, 'createTemporaryToken: Could not determine cozyBankId from account or konnector');
337
+ _context5.next = 6;
338
+ return client.stackClient.jobs.create('konnector', {
339
+ mode: 'getTemporaryToken',
340
+ konnector: konnector.slug,
341
+ bankIds: cozyBankIds
342
+ }, {}, true);
343
+
344
+ case 6:
345
+ jobResponse = _context5.sent;
346
+ _context5.next = 9;
347
+ return waitForRealtimeEvent(client, jobResponse.data.attributes, 'result', TEMP_TOKEN_TIMOUT_S * 1000);
348
+
349
+ case 9:
350
+ event = _context5.sent;
351
+ return _context5.abrupt("return", event.data.result);
352
+
353
+ case 11:
354
+ case "end":
355
+ return _context5.stop();
356
+ }
357
+ }
358
+ }, _callee5);
359
+ }));
360
+
361
+ return function createTemporaryToken(_x5) {
362
+ return _ref11.apply(this, arguments);
363
+ };
364
+ }();
263
365
  export var konnectorPolicy = {
264
366
  isBIWebView: true,
265
367
  name: 'budget-insight-webview',
@@ -113,7 +113,7 @@ describe('handleOAuthAccount', function () {
113
113
  t: t,
114
114
  account: _objectSpread(_objectSpread(_objectSpread({}, account), {
115
115
  auth: {
116
- bankId: TEST_BANK_COZY_ID
116
+ bankIds: [TEST_BANK_COZY_ID]
117
117
  }
118
118
  }), {
119
119
  data: {
@@ -34,6 +34,7 @@ import { mkConnAuth, biErrorMap } from 'cozy-bi-auth';
34
34
  import { KonnectorJobError } from '../helpers/konnectors';
35
35
  import { LOGIN_SUCCESS_EVENT } from '../models/flowEvents';
36
36
  import logger from '../logger';
37
+ import '../types';
37
38
  var DECOUPLED_ERROR = 'decoupled';
38
39
  var ADDITIONAL_INFORMATION_NEEDED_ERROR = 'additionalInformationNeeded';
39
40
  var TEMP_TOKEN_TIMOUT_S = 60;
@@ -401,19 +402,6 @@ export var resumeBIConnection = function resumeBIConnection(flow) {
401
402
  resume: 'true'
402
403
  });
403
404
  };
404
- /**
405
- * @typedef biConnection
406
- * @property {number} id
407
- * @property {number} id_user
408
- * @property {number} id_connector
409
- * @property {string|null} state - ( wrongpass | additionalInformationNeeded | websiteUnavailable | actionNeeded | SCARequired | decoupled | passwordExpired | webauthRequired | rateLimiting | bug). Null indicates a success
410
- * @property {string|null} last_update - Date string: Last successful update.
411
- * @property {string|null} created - Date string: Creation date
412
- * @property {boolean} active - Whether this connection is active and will be automatically synced.
413
- * @property {string|null} last_push - Date string: Last successfull push
414
- * @property {string|null} next_try - Date string: Date of next synchronization.
415
- */
416
-
417
405
  /**
418
406
  * Checks for any number 2FA and/or decoupled requests
419
407
  *
package/dist/types.js ADDED
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @typedef createTemporaryTokenResponse
3
+ * @property {String} code - the temporary token
4
+ * @property {String} url - BI environment url
5
+ * @property {String} bankId - Cozy bank id corresponding to the current connector (deprecated once bi webviews are in production)
6
+ * @property {String} biBankId - BI bank id corresponding to the bankId translated by the connector (deprecated once bi webviews are in production)
7
+ * @property {Array<String>} bankIds - Cozy bank ids corresponding to the current connector
8
+ * @property {Array<String>} biBankIds - BI bank ids corresponding to the bankIds translated by the connector
9
+ */
10
+
11
+ /**
12
+ * @typedef biConnection
13
+ * @property {number} id
14
+ * @property {number} id_user
15
+ * @property {number} id_connector
16
+ * @property {string|null} state - ( wrongpass | additionalInformationNeeded | websiteUnavailable | actionNeeded | SCARequired | decoupled | passwordExpired | webauthRequired | rateLimiting | bug). Null indicates a success
17
+ * @property {string|null} last_update - Date string: Last successful update.
18
+ * @property {string|null} created - Date string: Creation date
19
+ * @property {boolean} active - Whether this connection is active and will be automatically synced.
20
+ * @property {string|null} last_push - Date string: Last successfull push
21
+ * @property {string|null} next_try - Date string: Date of next synchronization.
22
+ */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-harvest-lib",
3
- "version": "9.4.0",
3
+ "version": "9.5.0",
4
4
  "description": "Provides logic, modules and components for Cozy's harvest applications.",
5
5
  "main": "dist/index.js",
6
6
  "author": "Cozy",
@@ -87,5 +87,5 @@
87
87
  "react-router-dom": "^5.0.1"
88
88
  },
89
89
  "sideEffects": false,
90
- "gitHead": "9ab356f1f7eea371ff0d364ec1eb740aa8d4fd47"
90
+ "gitHead": "d941e5ac9af1ce3e4394034f8a989431d233e84f"
91
91
  }
@@ -9,8 +9,6 @@ import assert from '../assert'
9
9
  import logger from '../logger'
10
10
  import flag from 'cozy-flags'
11
11
  import {
12
- fetchExtraOAuthUrlParams,
13
- createTemporaryToken,
14
12
  setBIConnectionId,
15
13
  saveBIConfig,
16
14
  findAccountWithBiConnection,
@@ -18,6 +16,10 @@ import {
18
16
  isBudgetInsightConnector
19
17
  } from './budget-insight'
20
18
  import { KonnectorJobError } from '../helpers/konnectors'
19
+ import { waitForRealtimeEvent } from './jobUtils'
20
+ import '../types'
21
+
22
+ const TEMP_TOKEN_TIMOUT_S = 60
21
23
 
22
24
  export const isBiWebViewConnector = konnector =>
23
25
  flag('harvest.bi.webview') && isBudgetInsightConnector(konnector)
@@ -94,10 +96,10 @@ export const handleOAuthAccount = async ({
94
96
  client,
95
97
  t
96
98
  }) => {
97
- const cozyBankId = getCozyBankId({ konnector, account })
99
+ const cozyBankIds = getCozyBankIds({ konnector, account })
98
100
  let biWebviewAccount = {
99
101
  ...account,
100
- ...(cozyBankId ? { auth: { bankId: cozyBankId } } : {})
102
+ ...(cozyBankIds ? { auth: { bankIds: cozyBankIds } } : {})
101
103
  }
102
104
 
103
105
  const connectionId = getWebviewBIConnectionId(biWebviewAccount)
@@ -167,18 +169,81 @@ export const onBIAccountCreation = async ({
167
169
  return await flow.saveAccount(setBIConnectionId(account, biConnection.id))
168
170
  }
169
171
 
172
+ export const fetchExtraOAuthUrlParams = async ({
173
+ client,
174
+ konnector,
175
+ account
176
+ }) => {
177
+ const {
178
+ code: token,
179
+ biBankId,
180
+ biBankIds
181
+ } = await createTemporaryToken({
182
+ client,
183
+ konnector,
184
+ account
185
+ })
186
+
187
+ return { id_connector: biBankId || biBankIds, token }
188
+ }
189
+
170
190
  /**
171
191
  * Finds the current bankIid in a given konnector or account
172
192
  *
173
193
  * @param {io.cozy.accounts} options.account The account content
174
194
  * @param {io.cozy.konnectors} options.konnector connector manifest content
195
+ * @return {Array<String>} - list of bank ids
175
196
  */
176
- export const getCozyBankId = ({ konnector, account }) => {
197
+ export const getCozyBankIds = ({ konnector, account }) => {
177
198
  const cozyBankId = konnector?.parameters?.bankId || account?.auth?.bankId
178
- if (!cozyBankId) {
199
+
200
+ if (cozyBankId) {
201
+ return [cozyBankId]
202
+ }
203
+
204
+ const cozyBankIds = konnector?.fields?.bankId?.options.map(opt => opt?.value)
205
+ if (!cozyBankIds?.length) {
179
206
  logger.error('Could not find any bank id')
180
207
  }
181
- return cozyBankId
208
+ return cozyBankIds
209
+ }
210
+
211
+ /**
212
+ * Gets a temporary token corresponding to the current BI user
213
+ *
214
+ * @param {CozyClient} options.client - CozyClient instance
215
+ * @param {io.cozy.konnectors} options.konnector connector manifest content
216
+ * @param {io.cozy.accounts} options.account The account content
217
+ *
218
+ * @returns {createTemporaryTokenResponse}
219
+ */
220
+ export const createTemporaryToken = async ({ client, konnector, account }) => {
221
+ assert(
222
+ konnector.slug,
223
+ 'createTemporaryToken: konnector passed in options has no slug'
224
+ )
225
+ const cozyBankIds = getCozyBankIds({ konnector, account })
226
+ assert(
227
+ cozyBankIds.length,
228
+ 'createTemporaryToken: Could not determine cozyBankId from account or konnector'
229
+ )
230
+ const jobResponse = await client.stackClient.jobs.create(
231
+ 'konnector',
232
+ {
233
+ mode: 'getTemporaryToken',
234
+ konnector: konnector.slug,
235
+ bankIds: cozyBankIds
236
+ },
237
+ {},
238
+ true
239
+ )
240
+ const event = await waitForRealtimeEvent(
241
+ client,
242
+ jobResponse.data.attributes,
243
+ 'result',
244
+ TEMP_TOKEN_TIMOUT_S * 1000
245
+ )
246
+ return event.data.result
182
247
  }
183
248
 
184
249
  export const konnectorPolicy = {
@@ -69,7 +69,7 @@ describe('handleOAuthAccount', () => {
69
69
  t,
70
70
  account: {
71
71
  ...account,
72
- ...{ auth: { bankId: TEST_BANK_COZY_ID } },
72
+ ...{ auth: { bankIds: [TEST_BANK_COZY_ID] } },
73
73
  ...{ data: { auth: { bi: { connId: 12 } } } }
74
74
  }
75
75
  })
@@ -27,6 +27,7 @@ import { mkConnAuth, biErrorMap } from 'cozy-bi-auth'
27
27
  import { KonnectorJobError } from '../helpers/konnectors'
28
28
  import { LOGIN_SUCCESS_EVENT } from '../models/flowEvents'
29
29
  import logger from '../logger'
30
+ import '../types'
30
31
 
31
32
  const DECOUPLED_ERROR = 'decoupled'
32
33
  const ADDITIONAL_INFORMATION_NEEDED_ERROR = 'additionalInformationNeeded'
@@ -292,19 +293,6 @@ export const resumeBIConnection = flow => {
292
293
  return updateBIConnectionFromFlow(flow, { resume: 'true' })
293
294
  }
294
295
 
295
- /**
296
- * @typedef biConnection
297
- * @property {number} id
298
- * @property {number} id_user
299
- * @property {number} id_connector
300
- * @property {string|null} state - ( wrongpass | additionalInformationNeeded | websiteUnavailable | actionNeeded | SCARequired | decoupled | passwordExpired | webauthRequired | rateLimiting | bug). Null indicates a success
301
- * @property {string|null} last_update - Date string: Last successful update.
302
- * @property {string|null} created - Date string: Creation date
303
- * @property {boolean} active - Whether this connection is active and will be automatically synced.
304
- * @property {string|null} last_push - Date string: Last successfull push
305
- * @property {string|null} next_try - Date string: Date of next synchronization.
306
- */
307
-
308
296
  /**
309
297
  * Checks for any number 2FA and/or decoupled requests
310
298
  *
package/src/types.js ADDED
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @typedef createTemporaryTokenResponse
3
+ * @property {String} code - the temporary token
4
+ * @property {String} url - BI environment url
5
+ * @property {String} bankId - Cozy bank id corresponding to the current connector (deprecated once bi webviews are in production)
6
+ * @property {String} biBankId - BI bank id corresponding to the bankId translated by the connector (deprecated once bi webviews are in production)
7
+ * @property {Array<String>} bankIds - Cozy bank ids corresponding to the current connector
8
+ * @property {Array<String>} biBankIds - BI bank ids corresponding to the bankIds translated by the connector
9
+ */
10
+
11
+ /**
12
+ * @typedef biConnection
13
+ * @property {number} id
14
+ * @property {number} id_user
15
+ * @property {number} id_connector
16
+ * @property {string|null} state - ( wrongpass | additionalInformationNeeded | websiteUnavailable | actionNeeded | SCARequired | decoupled | passwordExpired | webauthRequired | rateLimiting | bug). Null indicates a success
17
+ * @property {string|null} last_update - Date string: Last successful update.
18
+ * @property {string|null} created - Date string: Creation date
19
+ * @property {boolean} active - Whether this connection is active and will be automatically synced.
20
+ * @property {string|null} last_push - Date string: Last successfull push
21
+ * @property {string|null} next_try - Date string: Date of next synchronization.
22
+ */