cozy-harvest-lib 9.22.2 → 9.23.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 +31 -0
- package/dist/components/InAppBrowser.js +109 -19
- package/dist/helpers/oauth.js +1 -1
- package/dist/helpers/oauth.spec.js +1 -1
- package/dist/services/biWebView.js +31 -1
- package/package.json +4 -3
- package/src/components/InAppBrowser.jsx +62 -18
- package/src/helpers/oauth.js +1 -1
- package/src/helpers/oauth.spec.js +1 -1
- package/src/services/biWebView.js +30 -3
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,37 @@
|
|
|
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.23.1](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@9.23.0...cozy-harvest-lib@9.23.1) (2022-07-26)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* Google connector in web mode ([1777fcc](https://github.com/cozy/cozy-libs/commit/1777fccc6b9e1e581189ca4563f851b341a60644))
|
|
12
|
+
* OauthWindowInAppBrowser re-render ([334e7d8](https://github.com/cozy/cozy-libs/commit/334e7d8b7d777bf265803f81583a65f39fb0cabb))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# [9.23.0](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@9.22.3...cozy-harvest-lib@9.23.0) (2022-07-26)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Features
|
|
22
|
+
|
|
23
|
+
* Add BI aggregator releationship to BI accounts ([cb7a79c](https://github.com/cozy/cozy-libs/commit/cb7a79c6cd72a9f8e95ae71307f27f04b68f0e94))
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
## [9.22.3](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@9.22.2...cozy-harvest-lib@9.22.3) (2022-07-26)
|
|
30
|
+
|
|
31
|
+
**Note:** Version bump only for package cozy-harvest-lib
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
6
37
|
## [9.22.2](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@9.22.1...cozy-harvest-lib@9.22.2) (2022-07-21)
|
|
7
38
|
|
|
8
39
|
**Note:** Version bump only for package cozy-harvest-lib
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
2
|
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
3
|
-
import { useEffect } from 'react';
|
|
3
|
+
import React, { useEffect } from 'react';
|
|
4
4
|
import PropTypes from 'prop-types';
|
|
5
5
|
import { useWebviewIntent } from 'cozy-intent';
|
|
6
6
|
import logger from '../logger';
|
|
@@ -9,22 +9,27 @@ import { intentsApiProptype } from '../helpers/proptypes';
|
|
|
9
9
|
var InAppBrowser = function InAppBrowser(_ref) {
|
|
10
10
|
var url = _ref.url,
|
|
11
11
|
onClose = _ref.onClose,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
return webviewIntent.call('showInAppBrowser', {
|
|
20
|
-
url: url
|
|
12
|
+
intentsApi = _ref.intentsApi;
|
|
13
|
+
|
|
14
|
+
if (intentsApi) {
|
|
15
|
+
return /*#__PURE__*/React.createElement(InAppBrowserWithIntentsApi, {
|
|
16
|
+
url: url,
|
|
17
|
+
onClose: onClose,
|
|
18
|
+
intentsApi: intentsApi
|
|
21
19
|
});
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
} else {
|
|
21
|
+
return /*#__PURE__*/React.createElement(InAppBrowserWithWebviewIntent, {
|
|
22
|
+
url: url,
|
|
23
|
+
onClose: onClose
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
var InAppBrowserWithWebviewIntent = function InAppBrowserWithWebviewIntent(_ref2) {
|
|
29
|
+
var url = _ref2.url,
|
|
30
|
+
onClose = _ref2.onClose;
|
|
31
|
+
var webviewIntent = useWebviewIntent();
|
|
32
|
+
var isReady = Boolean(webviewIntent);
|
|
28
33
|
useEffect(function () {
|
|
29
34
|
function insideEffect() {
|
|
30
35
|
return _insideEffect.apply(this, arguments);
|
|
@@ -45,19 +50,21 @@ var InAppBrowser = function InAppBrowser(_ref) {
|
|
|
45
50
|
_context.prev = 1;
|
|
46
51
|
logger.debug('url at the beginning: ', url);
|
|
47
52
|
_context.next = 5;
|
|
48
|
-
return fetchSessionCode
|
|
53
|
+
return webviewIntent.call('fetchSessionCode');
|
|
49
54
|
|
|
50
55
|
case 5:
|
|
51
56
|
sessionCode = _context.sent;
|
|
52
57
|
logger.debug('got session code', sessionCode);
|
|
53
58
|
iabUrl = new URL(url);
|
|
54
|
-
iabUrl.searchParams.append(
|
|
59
|
+
iabUrl.searchParams.append('session_code', sessionCode); // we need to decodeURIComponent since toString() encodes URL
|
|
55
60
|
// but native browser will also encode them.
|
|
56
61
|
|
|
57
62
|
urlToOpen = decodeURIComponent(iabUrl.toString());
|
|
58
63
|
logger.debug('url to open: ', urlToOpen);
|
|
59
64
|
_context.next = 13;
|
|
60
|
-
return showInAppBrowser
|
|
65
|
+
return webviewIntent.call('showInAppBrowser', {
|
|
66
|
+
url: urlToOpen
|
|
67
|
+
});
|
|
61
68
|
|
|
62
69
|
case 13:
|
|
63
70
|
result = _context.sent;
|
|
@@ -89,6 +96,89 @@ var InAppBrowser = function InAppBrowser(_ref) {
|
|
|
89
96
|
return _insideEffect.apply(this, arguments);
|
|
90
97
|
}
|
|
91
98
|
|
|
99
|
+
insideEffect();
|
|
100
|
+
return function cleanup() {
|
|
101
|
+
webviewIntent.call('closeInAppBrowser');
|
|
102
|
+
};
|
|
103
|
+
}, [isReady, url, onClose, webviewIntent]);
|
|
104
|
+
return null;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
var InAppBrowserWithIntentsApi = function InAppBrowserWithIntentsApi(_ref3) {
|
|
108
|
+
var url = _ref3.url,
|
|
109
|
+
onClose = _ref3.onClose,
|
|
110
|
+
_ref3$intentsApi = _ref3.intentsApi,
|
|
111
|
+
intentsApi = _ref3$intentsApi === void 0 ? {} : _ref3$intentsApi;
|
|
112
|
+
var fetchSessionCode = intentsApi.fetchSessionCode,
|
|
113
|
+
showInAppBrowser = intentsApi.showInAppBrowser,
|
|
114
|
+
closeInAppBrowser = intentsApi.closeInAppBrowser,
|
|
115
|
+
_intentsApi$tokenPara = intentsApi.tokenParamName,
|
|
116
|
+
tokenParamName = _intentsApi$tokenPara === void 0 ? 'session_code' : _intentsApi$tokenPara;
|
|
117
|
+
var isReady = Boolean((intentsApi === null || intentsApi === void 0 ? void 0 : intentsApi.fetchSessionCode) && (intentsApi === null || intentsApi === void 0 ? void 0 : intentsApi.showInAppBrowser) && (intentsApi === null || intentsApi === void 0 ? void 0 : intentsApi.closeInAppBrowser));
|
|
118
|
+
useEffect(function () {
|
|
119
|
+
function insideEffect() {
|
|
120
|
+
return _insideEffect2.apply(this, arguments);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function _insideEffect2() {
|
|
124
|
+
_insideEffect2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
|
|
125
|
+
var sessionCode, iabUrl, urlToOpen, result;
|
|
126
|
+
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
|
|
127
|
+
while (1) {
|
|
128
|
+
switch (_context2.prev = _context2.next) {
|
|
129
|
+
case 0:
|
|
130
|
+
if (!isReady) {
|
|
131
|
+
_context2.next = 21;
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
_context2.prev = 1;
|
|
136
|
+
logger.debug('url at the beginning: ', url);
|
|
137
|
+
_context2.next = 5;
|
|
138
|
+
return fetchSessionCode();
|
|
139
|
+
|
|
140
|
+
case 5:
|
|
141
|
+
sessionCode = _context2.sent;
|
|
142
|
+
logger.debug('got session code', sessionCode);
|
|
143
|
+
iabUrl = new URL(url);
|
|
144
|
+
iabUrl.searchParams.append(tokenParamName, sessionCode); // we need to decodeURIComponent since toString() encodes URL
|
|
145
|
+
// but native browser will also encode them.
|
|
146
|
+
|
|
147
|
+
urlToOpen = decodeURIComponent(iabUrl.toString());
|
|
148
|
+
logger.debug('url to open: ', urlToOpen);
|
|
149
|
+
_context2.next = 13;
|
|
150
|
+
return showInAppBrowser(urlToOpen);
|
|
151
|
+
|
|
152
|
+
case 13:
|
|
153
|
+
result = _context2.sent;
|
|
154
|
+
|
|
155
|
+
if ((result === null || result === void 0 ? void 0 : result.type) !== 'dismiss' && (result === null || result === void 0 ? void 0 : result.type) !== 'cancel') {
|
|
156
|
+
logger.error('Unexpected InAppBrowser result', result);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
_context2.next = 20;
|
|
160
|
+
break;
|
|
161
|
+
|
|
162
|
+
case 17:
|
|
163
|
+
_context2.prev = 17;
|
|
164
|
+
_context2.t0 = _context2["catch"](1);
|
|
165
|
+
logger.error('unexpected fetchSessionCode result', _context2.t0);
|
|
166
|
+
|
|
167
|
+
case 20:
|
|
168
|
+
if (onClose) {
|
|
169
|
+
onClose();
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
case 21:
|
|
173
|
+
case "end":
|
|
174
|
+
return _context2.stop();
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}, _callee2, null, [[1, 17]]);
|
|
178
|
+
}));
|
|
179
|
+
return _insideEffect2.apply(this, arguments);
|
|
180
|
+
}
|
|
181
|
+
|
|
92
182
|
insideEffect();
|
|
93
183
|
return function cleanup() {
|
|
94
184
|
closeInAppBrowser();
|
package/dist/helpers/oauth.js
CHANGED
|
@@ -118,7 +118,7 @@ export var getOAuthUrl = function getOAuthUrl(_ref) {
|
|
|
118
118
|
oAuthUrl.searchParams.set('nonce', nonce);
|
|
119
119
|
|
|
120
120
|
if (oAuthConf.scope !== undefined && oAuthConf.scope !== null && oAuthConf.scope !== false) {
|
|
121
|
-
var urlScope = Array.isArray(oAuthConf.scope) ? oAuthConf.scope.join('
|
|
121
|
+
var urlScope = Array.isArray(oAuthConf.scope) ? oAuthConf.scope.join('%2B') : oAuthConf.scope;
|
|
122
122
|
oAuthUrl.searchParams.set('scope', urlScope);
|
|
123
123
|
}
|
|
124
124
|
|
|
@@ -53,7 +53,7 @@ describe('Oauth helper', function () {
|
|
|
53
53
|
scope: ['thescope', 'thescope2']
|
|
54
54
|
}
|
|
55
55
|
}));
|
|
56
|
-
expect(url).toEqual('https://cozyurl/accounts/testslug/start?state=statekey&nonce=1234&scope=thescope
|
|
56
|
+
expect(url).toEqual('https://cozyurl/accounts/testslug/start?state=statekey&nonce=1234&scope=thescope%2Bthescope2');
|
|
57
57
|
});
|
|
58
58
|
it('should use redirectSlug if present', function () {
|
|
59
59
|
var url = getOAuthUrl(_objectSpread(_objectSpread({}, defaultConf), {}, {
|
|
@@ -33,6 +33,7 @@ import { waitForRealtimeEvent } from './jobUtils';
|
|
|
33
33
|
import '../types';
|
|
34
34
|
import { LOGIN_SUCCESS_EVENT } from '../models/flowEvents';
|
|
35
35
|
var TEMP_TOKEN_TIMOUT_S = 60;
|
|
36
|
+
export var ACCOUNTS_DOCTYPE = 'io.cozy.accounts';
|
|
36
37
|
export var isBiWebViewConnector = function isBiWebViewConnector(konnector) {
|
|
37
38
|
return flag('harvest.bi.webview') && isBudgetInsightConnector(konnector);
|
|
38
39
|
};
|
|
@@ -201,7 +202,7 @@ export var handleOAuthAccount = /*#__PURE__*/function () {
|
|
|
201
202
|
logger.info("Found a BI webview connection id: ".concat(connectionId));
|
|
202
203
|
flow.konnector = konnector;
|
|
203
204
|
_context3.next = 12;
|
|
204
|
-
return flow.saveAccount(setBIConnectionId(biWebviewAccount, connectionId));
|
|
205
|
+
return flow.saveAccount(_objectSpread(_objectSpread({}, setBIConnectionId(biWebviewAccount, connectionId)), getBiAggregatorParentRelationship(konnector)));
|
|
205
206
|
|
|
206
207
|
case 12:
|
|
207
208
|
biWebviewAccount = _context3.sent;
|
|
@@ -228,6 +229,34 @@ export var handleOAuthAccount = /*#__PURE__*/function () {
|
|
|
228
229
|
return _ref6.apply(this, arguments);
|
|
229
230
|
};
|
|
230
231
|
}();
|
|
232
|
+
/**
|
|
233
|
+
* Return the bi aggregator parent relationship configuration for a given konnector
|
|
234
|
+
*
|
|
235
|
+
* @param {io.cozy.konnectors} konnector connector manifest content
|
|
236
|
+
*
|
|
237
|
+
* @return {Object}
|
|
238
|
+
*/
|
|
239
|
+
|
|
240
|
+
var getBiAggregatorParentRelationship = function getBiAggregatorParentRelationship(konnector) {
|
|
241
|
+
var _konnector$aggregator;
|
|
242
|
+
|
|
243
|
+
var biAggregatorId = konnector === null || konnector === void 0 ? void 0 : (_konnector$aggregator = konnector.aggregator) === null || _konnector$aggregator === void 0 ? void 0 : _konnector$aggregator.accountId;
|
|
244
|
+
|
|
245
|
+
if (!biAggregatorId) {
|
|
246
|
+
return {};
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return {
|
|
250
|
+
relationships: {
|
|
251
|
+
parent: {
|
|
252
|
+
data: {
|
|
253
|
+
_id: biAggregatorId,
|
|
254
|
+
_type: ACCOUNTS_DOCTYPE
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
};
|
|
231
260
|
/**
|
|
232
261
|
* Gets BI webview connection id which is returned in the account by the stack
|
|
233
262
|
* via oauth callback url
|
|
@@ -237,6 +266,7 @@ export var handleOAuthAccount = /*#__PURE__*/function () {
|
|
|
237
266
|
* @return {Integer} Connection Id
|
|
238
267
|
*/
|
|
239
268
|
|
|
269
|
+
|
|
240
270
|
var getWebviewBIConnectionId = function getWebviewBIConnectionId(account) {
|
|
241
271
|
var _account$oauth, _account$oauth$query, _account$oauth$query$;
|
|
242
272
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cozy-harvest-lib",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.23.1",
|
|
4
4
|
"description": "Provides logic, modules and components for Cozy's harvest applications.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"author": "Cozy",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"@cozy/minilog": "^1.0.0",
|
|
30
30
|
"@sentry/browser": "^6.0.1",
|
|
31
31
|
"cozy-bi-auth": "0.0.25",
|
|
32
|
-
"cozy-doctypes": "^1.
|
|
32
|
+
"cozy-doctypes": "^1.85.0",
|
|
33
33
|
"cozy-logger": "^1.9.0",
|
|
34
34
|
"date-fns": "^1.30.1",
|
|
35
35
|
"final-form": "^4.18.5",
|
|
@@ -77,6 +77,7 @@
|
|
|
77
77
|
"peerDependencies": {
|
|
78
78
|
"@babel/runtime": ">=7.12.5",
|
|
79
79
|
"@material-ui/core": ">=4",
|
|
80
|
+
"@material-ui/lab": "4.0.0-alpha.60",
|
|
80
81
|
"cozy-client": ">=27.17.0",
|
|
81
82
|
"cozy-device-helper": ">=1.10.2",
|
|
82
83
|
"cozy-flags": ">=2.3.5",
|
|
@@ -89,5 +90,5 @@
|
|
|
89
90
|
"react-router-dom": "^5.0.1"
|
|
90
91
|
},
|
|
91
92
|
"sideEffects": false,
|
|
92
|
-
"gitHead": "
|
|
93
|
+
"gitHead": "3e2319da1add48da77bf8dd3f9c8113e831ea752"
|
|
93
94
|
}
|
|
@@ -1,30 +1,73 @@
|
|
|
1
|
-
import { useEffect } from 'react'
|
|
1
|
+
import React, { useEffect } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import { useWebviewIntent } from 'cozy-intent'
|
|
4
4
|
import logger from '../logger'
|
|
5
5
|
import { intentsApiProptype } from '../helpers/proptypes'
|
|
6
6
|
|
|
7
|
-
const InAppBrowser = ({ url, onClose, intentsApi
|
|
7
|
+
const InAppBrowser = ({ url, onClose, intentsApi }) => {
|
|
8
|
+
if (intentsApi) {
|
|
9
|
+
return (
|
|
10
|
+
<InAppBrowserWithIntentsApi
|
|
11
|
+
url={url}
|
|
12
|
+
onClose={onClose}
|
|
13
|
+
intentsApi={intentsApi}
|
|
14
|
+
/>
|
|
15
|
+
)
|
|
16
|
+
} else {
|
|
17
|
+
return <InAppBrowserWithWebviewIntent url={url} onClose={onClose} />
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const InAppBrowserWithWebviewIntent = ({ url, onClose }) => {
|
|
8
22
|
const webviewIntent = useWebviewIntent()
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
23
|
+
const isReady = Boolean(webviewIntent)
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
async function insideEffect() {
|
|
26
|
+
if (isReady) {
|
|
27
|
+
try {
|
|
28
|
+
logger.debug('url at the beginning: ', url)
|
|
29
|
+
const sessionCode = await webviewIntent.call('fetchSessionCode')
|
|
30
|
+
logger.debug('got session code', sessionCode)
|
|
31
|
+
const iabUrl = new URL(url)
|
|
32
|
+
iabUrl.searchParams.append('session_code', sessionCode)
|
|
33
|
+
// we need to decodeURIComponent since toString() encodes URL
|
|
34
|
+
// but native browser will also encode them.
|
|
35
|
+
const urlToOpen = decodeURIComponent(iabUrl.toString())
|
|
36
|
+
logger.debug('url to open: ', urlToOpen)
|
|
37
|
+
const result = await webviewIntent.call('showInAppBrowser', {
|
|
38
|
+
url: urlToOpen
|
|
39
|
+
})
|
|
40
|
+
if (result?.type !== 'dismiss' && result?.type !== 'cancel') {
|
|
41
|
+
logger.error('Unexpected InAppBrowser result', result)
|
|
42
|
+
}
|
|
43
|
+
} catch (err) {
|
|
44
|
+
logger.error('unexpected fetchSessionCode result', err)
|
|
45
|
+
}
|
|
46
|
+
if (onClose) {
|
|
47
|
+
onClose()
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
insideEffect()
|
|
52
|
+
return function cleanup() {
|
|
53
|
+
webviewIntent.call('closeInAppBrowser')
|
|
54
|
+
}
|
|
55
|
+
}, [isReady, url, onClose, webviewIntent])
|
|
56
|
+
return null
|
|
57
|
+
}
|
|
18
58
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
59
|
+
const InAppBrowserWithIntentsApi = ({ url, onClose, intentsApi = {} }) => {
|
|
60
|
+
const {
|
|
61
|
+
fetchSessionCode,
|
|
62
|
+
showInAppBrowser,
|
|
63
|
+
closeInAppBrowser,
|
|
64
|
+
tokenParamName = 'session_code'
|
|
65
|
+
} = intentsApi
|
|
22
66
|
|
|
23
67
|
const isReady = Boolean(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
intentsApi?.closeInAppBrowser)
|
|
68
|
+
intentsApi?.fetchSessionCode &&
|
|
69
|
+
intentsApi?.showInAppBrowser &&
|
|
70
|
+
intentsApi?.closeInAppBrowser
|
|
28
71
|
)
|
|
29
72
|
|
|
30
73
|
useEffect(() => {
|
|
@@ -52,6 +95,7 @@ const InAppBrowser = ({ url, onClose, intentsApi = {} }) => {
|
|
|
52
95
|
}
|
|
53
96
|
}
|
|
54
97
|
}
|
|
98
|
+
|
|
55
99
|
insideEffect()
|
|
56
100
|
return function cleanup() {
|
|
57
101
|
closeInAppBrowser()
|
package/src/helpers/oauth.js
CHANGED
|
@@ -130,7 +130,7 @@ export const getOAuthUrl = ({
|
|
|
130
130
|
oAuthConf.scope !== false
|
|
131
131
|
) {
|
|
132
132
|
const urlScope = Array.isArray(oAuthConf.scope)
|
|
133
|
-
? oAuthConf.scope.join('
|
|
133
|
+
? oAuthConf.scope.join('%2B')
|
|
134
134
|
: oAuthConf.scope
|
|
135
135
|
oAuthUrl.searchParams.set('scope', urlScope)
|
|
136
136
|
}
|
|
@@ -50,7 +50,7 @@ describe('Oauth helper', () => {
|
|
|
50
50
|
oAuthConf: { scope: ['thescope', 'thescope2'] }
|
|
51
51
|
})
|
|
52
52
|
expect(url).toEqual(
|
|
53
|
-
'https://cozyurl/accounts/testslug/start?state=statekey&nonce=1234&scope=thescope
|
|
53
|
+
'https://cozyurl/accounts/testslug/start?state=statekey&nonce=1234&scope=thescope%2Bthescope2'
|
|
54
54
|
)
|
|
55
55
|
})
|
|
56
56
|
it('should use redirectSlug if present', () => {
|
|
@@ -23,6 +23,7 @@ import '../types'
|
|
|
23
23
|
import { LOGIN_SUCCESS_EVENT } from '../models/flowEvents'
|
|
24
24
|
|
|
25
25
|
const TEMP_TOKEN_TIMOUT_S = 60
|
|
26
|
+
export const ACCOUNTS_DOCTYPE = 'io.cozy.accounts'
|
|
26
27
|
|
|
27
28
|
export const isBiWebViewConnector = konnector =>
|
|
28
29
|
flag('harvest.bi.webview') && isBudgetInsightConnector(konnector)
|
|
@@ -130,9 +131,11 @@ export const handleOAuthAccount = async ({
|
|
|
130
131
|
if (connectionId) {
|
|
131
132
|
logger.info(`Found a BI webview connection id: ${connectionId}`)
|
|
132
133
|
flow.konnector = konnector
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
|
|
135
|
+
biWebviewAccount = await flow.saveAccount({
|
|
136
|
+
...setBIConnectionId(biWebviewAccount, connectionId),
|
|
137
|
+
...getBiAggregatorParentRelationship(konnector)
|
|
138
|
+
})
|
|
136
139
|
|
|
137
140
|
await flow.handleFormSubmit({
|
|
138
141
|
client,
|
|
@@ -145,6 +148,30 @@ export const handleOAuthAccount = async ({
|
|
|
145
148
|
return connectionId
|
|
146
149
|
}
|
|
147
150
|
|
|
151
|
+
/**
|
|
152
|
+
* Return the bi aggregator parent relationship configuration for a given konnector
|
|
153
|
+
*
|
|
154
|
+
* @param {io.cozy.konnectors} konnector connector manifest content
|
|
155
|
+
*
|
|
156
|
+
* @return {Object}
|
|
157
|
+
*/
|
|
158
|
+
const getBiAggregatorParentRelationship = konnector => {
|
|
159
|
+
const biAggregatorId = konnector?.aggregator?.accountId
|
|
160
|
+
if (!biAggregatorId) {
|
|
161
|
+
return {}
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
relationships: {
|
|
165
|
+
parent: {
|
|
166
|
+
data: {
|
|
167
|
+
_id: biAggregatorId,
|
|
168
|
+
_type: ACCOUNTS_DOCTYPE
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
148
175
|
/**
|
|
149
176
|
* Gets BI webview connection id which is returned in the account by the stack
|
|
150
177
|
* via oauth callback url
|