@webex/internal-plugin-conversation 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 (44) hide show
  1. package/README.md +1 -3
  2. package/dist/activities.js +8 -69
  3. package/dist/activities.js.map +1 -1
  4. package/dist/activity-thread-ordering.js +19 -79
  5. package/dist/activity-thread-ordering.js.map +1 -1
  6. package/dist/config.js +1 -7
  7. package/dist/config.js.map +1 -1
  8. package/dist/constants.js +4 -5
  9. package/dist/constants.js.map +1 -1
  10. package/dist/conversation.js +791 -1202
  11. package/dist/conversation.js.map +1 -1
  12. package/dist/convo-error.js +0 -23
  13. package/dist/convo-error.js.map +1 -1
  14. package/dist/decryption-transforms.js +35 -98
  15. package/dist/decryption-transforms.js.map +1 -1
  16. package/dist/encryption-transforms.js +17 -49
  17. package/dist/encryption-transforms.js.map +1 -1
  18. package/dist/index.js +7 -50
  19. package/dist/index.js.map +1 -1
  20. package/dist/share-activity.js +40 -106
  21. package/dist/share-activity.js.map +1 -1
  22. package/dist/to-array.js +9 -11
  23. package/dist/to-array.js.map +1 -1
  24. package/package.json +15 -15
  25. package/src/activities.js +10 -7
  26. package/src/activity-thread-ordering.js +27 -30
  27. package/src/activity-threading.md +68 -49
  28. package/src/config.js +5 -5
  29. package/src/conversation.js +621 -591
  30. package/src/decryption-transforms.js +103 -62
  31. package/src/encryption-transforms.js +111 -83
  32. package/src/index.js +82 -66
  33. package/src/share-activity.js +64 -55
  34. package/src/to-array.js +2 -2
  35. package/test/integration/spec/create.js +186 -121
  36. package/test/integration/spec/encryption.js +249 -186
  37. package/test/integration/spec/get.js +764 -514
  38. package/test/integration/spec/mercury.js +37 -27
  39. package/test/integration/spec/share.js +292 -229
  40. package/test/integration/spec/verbs.js +628 -441
  41. package/test/unit/spec/conversation.js +265 -163
  42. package/test/unit/spec/decrypt-transforms.js +112 -131
  43. package/test/unit/spec/encryption-transforms.js +47 -18
  44. package/test/unit/spec/share-activity.js +37 -40
@@ -6,11 +6,12 @@ import {camelCase, capitalize, curry} from 'lodash';
6
6
 
7
7
  import toArray from './to-array';
8
8
 
9
- const decryptTextProp = curry((name, ctx, key, object) => ctx.transform('decryptTextProp', name, key, object));
9
+ const decryptTextProp = curry((name, ctx, key, object) =>
10
+ ctx.transform('decryptTextProp', name, key, object)
11
+ );
10
12
 
11
13
  // eslint-disable-next-line import/prefer-default-export
