@webex/plugin-meetings 3.7.0 → 3.8.0-next.10

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 (206) hide show
  1. package/dist/annotation/index.js +17 -0
  2. package/dist/annotation/index.js.map +1 -1
  3. package/dist/breakouts/breakout.js +1 -1
  4. package/dist/breakouts/index.js +1 -1
  5. package/dist/common/errors/join-forbidden-error.js +52 -0
  6. package/dist/common/errors/join-forbidden-error.js.map +1 -0
  7. package/dist/common/errors/{webinar-registration-error.js → join-webinar-error.js} +12 -12
  8. package/dist/common/errors/join-webinar-error.js.map +1 -0
  9. package/dist/common/errors/multistream-not-supported-error.js +53 -0
  10. package/dist/common/errors/multistream-not-supported-error.js.map +1 -0
  11. package/dist/config.js +3 -1
  12. package/dist/config.js.map +1 -1
  13. package/dist/constants.js +69 -6
  14. package/dist/constants.js.map +1 -1
  15. package/dist/index.js +16 -11
  16. package/dist/index.js.map +1 -1
  17. package/dist/interpretation/index.js +4 -4
  18. package/dist/interpretation/index.js.map +1 -1
  19. package/dist/interpretation/siLanguage.js +1 -1
  20. package/dist/locus-info/index.js +14 -3
  21. package/dist/locus-info/index.js.map +1 -1
  22. package/dist/locus-info/selfUtils.js +35 -17
  23. package/dist/locus-info/selfUtils.js.map +1 -1
  24. package/dist/media/MediaConnectionAwaiter.js +1 -0
  25. package/dist/media/MediaConnectionAwaiter.js.map +1 -1
  26. package/dist/media/properties.js +30 -16
  27. package/dist/media/properties.js.map +1 -1
  28. package/dist/meeting/brbState.js +167 -0
  29. package/dist/meeting/brbState.js.map +1 -0
  30. package/dist/meeting/in-meeting-actions.js +13 -1
  31. package/dist/meeting/in-meeting-actions.js.map +1 -1
  32. package/dist/meeting/index.js +1373 -1052
  33. package/dist/meeting/index.js.map +1 -1
  34. package/dist/meeting/locusMediaRequest.js +32 -11
  35. package/dist/meeting/locusMediaRequest.js.map +1 -1
  36. package/dist/meeting/muteState.js +1 -6
  37. package/dist/meeting/muteState.js.map +1 -1
  38. package/dist/meeting/request.js +51 -29
  39. package/dist/meeting/request.js.map +1 -1
  40. package/dist/meeting/request.type.js.map +1 -1
  41. package/dist/meeting/util.js +103 -67
  42. package/dist/meeting/util.js.map +1 -1
  43. package/dist/meeting-info/meeting-info-v2.js +115 -45
  44. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  45. package/dist/meeting-info/utilv2.js +6 -2
  46. package/dist/meeting-info/utilv2.js.map +1 -1
  47. package/dist/meetings/index.js +107 -55
  48. package/dist/meetings/index.js.map +1 -1
  49. package/dist/meetings/meetings.types.js +2 -0
  50. package/dist/meetings/meetings.types.js.map +1 -1
  51. package/dist/meetings/util.js +1 -1
  52. package/dist/meetings/util.js.map +1 -1
  53. package/dist/member/index.js +9 -0
  54. package/dist/member/index.js.map +1 -1
  55. package/dist/member/types.js.map +1 -1
  56. package/dist/member/util.js +39 -28
  57. package/dist/member/util.js.map +1 -1
  58. package/dist/members/util.js +4 -2
  59. package/dist/members/util.js.map +1 -1
  60. package/dist/metrics/constants.js +6 -1
  61. package/dist/metrics/constants.js.map +1 -1
  62. package/dist/multistream/remoteMedia.js +30 -15
  63. package/dist/multistream/remoteMedia.js.map +1 -1
  64. package/dist/multistream/remoteMediaManager.js +40 -8
  65. package/dist/multistream/remoteMediaManager.js.map +1 -1
  66. package/dist/multistream/sendSlotManager.js +24 -0
  67. package/dist/multistream/sendSlotManager.js.map +1 -1
  68. package/dist/reachability/clusterReachability.js +12 -15
  69. package/dist/reachability/clusterReachability.js.map +1 -1
  70. package/dist/reachability/index.js +471 -140
  71. package/dist/reachability/index.js.map +1 -1
  72. package/dist/{rtcMetrics/constants.js → reachability/reachability.types.js} +1 -5
  73. package/dist/reachability/reachability.types.js.map +1 -0
  74. package/dist/reachability/request.js +21 -8
  75. package/dist/reachability/request.js.map +1 -1
  76. package/dist/recording-controller/enums.js +8 -4
  77. package/dist/recording-controller/enums.js.map +1 -1
  78. package/dist/recording-controller/index.js +18 -9
  79. package/dist/recording-controller/index.js.map +1 -1
  80. package/dist/recording-controller/util.js +13 -9
  81. package/dist/recording-controller/util.js.map +1 -1
  82. package/dist/roap/index.js +15 -15
  83. package/dist/roap/index.js.map +1 -1
  84. package/dist/roap/request.js +45 -79
  85. package/dist/roap/request.js.map +1 -1
  86. package/dist/roap/turnDiscovery.js +3 -6
  87. package/dist/roap/turnDiscovery.js.map +1 -1
  88. package/dist/types/annotation/index.d.ts +5 -0
  89. package/dist/types/common/errors/join-forbidden-error.d.ts +15 -0
  90. package/dist/types/common/errors/{webinar-registration-error.d.ts → join-webinar-error.d.ts} +2 -2
  91. package/dist/types/common/errors/multistream-not-supported-error.d.ts +17 -0
  92. package/dist/types/config.d.ts +2 -0
  93. package/dist/types/constants.d.ts +54 -1
  94. package/dist/types/index.d.ts +3 -3
  95. package/dist/types/locus-info/index.d.ts +2 -1
  96. package/dist/types/meeting/brbState.d.ts +54 -0
  97. package/dist/types/meeting/in-meeting-actions.d.ts +12 -0
  98. package/dist/types/meeting/index.d.ts +86 -14
  99. package/dist/types/meeting/locusMediaRequest.d.ts +6 -3
  100. package/dist/types/meeting/request.d.ts +14 -3
  101. package/dist/types/meeting/request.type.d.ts +6 -0
  102. package/dist/types/meeting/util.d.ts +3 -3
  103. package/dist/types/meeting-info/meeting-info-v2.d.ts +30 -5
  104. package/dist/types/meetings/index.d.ts +20 -2
  105. package/dist/types/meetings/meetings.types.d.ts +8 -0
  106. package/dist/types/member/index.d.ts +1 -0
  107. package/dist/types/member/types.d.ts +7 -0
  108. package/dist/types/members/util.d.ts +2 -0
  109. package/dist/types/metrics/constants.d.ts +6 -1
  110. package/dist/types/multistream/remoteMediaManager.d.ts +10 -1
  111. package/dist/types/multistream/sendSlotManager.d.ts +8 -1
  112. package/dist/types/reachability/clusterReachability.d.ts +1 -10
  113. package/dist/types/reachability/index.d.ts +83 -36
  114. package/dist/types/reachability/reachability.types.d.ts +64 -0
  115. package/dist/types/reachability/request.d.ts +5 -1
  116. package/dist/types/recording-controller/enums.d.ts +5 -2
  117. package/dist/types/recording-controller/index.d.ts +1 -0
  118. package/dist/types/recording-controller/util.d.ts +2 -1
  119. package/dist/types/roap/request.d.ts +1 -13
  120. package/dist/webinar/index.js +390 -7
  121. package/dist/webinar/index.js.map +1 -1
  122. package/package.json +23 -22
  123. package/src/annotation/index.ts +16 -0
  124. package/src/common/errors/join-forbidden-error.ts +26 -0
  125. package/src/common/errors/join-webinar-error.ts +24 -0
  126. package/src/common/errors/multistream-not-supported-error.ts +30 -0
  127. package/src/config.ts +2 -0
  128. package/src/constants.ts +62 -3
  129. package/src/index.ts +5 -3
  130. package/src/interpretation/index.ts +3 -3
  131. package/src/locus-info/index.ts +20 -3
  132. package/src/locus-info/selfUtils.ts +24 -6
  133. package/src/media/MediaConnectionAwaiter.ts +2 -0
  134. package/src/media/properties.ts +34 -13
  135. package/src/meeting/brbState.ts +169 -0
  136. package/src/meeting/in-meeting-actions.ts +25 -0
  137. package/src/meeting/index.ts +485 -88
  138. package/src/meeting/locusMediaRequest.ts +38 -12
  139. package/src/meeting/muteState.ts +1 -6
  140. package/src/meeting/request.ts +30 -12
  141. package/src/meeting/request.type.ts +7 -0
  142. package/src/meeting/util.ts +32 -13
  143. package/src/meeting-info/meeting-info-v2.ts +83 -12
  144. package/src/meeting-info/utilv2.ts +17 -3
  145. package/src/meetings/index.ts +79 -20
  146. package/src/meetings/meetings.types.ts +10 -0
  147. package/src/meetings/util.ts +2 -1
  148. package/src/member/index.ts +9 -0
  149. package/src/member/types.ts +8 -0
  150. package/src/member/util.ts +34 -24
  151. package/src/members/util.ts +1 -0
  152. package/src/metrics/constants.ts +6 -1
  153. package/src/multistream/remoteMedia.ts +28 -15
  154. package/src/multistream/remoteMediaManager.ts +32 -10
  155. package/src/multistream/sendSlotManager.ts +31 -0
  156. package/src/reachability/clusterReachability.ts +5 -15
  157. package/src/reachability/index.ts +315 -75
  158. package/src/reachability/reachability.types.ts +85 -0
  159. package/src/reachability/request.ts +55 -31
  160. package/src/recording-controller/enums.ts +5 -2
  161. package/src/recording-controller/index.ts +17 -4
  162. package/src/recording-controller/util.ts +28 -9
  163. package/src/roap/index.ts +14 -13
  164. package/src/roap/request.ts +30 -44
  165. package/src/roap/turnDiscovery.ts +2 -4
  166. package/src/webinar/index.ts +235 -9
  167. package/test/unit/spec/annotation/index.ts +46 -1
  168. package/test/unit/spec/interpretation/index.ts +39 -1
  169. package/test/unit/spec/locus-info/index.js +292 -60
  170. package/test/unit/spec/locus-info/selfConstant.js +7 -0
  171. package/test/unit/spec/locus-info/selfUtils.js +101 -1
  172. package/test/unit/spec/media/properties.ts +15 -0
  173. package/test/unit/spec/meeting/brbState.ts +114 -0
  174. package/test/unit/spec/meeting/in-meeting-actions.ts +15 -1
  175. package/test/unit/spec/meeting/index.js +908 -124
  176. package/test/unit/spec/meeting/locusMediaRequest.ts +111 -66
  177. package/test/unit/spec/meeting/muteState.js +0 -24
  178. package/test/unit/spec/meeting/request.js +3 -26
  179. package/test/unit/spec/meeting/utils.js +73 -28
  180. package/test/unit/spec/meeting-info/meetinginfov2.js +46 -4
  181. package/test/unit/spec/meeting-info/utilv2.js +26 -0
  182. package/test/unit/spec/meetings/index.js +172 -18
  183. package/test/unit/spec/meetings/utils.js +10 -0
  184. package/test/unit/spec/member/util.js +52 -11
  185. package/test/unit/spec/members/utils.js +95 -0
  186. package/test/unit/spec/multistream/remoteMedia.ts +11 -7
  187. package/test/unit/spec/multistream/remoteMediaManager.ts +397 -118
  188. package/test/unit/spec/reachability/clusterReachability.ts +7 -0
  189. package/test/unit/spec/reachability/index.ts +391 -9
  190. package/test/unit/spec/reachability/request.js +48 -12
  191. package/test/unit/spec/recording-controller/index.js +61 -5
  192. package/test/unit/spec/recording-controller/util.js +39 -3
  193. package/test/unit/spec/roap/index.ts +48 -1
  194. package/test/unit/spec/roap/request.ts +51 -109
  195. package/test/unit/spec/roap/turnDiscovery.ts +202 -147
  196. package/test/unit/spec/webinar/index.ts +509 -0
  197. package/dist/common/errors/webinar-registration-error.js.map +0 -1
  198. package/dist/networkQualityMonitor/index.js +0 -227
  199. package/dist/networkQualityMonitor/index.js.map +0 -1
  200. package/dist/rtcMetrics/constants.js.map +0 -1
  201. package/dist/rtcMetrics/index.js +0 -197
  202. package/dist/rtcMetrics/index.js.map +0 -1
  203. package/dist/types/networkQualityMonitor/index.d.ts +0 -70
  204. package/dist/types/rtcMetrics/constants.d.ts +0 -4
  205. package/dist/types/rtcMetrics/index.d.ts +0 -71
  206. package/src/common/errors/webinar-registration-error.ts +0 -27
