cozy-harvest-lib 9.26.13 → 9.26.15
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 +19 -0
- package/dist/services/utils.js +122 -84
- package/dist/services/utils.spec.js +67 -32
- package/package.json +8 -8
- package/src/services/utils.js +18 -2
- package/src/services/utils.spec.js +15 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,25 @@
|
|
|
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.26.15](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@9.26.14...cozy-harvest-lib@9.26.15) (2022-10-03)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package cozy-harvest-lib
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [9.26.14](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@9.26.13...cozy-harvest-lib@9.26.14) (2022-09-19)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
* Deal with empty and malformed encrypted values ([b4a6406](https://github.com/cozy/cozy-libs/commit/b4a6406be80cec7d3b7246dc42c19a419e442224))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
6
25
|
## [9.26.13](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@9.26.12...cozy-harvest-lib@9.26.13) (2022-09-15)
|
|
7
26
|
|
|
8
27
|
|
package/dist/services/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
-
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
3
2
|
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
3
|
+
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
4
4
|
|
|
5
5
|
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; }
|
|
6
6
|
|
|
@@ -13,21 +13,59 @@ import Polyglot from 'node-polyglot';
|
|
|
13
13
|
import { Q } from 'cozy-client';
|
|
14
14
|
import SymmetricCryptoKey from 'cozy-keys-lib/transpiled/SymmetricCryptoKey';
|
|
15
15
|
import EncryptionType from 'cozy-keys-lib/transpiled/EncryptionType';
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
16
|
+
import logger from './logger';
|
|
17
|
+
/**
|
|
18
|
+
* Decrypt the given string with the organization key
|
|
19
|
+
*
|
|
20
|
+
* @param {string} encryptedString - The encrypted string
|
|
21
|
+
* @param {object} vaultClient - The vault client
|
|
22
|
+
* @param {ArrayBuffer} orgKey - The organization key
|
|
23
|
+
* @returns {Promise<string>} The decrypted string
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
export var decryptString = /*#__PURE__*/function () {
|
|
27
|
+
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(encryptedString, vaultClient, orgKey) {
|
|
28
|
+
var _encryptedString$spli, _encryptedString$spli2, encTypeAndIv, data, mac, _encTypeAndIv$split, _encTypeAndIv$split2, encTypeString, iv, encType;
|
|
29
|
+
|
|
30
|
+
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
31
|
+
while (1) {
|
|
32
|
+
switch (_context.prev = _context.next) {
|
|
33
|
+
case 0:
|
|
34
|
+
if (encryptedString) {
|
|
35
|
+
_context.next = 2;
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return _context.abrupt("return", '');
|
|
40
|
+
|
|
41
|
+
case 2:
|
|
42
|
+
_encryptedString$spli = encryptedString.split('|'), _encryptedString$spli2 = _slicedToArray(_encryptedString$spli, 3), encTypeAndIv = _encryptedString$spli2[0], data = _encryptedString$spli2[1], mac = _encryptedString$spli2[2];
|
|
43
|
+
|
|
44
|
+
if (encTypeAndIv) {
|
|
45
|
+
_context.next = 6;
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
logger.error('Encrypted string is malformed');
|
|
50
|
+
throw new Error('DECRYPT_FAILED');
|
|
51
|
+
|
|
52
|
+
case 6:
|
|
53
|
+
_encTypeAndIv$split = encTypeAndIv.split('.'), _encTypeAndIv$split2 = _slicedToArray(_encTypeAndIv$split, 2), encTypeString = _encTypeAndIv$split2[0], iv = _encTypeAndIv$split2[1];
|
|
54
|
+
encType = parseInt(encTypeString, 10);
|
|
55
|
+
return _context.abrupt("return", vaultClient.cryptoService.aesDecryptToUtf8(encType, data, iv, mac, orgKey));
|
|
56
|
+
|
|
57
|
+
case 9:
|
|
58
|
+
case "end":
|
|
59
|
+
return _context.stop();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}, _callee);
|
|
63
|
+
}));
|
|
64
|
+
|
|
65
|
+
return function decryptString(_x, _x2, _x3) {
|
|
66
|
+
return _ref.apply(this, arguments);
|
|
67
|
+
};
|
|
68
|
+
}();
|
|
31
69
|
export var getT = function getT() {
|
|
32
70
|
var supportedLocales = ['en', 'fr', 'es'];
|
|
33
71
|
var locale = supportedLocales.find(function (l) {
|
|
@@ -41,41 +79,41 @@ export var getT = function getT() {
|
|
|
41
79
|
return polyglot.t.bind(polyglot);
|
|
42
80
|
};
|
|
43
81
|
export var getOrganizationKey = /*#__PURE__*/function () {
|
|
44
|
-
var
|
|
82
|
+
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(cozyClient, vaultClient) {
|
|
45
83
|
var cozyKeys, orgKeyEncType, orgKey;
|
|
46
|
-
return _regeneratorRuntime.wrap(function
|
|
84
|
+
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
|
|
47
85
|
while (1) {
|
|
48
|
-
switch (
|
|
86
|
+
switch (_context2.prev = _context2.next) {
|
|
49
87
|
case 0:
|
|
50
|
-
|
|
88
|
+
_context2.next = 2;
|
|
51
89
|
return cozyClient.getStackClient().fetchJSON('GET', '/bitwarden/organizations/cozy');
|
|
52
90
|
|
|
53
91
|
case 2:
|
|
54
|
-
cozyKeys =
|
|
92
|
+
cozyKeys = _context2.sent;
|
|
55
93
|
orgKeyEncType = EncryptionType.AesCbc256_HmacSha256_B64;
|
|
56
94
|
orgKey = new SymmetricCryptoKey(vaultClient.Utils.fromB64ToArray(cozyKeys.organizationKey), orgKeyEncType);
|
|
57
|
-
return
|
|
95
|
+
return _context2.abrupt("return", orgKey);
|
|
58
96
|
|
|
59
97
|
case 6:
|
|
60
98
|
case "end":
|
|
61
|
-
return
|
|
99
|
+
return _context2.stop();
|
|
62
100
|
}
|
|
63
101
|
}
|
|
64
|
-
},
|
|
102
|
+
}, _callee2);
|
|
65
103
|
}));
|
|
66
104
|
|
|
67
|
-
return function getOrganizationKey(
|
|
68
|
-
return
|
|
105
|
+
return function getOrganizationKey(_x4, _x5) {
|
|
106
|
+
return _ref2.apply(this, arguments);
|
|
69
107
|
};
|
|
70
108
|
}();
|
|
71
109
|
export var fetchAccountsForCipherId = /*#__PURE__*/function () {
|
|
72
|
-
var
|
|
110
|
+
var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(cozyClient, cipherId) {
|
|
73
111
|
var accounts;
|
|
74
|
-
return _regeneratorRuntime.wrap(function
|
|
112
|
+
return _regeneratorRuntime.wrap(function _callee3$(_context3) {
|
|
75
113
|
while (1) {
|
|
76
|
-
switch (
|
|
114
|
+
switch (_context3.prev = _context3.next) {
|
|
77
115
|
case 0:
|
|
78
|
-
|
|
116
|
+
_context3.next = 2;
|
|
79
117
|
return cozyClient.query(Q('io.cozy.accounts').where({
|
|
80
118
|
'relationships.vaultCipher.data': {
|
|
81
119
|
_id: cipherId,
|
|
@@ -84,59 +122,59 @@ export var fetchAccountsForCipherId = /*#__PURE__*/function () {
|
|
|
84
122
|
}).indexFields(['relationships.vaultCipher.data._id']));
|
|
85
123
|
|
|
86
124
|
case 2:
|
|
87
|
-
accounts =
|
|
88
|
-
return
|
|
125
|
+
accounts = _context3.sent;
|
|
126
|
+
return _context3.abrupt("return", accounts);
|
|
89
127
|
|
|
90
128
|
case 4:
|
|
91
129
|
case "end":
|
|
92
|
-
return
|
|
130
|
+
return _context3.stop();
|
|
93
131
|
}
|
|
94
132
|
}
|
|
95
|
-
},
|
|
133
|
+
}, _callee3);
|
|
96
134
|
}));
|
|
97
135
|
|
|
98
|
-
return function fetchAccountsForCipherId(
|
|
99
|
-
return
|
|
136
|
+
return function fetchAccountsForCipherId(_x6, _x7) {
|
|
137
|
+
return _ref3.apply(this, arguments);
|
|
100
138
|
};
|
|
101
139
|
}();
|
|
102
140
|
export var fetchKonnectorFromAccount = /*#__PURE__*/function () {
|
|
103
|
-
var
|
|
141
|
+
var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4(cozyClient, account) {
|
|
104
142
|
var slug, konnector;
|
|
105
|
-
return _regeneratorRuntime.wrap(function
|
|
143
|
+
return _regeneratorRuntime.wrap(function _callee4$(_context4) {
|
|
106
144
|
while (1) {
|
|
107
|
-
switch (
|
|
145
|
+
switch (_context4.prev = _context4.next) {
|
|
108
146
|
case 0:
|
|
109
147
|
slug = account.account_type;
|
|
110
|
-
|
|
148
|
+
_context4.next = 3;
|
|
111
149
|
return cozyClient.query(Q('io.cozy.konnectors').getById("io.cozy.konnectors/".concat(slug)));
|
|
112
150
|
|
|
113
151
|
case 3:
|
|
114
|
-
konnector =
|
|
115
|
-
return
|
|
152
|
+
konnector = _context4.sent;
|
|
153
|
+
return _context4.abrupt("return", konnector.data ? _objectSpread({
|
|
116
154
|
_id: konnector.data._id,
|
|
117
155
|
_type: konnector.data.type
|
|
118
156
|
}, konnector.data.attributes) : null);
|
|
119
157
|
|
|
120
158
|
case 5:
|
|
121
159
|
case "end":
|
|
122
|
-
return
|
|
160
|
+
return _context4.stop();
|
|
123
161
|
}
|
|
124
162
|
}
|
|
125
|
-
},
|
|
163
|
+
}, _callee4);
|
|
126
164
|
}));
|
|
127
165
|
|
|
128
|
-
return function fetchKonnectorFromAccount(
|
|
129
|
-
return
|
|
166
|
+
return function fetchKonnectorFromAccount(_x8, _x9) {
|
|
167
|
+
return _ref4.apply(this, arguments);
|
|
130
168
|
};
|
|
131
169
|
}();
|
|
132
170
|
export var fetchTriggersFromAccount = /*#__PURE__*/function () {
|
|
133
|
-
var
|
|
171
|
+
var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5(cozyClient, account) {
|
|
134
172
|
var triggers;
|
|
135
|
-
return _regeneratorRuntime.wrap(function
|
|
173
|
+
return _regeneratorRuntime.wrap(function _callee5$(_context5) {
|
|
136
174
|
while (1) {
|
|
137
|
-
switch (
|
|
175
|
+
switch (_context5.prev = _context5.next) {
|
|
138
176
|
case 0:
|
|
139
|
-
|
|
177
|
+
_context5.next = 2;
|
|
140
178
|
return cozyClient.queryAll(Q('io.cozy.triggers').where({
|
|
141
179
|
worker: {
|
|
142
180
|
$in: ['konnector', 'client']
|
|
@@ -145,28 +183,28 @@ export var fetchTriggersFromAccount = /*#__PURE__*/function () {
|
|
|
145
183
|
}));
|
|
146
184
|
|
|
147
185
|
case 2:
|
|
148
|
-
triggers =
|
|
149
|
-
return
|
|
186
|
+
triggers = _context5.sent;
|
|
187
|
+
return _context5.abrupt("return", triggers);
|
|
150
188
|
|
|
151
189
|
case 4:
|
|
152
190
|
case "end":
|
|
153
|
-
return
|
|
191
|
+
return _context5.stop();
|
|
154
192
|
}
|
|
155
193
|
}
|
|
156
|
-
},
|
|
194
|
+
}, _callee5);
|
|
157
195
|
}));
|
|
158
196
|
|
|
159
|
-
return function fetchTriggersFromAccount(
|
|
160
|
-
return
|
|
197
|
+
return function fetchTriggersFromAccount(_x10, _x11) {
|
|
198
|
+
return _ref5.apply(this, arguments);
|
|
161
199
|
};
|
|
162
200
|
}();
|
|
163
201
|
export var updateAccountsAuth = /*#__PURE__*/function () {
|
|
164
|
-
var
|
|
165
|
-
return _regeneratorRuntime.wrap(function
|
|
202
|
+
var _ref6 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee6(cozyClient, accounts, authData) {
|
|
203
|
+
return _regeneratorRuntime.wrap(function _callee6$(_context6) {
|
|
166
204
|
while (1) {
|
|
167
|
-
switch (
|
|
205
|
+
switch (_context6.prev = _context6.next) {
|
|
168
206
|
case 0:
|
|
169
|
-
|
|
207
|
+
_context6.next = 2;
|
|
170
208
|
return Promise.all(accounts.map(function (account) {
|
|
171
209
|
merge(account.auth, authData);
|
|
172
210
|
unset(account, 'auth.credentials_encrypted');
|
|
@@ -180,24 +218,24 @@ export var updateAccountsAuth = /*#__PURE__*/function () {
|
|
|
180
218
|
|
|
181
219
|
case 2:
|
|
182
220
|
case "end":
|
|
183
|
-
return
|
|
221
|
+
return _context6.stop();
|
|
184
222
|
}
|
|
185
223
|
}
|
|
186
|
-
},
|
|
224
|
+
}, _callee6);
|
|
187
225
|
}));
|
|
188
226
|
|
|
189
|
-
return function updateAccountsAuth(
|
|
190
|
-
return
|
|
227
|
+
return function updateAccountsAuth(_x12, _x13, _x14) {
|
|
228
|
+
return _ref6.apply(this, arguments);
|
|
191
229
|
};
|
|
192
230
|
}();
|
|
193
231
|
export var fetchLoginFailedTriggersForAccountsIds = /*#__PURE__*/function () {
|
|
194
|
-
var
|
|
232
|
+
var _ref7 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee7(cozyClient, accountsIds) {
|
|
195
233
|
var triggers, triggersIds, triggersStates, triggersToRetry;
|
|
196
|
-
return _regeneratorRuntime.wrap(function
|
|
234
|
+
return _regeneratorRuntime.wrap(function _callee7$(_context7) {
|
|
197
235
|
while (1) {
|
|
198
|
-
switch (
|
|
236
|
+
switch (_context7.prev = _context7.next) {
|
|
199
237
|
case 0:
|
|
200
|
-
|
|
238
|
+
_context7.next = 2;
|
|
201
239
|
return cozyClient.queryAll(Q('io.cozy.triggers').where({
|
|
202
240
|
worker: {
|
|
203
241
|
$in: ['konnector', 'client']
|
|
@@ -208,17 +246,17 @@ export var fetchLoginFailedTriggersForAccountsIds = /*#__PURE__*/function () {
|
|
|
208
246
|
}));
|
|
209
247
|
|
|
210
248
|
case 2:
|
|
211
|
-
triggers =
|
|
249
|
+
triggers = _context7.sent;
|
|
212
250
|
triggersIds = triggers.map(function (trigger) {
|
|
213
251
|
return trigger._id;
|
|
214
252
|
});
|
|
215
|
-
|
|
253
|
+
_context7.next = 6;
|
|
216
254
|
return Promise.all(triggersIds.map(function (triggerId) {
|
|
217
255
|
return cozyClient.getStackClient().fetchJSON('GET', "/jobs/triggers/".concat(triggerId, "/state"));
|
|
218
256
|
}));
|
|
219
257
|
|
|
220
258
|
case 6:
|
|
221
|
-
triggersStates =
|
|
259
|
+
triggersStates = _context7.sent;
|
|
222
260
|
triggersToRetry = triggersStates.filter(function (state) {
|
|
223
261
|
var _state$data$attribute = state.data.attributes,
|
|
224
262
|
status = _state$data$attribute.status,
|
|
@@ -227,40 +265,40 @@ export var fetchLoginFailedTriggersForAccountsIds = /*#__PURE__*/function () {
|
|
|
227
265
|
}).map(function (state) {
|
|
228
266
|
return state.data.id;
|
|
229
267
|
});
|
|
230
|
-
return
|
|
268
|
+
return _context7.abrupt("return", triggersToRetry);
|
|
231
269
|
|
|
232
270
|
case 9:
|
|
233
271
|
case "end":
|
|
234
|
-
return
|
|
272
|
+
return _context7.stop();
|
|
235
273
|
}
|
|
236
274
|
}
|
|
237
|
-
},
|
|
275
|
+
}, _callee7);
|
|
238
276
|
}));
|
|
239
277
|
|
|
240
|
-
return function fetchLoginFailedTriggersForAccountsIds(
|
|
241
|
-
return
|
|
278
|
+
return function fetchLoginFailedTriggersForAccountsIds(_x15, _x16) {
|
|
279
|
+
return _ref7.apply(this, arguments);
|
|
242
280
|
};
|
|
243
281
|
}();
|
|
244
282
|
export var launchTriggers = /*#__PURE__*/function () {
|
|
245
|
-
var
|
|
246
|
-
return _regeneratorRuntime.wrap(function
|
|
283
|
+
var _ref8 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee8(cozyClient, triggersIds) {
|
|
284
|
+
return _regeneratorRuntime.wrap(function _callee8$(_context8) {
|
|
247
285
|
while (1) {
|
|
248
|
-
switch (
|
|
286
|
+
switch (_context8.prev = _context8.next) {
|
|
249
287
|
case 0:
|
|
250
|
-
|
|
288
|
+
_context8.next = 2;
|
|
251
289
|
return Promise.all(triggersIds.map(function (triggerId) {
|
|
252
290
|
return cozyClient.getStackClient().fetchJSON('POST', "/jobs/triggers/".concat(triggerId, "/launch"));
|
|
253
291
|
}));
|
|
254
292
|
|
|
255
293
|
case 2:
|
|
256
294
|
case "end":
|
|
257
|
-
return
|
|
295
|
+
return _context8.stop();
|
|
258
296
|
}
|
|
259
297
|
}
|
|
260
|
-
},
|
|
298
|
+
}, _callee8);
|
|
261
299
|
}));
|
|
262
300
|
|
|
263
|
-
return function launchTriggers(
|
|
264
|
-
return
|
|
301
|
+
return function launchTriggers(_x17, _x18) {
|
|
302
|
+
return _ref8.apply(this, arguments);
|
|
265
303
|
};
|
|
266
304
|
}();
|
|
@@ -76,23 +76,58 @@ describe('decryptString', function () {
|
|
|
76
76
|
}
|
|
77
77
|
}, _callee);
|
|
78
78
|
})));
|
|
79
|
+
it('should return empty if the encrypted string is empty', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
|
|
80
|
+
var res;
|
|
81
|
+
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
|
|
82
|
+
while (1) {
|
|
83
|
+
switch (_context2.prev = _context2.next) {
|
|
84
|
+
case 0:
|
|
85
|
+
_context2.next = 2;
|
|
86
|
+
return decryptString('', mockVaultClient, new SymmetricCryptoKey('123', 2));
|
|
87
|
+
|
|
88
|
+
case 2:
|
|
89
|
+
res = _context2.sent;
|
|
90
|
+
expect(res).toEqual('');
|
|
91
|
+
|
|
92
|
+
case 4:
|
|
93
|
+
case "end":
|
|
94
|
+
return _context2.stop();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}, _callee2);
|
|
98
|
+
})));
|
|
99
|
+
it('should throw if the encrypted string is empty', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
|
|
100
|
+
return _regeneratorRuntime.wrap(function _callee3$(_context3) {
|
|
101
|
+
while (1) {
|
|
102
|
+
switch (_context3.prev = _context3.next) {
|
|
103
|
+
case 0:
|
|
104
|
+
_context3.next = 2;
|
|
105
|
+
return expect(decryptString('|', mockVaultClient, new SymmetricCryptoKey('123', 2))).rejects.toThrowError();
|
|
106
|
+
|
|
107
|
+
case 2:
|
|
108
|
+
case "end":
|
|
109
|
+
return _context3.stop();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}, _callee3);
|
|
113
|
+
})));
|
|
79
114
|
});
|
|
80
115
|
describe('getOrganizationKey', function () {
|
|
81
|
-
it('should create a SymmetricCryptoKey with the params fetched from the stack', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
116
|
+
it('should create a SymmetricCryptoKey with the params fetched from the stack', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4() {
|
|
82
117
|
var fetchedOrganizationKey, orgKey;
|
|
83
|
-
return _regeneratorRuntime.wrap(function
|
|
118
|
+
return _regeneratorRuntime.wrap(function _callee4$(_context4) {
|
|
84
119
|
while (1) {
|
|
85
|
-
switch (
|
|
120
|
+
switch (_context4.prev = _context4.next) {
|
|
86
121
|
case 0:
|
|
87
122
|
fetchedOrganizationKey = '123';
|
|
88
123
|
mockCozyClient.fetchJSON.mockResolvedValue({
|
|
89
124
|
organizationKey: fetchedOrganizationKey
|
|
90
125
|
});
|
|
91
|
-
|
|
126
|
+
_context4.next = 4;
|
|
92
127
|
return getOrganizationKey(mockCozyClient, mockVaultClient);
|
|
93
128
|
|
|
94
129
|
case 4:
|
|
95
|
-
orgKey =
|
|
130
|
+
orgKey = _context4.sent;
|
|
96
131
|
expect(mockCozyClient.fetchJSON).toHaveBeenCalledWith('GET', '/bitwarden/organizations/cozy');
|
|
97
132
|
expect(orgKey).toEqual({
|
|
98
133
|
encType: EncryptionType.AesCbc256_HmacSha256_B64,
|
|
@@ -101,19 +136,19 @@ describe('getOrganizationKey', function () {
|
|
|
101
136
|
|
|
102
137
|
case 7:
|
|
103
138
|
case "end":
|
|
104
|
-
return
|
|
139
|
+
return _context4.stop();
|
|
105
140
|
}
|
|
106
141
|
}
|
|
107
|
-
},
|
|
142
|
+
}, _callee4);
|
|
108
143
|
})));
|
|
109
144
|
});
|
|
110
145
|
describe('fetchAccountsForCipherId', function () {
|
|
111
|
-
it('should fetch accounts with a relationship with the given cipher id', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
112
|
-
return _regeneratorRuntime.wrap(function
|
|
146
|
+
it('should fetch accounts with a relationship with the given cipher id', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5() {
|
|
147
|
+
return _regeneratorRuntime.wrap(function _callee5$(_context5) {
|
|
113
148
|
while (1) {
|
|
114
|
-
switch (
|
|
149
|
+
switch (_context5.prev = _context5.next) {
|
|
115
150
|
case 0:
|
|
116
|
-
|
|
151
|
+
_context5.next = 2;
|
|
117
152
|
return fetchAccountsForCipherId(mockCozyClient, '123-456');
|
|
118
153
|
|
|
119
154
|
case 2:
|
|
@@ -130,18 +165,18 @@ describe('fetchAccountsForCipherId', function () {
|
|
|
130
165
|
|
|
131
166
|
case 3:
|
|
132
167
|
case "end":
|
|
133
|
-
return
|
|
168
|
+
return _context5.stop();
|
|
134
169
|
}
|
|
135
170
|
}
|
|
136
|
-
},
|
|
171
|
+
}, _callee5);
|
|
137
172
|
})));
|
|
138
173
|
});
|
|
139
174
|
describe('updateAccountsAuth', function () {
|
|
140
|
-
it('should update all accounts with the given credentials', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
175
|
+
it('should update all accounts with the given credentials', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee6() {
|
|
141
176
|
var accounts;
|
|
142
|
-
return _regeneratorRuntime.wrap(function
|
|
177
|
+
return _regeneratorRuntime.wrap(function _callee6$(_context6) {
|
|
143
178
|
while (1) {
|
|
144
|
-
switch (
|
|
179
|
+
switch (_context6.prev = _context6.next) {
|
|
145
180
|
case 0:
|
|
146
181
|
accounts = [{
|
|
147
182
|
auth: {
|
|
@@ -156,7 +191,7 @@ describe('updateAccountsAuth', function () {
|
|
|
156
191
|
credentials_encrypted: 'toberemoved'
|
|
157
192
|
}
|
|
158
193
|
}];
|
|
159
|
-
|
|
194
|
+
_context6.next = 3;
|
|
160
195
|
return updateAccountsAuth(mockCozyClient, accounts, {
|
|
161
196
|
login: 'newLogin',
|
|
162
197
|
password: 'newPassword'
|
|
@@ -174,18 +209,18 @@ describe('updateAccountsAuth', function () {
|
|
|
174
209
|
|
|
175
210
|
case 5:
|
|
176
211
|
case "end":
|
|
177
|
-
return
|
|
212
|
+
return _context6.stop();
|
|
178
213
|
}
|
|
179
214
|
}
|
|
180
|
-
},
|
|
215
|
+
}, _callee6);
|
|
181
216
|
})));
|
|
182
217
|
});
|
|
183
218
|
describe('fetchLoginFailedTriggersForAccountsIds', function () {
|
|
184
|
-
it('should fetch triggers that are in a LOGIN_FAILED errored state for given accounts ids', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
219
|
+
it('should fetch triggers that are in a LOGIN_FAILED errored state for given accounts ids', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee7() {
|
|
185
220
|
var i, accountsIds, triggers;
|
|
186
|
-
return _regeneratorRuntime.wrap(function
|
|
221
|
+
return _regeneratorRuntime.wrap(function _callee7$(_context7) {
|
|
187
222
|
while (1) {
|
|
188
|
-
switch (
|
|
223
|
+
switch (_context7.prev = _context7.next) {
|
|
189
224
|
case 0:
|
|
190
225
|
mockCozyClient.queryAll.mockResolvedValue([{
|
|
191
226
|
_id: 'tri1'
|
|
@@ -209,11 +244,11 @@ describe('fetchLoginFailedTriggersForAccountsIds', function () {
|
|
|
209
244
|
return triggerState;
|
|
210
245
|
});
|
|
211
246
|
accountsIds = ['acc1', 'acc2'];
|
|
212
|
-
|
|
247
|
+
_context7.next = 6;
|
|
213
248
|
return fetchLoginFailedTriggersForAccountsIds(mockCozyClient, accountsIds);
|
|
214
249
|
|
|
215
250
|
case 6:
|
|
216
|
-
triggers =
|
|
251
|
+
triggers = _context7.sent;
|
|
217
252
|
expect(mockCozyClient.queryAll).toHaveBeenCalledWith(expect.objectContaining({
|
|
218
253
|
selector: {
|
|
219
254
|
'message.account': {
|
|
@@ -228,21 +263,21 @@ describe('fetchLoginFailedTriggersForAccountsIds', function () {
|
|
|
228
263
|
|
|
229
264
|
case 9:
|
|
230
265
|
case "end":
|
|
231
|
-
return
|
|
266
|
+
return _context7.stop();
|
|
232
267
|
}
|
|
233
268
|
}
|
|
234
|
-
},
|
|
269
|
+
}, _callee7);
|
|
235
270
|
})));
|
|
236
271
|
});
|
|
237
272
|
describe('launchTriggers', function () {
|
|
238
|
-
it('should launch all triggers which ids are passed in arguments', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
273
|
+
it('should launch all triggers which ids are passed in arguments', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee8() {
|
|
239
274
|
var triggersIds;
|
|
240
|
-
return _regeneratorRuntime.wrap(function
|
|
275
|
+
return _regeneratorRuntime.wrap(function _callee8$(_context8) {
|
|
241
276
|
while (1) {
|
|
242
|
-
switch (
|
|
277
|
+
switch (_context8.prev = _context8.next) {
|
|
243
278
|
case 0:
|
|
244
279
|
triggersIds = ['tri1', 'tri2'];
|
|
245
|
-
|
|
280
|
+
_context8.next = 3;
|
|
246
281
|
return launchTriggers(mockCozyClient, triggersIds);
|
|
247
282
|
|
|
248
283
|
case 3:
|
|
@@ -252,9 +287,9 @@ describe('launchTriggers', function () {
|
|
|
252
287
|
|
|
253
288
|
case 6:
|
|
254
289
|
case "end":
|
|
255
|
-
return
|
|
290
|
+
return _context8.stop();
|
|
256
291
|
}
|
|
257
292
|
}
|
|
258
|
-
},
|
|
293
|
+
}, _callee8);
|
|
259
294
|
})));
|
|
260
295
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cozy-harvest-lib",
|
|
3
|
-
"version": "9.26.
|
|
3
|
+
"version": "9.26.15",
|
|
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.85.
|
|
32
|
+
"cozy-doctypes": "^1.85.4",
|
|
33
33
|
"cozy-logger": "^1.9.1",
|
|
34
34
|
"date-fns": "^1.30.1",
|
|
35
35
|
"final-form": "^4.18.5",
|
|
@@ -51,13 +51,13 @@
|
|
|
51
51
|
"@testing-library/react": "10.4.9",
|
|
52
52
|
"babel-jest": "26.6.3",
|
|
53
53
|
"babel-plugin-inline-react-svg": "1.1.2",
|
|
54
|
-
"babel-preset-cozy-app": "^2.0.
|
|
54
|
+
"babel-preset-cozy-app": "^2.0.4",
|
|
55
55
|
"cozy-client": "27.17.0",
|
|
56
|
-
"cozy-device-helper": "^2.4.
|
|
57
|
-
"cozy-flags": "^2.10.
|
|
58
|
-
"cozy-intent": "^2.5.
|
|
56
|
+
"cozy-device-helper": "^2.4.1",
|
|
57
|
+
"cozy-flags": "^2.10.2",
|
|
58
|
+
"cozy-intent": "^2.5.1",
|
|
59
59
|
"cozy-keys-lib": "^4.1.9",
|
|
60
|
-
"cozy-realtime": "^4.2.
|
|
60
|
+
"cozy-realtime": "^4.2.6",
|
|
61
61
|
"cozy-ui": "60.6.0",
|
|
62
62
|
"enzyme": "3.11.0",
|
|
63
63
|
"enzyme-adapter-react-16": "1.15.6",
|
|
@@ -90,5 +90,5 @@
|
|
|
90
90
|
"react-router-dom": "^5.0.1"
|
|
91
91
|
},
|
|
92
92
|
"sideEffects": false,
|
|
93
|
-
"gitHead": "
|
|
93
|
+
"gitHead": "adad3d4b00ef7cd3aafdcab927bcb7e5288d6df5"
|
|
94
94
|
}
|
package/src/services/utils.js
CHANGED
|
@@ -5,9 +5,25 @@ import Polyglot from 'node-polyglot'
|
|
|
5
5
|
import { Q } from 'cozy-client'
|
|
6
6
|
import SymmetricCryptoKey from 'cozy-keys-lib/transpiled/SymmetricCryptoKey'
|
|
7
7
|
import EncryptionType from 'cozy-keys-lib/transpiled/EncryptionType'
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
import logger from './logger'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Decrypt the given string with the organization key
|
|
12
|
+
*
|
|
13
|
+
* @param {string} encryptedString - The encrypted string
|
|
14
|
+
* @param {object} vaultClient - The vault client
|
|
15
|
+
* @param {ArrayBuffer} orgKey - The organization key
|
|
16
|
+
* @returns {Promise<string>} The decrypted string
|
|
17
|
+
*/
|
|
18
|
+
export const decryptString = async (encryptedString, vaultClient, orgKey) => {
|
|
19
|
+
if (!encryptedString) {
|
|
20
|
+
return ''
|
|
21
|
+
}
|
|
10
22
|
const [encTypeAndIv, data, mac] = encryptedString.split('|')
|
|
23
|
+
if (!encTypeAndIv) {
|
|
24
|
+
logger.error('Encrypted string is malformed')
|
|
25
|
+
throw new Error('DECRYPT_FAILED')
|
|
26
|
+
}
|
|
11
27
|
const [encTypeString, iv] = encTypeAndIv.split('.')
|
|
12
28
|
const encType = parseInt(encTypeString, 10)
|
|
13
29
|
|
|
@@ -63,6 +63,21 @@ describe('decryptString', () => {
|
|
|
63
63
|
orgKey
|
|
64
64
|
)
|
|
65
65
|
})
|
|
66
|
+
|
|
67
|
+
it('should return empty if the encrypted string is empty', async () => {
|
|
68
|
+
const res = await decryptString(
|
|
69
|
+
'',
|
|
70
|
+
mockVaultClient,
|
|
71
|
+
new SymmetricCryptoKey('123', 2)
|
|
72
|
+
)
|
|
73
|
+
expect(res).toEqual('')
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('should throw if the encrypted string is empty', async () => {
|
|
77
|
+
await expect(
|
|
78
|
+
decryptString('|', mockVaultClient, new SymmetricCryptoKey('123', 2))
|
|
79
|
+
).rejects.toThrowError()
|
|
80
|
+
})
|
|
66
81
|
})
|
|
67
82
|
|
|
68
83
|
describe('getOrganizationKey', () => {
|