cozy-harvest-lib 9.1.0 → 9.2.1

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,48 @@
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.2.1](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@9.2.0...cozy-harvest-lib@9.2.1) (2022-05-09)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * bump react-dom from 16.12.0 to 16.13.0 ([2a5b850](https://github.com/cozy/cozy-libs/commit/2a5b8509555f061b136a4b5f2e38b36eb75ea0be))
12
+
13
+
14
+
15
+
16
+
17
+ # [9.2.0](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@9.1.2...cozy-harvest-lib@9.2.0) (2022-05-09)
18
+
19
+
20
+ ### Features
21
+
22
+ * Add BI connection creation via BI webview ([35ea078](https://github.com/cozy/cozy-libs/commit/35ea07805b5604d7882051bc0f7b43b38516922f))
23
+ * Unit tests + comments ([93e960e](https://github.com/cozy/cozy-libs/commit/93e960ee3236df742b8665d4d79cf6cf675d4f8f))
24
+
25
+
26
+
27
+
28
+
29
+ ## 9.1.2 (2022-05-05)
30
+
31
+ **Note:** Version bump only for package cozy-harvest-lib
32
+
33
+
34
+
35
+
36
+
37
+ ## [9.1.1](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@9.1.0...cozy-harvest-lib@9.1.1) (2022-05-02)
38
+
39
+
40
+ ### Bug Fixes
41
+
42
+ * bump form-data from 3.0.0 to 4.0.0 ([0a8546f](https://github.com/cozy/cozy-libs/commit/0a8546f2712a8164ff2bd08dfb60230bf97e1b85))
43
+
44
+
45
+
46
+
47
+
6
48
  # [9.1.0](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@9.0.0...cozy-harvest-lib@9.1.0) (2022-05-02)
7
49
 
8
50
 
@@ -522,8 +522,9 @@ export var DumbTriggerManager = /*#__PURE__*/function (_Component) {
522
522
  var showSpinner = submitting && selectedCipher && step === 'ciphersList';
523
523
  var showCiphersList = step === 'ciphersList';
524
524
  var showAccountForm = step === 'accountForm';
525
+ var konnectorPolicy = findKonnectorPolicy(konnector);
525
526
 
526
- if (oauth) {
527
+ if (oauth || konnectorPolicy.isBIWebView) {
527
528
  return /*#__PURE__*/React.createElement(OAuthForm, {
528
529
  client: client,
529
530
  flow: flow,
@@ -88,7 +88,7 @@ export var handleOAuthResponse = function handleOAuthResponse() {
88
88
  * @param {string} cozyUrl cozy url
89
89
  * @param {string} accountType connector slug
90
90
  * @param {string} oAuthStateKey localStorage key
91
- * @param {Object} oAuthConf connector manifest oauth configuration
91
+ * @param {Object} [oAuthConf={}] connector manifest oauth configuration
92
92
  * @param {string} redirectSlug The app we want to redirect the user on after the end of the flow
93
93
  * @param {string} nonce unique nonce string
94
94
  * @param {Object} extraParams some extra parameters to add to the query string
@@ -98,7 +98,8 @@ export var getOAuthUrl = function getOAuthUrl(_ref) {
98
98
  var cozyUrl = _ref.cozyUrl,
99
99
  accountType = _ref.accountType,
100
100
  oAuthStateKey = _ref.oAuthStateKey,
101
- oAuthConf = _ref.oAuthConf,
101
+ _ref$oAuthConf = _ref.oAuthConf,
102
+ oAuthConf = _ref$oAuthConf === void 0 ? {} : _ref$oAuthConf,
102
103
  nonce = _ref.nonce,
103
104
  redirectSlug = _ref.redirectSlug,
104
105
  extraParams = _ref.extraParams;
@@ -1,5 +1,6 @@
1
1
  import logger from './logger';
2
2
  import { konnectorPolicy as biKonnectorPolicy } from './services/budget-insight';
3
+ import { konnectorPolicy as biWebViewPolicy } from './services/biWebView';
3
4
  var defaultKonnectorPolicy = {
4
5
  accountContainsAuth: true,
5
6
  saveInVault: true,
@@ -9,7 +10,7 @@ var defaultKonnectorPolicy = {
9
10
  },
10
11
  name: 'default'
11
12
  };
12
- var policies = [biKonnectorPolicy, defaultKonnectorPolicy].filter(Boolean);
13
+ var policies = [biWebViewPolicy, biKonnectorPolicy, defaultKonnectorPolicy].filter(Boolean);
13
14
  logger.info('Available konnector policies', policies);
14
15
  export var findKonnectorPolicy = function findKonnectorPolicy(konnector) {
15
16
  var policy = policies.find(function (policy) {
@@ -0,0 +1,271 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
3
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
4
+ var _excluded = ["code"];
5
+
6
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
7
+
8
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
9
+
10
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
11
+
12
+ /**
13
+ * Interface between Budget Insight and Cozy using BI's webview
14
+ *
15
+ * - Deals with the konnector to get temporary tokens
16
+ */
17
+ import { getBIConnection } from './bi-http';
18
+ import assert from '../assert';
19
+ import logger from '../logger';
20
+ import flag from 'cozy-flags';
21
+ import { fetchExtraOAuthUrlParams, createTemporaryToken, setBIConnectionId, saveBIConfig, findAccountWithBiConnection, convertBIErrortoKonnectorJobError, isBudgetInsightConnector } from './budget-insight';
22
+ import { KonnectorJobError } from '../helpers/konnectors';
23
+ export var isBiWebViewConnector = function isBiWebViewConnector(konnector) {
24
+ return flag('harvest.bi.webview') && isBudgetInsightConnector(konnector);
25
+ };
26
+ /**
27
+ * Runs multiple checks on the bi connection referenced in the given account
28
+ *
29
+ * @param {io.cozy.accounts} options.account The account content
30
+ * @param {ConnectionFlow} options.flow
31
+ * @param {io.cozy.konnectors} options.konnector connector manifest content
32
+ * @param {CozyClient} options.client CozyClient object
33
+ *
34
+ * @return {Integer} Connection Id
35
+ */
36
+
37
+ export var checkBIConnection = /*#__PURE__*/function () {
38
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(_ref) {
39
+ var account, client, konnector, flow, connId, biConfig, tempToken, config, connection, sameAccount, err;
40
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
41
+ while (1) {
42
+ switch (_context.prev = _context.next) {
43
+ case 0:
44
+ account = _ref.account, client = _ref.client, konnector = _ref.konnector, flow = _ref.flow;
45
+ _context.prev = 1;
46
+ connId = getWebviewBIConnectionId(account);
47
+ logger.info('Creating temporary token...');
48
+ _context.next = 6;
49
+ return createTemporaryToken({
50
+ client: client,
51
+ konnector: konnector,
52
+ account: account
53
+ });
54
+
55
+ case 6:
56
+ biConfig = _context.sent;
57
+ saveBIConfig(flow, biConfig);
58
+ tempToken = biConfig.code, config = _objectWithoutProperties(biConfig, _excluded);
59
+ logger.info('Created temporary token');
60
+ assert(tempToken, 'No temporary token');
61
+ logger.info("fetch connection ".concat(connId, "..."));
62
+ _context.next = 14;
63
+ return getBIConnection(config, connId, tempToken);
64
+
65
+ case 14:
66
+ connection = _context.sent;
67
+ _context.next = 17;
68
+ return findAccountWithBiConnection({
69
+ client: client,
70
+ konnector: konnector,
71
+ connectionId: connection.id
72
+ });
73
+
74
+ case 17:
75
+ sameAccount = _context.sent;
76
+
77
+ if (!sameAccount) {
78
+ _context.next = 22;
79
+ break;
80
+ }
81
+
82
+ err = new KonnectorJobError('ACCOUNT_WITH_SAME_IDENTIFIER_ALREADY_DEFINED');
83
+ err.accountId = sameAccount._id;
84
+ throw err;
85
+
86
+ case 22:
87
+ return _context.abrupt("return", connection);
88
+
89
+ case 25:
90
+ _context.prev = 25;
91
+ _context.t0 = _context["catch"](1);
92
+ return _context.abrupt("return", convertBIErrortoKonnectorJobError(_context.t0));
93
+
94
+ case 28:
95
+ case "end":
96
+ return _context.stop();
97
+ }
98
+ }
99
+ }, _callee, null, [[1, 25]]);
100
+ }));
101
+
102
+ return function checkBIConnection(_x) {
103
+ return _ref2.apply(this, arguments);
104
+ };
105
+ }();
106
+ /**
107
+ * Handles webview connection
108
+ *
109
+ * @param {io.cozy.accounts} options.account The account content
110
+ * @param {ConnectionFlow} options.flow
111
+ * @param {io.cozy.konnectors} options.konnector connector manifest content
112
+ * @param {CozyClient} options.client CozyClient object
113
+ *
114
+ * @return {Integer} Connection Id
115
+ */
116
+
117
+ export var handleOAuthAccount = /*#__PURE__*/function () {
118
+ var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(_ref3) {
119
+ var account, flow, konnector, client, t, cozyBankId, biWebviewAccount, connectionId;
120
+ return _regeneratorRuntime.wrap(function _callee2$(_context2) {
121
+ while (1) {
122
+ switch (_context2.prev = _context2.next) {
123
+ case 0:
124
+ account = _ref3.account, flow = _ref3.flow, konnector = _ref3.konnector, client = _ref3.client, t = _ref3.t;
125
+ cozyBankId = getCozyBankId({
126
+ konnector: konnector,
127
+ account: account
128
+ });
129
+ biWebviewAccount = _objectSpread(_objectSpread({}, account), cozyBankId ? {
130
+ auth: {
131
+ bankId: cozyBankId
132
+ }
133
+ } : {});
134
+ connectionId = getWebviewBIConnectionId(biWebviewAccount);
135
+
136
+ if (!connectionId) {
137
+ _context2.next = 12;
138
+ break;
139
+ }
140
+
141
+ logger.info("Found a BI webview connection id: ".concat(connectionId));
142
+ flow.konnector = konnector;
143
+ _context2.next = 9;
144
+ return flow.saveAccount(setBIConnectionId(biWebviewAccount, connectionId));
145
+
146
+ case 9:
147
+ biWebviewAccount = _context2.sent;
148
+ _context2.next = 12;
149
+ return flow.handleFormSubmit({
150
+ client: client,
151
+ account: biWebviewAccount,
152
+ konnector: konnector,
153
+ t: t
154
+ });
155
+
156
+ case 12:
157
+ return _context2.abrupt("return", connectionId);
158
+
159
+ case 13:
160
+ case "end":
161
+ return _context2.stop();
162
+ }
163
+ }
164
+ }, _callee2);
165
+ }));
166
+
167
+ return function handleOAuthAccount(_x2) {
168
+ return _ref4.apply(this, arguments);
169
+ };
170
+ }();
171
+ /**
172
+ * Gets BI webview connection id which is returned in the account by the stack
173
+ * via oauth callback url
174
+ *
175
+ * @param {io.cozy.accounts} The account content created by the stack
176
+ *
177
+ * @return {Integer} Connection Id
178
+ */
179
+
180
+ var getWebviewBIConnectionId = function getWebviewBIConnectionId(account) {
181
+ var _account$oauth, _account$oauth$query, _account$oauth$query$;
182
+
183
+ return Number((account === null || account === void 0 ? void 0 : (_account$oauth = account.oauth) === null || _account$oauth === void 0 ? void 0 : (_account$oauth$query = _account$oauth.query) === null || _account$oauth$query === void 0 ? void 0 : (_account$oauth$query$ = _account$oauth$query.connection_id) === null || _account$oauth$query$ === void 0 ? void 0 : _account$oauth$query$[0]) || null);
184
+ };
185
+ /**
186
+ * Hook from ConnectionFlow after account creation
187
+ *
188
+ * @param {io.cozy.accounts} options.account - created account
189
+ * @param {io.cozy.konnectors} options.konnector - manifest of the konnector for which the account is created
190
+ * @param {ConnectionFlow} options.flow - current ConnectionFlow instance
191
+ * @param {CozyClient} options.client - current CozyClient instance
192
+ *
193
+ * @returns {Promise<io.cozy.accounts>}
194
+ */
195
+
196
+
197
+ export var onBIAccountCreation = /*#__PURE__*/function () {
198
+ var _ref6 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(_ref5) {
199
+ var fullAccount, client, flow, konnector, account, biConnection;
200
+ return _regeneratorRuntime.wrap(function _callee3$(_context3) {
201
+ while (1) {
202
+ switch (_context3.prev = _context3.next) {
203
+ case 0:
204
+ fullAccount = _ref5.account, client = _ref5.client, flow = _ref5.flow, konnector = _ref5.konnector;
205
+ _context3.next = 3;
206
+ return flow.saveAccount(fullAccount);
207
+
208
+ case 3:
209
+ account = _context3.sent;
210
+ _context3.next = 6;
211
+ return checkBIConnection({
212
+ account: _objectSpread(_objectSpread({}, fullAccount), {}, {
213
+ _id: account._id
214
+ }),
215
+ client: client,
216
+ konnector: konnector,
217
+ flow: flow
218
+ });
219
+
220
+ case 6:
221
+ biConnection = _context3.sent;
222
+ flow.setData({
223
+ biConnection: biConnection
224
+ });
225
+ _context3.next = 10;
226
+ return flow.saveAccount(setBIConnectionId(account, biConnection.id));
227
+
228
+ case 10:
229
+ return _context3.abrupt("return", _context3.sent);
230
+
231
+ case 11:
232
+ case "end":
233
+ return _context3.stop();
234
+ }
235
+ }
236
+ }, _callee3);
237
+ }));
238
+
239
+ return function onBIAccountCreation(_x3) {
240
+ return _ref6.apply(this, arguments);
241
+ };
242
+ }();
243
+ /**
244
+ * Finds the current bankIid in a given konnector or account
245
+ *
246
+ * @param {io.cozy.accounts} options.account The account content
247
+ * @param {io.cozy.konnectors} options.konnector connector manifest content
248
+ */
249
+
250
+ export var getCozyBankId = function getCozyBankId(_ref7) {
251
+ var _konnector$parameters, _account$auth;
252
+
253
+ var konnector = _ref7.konnector,
254
+ account = _ref7.account;
255
+ 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
+
257
+ if (!cozyBankId) {
258
+ logger.error('Could not find any bank id');
259
+ }
260
+
261
+ return cozyBankId;
262
+ };
263
+ export var konnectorPolicy = {
264
+ isBIWebView: true,
265
+ name: 'budget-insight-webview',
266
+ match: isBiWebViewConnector,
267
+ saveInVault: false,
268
+ onAccountCreation: onBIAccountCreation,
269
+ fetchExtraOAuthUrlParams: fetchExtraOAuthUrlParams,
270
+ handleOAuthAccount: handleOAuthAccount
271
+ };
@@ -0,0 +1,314 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
3
+
4
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
5
+
6
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
7
+
8
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
9
+ import CozyClient from 'cozy-client';
10
+ import { handleOAuthAccount, checkBIConnection, isBiWebViewConnector } from './biWebView';
11
+ import ConnectionFlow from '../models/ConnectionFlow';
12
+ import { waitForRealtimeEvent } from './jobUtils';
13
+ import biPublicKeyProd from './bi-public-key-prod.json';
14
+ import flag from 'cozy-flags';
15
+ jest.mock('./bi-http', function () {
16
+ return {
17
+ createBIConnection: jest.fn().mockResolvedValue({
18
+ text: Promise.resolve('{}')
19
+ }),
20
+ updateBIConnection: jest.fn(),
21
+ getBIConnection: jest.fn()
22
+ };
23
+ });
24
+ import { getBIConnection } from './bi-http';
25
+ jest.mock('cozy-logger', function () {
26
+ return {
27
+ namespace: function namespace() {
28
+ return function () {};
29
+ }
30
+ };
31
+ });
32
+ jest.mock('./jobUtils', function () {
33
+ return {
34
+ waitForRealtimeEvent: jest.fn()
35
+ };
36
+ });
37
+
38
+ var sleep = function sleep(duration) {
39
+ return new Promise(function (resolve) {
40
+ return setTimeout(resolve, duration);
41
+ });
42
+ };
43
+
44
+ var TEST_BANK_COZY_ID = '100000';
45
+ var konnector = {
46
+ slug: 'boursorama83',
47
+ parameters: {
48
+ bankId: TEST_BANK_COZY_ID
49
+ },
50
+ partnership: {
51
+ domain: 'https://budget-insight.com'
52
+ }
53
+ };
54
+ var account = {
55
+ _id: '1337'
56
+ };
57
+ describe('handleOAuthAccount', function () {
58
+ it('should handle bi webview authentication if any connection is found in the account', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
59
+ var client, flow, account, t;
60
+ return _regeneratorRuntime.wrap(function _callee2$(_context2) {
61
+ while (1) {
62
+ switch (_context2.prev = _context2.next) {
63
+ case 0:
64
+ client = new CozyClient({
65
+ uri: 'http://testcozy.mycozy.cloud'
66
+ });
67
+ flow = new ConnectionFlow(client, null, konnector);
68
+ flow.account = account;
69
+ flow.handleFormSubmit = jest.fn();
70
+
71
+ flow.saveAccount = /*#__PURE__*/function () {
72
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(account) {
73
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
74
+ while (1) {
75
+ switch (_context.prev = _context.next) {
76
+ case 0:
77
+ return _context.abrupt("return", account);
78
+
79
+ case 1:
80
+ case "end":
81
+ return _context.stop();
82
+ }
83
+ }
84
+ }, _callee);
85
+ }));
86
+
87
+ return function (_x) {
88
+ return _ref2.apply(this, arguments);
89
+ };
90
+ }();
91
+
92
+ account = {
93
+ oauth: {
94
+ query: {
95
+ connection_id: ['12']
96
+ }
97
+ }
98
+ };
99
+ t = jest.fn();
100
+ _context2.next = 9;
101
+ return handleOAuthAccount({
102
+ account: account,
103
+ flow: flow,
104
+ client: client,
105
+ konnector: konnector,
106
+ t: t
107
+ });
108
+
109
+ case 9:
110
+ expect(flow.handleFormSubmit).toHaveBeenCalledWith({
111
+ client: client,
112
+ konnector: konnector,
113
+ t: t,
114
+ account: _objectSpread(_objectSpread(_objectSpread({}, account), {
115
+ auth: {
116
+ bankId: TEST_BANK_COZY_ID
117
+ }
118
+ }), {
119
+ data: {
120
+ auth: {
121
+ bi: {
122
+ connId: 12
123
+ }
124
+ }
125
+ }
126
+ })
127
+ });
128
+
129
+ case 10:
130
+ case "end":
131
+ return _context2.stop();
132
+ }
133
+ }
134
+ }, _callee2);
135
+ })));
136
+ });
137
+ describe('checkBIConnection', function () {
138
+ var setup = function setup() {
139
+ var client = new CozyClient({
140
+ uri: 'http://testcozy.mycozy.cloud'
141
+ });
142
+ var flow = new ConnectionFlow(client, {
143
+ konnector: konnector,
144
+ account: account
145
+ });
146
+ client.stackClient.jobs.create = jest.fn().mockReturnValue({
147
+ data: {
148
+ attributes: {
149
+ _id: 'job-id-1337'
150
+ }
151
+ }
152
+ });
153
+ waitForRealtimeEvent.mockImplementation( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
154
+ return _regeneratorRuntime.wrap(function _callee3$(_context3) {
155
+ while (1) {
156
+ switch (_context3.prev = _context3.next) {
157
+ case 0:
158
+ sleep(2);
159
+ return _context3.abrupt("return", {
160
+ data: {
161
+ result: {
162
+ mode: 'prod',
163
+ url: 'https://cozy.biapi.pro/2.0',
164
+ publicKey: biPublicKeyProd,
165
+ code: 'bi-temporary-access-token-145613'
166
+ }
167
+ }
168
+ });
169
+
170
+ case 2:
171
+ case "end":
172
+ return _context3.stop();
173
+ }
174
+ }
175
+ }, _callee3);
176
+ })));
177
+ jest.spyOn(client, 'query').mockImplementation( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4() {
178
+ return _regeneratorRuntime.wrap(function _callee4$(_context4) {
179
+ while (1) {
180
+ switch (_context4.prev = _context4.next) {
181
+ case 0:
182
+ return _context4.abrupt("return", {
183
+ data: []
184
+ });
185
+
186
+ case 1:
187
+ case "end":
188
+ return _context4.stop();
189
+ }
190
+ }
191
+ }, _callee4);
192
+ })));
193
+ return {
194
+ client: client,
195
+ flow: flow
196
+ };
197
+ };
198
+
199
+ it('should refuse to create an account with a bi connection id which already exists', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee6() {
200
+ var _setup, client, flow, account, konnector;
201
+
202
+ return _regeneratorRuntime.wrap(function _callee6$(_context6) {
203
+ while (1) {
204
+ switch (_context6.prev = _context6.next) {
205
+ case 0:
206
+ _setup = setup(), client = _setup.client, flow = _setup.flow;
207
+ getBIConnection.mockReset().mockResolvedValue({
208
+ id: 12
209
+ });
210
+ account = {};
211
+ konnector = {
212
+ slug: 'bankingconnectortest',
213
+ parameters: {
214
+ bankId: TEST_BANK_COZY_ID
215
+ }
216
+ };
217
+ jest.spyOn(flow, 'saveAccount').mockImplementation(function (account) {
218
+ return _objectSpread({
219
+ _id: 'created-account-id'
220
+ }, account);
221
+ });
222
+ jest.spyOn(client, 'query').mockImplementation( /*#__PURE__*/function () {
223
+ var _ref7 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5(_ref6) {
224
+ var doctype;
225
+ return _regeneratorRuntime.wrap(function _callee5$(_context5) {
226
+ while (1) {
227
+ switch (_context5.prev = _context5.next) {
228
+ case 0:
229
+ doctype = _ref6.doctype;
230
+
231
+ if (!(doctype === 'io.cozy.accounts')) {
232
+ _context5.next = 5;
233
+ break;
234
+ }
235
+
236
+ return _context5.abrupt("return", {
237
+ data: [{
238
+ _id: 'account_id',
239
+ auth: {
240
+ bi: {
241
+ connId: 12
242
+ }
243
+ }
244
+ }]
245
+ });
246
+
247
+ case 5:
248
+ if (!(doctype === 'io.cozy.triggers')) {
249
+ _context5.next = 9;
250
+ break;
251
+ }
252
+
253
+ return _context5.abrupt("return", {
254
+ data: [{
255
+ message: {
256
+ account: 'account_id'
257
+ }
258
+ }]
259
+ });
260
+
261
+ case 9:
262
+ throw new Error('unexpected doctype ' + doctype);
263
+
264
+ case 10:
265
+ case "end":
266
+ return _context5.stop();
267
+ }
268
+ }
269
+ }, _callee5);
270
+ }));
271
+
272
+ return function (_x2) {
273
+ return _ref7.apply(this, arguments);
274
+ };
275
+ }());
276
+ _context6.next = 8;
277
+ return expect(checkBIConnection({
278
+ client: client,
279
+ flow: flow,
280
+ account: account,
281
+ konnector: konnector
282
+ })).rejects.toEqual(new Error('ACCOUNT_WITH_SAME_IDENTIFIER_ALREADY_DEFINED'));
283
+
284
+ case 8:
285
+ case "end":
286
+ return _context6.stop();
287
+ }
288
+ }
289
+ }, _callee6);
290
+ })));
291
+ });
292
+ describe('isBiWebViewConnector', function () {
293
+ var BIConnector = {
294
+ slug: 'biconnector',
295
+ partnership: {
296
+ domain: 'budget-insight.com'
297
+ }
298
+ };
299
+ var notBIConnector = {
300
+ slug: 'otherconnector'
301
+ };
302
+ it('should return true if the connector is a BI connector and if the "harvest.bi.webview" is activated', function () {
303
+ flag('harvest.bi.webview', true);
304
+ expect(isBiWebViewConnector(BIConnector)).toEqual(true);
305
+ });
306
+ it('should return false if the connector is not a BI connector', function () {
307
+ flag('harvest.bi.webview', true);
308
+ expect(isBiWebViewConnector(notBIConnector)).toEqual(false);
309
+ });
310
+ it('should return false if the "harvest.bi.webview" flag is not activated', function () {
311
+ flag('harvest.bi.webview', false);
312
+ expect(isBiWebViewConnector(BIConnector)).toEqual(false);
313
+ });
314
+ });
@@ -61,7 +61,7 @@ var extraBIErrorMap = {
61
61
  * Converts and chains error
62
62
  */
63
63
 
64
- var convertBIErrortoKonnectorJobError = function convertBIErrortoKonnectorJobError(error) {
64
+ export var convertBIErrortoKonnectorJobError = function convertBIErrortoKonnectorJobError(error) {
65
65
  var errorCode = error ? error.code : null;
66
66
  var cozyErrorMessage = errorCode ? biErrorMap[errorCode] || extraBIErrorMap[errorCode] || null : null;
67
67
  var errorMessage = cozyErrorMessage || (errorCode ? "UNKNOWN_ERROR.".concat(errorCode) : 'UNKNOWN_ERROR');
@@ -69,12 +69,12 @@ var convertBIErrortoKonnectorJobError = function convertBIErrortoKonnectorJobErr
69
69
  err.original = error;
70
70
  throw err;
71
71
  };
72
-
73
72
  export var isBudgetInsightConnector = function isBudgetInsightConnector(konnector) {
74
- return konnector.partnership && konnector.partnership.domain.includes('budget-insight');
75
- };
73
+ var _konnector$partnershi;
76
74
 
77
- var createTemporaryToken = /*#__PURE__*/function () {
75
+ return (konnector === null || konnector === void 0 ? void 0 : (_konnector$partnershi = konnector.partnership) === null || _konnector$partnershi === void 0 ? void 0 : _konnector$partnershi.domain) === 'budget-insight.com';
76
+ };
77
+ export var createTemporaryToken = /*#__PURE__*/function () {
78
78
  var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(_ref) {
79
79
  var client, konnector, account, cozyBankId, jobResponse, event;
80
80
  return _regeneratorRuntime.wrap(function _callee$(_context) {
@@ -116,7 +116,6 @@ var createTemporaryToken = /*#__PURE__*/function () {
116
116
  return _ref2.apply(this, arguments);
117
117
  };
118
118
  }();
119
-
120
119
  export var saveBIConfig = function saveBIConfig(flow, biConfig) {
121
120
  return flow.setData({
122
121
  biConfig: biConfig
@@ -281,9 +280,6 @@ export var setBIConnectionId = function setBIConnectionId(originalAccount, biCon
281
280
  set(account, 'data.auth.bi.connId', biConnectionId);
282
281
  return account;
283
282
  };
284
- export var getBIConnectionId = function getBIConnectionId(account) {
285
- return get(account, 'data.auth.bi.connId');
286
- };
287
283
  /**
288
284
  * Handles webauth connection
289
285
  *
@@ -90,7 +90,7 @@ var konnector = {
90
90
  bankId: TEST_BANK_COZY_ID
91
91
  },
92
92
  partnership: {
93
- domain: 'https://budget-insight.com'
93
+ domain: 'budget-insight.com'
94
94
  }
95
95
  };
96
96
  var konnectorWithoutParam = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-harvest-lib",
3
- "version": "9.1.0",
3
+ "version": "9.2.1",
4
4
  "description": "Provides logic, modules and components for Cozy's harvest applications.",
5
5
  "main": "dist/index.js",
6
6
  "author": "Cozy",
@@ -55,13 +55,13 @@
55
55
  "cozy-client": "27.17.0",
56
56
  "cozy-device-helper": "^2.0.0",
57
57
  "cozy-flags": "^2.8.7",
58
- "cozy-intent": "^1.17.1",
58
+ "cozy-intent": "^1.17.2",
59
59
  "cozy-keys-lib": "^4.1.9",
60
60
  "cozy-realtime": "^4.0.8",
61
61
  "cozy-ui": "60.6.0",
62
62
  "enzyme": "3.11.0",
63
63
  "enzyme-adapter-react-16": "1.15.6",
64
- "form-data": "3.0.0",
64
+ "form-data": "4.0.0",
65
65
  "identity-obj-proxy": "3.0.0",
66
66
  "jest": "26.6.3",
67
67
  "jest-environment-jsdom-sixteen": "1.0.3",
@@ -70,7 +70,7 @@
70
70
  "leaflet": "1.7.1",
71
71
  "prop-types": "15.7.2",
72
72
  "react": "16.12.0",
73
- "react-dom": "16.12.0",
73
+ "react-dom": "16.13.0",
74
74
  "react-swipeable-views": "0.13.9"
75
75
  },
76
76
  "peerDependencies": {
@@ -87,5 +87,5 @@
87
87
  "react-router-dom": "^5.0.1"
88
88
  },
89
89
  "sideEffects": false,
90
- "gitHead": "2e308c267a13adc3cd826639e3058fe35770d830"
90
+ "gitHead": "77b4f43e2da379fbd0f5a6269078b1ba5b4f3ede"
91
91
  }
@@ -326,8 +326,9 @@ export class DumbTriggerManager extends Component {
326
326
  const showSpinner = submitting && selectedCipher && step === 'ciphersList'
327
327
  const showCiphersList = step === 'ciphersList'
328
328
  const showAccountForm = step === 'accountForm'
329
+ const konnectorPolicy = findKonnectorPolicy(konnector)
329
330
 
330
- if (oauth) {
331
+ if (oauth || konnectorPolicy.isBIWebView) {
331
332
  return (
332
333
  <OAuthForm
333
334
  client={client}
@@ -92,7 +92,7 @@ export const handleOAuthResponse = (options = {}) => {
92
92
  * @param {string} cozyUrl cozy url
93
93
  * @param {string} accountType connector slug
94
94
  * @param {string} oAuthStateKey localStorage key
95
- * @param {Object} oAuthConf connector manifest oauth configuration
95
+ * @param {Object} [oAuthConf={}] connector manifest oauth configuration
96
96
  * @param {string} redirectSlug The app we want to redirect the user on after the end of the flow
97
97
  * @param {string} nonce unique nonce string
98
98
  * @param {Object} extraParams some extra parameters to add to the query string
@@ -101,7 +101,7 @@ export const getOAuthUrl = ({
101
101
  cozyUrl,
102
102
  accountType,
103
103
  oAuthStateKey,
104
- oAuthConf,
104
+ oAuthConf = {},
105
105
  nonce,
106
106
  redirectSlug,
107
107
  extraParams
@@ -1,5 +1,6 @@
1
1
  import logger from './logger'
2
2
  import { konnectorPolicy as biKonnectorPolicy } from './services/budget-insight'
3
+ import { konnectorPolicy as biWebViewPolicy } from './services/biWebView'
3
4
 
4
5
  const defaultKonnectorPolicy = {
5
6
  accountContainsAuth: true,
@@ -9,7 +10,11 @@ const defaultKonnectorPolicy = {
9
10
  name: 'default'
10
11
  }
11
12
 
12
- const policies = [biKonnectorPolicy, defaultKonnectorPolicy].filter(Boolean)
13
+ const policies = [
14
+ biWebViewPolicy,
15
+ biKonnectorPolicy,
16
+ defaultKonnectorPolicy
17
+ ].filter(Boolean)
13
18
 
14
19
  logger.info('Available konnector policies', policies)
15
20
 
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Interface between Budget Insight and Cozy using BI's webview
3
+ *
4
+ * - Deals with the konnector to get temporary tokens
5
+ */
6
+
7
+ import { getBIConnection } from './bi-http'
8
+ import assert from '../assert'
9
+ import logger from '../logger'
10
+ import flag from 'cozy-flags'
11
+ import {
12
+ fetchExtraOAuthUrlParams,
13
+ createTemporaryToken,
14
+ setBIConnectionId,
15
+ saveBIConfig,
16
+ findAccountWithBiConnection,
17
+ convertBIErrortoKonnectorJobError,
18
+ isBudgetInsightConnector
19
+ } from './budget-insight'
20
+ import { KonnectorJobError } from '../helpers/konnectors'
21
+
22
+ export const isBiWebViewConnector = konnector =>
23
+ flag('harvest.bi.webview') && isBudgetInsightConnector(konnector)
24
+
25
+ /**
26
+ * Runs multiple checks on the bi connection referenced in the given account
27
+ *
28
+ * @param {io.cozy.accounts} options.account The account content
29
+ * @param {ConnectionFlow} options.flow
30
+ * @param {io.cozy.konnectors} options.konnector connector manifest content
31
+ * @param {CozyClient} options.client CozyClient object
32
+ *
33
+ * @return {Integer} Connection Id
34
+ */
35
+ export const checkBIConnection = async ({
36
+ account,
37
+ client,
38
+ konnector,
39
+ flow
40
+ }) => {
41
+ try {
42
+ let connId = getWebviewBIConnectionId(account)
43
+
44
+ logger.info('Creating temporary token...')
45
+
46
+ const biConfig = await createTemporaryToken({
47
+ client,
48
+ konnector,
49
+ account
50
+ })
51
+ saveBIConfig(flow, biConfig)
52
+
53
+ const { code: tempToken, ...config } = biConfig
54
+
55
+ logger.info('Created temporary token')
56
+ assert(tempToken, 'No temporary token')
57
+
58
+ logger.info(`fetch connection ${connId}...`)
59
+
60
+ const connection = await getBIConnection(config, connId, tempToken)
61
+
62
+ const sameAccount = await findAccountWithBiConnection({
63
+ client,
64
+ konnector,
65
+ connectionId: connection.id
66
+ })
67
+ if (sameAccount) {
68
+ const err = new KonnectorJobError(
69
+ 'ACCOUNT_WITH_SAME_IDENTIFIER_ALREADY_DEFINED'
70
+ )
71
+ err.accountId = sameAccount._id
72
+ throw err
73
+ }
74
+ return connection
75
+ } catch (err) {
76
+ return convertBIErrortoKonnectorJobError(err)
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Handles webview connection
82
+ *
83
+ * @param {io.cozy.accounts} options.account The account content
84
+ * @param {ConnectionFlow} options.flow
85
+ * @param {io.cozy.konnectors} options.konnector connector manifest content
86
+ * @param {CozyClient} options.client CozyClient object
87
+ *
88
+ * @return {Integer} Connection Id
89
+ */
90
+ export const handleOAuthAccount = async ({
91
+ account,
92
+ flow,
93
+ konnector,
94
+ client,
95
+ t
96
+ }) => {
97
+ const cozyBankId = getCozyBankId({ konnector, account })
98
+ let biWebviewAccount = {
99
+ ...account,
100
+ ...(cozyBankId ? { auth: { bankId: cozyBankId } } : {})
101
+ }
102
+
103
+ const connectionId = getWebviewBIConnectionId(biWebviewAccount)
104
+
105
+ if (connectionId) {
106
+ logger.info(`Found a BI webview connection id: ${connectionId}`)
107
+ flow.konnector = konnector
108
+ biWebviewAccount = await flow.saveAccount(
109
+ setBIConnectionId(biWebviewAccount, connectionId)
110
+ )
111
+
112
+ await flow.handleFormSubmit({
113
+ client,
114
+ account: biWebviewAccount,
115
+ konnector,
116
+ t
117
+ })
118
+ }
119
+
120
+ return connectionId
121
+ }
122
+
123
+ /**
124
+ * Gets BI webview connection id which is returned in the account by the stack
125
+ * via oauth callback url
126
+ *
127
+ * @param {io.cozy.accounts} The account content created by the stack
128
+ *
129
+ * @return {Integer} Connection Id
130
+ */
131
+ const getWebviewBIConnectionId = account => {
132
+ return Number(account?.oauth?.query?.connection_id?.[0] || null)
133
+ }
134
+
135
+ /**
136
+ * Hook from ConnectionFlow after account creation
137
+ *
138
+ * @param {io.cozy.accounts} options.account - created account
139
+ * @param {io.cozy.konnectors} options.konnector - manifest of the konnector for which the account is created
140
+ * @param {ConnectionFlow} options.flow - current ConnectionFlow instance
141
+ * @param {CozyClient} options.client - current CozyClient instance
142
+ *
143
+ * @returns {Promise<io.cozy.accounts>}
144
+ */
145
+ export const onBIAccountCreation = async ({
146
+ account: fullAccount,
147
+ client,
148
+ flow,
149
+ konnector
150
+ }) => {
151
+ const account = await flow.saveAccount(fullAccount)
152
+
153
+ const biConnection = await checkBIConnection({
154
+ account: {
155
+ ...fullAccount,
156
+ _id: account._id
157
+ },
158
+ client,
159
+ konnector,
160
+ flow
161
+ })
162
+
163
+ flow.setData({
164
+ biConnection
165
+ })
166
+
167
+ return await flow.saveAccount(setBIConnectionId(account, biConnection.id))
168
+ }
169
+
170
+ /**
171
+ * Finds the current bankIid in a given konnector or account
172
+ *
173
+ * @param {io.cozy.accounts} options.account The account content
174
+ * @param {io.cozy.konnectors} options.konnector connector manifest content
175
+ */
176
+ export const getCozyBankId = ({ konnector, account }) => {
177
+ const cozyBankId = konnector?.parameters?.bankId || account?.auth?.bankId
178
+ if (!cozyBankId) {
179
+ logger.error('Could not find any bank id')
180
+ }
181
+ return cozyBankId
182
+ }
183
+
184
+ export const konnectorPolicy = {
185
+ isBIWebView: true,
186
+ name: 'budget-insight-webview',
187
+ match: isBiWebViewConnector,
188
+ saveInVault: false,
189
+ onAccountCreation: onBIAccountCreation,
190
+ fetchExtraOAuthUrlParams: fetchExtraOAuthUrlParams,
191
+ handleOAuthAccount
192
+ }
@@ -0,0 +1,185 @@
1
+ import CozyClient from 'cozy-client'
2
+ import {
3
+ handleOAuthAccount,
4
+ checkBIConnection,
5
+ isBiWebViewConnector
6
+ } from './biWebView'
7
+ import ConnectionFlow from '../models/ConnectionFlow'
8
+ import { waitForRealtimeEvent } from './jobUtils'
9
+ import biPublicKeyProd from './bi-public-key-prod.json'
10
+ import flag from 'cozy-flags'
11
+
12
+ jest.mock('./bi-http', () => ({
13
+ createBIConnection: jest
14
+ .fn()
15
+ .mockResolvedValue({ text: Promise.resolve('{}') }),
16
+ updateBIConnection: jest.fn(),
17
+ getBIConnection: jest.fn()
18
+ }))
19
+
20
+ import { getBIConnection } from './bi-http'
21
+
22
+ jest.mock('cozy-logger', () => ({
23
+ namespace: () => () => {}
24
+ }))
25
+
26
+ jest.mock('./jobUtils', () => ({
27
+ waitForRealtimeEvent: jest.fn()
28
+ }))
29
+
30
+ const sleep = duration => new Promise(resolve => setTimeout(resolve, duration))
31
+
32
+ const TEST_BANK_COZY_ID = '100000'
33
+
34
+ const konnector = {
35
+ slug: 'boursorama83',
36
+ parameters: {
37
+ bankId: TEST_BANK_COZY_ID
38
+ },
39
+ partnership: {
40
+ domain: 'https://budget-insight.com'
41
+ }
42
+ }
43
+
44
+ const account = {
45
+ _id: '1337'
46
+ }
47
+
48
+ describe('handleOAuthAccount', () => {
49
+ it('should handle bi webview authentication if any connection is found in the account', async () => {
50
+ const client = new CozyClient({
51
+ uri: 'http://testcozy.mycozy.cloud'
52
+ })
53
+ const flow = new ConnectionFlow(client, null, konnector)
54
+ flow.account = account
55
+ flow.handleFormSubmit = jest.fn()
56
+ flow.saveAccount = async account => account
57
+ const account = { oauth: { query: { connection_id: ['12'] } } }
58
+ const t = jest.fn()
59
+ await handleOAuthAccount({
60
+ account,
61
+ flow,
62
+ client,
63
+ konnector,
64
+ t
65
+ })
66
+ expect(flow.handleFormSubmit).toHaveBeenCalledWith({
67
+ client,
68
+ konnector,
69
+ t,
70
+ account: {
71
+ ...account,
72
+ ...{ auth: { bankId: TEST_BANK_COZY_ID } },
73
+ ...{ data: { auth: { bi: { connId: 12 } } } }
74
+ }
75
+ })
76
+ })
77
+ })
78
+
79
+ describe('checkBIConnection', () => {
80
+ const setup = () => {
81
+ const client = new CozyClient({
82
+ uri: 'http://testcozy.mycozy.cloud'
83
+ })
84
+ const flow = new ConnectionFlow(client, { konnector, account })
85
+ client.stackClient.jobs.create = jest.fn().mockReturnValue({
86
+ data: {
87
+ attributes: {
88
+ _id: 'job-id-1337'
89
+ }
90
+ }
91
+ })
92
+ waitForRealtimeEvent.mockImplementation(async () => {
93
+ sleep(2)
94
+ return {
95
+ data: {
96
+ result: {
97
+ mode: 'prod',
98
+ url: 'https://cozy.biapi.pro/2.0',
99
+ publicKey: biPublicKeyProd,
100
+ code: 'bi-temporary-access-token-145613'
101
+ }
102
+ }
103
+ }
104
+ })
105
+ jest.spyOn(client, 'query').mockImplementation(async () => ({ data: [] }))
106
+
107
+ return { client, flow }
108
+ }
109
+
110
+ it('should refuse to create an account with a bi connection id which already exists', async () => {
111
+ const { client, flow } = setup()
112
+
113
+ getBIConnection.mockReset().mockResolvedValue({
114
+ id: 12
115
+ })
116
+
117
+ const account = {}
118
+
119
+ const konnector = {
120
+ slug: 'bankingconnectortest',
121
+ parameters: {
122
+ bankId: TEST_BANK_COZY_ID
123
+ }
124
+ }
125
+
126
+ jest.spyOn(flow, 'saveAccount').mockImplementation(account => ({
127
+ _id: 'created-account-id',
128
+ ...account
129
+ }))
130
+
131
+ jest.spyOn(client, 'query').mockImplementation(async ({ doctype }) => {
132
+ if (doctype === 'io.cozy.accounts') {
133
+ return {
134
+ data: [
135
+ {
136
+ _id: 'account_id',
137
+ auth: { bi: { connId: 12 } }
138
+ }
139
+ ]
140
+ }
141
+ } else if (doctype === 'io.cozy.triggers') {
142
+ return {
143
+ data: [
144
+ {
145
+ message: { account: 'account_id' }
146
+ }
147
+ ]
148
+ }
149
+ } else {
150
+ throw new Error('unexpected doctype ' + doctype)
151
+ }
152
+ })
153
+
154
+ await expect(
155
+ checkBIConnection({
156
+ client,
157
+ flow,
158
+ account,
159
+ konnector
160
+ })
161
+ ).rejects.toEqual(new Error('ACCOUNT_WITH_SAME_IDENTIFIER_ALREADY_DEFINED'))
162
+ })
163
+ })
164
+
165
+ describe('isBiWebViewConnector', () => {
166
+ const BIConnector = {
167
+ slug: 'biconnector',
168
+ partnership: { domain: 'budget-insight.com' }
169
+ }
170
+ const notBIConnector = {
171
+ slug: 'otherconnector'
172
+ }
173
+ it('should return true if the connector is a BI connector and if the "harvest.bi.webview" is activated', () => {
174
+ flag('harvest.bi.webview', true)
175
+ expect(isBiWebViewConnector(BIConnector)).toEqual(true)
176
+ })
177
+ it('should return false if the connector is not a BI connector', () => {
178
+ flag('harvest.bi.webview', true)
179
+ expect(isBiWebViewConnector(notBIConnector)).toEqual(false)
180
+ })
181
+ it('should return false if the "harvest.bi.webview" flag is not activated', () => {
182
+ flag('harvest.bi.webview', false)
183
+ expect(isBiWebViewConnector(BIConnector)).toEqual(false)
184
+ })
185
+ })
@@ -52,7 +52,7 @@ const extraBIErrorMap = {
52
52
  /**
53
53
  * Converts and chains error
54
54
  */
55
- const convertBIErrortoKonnectorJobError = error => {
55
+ export const convertBIErrortoKonnectorJobError = error => {
56
56
  const errorCode = error ? error.code : null
57
57
  const cozyErrorMessage = errorCode
58
58
  ? biErrorMap[errorCode] || extraBIErrorMap[errorCode] || null
@@ -65,14 +65,10 @@ const convertBIErrortoKonnectorJobError = error => {
65
65
  throw err
66
66
  }
67
67
 
68
- export const isBudgetInsightConnector = konnector => {
69
- return (
70
- konnector.partnership &&
71
- konnector.partnership.domain.includes('budget-insight')
72
- )
73
- }
68
+ export const isBudgetInsightConnector = konnector =>
69
+ konnector?.partnership?.domain === 'budget-insight.com'
74
70
 
75
- const createTemporaryToken = async ({ client, konnector, account }) => {
71
+ export const createTemporaryToken = async ({ client, konnector, account }) => {
76
72
  assert(
77
73
  konnector.slug,
78
74
  'createTemporaryToken: konnector passed in options has no slug'
@@ -215,10 +211,6 @@ export const setBIConnectionId = (originalAccount, biConnectionId) => {
215
211
  return account
216
212
  }
217
213
 
218
- export const getBIConnectionId = account => {
219
- return get(account, 'data.auth.bi.connId')
220
- }
221
-
222
214
  /**
223
215
  * Handles webauth connection
224
216
  *
@@ -70,7 +70,7 @@ const konnector = {
70
70
  bankId: TEST_BANK_COZY_ID
71
71
  },
72
72
  partnership: {
73
- domain: 'https://budget-insight.com'
73
+ domain: 'budget-insight.com'
74
74
  }
75
75
  }
76
76