@@ -1,9 +1,11 @@
1
1
  /* eslint-disable valid-jsdoc */
2
2
  import {defer} from 'lodash';
3
- import {Defer} from '@webex/common';
3
+ import {Defer, transferEvents} from '@webex/common';
4
+ import {EventEmitter} from 'events';
4
5
  import {WebexPlugin} from '@webex/webex-core';
5
- import {MEDIA, HTTP_VERBS, ROAP, IP_VERSION} from '../constants';
6
+ import {MEDIA, HTTP_VERBS, ROAP} from '../constants';
6
7
  import LoggerProxy from '../common/logs/logger-proxy';
8
+ import {ClientMediaPreferences} from '../reachability/reachability.types';
7
9
 
8
10
  export type MediaRequestType = 'RoapMessage' | 'LocalMute';
9
11
  export type RequestResult = any;
@@ -14,9 +16,8 @@ export type RoapRequest = {
14
16
  mediaId: string;
15
17
  roapMessage: any;
16
18
  reachability: any;
19
+ clientMediaPreferences: ClientMediaPreferences;
17
20
  sequence?: any;
18
- joinCookie: any; // any, because this is opaque to the client, we pass whatever object we got from one backend component (Orpheus) to the other (Locus)
19
- ipVersion?: IP_VERSION;
20
21
  };
