@wazo/sdk 0.38.6 → 0.38.9

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 (118) hide show
  1. package/dist/wazo-sdk.js +2 -2
  2. package/esm/__tests__/api-client.test.js +142 -2
  3. package/esm/__tests__/web-rtc-client.test.js +249 -28
  4. package/esm/api/calld.js +8 -0
  5. package/esm/api/confd.js +134 -2
  6. package/esm/api-client.js +142 -2
  7. package/esm/checker/Checker.js +205 -25
  8. package/esm/checker/checks/aor.js +142 -2
  9. package/esm/checker/checks/api.js +142 -2
  10. package/esm/checker/checks/index.js +205 -25
  11. package/esm/checker/checks/wazo-websocket.js +2 -0
  12. package/esm/checker/checks/webrtc-transport.js +203 -25
  13. package/esm/checker/checks/webrtc.js +203 -25
  14. package/esm/domain/AdHocAPIConference.js +142 -2
  15. package/esm/domain/Features.js +142 -2
  16. package/esm/domain/Meeting.js +18 -0
  17. package/esm/domain/MeetingAuthorization.js +70 -0
  18. package/esm/domain/Phone/CTIPhone.js +142 -2
  19. package/esm/domain/Phone/WebRTCPhone.js +1 -3
  20. package/esm/domain/__tests__/Meeting.test.js +87 -1
  21. package/esm/domain/__tests__/MeetingAuthorization.test.js +109 -0
  22. package/esm/index.js +249 -31
  23. package/esm/lib/WazoSessionDescriptionHandler.js +22 -1
  24. package/esm/service/CallApi.js +142 -2
  25. package/esm/service/getApiClient.js +142 -2
  26. package/esm/simple/Auth.js +249 -31
  27. package/esm/simple/Configuration.js +249 -31
  28. package/esm/simple/Directory.js +142 -2
  29. package/esm/simple/Phone.js +249 -31
  30. package/esm/simple/Websocket.js +3 -0
  31. package/esm/simple/index.js +249 -31
  32. package/esm/simple/room/LocalParticipant.js +249 -31
  33. package/esm/simple/room/Participant.js +249 -31
  34. package/esm/simple/room/RemoteParticipant.js +249 -31
  35. package/esm/simple/room/Room.js +249 -31
  36. package/esm/simple/room/SipRoom.js +249 -31
  37. package/esm/simple/room/Stream.js +249 -31
  38. package/esm/simple/room/__tests__/Participant.test.js +14745 -0
  39. package/esm/simple/room/__tests__/RemoteParticipant.test.js +249 -31
  40. package/esm/simple/utils.js +249 -31
  41. package/esm/utils/__tests__/object.test.js +57 -0
  42. package/esm/utils/__tests__/sdp.test.js +50 -0
  43. package/esm/utils/__tests__/string.test.js +30 -0
  44. package/esm/utils/object.js +24 -0
  45. package/esm/utils/sdp.js +19 -1
  46. package/esm/utils/string.js +10 -0
  47. package/esm/web-rtc-client.js +203 -25
  48. package/esm/websocket-client.js +3 -1
  49. package/lib/__tests__/api-client.test.js +142 -2
  50. package/lib/__tests__/web-rtc-client.test.js +249 -28
  51. package/lib/api/calld.js +8 -0
  52. package/lib/api/confd.js +134 -2
  53. package/lib/api-client.js +142 -2
  54. package/lib/checker/Checker.js +205 -25
  55. package/lib/checker/checks/aor.js +142 -2
  56. package/lib/checker/checks/api.js +142 -2
  57. package/lib/checker/checks/index.js +205 -25
  58. package/lib/checker/checks/wazo-websocket.js +2 -0
  59. package/lib/checker/checks/webrtc-transport.js +203 -25
  60. package/lib/checker/checks/webrtc.js +203 -25
  61. package/lib/domain/AdHocAPIConference.js +142 -2
  62. package/lib/domain/Features.js +142 -2
  63. package/lib/domain/Meeting.js +18 -0
  64. package/lib/domain/MeetingAuthorization.js +79 -0
  65. package/lib/domain/Phone/CTIPhone.js +142 -2
  66. package/lib/domain/Phone/WebRTCPhone.js +1 -3
  67. package/lib/domain/__tests__/Meeting.test.js +87 -1
  68. package/lib/domain/__tests__/MeetingAuthorization.test.js +111 -0
  69. package/lib/index.js +249 -31
  70. package/lib/lib/WazoSessionDescriptionHandler.js +22 -1
  71. package/lib/service/CallApi.js +142 -2
  72. package/lib/service/getApiClient.js +142 -2
  73. package/lib/simple/Auth.js +249 -31
  74. package/lib/simple/Configuration.js +249 -31
  75. package/lib/simple/Directory.js +142 -2
  76. package/lib/simple/Phone.js +249 -31
  77. package/lib/simple/Websocket.js +3 -0
  78. package/lib/simple/index.js +249 -31
  79. package/lib/simple/room/LocalParticipant.js +249 -31
  80. package/lib/simple/room/Participant.js +249 -31
  81. package/lib/simple/room/RemoteParticipant.js +249 -31
  82. package/lib/simple/room/Room.js +249 -31
  83. package/lib/simple/room/SipRoom.js +249 -31
  84. package/lib/simple/room/Stream.js +249 -31
  85. package/lib/simple/room/__tests__/Participant.test.js +14755 -0
  86. package/lib/simple/room/__tests__/RemoteParticipant.test.js +249 -31
  87. package/lib/simple/utils.js +249 -31
  88. package/lib/utils/__tests__/object.test.js +59 -0
  89. package/lib/utils/__tests__/sdp.test.js +50 -0
  90. package/lib/utils/__tests__/string.test.js +32 -0
  91. package/lib/utils/object.js +28 -0
  92. package/lib/utils/sdp.js +19 -0
  93. package/lib/utils/string.js +14 -0
  94. package/lib/web-rtc-client.js +203 -25
  95. package/lib/websocket-client.js +3 -0
  96. package/package.json +2 -2
  97. package/src/__tests__/web-rtc-client.test.js +46 -3
  98. package/src/api/calld.js +8 -0
  99. package/src/api/confd.js +43 -2
  100. package/src/domain/Meeting.js +20 -0
  101. package/src/domain/MeetingAuthorization.js +67 -0
  102. package/src/domain/Phone/WebRTCPhone.js +1 -3
  103. package/src/domain/__tests__/Meeting.test.js +70 -1
  104. package/src/domain/__tests__/MeetingAuthorization.test.js +58 -0
  105. package/src/lib/WazoSessionDescriptionHandler.js +5 -2
  106. package/src/simple/room/Participant.js +40 -0
  107. package/src/simple/room/Room.js +2 -2
  108. package/src/simple/room/SipRoom.js +1 -1
  109. package/src/simple/room/__tests__/Participant.test.js +81 -0
  110. package/src/types/WebSocketMessage.js +7 -1
  111. package/src/utils/__tests__/object.test.js +35 -0
  112. package/src/utils/__tests__/sdp.test.js +33 -1
  113. package/src/utils/__tests__/string.test.js +23 -0
  114. package/src/utils/object.js +15 -0
  115. package/src/utils/sdp.js +18 -0
  116. package/src/utils/string.js +8 -0
  117. package/src/web-rtc-client.js +39 -22
  118. package/src/websocket-client.js +2 -0
