@webex/internal-plugin-encryption 3.0.0-beta.4 → 3.0.0-beta.400

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.
Files changed (42) hide show
  1. package/README.md +1 -3
  2. package/dist/config.js +0 -9
  3. package/dist/config.js.map +1 -1
  4. package/dist/constants.js +14 -0
  5. package/dist/constants.js.map +1 -0
  6. package/dist/encryption.js +25 -74
  7. package/dist/encryption.js.map +1 -1
  8. package/dist/ensure-buffer.browser.js +0 -12
  9. package/dist/ensure-buffer.browser.js.map +1 -1
  10. package/dist/ensure-buffer.js +5 -12
  11. package/dist/ensure-buffer.js.map +1 -1
  12. package/dist/index.js +7 -33
  13. package/dist/index.js.map +1 -1
  14. package/dist/kms-batcher.js +7 -30
  15. package/dist/kms-batcher.js.map +1 -1
  16. package/dist/kms-certificate-validation.js +24 -90
  17. package/dist/kms-certificate-validation.js.map +1 -1
  18. package/dist/kms-dry-error-interceptor.js +1 -23
  19. package/dist/kms-dry-error-interceptor.js.map +1 -1
  20. package/dist/kms-errors.js +21 -51
  21. package/dist/kms-errors.js.map +1 -1
  22. package/dist/kms.js +88 -218
  23. package/dist/kms.js.map +1 -1
  24. package/package.json +15 -15
  25. package/src/config.js +3 -3
  26. package/src/constants.js +3 -0
  27. package/src/encryption.js +74 -57
  28. package/src/ensure-buffer.browser.js +0 -1
  29. package/src/ensure-buffer.js +5 -5
  30. package/src/index.js +120 -96
  31. package/src/kms-batcher.js +53 -45
  32. package/src/kms-certificate-validation.js +48 -50
  33. package/src/kms-dry-error-interceptor.js +8 -4
  34. package/src/kms-errors.js +47 -16
  35. package/src/kms.js +219 -212
  36. package/test/integration/spec/encryption.js +313 -231
  37. package/test/integration/spec/kms.js +532 -405
  38. package/test/integration/spec/payload-transfom.js +69 -69
  39. package/test/unit/spec/encryption.js +21 -18
  40. package/test/unit/spec/kms-certificate-validation.js +76 -34
  41. package/test/unit/spec/kms-errors.js +70 -0
  42. package/test/unit/spec/kms.js +103 -0