21
22
 
22
23
  export type LocalMuteRequest = {
@@ -202,10 +203,6 @@ export class LocusMediaRequest extends WebexPlugin {
202
203
  const body: any = {
203
204
  device: this.config.device,
204
205
  correlationId: this.config.correlationId,
205
- clientMediaPreferences: {
206
- preferTranscoding: this.config.preferTranscoding,
207
- ipver: request.type === 'RoapMessage' ? request.ipVersion : undefined,
208
- },
209
206
  };
210
207
 
211
208
  const localMedias: any = {
@@ -223,7 +220,7 @@ export class LocusMediaRequest extends WebexPlugin {
223
220
  case 'RoapMessage':
224
221
  localMedias.roapMessage = request.roapMessage;
225
222
  localMedias.reachability = request.reachability;
226
- body.clientMediaPreferences.joinCookie = request.joinCookie;
223
+ body.clientMediaPreferences = request.clientMediaPreferences;
227
224
 
228
225
  // @ts-ignore
229
226
  this.webex.internal.newMetrics.submitClientEvent({
@@ -254,12 +251,19 @@ export class LocusMediaRequest extends WebexPlugin {
254
251
  this.confluenceState = 'creation in progress';
255
252
  }
256
253
 
257
- // @ts-ignore
258
- return this.request({
254
+ const upload = new EventEmitter();
255
+ const download = new EventEmitter();
256
+
257
+ const options = {
259
258
  method: HTTP_VERBS.PUT,
260
259
  uri,
261
260
  body,
262
- })
261
+ upload,
262
+ download,
263
+ };
264
+
265
+ // @ts-ignore
266
+ const promise = this.request(options)
263
267
  .then((result) => {
264
268
  if (isRequestAffectingConfluenceState(request)) {
265
269
  this.confluenceState = 'created';
@@ -298,6 +302,21 @@ export class LocusMediaRequest extends WebexPlugin {
298
302
 
299
303
  throw e;
300
304
  });
305
+
306
+ if (request.type === 'RoapMessage') {
307
+ const setupProgressListener = (direction: string, eventEmitter: EventEmitter) => {
308
+ eventEmitter.on('progress', (progressEvent: ProgressEvent) => {
309
+ LoggerProxy.logger.info(
310
+ `${request.type}: ${direction} Progress, Timestamp: ${progressEvent.timeStamp}, Progress: ${progressEvent.loaded}/${progressEvent.total}`
311
+ );
312
+ });
313
+ };
314
+
315
+ setupProgressListener('Upload', options.upload);
316
+ setupProgressListener('Download', options.download);
317
+ }
318
+
319
+ return promise;
301
320
  }
302
321
 
303
322
  /**
@@ -346,4 +365,11 @@ export class LocusMediaRequest extends WebexPlugin {
346
365
  public isConfluenceCreated() {
347
366
  return this.confluenceState === 'created';
348
367
  }
368
+
369
+ /**
370
+ * This method needs to be called when we downgrade from multistream to transcoded connection.
371
+ */
372
+ public downgradeFromMultistreamToTranscoded() {
373
+ this.config.preferTranscoding = true;
374
+ }
349
375
  }
@@ -379,12 +379,7 @@ export class MuteState {
379
379
  }
380
380
  if (muted !== undefined) {
381
381
  this.state.server.remoteMute = muted;
382
-
383
- // We never want to unmute the local stream from a server remote mute update.
384
- // Moderated unmute is handled by a different function.
385
- if (muted) {
386
- this.muteLocalStream(meeting, muted, 'remotelyMuted');
387
- }
382
+ this.muteLocalStream(meeting, muted, 'remotelyMuted');
388
383
  }
389
384
  }
390
385
 
@@ -26,11 +26,11 @@ import {
26
26
  SEND_DTMF_ENDPOINT,
27
27
  _SLIDES_,
28
28
  ANNOTATION,
29
- IP_VERSION,
30
29
  } from '../constants';
31
- import {SendReactionOptions, ToggleReactionsOptions} from './request.type';
30
+ import {SendReactionOptions, BrbOptions, ToggleReactionsOptions} from './request.type';
32
31
  import MeetingUtil from './util';
33
32
  import {AnnotationInfo} from '../annotation/annotation.types';
33
+ import {ClientMediaPreferences} from '../reachability/reachability.types';
34
34
 
35
35
  /**
36
36
  * @class MeetingRequest
@@ -128,8 +128,8 @@ export default class MeetingRequest extends StatelessWebexPlugin {
128
128
  locale?: string;
129
129
  deviceCapabilities?: Array<string>;
130
130
  liveAnnotationSupported: boolean;
131
- ipVersion?: IP_VERSION;
132
131
  alias?: string;
132
+ clientMediaPreferences: ClientMediaPreferences;
133
133
  }) {
134
134
  const {
135
135
  asResourceOccupant,
@@ -147,12 +147,11 @@ export default class MeetingRequest extends StatelessWebexPlugin {
147
147
  moveToResource,
148
148
  roapMessage,
149
149
  reachability,
150
- preferTranscoding,
151
150
  breakoutsSupported,
152
151
  locale,
153
152
  deviceCapabilities = [],
154
153
  liveAnnotationSupported,
155
- ipVersion,
154
+ clientMediaPreferences,
156
155
  alias,
157
156
  } = options;
158
157
 
@@ -160,8 +159,6 @@ export default class MeetingRequest extends StatelessWebexPlugin {
160
159
 
161
160
  let url = '';
162
161
 
163
- const joinCookie = await this.getJoinCookie();
164
-
165
162
  const body: any = {
166
163
  asResourceOccupant,
167
164
  device: {
@@ -176,11 +173,7 @@ export default class MeetingRequest extends StatelessWebexPlugin {
176
173
  allowMultiDevice: true,
177
174
  ensureConversation: ensureConversation || false,
178
175
  supportsNativeLobby: 1,
179
- clientMediaPreferences: {
180
- preferTranscoding: preferTranscoding ?? true,
181
- joinCookie,
182
- ipver: ipVersion,
183
- },
176
+ clientMediaPreferences,
184
177
  };
185
178
 
186
179
  if (alias) {
@@ -916,4 +909,29 @@ export default class MeetingRequest extends StatelessWebexPlugin {
916
909
  uri: locusUrl,
917
910
  });
918
911
  }
912
+
913
+ /**
914
+ * Sends a request to set be right back status.
915
+ *
916
+ * @param {Object} options - The options for brb request.
917
+ * @param {boolean} options.enabled - Whether brb status is enabled.
918
+ * @param {string} options.locusUrl - The URL of the locus.
919
+ * @param {string} options.deviceUrl - The URL of the device.
920
+ * @param {string} options.selfId - The ID of the participant.
921
+ * @returns {Promise}
922
+ */
923
+ setBrb({enabled, locusUrl, deviceUrl, selfId}: BrbOptions) {
924
+ const uri = `${locusUrl}/${PARTICIPANT}/${selfId}/${CONTROLS}`;
925
+
926
+ return this.locusDeltaRequest({
927
+ method: HTTP_VERBS.PATCH,
928
+ uri,
929
+ body: {
930
+ brb: {
931
+ enabled,
932
+ deviceUrl,
933
+ },
934
+ },
935
+ });
936
+ }
919
937
  }
@@ -11,3 +11,10 @@ export type ToggleReactionsOptions = {
11
11
  locusUrl: string;
12
12
  requestingParticipantId: string;
13
13
  };
14
+
15
+ export type BrbOptions = {
16
+ enabled: boolean;
17
+ locusUrl: string;
18
+ deviceUrl: string;
19
+ selfId: string;
20
+ };
@@ -115,7 +115,7 @@ const MeetingUtil = {
115
115
  return IP_VERSION.unknown;
116
116
  },
117
117
 
118
- joinMeeting: (meeting, options) => {
118
+ joinMeeting: async (meeting, options) => {
119
119
  if (!meeting) {
120
120
  return Promise.reject(new ParameterError('You need a meeting object.'));
121
121
  }
@@ -127,6 +127,31 @@ const MeetingUtil = {
127
127
  options: {meetingId: meeting.id},
128
128
  });
129
129
 
130
+ let reachability;
131
+ let clientMediaPreferences = {
132
+ // bare minimum fallback value that should allow us to join
133
+ ipver: IP_VERSION.unknown,
134
+ joinCookie: undefined,
135
+ preferTranscoding: !meeting.isMultistream,
136
+ };
137
+
138
+ try {
139
+ clientMediaPreferences = await webex.meetings.reachability.getClientMediaPreferences(
140
+ meeting.isMultistream,
141
+ MeetingUtil.getIpVersion(webex)
142
+ );
143
+ if (options.roapMessage) {
144
+ // we only need to attach reachability if we are sending a roap message
145
+ // sending reachability on its own will cause Locus to reject our join request
146
+ reachability = await webex.meetings.reachability.getReachabilityReportToAttachToRoap();
147
+ }
148
+ } catch (e) {
149
+ LoggerProxy.logger.error(
150
+ 'Meeting:util#joinMeeting --> Error getting reachability or clientMediaPreferences:',
151
+ e
152
+ );
153
+ }
154
+
130
155
  // eslint-disable-next-line no-warning-comments
131
156
  // TODO: check if the meeting is in JOINING state
132
157
  // if Joining state termintate the request as user might click multiple times
@@ -138,20 +163,19 @@ const MeetingUtil = {
138
163
  locusUrl: meeting.locusUrl,
139
164
  locusClusterUrl: meeting.meetingInfo?.locusClusterUrl,
140
165
  correlationId: meeting.correlationId,
141
- reachability: options.reachability,
166
+ reachability,
142
167
  roapMessage: options.roapMessage,
143
168
  permissionToken: meeting.permissionToken,
144
169
  resourceId: options.resourceId || null,
145
170
  moderator: options.moderator,
146
171
  pin: options.pin,
147
172
  moveToResource: options.moveToResource,
148
- preferTranscoding: !meeting.isMultistream,
149
173
  asResourceOccupant: options.asResourceOccupant,
150
174
  breakoutsSupported: options.breakoutsSupported,
151
175
  locale: options.locale,
152
176
  deviceCapabilities: options.deviceCapabilities,
153
177
  liveAnnotationSupported: options.liveAnnotationSupported,
154
- ipVersion: MeetingUtil.getIpVersion(meeting.getWebexObject()),
178
+ clientMediaPreferences,
155
179
  })
156
180
  .then((res) => {
157
181
  const parsed = MeetingUtil.parseLocusJoin(res);
@@ -177,6 +201,7 @@ const MeetingUtil = {
177
201
 
178
202
  cleanUp: (meeting) => {
179
203
  meeting.getWebexObject().internal.device.meetingEnded();
204
+ meeting.stopPeriodicLogUpload();
180
205
 
181
206
  meeting.breakouts.cleanUp();
182
207
  meeting.simultaneousInterpretation.cleanUp();
@@ -420,6 +445,9 @@ const MeetingUtil = {
420
445
  displayHints.includes(DISPLAY_HINTS.LEAVE_END_MEETING),
421
446
 
422
447
  canManageBreakout: (displayHints) => displayHints.includes(DISPLAY_HINTS.BREAKOUT_MANAGEMENT),
448
+
449
+ canStartBreakout: (displayHints) => !displayHints.includes(DISPLAY_HINTS.DISABLE_BREAKOUT_START),
450
+
423
451
  canBroadcastMessageToBreakout: (displayHints, policies = {}) =>
424
452
  displayHints.includes(DISPLAY_HINTS.BROADCAST_MESSAGE_TO_BREAKOUT) &&
425
453
  !!policies[SELF_POLICY.SUPPORT_BROADCAST_MESSAGE],
@@ -475,15 +503,6 @@ const MeetingUtil = {
475
503
  }
476
504
  },
477
505
 
478
- handleDeviceLogging: (devices = []) => {
479
- const LOG_HEADER = 'MeetingUtil#handleDeviceLogging -->';
480
-
481
- devices.forEach((device) => {
482
- LoggerProxy.logger.log(LOG_HEADER, `deviceId = ${device.deviceId}`);
483
- LoggerProxy.logger.log(LOG_HEADER, 'settings', JSON.stringify(device));
484
- });
485
- },
486
-
487
506
  endMeetingForAll: (meeting) => {
488
507
  if (meeting.meetingState === FULL_STATE.INACTIVE) {
489
508
  return Promise.reject(new MeetingNotActiveError());
@@ -17,8 +17,23 @@ const CAPTCHA_ERROR_DEFAULT_MESSAGE =
17
17
  const ADHOC_MEETING_DEFAULT_ERROR =
18
18
  'Failed starting the adhoc meeting, Please contact support team ';
19
19
  const CAPTCHA_ERROR_REQUIRES_PASSWORD_CODES = [423005, 423006];
20
+ const CAPTCHA_ERROR_REQUIRES_REGISTRATION_ID_CODES = [423007];
21
+
20
22
  const POLICY_ERROR_CODES = [403049, 403104, 403103, 403048, 403102, 403101];
21
- const WEBINAR_REGISTRATION_ERROR_CODES = [403021, 403022, 403024];
23
+ const JOIN_FORBIDDEN_CODES = [403003];
24
+ /**
25
+ * 403021 - Meeting registration is required
26
+ * 403022 - Meeting registration is still pending
27
+ * 403024 - Meeting registration have been rejected
28
+ * 403137 - Registration ID verified failure
29
+ * 423007 - Registration ID input too many time,please input captcha code
30
+ * 403026 - Need to join meeting via webcast
31
+ * 403037 - Meeting join required registration ID
32
+ * 403137 - Registration ID verified failure
33
+ *
34
+ */
35
+ const JOIN_WEBINAR_ERROR_CODES = [403021, 403022, 403024, 403137, 423007, 403026, 403037, 403137];
36
+
22
37
  /**
23
38
  * Error to indicate that wbxappapi requires a password
24
39
  */
@@ -100,6 +115,7 @@ export class MeetingInfoV2PolicyError extends Error {
100
115
  export class MeetingInfoV2CaptchaError extends Error {
101
116
  captchaInfo: any;
102
117
  isPasswordRequired: any;
118
+ isRegistrationIdRequired: any;
103
119
  sdkMessage: any;
104
120
  wbxAppApiCode: any;
105
121
  body: any;
@@ -121,14 +137,41 @@ export class MeetingInfoV2CaptchaError extends Error {
121
137
  this.stack = new Error().stack;
122
138
  this.wbxAppApiCode = wbxAppApiErrorCode;
123
139
  this.isPasswordRequired = CAPTCHA_ERROR_REQUIRES_PASSWORD_CODES.includes(wbxAppApiErrorCode);
140
+ this.isRegistrationIdRequired =
141
+ CAPTCHA_ERROR_REQUIRES_REGISTRATION_ID_CODES.includes(wbxAppApiErrorCode);
124
142
  this.captchaInfo = captchaInfo;
125
143
  }
126
144
  }
127
145
 
128
146
  /**
129
- * Error preventing join because of a webinar registration error
147
+ * Error preventing join because of a webinar have some error
148
+ */
149
+ export class MeetingInfoV2JoinWebinarError extends Error {
150
+ meetingInfo: any;
151
+ sdkMessage: any;
152
+ wbxAppApiCode: any;
153
+ body: any;
154
+ /**
155
+ *
156
+ * @constructor
157
+ * @param {Number} [wbxAppApiErrorCode]
158
+ * @param {Object} [meetingInfo]
159
+ * @param {String} [message]
160
+ */
161
+ constructor(wbxAppApiErrorCode?: number, meetingInfo?: object, message?: string) {
162
+ super(`${message}, code=${wbxAppApiErrorCode}`);
163
+ this.name = 'MeetingInfoV2JoinWebinarError';
164
+ this.sdkMessage = message;
165
+ this.stack = new Error().stack;
166
+ this.wbxAppApiCode = wbxAppApiErrorCode;
167
+ this.meetingInfo = meetingInfo;
168
+ }
169
+ }
170
+
171
+ /**
172
+ * Error preventing join because of a forbidden error
130
173
  */
131
- export class MeetingInfoV2WebinarRegistrationError extends Error {
174
+ export class MeetingInfoV2JoinForbiddenError extends Error {
132
175
  meetingInfo: any;
133
176
  sdkMessage: any;
134
177
  wbxAppApiCode: any;
@@ -142,7 +185,7 @@ export class MeetingInfoV2WebinarRegistrationError extends Error {
142
185
  */
143
186
  constructor(wbxAppApiErrorCode?: number, meetingInfo?: object, message?: string) {
144
187
  super(`${message}, code=${wbxAppApiErrorCode}`);
145
- this.name = 'MeetingInfoV2WebinarRegistrationError';
188
+ this.name = 'MeetingInfoV2JoinForbiddenError';
146
189
  this.sdkMessage = message;
147
190
  this.stack = new Error().stack;
148
191
  this.wbxAppApiCode = wbxAppApiErrorCode;
@@ -204,21 +247,44 @@ export default class MeetingInfoV2 {
204
247
  };
205
248
 
206
249
  /**
207
- * Raises a handleWebinarRegistrationError for webinar registration error codes
250
+ * Raises a handleJoinWebinarError for join webinar error codes
251
+ * @param {any} err the error from the request
252
+ * @returns {void}
253
+ */
254
+ handleJoinWebinarError = (err) => {
255
+ if (!err.body) {
256
+ return;
257
+ }
258
+
259
+ if (JOIN_WEBINAR_ERROR_CODES.includes(err.body?.code)) {
260
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.JOIN_WEBINAR_ERROR, {
261
+ code: err.body?.code,
262
+ });
263
+
264
+ throw new MeetingInfoV2JoinWebinarError(
265
+ err.body?.code,
266
+ err.body?.data?.meetingInfo,
267
+ err.body?.message
268
+ );
269
+ }
270
+ };
271
+
272
+ /**
273
+ * Raises a handleForbiddenError for join meeting forbidden error
208
274
  * @param {any} err the error from the request
209
275
  * @returns {void}
210
276
  */
211
- handleWebinarRegistrationError = (err) => {
277
+ handleForbiddenError = (err) => {
212
278
  if (!err.body) {
213
279
  return;
214
280
  }
215
281
 
216
- if (WEBINAR_REGISTRATION_ERROR_CODES.includes(err.body?.code)) {
217
- Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.WEBINAR_REGISTRATION_ERROR, {
282
+ if (JOIN_FORBIDDEN_CODES.includes(err.body?.code)) {
283
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.JOIN_FORBIDDEN_ERROR, {
218
284
  code: err.body?.code,
219
285
  });
220
286
 
221
- throw new MeetingInfoV2WebinarRegistrationError(
287
+ throw new MeetingInfoV2JoinForbiddenError(
222
288
  err.body?.code,
223
289
  err.body?.data?.meetingInfo,
224
290
  err.body?.message
@@ -286,7 +352,8 @@ export default class MeetingInfoV2 {
286
352
  })
287
353
  .catch((err) => {
288
354
  this.handlePolicyError(err);
289
- this.handleWebinarRegistrationError(err);
355
+ this.handleJoinWebinarError(err);
356
+ this.handleForbiddenError(err);
290
357
 
291
358
  Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ADHOC_MEETING_FAILURE, {
292
359
  reason: err.message,
@@ -308,6 +375,7 @@ export default class MeetingInfoV2 {
308
375
  * @param {String} locusId
309
376
  * @param {Object} extraParams
310
377
  * @param {Object} options
378
+ * @param {String} registrationId
311
379
  * @returns {Promise} returns a meeting info object
312
380
  * @public
313
381
  * @memberof MeetingInfo
@@ -323,7 +391,8 @@ export default class MeetingInfoV2 {
323
391
  installedOrgID = null,
324
392
  locusId = null,
325
393
  extraParams: object = {},
326
- options: {meetingId?: string; sendCAevents?: boolean} = {}
394
+ options: {meetingId?: string; sendCAevents?: boolean} = {},
395
+ registrationId: string = null
327
396
  ) {
328
397
  const {meetingId, sendCAevents} = options;
329
398
 
@@ -348,6 +417,7 @@ export default class MeetingInfoV2 {
348
417
  installedOrgID,
349
418
  locusId,
350
419
  extraParams,
420
+ registrationId,
351
421
  });
352
422
 
353
423
  // If the body only contains the default properties, we don't have enough to
@@ -441,7 +511,8 @@ export default class MeetingInfoV2 {
441
511
 
442
512
  if (err?.statusCode === 403) {
443
513
  this.handlePolicyError(err);
444
- this.handleWebinarRegistrationError(err);
514
+ this.handleJoinWebinarError(err);
515
+ this.handleForbiddenError(err);
445
516
 
446
517
  Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.VERIFY_PASSWORD_ERROR, {
447
518
  reason: err.message,
@@ -19,6 +19,7 @@ import {
19
19
  UUID_REG,
20
20
  VALID_EMAIL_ADDRESS,
21
21
  DEFAULT_MEETING_INFO_REQUEST_BODY,
22
+ JOIN_LINK_MTID,
22
23
  } from '../constants';
23
24
  import ParameterError from '../common/errors/parameter';
24
25
  import LoggerProxy from '../common/logs/logger-proxy';
@@ -70,7 +71,8 @@ export default class MeetingInfoUtil {
70
71
  parsedUrl.pathname.includes(`/${MEET_M}`) ||
71
72
  parsedUrl.pathname.includes(`/${MEET_CISCO}`) ||
72
73
  parsedUrl.pathname.includes(`/${MEET_CO}`) ||
73
- parsedUrl.pathname.includes(`/${JOIN}`));
74
+ parsedUrl.pathname.includes(`/${JOIN}`) ||
75
+ (parsedUrl.search && parsedUrl.search.includes(JOIN_LINK_MTID)));
74
76
  }
75
77
 
76
78
  return hostNameBool && pathNameBool;
@@ -226,8 +228,16 @@ export default class MeetingInfoUtil {
226
228
  * @returns {Object} returns an object with {resource, method}
227
229
  */
228
230
  static getRequestBody(options: {type: DESTINATION_TYPE; destination: object} | any) {
229
- const {type, destination, password, captchaInfo, installedOrgID, locusId, extraParams} =
230
- options;
231
+ const {
232
+ type,
233
+ destination,
234
+ password,
235
+ captchaInfo,
236
+ installedOrgID,
237
+ locusId,
238
+ extraParams,
239
+ registrationId,
240
+ } = options;
231
241
  const body: any = {
232
242
  ...DEFAULT_MEETING_INFO_REQUEST_BODY,
233
243
  ...extraParams,
@@ -269,6 +279,10 @@ export default class MeetingInfoUtil {
269
279
  body.password = password;
270
280
  }
271
281
 
282
+ if (registrationId) {
283
+ body.registrationId = registrationId;
284
+ }
285
+
272
286
  if (captchaInfo) {
273
287
  body.captchaID = captchaInfo.id;
274
288
  body.captchaVerifyCode = captchaInfo.code;