@webex/internal-plugin-board 3.0.0-beta.2 → 3.0.0-beta.21
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/board.js +26 -108
- package/dist/board.js.map +1 -1
- package/dist/config.js +0 -8
- package/dist/config.js.map +1 -1
- package/dist/index.js +7 -28
- package/dist/index.js.map +1 -1
- package/dist/realtime-channel-collection.js +2 -8
- package/dist/realtime-channel-collection.js.map +1 -1
- package/dist/realtime-channel.js +1 -5
- package/dist/realtime-channel.js.map +1 -1
- package/dist/realtime.js +38 -82
- package/dist/realtime.js.map +1 -1
- package/package.json +14 -14
- package/src/board.js +255 -205
- package/src/config.js +2 -2
- package/src/index.js +19 -21
- package/src/realtime-channel-collection.js +2 -2
- package/src/realtime-channel.js +8 -9
- package/src/realtime.js +109 -93
- package/test/integration/spec/board.js +347 -220
- package/test/integration/spec/realtime.js +82 -56
- package/test/integration/spec/sharing-mercury.js +154 -73
- package/test/unit/spec/board.js +301 -215
- package/test/unit/spec/encryption.js +152 -120
- package/test/unit/spec/realtime.js +131 -89
package/src/board.js
CHANGED
|
@@ -14,7 +14,7 @@ const Board = WebexPlugin.extend({
|
|
|
14
14
|
namespace: 'Board',
|
|
15
15
|
|
|
16
16
|
children: {
|
|
17
|
-
realtime: Realtime
|
|
17
|
+
realtime: Realtime,
|
|
18
18
|
},
|
|
19
19
|
|
|
20
20
|
/**
|
|
@@ -48,17 +48,20 @@ const Board = WebexPlugin.extend({
|
|
|
48
48
|
* @returns {Promise<Board~Content>}
|
|
49
49
|
*/
|
|
50
50
|
addImage(channel, image, metadata) {
|
|
51
|
-
return this.webex.internal.board._uploadImage(channel, image)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
51
|
+
return this.webex.internal.board._uploadImage(channel, image).then((scr) =>
|
|
52
|
+
this.webex.internal.board.addContent(channel, [
|
|
53
|
+
{
|
|
54
|
+
type: 'FILE',
|
|
55
|
+
metadata,
|
|
56
|
+
file: {
|
|
57
|
+
mimeType: image.type,
|
|
58
|
+
scr,
|
|
59
|
+
size: image.size,
|
|
60
|
+
url: scr.loc,
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
])
|
|
64
|
+
);
|
|
62
65
|
},
|
|
63
66
|
|
|
64
67
|
/**
|
|
@@ -71,7 +74,8 @@ const Board = WebexPlugin.extend({
|
|
|
71
74
|
setSnapshotImage(channel, image) {
|
|
72
75
|
let imageScr;
|
|
73
76
|
|
|
74
|
-
return this.webex.internal.board
|
|
77
|
+
return this.webex.internal.board
|
|
78
|
+
._uploadImage(channel, image, {hiddenSpace: true})
|
|
75
79
|
.then((scr) => {
|
|
76
80
|
imageScr = scr;
|
|
77
81
|
|
|
@@ -91,14 +95,14 @@ const Board = WebexPlugin.extend({
|
|
|
91
95
|
mimeType: image.type || 'image/png',
|
|
92
96
|
scr: imageScr.encryptedScr,
|
|
93
97
|
encryptionKeyUrl: channel.defaultEncryptionKeyUrl,
|
|
94
|
-
fileSize: image.size
|
|
95
|
-
}
|
|
98
|
+
fileSize: image.size,
|
|
99
|
+
},
|
|
96
100
|
};
|
|
97
101
|
|
|
98
102
|
return this.webex.request({
|
|
99
103
|
method: 'PATCH',
|
|
100
104
|
uri: channel.channelUrl,
|
|
101
|
-
body: imageBody
|
|
105
|
+
body: imageBody,
|
|
102
106
|
});
|
|
103
107
|
})
|
|
104
108
|
.then((res) => res.body);
|
|
@@ -112,25 +116,27 @@ const Board = WebexPlugin.extend({
|
|
|
112
116
|
* @returns {Promise<Board~Channel>}
|
|
113
117
|
*/
|
|
114
118
|
createChannel(conversation, channel) {
|
|
115
|
-
return this.webex
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
return this.webex
|
|
120
|
+
.request({
|
|
121
|
+
method: 'POST',
|
|
122
|
+
api: 'board',
|
|
123
|
+
resource: '/channels',
|
|
124
|
+
body: this._prepareChannel(conversation, channel),
|
|
125
|
+
})
|
|
121
126
|
.then((res) => res.body);
|
|
122
127
|
},
|
|
123
128
|
|
|
124
129
|
_prepareChannel(conversation, channel) {
|
|
125
|
-
return
|
|
130
|
+
return {
|
|
126
131
|
aclUrlLink: conversation.aclUrl,
|
|
127
132
|
kmsMessage: {
|
|
128
133
|
method: 'create',
|
|
129
134
|
uri: '/resources',
|
|
130
135
|
userIds: [conversation.kmsResourceObjectUrl],
|
|
131
|
-
keyUris: []
|
|
132
|
-
}
|
|
133
|
-
|
|
136
|
+
keyUris: [],
|
|
137
|
+
},
|
|
138
|
+
...channel,
|
|
139
|
+
};
|
|
134
140
|
},
|
|
135
141
|
|
|
136
142
|
/**
|
|
@@ -150,9 +156,11 @@ const Board = WebexPlugin.extend({
|
|
|
150
156
|
linkedAcl: conversation.aclUrl,
|
|
151
157
|
kmsMessage: {
|
|
152
158
|
method: 'delete',
|
|
153
|
-
uri: `${channel.kmsResourceUrl}/authorizations?${querystring.stringify({
|
|
159
|
+
uri: `${channel.kmsResourceUrl}/authorizations?${querystring.stringify({
|
|
160
|
+
authId: conversation.kmsResourceObjectUrl,
|
|
161
|
+
})}`,
|
|
154
162
|
},
|
|
155
|
-
aclLinkOperation: 'DELETE'
|
|
163
|
+
aclLinkOperation: 'DELETE',
|
|
156
164
|
};
|
|
157
165
|
|
|
158
166
|
let promise = Promise.resolve();
|
|
@@ -162,11 +170,13 @@ const Board = WebexPlugin.extend({
|
|
|
162
170
|
}
|
|
163
171
|
|
|
164
172
|
return promise
|
|
165
|
-
.then(() =>
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
173
|
+
.then(() =>
|
|
174
|
+
this.webex.request({
|
|
175
|
+
method: 'PUT',
|
|
176
|
+
uri: `${channel.aclUrl}/links`,
|
|
177
|
+
body,
|
|
178
|
+
})
|
|
179
|
+
)
|
|
170
180
|
.then((res) => res.body);
|
|
171
181
|
},
|
|
172
182
|
|
|
@@ -178,13 +188,14 @@ const Board = WebexPlugin.extend({
|
|
|
178
188
|
* @returns {Promise}
|
|
179
189
|
*/
|
|
180
190
|
lockChannelForDeletion(channel) {
|
|
181
|
-
return this.webex
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
191
|
+
return this.webex
|
|
192
|
+
.request({
|
|
193
|
+
method: 'POST',
|
|
194
|
+
uri: `${channel.channelUrl}/lock`,
|
|
195
|
+
qs: {
|
|
196
|
+
intent: 'delete',
|
|
197
|
+
},
|
|
198
|
+
})
|
|
188
199
|
.then((res) => res.body);
|
|
189
200
|
},
|
|
190
201
|
|
|
@@ -196,7 +207,7 @@ const Board = WebexPlugin.extend({
|
|
|
196
207
|
keepActive(channel) {
|
|
197
208
|
return this.webex.request({
|
|
198
209
|
method: 'POST',
|
|
199
|
-
uri: `${channel.channelUrl}/keepAlive
|
|
210
|
+
uri: `${channel.channelUrl}/keepAlive`,
|
|
200
211
|
});
|
|
201
212
|
},
|
|
202
213
|
|
|
@@ -208,24 +219,24 @@ const Board = WebexPlugin.extend({
|
|
|
208
219
|
* @returns {Promise<Array>} Resolves with an array of {@link Board~Content} objects.
|
|
209
220
|
*/
|
|
210
221
|
decryptContents(contents) {
|
|
211
|
-
return Promise.all(
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
.then((res) => {
|
|
222
|
+
return Promise.all(
|
|
223
|
+
contents.items.map((content) => {
|
|
224
|
+
let decryptPromise;
|
|
225
|
+
|
|
226
|
+
if (content.type === 'FILE') {
|
|
227
|
+
decryptPromise = this.decryptSingleFileContent(content.encryptionKeyUrl, content);
|
|
228
|
+
} else {
|
|
229
|
+
decryptPromise = this.decryptSingleContent(content.encryptionKeyUrl, content.payload);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return decryptPromise.then((res) => {
|
|
223
233
|
Reflect.deleteProperty(content, 'payload');
|
|
224
234
|
Reflect.deleteProperty(content, 'encryptionKeyUrl');
|
|
225
235
|
|
|
226
236
|
return defaults(res, content);
|
|
227
237
|
});
|
|
228
|
-
|
|
238
|
+
})
|
|
239
|
+
);
|
|
229
240
|
},
|
|
230
241
|
|
|
231
242
|
/**
|
|
@@ -236,7 +247,8 @@ const Board = WebexPlugin.extend({
|
|
|
236
247
|
* @returns {Promise<Board~Content>}
|
|
237
248
|
*/
|
|
238
249
|
decryptSingleContent(encryptionKeyUrl, encryptedData) {
|
|
239
|
-
return this.webex.internal.encryption
|
|
250
|
+
return this.webex.internal.encryption
|
|
251
|
+
.decryptText(encryptionKeyUrl, encryptedData)
|
|
240
252
|
.then((res) => JSON.parse(res));
|
|
241
253
|
},
|
|
242
254
|
|
|
@@ -254,7 +266,8 @@ const Board = WebexPlugin.extend({
|
|
|
254
266
|
metadata = encryptedContent.payload;
|
|
255
267
|
}
|
|
256
268
|
|
|
257
|
-
return this.webex.internal.encryption
|
|
269
|
+
return this.webex.internal.encryption
|
|
270
|
+
.decryptScr(encryptionKeyUrl, encryptedContent.file.scr)
|
|
258
271
|
.then((scr) => {
|
|
259
272
|
encryptedContent.file.scr = scr;
|
|
260
273
|
if (metadata) {
|
|
@@ -269,8 +282,7 @@ const Board = WebexPlugin.extend({
|
|
|
269
282
|
if (encryptedContent.metadata.displayName) {
|
|
270
283
|
encryptedContent.displayName = encryptedContent.metadata.displayName;
|
|
271
284
|
}
|
|
272
|
-
}
|
|
273
|
-
catch (error) {
|
|
285
|
+
} catch (error) {
|
|
274
286
|
encryptedContent.metadata = {};
|
|
275
287
|
}
|
|
276
288
|
|
|
@@ -285,10 +297,11 @@ const Board = WebexPlugin.extend({
|
|
|
285
297
|
* @returns {Promise} Resolves with an content response
|
|
286
298
|
*/
|
|
287
299
|
deleteAllContent(channel) {
|
|
288
|
-
return this.webex
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
300
|
+
return this.webex
|
|
301
|
+
.request({
|
|
302
|
+
method: 'DELETE',
|
|
303
|
+
uri: `${channel.channelUrl}/contents`,
|
|
304
|
+
})
|
|
292
305
|
.then((res) => res.body);
|
|
293
306
|
},
|
|
294
307
|
|
|
@@ -302,14 +315,15 @@ const Board = WebexPlugin.extend({
|
|
|
302
315
|
deletePartialContent(channel, contentsToKeep) {
|
|
303
316
|
const body = contentsToKeep.map((content) => pick(content, 'contentId'));
|
|
304
317
|
|
|
305
|
-
return this.webex
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
318
|
+
return this.webex
|
|
319
|
+
.request({
|
|
320
|
+
method: 'POST',
|
|
321
|
+
uri: `${channel.channelUrl}/contents`,
|
|
322
|
+
body,
|
|
323
|
+
qs: {
|
|
324
|
+
clearBoard: true,
|
|
325
|
+
},
|
|
326
|
+
})
|
|
313
327
|
.then((res) => res.body);
|
|
314
328
|
},
|
|
315
329
|
|
|
@@ -321,27 +335,31 @@ const Board = WebexPlugin.extend({
|
|
|
321
335
|
* @returns {Promise<Array>} Resolves with an array of encrypted {@link Board~Content} objects.
|
|
322
336
|
*/
|
|
323
337
|
encryptContents(encryptionKeyUrl, contents) {
|
|
324
|
-
return Promise.all(
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
338
|
+
return Promise.all(
|
|
339
|
+
contents.map((content) => {
|
|
340
|
+
let encryptionPromise;
|
|
341
|
+
let contentType = 'STRING';
|
|
342
|
+
|
|
343
|
+
// the existence of an scr will determine if the content is a FILE.
|
|
344
|
+
if (content.file) {
|
|
345
|
+
contentType = 'FILE';
|
|
346
|
+
encryptionPromise = this.encryptSingleFileContent(encryptionKeyUrl, content);
|
|
347
|
+
} else {
|
|
348
|
+
encryptionPromise = this.encryptSingleContent(encryptionKeyUrl, content);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
return encryptionPromise.then((res) =>
|
|
352
|
+
assign(
|
|
353
|
+
{
|
|
354
|
+
device: this.webex.internal.device.deviceType,
|
|
355
|
+
type: contentType,
|
|
356
|
+
encryptionKeyUrl,
|
|
357
|
+
},
|
|
358
|
+
pick(res, 'file', 'payload')
|
|
359
|
+
)
|
|
360
|
+
);
|
|
361
|
+
})
|
|
362
|
+
);
|
|
345
363
|
},
|
|
346
364
|
|
|
347
365
|
/**
|
|
@@ -352,10 +370,11 @@ const Board = WebexPlugin.extend({
|
|
|
352
370
|
* @returns {Promise<Board~Content>}
|
|
353
371
|
*/
|
|
354
372
|
encryptSingleContent(encryptionKeyUrl, content) {
|
|
355
|
-
return this.webex.internal.encryption
|
|
373
|
+
return this.webex.internal.encryption
|
|
374
|
+
.encryptText(encryptionKeyUrl, JSON.stringify(content))
|
|
356
375
|
.then((res) => ({
|
|
357
376
|
payload: res,
|
|
358
|
-
encryptionKeyUrl
|
|
377
|
+
encryptionKeyUrl,
|
|
359
378
|
}));
|
|
360
379
|
},
|
|
361
380
|
|
|
@@ -367,14 +386,16 @@ const Board = WebexPlugin.extend({
|
|
|
367
386
|
* @returns {Promise<Board~Content>}
|
|
368
387
|
*/
|
|
369
388
|
encryptSingleFileContent(encryptionKeyUrl, content) {
|
|
370
|
-
return this.webex.internal.encryption
|
|
389
|
+
return this.webex.internal.encryption
|
|
390
|
+
.encryptScr(encryptionKeyUrl, content.file.scr)
|
|
371
391
|
.then((encryptedScr) => {
|
|
372
392
|
content.file.scr = encryptedScr;
|
|
373
393
|
if (content.displayName) {
|
|
374
394
|
content.metadata = assign(content.metadata, {displayName: content.displayName});
|
|
375
395
|
}
|
|
376
396
|
if (content.metadata) {
|
|
377
|
-
return this.webex.internal.encryption
|
|
397
|
+
return this.webex.internal.encryption
|
|
398
|
+
.encryptText(encryptionKeyUrl, JSON.stringify(content.metadata))
|
|
378
399
|
.then((encryptedMetadata) => {
|
|
379
400
|
content.metadata = encryptedMetadata;
|
|
380
401
|
});
|
|
@@ -385,7 +406,7 @@ const Board = WebexPlugin.extend({
|
|
|
385
406
|
.then(() => ({
|
|
386
407
|
file: content.file,
|
|
387
408
|
payload: content.metadata,
|
|
388
|
-
encryptionKeyUrl
|
|
409
|
+
encryptionKeyUrl,
|
|
389
410
|
}));
|
|
390
411
|
},
|
|
391
412
|
|
|
@@ -403,14 +424,13 @@ const Board = WebexPlugin.extend({
|
|
|
403
424
|
const params = {
|
|
404
425
|
uri: `${channel.channelUrl}/contents`,
|
|
405
426
|
qs: {
|
|
406
|
-
contentsLimit: this.config.numberContentsPerPageForGet
|
|
407
|
-
}
|
|
427
|
+
contentsLimit: this.config.numberContentsPerPageForGet,
|
|
428
|
+
},
|
|
408
429
|
};
|
|
409
430
|
|
|
410
431
|
assign(params.qs, pick(options, 'contentsLimit'));
|
|
411
432
|
|
|
412
|
-
return this.request(params)
|
|
413
|
-
.then((res) => new Page(res, this.webex));
|
|
433
|
+
return this.request(params).then((res) => new Page(res, this.webex));
|
|
414
434
|
},
|
|
415
435
|
|
|
416
436
|
/**
|
|
@@ -420,10 +440,11 @@ const Board = WebexPlugin.extend({
|
|
|
420
440
|
* @returns {Promise<Board~Channel>}
|
|
421
441
|
*/
|
|
422
442
|
getChannel(channel) {
|
|
423
|
-
return this.webex
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
443
|
+
return this.webex
|
|
444
|
+
.request({
|
|
445
|
+
method: 'GET',
|
|
446
|
+
uri: channel.channelUrl,
|
|
447
|
+
})
|
|
427
448
|
.then((res) => res.body);
|
|
428
449
|
},
|
|
429
450
|
|
|
@@ -447,14 +468,13 @@ const Board = WebexPlugin.extend({
|
|
|
447
468
|
api: 'board',
|
|
448
469
|
resource: '/channels',
|
|
449
470
|
qs: {
|
|
450
|
-
aclUrlLink: conversation.aclUrl
|
|
451
|
-
}
|
|
471
|
+
aclUrlLink: conversation.aclUrl,
|
|
472
|
+
},
|
|
452
473
|
};
|
|
453
474
|
|
|
454
475
|
assign(params.qs, pick(options, 'channelsLimit', 'type'));
|
|
455
476
|
|
|
456
|
-
return this.request(params)
|
|
457
|
-
.then((res) => new Page(res, this.webex));
|
|
477
|
+
return this.request(params).then((res) => new Page(res, this.webex));
|
|
458
478
|
},
|
|
459
479
|
|
|
460
480
|
/**
|
|
@@ -463,11 +483,12 @@ const Board = WebexPlugin.extend({
|
|
|
463
483
|
* @returns {Promise<Object>} ping response body
|
|
464
484
|
*/
|
|
465
485
|
ping() {
|
|
466
|
-
return this.webex
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
486
|
+
return this.webex
|
|
487
|
+
.request({
|
|
488
|
+
method: 'GET',
|
|
489
|
+
api: 'board',
|
|
490
|
+
resource: '/ping',
|
|
491
|
+
})
|
|
471
492
|
.then((res) => res.body);
|
|
472
493
|
},
|
|
473
494
|
|
|
@@ -475,19 +496,23 @@ const Board = WebexPlugin.extend({
|
|
|
475
496
|
let decryptionPromise;
|
|
476
497
|
|
|
477
498
|
if (message.contentType === 'FILE') {
|
|
478
|
-
decryptionPromise = this.decryptSingleFileContent(
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
499
|
+
decryptionPromise = this.decryptSingleFileContent(
|
|
500
|
+
message.envelope.encryptionKeyUrl,
|
|
501
|
+
message.payload
|
|
502
|
+
);
|
|
503
|
+
} else {
|
|
504
|
+
decryptionPromise = this.decryptSingleContent(
|
|
505
|
+
message.envelope.encryptionKeyUrl,
|
|
506
|
+
message.payload
|
|
507
|
+
);
|
|
482
508
|
}
|
|
483
509
|
|
|
484
|
-
return decryptionPromise
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
message.payload = decryptedData;
|
|
510
|
+
return decryptionPromise.then((decryptedData) => {
|
|
511
|
+
// call the event handlers
|
|
512
|
+
message.payload = decryptedData;
|
|
488
513
|
|
|
489
|
-
|
|
490
|
-
|
|
514
|
+
return message;
|
|
515
|
+
});
|
|
491
516
|
},
|
|
492
517
|
|
|
493
518
|
/**
|
|
@@ -497,12 +522,13 @@ const Board = WebexPlugin.extend({
|
|
|
497
522
|
* @returns {Promise<Board~Registration>}
|
|
498
523
|
*/
|
|
499
524
|
register(data) {
|
|
500
|
-
return this.webex
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
525
|
+
return this.webex
|
|
526
|
+
.request({
|
|
527
|
+
method: 'POST',
|
|
528
|
+
api: 'board',
|
|
529
|
+
resource: '/registrations',
|
|
530
|
+
body: data,
|
|
531
|
+
})
|
|
506
532
|
.then((res) => res.body);
|
|
507
533
|
},
|
|
508
534
|
|
|
@@ -513,28 +539,32 @@ const Board = WebexPlugin.extend({
|
|
|
513
539
|
* @returns {Promise<Board~Registration>}
|
|
514
540
|
*/
|
|
515
541
|
registerToShareMercury(channel) {
|
|
516
|
-
return this.webex.internal.feature
|
|
542
|
+
return this.webex.internal.feature
|
|
543
|
+
.getFeature('developer', 'web-shared-mercury')
|
|
517
544
|
.then((isSharingMercuryFeatureEnabled) => {
|
|
518
545
|
if (!this.webex.internal.mercury.localClusterServiceUrls) {
|
|
519
|
-
return Promise.reject(
|
|
546
|
+
return Promise.reject(
|
|
547
|
+
new Error('`localClusterServiceUrls` is not defined, make sure mercury is connected')
|
|
548
|
+
);
|
|
520
549
|
}
|
|
521
550
|
if (!isSharingMercuryFeatureEnabled) {
|
|
522
551
|
return Promise.reject(new Error('`web-shared-mercury` is not enabled'));
|
|
523
552
|
}
|
|
524
553
|
|
|
525
554
|
const {webSocketUrl} = this.webex.internal.device;
|
|
526
|
-
const {mercuryConnectionServiceClusterUrl} =
|
|
555
|
+
const {mercuryConnectionServiceClusterUrl} =
|
|
556
|
+
this.webex.internal.mercury.localClusterServiceUrls;
|
|
527
557
|
|
|
528
558
|
const data = {
|
|
529
559
|
mercuryConnectionServiceClusterUrl,
|
|
530
560
|
webSocketUrl,
|
|
531
|
-
action: 'ADD'
|
|
561
|
+
action: 'ADD',
|
|
532
562
|
};
|
|
533
563
|
|
|
534
564
|
return this.webex.request({
|
|
535
565
|
method: 'POST',
|
|
536
566
|
uri: `${channel.channelUrl}/register`,
|
|
537
|
-
body: data
|
|
567
|
+
body: data,
|
|
538
568
|
});
|
|
539
569
|
})
|
|
540
570
|
.then((res) => res.body);
|
|
@@ -552,24 +582,28 @@ const Board = WebexPlugin.extend({
|
|
|
552
582
|
const data = {
|
|
553
583
|
binding,
|
|
554
584
|
webSocketUrl,
|
|
555
|
-
action: 'REMOVE'
|
|
585
|
+
action: 'REMOVE',
|
|
556
586
|
};
|
|
557
587
|
|
|
558
|
-
return this.webex
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
588
|
+
return this.webex
|
|
589
|
+
.request({
|
|
590
|
+
method: 'POST',
|
|
591
|
+
uri: `${channel.channelUrl}/register`,
|
|
592
|
+
body: data,
|
|
593
|
+
})
|
|
563
594
|
.then((res) => res.body);
|
|
564
595
|
},
|
|
565
596
|
|
|
566
597
|
_addContentChunk(channel, contentChunk) {
|
|
567
|
-
return this.webex.internal.board
|
|
568
|
-
.
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
598
|
+
return this.webex.internal.board
|
|
599
|
+
.encryptContents(channel.defaultEncryptionKeyUrl, contentChunk)
|
|
600
|
+
.then((res) =>
|
|
601
|
+
this.webex.request({
|
|
602
|
+
method: 'POST',
|
|
603
|
+
uri: `${channel.channelUrl}/contents`,
|
|
604
|
+
body: res,
|
|
605
|
+
})
|
|
606
|
+
)
|
|
573
607
|
.then((res) => res.body);
|
|
574
608
|
},
|
|
575
609
|
|
|
@@ -586,8 +620,11 @@ const Board = WebexPlugin.extend({
|
|
|
586
620
|
_uploadImage(channel, file, options) {
|
|
587
621
|
options = options || {};
|
|
588
622
|
|
|
589
|
-
return this.webex.internal.encryption
|
|
590
|
-
.
|
|
623
|
+
return this.webex.internal.encryption
|
|
624
|
+
.encryptBinary(file)
|
|
625
|
+
.then(({scr, cdata}) =>
|
|
626
|
+
Promise.all([scr, this._uploadImageToWebexFiles(channel, cdata, options.hiddenSpace)])
|
|
627
|
+
)
|
|
591
628
|
.then(([scr, res]) => assign(scr, {loc: res.downloadUrl}));
|
|
592
629
|
},
|
|
593
630
|
|
|
@@ -598,38 +635,40 @@ const Board = WebexPlugin.extend({
|
|
|
598
635
|
requestUri = `${channel.channelUrl}/spaces/hidden`;
|
|
599
636
|
}
|
|
600
637
|
|
|
601
|
-
return this.webex
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
638
|
+
return this.webex
|
|
639
|
+
.request({
|
|
640
|
+
method: 'PUT',
|
|
641
|
+
uri: requestUri,
|
|
642
|
+
})
|
|
605
643
|
.then((res) => res.body.spaceUrl);
|
|
606
644
|
},
|
|
607
645
|
|
|
608
646
|
_uploadImageToWebexFiles(channel, file, hiddenSpace) {
|
|
609
647
|
const fileSize = file.length || file.size || file.byteLength;
|
|
610
648
|
|
|
611
|
-
return this._getSpaceUrl(channel, hiddenSpace)
|
|
612
|
-
|
|
649
|
+
return this._getSpaceUrl(channel, hiddenSpace).then((spaceUrl) =>
|
|
650
|
+
this.webex.upload({
|
|
613
651
|
uri: `${spaceUrl}/upload_sessions`,
|
|
614
652
|
file,
|
|
615
653
|
qs: {
|
|
616
|
-
transcode: true
|
|
654
|
+
transcode: true,
|
|
617
655
|
},
|
|
618
656
|
phases: {
|
|
619
657
|
initialize: {fileSize},
|
|
620
658
|
upload: {
|
|
621
659
|
$url(session) {
|
|
622
660
|
return session.uploadUrl;
|
|
623
|
-
}
|
|
661
|
+
},
|
|
624
662
|
},
|
|
625
663
|
finalize: {
|
|
626
664
|
$uri(session) {
|
|
627
665
|
return session.finishUploadUrl;
|
|
628
666
|
},
|
|
629
|
-
body: {fileSize}
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
})
|
|
667
|
+
body: {fileSize},
|
|
668
|
+
},
|
|
669
|
+
},
|
|
670
|
+
})
|
|
671
|
+
);
|
|
633
672
|
},
|
|
634
673
|
|
|
635
674
|
/** Authorize transcoder (for sharing whiteboard to mobile)
|
|
@@ -640,22 +679,26 @@ const Board = WebexPlugin.extend({
|
|
|
640
679
|
*/
|
|
641
680
|
authorizeMediaInjector(board) {
|
|
642
681
|
if (!board) {
|
|
643
|
-
Promise.reject(
|
|
682
|
+
Promise.reject(
|
|
683
|
+
new Error('#authorizeMediaInjector --> cannot authorize transcoder without board')
|
|
684
|
+
);
|
|
644
685
|
}
|
|
645
686
|
|
|
646
|
-
return this.webex.internal.encryption.kms
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
687
|
+
return this.webex.internal.encryption.kms
|
|
688
|
+
.prepareRequest({
|
|
689
|
+
method: 'create',
|
|
690
|
+
uri: '/authorizations',
|
|
691
|
+
resourceUri: board.kmsResourceUrl,
|
|
692
|
+
anonymous: 1,
|
|
693
|
+
})
|
|
694
|
+
.then((request) =>
|
|
695
|
+
this.webex.request({
|
|
696
|
+
uri: `${board.channelUrl}/sharePolicies/transcoder`,
|
|
697
|
+
method: 'PUT',
|
|
698
|
+
body: {kmsMessage: request.wrapped},
|
|
699
|
+
})
|
|
700
|
+
)
|
|
701
|
+
.then((res) => this.webex.internal.encryption.kms.decryptKmsMessage(res.body.kmsResponse))
|
|
659
702
|
.then((decryptedKmsMessage) => {
|
|
660
703
|
if (decryptedKmsMessage?.authorizations.length > 0) {
|
|
661
704
|
return decryptedKmsMessage.authorizations[0].bearer;
|
|
@@ -664,10 +707,11 @@ const Board = WebexPlugin.extend({
|
|
|
664
707
|
return undefined;
|
|
665
708
|
})
|
|
666
709
|
.catch((err) =>
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
Promise.resolve(err)
|
|
710
|
+
/* We want to resolve any errors so that whiteboard share will still work
|
|
711
|
+
* except mobile being able to receive the share
|
|
712
|
+
*/
|
|
713
|
+
Promise.resolve(err)
|
|
714
|
+
);
|
|
671
715
|
},
|
|
672
716
|
|
|
673
717
|
/** Unauthorize transcoder (for stopping whiteboard share to mobile)
|
|
@@ -678,37 +722,43 @@ const Board = WebexPlugin.extend({
|
|
|
678
722
|
*/
|
|
679
723
|
unauthorizeMediaInjector(board) {
|
|
680
724
|
if (!board) {
|
|
681
|
-
Promise.reject(
|
|
725
|
+
Promise.reject(
|
|
726
|
+
new Error('#unauthorizeMediaInjector --> cannot unauthorize transcoder without board')
|
|
727
|
+
);
|
|
682
728
|
}
|
|
683
729
|
|
|
684
|
-
return this.webex.internal.encryption.kms
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
730
|
+
return this.webex.internal.encryption.kms
|
|
731
|
+
.listAuthorizations({
|
|
732
|
+
kroUri: board.kmsResourceUrl,
|
|
733
|
+
})
|
|
734
|
+
.then((authorizations) => {
|
|
735
|
+
/* Attempt to remove the authorization made from starting whiteboard share
|
|
736
|
+
* Also removing any previous authorizations that were not cleared
|
|
737
|
+
*/
|
|
738
|
+
const promises = authorizations.map((auth) => {
|
|
739
|
+
const {authId} = auth;
|
|
740
|
+
|
|
741
|
+
return this.webex.internal.encryption.kms
|
|
742
|
+
.removeAuthorization({
|
|
743
|
+
authId,
|
|
744
|
+
kroUri: board.kmsResourceUrl,
|
|
745
|
+
})
|
|
746
|
+
.then(() => Promise.resolve(authId))
|
|
747
|
+
.catch((err) =>
|
|
748
|
+
/* We don't want this to error out, otherwise the
|
|
749
|
+
* Promise.all will not process the rest of the request
|
|
750
|
+
*/
|
|
751
|
+
Promise.resolve(err)
|
|
752
|
+
);
|
|
753
|
+
});
|
|
704
754
|
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
755
|
+
if (promises.length > 0) {
|
|
756
|
+
return Promise.all(promises).then((responses) => responses);
|
|
757
|
+
}
|
|
708
758
|
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
}
|
|
759
|
+
return Promise.resolve([]);
|
|
760
|
+
});
|
|
761
|
+
},
|
|
712
762
|
});
|
|
713
763
|
|
|
714
764
|
export default Board;
|