cozy-harvest-lib 9.26.13 → 9.26.14

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,17 @@
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.14](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@9.26.13...cozy-harvest-lib@9.26.14) (2022-09-19)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * Deal with empty and malformed encrypted values ([b4a6406](https://github.com/cozy/cozy-libs/commit/b4a6406be80cec7d3b7246dc42c19a419e442224))
12
+
13
+
14
+
15
+
16
+
6
17
  ## [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
18
 
8
19
 
@@ -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
- export var decryptString = function decryptString(encryptedString, vaultClient, orgKey) {
17
- var _encryptedString$spli = encryptedString.split('|'),
18
- _encryptedString$spli2 = _slicedToArray(_encryptedString$spli, 3),
19
- encTypeAndIv = _encryptedString$spli2[0],
20
- data = _encryptedString$spli2[1],
21
- mac = _encryptedString$spli2[2];
22
-
23
- var _encTypeAndIv$split = encTypeAndIv.split('.'),
24
- _encTypeAndIv$split2 = _slicedToArray(_encTypeAndIv$split, 2),
25
- encTypeString = _encTypeAndIv$split2[0],
26
- iv = _encTypeAndIv$split2[1];
27
-
28
- var encType = parseInt(encTypeString, 10);
29
- return vaultClient.cryptoService.aesDecryptToUtf8(encType, data, iv, mac, orgKey);
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 _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(cozyClient, vaultClient) {
82
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(cozyClient, vaultClient) {
45
83
  var cozyKeys, orgKeyEncType, orgKey;
46
- return _regeneratorRuntime.wrap(function _callee$(_context) {
84
+ return _regeneratorRuntime.wrap(function _callee2$(_context2) {
47
85
  while (1) {
48
- switch (_context.prev = _context.next) {
86
+ switch (_context2.prev = _context2.next) {
49
87
  case 0:
50
- _context.next = 2;
88
+ _context2.next = 2;
51
89
  return cozyClient.getStackClient().fetchJSON('GET', '/bitwarden/organizations/cozy');
52
90
 
53
91
  case 2:
54
- cozyKeys = _context.sent;
92
+ cozyKeys = _context2.sent;
55
93
  orgKeyEncType = EncryptionType.AesCbc256_HmacSha256_B64;
56
94
  orgKey = new SymmetricCryptoKey(vaultClient.Utils.fromB64ToArray(cozyKeys.organizationKey), orgKeyEncType);
57
- return _context.abrupt("return", orgKey);
95
+ return _context2.abrupt("return", orgKey);
58
96
 
59
97
  case 6:
60
98
  case "end":
61
- return _context.stop();
99
+ return _context2.stop();
62
100
  }
63
101
  }
64
- }, _callee);
102
+ }, _callee2);
65
103
  }));
66
104
 
67
- return function getOrganizationKey(_x, _x2) {
68
- return _ref.apply(this, arguments);
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 _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(cozyClient, cipherId) {
110
+ var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(cozyClient, cipherId) {
73
111
  var accounts;
74
- return _regeneratorRuntime.wrap(function _callee2$(_context2) {
112
+ return _regeneratorRuntime.wrap(function _callee3$(_context3) {
75
113
  while (1) {
76
- switch (_context2.prev = _context2.next) {
114
+ switch (_context3.prev = _context3.next) {
77
115
  case 0:
78
- _context2.next = 2;
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 = _context2.sent;
88
- return _context2.abrupt("return", accounts);
125
+ accounts = _context3.sent;
126
+ return _context3.abrupt("return", accounts);
89
127
 
90
128
  case 4:
91
129
  case "end":
92
- return _context2.stop();
130
+ return _context3.stop();
93
131
  }
94
132
  }
95
- }, _callee2);
133
+ }, _callee3);
96
134
  }));
97
135
 
98
- return function fetchAccountsForCipherId(_x3, _x4) {
99
- return _ref2.apply(this, arguments);
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 _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(cozyClient, account) {
141
+ var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4(cozyClient, account) {
104
142
  var slug, konnector;
105
- return _regeneratorRuntime.wrap(function _callee3$(_context3) {
143
+ return _regeneratorRuntime.wrap(function _callee4$(_context4) {
106
144
  while (1) {
107
- switch (_context3.prev = _context3.next) {
145
+ switch (_context4.prev = _context4.next) {
108
146
  case 0:
109
147
  slug = account.account_type;
110
- _context3.next = 3;
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 = _context3.sent;
115
- return _context3.abrupt("return", konnector.data ? _objectSpread({
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 _context3.stop();
160
+ return _context4.stop();
123
161
  }
124
162
  }
125
- }, _callee3);
163
+ }, _callee4);
126
164
  }));
127
165
 
128
- return function fetchKonnectorFromAccount(_x5, _x6) {
129
- return _ref3.apply(this, arguments);
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 _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4(cozyClient, account) {
171
+ var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5(cozyClient, account) {
134
172
  var triggers;
135
- return _regeneratorRuntime.wrap(function _callee4$(_context4) {
173
+ return _regeneratorRuntime.wrap(function _callee5$(_context5) {
136
174
  while (1) {
137
- switch (_context4.prev = _context4.next) {
175
+ switch (_context5.prev = _context5.next) {
138
176
  case 0:
139
- _context4.next = 2;
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 = _context4.sent;
149
- return _context4.abrupt("return", triggers);
186
+ triggers = _context5.sent;
187
+ return _context5.abrupt("return", triggers);
150
188
 
151
189
  case 4:
152
190
  case "end":
153
- return _context4.stop();
191
+ return _context5.stop();
154
192
  }
155
193
  }
156
- }, _callee4);
194
+ }, _callee5);
157
195
  }));
158
196
 
159
- return function fetchTriggersFromAccount(_x7, _x8) {
160
- return _ref4.apply(this, arguments);
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 _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5(cozyClient, accounts, authData) {
165
- return _regeneratorRuntime.wrap(function _callee5$(_context5) {
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 (_context5.prev = _context5.next) {
205
+ switch (_context6.prev = _context6.next) {
168
206
  case 0:
169
- _context5.next = 2;
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 _context5.stop();
221
+ return _context6.stop();
184
222
  }
185
223
  }
186
- }, _callee5);
224
+ }, _callee6);
187
225
  }));
188
226
 
189
- return function updateAccountsAuth(_x9, _x10, _x11) {
190
- return _ref5.apply(this, arguments);
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 _ref6 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee6(cozyClient, accountsIds) {
232
+ var _ref7 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee7(cozyClient, accountsIds) {
195
233
  var triggers, triggersIds, triggersStates, triggersToRetry;
196
- return _regeneratorRuntime.wrap(function _callee6$(_context6) {
234
+ return _regeneratorRuntime.wrap(function _callee7$(_context7) {
197
235
  while (1) {
198
- switch (_context6.prev = _context6.next) {
236
+ switch (_context7.prev = _context7.next) {
199
237
  case 0:
200
- _context6.next = 2;
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 = _context6.sent;
249
+ triggers = _context7.sent;
212
250
  triggersIds = triggers.map(function (trigger) {
213
251
  return trigger._id;
214
252
  });
215
- _context6.next = 6;
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 = _context6.sent;
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 _context6.abrupt("return", triggersToRetry);
268
+ return _context7.abrupt("return", triggersToRetry);
231
269
 
232
270
  case 9:
233
271
  case "end":
234
- return _context6.stop();
272
+ return _context7.stop();
235
273
  }
236
274
  }
237
- }, _callee6);
275
+ }, _callee7);
238
276
  }));
239
277
 
240
- return function fetchLoginFailedTriggersForAccountsIds(_x12, _x13) {
241
- return _ref6.apply(this, arguments);
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 _ref7 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee7(cozyClient, triggersIds) {
246
- return _regeneratorRuntime.wrap(function _callee7$(_context7) {
283
+ var _ref8 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee8(cozyClient, triggersIds) {
284
+ return _regeneratorRuntime.wrap(function _callee8$(_context8) {
247
285
  while (1) {
248
- switch (_context7.prev = _context7.next) {
286
+ switch (_context8.prev = _context8.next) {
249
287
  case 0:
250
- _context7.next = 2;
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 _context7.stop();
295
+ return _context8.stop();
258
296
  }
259
297
  }
260
- }, _callee7);
298
+ }, _callee8);
261
299
  }));
262
300
 
263
- return function launchTriggers(_x14, _x15) {
264
- return _ref7.apply(this, arguments);
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 _callee2() {
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 _callee2$(_context2) {
118
+ return _regeneratorRuntime.wrap(function _callee4$(_context4) {
84
119
  while (1) {
85
- switch (_context2.prev = _context2.next) {
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
- _context2.next = 4;
126
+ _context4.next = 4;
92
127
  return getOrganizationKey(mockCozyClient, mockVaultClient);
93
128
 
94
129
  case 4:
95
- orgKey = _context2.sent;
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 _context2.stop();
139
+ return _context4.stop();
105
140
  }
106
141
  }
107
- }, _callee2);
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 _callee3() {
112
- return _regeneratorRuntime.wrap(function _callee3$(_context3) {
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 (_context3.prev = _context3.next) {
149
+ switch (_context5.prev = _context5.next) {
115
150
  case 0:
116
- _context3.next = 2;
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 _context3.stop();
168
+ return _context5.stop();
134
169
  }
135
170
  }
136
- }, _callee3);
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 _callee4() {
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 _callee4$(_context4) {
177
+ return _regeneratorRuntime.wrap(function _callee6$(_context6) {
143
178
  while (1) {
144
- switch (_context4.prev = _context4.next) {
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
- _context4.next = 3;
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 _context4.stop();
212
+ return _context6.stop();
178
213
  }
179
214
  }
180
- }, _callee4);
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 _callee5() {
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 _callee5$(_context5) {
221
+ return _regeneratorRuntime.wrap(function _callee7$(_context7) {
187
222
  while (1) {
188
- switch (_context5.prev = _context5.next) {
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
- _context5.next = 6;
247
+ _context7.next = 6;
213
248
  return fetchLoginFailedTriggersForAccountsIds(mockCozyClient, accountsIds);
214
249
 
215
250
  case 6:
216
- triggers = _context5.sent;
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 _context5.stop();
266
+ return _context7.stop();
232
267
  }
233
268
  }
234
- }, _callee5);
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 _callee6() {
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 _callee6$(_context6) {
275
+ return _regeneratorRuntime.wrap(function _callee8$(_context8) {
241
276
  while (1) {
242
- switch (_context6.prev = _context6.next) {
277
+ switch (_context8.prev = _context8.next) {
243
278
  case 0:
244
279
  triggersIds = ['tri1', 'tri2'];
245
- _context6.next = 3;
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 _context6.stop();
290
+ return _context8.stop();
256
291
  }
257
292
  }
258
- }, _callee6);
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.13",
3
+ "version": "9.26.14",
4
4
  "description": "Provides logic, modules and components for Cozy's harvest applications.",
5
5
  "main": "dist/index.js",
6
6
  "author": "Cozy",
@@ -90,5 +90,5 @@
90
90
  "react-router-dom": "^5.0.1"
91
91
  },
92
92
  "sideEffects": false,
93
- "gitHead": "f7d4761ad1b80385ba4977c193ef8b7177413ca8"
93
+ "gitHead": "16f7bf24064d091e969cebb24cf04c19c4738e93"
94
94
  }
@@ -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
- export const decryptString = (encryptedString, vaultClient, orgKey) => {
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', () => {