cozy-harvest-lib 9.4.0 → 9.6.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,36 @@
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.6.0](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@9.5.1...cozy-harvest-lib@9.6.0) (2022-06-01)
7
+
8
+
9
+ ### Features
10
+
11
+ * Trigger success sooner for BI webviews ([b0dbd39](https://github.com/cozy/cozy-libs/commit/b0dbd396552cfa3cc7ae2972e500c449331ba83b))
12
+
13
+
14
+
15
+
16
+
17
+ ## [9.5.1](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@9.5.0...cozy-harvest-lib@9.5.1) (2022-05-25)
18
+
19
+ **Note:** Version bump only for package cozy-harvest-lib
20
+
21
+
22
+
23
+
24
+
25
+ # [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)
26
+
27
+
28
+ ### Features
29
+
30
+ * Handle banks with mulitple bank ids ([a944201](https://github.com/cozy/cozy-libs/commit/a944201ca5752766a49689f42531c84f03798002))
31
+
32
+
33
+
34
+
35
+
6
36
  # [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
37
 
8
38
 
@@ -18,8 +18,12 @@ 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
+ import { LOGIN_SUCCESS_EVENT } from '../models/flowEvents';
26
+ var TEMP_TOKEN_TIMOUT_S = 60;
23
27
  export var isBiWebViewConnector = function isBiWebViewConnector(konnector) {
24
28
  return flag('harvest.bi.webview') && isBudgetInsightConnector(konnector);
25
29
  };
@@ -116,19 +120,19 @@ export var checkBIConnection = /*#__PURE__*/function () {
116
120
 
117
121
  export var handleOAuthAccount = /*#__PURE__*/function () {
118
122
  var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(_ref3) {
119
- var account, flow, konnector, client, t, cozyBankId, biWebviewAccount, connectionId;
123
+ var account, flow, konnector, client, t, cozyBankIds, biWebviewAccount, connectionId;
120
124
  return _regeneratorRuntime.wrap(function _callee2$(_context2) {
121
125
  while (1) {
122
126
  switch (_context2.prev = _context2.next) {
123
127
  case 0:
124
128
  account = _ref3.account, flow = _ref3.flow, konnector = _ref3.konnector, client = _ref3.client, t = _ref3.t;
125
- cozyBankId = getCozyBankId({
129
+ cozyBankIds = getCozyBankIds({
126
130
  konnector: konnector,
127
131
  account: account
128
132
  });
129
- biWebviewAccount = _objectSpread(_objectSpread({}, account), cozyBankId ? {
133
+ biWebviewAccount = _objectSpread(_objectSpread({}, account), cozyBankIds ? {
130
134
  auth: {
131
- bankId: cozyBankId
135
+ bankIds: cozyBankIds
132
136
  }
133
137
  } : {});
134
138
  connectionId = getWebviewBIConnectionId(biWebviewAccount);
@@ -196,7 +200,7 @@ var getWebviewBIConnectionId = function getWebviewBIConnectionId(account) {
196
200
 
197
201
  export var onBIAccountCreation = /*#__PURE__*/function () {
198
202
  var _ref6 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(_ref5) {
199
- var fullAccount, client, flow, konnector, account, biConnection;
203
+ var fullAccount, client, flow, konnector, account, biConnection, updatedAccount;
200
204
  return _regeneratorRuntime.wrap(function _callee3$(_context3) {
201
205
  while (1) {
202
206
  switch (_context3.prev = _context3.next) {
@@ -226,9 +230,11 @@ export var onBIAccountCreation = /*#__PURE__*/function () {
226
230
  return flow.saveAccount(setBIConnectionId(account, biConnection.id));
227
231
 
228
232
  case 10:
229
- return _context3.abrupt("return", _context3.sent);
233
+ updatedAccount = _context3.sent;
234
+ flow.triggerEvent(LOGIN_SUCCESS_EVENT);
235
+ return _context3.abrupt("return", updatedAccount);
230
236
 
231
- case 11:
237
+ case 13:
232
238
  case "end":
233
239
  return _context3.stop();
234
240
  }
@@ -240,26 +246,125 @@ export var onBIAccountCreation = /*#__PURE__*/function () {
240
246
  return _ref6.apply(this, arguments);
241
247
  };
242
248
  }();
249
+ export var fetchExtraOAuthUrlParams = /*#__PURE__*/function () {
250
+ var _ref8 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4(_ref7) {
251
+ var client, konnector, account, _yield$createTemporar, token, biBankId, biBankIds;
252
+
253
+ return _regeneratorRuntime.wrap(function _callee4$(_context4) {
254
+ while (1) {
255
+ switch (_context4.prev = _context4.next) {
256
+ case 0:
257
+ client = _ref7.client, konnector = _ref7.konnector, account = _ref7.account;
258
+ _context4.next = 3;
259
+ return createTemporaryToken({
260
+ client: client,
261
+ konnector: konnector,
262
+ account: account
263
+ });
264
+
265
+ case 3:
266
+ _yield$createTemporar = _context4.sent;
267
+ token = _yield$createTemporar.code;
268
+ biBankId = _yield$createTemporar.biBankId;
269
+ biBankIds = _yield$createTemporar.biBankIds;
270
+ return _context4.abrupt("return", {
271
+ id_connector: biBankId || biBankIds,
272
+ token: token
273
+ });
274
+
275
+ case 8:
276
+ case "end":
277
+ return _context4.stop();
278
+ }
279
+ }
280
+ }, _callee4);
281
+ }));
282
+
283
+ return function fetchExtraOAuthUrlParams(_x4) {
284
+ return _ref8.apply(this, arguments);
285
+ };
286
+ }();
243
287
  /**
244
288
  * Finds the current bankIid in a given konnector or account
245
289
  *
246
290
  * @param {io.cozy.accounts} options.account The account content
247
291
  * @param {io.cozy.konnectors} options.konnector connector manifest content
292
+ * @return {Array<String>} - list of bank ids
248
293
  */
249
294
 
250
- export var getCozyBankId = function getCozyBankId(_ref7) {
251
- var _konnector$parameters, _account$auth;
295
+ export var getCozyBankIds = function getCozyBankIds(_ref9) {
296
+ var _konnector$parameters, _account$auth, _konnector$fields, _konnector$fields$ban;
252
297
 
253
- var konnector = _ref7.konnector,
254
- account = _ref7.account;
298
+ var konnector = _ref9.konnector,
299
+ account = _ref9.account;
255
300
  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
301
 
257
- if (!cozyBankId) {
302
+ if (cozyBankId) {
303
+ return [cozyBankId];
304
+ }
305
+
306
+ 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) {
307
+ return opt === null || opt === void 0 ? void 0 : opt.value;
308
+ });
309
+
310
+ if (!(cozyBankIds !== null && cozyBankIds !== void 0 && cozyBankIds.length)) {
258
311
  logger.error('Could not find any bank id');
259
312
  }
260
313
 
261
- return cozyBankId;
314
+ return cozyBankIds;
262
315
  };
316
+ /**
317
+ * Gets a temporary token corresponding to the current BI user
318
+ *
319
+ * @param {CozyClient} options.client - CozyClient instance
320
+ * @param {io.cozy.konnectors} options.konnector connector manifest content
321
+ * @param {io.cozy.accounts} options.account The account content
322
+ *
323
+ * @returns {createTemporaryTokenResponse}
324
+ */
325
+
326
+ export var createTemporaryToken = /*#__PURE__*/function () {
327
+ var _ref11 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5(_ref10) {
328
+ var client, konnector, account, cozyBankIds, jobResponse, event;
329
+ return _regeneratorRuntime.wrap(function _callee5$(_context5) {
330
+ while (1) {
331
+ switch (_context5.prev = _context5.next) {
332
+ case 0:
333
+ client = _ref10.client, konnector = _ref10.konnector, account = _ref10.account;
334
+ assert(konnector.slug, 'createTemporaryToken: konnector passed in options has no slug');
335
+ cozyBankIds = getCozyBankIds({
336
+ konnector: konnector,
337
+ account: account
338
+ });
339
+ assert(cozyBankIds.length, 'createTemporaryToken: Could not determine cozyBankId from account or konnector');
340
+ _context5.next = 6;
341
+ return client.stackClient.jobs.create('konnector', {
342
+ mode: 'getTemporaryToken',
343
+ konnector: konnector.slug,
344
+ bankIds: cozyBankIds
345
+ }, {}, true);
346
+
347
+ case 6:
348
+ jobResponse = _context5.sent;
349
+ _context5.next = 9;
350
+ return waitForRealtimeEvent(client, jobResponse.data.attributes, 'result', TEMP_TOKEN_TIMOUT_S * 1000);
351
+
352
+ case 9:
353
+ event = _context5.sent;
354
+ return _context5.abrupt("return", event.data.result);
355
+
356
+ case 11:
357
+ case "end":
358
+ return _context5.stop();
359
+ }
360
+ }
361
+ }, _callee5);
362
+ }));
363
+
364
+ return function createTemporaryToken(_x5) {
365
+ return _ref11.apply(this, arguments);
366
+ };
367
+ }();
263
368
  export var konnectorPolicy = {
264
369
  isBIWebView: true,
265
370
  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.6.0",
4
4
  "description": "Provides logic, modules and components for Cozy's harvest applications.",
5
5
  "main": "dist/index.js",
6
6
  "author": "Cozy",
@@ -44,7 +44,7 @@
44
44
  "@babel/cli": "7.16.8",
45
45
  "@babel/core": "7.16.12",
46
46
  "@babel/register": "7.16.9",
47
- "@cozy/cli-tree": "^0.5.0",
47
+ "@cozy/cli-tree": "^0.6.0",
48
48
  "@material-ui/core": "4.11.3",
49
49
  "@material-ui/lab": "4.0.0-alpha.60",
50
50
  "@testing-library/jest-dom": "5.16.4",
@@ -87,5 +87,5 @@
87
87
  "react-router-dom": "^5.0.1"
88
88
  },
89
89
  "sideEffects": false,
90
- "gitHead": "9ab356f1f7eea371ff0d364ec1eb740aa8d4fd47"
90
+ "gitHead": "24403169dfb9d4df1a754248b55f663d1161d166"
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,11 @@ 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
+ import { LOGIN_SUCCESS_EVENT } from '../models/flowEvents'
22
+
23
+ const TEMP_TOKEN_TIMOUT_S = 60
21
24
 
22
25
  export const isBiWebViewConnector = konnector =>
23
26
  flag('harvest.bi.webview') && isBudgetInsightConnector(konnector)
@@ -94,10 +97,10 @@ export const handleOAuthAccount = async ({
94
97
  client,
95
98
  t
96
99
  }) => {
97
- const cozyBankId = getCozyBankId({ konnector, account })
100
+ const cozyBankIds = getCozyBankIds({ konnector, account })
98
101
  let biWebviewAccount = {
99
102
  ...account,
100
- ...(cozyBankId ? { auth: { bankId: cozyBankId } } : {})
103
+ ...(cozyBankIds ? { auth: { bankIds: cozyBankIds } } : {})
101
104
  }
102
105
 
103
106
  const connectionId = getWebviewBIConnectionId(biWebviewAccount)
@@ -164,7 +167,31 @@ export const onBIAccountCreation = async ({
164
167
  biConnection
165
168
  })
166
169
 
167
- return await flow.saveAccount(setBIConnectionId(account, biConnection.id))
170
+ const updatedAccount = await flow.saveAccount(
171
+ setBIConnectionId(account, biConnection.id)
172
+ )
173
+
174
+ flow.triggerEvent(LOGIN_SUCCESS_EVENT)
175
+
176
+ return updatedAccount
177
+ }
178
+
179
+ export const fetchExtraOAuthUrlParams = async ({
180
+ client,
181
+ konnector,
182
+ account
183
+ }) => {
184
+ const {
185
+ code: token,
186
+ biBankId,
187
+ biBankIds
188
+ } = await createTemporaryToken({
189
+ client,
190
+ konnector,
191
+ account
192
+ })
193
+
194
+ return { id_connector: biBankId || biBankIds, token }
168
195
  }
169
196
 
170
197
  /**
@@ -172,13 +199,58 @@ export const onBIAccountCreation = async ({
172
199
  *
173
200
  * @param {io.cozy.accounts} options.account The account content
174
201
  * @param {io.cozy.konnectors} options.konnector connector manifest content
202
+ * @return {Array<String>} - list of bank ids
175
203
  */
176
- export const getCozyBankId = ({ konnector, account }) => {
204
+ export const getCozyBankIds = ({ konnector, account }) => {
177
205
  const cozyBankId = konnector?.parameters?.bankId || account?.auth?.bankId
178
- if (!cozyBankId) {
206
+
207
+ if (cozyBankId) {
208
+ return [cozyBankId]
209
+ }
210
+
211
+ const cozyBankIds = konnector?.fields?.bankId?.options.map(opt => opt?.value)
212
+ if (!cozyBankIds?.length) {
179
213
  logger.error('Could not find any bank id')
180
214
  }
181
- return cozyBankId
215
+ return cozyBankIds
216
+ }
217
+
218
+ /**
219
+ * Gets a temporary token corresponding to the current BI user
220
+ *
221
+ * @param {CozyClient} options.client - CozyClient instance
222
+ * @param {io.cozy.konnectors} options.konnector connector manifest content
223
+ * @param {io.cozy.accounts} options.account The account content
224
+ *
225
+ * @returns {createTemporaryTokenResponse}
226
+ */
227
+ export const createTemporaryToken = async ({ client, konnector, account }) => {
228
+ assert(
229
+ konnector.slug,
230
+ 'createTemporaryToken: konnector passed in options has no slug'
231
+ )
232
+ const cozyBankIds = getCozyBankIds({ konnector, account })
233
+ assert(
234
+ cozyBankIds.length,
235
+ 'createTemporaryToken: Could not determine cozyBankId from account or konnector'
236
+ )
237
+ const jobResponse = await client.stackClient.jobs.create(
238
+ 'konnector',
239
+ {
240
+ mode: 'getTemporaryToken',
241
+ konnector: konnector.slug,
242
+ bankIds: cozyBankIds
243
+ },
244
+ {},
245
+ true
246
+ )
247
+ const event = await waitForRealtimeEvent(
248
+ client,
249
+ jobResponse.data.attributes,
250
+ 'result',
251
+ TEMP_TOKEN_TIMOUT_S * 1000
252
+ )
253
+ return event.data.result
182
254
  }
183
255
 
184
256
  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
+ */