package/src/kms.js CHANGED
@@ -29,7 +29,7 @@ const KMS = WebexPlugin.extend({
29
29
  namespace: 'Encryption',
30
30
 
31
31
  children: {
32
- batcher: KMSBatcher
32
+ batcher: KMSBatcher,
33
33
  },
34
34
 
35
35
  /**
@@ -41,9 +41,7 @@ const KMS = WebexPlugin.extend({
41
41
  * @param {string} options.keyUri
42
42
  * @returns {Promise<Key>}
43
43
  */
44
- bindKey({
45
- kro, kroUri, key, keyUri
46
- }) {
44
+ bindKey({kro, kroUri, key, keyUri}) {
47
45
  kroUri = kroUri || kro.uri;
48
46
  keyUri = keyUri || key.uri;
49
47
 
@@ -62,13 +60,12 @@ const KMS = WebexPlugin.extend({
62
60
  return this.request({
63
61
  method: 'update',
64
62
  resourceUri: kroUri,
65
- uri: keyUri
66
- })
67
- .then((res) => {
68
- this.logger.info('kms: bound key to resource');
63
+ uri: keyUri,
64
+ }).then((res) => {
65
+ this.logger.info('kms: bound key to resource');
69
66
 
70
- return res.key;
71
- });
67
+ return res.key;
68
+ });
72
69
  },
73
70
 
74
71
  /**
@@ -80,9 +77,7 @@ const KMS = WebexPlugin.extend({
80
77
  * @param {Array<Keys>} options.keys
81
78
  * @returns {Promise<KMSResourceObject>}
82
79
  */
83
- createResource({
84
- userIds, keyUris, key, keys
85
- }) {
80
+ createResource({userIds, keyUris, key, keys}) {
86
81
  keyUris = keyUris || [];
87
82
  /* istanbul ignore if */
88
83
  if (keys) {
@@ -109,13 +104,12 @@ const KMS = WebexPlugin.extend({
109
104
  method: 'create',
110
105
  uri: '/resources',
111
106
  userIds,
112
- keyUris
113
- })
114
- .then((res) => {
115
- this.logger.info('kms: created resource');
107
+ keyUris,
108
+ }).then((res) => {
109
+ this.logger.info('kms: created resource');
116
110
 
117
- return res.resource;
118
- });
111
+ return res.resource;
112
+ });
119
113
  },
120
114
 
121
115
  /**
@@ -127,9 +121,7 @@ const KMS = WebexPlugin.extend({
127
121
  * @param {string} options.kroUri
128
122
  * @returns {Promise<KMSAuthorizationObject>}
129
123
  */
130
- addAuthorization({
131
- userIds, authIds, kro, kroUri
132
- }) {
124
+ addAuthorization({userIds, authIds, kro, kroUri}) {
133
125
  userIds = userIds || [];
134
126
  kroUri = kroUri || kro.uri;
135
127
 
@@ -153,13 +145,12 @@ const KMS = WebexPlugin.extend({
153
145
  method: 'create',
154
146
  uri: '/authorizations',
155
147
  resourceUri: kroUri,
156
- userIds
157
- })
158
- .then((res) => {
159
- this.logger.info('kms: added authorization');
148
+ userIds,
149
+ }).then((res) => {
150
+ this.logger.info('kms: added authorization');
160
151
 
161
- return res.authorizations;
162
- });
152
+ return res.authorizations;
153
+ });
163
154
  },
164
155
 
165
156
  /**
@@ -178,13 +169,12 @@ const KMS = WebexPlugin.extend({
178
169
 
179
170
  return this.request({
180
171
  method: 'retrieve',
181
- uri: `${kroUri}/authorizations`
182
- })
183
- .then((res) => {
184
- this.logger.info('kms: retrieved authorization list');
172
+ uri: `${kroUri}/authorizations`,
173
+ }).then((res) => {
174
+ this.logger.info('kms: retrieved authorization list');
185
175
 
186
- return res.authorizations;
187
- });
176
+ return res.authorizations;
177
+ });
188
178
  },
189
179
 
190
180
  /**
@@ -196,9 +186,7 @@ const KMS = WebexPlugin.extend({
196
186
  * @param {string} options.kroUri
197
187
  * @returns {Promise<KMSAuthorizationObject>}
198
188
  */
199
- removeAuthorization({
200
- authId, userId, kro, kroUri
201
- }) {
189
+ removeAuthorization({authId, userId, kro, kroUri}) {
202
190
  authId = authId || userId;
203
191
  kroUri = kroUri || kro.uri;
204
192
 
@@ -216,13 +204,12 @@ const KMS = WebexPlugin.extend({
216
204
 
217
205
  return this.request({
218
206
  method: 'delete',
219
- uri: `${kroUri}/authorizations?${querystring.stringify({authId})}`
220
- })
221
- .then((res) => {
222
- this.logger.info('kms: removed authorization');
207
+ uri: `${kroUri}/authorizations?${querystring.stringify({authId})}`,
208
+ }).then((res) => {
209
+ this.logger.info('kms: removed authorization');
223
210
 
224
- return res.authorizations;
225
- });
211
+ return res.authorizations;
212
+ });
226
213
  },
227
214
 
228
215
  /**
@@ -242,21 +229,20 @@ const KMS = WebexPlugin.extend({
242
229
  return this.request({
243
230
  method: 'create',
244
231
  uri: '/keys',
245
- count
246
- })
247
- .then((res) => {
248
- this.logger.info('kms: received unbound keys');
232
+ count,
233
+ }).then((res) => {
234
+ this.logger.info('kms: received unbound keys');
249
235
 
250
- return Promise.all(res.keys.map(this.asKey));
251
- });
236
+ return Promise.all(res.keys.map(this.asKey));
237
+ });
252
238
  },
253
239
 
254
240
  /**
255
- * @typedef {Object} FetchPublicKeyResponse
256
- * @property {number} status 200,400(Bad Request: Request payload missing info),404(Not Found: HSM Public Key not found),501(Not Implemented: This KMS does not support BYOK),502(Bad Gateway: KMS could not communicate with HSM)
257
- * @property {UUID} requestId this is should be unique, used for debug.
258
- * @property {string} publicKey
259
- */
241
+ * @typedef {Object} FetchPublicKeyResponse
242
+ * @property {number} status 200,400(Bad Request: Request payload missing info),404(Not Found: HSM Public Key not found),501(Not Implemented: This KMS does not support BYOK),502(Bad Gateway: KMS could not communicate with HSM)
243
+ * @property {UUID} requestId this is should be unique, used for debug.
244
+ * @property {string} publicKey
245
+ */
260
246
  /**
261
247
  * get public key from kms
262
248
  * @param {Object} options
@@ -269,38 +255,38 @@ const KMS = WebexPlugin.extend({
269
255
  return this.request({
270
256
  method: 'retrieve',
271
257
  uri: '/publicKey',
272
- assignedOrgId
273
- })
274
- .then((res) => {
275
- this.logger.info('kms: received public key');
258
+ assignedOrgId,
259
+ }).then((res) => {
260
+ this.logger.info('kms: received public key');
276
261
 
277
- return res.publicKey;
278
- });
262
+ return res.publicKey;
263
+ });
279
264
  },
280
265
 
281
266
  /**
282
- * @typedef {Object} UploadCmkResponse
283
- * @property {number} status
284
- * @property {UUID} requestId
285
- * @property {string} uri
286
- * @property {string} keysState
287
- */
267
+ * @typedef {Object} UploadCmkResponse
268
+ * @property {number} status
269
+ * @property {UUID} requestId
270
+ * @property {string} uri
271
+ * @property {string} keysState
272
+ */
288
273
  /**
289
274
  * upload master key for one org.
290
275
  * @param {Object} options
291
276
  * @param {UUID} options.assignedOrgId the orgId
292
277
  * @param {string} options.customerMasterKey the master key
278
+ * @param {boolean} options.awsKms enable amazon aws keys
293
279
  * @returns {Promise.<UploadCmkResponse>} response of upload CMK api
294
280
  */
295
- uploadCustomerMasterKey({assignedOrgId, customerMasterKey}) {
281
+ uploadCustomerMasterKey({assignedOrgId, customerMasterKey, awsKms = false}) {
296
282
  this.logger.info('kms: upload customer master key for byok');
297
283
 
298
284
  return this.request({
299
285
  method: 'create',
300
- uri: '/cmk',
286
+ uri: awsKms ? '/awsKmsCmk' : '/cmk',
301
287
  assignedOrgId,
302
288
  customerMasterKey,
303
- requestId: uuid.v4()
289
+ requestId: uuid.v4(),
304
290
  }).then((res) => {
305
291
  this.logger.info('kms: finish to upload customer master key');
306
292
 
@@ -312,16 +298,17 @@ const KMS = WebexPlugin.extend({
312
298
  * get all customer master keys for one org.
313
299
  * @param {Object} options
314
300
  * @param {UUID} options.assignedOrgId the orgId
301
+ * @param {boolean} options.awsKms enable amazon aws keys
315
302
  * @returns {Promise.<ActivateCmkResponse>} response of list CMKs api
316
303
  */
317
- listAllCustomerMasterKey({assignedOrgId}) {
304
+ listAllCustomerMasterKey({assignedOrgId, awsKms = false}) {
318
305
  this.logger.info('kms: get all customer master keys for byok');
319
306
 
320
307
  return this.request({
321
308
  method: 'retrieve',
322
- uri: '/cmk',
309
+ uri: awsKms ? '/awsKmsCmk' : '/cmk',
323
310
  assignedOrgId,
324
- requestId: uuid.v4()
311
+ requestId: uuid.v4(),
325
312
  }).then((res) => {
326
313
  this.logger.info('kms: finish to get all customer master keys');
327
314
 
@@ -330,11 +317,11 @@ const KMS = WebexPlugin.extend({
330
317
  },
331
318
 
332
319
  /**
333
- * @typedef {Object} ActivateCmkResponse
334
- * @property {number} status
335
- * @property {UUID} requestId
336
- * @property {Array<CMK>} customerMasterKeys
337
- */
320
+ * @typedef {Object} ActivateCmkResponse
321
+ * @property {number} status
322
+ * @property {UUID} requestId
323
+ * @property {Array<CMK>} customerMasterKeys
324
+ */
338
325
  /**
339
326
  *
340
327
  * @typedef {Object} CMK
@@ -364,7 +351,7 @@ const KMS = WebexPlugin.extend({
364
351
  uri: keyId,
365
352
  keyState,
366
353
  assignedOrgId,
367
- requestId: uuid.v4()
354
+ requestId: uuid.v4(),
368
355
  }).then((res) => {
369
356
  this.logger.info('kms: finish to change the customer master key state to {}', keyState);
370
357
 
@@ -376,16 +363,17 @@ const KMS = WebexPlugin.extend({
376
363
  * this is for test case. it will delete all CMKs, no matter what their status is. This is mainly for test purpose
377
364
  * @param {Object} options
378
365
  * @param {UUID} options.assignedOrgId the orgId
366
+ * @param {boolean} options.awsKms enable amazon aws keys
379
367
  * @returns {Promise.<{status, requestId}>}
380
368
  */
381
- deleteAllCustomerMasterKeys({assignedOrgId}) {
369
+ deleteAllCustomerMasterKeys({assignedOrgId, awsKms = false}) {
382
370
  this.logger.info('kms: delete all customer master keys at the same time');
383
371
 
384
372
  return this.request({
385
373
  method: 'delete',
386
- uri: '/cmk',
374
+ uri: awsKms ? '/awsKmsCmk' : '/cmk',
387
375
  assignedOrgId,
388
- requestId: uuid.v4()
376
+ requestId: uuid.v4(),
389
377
  }).then((res) => {
390
378
  this.logger.info('kms: finish to delete all customer master keys');
391
379
 
@@ -407,7 +395,7 @@ const KMS = WebexPlugin.extend({
407
395
  uri: 'default',
408
396
  keyState: 'ACTIVE',
409
397
  assignedOrgId,
410
- requestId: uuid.v4()
398
+ requestId: uuid.v4(),
411
399
  }).then((res) => {
412
400
  this.logger.info('kms: finish to return to global master key');
413
401
 
@@ -427,7 +415,7 @@ const KMS = WebexPlugin.extend({
427
415
  // request. as such, we need the batcher to group requests, but one flight to
428
416
  // make sure we don't make the same request multiple times.
429
417
  @oneFlight({
430
- keyFactory: ({uri, onBehalfOf}) => `${uri}/${onBehalfOf}`
418
+ keyFactory: ({uri, onBehalfOf}) => `${uri}/${onBehalfOf}`,
431
419
  })
432
420
  fetchKey({uri, onBehalfOf}) {
433
421
  /* istanbul ignore if */
@@ -437,15 +425,17 @@ const KMS = WebexPlugin.extend({
437
425
 
438
426
  this.logger.info('kms: fetching key');
439
427
 
440
- return this.request({
441
- method: 'retrieve',
442
- uri
443
- }, {onBehalfOf})
444
- .then((res) => {
445
- this.logger.info('kms: fetched key');
428
+ return this.request(
429
+ {
430
+ method: 'retrieve',
431
+ uri,
432
+ },
433
+ {onBehalfOf}
434
+ ).then((res) => {
435
+ this.logger.info('kms: fetched key');
446
436
 
447
- return this.asKey(res.key);
448
- });
437
+ return this.asKey(res.key);
438
+ });
449
439
  },
450
440
 
451
441
  /**
@@ -455,7 +445,7 @@ const KMS = WebexPlugin.extend({
455
445
  ping() {
456
446
  return this.request({
457
447
  method: 'update',
458
- uri: '/ping'
448
+ uri: '/ping',
459
449
  });
460
450
  },
461
451
 
@@ -465,12 +455,11 @@ const KMS = WebexPlugin.extend({
465
455
  * @returns {Promise<Key>}
466
456
  */
467
457
  asKey(key) {
468
- return jose.JWK.asKey(key.jwk)
469
- .then((jwk) => {
470
- key.jwk = jwk;
458
+ return jose.JWK.asKey(key.jwk).then((jwk) => {
459
+ key.jwk = jwk;
471
460
 
472
- return key;
473
- });
461
+ return key;
462
+ });
474
463
  },
475
464
 
476
465
  /**
@@ -482,8 +471,8 @@ const KMS = WebexPlugin.extend({
482
471
  prepareRequest(payload, onBehalfOf) {
483
472
  const isECDHRequest = payload.method === 'create' && payload.uri.includes('/ecdhe');
484
473
 
485
- return Promise.resolve(isECDHRequest ? partialContexts.get(this) : this._getContext())
486
- .then((context) => {
474
+ return Promise.resolve(isECDHRequest ? partialContexts.get(this) : this._getContext()).then(
475
+ (context) => {
487
476
  this.logger.info(`kms: wrapping ${isECDHRequest ? 'ephemeral key' : 'kms'} request`);
488
477
  const req = new Request(payload);
489
478
  let requestContext = context;
@@ -492,16 +481,19 @@ const KMS = WebexPlugin.extend({
492
481
  requestContext = this._contextOnBehalfOf(context, onBehalfOf);
493
482
  }
494
483
 
495
- return req.wrap(requestContext, {serverKey: isECDHRequest})
496
- .then(() => {
497
- /* istanbul ignore else */
498
- if (process.env.NODE_ENV !== 'production') {
499
- this.logger.info('kms: request payload', util.inspect(omit(JSON.parse(JSON.stringify(req)), 'wrapped'), {depth: null}));
500
- }
484
+ return req.wrap(requestContext, {serverKey: isECDHRequest}).then(() => {
485
+ /* istanbul ignore else */
486
+ if (process.env.NODE_ENV !== 'production') {
487
+ this.logger.info(
488
+ 'kms: request payload',
489
+ util.inspect(omit(JSON.parse(JSON.stringify(req)), 'wrapped'), {depth: null})
490
+ );
491
+ }
501
492
 
502
- return req;
503
- });
504
- });
493
+ return req;
494
+ });
495
+ }
496
+ );
505
497
  },
506
498
 
507
499
  /**
@@ -512,25 +504,35 @@ const KMS = WebexPlugin.extend({
512
504
  processKmsMessageEvent(event) {
513
505
  this.logger.info('kms: received kms message');
514
506
 
515
- return Promise.all(event.encryption.kmsMessages.map((kmsMessage, index) => this._isECDHEMessage(kmsMessage)
516
- .then((isECDHMessage) => {
517
- this.logger.info(`kms: received ${isECDHMessage ? 'ecdhe' : 'normal'} message`);
518
- const res = new Response(kmsMessage);
519
-
520
- return Promise.resolve(isECDHMessage ? partialContexts.get(this) : contexts.get(this))
521
- // eslint-disable-next-line max-nested-callbacks
522
- .then((context) => res.unwrap(context))
523
- // eslint-disable-next-line max-nested-callbacks
524
- .then(() => {
525
- if (process.env.NODE_ENV !== 'production') {
526
- this.logger.info('kms: response payload', util.inspect(omit(JSON.parse(JSON.stringify(res)), 'wrapped'), {depth: null}));
527
- }
528
- })
529
- // eslint-disable-next-line max-nested-callbacks
530
- .then(() => { event.encryption.kmsMessages[index] = res; })
531
- // eslint-disable-next-line max-nested-callbacks
532
- .then(() => res);
533
- })))
507
+ return Promise.all(
508
+ event.encryption.kmsMessages.map((kmsMessage, index) =>
509
+ this._isECDHEMessage(kmsMessage).then((isECDHMessage) => {
510
+ this.logger.info(`kms: received ${isECDHMessage ? 'ecdhe' : 'normal'} message`);
511
+ const res = new Response(kmsMessage);
512
+
513
+ return (
514
+ Promise.resolve(isECDHMessage ? partialContexts.get(this) : contexts.get(this))
515
+ // eslint-disable-next-line max-nested-callbacks
516
+ .then((context) => res.unwrap(context))
517
+ // eslint-disable-next-line max-nested-callbacks
518
+ .then(() => {
519
+ if (process.env.NODE_ENV !== 'production') {
520
+ this.logger.info(
521
+ 'kms: response payload',
522
+ util.inspect(omit(JSON.parse(JSON.stringify(res)), 'wrapped'), {depth: null})
523
+ );
524
+ }
525
+ })
526
+ // eslint-disable-next-line max-nested-callbacks
527
+ .then(() => {
528
+ event.encryption.kmsMessages[index] = res;
529
+ })
530
+ // eslint-disable-next-line max-nested-callbacks
531
+ .then(() => res)
532
+ );
533
+ })
534
+ )
535
+ )
534
536
  .then(() => this.batcher.processKmsMessageEvent(event))
535
537
  .catch((reason) => {
536
538
  this.logger.error('kms: decrypt failed', reason.stack);
@@ -548,7 +550,8 @@ const KMS = WebexPlugin.extend({
548
550
  decryptKmsMessage(kmsMessage) {
549
551
  const res = new Response(kmsMessage);
550
552
 
551
- return contexts.get(this)
553
+ return contexts
554
+ .get(this)
552
555
  .then((context) => res.unwrap(context))
553
556
  .then(() => res.body);
554
557
  },
@@ -559,18 +562,17 @@ const KMS = WebexPlugin.extend({
559
562
  * @returns {Promise<boolean>}
560
563
  */
561
564
  _isECDHEMessage(kmsMessage) {
562
- return this._getKMSStaticPubKey()
563
- .then((kmsStaticPubKey) => {
564
- const fields = kmsMessage.split('.');
565
+ return this._getKMSStaticPubKey().then((kmsStaticPubKey) => {
566
+ const fields = kmsMessage.split('.');
565
567
 
566
- if (fields.length !== 3) {
567
- return false;
568
- }
568
+ if (fields.length !== 3) {
569
+ return false;
570
+ }
569
571
 
570
- const header = JSON.parse(jose.util.base64url.decode(fields[0]));
572
+ const header = JSON.parse(jose.util.base64url.decode(fields[0]));
571
573
 
572
- return header.kid === kmsStaticPubKey.kid;
573
- });
574
+ return header.kid === kmsStaticPubKey.kid;
575
+ });
574
576
  },
575
577
 
576
578
  /**
@@ -586,69 +588,80 @@ const KMS = WebexPlugin.extend({
586
588
 
587
589
  // Note: this should only happen when we're using the async kms batcher;
588
590
  // once we implement the sync batcher, this'll need to be smarter.
589
- return this.webex.internal.mercury.connect()
590
- .then(() => this.prepareRequest(payload, onBehalfOf))
591
- .then((req) => {
592
- req[TIMEOUT_SYMBOL] = timeout;
593
-
594
- return this.batcher.request(req);
595
- })
596
- // High complexity is due to attempt at test mode resiliency
597
- // eslint-disable-next-line complexity
598
- .catch((reason) => {
599
- if (process.env.NODE_ENV === 'test' && (reason.status === 403 || reason.statusCode === 403) && reason.message.match(/Failed to resolve authorization token in KmsMessage request for user/)) {
600
- this.logger.warn('kms: rerequested key due to test-mode kms auth failure');
591
+ return (
592
+ this.webex.internal.mercury
593
+ .connect()
594
+ .then(() => this.prepareRequest(payload, onBehalfOf))
595
+ .then((req) => {
596
+ req[TIMEOUT_SYMBOL] = timeout;
597
+
598
+ return this.batcher.request(req);
599
+ })
600
+ // High complexity is due to attempt at test mode resiliency
601
+ // eslint-disable-next-line complexity
602
+ .catch((reason) => {
603
+ if (
604
+ process.env.NODE_ENV === 'test' &&
605
+ (reason.status === 403 || reason.statusCode === 403) &&
606
+ reason.message.match(
607
+ /Failed to resolve authorization token in KmsMessage request for user/
608
+ )
609
+ ) {
610
+ this.logger.warn('kms: rerequested key due to test-mode kms auth failure');
611
+
612
+ return this.request(payload, {onBehalfOf});
613
+ }
601
614
 
602
- return this.request(payload, {onBehalfOf});
603
- }
615
+ // KMS Error. Notify the user
616
+ if (reason instanceof KMSError) {
617
+ this.webex.trigger('client:InvalidRequestError');
604
618
 
605
- // KMS Error. Notify the user
606
- if (reason instanceof KMSError) {
607
- this.webex.trigger('client:InvalidRequestError');
619
+ return Promise.reject(reason);
620
+ }
608
621
 
609
- return Promise.reject(reason);
610
- }
622
+ // Ideally, most or all of the code below would go in kms-batcher, but
623
+ // but batching needs at least one more round of refactoring for that to
624
+ // work.
625
+ if (!reason.statusCode && !reason.status) {
626
+ /* istanbul ignore else */
627
+ if (process.env.NODE_ENV !== 'production') {
628
+ /* istanbul ignore next: reason.stack vs stack difficult to control in test */
629
+ this.logger.info('kms: request error', reason.stack || reason);
630
+ }
611
631
 
612
- // Ideally, most or all of the code below would go in kms-batcher, but
613
- // but batching needs at least one more round of refactoring for that to
614
- // work.
615
- if (!reason.statusCode && !reason.status) {
616
- /* istanbul ignore else */
617
- if (process.env.NODE_ENV !== 'production') {
618
- /* istanbul ignore next: reason.stack vs stack difficult to control in test */
619
- this.logger.info('kms: request error', reason.stack || reason);
620
- }
632
+ consoleDebug(`timeout ${timeout}`);
633
+ timeout *= 2;
621
634
 
622
- consoleDebug(`timeout ${timeout}`);
623
- timeout *= 2;
635
+ if (timeout >= this.config.ecdhMaxTimeout) {
636
+ this.logger.info('kms: exceeded maximum KMS request retries');
624
637
 
625
- if (timeout >= this.config.ecdhMaxTimeout) {
626
- this.logger.info('kms: exceeded maximum KMS request retries');
638
+ return Promise.reject(reason);
639
+ }
627
640
 
628
- return Promise.reject(reason);
629
- }
641
+ // Peek ahead to make sure we don't reset the timeout if the next timeout
642
+ // will exceed the maximum timeout for renegotiating ECDH keys.
643
+ const nextTimeout = timeout * 2;
630
644
 
631
- // Peek ahead to make sure we don't reset the timeout if the next timeout
632
- // will exceed the maximum timeout for renegotiating ECDH keys.
633
- const nextTimeout = timeout * 2;
645
+ if (timeout >= this.config.kmsMaxTimeout && nextTimeout < this.config.ecdhMaxTimeout) {
646
+ this.logger.info(
647
+ 'kms: exceeded maximum KMS request retries; negotiating new ecdh key'
648
+ );
634
649
 
635
- if (timeout >= this.config.kmsMaxTimeout && nextTimeout < this.config.ecdhMaxTimeout) {
636
- this.logger.info('kms: exceeded maximum KMS request retries; negotiating new ecdh key');
650
+ /* istanbul ignore else */
651
+ if (process.env.NODE_ENV !== 'production') {
652
+ this.logger.info('kms: timeout/maxtimeout', timeout, this.config.kmsMaxTimeout);
653
+ }
637
654
 
638
- /* istanbul ignore else */
639
- if (process.env.NODE_ENV !== 'production') {
640
- this.logger.info('kms: timeout/maxtimeout', timeout, this.config.kmsMaxTimeout);
655
+ contexts.delete(this);
656
+ timeout = 0;
641
657
  }
642
658
 
643
- contexts.delete(this);
644
- timeout = 0;
659
+ return this.request(payload, {timeout, onBehalfOf});
645
660
  }
646
661
 
647
- return this.request(payload, {timeout, onBehalfOf});
648
- }
649
-
650
- return Promise.reject(reason);
651
- });
662
+ return Promise.reject(reason);
663
+ })
664
+ );
652
665
  },
653
666
 
654
667
  /**
@@ -656,8 +669,7 @@ const KMS = WebexPlugin.extend({
656
669
  * @returns {Promise<string>}
657
670
  */
658
671
  _getAuthorization() {
659
- return this.webex.credentials.getUserToken('spark:kms')
660
- .then((token) => token.access_token);
672
+ return this.webex.credentials.getUserToken('spark:kms').then((token) => token.access_token);
661
673
  },
662
674
 
663
675
  @oneFlight
@@ -679,15 +691,11 @@ const KMS = WebexPlugin.extend({
679
691
  });
680
692
  }
681
693
 
682
- return Promise.all([
683
- promise,
684
- this._getAuthorization()
685
- ])
686
- .then(([context, authorization]) => {
687
- context.clientInfo.credential.bearer = authorization;
694
+ return Promise.all([promise, this._getAuthorization()]).then(([context, authorization]) => {
695
+ context.clientInfo.credential.bearer = authorization;
688
696
 
689
- return context;
690
- });
697
+ return context;
698
+ });
691
699
  },
692
700
 
693
701
  /**
@@ -697,8 +705,7 @@ const KMS = WebexPlugin.extend({
697
705
  _getKMSCluster() {
698
706
  this.logger.info('kms: retrieving KMS cluster');
699
707
 
700
- return this._getKMSDetails()
701
- .then(({kmsCluster}) => kmsCluster);
708
+ return this._getKMSDetails().then(({kmsCluster}) => kmsCluster);
702
709
  },
703
710
 
704
711
  /**
@@ -710,10 +717,11 @@ const KMS = WebexPlugin.extend({
710
717
 
711
718
  if (!details) {
712
719
  this.logger.info('kms: fetching KMS details');
713
- details = this.webex.request({
714
- service: 'encryption',
715
- resource: `/kms/${this.webex.internal.device.userId}`
716
- })
720
+ details = this.webex
721
+ .request({
722
+ service: 'encryption',
723
+ resource: `/kms/${this.webex.internal.device.userId}`,
724
+ })
717
725
  .then((res) => {
718
726
  this.logger.info('kms: fetched KMS details');
719
727
  const {body} = res;
@@ -741,8 +749,7 @@ const KMS = WebexPlugin.extend({
741
749
  _getKMSStaticPubKey() {
742
750
  this.logger.info('kms: retrieving KMS static public key');
743
751
 
744
- return this._getKMSDetails()
745
- .then(({rsaPublicKey}) => rsaPublicKey);
752
+ return this._getKMSDetails().then(({rsaPublicKey}) => rsaPublicKey);
746
753
  },
747
754
 
748
755
  /**
@@ -755,19 +762,19 @@ const KMS = WebexPlugin.extend({
755
762
 
756
763
  return Promise.all([
757
764
  this._getKMSStaticPubKey().then(validateKMS(this.config.caroots)),
758
- this._getAuthorization()
765
+ this._getAuthorization(),
759
766
  ])
760
767
  .then(([kmsStaticPubKey, authorization]) => {
761
768
  context.clientInfo = {
762
769
  clientId: this.webex.internal.device.url,
763
770
  credential: {
764
771
  userId: this.webex.internal.device.userId,
765
- bearer: authorization
766
- }
772
+ bearer: authorization,
773
+ },
767
774
  };
768
775
 
769
776
  context.serverInfo = {
770
- key: kmsStaticPubKey
777
+ key: kmsStaticPubKey,
771
778
  };
772
779
 
773
780
  this.logger.info('kms: creating local ephemeral key');
@@ -786,7 +793,7 @@ const KMS = WebexPlugin.extend({
786
793
  return this.request({
787
794
  uri: `${cluster}/ecdhe`,
788
795
  method: 'create',
789
- jwk: localECDHKey.toJSON()
796
+ jwk: localECDHKey.toJSON(),
790
797
  });
791
798
  })
792
799
  .then((res) => {
@@ -828,14 +835,14 @@ const KMS = WebexPlugin.extend({
828
835
  credential: {
829
836
  userId: onBehalfOf,
830
837
  onBehalfOf, // Supports running onBehalfOf self. i.e. A CO which calls onBehalfOf with CO.id.
831
- bearer: originalContext.clientInfo.credential.bearer
832
- }
838
+ bearer: originalContext.clientInfo.credential.bearer,
839
+ },
833
840
  };
834
841
  context.serverInfo = originalContext.serverInfo;
835
842
  context.ephemeralKey = originalContext.ephemeralKey;
836
843
 
837
844
  return context;
838
- }
845
+ },
839
846
  });
840
847
 
841
848
  export default KMS;