@webex/internal-plugin-conversation 3.0.0-beta.9 → 3.0.0-bnr.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -3
- package/dist/activities.js +8 -69
- package/dist/activities.js.map +1 -1
- package/dist/activity-thread-ordering.js +19 -79
- package/dist/activity-thread-ordering.js.map +1 -1
- package/dist/config.js +1 -7
- package/dist/config.js.map +1 -1
- package/dist/constants.js +4 -5
- package/dist/constants.js.map +1 -1
- package/dist/conversation.js +790 -1199
- package/dist/conversation.js.map +1 -1
- package/dist/convo-error.js +0 -23
- package/dist/convo-error.js.map +1 -1
- package/dist/decryption-transforms.js +35 -98
- package/dist/decryption-transforms.js.map +1 -1
- package/dist/encryption-transforms.js +11 -48
- package/dist/encryption-transforms.js.map +1 -1
- package/dist/index.js +7 -50
- package/dist/index.js.map +1 -1
- package/dist/internal-plugin-conversation.d.ts +21 -0
- package/dist/share-activity.js +40 -106
- package/dist/share-activity.js.map +1 -1
- package/dist/to-array.js +9 -11
- package/dist/to-array.js.map +1 -1
- package/dist/tsdoc-metadata.json +11 -0
- package/dist/types/activities.d.ts +32 -0
- package/dist/types/activity-thread-ordering.d.ts +18 -0
- package/dist/types/config.d.ts +19 -0
- package/dist/types/constants.d.ts +5 -0
- package/dist/types/conversation.d.ts +2 -0
- package/dist/types/convo-error.d.ts +10 -0
- package/dist/types/decryption-transforms.d.ts +1 -0
- package/dist/types/encryption-transforms.d.ts +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/share-activity.d.ts +7 -0
- package/dist/types/to-array.d.ts +9 -0
- package/package.json +15 -15
- package/src/activities.js +10 -7
- package/src/activity-thread-ordering.js +27 -30
- package/src/activity-threading.md +68 -49
- package/src/config.js +5 -5
- package/src/conversation.js +621 -589
- package/src/decryption-transforms.js +103 -62
- package/src/encryption-transforms.js +103 -83
- package/src/index.js +82 -66
- package/src/share-activity.js +64 -55
- package/src/to-array.js +2 -2
- package/test/integration/spec/create.js +184 -118
- package/test/integration/spec/encryption.js +250 -186
- package/test/integration/spec/get.js +761 -513
- package/test/integration/spec/mercury.js +37 -27
- package/test/integration/spec/share.js +292 -229
- package/test/integration/spec/verbs.js +628 -441
- package/test/unit/spec/conversation.js +265 -163
- package/test/unit/spec/decrypt-transforms.js +112 -131
- package/test/unit/spec/encryption-transforms.js +24 -18
- 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) =>
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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) =>
|
|
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
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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(
|
|
168
|
+
const itemsToDecrypt = meetingContainerActivity.extensions.items.filter(
|
|
169
|
+
(item) => item.data.objectType === 'recording'
|
|
170
|
+
);
|
|
159
171
|
|
|
160
172
|
itemsToDecrypt.forEach((itemToDecrypt) => {
|
|
161
|
-
promises.push(
|
|
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(
|
|
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(
|
|
189
|
-
.catch((error) => {
|
|
190
|
-
ctx.webex.logger.warn(
|
|
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(
|
|
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) =>
|
|
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) =>
|
|
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) =>
|
|
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 &&
|
|
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(
|
|
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
|
|
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 (
|
|
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
|
|
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
|
-
.
|
|
473
|
-
|
|
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
|
-
.
|
|
487
|
-
|
|
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) =>
|
|
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) =>
|
|
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,32 +48,37 @@ export const transforms = toArray('outbound', {
|
|
|
50
48
|
return Promise.resolve();
|
|
51
49
|
}
|
|
52
50
|
|
|
53
|
-
return Promise.resolve(
|
|
54
|
-
.
|
|
55
|
-
|
|
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
|
-
|
|
58
|
-
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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) {
|
|
@@ -84,16 +87,16 @@ export const transforms = toArray('outbound', {
|
|
|
84
87
|
return Promise.resolve();
|
|
85
88
|
}
|
|
86
89
|
|
|
87
|
-
return ctx.transform(`encrypt${capitalize(activity.verb)}Activity`, key, activity)
|
|
88
|
-
|
|
89
|
-
key = key || activity[KEY];
|
|
90
|
+
return ctx.transform(`encrypt${capitalize(activity.verb)}Activity`, key, activity).then(() => {
|
|
91
|
+
key = key || activity[KEY];
|
|
90
92
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
+
return ctx.transform('prepareActivityKmsMessage', key, activity);
|
|
94
|
+
});
|
|
93
95
|
},
|
|
94
96
|
|
|
95
97
|
encryptVerbActivity(ctx, key, activity) {
|
|
96
|
-
return ctx
|
|
98
|
+
return ctx
|
|
99
|
+
.transform('maybeEncryptTarget', key, activity)
|
|
97
100
|
.then(() => {
|
|
98
101
|
key = key || activity[KEY];
|
|
99
102
|
})
|
|
@@ -107,7 +110,8 @@ export const transforms = toArray('outbound', {
|
|
|
107
110
|
return Promise.resolve();
|
|
108
111
|
}
|
|
109
112
|
|
|
110
|
-
if (
|
|
113
|
+
if (
|
|
114
|
+
has(activity, 'target.defaultActivityEncryptionKeyUrl') &&
|
|
111
115
|
activity.target.defaultActivityEncryptionKeyUrl &&
|
|
112
116
|
has(activity, 'target.kmsResourceObjectUrl')
|
|
113
117
|
) {
|
|
@@ -119,34 +123,42 @@ export const transforms = toArray('outbound', {
|
|
|
119
123
|
const conversationUrl = activity.target && activity.target.url;
|
|
120
124
|
|
|
121
125
|
if (!conversationUrl) {
|
|
122
|
-
return Promise.reject(
|
|
126
|
+
return Promise.reject(
|
|
127
|
+
new Error(
|
|
128
|
+
"Cannot determine encryption key for activity's conversation; no key url or conversation url provided"
|
|
129
|
+
)
|
|
130
|
+
);
|
|
123
131
|
}
|
|
124
132
|
|
|
125
|
-
return ctx.webex.internal.conversation.get({url: conversationUrl})
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
.
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
133
|
+
return ctx.webex.internal.conversation.get({url: conversationUrl}).then((conversation) => {
|
|
134
|
+
if (!conversation.defaultActivityEncryptionKeyUrl) {
|
|
135
|
+
return ctx.webex.internal.conversation.updateKey(conversation).then((updateKeyActivity) => {
|
|
136
|
+
if (updateKeyActivity.kmsMessage.resource) {
|
|
137
|
+
activity.target.kmsResourceObjectUrl = updateKeyActivity.kmsMessage.resource.uri;
|
|
138
|
+
}
|
|
139
|
+
activity[KEY] = activity.target.defaultActivityEncryptionKeyUrl =
|
|
140
|
+
updateKeyActivity.object.defaultActivityEncryptionKeyUrl;
|
|
141
|
+
});
|
|
142
|
+
}
|
|
136
143
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
144
|
+
if (!activity.target.defaultActivityEncryptionKeyUrl) {
|
|
145
|
+
ctx.webex.logger.warn(
|
|
146
|
+
'plugin-conversation: downloaded conversation to determine its defaultActivityEncryptionKeyUrl; make sure to pass all encryption related properties when calling Webex.conversation methods.'
|
|
147
|
+
);
|
|
148
|
+
}
|
|
140
149
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
150
|
+
if (!activity.target.kmsResourceObjectUrl) {
|
|
151
|
+
ctx.webex.logger.warn(
|
|
152
|
+
'plugin-conversation: downloaded conversation to determine its kmsResourceObjectUrl; make sure to pass all encryption related properties when calling Webex.conversation methods.'
|
|
153
|
+
);
|
|
154
|
+
}
|
|
144
155
|
|
|
145
|
-
|
|
146
|
-
|
|
156
|
+
activity[KEY] = activity.target.defaultActivityEncryptionKeyUrl =
|
|
157
|
+
conversation.defaultActivityEncryptionKeyUrl;
|
|
158
|
+
activity.target.kmsResourceObjectUrl = conversation.kmsResourceObjectUrl;
|
|
147
159
|
|
|
148
|
-
|
|
149
|
-
|
|
160
|
+
return Promise.resolve();
|
|
161
|
+
});
|
|
150
162
|
},
|
|
151
163
|
|
|
152
164
|
prepareActivityKmsMessage(ctx, key, activity) {
|
|
@@ -155,11 +167,19 @@ export const transforms = toArray('outbound', {
|
|
|
155
167
|
key = get(activity, 'target.defaultActivityEncryptionKeyUrl');
|
|
156
168
|
}
|
|
157
169
|
|
|
158
|
-
if (
|
|
170
|
+
if (
|
|
171
|
+
!key &&
|
|
172
|
+
activity.verb === 'updateKey' &&
|
|
173
|
+
has(activity, 'object.defaultActivityEncryptionKeyUrl')
|
|
174
|
+
) {
|
|
159
175
|
key = get(activity, 'object.defaultActivityEncryptionKeyUrl');
|
|
160
176
|
}
|
|
161
177
|
|
|
162
|
-
if (
|
|
178
|
+
if (
|
|
179
|
+
!key &&
|
|
180
|
+
activity.verb === 'leave' &&
|
|
181
|
+
has(activity, 'target.defaultActivityEncryptionKeyUrl')
|
|
182
|
+
) {
|
|
163
183
|
key = get(activity, 'target.defaultActivityEncryptionKeyUrl');
|
|
164
184
|
}
|
|
165
185
|
|
|
@@ -190,12 +210,11 @@ export const transforms = toArray('outbound', {
|
|
|
190
210
|
encryptVerbActivityWithKey: {
|
|
191
211
|
direction: 'outbound',
|
|
192
212
|
fn(ctx, key, activity) {
|
|
193
|
-
return ctx.transform('encryptVerbActivity', key, activity)
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
}
|
|
213
|
+
return ctx.transform('encryptVerbActivity', key, activity).then(() => {
|
|
214
|
+
key = key || activity[KEY];
|
|
215
|
+
activity.encryptionKeyUrl = key.uri || key;
|
|
216
|
+
});
|
|
217
|
+
},
|
|
199
218
|
},
|
|
200
219
|
|
|
201
220
|
encryptAddActivity: {
|
|
@@ -206,48 +225,48 @@ export const transforms = toArray('outbound', {
|
|
|
206
225
|
}
|
|
207
226
|
|
|
208
227
|
return ctx.transform('encryptVerbActivity', key, activity);
|
|
209
|
-
}
|
|
228
|
+
},
|
|
210
229
|
},
|
|
211
230
|
|
|
212
231
|
encryptAssignActivity: {
|
|
213
232
|
direction: 'outbound',
|
|
214
|
-
alias: 'encryptVerbActivityWithKey'
|
|
233
|
+
alias: 'encryptVerbActivityWithKey',
|
|
215
234
|
},
|
|
216
235
|
|
|
217
236
|
encryptCreateActivity: {
|
|
218
237
|
direction: 'outbound',
|
|
219
|
-
alias: 'encryptVerbActivity'
|
|
238
|
+
alias: 'encryptVerbActivity',
|
|
220
239
|
},
|
|
221
240
|
|
|
222
241
|
encryptPostActivity: {
|
|
223
242
|
direction: 'outbound',
|
|
224
|
-
alias: 'encryptVerbActivityWithKey'
|
|
243
|
+
alias: 'encryptVerbActivityWithKey',
|
|
225
244
|
},
|
|
226
245
|
|
|
227
246
|
encryptShareActivity: {
|
|
228
247
|
direction: 'outbound',
|
|
229
|
-
alias: 'encryptVerbActivityWithKey'
|
|
248
|
+
alias: 'encryptVerbActivityWithKey',
|
|
230
249
|
},
|
|
231
250
|
|
|
232
251
|
encryptCardactionActivity: {
|
|
233
252
|
direction: 'outbound',
|
|
234
|
-
alias: 'encryptVerbActivityWithKey'
|
|
253
|
+
alias: 'encryptVerbActivityWithKey',
|
|
235
254
|
},
|
|
236
255
|
|
|
237
256
|
encryptUpdateActivity: {
|
|
238
257
|
direction: 'outbound',
|
|
239
|
-
alias: 'encryptVerbActivityWithKey'
|
|
258
|
+
alias: 'encryptVerbActivityWithKey',
|
|
240
259
|
},
|
|
241
260
|
|
|
242
261
|
encryptUpdateKeyActivity: {
|
|
243
262
|
direction: 'outbound',
|
|
244
|
-
alias: 'encryptVerbActivity'
|
|
263
|
+
alias: 'encryptVerbActivity',
|
|
245
264
|
},
|
|
246
265
|
|
|
247
266
|
encryptComment(ctx, key, comment) {
|
|
248
267
|
return Promise.all([
|
|
249
268
|
ctx.transform('encryptPropDisplayName', key, comment),
|
|
250
|
-
ctx.transform('encryptPropContent', key, comment)
|
|
269
|
+
ctx.transform('encryptPropContent', key, comment),
|
|
251
270
|
]);
|
|
252
271
|
},
|
|
253
272
|
|
|
@@ -269,7 +288,7 @@ export const transforms = toArray('outbound', {
|
|
|
269
288
|
ctx.transform('encryptPropScr', key, file),
|
|
270
289
|
ctx.transform('encryptPropDisplayName', key, file),
|
|
271
290
|
ctx.transform('encryptPropContent', key, file),
|
|
272
|
-
file.image && ctx.transform('encryptPropScr', key, file.image)
|
|
291
|
+
file.image && ctx.transform('encryptPropScr', key, file.image),
|
|
273
292
|
]);
|
|
274
293
|
},
|
|
275
294
|
|
|
@@ -295,10 +314,9 @@ export const transforms = toArray('outbound', {
|
|
|
295
314
|
return Promise.resolve();
|
|
296
315
|
}
|
|
297
316
|
|
|
298
|
-
return ctx.webex.internal.encryption.encryptScr(key, object.scr)
|
|
299
|
-
.
|
|
300
|
-
|
|
301
|
-
});
|
|
317
|
+
return ctx.webex.internal.encryption.encryptScr(key, object.scr).then((scr) => {
|
|
318
|
+
object.scr = scr;
|
|
319
|
+
});
|
|
302
320
|
},
|
|
303
321
|
|
|
304
322
|
encryptJsonProp(ctx, name, key, object) {
|
|
@@ -306,7 +324,8 @@ export const transforms = toArray('outbound', {
|
|
|
306
324
|
return Promise.resolve();
|
|
307
325
|
}
|
|
308
326
|
|
|
309
|
-
return ctx.webex.internal.encryption
|
|
327
|
+
return ctx.webex.internal.encryption
|
|
328
|
+
.encryptText(key.uri || key, JSON.stringify(object[name]))
|
|
310
329
|
.then((ciphertext) => {
|
|
311
330
|
object[name] = ciphertext;
|
|
312
331
|
});
|
|
@@ -317,9 +336,10 @@ export const transforms = toArray('outbound', {
|
|
|
317
336
|
return Promise.resolve();
|
|
318
337
|
}
|
|
319
338
|
|
|
320
|
-
return ctx.webex.internal.encryption
|
|
339
|
+
return ctx.webex.internal.encryption
|
|
340
|
+
.encryptText(key.uri || key, object[name])
|
|
321
341
|
.then((ciphertext) => {
|
|
322
342
|
object[name] = ciphertext;
|
|
323
343
|
});
|
|
324
|
-
}
|
|
344
|
+
},
|
|
325
345
|
});
|