package/esm/index.js CHANGED
@@ -2646,6 +2646,70 @@ class ExternalApp {
2646
2646
 
2647
2647
  //
2648
2648
 
2649
+ class MeetingAuthorization {
2650
+
2651
+
2652
+
2653
+
2654
+
2655
+
2656
+ constructor({
2657
+ meetingUuid,
2658
+ uuid,
2659
+ userUuid,
2660
+ userName,
2661
+ } = {}) {
2662
+ this.meetingUuid = meetingUuid;
2663
+ this.uuid = uuid;
2664
+ this.userUuid = userUuid;
2665
+ this.userName = userName;
2666
+ }
2667
+
2668
+ setStatus(status ) {
2669
+ this.status = status;
2670
+ }
2671
+
2672
+ getStatus() {
2673
+ return this.status;
2674
+ }
2675
+
2676
+ static parse(plain ) {
2677
+ const {
2678
+ meeting_uuid: meetingUuid,
2679
+ uuid,
2680
+ guest_uuid: userUuid,
2681
+ guest_name: userName,
2682
+ } = plain;
2683
+
2684
+ return new MeetingAuthorization({
2685
+ meetingUuid,
2686
+ uuid,
2687
+ userUuid,
2688
+ userName,
2689
+ });
2690
+ }
2691
+
2692
+ static parseMany(items ) {
2693
+ if (!items) {
2694
+ return [];
2695
+ }
2696
+ return items.map(MeetingAuthorization.parse);
2697
+ }
2698
+ }
2699
+
2700
+ //
2701
+
2702
+
2703
+
2704
+
2705
+
2706
+
2707
+
2708
+
2709
+
2710
+
2711
+
2712
+
2649
2713
 
2650
2714
 
2651
2715
 
@@ -2656,6 +2720,7 @@ class ExternalApp {
2656
2720
 
2657
2721
 
2658
2722
 
2723
+
2659
2724
 
2660
2725
 
2661
2726
  class Meeting {
@@ -2670,6 +2735,8 @@ class Meeting {
2670
2735
 
2671
2736
 
2672
2737
 
2738
+
2739
+
2673
2740
 
2674
2741
  static parse(plain ) {
2675
2742
  return new Meeting({
@@ -2682,6 +2749,7 @@ class Meeting {
2682
2749
  extension: plain.exten,
2683
2750
  persistent: plain.persistent,
2684
2751
  creationTime: moment(plain.creation_time).toDate(),
2752
+ requireAuthorization: plain.require_authorization,
2685
2753
  });
2686
2754
  }
2687
2755
 
@@ -2706,6 +2774,7 @@ class Meeting {
2706
2774
  extension,
2707
2775
  persistent,
2708
2776
  creationTime,
2777
+ requireAuthorization,
2709
2778
  } = {}) {
2710
2779
  this.guestSipAuthorization = guestSipAuthorization;
2711
2780
  this.uri = uri;
@@ -2716,6 +2785,7 @@ class Meeting {
2716
2785
  this.extension = extension;
2717
2786
  this.persistent = persistent;
2718
2787
  this.creationTime = creationTime;
2788
+ this.requireAuthorization = requireAuthorization;
2719
2789
 
2720
2790
  // Useful to compare instead of instanceof with minified code
2721
2791
  this.type = 'Meeting';
@@ -2726,8 +2796,32 @@ class Meeting {
2726
2796
  const [username, secret] = atob(this.guestSipAuthorization).split(':');
2727
2797
  return { username, secret };
2728
2798
  }
2799
+
2729
2800
  }
2730
2801
 
2802
+ //
2803
+
2804
+ const camelToUnderscore = (key ) => {
2805
+ if (typeof key !== 'string') {
2806
+ throw new Error('Input is not a string');
2807
+ }
2808
+ return key.charAt(0).toLowerCase() + key.substring(1).replace(/([A-Z])/g, '_$1').toLowerCase();
2809
+ };
2810
+
2811
+ //
2812
+
2813
+ const convertKeysFromCamelToUnderscore = (args ) => {
2814
+ if (!args || typeof args !== 'object' || Array.isArray(args)) {
2815
+ throw new Error('Input is not an object');
2816
+ }
2817
+
2818
+ return Object.keys(args).reduce((acc, key) => {
2819
+ acc[camelToUnderscore(key)] = typeof args[key] === 'object' && !Array.isArray(args[key])
2820
+ ? convertKeysFromCamelToUnderscore(args[key]) : args[key];
2821
+ return acc;
2822
+ }, {});
2823
+ };
2824
+
2731
2825
  /* */
2732
2826
 
2733
2827
  var confdMethods = (client , baseUrl ) => ({
@@ -2796,8 +2890,18 @@ var confdMethods = (client , baseUrl ) => ({
2796
2890
  getMyMeetings: () =>
2797
2891
  client.get(`${baseUrl}/users/me/meetings`).then(response => Meeting.parseMany(response.items)),
2798
2892
 
2799
- createMyMeeting: (name , persistent ) =>
2800
- client.post(`${baseUrl}/users/me/meetings`, { name, persistent }).then(Meeting.parse),
2893
+ createMyMeeting: (args ) =>
2894
+ client
2895
+ .post(`${baseUrl}/users/me/meetings`, convertKeysFromCamelToUnderscore(args))
2896
+ .then(Meeting.parse),
2897
+
2898
+ updateMyMeeting: (meetingUuid , data ) =>
2899
+ client.put(
2900
+ `${baseUrl}/users/me/meetings/${meetingUuid}`,
2901
+ convertKeysFromCamelToUnderscore(data),
2902
+ null,
2903
+ ApiRequester.successResponseParser,
2904
+ ),
2801
2905
 
2802
2906
  deleteMyMeeting: (meetingUuid ) =>
2803
2907
  client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
@@ -2805,8 +2909,36 @@ var confdMethods = (client , baseUrl ) => ({
2805
2909
  getMeeting: (meetingUuid ) =>
2806
2910
  client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
2807
2911
 
2912
+ meetingAuthorizations: (meetingUuid ) =>
2913
+ client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/authorizations`, null).then(MeetingAuthorization.parseMany),
2914
+
2915
+ meetingAuthorizationReject: (meetingUuid , authorizationUuid ) =>
2916
+ client.put(
2917
+ `${baseUrl}/users/me/meetings/${meetingUuid}/authorizations/${authorizationUuid}/reject`,
2918
+ {},
2919
+ null,
2920
+ ApiRequester.successResponseParser,
2921
+ ),
2922
+
2923
+ meetingAuthorizationAccept: (meetingUuid , authorizationUuid ) =>
2924
+ client.put(
2925
+ `${baseUrl}/users/me/meetings/${meetingUuid}/authorizations/${authorizationUuid}/accept`,
2926
+ {},
2927
+ null,
2928
+ ApiRequester.successResponseParser,
2929
+ ),
2930
+
2808
2931
  guestGetMeeting: (meetingUuid ) =>
2809
2932
  client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
2933
+
2934
+ guestAuthorizationRequest: (userUuid , meetingUuid , username ) =>
2935
+ client
2936
+ .post(`${baseUrl}/guests/${userUuid}/meetings/${meetingUuid}/authorizations`, { guest_name: username })
2937
+ .then(MeetingAuthorization.parse),
2938
+
2939
+ guestAuthorizationCheck: (userUuid , meetingUuid , authorizationUuid ) =>
2940
+ client.get(`${baseUrl}/guests/${userUuid}/meetings/${meetingUuid}/authorizations/${authorizationUuid}`, null),
2941
+
2810
2942
  });
2811
2943
 
2812
2944
  //
@@ -5158,6 +5290,14 @@ var calldMethods = (client , baseUrl ) => ({
5158
5290
  getMeetingParticipantsAsUser: async (meetingUuid ) =>
5159
5291
  client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
5160
5292
 
5293
+ banMeetingParticipant: (meetingUuid , participantUuid ) =>
5294
+ client.delete(
5295
+ `${baseUrl}/users/me/meetings/${meetingUuid}/participants/${participantUuid}`,
5296
+ null,
5297
+ null,
5298
+ ApiRequester.successResponseParser,
5299
+ ),
5300
+
5161
5301
  listTrunks: () => client.get(`${baseUrl}/trunks`),
5162
5302
 
5163
5303
  mute: (callId ) =>
@@ -5725,6 +5865,24 @@ const fixSdp = (sdp , candidates , forcePort = true)
5725
5865
  return fixed;
5726
5866
  };
5727
5867
 
5868
+ const addIcesInAllBundles = (sdp ) => {
5869
+ const parsedSdp = sdpParser.parse(sdp);
5870
+
5871
+ const mediaWithCandidate = parsedSdp.media.find(media => !!media.candidates);
5872
+ if (!mediaWithCandidate) {
5873
+ return sdp;
5874
+ }
5875
+
5876
+ const { candidates } = mediaWithCandidate;
5877
+
5878
+ parsedSdp.media = parsedSdp.media.map(media => ({
5879
+ ...media,
5880
+ candidates: media.candidates || candidates,
5881
+ }));
5882
+
5883
+ return sdpParser.write(parsedSdp);
5884
+ };
5885
+
5728
5886
  /* global RTCSessionDescriptionInit, navigator */
5729
5887
 
5730
5888
  const wazoLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-sdh') : console;
@@ -5854,7 +6012,10 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5854
6012
 
5855
6013
  // Check if we got ICEs
5856
6014
  if (sdp.indexOf('a=candidate') !== -1) {
5857
- return description;
6015
+ return {
6016
+ type: description.type,
6017
+ sdp: addIcesInAllBundles(sdp),
6018
+ };
5858
6019
  }
5859
6020
 
5860
6021
  wazoLogger.info('No ICE candidates found in SDP, fixing it with gathered ices', this.gatheredCandidates);
@@ -7314,7 +7475,7 @@ class WebRTCClient extends Emitter {
7314
7475
  });
7315
7476
  }
7316
7477
 
7317
- changeAudioInputDevice(id , session , force ) {
7478
+ async changeAudioInputDevice(id , session , force ) {
7318
7479
  const currentId = this.getAudioDeviceId();
7319
7480
  logger$9.info('setting audio input device', { id, currentId, session: !!session });
7320
7481
 
@@ -7322,33 +7483,50 @@ class WebRTCClient extends Emitter {
7322
7483
  return null;
7323
7484
  }
7324
7485
 
7486
+ // in order to handle an audio track change for default devices
7487
+ // we need the actual id of the device (not 'default')
7488
+ let deviceId = id;
7489
+ if (id === 'default' && navigator.mediaDevices) {
7490
+ const devices = await navigator.mediaDevices.enumerateDevices();
7491
+ const defaultDevice = devices.find(device => device.deviceId === 'default');
7492
+ if (defaultDevice) {
7493
+ const deviceLabel = defaultDevice.label.replace('Default - ', '');
7494
+ const targetDevice = devices.find(device => device.label === deviceLabel);
7495
+ if (targetDevice) {
7496
+ deviceId = targetDevice.deviceId;
7497
+ if (!force && deviceId === currentId) {
7498
+ return null;
7499
+ }
7500
+ }
7501
+ }
7502
+ }
7503
+
7325
7504
  // let's update the local audio value
7326
7505
  if (this.audio) {
7327
7506
  this.audio = {
7328
7507
  deviceId: {
7329
- exact: id,
7508
+ exact: deviceId,
7330
7509
  },
7331
7510
  };
7332
7511
  }
7333
7512
 
7334
- if (session) {
7513
+ if (session && navigator.mediaDevices) {
7335
7514
  const sdh = session.sessionDescriptionHandler;
7336
7515
  const pc = sdh.peerConnection;
7337
7516
 
7338
- // $FlowFixMe
7339
- return navigator.mediaDevices.getUserMedia({ audio: { deviceId: { exact: id } } }).then(async stream => {
7340
- const audioTrack = stream.getAudioTracks()[0];
7341
- const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
7517
+ const constraints = { audio: { deviceId: { exact: deviceId } } };
7518
+ const stream = await navigator.mediaDevices.getUserMedia(constraints);
7519
+ const audioTrack = stream.getAudioTracks()[0];
7520
+ const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
7342
7521
 
7343
- if (sender) {
7344
- if (sender.track) {
7345
- audioTrack.enabled = sender.track.enabled;
7346
- }
7347
- sender.replaceTrack(audioTrack);
7522
+ if (sender) {
7523
+ if (sender.track) {
7524
+ audioTrack.enabled = sender.track.enabled;
7348
7525
  }
7526
+ sender.replaceTrack(audioTrack);
7527
+ }
7349
7528
 
7350
- return stream;
7351
- });
7529
+ return stream;
7352
7530
  }
7353
7531
  }
7354
7532
 
@@ -7368,14 +7546,14 @@ class WebRTCClient extends Emitter {
7368
7546
  return null;
7369
7547
  }
7370
7548
 
7371
- // let's update the local video value
7372
- if (this.video) {
7373
- this.video = {
7374
- deviceId: {
7375
- exact: id,
7376
- },
7377
- };
7378
- }
7549
+ // let's make sure we don't lose other video constraints settings -- width, height, frameRate...
7550
+ const videoObject = typeof this.video === 'object' ? this.video : {};
7551
+ this.video = {
7552
+ ...videoObject,
7553
+ deviceId: {
7554
+ exact: id,
7555
+ },
7556
+ };
7379
7557
  }
7380
7558
 
7381
7559
  changeSessionVideoInputDevice(id , session ) {
@@ -8548,6 +8726,7 @@ const AGENT_UNPAUSED = 'agent_unpaused';
8548
8726
  const CONFERENCE_ADHOC_PARTICIPANT_LEFT = 'conference_adhoc_participant_left';
8549
8727
  const CONFERENCE_ADHOC_DELETED = 'conference_adhoc_deleted';
8550
8728
  const MEETING_USER_PROGRESS = 'meeting_user_progress';
8729
+ const MEETING_USER_GUEST_AUTHORIZATION_CREATED = 'meeting_user_guest_authorization_created';
8551
8730
 
8552
8731
  const BLACKLIST_EVENTS = [
8553
8732
  CHAT_MESSAGE_SENT,
@@ -8899,6 +9078,7 @@ WebSocketClient.eventLists = [
8899
9078
  CONFERENCE_ADHOC_PARTICIPANT_LEFT,
8900
9079
  CONFERENCE_ADHOC_DELETED,
8901
9080
  MEETING_USER_PROGRESS,
9081
+ MEETING_USER_GUEST_AUTHORIZATION_CREATED,
8902
9082
  ];
8903
9083
 
8904
9084
  var WebSocketClient$1 = /*#__PURE__*/Object.freeze({
@@ -8970,6 +9150,7 @@ var WebSocketClient$1 = /*#__PURE__*/Object.freeze({
8970
9150
  CONFERENCE_ADHOC_PARTICIPANT_LEFT: CONFERENCE_ADHOC_PARTICIPANT_LEFT,
8971
9151
  CONFERENCE_ADHOC_DELETED: CONFERENCE_ADHOC_DELETED,
8972
9152
  MEETING_USER_PROGRESS: MEETING_USER_PROGRESS,
9153
+ MEETING_USER_GUEST_AUTHORIZATION_CREATED: MEETING_USER_GUEST_AUTHORIZATION_CREATED,
8973
9154
  HEARTBEAT_ENGINE_VERSION: HEARTBEAT_ENGINE_VERSION,
8974
9155
  'default': WebSocketClient
8975
9156
  });
@@ -9878,9 +10059,7 @@ class WebRTCPhone extends Emitter {
9878
10059
 
9879
10060
  try {
9880
10061
  if (this.currentScreenShare.stream) {
9881
- this.currentScreenShare.stream.getTracks()
9882
- .filter(track => track.kind === 'video')
9883
- .forEach(track => track.stop());
10062
+ this.currentScreenShare.stream.getTracks().forEach(track => track.stop());
9884
10063
  }
9885
10064
 
9886
10065
  if (restoreLocalStream) {
@@ -12750,6 +12929,7 @@ class Participant extends Emitter {
12750
12929
 
12751
12930
 
12752
12931
 
12932
+
12753
12933
 
12754
12934
 
12755
12935
 
@@ -12767,6 +12947,7 @@ class Participant extends Emitter {
12767
12947
 
12768
12948
 
12769
12949
 
12950
+
12770
12951
 
12771
12952
  /**
12772
12953
  * @param room Room The room where the participant is
@@ -12790,6 +12971,7 @@ class Participant extends Emitter {
12790
12971
  this.screensharing = false;
12791
12972
  this.isOnHold = false;
12792
12973
  this.extra = extra;
12974
+ this.banned = false;
12793
12975
 
12794
12976
  this.ON_UPDATED = 'participant/ON_UPDATED';
12795
12977
  this.ON_START_TALKING = 'participant/ON_START_TALKING';
@@ -12806,6 +12988,7 @@ class Participant extends Emitter {
12806
12988
  this.ON_EXTRA_CHANGE = 'participant/ON_EXTRA_CHANGE';
12807
12989
  this.ON_HOLD = 'participant/ON_HOLD';
12808
12990
  this.ON_RESUME = 'participant/ON_RESUME';
12991
+ this.ON_BAN = 'participant/ON_BAN';
12809
12992
  }
12810
12993
 
12811
12994
  triggerEvent(name , ...args ) {
@@ -12846,6 +13029,10 @@ class Participant extends Emitter {
12846
13029
  status.extra = this.extra;
12847
13030
  break;
12848
13031
  }
13032
+ case this.ON_BAN: {
13033
+ status.banned = true;
13034
+ break;
13035
+ }
12849
13036
  }
12850
13037
 
12851
13038
  if (broadcast) {
@@ -12948,6 +13135,11 @@ class Participant extends Emitter {
12948
13135
  this.triggerUpdate(this.ON_RESUME, broadcast);
12949
13136
  }
12950
13137
 
13138
+ onBan(broadcast = true) {
13139
+ this.banned = true;
13140
+ this.triggerUpdate(this.ON_BAN, broadcast);
13141
+ }
13142
+
12951
13143
  getStatus() {
12952
13144
  return {
12953
13145
  callId: this.callId,
@@ -12994,6 +13186,10 @@ class Participant extends Emitter {
12994
13186
  }
12995
13187
  }
12996
13188
 
13189
+ if (status.banned) {
13190
+ this.onBan(false);
13191
+ }
13192
+
12997
13193
  // Poor man's object comparison
12998
13194
  if (typeof status.extra !== 'undefined' && JSON.stringify(this.extra) !== JSON.stringify(status.extra)) {
12999
13195
  this.extra = { ...this.extra, ...status.extra };
@@ -13021,6 +13217,28 @@ class Participant extends Emitter {
13021
13217
  this.streams = streams;
13022
13218
  this.videoStreams = streams;
13023
13219
  }
13220
+
13221
+ async ban(apiRequestDelay = null) {
13222
+ const { meetingUuid } = this.room;
13223
+ if (!meetingUuid) {
13224
+ throw new Error('Attempting to ban a participant without a `meetingUuid`');
13225
+ }
13226
+
13227
+ // this notifies all that someone is being banned
13228
+ this.onBan(true);
13229
+
13230
+ // this allows to delay the actual ban, in order for the banned participant as well as others to react to the situation
13231
+ if (apiRequestDelay) {
13232
+ await this.delay(apiRequestDelay);
13233
+ }
13234
+
13235
+ // proceed with the actual kick
13236
+ return getApiClient().calld.banMeetingParticipant(meetingUuid, this.callId);
13237
+ }
13238
+
13239
+ async delay(ms ) {
13240
+ return new Promise(resolve => setTimeout(resolve, ms));
13241
+ }
13024
13242
  }
13025
13243
 
13026
13244
  //
@@ -13173,7 +13391,7 @@ class Room extends Emitter {
13173
13391
  logger$1.info('connecting to room', { extension, audioOnly, room: !!room });
13174
13392
 
13175
13393
  if (!room) {
13176
- await Wazo.Phone.connect();
13394
+ await Wazo.Phone.connect({ media: constraints });
13177
13395
 
13178
13396
  const withCamera = constraints && !!constraints.video;
13179
13397
 
@@ -13618,7 +13836,7 @@ class Room extends Emitter {
13618
13836
  const participant = this._getParticipantFromCallId(status.callId);
13619
13837
 
13620
13838
  if (participant) {
13621
- // we're received, so no need to broadcast, hence the input false arg
13839
+ // we're receiving, so no need to broadcast
13622
13840
  participant.updateStatus(status, false);
13623
13841
  }
13624
13842
  break;
@@ -13885,7 +14103,7 @@ class SipRoom extends Room {
13885
14103
  logger.info('connecting to sip room', { extension, audioOnly, room: !!room });
13886
14104
 
13887
14105
  if (!room) {
13888
- await Wazo.Phone.connect();
14106
+ await Wazo.Phone.connect({ media: constraints });
13889
14107
 
13890
14108
  const withCamera = constraints && !!constraints.video;
13891
14109
 
@@ -442,6 +442,24 @@ const fixSdp = (sdp , candidates , forcePort = true)
442
442
  return fixed;
443
443
  };
444
444
 
445
+ const addIcesInAllBundles = (sdp ) => {
446
+ const parsedSdp = sdpParser.parse(sdp);
447
+
448
+ const mediaWithCandidate = parsedSdp.media.find(media => !!media.candidates);
449
+ if (!mediaWithCandidate) {
450
+ return sdp;
451
+ }
452
+
453
+ const { candidates } = mediaWithCandidate;
454
+
455
+ parsedSdp.media = parsedSdp.media.map(media => ({
456
+ ...media,
457
+ candidates: media.candidates || candidates,
458
+ }));
459
+
460
+ return sdpParser.write(parsedSdp);
461
+ };
462
+
445
463
  /* global RTCSessionDescriptionInit, navigator */
446
464
 
447
465
  const wazoLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-sdh') : console;
@@ -571,7 +589,10 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
571
589
 
572
590
  // Check if we got ICEs
573
591
  if (sdp.indexOf('a=candidate') !== -1) {
574
- return description;
592
+ return {
593
+ type: description.type,
594
+ sdp: addIcesInAllBundles(sdp),
595
+ };
575
596
  }
576
597
 
577
598
  wazoLogger.info('No ICE candidates found in SDP, fixing it with gathered ices', this.gatheredCandidates);