12
14
  export const transforms = toArray('inbound', {
13
-
14
15
  /**
15
16
  * This function is used recursively to decrypt various properties on conversations, activities, etc
16
17
  * @param {Object} ctx An object containing a webex instance and a transform
@@ -61,12 +62,15 @@ export const transforms = toArray('inbound', {
61
62
  }
62
63
  const {decryptionFailureMessage} = ctx.webex.internal.conversation.config;
63
64
 
64
- return ctx.transform('decryptPropCardItem', 0, key, [object.inputs])
65
+ return ctx
66
+ .transform('decryptPropCardItem', 0, key, [object.inputs])
65
67
  .then((inputs) => {
66
68
  object.inputs = JSON.parse(inputs[0]); // eslint-disable-line no-param-reassign
67
69
  })
68
70
  .catch((reason) => {
69
- ctx.webex.logger.warn(`plugin-conversation: failed to decrypt attachmentAction.inputs: ${reason}`);
71
+ ctx.webex.logger.warn(
72
+ `plugin-conversation: failed to decrypt attachmentAction.inputs: ${reason}`
73
+ );
70
74
  object.inputs = decryptionFailureMessage; // eslint-disable-line no-param-reassign
71
75
 
72
76
  return Promise.resolve(decryptionFailureMessage);
@@ -87,7 +91,9 @@ export const transforms = toArray('inbound', {
87
91
  return Promise.resolve();
88
92
  }
89
93
 
90
- return Promise.all(object.reactions.map((reaction) => ctx.transform('decryptPropDisplayName', key, reaction)));
94
+ return Promise.all(
95
+ object.reactions.map((reaction) => ctx.transform('decryptPropDisplayName', key, reaction))
96
+ );
91
97
  },
92
98
 
93
99
  /**
@@ -106,7 +112,9 @@ export const transforms = toArray('inbound', {
106
112
  return Promise.resolve();
107
113
  }
108
114
 
109
- return Promise.all(object.reactions.map((reaction) => ctx.transform('decryptPropDisplayName', key, reaction)));
115
+ return Promise.all(
116
+ object.reactions.map((reaction) => ctx.transform('decryptPropDisplayName', key, reaction))
117
+ );
110
118
  },
111
119
 
112
120
  /**
@@ -123,28 +131,30 @@ export const transforms = toArray('inbound', {
123
131
  },
124
132
 
125
133
  /**
126
- * Decrypt an individual threadObject
127
- * @param {Object} ctx An object containing a webex instance and a transform
128
- * @param {Object} threadObject An instance of a Webex threadObject (the objects returned by the /conversation/api/v1/threads api)
129
- * @returns {Promise} Returns a ctx.transform promise
130
- */
134
+ * Decrypt an individual threadObject
135
+ * @param {Object} ctx An object containing a webex instance and a transform
136
+ * @param {Object} threadObject An instance of a Webex threadObject (the objects returned by the /conversation/api/v1/threads api)
137
+ * @returns {Promise} Returns a ctx.transform promise
138
+ */
131
139
  decryptThread(ctx, threadObject) {
132
140
  let promises = [];
133
141
 
134
142
  if (threadObject.childActivities && Array.isArray(threadObject.childActivities)) {
135
- promises = threadObject.childActivities.map((child) => ctx.transform('decryptObject', null, child));
143
+ promises = threadObject.childActivities.map((child) =>
144
+ ctx.transform('decryptObject', null, child)
145
+ );
136
146
  }
137
147
 
138
148
  return Promise.all(promises);
139
149
  },
140
150
 
141
151
  /**
142
- * Decrypt an individual meeting container activity
143
- * @param {Object} ctx An object containing a webex instance and a transform
144
- * @param {object} key KMS encryption key url
145
- * @param {Object} meetingContainerActivity An instance of a Webex meeting container activity
146
- * @returns {Promise} Returns a ctx.transform promise
147
- */
152
+ * Decrypt an individual meeting container activity
153
+ * @param {Object} ctx An object containing a webex instance and a transform
154
+ * @param {object} key KMS encryption key url
155
+ * @param {Object} meetingContainerActivity An instance of a Webex meeting container activity
156
+ * @returns {Promise} Returns a ctx.transform promise
157
+ */
148
158
  decryptMeetingcontainer(ctx, key, meetingContainerActivity) {
149
159
  const promises = [];
150
160
 
@@ -155,10 +165,14 @@ export const transforms = toArray('inbound', {
155
165
  }
156
166
 
157
167
  if (meetingContainerActivity.extensions) {
158
- const itemsToDecrypt = meetingContainerActivity.extensions.items.filter((item) => item.data.objectType === 'recording');
168
+ const itemsToDecrypt = meetingContainerActivity.extensions.items.filter(
169
+ (item) => item.data.objectType === 'recording'
170
+ );
159
171
 
160
172
  itemsToDecrypt.forEach((itemToDecrypt) => {
161
- promises.push(ctx.transform('decryptPropTopic', itemToDecrypt.encryptionKeyUrl, itemToDecrypt.data));
173
+ promises.push(
174
+ ctx.transform('decryptPropTopic', itemToDecrypt.encryptionKeyUrl, itemToDecrypt.data)
175
+ );
162
176
  });
163
177
  }
164
178
 
@@ -178,22 +192,33 @@ export const transforms = toArray('inbound', {
178
192
  const promises = [];
179
193
 
180
194
  if (conversation.activities.items) {
181
- promises.push(Promise.all(conversation.activities.items.map((item) => ctx.transform('decryptObject', null, item))));
195
+ promises.push(
196
+ Promise.all(
197
+ conversation.activities.items.map((item) => ctx.transform('decryptObject', null, item))
198
+ )
199
+ );
182
200
  }
183
201
 
184
202
  const usableKey = conversation.encryptionKeyUrl || key;
185
203
  const {decryptionFailureMessage} = ctx.webex.internal.conversation.config;
186
204
 
187
205
  if (usableKey) {
188
- promises.push(ctx.transform('decryptPropDisplayName', usableKey, conversation)
189
- .catch((error) => {
190
- ctx.webex.logger.warn('plugin-conversation: failed to decrypt display name of ', conversation.url, error);
206
+ promises.push(
207
+ ctx.transform('decryptPropDisplayName', usableKey, conversation).catch((error) => {
208
+ ctx.webex.logger.warn(
209
+ 'plugin-conversation: failed to decrypt display name of ',
210
+ conversation.url,
211
+ error
212
+ );
191
213
  Promise.resolve(decryptionFailureMessage);
192
- }));
214
+ })
215
+ );
193
216
  promises.push(ctx.transform('decryptPropContent', usableKey, conversation));
194
217
  }
195
218
  if (conversation.avatarEncryptionKeyUrl) {
196
- promises.push(ctx.transform('decryptObject', conversation.avatarEncryptionKeyUrl, conversation.avatar));
219
+ promises.push(
220
+ ctx.transform('decryptObject', conversation.avatarEncryptionKeyUrl, conversation.avatar)
221
+ );
197
222
  }
198
223
  // TODO (holsted 04/06/19): This was deprecated in favor of .previousValue below. I wanted to remove this entirely
199
224
  // but I wasn't sure if some open source use cases may be reading from cached conversations or not so leaving it for now.
@@ -226,7 +251,9 @@ export const transforms = toArray('inbound', {
226
251
  // iterate and recursively decrypt over children objects
227
252
 
228
253
  if (activity.children && Array.isArray(activity.children)) {
229
- promises = activity.children.map((child) => ctx.transform('decryptObject', keyUrl, child.activity));
254
+ promises = activity.children.map((child) =>
255
+ ctx.transform('decryptObject', keyUrl, child.activity)
256
+ );
230
257
  }
231
258
 
232
259
  promises.push(ctx.transform('decryptObject', keyUrl, activity.object));
@@ -247,20 +274,22 @@ export const transforms = toArray('inbound', {
247
274
  },
248
275
 
249
276
  /**
250
- * Decrypts a comment...
251
- * @param {Object} ctx An object containing a webex instance and transform prop
252
- * @param {String} key KMS key
253
- * @param {Object} comment A comment object with a displayName and content (encrypted)
254
- * @returns {Promise} Returns the results of Promise.all on two transforms
255
- */
277
+ * Decrypts a comment...
278
+ * @param {Object} ctx An object containing a webex instance and transform prop
279
+ * @param {String} key KMS key
280
+ * @param {Object} comment A comment object with a displayName and content (encrypted)
281
+ * @returns {Promise} Returns the results of Promise.all on two transforms
282
+ */
256
283
  decryptComment(ctx, key, comment) {
257
284
  const promises = [
258
285
  ctx.transform('decryptPropDisplayName', key, comment),
259
- ctx.transform('decryptPropContent', key, comment)
286
+ ctx.transform('decryptPropContent', key, comment),
260
287
  ];
261
288
 
262
289
  if (comment.cards && Array.isArray(comment.cards)) {
263
- comment.cards.map((item, index) => promises.push(ctx.transform('decryptPropCardItem', index, key, comment.cards)));
290
+ comment.cards.map((item, index) =>
291
+ promises.push(ctx.transform('decryptPropCardItem', index, key, comment.cards))
292
+ );
264
293
  }
265
294
 
266
295
  return Promise.all(promises);
@@ -300,7 +329,9 @@ export const transforms = toArray('inbound', {
300
329
  promises.push(ctx.transform('decryptComment', key, content));
301
330
 
302
331
  if (content.links && content.links.items && Array.isArray(content.links.items)) {
303
- content.links.items.forEach((item) => promises.push(ctx.transform('decryptObject', key, item)));
332
+ content.links.items.forEach((item) =>
333
+ promises.push(ctx.transform('decryptObject', key, item))
334
+ );
304
335
  }
305
336
 
306
337
  return Promise.all(promises);
@@ -334,9 +365,7 @@ export const transforms = toArray('inbound', {
334
365
  * @returns {Promise} Returns the result of Promise.all
335
366
  */
336
367
  decryptEvent(ctx, key, event) {
337
- const promises = [
338
- ctx.transform('decryptPropDisplayName', key, event)
339
- ];
368
+ const promises = [ctx.transform('decryptPropDisplayName', key, event)];
340
369
 
341
370
  if (event.location && event.location.split('.').length === 5) {
342
371
  promises.push(ctx.transform('decryptPropLocation', key, event));
@@ -359,11 +388,14 @@ export const transforms = toArray('inbound', {
359
388
  }
360
389
 
361
390
  return Promise.all([
362
- file.transcodedCollection && Promise.all(file.transcodedCollection.items.map((item) => ctx.transform('decryptObject', key, item))),
391
+ file.transcodedCollection &&
392
+ Promise.all(
393
+ file.transcodedCollection.items.map((item) => ctx.transform('decryptObject', key, item))
394
+ ),
363
395
  ctx.transform('decryptPropScr', key, file),
364
396
  ctx.transform('decryptPropDisplayName', key, file),
365
397
  ctx.transform('decryptPropContent', key, file),
366
- file.image && ctx.transform('decryptPropScr', key, file.image)
398
+ file.image && ctx.transform('decryptPropScr', key, file.image),
367
399
  ]);
368
400
  },
369
401
 
@@ -377,7 +409,7 @@ export const transforms = toArray('inbound', {
377
409
  decryptLink(ctx, key, link) {
378
410
  return Promise.all([
379
411
  ctx.transform('decryptPropSslr', key, link),
380
- ctx.transform('decryptPropDisplayName', key, link)
412
+ ctx.transform('decryptPropDisplayName', key, link),
381
413
  ]);
382
414
  },
383
415
 
@@ -389,7 +421,9 @@ export const transforms = toArray('inbound', {
389
421
  * @returns {Promise} Returns the result of Promise.all
390
422
  */
391
423
  decryptTranscodedContent(ctx, key, transcodedContent) {
392
- return Promise.all(transcodedContent.files.items.map((item) => ctx.transform('decryptFile', key, item)));
424
+ return Promise.all(
425
+ transcodedContent.files.items.map((item) => ctx.transform('decryptFile', key, item))
426
+ );
393
427
  },
394
428
 
395
429
  /**
@@ -417,7 +451,8 @@ export const transforms = toArray('inbound', {
417
451
  }
418
452
  const {decryptionFailureMessage} = ctx.webex.internal.conversation.config;
419
453
 
420
- return ctx.webex.internal.encryption.decryptText(key, object[name])
454
+ return ctx.webex.internal.encryption
455
+ .decryptText(key, object[name])
421
456
  .then((plaintext) => {
422
457
  if (ctx.webex.config.conversation.keepEncryptedProperties) {
423
458
  const encryptedPropName = camelCase(`encrypted_${name}`);
@@ -436,20 +471,28 @@ export const transforms = toArray('inbound', {
436
471
  },
437
472
 
438
473
  /**
439
- * Decrypting an element in an Array.
440
- * @param {Object} ctx An object containing a webex instance and transform prop
441
- * @param {Integer} index Property of an object to be decrypted
442
- * @param {String} key KMS key
443
- * @param {Array} array An array of Strings to be decrypted
444
- * @returns {Promise} Returns a lonely Promise
445
- */
474
+ * Decrypting an element in an Array.
475
+ * @param {Object} ctx An object containing a webex instance and transform prop
476
+ * @param {Integer} index Property of an object to be decrypted
477
+ * @param {String} key KMS key
478
+ * @param {Array} array An array of Strings to be decrypted
479
+ * @returns {Promise} Returns a lonely Promise
480
+ */
446
481
  decryptPropCardItem(ctx, index, key, array) {
447
- if (!Number.isInteger(index) || !array || !Array.isArray(array) || index < 0 || index >= array.length || !(array[index] instanceof String || typeof array[index] === 'string')) {
482
+ if (
483
+ !Number.isInteger(index) ||
484
+ !array ||
485
+ !Array.isArray(array) ||
486
+ index < 0 ||
487
+ index >= array.length ||
488
+ !(array[index] instanceof String || typeof array[index] === 'string')
489
+ ) {
448
490
  return Promise.resolve();
449
491
  }
450
492
  const {decryptionFailureMessage} = ctx.webex.internal.conversation.config;
451
493
 
452
- return ctx.webex.internal.encryption.decryptText(key, array[index])
494
+ return ctx.webex.internal.encryption
495
+ .decryptText(key, array[index])
453
496
  .then((plaintext) => {
454
497
  array[index] = plaintext; // eslint-disable-line no-param-reassign
455
498
  })
@@ -468,10 +511,9 @@ export const transforms = toArray('inbound', {
468
511
  * @returns {Promise} Returns a promise
469
512
  */
470
513
  decryptPropScr(ctx, key, object) {
471
- return ctx.webex.internal.encryption.decryptScr(key, object.scr)
472
- .then((scr) => {
473
- object.scr = scr; // eslint-disable-line no-param-reassign
474
- });
514
+ return ctx.webex.internal.encryption.decryptScr(key, object.scr).then((scr) => {
515
+ object.scr = scr; // eslint-disable-line no-param-reassign
516
+ });
475
517
  },
476
518
 
477
519
  /**
@@ -482,10 +524,9 @@ export const transforms = toArray('inbound', {
482
524
  * @returns {Promise} Returns a promise
483
525
  */
484
526
  decryptPropSslr(ctx, key, object) {
485
- return ctx.webex.internal.encryption.decryptScr(key, object.sslr)
486
- .then((sslr) => {
487
- object.sslr = sslr; // eslint-disable-line no-param-reassign
488
- });
527
+ return ctx.webex.internal.encryption.decryptScr(key, object.sslr).then((sslr) => {
528
+ object.sslr = sslr; // eslint-disable-line no-param-reassign
529
+ });
489
530
  },
490
531
 
491
532
  decryptPropDisplayName: decryptTextProp('displayName'),
@@ -496,5 +537,5 @@ export const transforms = toArray('inbound', {
496
537
 
497
538
  decryptPropLocation: decryptTextProp('location'),
498
539
 
499
- decryptPropTopic: decryptTextProp('topic')
540
+ decryptPropTopic: decryptTextProp('topic'),
500
541
  });
@@ -2,21 +2,19 @@
2
2
  * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
3
  */
4
4
 
5
- import {
6
- capitalize,
7
- curry,
8
- get,
9
- has,
10
- isArray
11
- } from 'lodash';
5
+ import {capitalize, curry, get, has, isArray} from 'lodash';
12
6
 
13
7
  import toArray from './to-array';
14
8
 
15
9
  const KEY = Symbol('KEY');
16
10
 
17
- const encryptTextProp = curry((name, ctx, key, object) => ctx.transform('encryptTextProp', name, key, object));
11
+ const encryptTextProp = curry((name, ctx, key, object) =>
12
+ ctx.transform('encryptTextProp', name, key, object)
13
+ );
18
14
 
19
- const encryptJsonProp = curry((name, ctx, key, object) => ctx.transform('encryptJsonProp', name, key, object));
15
+ const encryptJsonProp = curry((name, ctx, key, object) =>
16
+ ctx.transform('encryptJsonProp', name, key, object)
17
+ );
20
18
 
21
19
  // eslint-disable-next-line import/prefer-default-export
22
20
  export const transforms = toArray('outbound', {
@@ -50,50 +48,63 @@ export const transforms = toArray('outbound', {
50
48
  return Promise.resolve();
51
49
  }
52
50
 
53
- return Promise.resolve(key || ctx.webex.internal.encryption.kms.createUnboundKeys({count: 1}))
54
- .then((keys) => {
55
- const k = isArray(keys) ? keys[0] : keys;
51
+ return Promise.resolve(
52
+ key || ctx.webex.internal.encryption.kms.createUnboundKeys({count: 1})
53
+ ).then((keys) => {
54
+ const k = isArray(keys) ? keys[0] : keys;
56
55
 
57
- if (has(conversation, 'kmsMessage.keyUris') && !conversation.kmsMessage.keyUris.includes(k.uri)) {
58
- conversation.kmsMessage.keyUris.push(k.uri);
59
- }
56
+ if (
57
+ has(conversation, 'kmsMessage.keyUris') &&
58
+ !conversation.kmsMessage.keyUris.includes(k.uri)
59
+ ) {
60
+ conversation.kmsMessage.keyUris.push(k.uri);
61
+ }
60
62
 
61
- return Promise.all([
62
- // too many implicit returns on the same line is difficult to interpret
63
- // eslint-disable-next-line arrow-body-style
64
- has(conversation, 'activities.items') && conversation.activities.items.reduce((p, activity) => {
63
+ return Promise.all([
64
+ // too many implicit returns on the same line is difficult to interpret
65
+ // eslint-disable-next-line arrow-body-style
66
+ has(conversation, 'activities.items') &&
67
+ conversation.activities.items.reduce((p, activity) => {
65
68
  // eslint-disable-next-line max-nested-callbacks
66
69
  return p.then(() => ctx.transform('encryptObject', k, activity));
67
70
  }, Promise.resolve()),
68
- ctx.transform('encryptPropDisplayName', k, conversation)
69
- ])
70
- .then(() => {
71
- conversation.encryptionKeyUrl = k.uri || k;
72
- // we only want to set the defaultActivityEncryptionKeyUrl if we've
73
- // bound a new key
74
- if (!key) {
75
- conversation.defaultActivityEncryptionKeyUrl = conversation.defaultActivityEncryptionKeyUrl || k.uri || k;
76
- }
77
- });
71
+ ctx.transform('encryptPropDisplayName', k, conversation),
72
+ ]).then(() => {
73
+ conversation.encryptionKeyUrl = k.uri || k;
74
+ // we only want to set the defaultActivityEncryptionKeyUrl if we've
75
+ // bound a new key
76
+ if (!key) {
77
+ conversation.defaultActivityEncryptionKeyUrl =
78
+ conversation.defaultActivityEncryptionKeyUrl || k.uri || k;
79
+ }
78
80
  });
81
+ });
79
82
  },
80
83
 
81
84
  encryptActivity(ctx, key, activity) {
85
+ // Meeting Container policy update requests do not need to be encrypted.
86
+ if (
87
+ activity?.target?.objectType === 'meetingContainer' &&
88
+ activity?.object?.objectType === 'policies'
89
+ ) {
90
+ return Promise.resolve();
91
+ }
92
+
82
93
  // Activity is already encrypted
83
94
  if (activity.encryptionKeyUrl || activity.object?.created === 'True') {
84
95
  return Promise.resolve();
85
96
  }
86
97
 
87
- return ctx.transform(`encrypt${capitalize(activity.verb)}Activity`, key, activity)
88
- .then(() => {
89
- key = key || activity[KEY];
98
+ return ctx.transform(`encrypt${capitalize(activity.verb)}Activity`, key, activity).then(() => {
99
+ key = key || activity[KEY];
90
100
 
91
- return ctx.transform('prepareActivityKmsMessage', key, activity);
92
- });
101
+ return ctx.transform('prepareActivityKmsMessage', key, activity);
102
+ });
93
103
  },
94
104
 
95
105
  encryptVerbActivity(ctx, key, activity) {
96
- return ctx.transform('maybeEncryptTarget', key, activity)
106
+ return ctx
107
+ .transform('maybeEncryptTarget', key, activity)
97
108
  .then(() => {
98
109
  key = key || activity[KEY];
99
110
  })
@@ -107,7 +118,8 @@ export const transforms = toArray('outbound', {
107
118
  return Promise.resolve();
108
119
  }
109
120
 
110
- if (has(activity, 'target.defaultActivityEncryptionKeyUrl') &&
121
+ if (
122
+ has(activity, 'target.defaultActivityEncryptionKeyUrl') &&
111
123
  activity.target.defaultActivityEncryptionKeyUrl &&
112
124
  has(activity, 'target.kmsResourceObjectUrl')
113
125
  ) {
@@ -119,34 +131,42 @@ export const transforms = toArray('outbound', {
119
131
  const conversationUrl = activity.target && activity.target.url;
120
132
 
121
133
  if (!conversationUrl) {
122
- return Promise.reject(new Error('Cannot determine encryption key for activity\'s conversation; no key url or conversation url provided'));
134
+ return Promise.reject(
135
+ new Error(
136
+ "Cannot determine encryption key for activity's conversation; no key url or conversation url provided"
137
+ )
138
+ );
123
139
  }
124
140
 
125
- return ctx.webex.internal.conversation.get({url: conversationUrl})
126
- .then((conversation) => {
127
- if (!conversation.defaultActivityEncryptionKeyUrl) {
128
- return ctx.webex.internal.conversation.updateKey(conversation)
129
- .then((updateKeyActivity) => {
130
- if (updateKeyActivity.kmsMessage.resource) {
131
- activity.target.kmsResourceObjectUrl = updateKeyActivity.kmsMessage.resource.uri;
132
- }
133
- activity[KEY] = activity.target.defaultActivityEncryptionKeyUrl = updateKeyActivity.object.defaultActivityEncryptionKeyUrl;
134
- });
135
- }
141
+ return ctx.webex.internal.conversation.get({url: conversationUrl}).then((conversation) => {
142
+ if (!conversation.defaultActivityEncryptionKeyUrl) {
143
+ return ctx.webex.internal.conversation.updateKey(conversation).then((updateKeyActivity) => {
144
+ if (updateKeyActivity.kmsMessage.resource) {
145
+ activity.target.kmsResourceObjectUrl = updateKeyActivity.kmsMessage.resource.uri;
146
+ }
147
+ activity[KEY] = activity.target.defaultActivityEncryptionKeyUrl =
148
+ updateKeyActivity.object.defaultActivityEncryptionKeyUrl;
149
+ });
150
+ }
136
151
 
137
- if (!activity.target.defaultActivityEncryptionKeyUrl) {
138
- ctx.webex.logger.warn('plugin-conversation: downloaded conversation to determine its defaultActivityEncryptionKeyUrl; make sure to pass all encryption related properties when calling Webex.conversation methods.');
139
- }
152
+ if (!activity.target.defaultActivityEncryptionKeyUrl) {
153
+ ctx.webex.logger.warn(
154
+ 'plugin-conversation: downloaded conversation to determine its defaultActivityEncryptionKeyUrl; make sure to pass all encryption related properties when calling Webex.conversation methods.'
155
+ );
156
+ }
140
157
 
141
- if (!activity.target.kmsResourceObjectUrl) {
142
- ctx.webex.logger.warn('plugin-conversation: downloaded conversation to determine its kmsResourceObjectUrl; make sure to pass all encryption related properties when calling Webex.conversation methods.');
143
- }
158
+ if (!activity.target.kmsResourceObjectUrl) {
159
+ ctx.webex.logger.warn(
160
+ 'plugin-conversation: downloaded conversation to determine its kmsResourceObjectUrl; make sure to pass all encryption related properties when calling Webex.conversation methods.'
161
+ );
162
+ }
144
163
 
145
- activity[KEY] = activity.target.defaultActivityEncryptionKeyUrl = conversation.defaultActivityEncryptionKeyUrl;
146
- activity.target.kmsResourceObjectUrl = conversation.kmsResourceObjectUrl;
164
+ activity[KEY] = activity.target.defaultActivityEncryptionKeyUrl =
165
+ conversation.defaultActivityEncryptionKeyUrl;
166
+ activity.target.kmsResourceObjectUrl = conversation.kmsResourceObjectUrl;
147
167
 
148
- return Promise.resolve();
149
- });
168
+ return Promise.resolve();
169
+ });
150
170
  },
151
171
 
152
172
  prepareActivityKmsMessage(ctx, key, activity) {
@@ -155,11 +175,19 @@ export const transforms = toArray('outbound', {
155
175
  key = get(activity, 'target.defaultActivityEncryptionKeyUrl');
156
176
  }
157
177
 
158
- if (!key && activity.verb === 'updateKey' && has(activity, 'object.defaultActivityEncryptionKeyUrl')) {
178
+ if (
179
+ !key &&
180
+ activity.verb === 'updateKey' &&
181
+ has(activity, 'object.defaultActivityEncryptionKeyUrl')
182
+ ) {
159
183
  key = get(activity, 'object.defaultActivityEncryptionKeyUrl');
160
184
  }
161
185
 
162
- if (!key && activity.verb === 'leave' && has(activity, 'target.defaultActivityEncryptionKeyUrl')) {
186
+ if (
187
+ !key &&
188
+ activity.verb === 'leave' &&
189
+ has(activity, 'target.defaultActivityEncryptionKeyUrl')
190
+ ) {
163
191
  key = get(activity, 'target.defaultActivityEncryptionKeyUrl');
164
192
  }
165
193
 
@@ -190,12 +218,11 @@ export const transforms = toArray('outbound', {
190
218
  encryptVerbActivityWithKey: {
191
219
  direction: 'outbound',
192
220
  fn(ctx, key, activity) {
193
- return ctx.transform('encryptVerbActivity', key, activity)
194
- .then(() => {
195
- key = key || activity[KEY];
196
- activity.encryptionKeyUrl = key.uri || key;
197
- });
198
- }
221
+ return ctx.transform('encryptVerbActivity', key, activity).then(() => {
222
+ key = key || activity[KEY];
223
+ activity.encryptionKeyUrl = key.uri || key;
224
+ });
225
+ },
199
226
  },
200
227
 
201
228
  encryptAddActivity: {
@@ -206,48 +233,48 @@ export const transforms = toArray('outbound', {
206
233
  }
207
234
 
208
235
  return ctx.transform('encryptVerbActivity', key, activity);
209
- }
236
+ },
210
237
  },
211
238
 
212
239
  encryptAssignActivity: {
213
240
  direction: 'outbound',
214
- alias: 'encryptVerbActivityWithKey'
241
+ alias: 'encryptVerbActivityWithKey',
215
242
  },
216
243
 
217
244
  encryptCreateActivity: {
218
245
  direction: 'outbound',
219
- alias: 'encryptVerbActivity'
246
+ alias: 'encryptVerbActivity',
220
247
  },
221
248
 
222
249
  encryptPostActivity: {
223
250
  direction: 'outbound',
224
- alias: 'encryptVerbActivityWithKey'
251
+ alias: 'encryptVerbActivityWithKey',
225
252
  },
226
253
 
227
254
  encryptShareActivity: {
228
255
  direction: 'outbound',
229
- alias: 'encryptVerbActivityWithKey'
256
+ alias: 'encryptVerbActivityWithKey',
230
257
  },
231
258
 
232
259
  encryptCardactionActivity: {
233
260
  direction: 'outbound',
234
- alias: 'encryptVerbActivityWithKey'
261
+ alias: 'encryptVerbActivityWithKey',
235
262
  },
236
263
 
237
264
  encryptUpdateActivity: {
238
265
  direction: 'outbound',
239
- alias: 'encryptVerbActivityWithKey'
266
+ alias: 'encryptVerbActivityWithKey',
240
267
  },
241
268
 
242
269
  encryptUpdateKeyActivity: {
243
270
  direction: 'outbound',
244
- alias: 'encryptVerbActivity'
271
+ alias: 'encryptVerbActivity',
245
272
  },
246
273
 
247
274
  encryptComment(ctx, key, comment) {
248
275
  return Promise.all([
249
276
  ctx.transform('encryptPropDisplayName', key, comment),
250
- ctx.transform('encryptPropContent', key, comment)
277
+ ctx.transform('encryptPropContent', key, comment),
251
278
  ]);
252
279
  },
253
280
 
@@ -269,7 +296,7 @@ export const transforms = toArray('outbound', {
269
296
  ctx.transform('encryptPropScr', key, file),
270
297
  ctx.transform('encryptPropDisplayName', key, file),
271
298
  ctx.transform('encryptPropContent', key, file),
272
- file.image && ctx.transform('encryptPropScr', key, file.image)
299
+ file.image && ctx.transform('encryptPropScr', key, file.image),
273
300
  ]);
274
301
  },
275
302
 
@@ -295,10 +322,9 @@ export const transforms = toArray('outbound', {
295
322
  return Promise.resolve();
296
323
  }
297
324
 
298
- return ctx.webex.internal.encryption.encryptScr(key, object.scr)
299
- .then((scr) => {
300
- object.scr = scr;
301
- });
325
+ return ctx.webex.internal.encryption.encryptScr(key, object.scr).then((scr) => {
326
+ object.scr = scr;
327
+ });
302
328
  },
303
329
 
304
330
  encryptJsonProp(ctx, name, key, object) {
@@ -306,7 +332,8 @@ export const transforms = toArray('outbound', {
306
332
  return Promise.resolve();
307
333
  }
308
334
 
309
- return ctx.webex.internal.encryption.encryptText(key.uri || key, JSON.stringify(object[name]))
335
+ return ctx.webex.internal.encryption
336
+ .encryptText(key.uri || key, JSON.stringify(object[name]))
310
337
  .then((ciphertext) => {
311
338
  object[name] = ciphertext;
312
339
  });
@@ -317,9 +344,10 @@ export const transforms = toArray('outbound', {
317
344
  return Promise.resolve();
318
345
  }
319
346
 
320
- return ctx.webex.internal.encryption.encryptText(key.uri || key, object[name])
347
+ return ctx.webex.internal.encryption
348
+ .encryptText(key.uri || key, object[name])
321
349
  .then((ciphertext) => {
322
350
  object[name] = ciphertext;
323
351
  });
324
- }
352
+ },
325
353
  });