@webex/plugin-meetings 1.146.0 → 1.148.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.
@@ -72,13 +72,7 @@ MeetingUtil.hasOwner = (info) => info && info.owner;
72
72
 
73
73
  MeetingUtil.isOwnerSelf = (owner, selfId) => owner === selfId;
74
74
 
75
- MeetingUtil.isPinOrGuest = (err) => {
76
- if (err && err.body && err.body.errorCode === INTENT_TO_JOIN) {
77
- return true;
78
- }
79
-
80
- return false;
81
- };
75
+ MeetingUtil.isPinOrGuest = (err) => err?.body?.errorCode && INTENT_TO_JOIN.includes(err.body.errorCode);
82
76
 
83
77
  MeetingUtil.joinMeeting = (meeting, options) => {
84
78
  if (!meeting) {
@@ -140,7 +134,7 @@ MeetingUtil.cleanUp = (meeting) => {
140
134
  .then(() => meeting.roap.stop(meeting.correlationId, meeting.roapSeq));
141
135
  };
142
136
 
143
- MeetingUtil.leavePstn = (meeting, dialInUrl) => {
137
+ MeetingUtil.disconnectPhoneAudio = (meeting, phoneUrl) => {
144
138
  if (meeting.meetingState === FULL_STATE.INACTIVE) {
145
139
  return Promise.reject(new MeetingNotActiveError());
146
140
  }
@@ -149,11 +143,11 @@ MeetingUtil.leavePstn = (meeting, dialInUrl) => {
149
143
  locusUrl: meeting.locusUrl,
150
144
  selfId: meeting.selfId,
151
145
  correlationId: meeting.correlationId,
152
- dialInUrl
146
+ phoneUrl
153
147
  };
154
148
 
155
149
  return meeting.meetingRequest
156
- .leavePstn(options)
150
+ .disconnectPhoneAudio(options)
157
151
  .then((response) => {
158
152
  if (response?.body?.locus) {
159
153
  meeting.locusInfo.onFullLocus(response.body.locus);
@@ -161,7 +155,7 @@ MeetingUtil.leavePstn = (meeting, dialInUrl) => {
161
155
  })
162
156
  .catch((err) => {
163
157
  LoggerProxy.logger.error(
164
- `Meeting:util#leavePstn --> An error occured while trying to leave pstn with an id of ${
158
+ `Meeting:util#disconnectPhoneAudio --> An error occured while disconnecting phone audio in meeting ${
165
159
  meeting.id
166
160
  }, error: ${err}`
167
161
  );
@@ -263,14 +257,6 @@ MeetingUtil.joinMeetingOptions = (meeting, options = {}) => {
263
257
  .catch((err) => {
264
258
  // joining a claimed PMR that is not my own, scenario B
265
259
  if (MeetingUtil.isPinOrGuest(err)) {
266
- if (MeetingUtil.hasOwner(meeting.meetingInfo)) {
267
- return MeetingUtil.joinMeeting(meeting, options).then((response) => {
268
- meeting.setLocus(response);
269
-
270
- return Promise.resolve();
271
- });
272
- }
273
-
274
260
  Metrics.postEvent({
275
261
  event: eventType.PIN_PROMPT,
276
262
  meeting
@@ -302,7 +288,8 @@ MeetingUtil.updateTransceiver = (options, meetingOptions) => {
302
288
  return Media.updateTransceiver({
303
289
  meetingId: meetingOptions.meeting.id,
304
290
  remoteQualityLevel: meetingOptions.mediaProperties.remoteQualityLevel,
305
- enableRtx: meetingOptions.meeting.config.enableRtx
291
+ enableRtx: meetingOptions.meeting.config.enableRtx,
292
+ enableExtmap: meetingOptions.meeting.config.enableExtmap
306
293
  }, peerConnection, transceiver,
307
294
  {
308
295
  track,
@@ -175,7 +175,6 @@ class Metrics {
175
175
  eventId: uuid.v4(),
176
176
  version: 1,
177
177
  origin: {
178
- buildType: 'prod',
179
178
  name: 'endpoint',
180
179
  networkType: 'unknown',
181
180
  userAgent: this.userAgentToString(),
@@ -264,7 +263,6 @@ class Metrics {
264
263
  origin: {
265
264
  audioSetupDelay,
266
265
  videoSetupDelay,
267
- buildType: 'prod',
268
266
  name: 'endpoint',
269
267
  networkType: options.networkType || UNKNOWN,
270
268
  userAgent: this.userAgentToString(),
@@ -186,7 +186,6 @@ pc.iceCandidate = (peerConnection, {remoteQualityLevel}) =>
186
186
  const timeout = setTimeout(() => {
187
187
  peerConnection.sdp = limitBandwidth(peerConnection.localDescription.sdp);
188
188
  peerConnection.sdp = setMaxFs(peerConnection.sdp, remoteQualityLevel);
189
- peerConnection.sdp = peerConnection.sdp.replace(/\na=extmap.*/g, '');
190
189
 
191
190
  if (isSdpInvalid(peerConnection.sdp)) {
192
191
  setTimeout(() => {
@@ -214,7 +213,6 @@ pc.iceCandidate = (peerConnection, {remoteQualityLevel}) =>
214
213
  if (!evt.candidate && !peerConnection.sdp) {
215
214
  peerConnection.sdp = limitBandwidth(peerConnection.localDescription.sdp);
216
215
  peerConnection.sdp = setMaxFs(peerConnection.sdp, remoteQualityLevel);
217
- peerConnection.sdp = peerConnection.sdp.replace(/\na=extmap.*/g, '');
218
216
 
219
217
  if (evt.candidate === null && !isSdpInvalid(peerConnection.sdp)) {
220
218
  clearTimeout(timeout);
@@ -292,9 +290,7 @@ pc.addStream = (peerConnection, stream) => {
292
290
  */
293
291
  pc.setRemoteSessionDetails = (peerConnection, typeStr, remoteSdp, meetingId) => {
294
292
  LoggerProxy.logger.log(`PeerConnectionManager:index#setRemoteSessionDetails --> Setting the remote description type: ${typeStr}State: ${peerConnection.signalingState}`);
295
- let sdp = remoteSdp;
296
-
297
- sdp = sdp.replace(/\na=extmap.*/g, '');
293
+ const sdp = remoteSdp;
298
294
 
299
295
  // making sure that the remoteDescription is only set when there is a answer for offer
300
296
  // or there is a offer from the server
@@ -363,9 +359,15 @@ pc.setRemoteSessionDetails = (peerConnection, typeStr, remoteSdp, meetingId) =>
363
359
  * @param {string} meetingProperties.meetingId
364
360
  * @param {string} meetingProperties.remoteQualityLevel LOW|MEDIUM|HIGH
365
361
  * @param {string} meetingProperties.enableRtx
362
+ * @param {string} meetingProperties.enableExtmap
366
363
  * @returns {RTCPeerConnection}
367
364
  */
368
- pc.createOffer = (peerConnection, {meetingId, remoteQualityLevel, enableRtx}) => {
365
+ pc.createOffer = (peerConnection, {
366
+ meetingId,
367
+ remoteQualityLevel,
368
+ enableRtx,
369
+ enableExtmap
370
+ }) => {
369
371
  LoggerProxy.logger.log('PeerConnectionManager:index#createOffer --> creating a new offer');
370
372
 
371
373
  return peerConnection
@@ -389,7 +391,11 @@ pc.createOffer = (peerConnection, {meetingId, remoteQualityLevel, enableRtx}) =>
389
391
  if (!checkH264Support(peerConnection.sdp)) {
390
392
  throw new MediaError('openH264 is downloading please Wait. Upload logs if not working on second try');
391
393
  }
392
- peerConnection.sdp = peerConnection.sdp.replace(/\na=extmap.*/g, '');
394
+
395
+ if (!enableExtmap) {
396
+ peerConnection.sdp = peerConnection.sdp.replace(/\na=extmap.*/g, '');
397
+ }
398
+
393
399
  pc.setContentSlides(peerConnection);
394
400
 
395
401
  Metrics.postEvent({
@@ -512,8 +518,6 @@ pc.createAnswer = (params, {meetingId, remoteQualityLevel}) => {
512
518
  throw new MediaError('openH264 is downloading please Wait. Upload logs if not working on second try');
513
519
  }
514
520
 
515
- peerConnection.sdp = peerConnection.sdp.replace(/\na=extmap.*/g, '');
516
-
517
521
  return peerConnection;
518
522
  })
519
523
  .catch((error) => {
@@ -459,7 +459,8 @@ export default class ReconnectionManager {
459
459
  return Media.attachMedia(this.meeting.mediaProperties, {
460
460
  meetingId: this.meeting.id,
461
461
  remoteQualityLevel: this.meeting.mediaProperties.remoteQualityLevel,
462
- enableRtx: this.meeting.config.enableRtx
462
+ enableRtx: this.meeting.config.enableRtx,
463
+ enableExtmap: this.meeting.config.enableExtmap
463
464
  })
464
465
  .then((peerConnection) => this.meeting.setRemoteStream(peerConnection))
465
466
  .then(() => {
@@ -1902,7 +1902,9 @@ describe('plugin-meetings', () => {
1902
1902
 
1903
1903
  describe('#usePhoneAudio', () => {
1904
1904
  beforeEach(() => {
1905
- meeting.meetingRequest.dialIn = sinon.stub().returns(Promise.resolve());
1905
+ meeting.meetingRequest.dialIn = sinon.stub().returns(Promise.resolve({body: {locus: 'testData'}}));
1906
+ meeting.meetingRequest.dialOut = sinon.stub().returns(Promise.resolve({body: {locus: 'testData'}}));
1907
+ meeting.locusInfo.onFullLocus = sinon.stub().returns(Promise.resolve());
1906
1908
  });
1907
1909
 
1908
1910
  it('with no parameters triggers dial-in, delegating request to meetingRequest correctly', async () => {
@@ -1915,8 +1917,11 @@ describe('plugin-meetings', () => {
1915
1917
  locusUrl: meeting.locusUrl,
1916
1918
  clientUrl: meeting.deviceUrl
1917
1919
  });
1920
+ assert.calledWith(meeting.locusInfo.onFullLocus, 'testData');
1921
+ assert.notCalled(meeting.meetingRequest.dialOut);
1918
1922
 
1919
1923
  meeting.meetingRequest.dialIn.resetHistory();
1924
+ meeting.locusInfo.onFullLocus.resetHistory();
1920
1925
 
1921
1926
  // try again. the dial in urls should match
1922
1927
  await meeting.usePhoneAudio();
@@ -1927,6 +1932,65 @@ describe('plugin-meetings', () => {
1927
1932
  locusUrl: meeting.locusUrl,
1928
1933
  clientUrl: meeting.deviceUrl
1929
1934
  });
1935
+ assert.calledWith(meeting.locusInfo.onFullLocus, 'testData');
1936
+ assert.notCalled(meeting.meetingRequest.dialOut);
1937
+ });
1938
+
1939
+ it('given a phone number, triggers dial-out, delegating request to meetingRequest correctly', async () => {
1940
+ const phoneNumber = '+442088241000';
1941
+
1942
+ await meeting.usePhoneAudio(phoneNumber);
1943
+ const DIAL_OUT_URL = meeting.dialOutUrl;
1944
+
1945
+ assert.calledWith(meeting.meetingRequest.dialOut, {
1946
+ correlationId: meeting.correlationId,
1947
+ dialOutUrl: DIAL_OUT_URL,
1948
+ locusUrl: meeting.locusUrl,
1949
+ clientUrl: meeting.deviceUrl,
1950
+ phoneNumber
1951
+ });
1952
+ assert.calledWith(meeting.locusInfo.onFullLocus, 'testData');
1953
+ assert.notCalled(meeting.meetingRequest.dialIn);
1954
+
1955
+ meeting.meetingRequest.dialOut.resetHistory();
1956
+ meeting.locusInfo.onFullLocus.resetHistory();
1957
+
1958
+ // try again. the dial out urls should match
1959
+ await meeting.usePhoneAudio(phoneNumber);
1960
+
1961
+ assert.calledWith(meeting.meetingRequest.dialOut, {
1962
+ correlationId: meeting.correlationId,
1963
+ dialOutUrl: DIAL_OUT_URL,
1964
+ locusUrl: meeting.locusUrl,
1965
+ clientUrl: meeting.deviceUrl,
1966
+ phoneNumber
1967
+ });
1968
+ assert.calledWith(meeting.locusInfo.onFullLocus, 'testData');
1969
+ assert.notCalled(meeting.meetingRequest.dialIn);
1970
+ });
1971
+
1972
+ it('rejects if the request failed (dial in)', () => {
1973
+ const error = 'something bad happened';
1974
+
1975
+ meeting.meetingRequest.dialIn = sinon.stub().returns(Promise.reject(error));
1976
+
1977
+ return meeting.usePhoneAudio().then(() => Promise.reject(new Error('Promise resolved when it should have rejected'))).catch((e) => {
1978
+ assert.equal(e, error);
1979
+
1980
+ return Promise.resolve();
1981
+ });
1982
+ });
1983
+
1984
+ it('rejects if the request failed (dial out)', async () => {
1985
+ const error = 'something bad happened';
1986
+
1987
+ meeting.meetingRequest.dialOut = sinon.stub().returns(Promise.reject(error));
1988
+
1989
+ return meeting.usePhoneAudio('+441234567890').then(() => Promise.reject(new Error('Promise resolved when it should have rejected'))).catch((e) => {
1990
+ assert.equal(e, error);
1991
+
1992
+ return Promise.resolve();
1993
+ });
1930
1994
  });
1931
1995
  });
1932
1996
 
@@ -152,23 +152,48 @@ describe('plugin-meetings', () => {
152
152
  assert.equal(requestParams.body.device.clientUrl, 'clientUrl');
153
153
  });
154
154
 
155
- it('sends leave pstn request', async () => {
155
+ it('sends dial out pstn request', async () => {
156
+ const locusUrl = 'locusUrl';
157
+ const clientUrl = 'clientUrl';
158
+ const correlationId = 'random-uuid';
159
+ const dialOutUrl = 'url';
160
+ const phoneNumber = '+442088241000';
161
+
162
+ await meetingsRequest.dialOut({
163
+ locusUrl,
164
+ clientUrl,
165
+ correlationId,
166
+ dialOutUrl,
167
+ phoneNumber
168
+ });
169
+ const requestParams = meetingsRequest.request.getCall(0).args[0];
170
+
171
+ assert.equal(requestParams.method, 'POST');
172
+ assert.equal(requestParams.uri, `${locusUrl}/participant`);
173
+ assert.equal(requestParams.body.device.url, dialOutUrl);
174
+ assert.equal(requestParams.body.device.deviceType, 'PROVISIONAL');
175
+ assert.equal(requestParams.body.device.provisionalType, 'DIAL_OUT');
176
+ assert.equal(requestParams.body.device.clientUrl, 'clientUrl');
177
+ assert.equal(requestParams.body.device.dialoutAddress, phoneNumber);
178
+ });
179
+
180
+ it('sends disconnect phone audio request', async () => {
156
181
  const locusUrl = 'locusUrl';
157
182
  const selfId = 'selfId';
158
183
  const correlationId = 'random-uuid';
159
- const dialInUrl = 'url';
184
+ const phoneUrl = 'url';
160
185
 
161
- await meetingsRequest.leavePstn({
186
+ await meetingsRequest.disconnectPhoneAudio({
162
187
  locusUrl,
163
188
  selfId,
164
189
  correlationId,
165
- dialInUrl
190
+ phoneUrl
166
191
  });
167
192
  const requestParams = meetingsRequest.request.getCall(0).args[0];
168
193
 
169
194
  assert.equal(requestParams.method, 'PUT');
170
195
  assert.equal(requestParams.uri, `${locusUrl}/participant/${selfId}/leave`);
171
- assert.equal(requestParams.body.device.url, dialInUrl);
196
+ assert.equal(requestParams.body.device.url, phoneUrl);
172
197
  assert.equal(requestParams.body.device.deviceType, 'PROVISIONAL');
173
198
  });
174
199
  });