cozy-harvest-lib 9.7.3 → 9.9.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 +38 -0
- package/dist/components/EditAccountModal.js +4 -1
- package/dist/components/InAppBrowser.js +30 -10
- package/dist/components/InAppBrowser.spec.js +12 -5
- package/dist/components/OAuthForm.js +13 -10
- package/dist/components/OAuthForm.spec.js +3 -2
- package/dist/components/OAuthWindow.js +11 -3
- package/dist/components/TriggerManager.js +7 -2
- package/dist/components/__snapshots__/OAuthForm.spec.js.snap +13 -0
- package/dist/helpers/oauth.js +31 -11
- package/dist/helpers/oauth.spec.js +15 -1
- package/dist/locales/en.json +3 -0
- package/dist/locales/fr.json +4 -1
- package/dist/services/biWebView.js +104 -42
- package/dist/services/biWebView.spec.js +293 -1
- package/dist/services/budget-insight.js +3 -2
- package/package.json +2 -2
- package/src/components/EditAccountModal.jsx +2 -0
- package/src/components/InAppBrowser.jsx +15 -4
- package/src/components/InAppBrowser.spec.jsx +9 -4
- package/src/components/OAuthForm.jsx +11 -8
- package/src/components/OAuthForm.spec.js +3 -2
- package/src/components/OAuthWindow.jsx +9 -3
- package/src/components/TriggerManager.jsx +6 -2
- package/src/components/__snapshots__/OAuthForm.spec.js.snap +13 -0
- package/src/helpers/oauth.js +35 -12
- package/src/helpers/oauth.spec.js +16 -1
- package/src/locales/en.json +3 -0
- package/src/locales/fr.json +4 -1
- package/src/services/biWebView.js +49 -2
- package/src/services/biWebView.spec.js +150 -1
- package/src/services/budget-insight.js +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,44 @@
|
|
|
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.9.0](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@9.8.1...cozy-harvest-lib@9.9.0) (2022-06-13)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* Add session code inAppBrowser url ([e2037ef](https://github.com/cozy/cozy-libs/commit/e2037efabd73d93106d2f88bb122f75e783afb6e))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## [9.8.1](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@9.8.0...cozy-harvest-lib@9.8.1) (2022-06-12)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* Update french locale ([902ae96](https://github.com/cozy/cozy-libs/commit/902ae967a14c106c7cc3adc0543d479d94e2f07e))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# [9.8.0](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@9.7.3...cozy-harvest-lib@9.8.0) (2022-06-09)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
### Bug Fixes
|
|
32
|
+
|
|
33
|
+
* Small fixes after review ([d4f50ba](https://github.com/cozy/cozy-libs/commit/d4f50ba114cd4f8d43fac8545f6356c380edd262))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
### Features
|
|
37
|
+
|
|
38
|
+
* Add BI webview reconnection ([d0f9c9e](https://github.com/cozy/cozy-libs/commit/d0f9c9e556d847e072063eb877d5d4e57ee8cca0))
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
6
44
|
## [9.7.3](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@9.7.2...cozy-harvest-lib@9.7.3) (2022-06-08)
|
|
7
45
|
|
|
8
46
|
|
|
@@ -102,7 +102,10 @@ var DumbEditAccountModal = withRouter(function (_ref) {
|
|
|
102
102
|
onSuccess: redirectToAccount,
|
|
103
103
|
showError: true,
|
|
104
104
|
onVaultDismiss: redirectToAccount,
|
|
105
|
-
fieldOptions: fieldOptions
|
|
105
|
+
fieldOptions: fieldOptions,
|
|
106
|
+
reconnect: fromReconnect
|
|
107
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
108
|
+
className: "u-mb-2"
|
|
106
109
|
})));
|
|
107
110
|
});
|
|
108
111
|
export var EditAccountModal = /*#__PURE__*/function (_Component) {
|
|
@@ -16,36 +16,56 @@ var InAppBrowser = function InAppBrowser(_ref) {
|
|
|
16
16
|
|
|
17
17
|
function _insideEffect() {
|
|
18
18
|
_insideEffect = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
19
|
-
var result;
|
|
19
|
+
var sessionCode, iabUrl, result;
|
|
20
20
|
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
21
21
|
while (1) {
|
|
22
22
|
switch (_context.prev = _context.next) {
|
|
23
23
|
case 0:
|
|
24
24
|
if (!webviewIntent) {
|
|
25
|
-
_context.next =
|
|
25
|
+
_context.next = 18;
|
|
26
26
|
break;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
_context.
|
|
29
|
+
_context.prev = 1;
|
|
30
|
+
_context.next = 4;
|
|
31
|
+
return webviewIntent.call('fetchSessionCode');
|
|
32
|
+
|
|
33
|
+
case 4:
|
|
34
|
+
sessionCode = _context.sent;
|
|
35
|
+
logger.debug('got session code', sessionCode);
|
|
36
|
+
iabUrl = new URL(url);
|
|
37
|
+
iabUrl.searchParams.append('session_code', sessionCode);
|
|
38
|
+
_context.next = 10;
|
|
30
39
|
return webviewIntent.call('showInAppBrowser', {
|
|
31
|
-
url:
|
|
40
|
+
url: iabUrl.toString()
|
|
32
41
|
});
|
|
33
42
|
|
|
34
|
-
case
|
|
43
|
+
case 10:
|
|
35
44
|
result = _context.sent;
|
|
36
45
|
|
|
37
|
-
if ((result === null || result === void 0 ? void 0 : result.type)
|
|
38
|
-
onClose();
|
|
39
|
-
} else if ((result === null || result === void 0 ? void 0 : result.type) !== 'dismiss') {
|
|
46
|
+
if ((result === null || result === void 0 ? void 0 : result.type) !== 'dismiss' && (result === null || result === void 0 ? void 0 : result.type) !== 'cancel') {
|
|
40
47
|
logger.error('Unexpected InAppBrowser result', result);
|
|
41
48
|
}
|
|
42
49
|
|
|
43
|
-
|
|
50
|
+
_context.next = 17;
|
|
51
|
+
break;
|
|
52
|
+
|
|
53
|
+
case 14:
|
|
54
|
+
_context.prev = 14;
|
|
55
|
+
_context.t0 = _context["catch"](1);
|
|
56
|
+
logger.error('unexpected fetchSessionCode result', _context.t0);
|
|
57
|
+
|
|
58
|
+
case 17:
|
|
59
|
+
if (onClose) {
|
|
60
|
+
onClose();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
case 18:
|
|
44
64
|
case "end":
|
|
45
65
|
return _context.stop();
|
|
46
66
|
}
|
|
47
67
|
}
|
|
48
|
-
}, _callee);
|
|
68
|
+
}, _callee, null, [[1, 14]]);
|
|
49
69
|
}));
|
|
50
70
|
return _insideEffect.apply(this, arguments);
|
|
51
71
|
}
|
|
@@ -5,7 +5,7 @@ import { render, waitFor } from '@testing-library/react';
|
|
|
5
5
|
import InAppBrowser from './InAppBrowser';
|
|
6
6
|
import { WebviewIntentProvider } from 'cozy-intent';
|
|
7
7
|
describe('InAppBrowser', function () {
|
|
8
|
-
it('should call showInAppBrowser', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
8
|
+
it('should call fetchSessionCode and showInAppBrowser', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
9
9
|
var url, intentCall, webviewService;
|
|
10
10
|
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
11
11
|
while (1) {
|
|
@@ -16,7 +16,7 @@ describe('InAppBrowser', function () {
|
|
|
16
16
|
webviewService = {
|
|
17
17
|
call: intentCall
|
|
18
18
|
};
|
|
19
|
-
intentCall.
|
|
19
|
+
intentCall.mockResolvedValueOnce('sessioncode').mockResolvedValueOnce({
|
|
20
20
|
type: 'dismiss'
|
|
21
21
|
});
|
|
22
22
|
render( /*#__PURE__*/React.createElement(WebviewIntentProvider, {
|
|
@@ -24,11 +24,18 @@ describe('InAppBrowser', function () {
|
|
|
24
24
|
}, /*#__PURE__*/React.createElement(InAppBrowser, {
|
|
25
25
|
url: url
|
|
26
26
|
})));
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
_context.next = 7;
|
|
28
|
+
return waitFor(function () {
|
|
29
|
+
return expect(webviewService.call).toHaveBeenCalled();
|
|
29
30
|
});
|
|
30
31
|
|
|
31
|
-
case
|
|
32
|
+
case 7:
|
|
33
|
+
expect(webviewService.call).toHaveBeenNthCalledWith(1, 'fetchSessionCode');
|
|
34
|
+
expect(webviewService.call).toHaveBeenNthCalledWith(2, 'showInAppBrowser', {
|
|
35
|
+
url: url + '/?session_code=sessioncode'
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
case 9:
|
|
32
39
|
case "end":
|
|
33
40
|
return _context.stop();
|
|
34
41
|
}
|
|
@@ -38,7 +38,6 @@ export var OAuthForm = /*#__PURE__*/function (_PureComponent) {
|
|
|
38
38
|
_this.handleOAuthCancel = _this.handleOAuthCancel.bind(_assertThisInitialized(_this));
|
|
39
39
|
_this.handleExtraParams = _this.handleExtraParams.bind(_assertThisInitialized(_this));
|
|
40
40
|
_this.state = {
|
|
41
|
-
initialValues: null,
|
|
42
41
|
showingOAuthModal: false
|
|
43
42
|
};
|
|
44
43
|
return _this;
|
|
@@ -52,9 +51,6 @@ export var OAuthForm = /*#__PURE__*/function (_PureComponent) {
|
|
|
52
51
|
konnector = _this$props.konnector,
|
|
53
52
|
flow = _this$props.flow,
|
|
54
53
|
client = _this$props.client;
|
|
55
|
-
this.setState({
|
|
56
|
-
initialValues: account ? account.oauth : null
|
|
57
|
-
});
|
|
58
54
|
var konnectorPolicy = findKonnectorPolicy(konnector);
|
|
59
55
|
|
|
60
56
|
if (konnectorPolicy.fetchExtraOAuthUrlParams) {
|
|
@@ -114,25 +110,29 @@ export var OAuthForm = /*#__PURE__*/function (_PureComponent) {
|
|
|
114
110
|
var _this$props2 = this.props,
|
|
115
111
|
konnector = _this$props2.konnector,
|
|
116
112
|
t = _this$props2.t,
|
|
117
|
-
flowState = _this$props2.flowState
|
|
113
|
+
flowState = _this$props2.flowState,
|
|
114
|
+
reconnect = _this$props2.reconnect,
|
|
115
|
+
account = _this$props2.account;
|
|
118
116
|
var _this$state = this.state,
|
|
119
|
-
initialValues = _this$state.initialValues,
|
|
120
117
|
showOAuthWindow = _this$state.showOAuthWindow,
|
|
121
118
|
needExtraParams = _this$state.needExtraParams,
|
|
122
119
|
extraParams = _this$state.extraParams;
|
|
123
120
|
var isBusy = showOAuthWindow === true || flowState.running || needExtraParams && !extraParams;
|
|
124
|
-
|
|
121
|
+
var buttonLabel = reconnect ? 'oauth.reconnect.label' : 'oauth.connect.label';
|
|
122
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Button, {
|
|
125
123
|
className: "u-mt-1",
|
|
126
124
|
busy: isBusy,
|
|
127
125
|
disabled: isBusy,
|
|
128
126
|
extension: "full",
|
|
129
|
-
label: t(
|
|
127
|
+
label: t(buttonLabel),
|
|
130
128
|
onClick: this.handleConnect
|
|
131
129
|
}), showOAuthWindow && /*#__PURE__*/React.createElement(OAuthWindow, {
|
|
132
130
|
extraParams: extraParams,
|
|
133
131
|
konnector: konnector,
|
|
132
|
+
reconnect: reconnect,
|
|
134
133
|
onSuccess: this.handleAccountId,
|
|
135
|
-
onCancel: this.handleOAuthCancel
|
|
134
|
+
onCancel: this.handleOAuthCancel,
|
|
135
|
+
account: account
|
|
136
136
|
}));
|
|
137
137
|
}
|
|
138
138
|
}]);
|
|
@@ -150,6 +150,9 @@ OAuthForm.propTypes = {
|
|
|
150
150
|
onSuccess: PropTypes.func,
|
|
151
151
|
|
|
152
152
|
/** Translation function */
|
|
153
|
-
t: PropTypes.func.isRequired
|
|
153
|
+
t: PropTypes.func.isRequired,
|
|
154
|
+
|
|
155
|
+
/** Is it a reconnection or not */
|
|
156
|
+
reconnect: PropTypes.bool
|
|
154
157
|
};
|
|
155
158
|
export default compose(translate(), withConnectionFlow())(OAuthForm);
|
|
@@ -30,7 +30,7 @@ describe('OAuthForm', function () {
|
|
|
30
30
|
})).getElement();
|
|
31
31
|
expect(component).toMatchSnapshot();
|
|
32
32
|
});
|
|
33
|
-
it('should
|
|
33
|
+
it('should render reconnect button when updating an account', function () {
|
|
34
34
|
var component = shallow( /*#__PURE__*/React.createElement(OAuthForm, {
|
|
35
35
|
flowState: {},
|
|
36
36
|
account: {
|
|
@@ -39,9 +39,10 @@ describe('OAuthForm', function () {
|
|
|
39
39
|
}
|
|
40
40
|
},
|
|
41
41
|
konnector: fixtures.konnector,
|
|
42
|
+
reconnect: true,
|
|
42
43
|
t: t
|
|
43
44
|
})).getElement();
|
|
44
|
-
expect(component).
|
|
45
|
+
expect(component).toMatchSnapshot();
|
|
45
46
|
});
|
|
46
47
|
it('should call policy fetchExtraOAuthUrlParams with proper params', function () {
|
|
47
48
|
shallow( /*#__PURE__*/React.createElement(OAuthForm, {
|
|
@@ -65,13 +65,15 @@ export var OAuthWindow = /*#__PURE__*/function (_PureComponent) {
|
|
|
65
65
|
client = _this$props.client,
|
|
66
66
|
konnector = _this$props.konnector,
|
|
67
67
|
redirectSlug = _this$props.redirectSlug,
|
|
68
|
-
extraParams = _this$props.extraParams
|
|
68
|
+
extraParams = _this$props.extraParams,
|
|
69
|
+
reconnect = _this$props.reconnect,
|
|
70
|
+
account = _this$props.account;
|
|
69
71
|
this.realtime = new CozyRealtime({
|
|
70
72
|
client: client
|
|
71
73
|
});
|
|
72
74
|
this.realtime.subscribe('notified', 'io.cozy.accounts', OAUTH_REALTIME_CHANNEL, this.handleMessage);
|
|
73
75
|
|
|
74
|
-
var _prepareOAuth = prepareOAuth(client, konnector, redirectSlug, extraParams),
|
|
76
|
+
var _prepareOAuth = prepareOAuth(client, konnector, redirectSlug, extraParams, reconnect, account),
|
|
75
77
|
oAuthStateKey = _prepareOAuth.oAuthStateKey,
|
|
76
78
|
oAuthUrl = _prepareOAuth.oAuthUrl;
|
|
77
79
|
|
|
@@ -210,6 +212,12 @@ OAuthWindow.propTypes = {
|
|
|
210
212
|
onCancel: PropTypes.func,
|
|
211
213
|
|
|
212
214
|
/** The app we want to redirect the user on, after the OAuth flow. It used by the stack */
|
|
213
|
-
redirectSlug: PropTypes.string
|
|
215
|
+
redirectSlug: PropTypes.string,
|
|
216
|
+
|
|
217
|
+
/** Is it a reconnection or not */
|
|
218
|
+
reconnect: PropTypes.bool,
|
|
219
|
+
|
|
220
|
+
/** Existing account */
|
|
221
|
+
account: PropTypes.object
|
|
214
222
|
};
|
|
215
223
|
export default translate()(withClient(OAuthWindow));
|
|
@@ -507,7 +507,8 @@ export var DumbTriggerManager = /*#__PURE__*/function (_Component) {
|
|
|
507
507
|
flow = _this$props5.flow,
|
|
508
508
|
flowState = _this$props5.flowState,
|
|
509
509
|
client = _this$props5.client,
|
|
510
|
-
OAuthFormWrapperComp = _this$props5.OAuthFormWrapperComp
|
|
510
|
+
OAuthFormWrapperComp = _this$props5.OAuthFormWrapperComp,
|
|
511
|
+
reconnect = _this$props5.reconnect;
|
|
511
512
|
var submitting = flowState.running;
|
|
512
513
|
var _this$state = this.state,
|
|
513
514
|
account = _this$state.account,
|
|
@@ -527,6 +528,7 @@ export var DumbTriggerManager = /*#__PURE__*/function (_Component) {
|
|
|
527
528
|
client: client,
|
|
528
529
|
flow: flow,
|
|
529
530
|
account: account,
|
|
531
|
+
reconnect: reconnect,
|
|
530
532
|
konnector: konnector,
|
|
531
533
|
onSuccess: this.handleOAuthAccountId
|
|
532
534
|
}));
|
|
@@ -617,7 +619,10 @@ DumbTriggerManager.propTypes = {
|
|
|
617
619
|
flow: PropTypes.object,
|
|
618
620
|
flowState: PropTypes.object,
|
|
619
621
|
// Used to inject a component around OAuthForm, and so customize the UI from the app
|
|
620
|
-
OAuthFormWrapperComp: PropTypes.node
|
|
622
|
+
OAuthFormWrapperComp: PropTypes.node,
|
|
623
|
+
|
|
624
|
+
/** Is it a reconnection or not */
|
|
625
|
+
reconnect: PropTypes.bool
|
|
621
626
|
};
|
|
622
627
|
var TriggerManager = compose(translate(), withClient, withVaultUnlockContext, withConnectionFlow())(DumbTriggerManager); // TriggerManager is exported wrapped in FlowProvider to avoid breaking changes.
|
|
623
628
|
|
|
@@ -12,3 +12,16 @@ exports[`OAuthForm should render 1`] = `
|
|
|
12
12
|
/>
|
|
13
13
|
</React.Fragment>
|
|
14
14
|
`;
|
|
15
|
+
|
|
16
|
+
exports[`OAuthForm should render reconnect button when update 1`] = `
|
|
17
|
+
<React.Fragment>
|
|
18
|
+
<DefaultButton
|
|
19
|
+
busy={true}
|
|
20
|
+
className="u-mt-1"
|
|
21
|
+
disabled={true}
|
|
22
|
+
extension="full"
|
|
23
|
+
label="oauth.reconnect.label"
|
|
24
|
+
onClick={[Function]}
|
|
25
|
+
/>
|
|
26
|
+
</React.Fragment>
|
|
27
|
+
`;
|
package/dist/helpers/oauth.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
1
2
|
import uuid from 'uuid/v4';
|
|
2
3
|
import get from 'lodash/get';
|
|
3
4
|
import CozyClient from 'cozy-client';
|
|
@@ -94,6 +95,9 @@ export var handleOAuthResponse = function handleOAuthResponse() {
|
|
|
94
95
|
* @param {string} redirectSlug The app we want to redirect the user on after the end of the flow
|
|
95
96
|
* @param {string} nonce unique nonce string
|
|
96
97
|
* @param {Object} extraParams some extra parameters to add to the query string
|
|
98
|
+
* @param {Boolean} reconnect Are we trying to reconnect an existing account ?
|
|
99
|
+
* @param {io.cozy.accounts} account targeted account if any
|
|
100
|
+
* @returns {String} final OAuth url string
|
|
97
101
|
*/
|
|
98
102
|
|
|
99
103
|
export var getOAuthUrl = function getOAuthUrl(_ref) {
|
|
@@ -104,25 +108,35 @@ export var getOAuthUrl = function getOAuthUrl(_ref) {
|
|
|
104
108
|
oAuthConf = _ref$oAuthConf === void 0 ? {} : _ref$oAuthConf,
|
|
105
109
|
nonce = _ref.nonce,
|
|
106
110
|
redirectSlug = _ref.redirectSlug,
|
|
107
|
-
extraParams = _ref.extraParams
|
|
108
|
-
|
|
111
|
+
extraParams = _ref.extraParams,
|
|
112
|
+
reconnect = _ref.reconnect,
|
|
113
|
+
account = _ref.account;
|
|
114
|
+
var startOrReconnect = reconnect ? 'reconnect' : 'start';
|
|
115
|
+
var accountIdParam = reconnect ? account._id + '/' : '';
|
|
116
|
+
var oAuthUrl = new URL("".concat(cozyUrl, "/accounts/").concat(accountType, "/").concat(accountIdParam).concat(startOrReconnect));
|
|
117
|
+
oAuthUrl.searchParams.set('state', oAuthStateKey);
|
|
118
|
+
oAuthUrl.searchParams.set('nonce', nonce);
|
|
109
119
|
|
|
110
120
|
if (oAuthConf.scope !== undefined && oAuthConf.scope !== null && oAuthConf.scope !== false) {
|
|
111
121
|
var urlScope = Array.isArray(oAuthConf.scope) ? oAuthConf.scope.join('+') : oAuthConf.scope;
|
|
112
|
-
oAuthUrl
|
|
122
|
+
oAuthUrl.searchParams.set('scope', urlScope);
|
|
113
123
|
}
|
|
114
124
|
|
|
115
125
|
if (redirectSlug) {
|
|
116
|
-
oAuthUrl
|
|
126
|
+
oAuthUrl.searchParams.set('slug', redirectSlug);
|
|
117
127
|
}
|
|
118
128
|
|
|
119
129
|
if (extraParams) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
130
|
+
Object.entries(extraParams).forEach(function (_ref2) {
|
|
131
|
+
var _ref3 = _slicedToArray(_ref2, 2),
|
|
132
|
+
key = _ref3[0],
|
|
133
|
+
value = _ref3[1];
|
|
134
|
+
|
|
135
|
+
return oAuthUrl.searchParams.set(key, value);
|
|
136
|
+
});
|
|
123
137
|
}
|
|
124
138
|
|
|
125
|
-
return oAuthUrl;
|
|
139
|
+
return oAuthUrl.toString();
|
|
126
140
|
};
|
|
127
141
|
|
|
128
142
|
var getAppSlug = function getAppSlug(client) {
|
|
@@ -135,12 +149,16 @@ var getAppSlug = function getAppSlug(client) {
|
|
|
135
149
|
* @param {string} domain Cozy domain
|
|
136
150
|
* @param {Object} konnector
|
|
137
151
|
* @param {string} redirectSlug The app we want to redirect the user on after the end of the flow
|
|
138
|
-
* @
|
|
139
|
-
*
|
|
152
|
+
* @param {Object} extraParams some extra parameters to add to the query string
|
|
153
|
+
* @param {Boolean} reconnect Are we trying to reconnect an existing account ?
|
|
154
|
+
* @param {io.cozy.accounts} account targetted account if any
|
|
155
|
+
* @return {Object} Object containing: `oAuthUrl` (URL of cozy stack OAuth endpoint) and `oAuthStateKey` (localStorage key)
|
|
140
156
|
*/
|
|
141
157
|
|
|
142
158
|
|
|
143
159
|
export var prepareOAuth = function prepareOAuth(client, konnector, redirectSlug, extraParams) {
|
|
160
|
+
var reconnect = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
|
|
161
|
+
var account = arguments.length > 5 ? arguments[5] : undefined;
|
|
144
162
|
var oauth = konnector.oauth;
|
|
145
163
|
var accountType = konnectors.getAccountType(konnector); // We use localStorage to store the account related data
|
|
146
164
|
// We will later check in localStorage that the received information is
|
|
@@ -159,7 +177,9 @@ export var prepareOAuth = function prepareOAuth(client, konnector, redirectSlug,
|
|
|
159
177
|
oAuthConf: oauth,
|
|
160
178
|
nonce: Date.now(),
|
|
161
179
|
redirectSlug: redirectSlug || getAppSlug(client),
|
|
162
|
-
extraParams: extraParams
|
|
180
|
+
extraParams: extraParams,
|
|
181
|
+
reconnect: reconnect,
|
|
182
|
+
account: account
|
|
163
183
|
});
|
|
164
184
|
return {
|
|
165
185
|
oAuthStateKey: oAuthStateKey,
|
|
@@ -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), {}, {
|
|
@@ -72,6 +72,20 @@ describe('Oauth helper', function () {
|
|
|
72
72
|
}));
|
|
73
73
|
expect(url).toEqual('https://cozyurl/accounts/testslug/start?state=statekey&nonce=1234&token=thetoken&id_connector=40');
|
|
74
74
|
});
|
|
75
|
+
it('should return reconnect url with account id if reconnect', function () {
|
|
76
|
+
var url = getOAuthUrl(_objectSpread(_objectSpread({}, defaultConf), {}, {
|
|
77
|
+
oAuthConf: {},
|
|
78
|
+
account: {
|
|
79
|
+
_id: 'accountid'
|
|
80
|
+
},
|
|
81
|
+
reconnect: true,
|
|
82
|
+
extraParams: {
|
|
83
|
+
code: 'thecode',
|
|
84
|
+
connection_id: 12345
|
|
85
|
+
}
|
|
86
|
+
}));
|
|
87
|
+
expect(url).toEqual('https://cozyurl/accounts/testslug/accountid/reconnect?state=statekey&nonce=1234&code=thecode&connection_id=12345');
|
|
88
|
+
});
|
|
75
89
|
});
|
|
76
90
|
describe('handleOAuthResponse', function () {
|
|
77
91
|
var originalLocation;
|
package/dist/locales/en.json
CHANGED