@wazo/sdk 0.38.7 → 0.38.8

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 (106) 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 +227 -27
  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 +183 -24
  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 +183 -24
  11. package/esm/checker/checks/wazo-websocket.js +2 -0
  12. package/esm/checker/checks/webrtc-transport.js +181 -24
  13. package/esm/checker/checks/webrtc.js +181 -24
  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/__tests__/Meeting.test.js +87 -1
  20. package/esm/domain/__tests__/MeetingAuthorization.test.js +109 -0
  21. package/esm/index.js +226 -27
  22. package/esm/service/CallApi.js +142 -2
  23. package/esm/service/getApiClient.js +142 -2
  24. package/esm/simple/Auth.js +226 -27
  25. package/esm/simple/Configuration.js +226 -27
  26. package/esm/simple/Directory.js +142 -2
  27. package/esm/simple/Phone.js +226 -27
  28. package/esm/simple/Websocket.js +3 -0
  29. package/esm/simple/index.js +226 -27
  30. package/esm/simple/room/LocalParticipant.js +226 -27
  31. package/esm/simple/room/Participant.js +226 -27
  32. package/esm/simple/room/RemoteParticipant.js +226 -27
  33. package/esm/simple/room/Room.js +226 -27
  34. package/esm/simple/room/SipRoom.js +226 -27
  35. package/esm/simple/room/Stream.js +226 -27
  36. package/esm/simple/room/__tests__/Participant.test.js +14747 -0
  37. package/esm/simple/room/__tests__/RemoteParticipant.test.js +226 -27
  38. package/esm/simple/utils.js +226 -27
  39. package/esm/utils/__tests__/object.test.js +57 -0
  40. package/esm/utils/__tests__/string.test.js +30 -0
  41. package/esm/utils/object.js +24 -0
  42. package/esm/utils/string.js +10 -0
  43. package/esm/web-rtc-client.js +181 -24
  44. package/esm/websocket-client.js +3 -1
  45. package/lib/__tests__/api-client.test.js +142 -2
  46. package/lib/__tests__/web-rtc-client.test.js +227 -27
  47. package/lib/api/calld.js +8 -0
  48. package/lib/api/confd.js +134 -2
  49. package/lib/api-client.js +142 -2
  50. package/lib/checker/Checker.js +183 -24
  51. package/lib/checker/checks/aor.js +142 -2
  52. package/lib/checker/checks/api.js +142 -2
  53. package/lib/checker/checks/index.js +183 -24
  54. package/lib/checker/checks/wazo-websocket.js +2 -0
  55. package/lib/checker/checks/webrtc-transport.js +181 -24
  56. package/lib/checker/checks/webrtc.js +181 -24
  57. package/lib/domain/AdHocAPIConference.js +142 -2
  58. package/lib/domain/Features.js +142 -2
  59. package/lib/domain/Meeting.js +18 -0
  60. package/lib/domain/MeetingAuthorization.js +79 -0
  61. package/lib/domain/Phone/CTIPhone.js +142 -2
  62. package/lib/domain/__tests__/Meeting.test.js +87 -1
  63. package/lib/domain/__tests__/MeetingAuthorization.test.js +111 -0
  64. package/lib/index.js +226 -27
  65. package/lib/service/CallApi.js +142 -2
  66. package/lib/service/getApiClient.js +142 -2
  67. package/lib/simple/Auth.js +226 -27
  68. package/lib/simple/Configuration.js +226 -27
  69. package/lib/simple/Directory.js +142 -2
  70. package/lib/simple/Phone.js +226 -27
  71. package/lib/simple/Websocket.js +3 -0
  72. package/lib/simple/index.js +226 -27
  73. package/lib/simple/room/LocalParticipant.js +226 -27
  74. package/lib/simple/room/Participant.js +226 -27
  75. package/lib/simple/room/RemoteParticipant.js +226 -27
  76. package/lib/simple/room/Room.js +226 -27
  77. package/lib/simple/room/SipRoom.js +226 -27
  78. package/lib/simple/room/Stream.js +226 -27
  79. package/lib/simple/room/__tests__/Participant.test.js +14757 -0
  80. package/lib/simple/room/__tests__/RemoteParticipant.test.js +226 -27
  81. package/lib/simple/utils.js +226 -27
  82. package/lib/utils/__tests__/object.test.js +59 -0
  83. package/lib/utils/__tests__/string.test.js +32 -0
  84. package/lib/utils/object.js +28 -0
  85. package/lib/utils/string.js +14 -0
  86. package/lib/web-rtc-client.js +181 -24
  87. package/lib/websocket-client.js +3 -0
  88. package/package.json +2 -2
  89. package/src/__tests__/web-rtc-client.test.js +46 -3
  90. package/src/api/calld.js +8 -0
  91. package/src/api/confd.js +43 -2
  92. package/src/domain/Meeting.js +20 -0
  93. package/src/domain/MeetingAuthorization.js +67 -0
  94. package/src/domain/__tests__/Meeting.test.js +70 -1
  95. package/src/domain/__tests__/MeetingAuthorization.test.js +58 -0
  96. package/src/simple/room/Participant.js +40 -0
  97. package/src/simple/room/Room.js +2 -2
  98. package/src/simple/room/SipRoom.js +1 -1
  99. package/src/simple/room/__tests__/Participant.test.js +81 -0
  100. package/src/types/WebSocketMessage.js +7 -1
  101. package/src/utils/__tests__/object.test.js +35 -0
  102. package/src/utils/__tests__/string.test.js +23 -0
  103. package/src/utils/object.js +15 -0
  104. package/src/utils/string.js +8 -0
  105. package/src/web-rtc-client.js +39 -22
  106. package/src/websocket-client.js +2 -0
package/lib/index.js CHANGED
@@ -2657,6 +2657,70 @@ class ExternalApp {
2657
2657
 
2658
2658
  //
2659
2659
 
2660
+ class MeetingAuthorization {
2661
+
2662
+
2663
+
2664
+
2665
+
2666
+
2667
+ constructor({
2668
+ meetingUuid,
2669
+ uuid,
2670
+ userUuid,
2671
+ userName,
2672
+ } = {}) {
2673
+ this.meetingUuid = meetingUuid;
2674
+ this.uuid = uuid;
2675
+ this.userUuid = userUuid;
2676
+ this.userName = userName;
2677
+ }
2678
+
2679
+ setStatus(status ) {
2680
+ this.status = status;
2681
+ }
2682
+
2683
+ getStatus() {
2684
+ return this.status;
2685
+ }
2686
+
2687
+ static parse(plain ) {
2688
+ const {
2689
+ meeting_uuid: meetingUuid,
2690
+ uuid,
2691
+ guest_uuid: userUuid,
2692
+ guest_name: userName,
2693
+ } = plain;
2694
+
2695
+ return new MeetingAuthorization({
2696
+ meetingUuid,
2697
+ uuid,
2698
+ userUuid,
2699
+ userName,
2700
+ });
2701
+ }
2702
+
2703
+ static parseMany(items ) {
2704
+ if (!items) {
2705
+ return [];
2706
+ }
2707
+ return items.map(MeetingAuthorization.parse);
2708
+ }
2709
+ }
2710
+
2711
+ //
2712
+
2713
+
2714
+
2715
+
2716
+
2717
+
2718
+
2719
+
2720
+
2721
+
2722
+
2723
+
2660
2724
 
2661
2725
 
2662
2726
 
@@ -2667,6 +2731,7 @@ class ExternalApp {
2667
2731
 
2668
2732
 
2669
2733
 
2734
+
2670
2735
 
2671
2736
 
2672
2737
  class Meeting {
@@ -2681,6 +2746,8 @@ class Meeting {
2681
2746
 
2682
2747
 
2683
2748
 
2749
+
2750
+
2684
2751
 
2685
2752
  static parse(plain ) {
2686
2753
  return new Meeting({
@@ -2693,6 +2760,7 @@ class Meeting {
2693
2760
  extension: plain.exten,
2694
2761
  persistent: plain.persistent,
2695
2762
  creationTime: moment__default['default'](plain.creation_time).toDate(),
2763
+ requireAuthorization: plain.require_authorization,
2696
2764
  });
2697
2765
  }
2698
2766
 
@@ -2717,6 +2785,7 @@ class Meeting {
2717
2785
  extension,
2718
2786
  persistent,
2719
2787
  creationTime,
2788
+ requireAuthorization,
2720
2789
  } = {}) {
2721
2790
  this.guestSipAuthorization = guestSipAuthorization;
2722
2791
  this.uri = uri;
@@ -2727,6 +2796,7 @@ class Meeting {
2727
2796
  this.extension = extension;
2728
2797
  this.persistent = persistent;
2729
2798
  this.creationTime = creationTime;
2799
+ this.requireAuthorization = requireAuthorization;
2730
2800
 
2731
2801
  // Useful to compare instead of instanceof with minified code
2732
2802
  this.type = 'Meeting';
@@ -2737,8 +2807,32 @@ class Meeting {
2737
2807
  const [username, secret] = atob(this.guestSipAuthorization).split(':');
2738
2808
  return { username, secret };
2739
2809
  }
2810
+
2740
2811
  }
2741
2812
 
2813
+ //
2814
+
2815
+ const camelToUnderscore = (key ) => {
2816
+ if (typeof key !== 'string') {
2817
+ throw new Error('Input is not a string');
2818
+ }
2819
+ return key.charAt(0).toLowerCase() + key.substring(1).replace(/([A-Z])/g, '_$1').toLowerCase();
2820
+ };
2821
+
2822
+ //
2823
+
2824
+ const convertKeysFromCamelToUnderscore = (args ) => {
2825
+ if (!args || typeof args !== 'object' || Array.isArray(args)) {
2826
+ throw new Error('Input is not an object');
2827
+ }
2828
+
2829
+ return Object.keys(args).reduce((acc, key) => {
2830
+ acc[camelToUnderscore(key)] = typeof args[key] === 'object' && !Array.isArray(args[key])
2831
+ ? convertKeysFromCamelToUnderscore(args[key]) : args[key];
2832
+ return acc;
2833
+ }, {});
2834
+ };
2835
+
2742
2836
  /* */
2743
2837
 
2744
2838
  var confdMethods = (client , baseUrl ) => ({
@@ -2807,8 +2901,18 @@ var confdMethods = (client , baseUrl ) => ({
2807
2901
  getMyMeetings: () =>
2808
2902
  client.get(`${baseUrl}/users/me/meetings`).then(response => Meeting.parseMany(response.items)),
2809
2903
 
2810
- createMyMeeting: (name , persistent ) =>
2811
- client.post(`${baseUrl}/users/me/meetings`, { name, persistent }).then(Meeting.parse),
2904
+ createMyMeeting: (args ) =>
2905
+ client
2906
+ .post(`${baseUrl}/users/me/meetings`, convertKeysFromCamelToUnderscore(args))
2907
+ .then(Meeting.parse),
2908
+
2909
+ updateMyMeeting: (meetingUuid , data ) =>
2910
+ client.put(
2911
+ `${baseUrl}/users/me/meetings/${meetingUuid}`,
2912
+ convertKeysFromCamelToUnderscore(data),
2913
+ null,
2914
+ ApiRequester.successResponseParser,
2915
+ ),
2812
2916
 
2813
2917
  deleteMyMeeting: (meetingUuid ) =>
2814
2918
  client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
@@ -2816,8 +2920,36 @@ var confdMethods = (client , baseUrl ) => ({
2816
2920
  getMeeting: (meetingUuid ) =>
2817
2921
  client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
2818
2922
 
2923
+ meetingAuthorizations: (meetingUuid ) =>
2924
+ client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/authorizations`, null).then(MeetingAuthorization.parseMany),
2925
+
2926
+ meetingAuthorizationReject: (meetingUuid , authorizationUuid ) =>
2927
+ client.put(
2928
+ `${baseUrl}/users/me/meetings/${meetingUuid}/authorizations/${authorizationUuid}/reject`,
2929
+ {},
2930
+ null,
2931
+ ApiRequester.successResponseParser,
2932
+ ),
2933
+
2934
+ meetingAuthorizationAccept: (meetingUuid , authorizationUuid ) =>
2935
+ client.put(
2936
+ `${baseUrl}/users/me/meetings/${meetingUuid}/authorizations/${authorizationUuid}/accept`,
2937
+ {},
2938
+ null,
2939
+ ApiRequester.successResponseParser,
2940
+ ),
2941
+
2819
2942
  guestGetMeeting: (meetingUuid ) =>
2820
2943
  client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
2944
+
2945
+ guestAuthorizationRequest: (userUuid , meetingUuid , username ) =>
2946
+ client
2947
+ .post(`${baseUrl}/guests/${userUuid}/meetings/${meetingUuid}/authorizations`, { guest_name: username })
2948
+ .then(MeetingAuthorization.parse),
2949
+
2950
+ guestAuthorizationCheck: (userUuid , meetingUuid , authorizationUuid ) =>
2951
+ client.get(`${baseUrl}/guests/${userUuid}/meetings/${meetingUuid}/authorizations/${authorizationUuid}`, null),
2952
+
2821
2953
  });
2822
2954
 
2823
2955
  //
@@ -5169,6 +5301,14 @@ var calldMethods = (client , baseUrl ) => ({
5169
5301
  getMeetingParticipantsAsUser: async (meetingUuid ) =>
5170
5302
  client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
5171
5303
 
5304
+ banMeetingParticipant: (meetingUuid , participantUuid ) =>
5305
+ client.delete(
5306
+ `${baseUrl}/users/me/meetings/${meetingUuid}/participants/${participantUuid}`,
5307
+ null,
5308
+ null,
5309
+ ApiRequester.successResponseParser,
5310
+ ),
5311
+
5172
5312
  listTrunks: () => client.get(`${baseUrl}/trunks`),
5173
5313
 
5174
5314
  mute: (callId ) =>
@@ -7346,7 +7486,7 @@ class WebRTCClient extends Emitter {
7346
7486
  });
7347
7487
  }
7348
7488
 
7349
- changeAudioInputDevice(id , session , force ) {
7489
+ async changeAudioInputDevice(id , session , force ) {
7350
7490
  const currentId = this.getAudioDeviceId();
7351
7491
  logger$9.info('setting audio input device', { id, currentId, session: !!session });
7352
7492
 
@@ -7354,33 +7494,50 @@ class WebRTCClient extends Emitter {
7354
7494
  return null;
7355
7495
  }
7356
7496
 
7497
+ // in order to handle an audio track change for default devices
7498
+ // we need the actual id of the device (not 'default')
7499
+ let deviceId = id;
7500
+ if (id === 'default' && navigator.mediaDevices) {
7501
+ const devices = await navigator.mediaDevices.enumerateDevices();
7502
+ const defaultDevice = devices.find(device => device.deviceId === 'default');
7503
+ if (defaultDevice) {
7504
+ const deviceLabel = defaultDevice.label.replace('Default - ', '');
7505
+ const targetDevice = devices.find(device => device.label === deviceLabel);
7506
+ if (targetDevice) {
7507
+ deviceId = targetDevice.deviceId;
7508
+ if (!force && deviceId === currentId) {
7509
+ return null;
7510
+ }
7511
+ }
7512
+ }
7513
+ }
7514
+
7357
7515
  // let's update the local audio value
7358
7516
  if (this.audio) {
7359
7517
  this.audio = {
7360
7518
  deviceId: {
7361
- exact: id,
7519
+ exact: deviceId,
7362
7520
  },
7363
7521
  };
7364
7522
  }
7365
7523
 
7366
- if (session) {
7524
+ if (session && navigator.mediaDevices) {
7367
7525
  const sdh = session.sessionDescriptionHandler;
7368
7526
  const pc = sdh.peerConnection;
7369
7527
 
7370
- // $FlowFixMe
7371
- return navigator.mediaDevices.getUserMedia({ audio: { deviceId: { exact: id } } }).then(async stream => {
7372
- const audioTrack = stream.getAudioTracks()[0];
7373
- const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
7528
+ const constraints = { audio: { deviceId: { exact: deviceId } } };
7529
+ const stream = await navigator.mediaDevices.getUserMedia(constraints);
7530
+ const audioTrack = stream.getAudioTracks()[0];
7531
+ const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
7374
7532
 
7375
- if (sender) {
7376
- if (sender.track) {
7377
- audioTrack.enabled = sender.track.enabled;
7378
- }
7379
- sender.replaceTrack(audioTrack);
7533
+ if (sender) {
7534
+ if (sender.track) {
7535
+ audioTrack.enabled = sender.track.enabled;
7380
7536
  }
7537
+ sender.replaceTrack(audioTrack);
7538
+ }
7381
7539
 
7382
- return stream;
7383
- });
7540
+ return stream;
7384
7541
  }
7385
7542
  }
7386
7543
 
@@ -7400,14 +7557,14 @@ class WebRTCClient extends Emitter {
7400
7557
  return null;
7401
7558
  }
7402
7559
 
7403
- // let's update the local video value
7404
- if (this.video) {
7405
- this.video = {
7406
- deviceId: {
7407
- exact: id,
7408
- },
7409
- };
7410
- }
7560
+ // let's make sure we don't lose other video constraints settings -- width, height, frameRate...
7561
+ const videoObject = typeof this.video === 'object' ? this.video : {};
7562
+ this.video = {
7563
+ ...videoObject,
7564
+ deviceId: {
7565
+ exact: id,
7566
+ },
7567
+ };
7411
7568
  }
7412
7569
 
7413
7570
  changeSessionVideoInputDevice(id , session ) {
@@ -8580,6 +8737,7 @@ const AGENT_UNPAUSED = 'agent_unpaused';
8580
8737
  const CONFERENCE_ADHOC_PARTICIPANT_LEFT = 'conference_adhoc_participant_left';
8581
8738
  const CONFERENCE_ADHOC_DELETED = 'conference_adhoc_deleted';
8582
8739
  const MEETING_USER_PROGRESS = 'meeting_user_progress';
8740
+ const MEETING_USER_GUEST_AUTHORIZATION_CREATED = 'meeting_user_guest_authorization_created';
8583
8741
 
8584
8742
  const BLACKLIST_EVENTS = [
8585
8743
  CHAT_MESSAGE_SENT,
@@ -8931,6 +9089,7 @@ WebSocketClient.eventLists = [
8931
9089
  CONFERENCE_ADHOC_PARTICIPANT_LEFT,
8932
9090
  CONFERENCE_ADHOC_DELETED,
8933
9091
  MEETING_USER_PROGRESS,
9092
+ MEETING_USER_GUEST_AUTHORIZATION_CREATED,
8934
9093
  ];
8935
9094
 
8936
9095
  var WebSocketClient$1 = /*#__PURE__*/Object.freeze({
@@ -9002,6 +9161,7 @@ var WebSocketClient$1 = /*#__PURE__*/Object.freeze({
9002
9161
  CONFERENCE_ADHOC_PARTICIPANT_LEFT: CONFERENCE_ADHOC_PARTICIPANT_LEFT,
9003
9162
  CONFERENCE_ADHOC_DELETED: CONFERENCE_ADHOC_DELETED,
9004
9163
  MEETING_USER_PROGRESS: MEETING_USER_PROGRESS,
9164
+ MEETING_USER_GUEST_AUTHORIZATION_CREATED: MEETING_USER_GUEST_AUTHORIZATION_CREATED,
9005
9165
  HEARTBEAT_ENGINE_VERSION: HEARTBEAT_ENGINE_VERSION,
9006
9166
  'default': WebSocketClient
9007
9167
  });
@@ -12782,6 +12942,7 @@ class Participant extends Emitter {
12782
12942
 
12783
12943
 
12784
12944
 
12945
+
12785
12946
 
12786
12947
 
12787
12948
 
@@ -12799,6 +12960,7 @@ class Participant extends Emitter {
12799
12960
 
12800
12961
 
12801
12962
 
12963
+
12802
12964
 
12803
12965
  /**
12804
12966
  * @param room Room The room where the participant is
@@ -12822,6 +12984,7 @@ class Participant extends Emitter {
12822
12984
  this.screensharing = false;
12823
12985
  this.isOnHold = false;
12824
12986
  this.extra = extra;
12987
+ this.banned = false;
12825
12988
 
12826
12989
  this.ON_UPDATED = 'participant/ON_UPDATED';
12827
12990
  this.ON_START_TALKING = 'participant/ON_START_TALKING';
@@ -12838,6 +13001,7 @@ class Participant extends Emitter {
12838
13001
  this.ON_EXTRA_CHANGE = 'participant/ON_EXTRA_CHANGE';
12839
13002
  this.ON_HOLD = 'participant/ON_HOLD';
12840
13003
  this.ON_RESUME = 'participant/ON_RESUME';
13004
+ this.ON_BAN = 'participant/ON_BAN';
12841
13005
  }
12842
13006
 
12843
13007
  triggerEvent(name , ...args ) {
@@ -12878,6 +13042,10 @@ class Participant extends Emitter {
12878
13042
  status.extra = this.extra;
12879
13043
  break;
12880
13044
  }
13045
+ case this.ON_BAN: {
13046
+ status.banned = true;
13047
+ break;
13048
+ }
12881
13049
  }
12882
13050
 
12883
13051
  if (broadcast) {
@@ -12980,6 +13148,11 @@ class Participant extends Emitter {
12980
13148
  this.triggerUpdate(this.ON_RESUME, broadcast);
12981
13149
  }
12982
13150
 
13151
+ onBan(broadcast = true) {
13152
+ this.banned = true;
13153
+ this.triggerUpdate(this.ON_BAN, broadcast);
13154
+ }
13155
+
12983
13156
  getStatus() {
12984
13157
  return {
12985
13158
  callId: this.callId,
@@ -13026,6 +13199,10 @@ class Participant extends Emitter {
13026
13199
  }
13027
13200
  }
13028
13201
 
13202
+ if (status.banned) {
13203
+ this.onBan(false);
13204
+ }
13205
+
13029
13206
  // Poor man's object comparison
13030
13207
  if (typeof status.extra !== 'undefined' && JSON.stringify(this.extra) !== JSON.stringify(status.extra)) {
13031
13208
  this.extra = { ...this.extra, ...status.extra };
@@ -13053,6 +13230,28 @@ class Participant extends Emitter {
13053
13230
  this.streams = streams;
13054
13231
  this.videoStreams = streams;
13055
13232
  }
13233
+
13234
+ async ban(apiRequestDelay = null) {
13235
+ const { meetingUuid } = this.room;
13236
+ if (!meetingUuid) {
13237
+ throw new Error('Attempting to ban a participant without a `meetingUuid`');
13238
+ }
13239
+
13240
+ // this notifies all that someone is being banned
13241
+ this.onBan(true);
13242
+
13243
+ // this allows to delay the actual ban, in order for the banned participant as well as others to react to the situation
13244
+ if (apiRequestDelay) {
13245
+ await this.delay(apiRequestDelay);
13246
+ }
13247
+
13248
+ // proceed with the actual kick
13249
+ return getApiClient().calld.banMeetingParticipant(meetingUuid, this.callId);
13250
+ }
13251
+
13252
+ async delay(ms ) {
13253
+ return new Promise(resolve => setTimeout(resolve, ms));
13254
+ }
13056
13255
  }
13057
13256
 
13058
13257
  //
@@ -13205,7 +13404,7 @@ class Room extends Emitter {
13205
13404
  logger$1.info('connecting to room', { extension, audioOnly, room: !!room });
13206
13405
 
13207
13406
  if (!room) {
13208
- await Wazo.Phone.connect();
13407
+ await Wazo.Phone.connect({ media: constraints });
13209
13408
 
13210
13409
  const withCamera = constraints && !!constraints.video;
13211
13410
 
@@ -13650,7 +13849,7 @@ class Room extends Emitter {
13650
13849
  const participant = this._getParticipantFromCallId(status.callId);
13651
13850
 
13652
13851
  if (participant) {
13653
- // we're received, so no need to broadcast, hence the input false arg
13852
+ // we're receiving, so no need to broadcast
13654
13853
  participant.updateStatus(status, false);
13655
13854
  }
13656
13855
  break;
@@ -13917,7 +14116,7 @@ class SipRoom extends Room {
13917
14116
  logger.info('connecting to sip room', { extension, audioOnly, room: !!room });
13918
14117
 
13919
14118
  if (!room) {
13920
- await Wazo.Phone.connect();
14119
+ await Wazo.Phone.connect({ media: constraints });
13921
14120
 
13922
14121
  const withCamera = constraints && !!constraints.video;
13923
14122
 
@@ -3177,6 +3177,70 @@ class ExternalApp {
3177
3177
 
3178
3178
  //
3179
3179
 
3180
+ class MeetingAuthorization {
3181
+
3182
+
3183
+
3184
+
3185
+
3186
+
3187
+ constructor({
3188
+ meetingUuid,
3189
+ uuid,
3190
+ userUuid,
3191
+ userName,
3192
+ } = {}) {
3193
+ this.meetingUuid = meetingUuid;
3194
+ this.uuid = uuid;
3195
+ this.userUuid = userUuid;
3196
+ this.userName = userName;
3197
+ }
3198
+
3199
+ setStatus(status ) {
3200
+ this.status = status;
3201
+ }
3202
+
3203
+ getStatus() {
3204
+ return this.status;
3205
+ }
3206
+
3207
+ static parse(plain ) {
3208
+ const {
3209
+ meeting_uuid: meetingUuid,
3210
+ uuid,
3211
+ guest_uuid: userUuid,
3212
+ guest_name: userName,
3213
+ } = plain;
3214
+
3215
+ return new MeetingAuthorization({
3216
+ meetingUuid,
3217
+ uuid,
3218
+ userUuid,
3219
+ userName,
3220
+ });
3221
+ }
3222
+
3223
+ static parseMany(items ) {
3224
+ if (!items) {
3225
+ return [];
3226
+ }
3227
+ return items.map(MeetingAuthorization.parse);
3228
+ }
3229
+ }
3230
+
3231
+ //
3232
+
3233
+
3234
+
3235
+
3236
+
3237
+
3238
+
3239
+
3240
+
3241
+
3242
+
3243
+
3180
3244
 
3181
3245
 
3182
3246
 
@@ -3187,6 +3251,7 @@ class ExternalApp {
3187
3251
 
3188
3252
 
3189
3253
 
3254
+
3190
3255
 
3191
3256
 
3192
3257
  class Meeting {
@@ -3201,6 +3266,8 @@ class Meeting {
3201
3266
 
3202
3267
 
3203
3268
 
3269
+
3270
+
3204
3271
 
3205
3272
  static parse(plain ) {
3206
3273
  return new Meeting({
@@ -3213,6 +3280,7 @@ class Meeting {
3213
3280
  extension: plain.exten,
3214
3281
  persistent: plain.persistent,
3215
3282
  creationTime: moment__default['default'](plain.creation_time).toDate(),
3283
+ requireAuthorization: plain.require_authorization,
3216
3284
  });
3217
3285
  }
3218
3286
 
@@ -3237,6 +3305,7 @@ class Meeting {
3237
3305
  extension,
3238
3306
  persistent,
3239
3307
  creationTime,
3308
+ requireAuthorization,
3240
3309
  } = {}) {
3241
3310
  this.guestSipAuthorization = guestSipAuthorization;
3242
3311
  this.uri = uri;
@@ -3247,6 +3316,7 @@ class Meeting {
3247
3316
  this.extension = extension;
3248
3317
  this.persistent = persistent;
3249
3318
  this.creationTime = creationTime;
3319
+ this.requireAuthorization = requireAuthorization;
3250
3320
 
3251
3321
  // Useful to compare instead of instanceof with minified code
3252
3322
  this.type = 'Meeting';
@@ -3257,8 +3327,32 @@ class Meeting {
3257
3327
  const [username, secret] = atob(this.guestSipAuthorization).split(':');
3258
3328
  return { username, secret };
3259
3329
  }
3330
+
3260
3331
  }
3261
3332
 
3333
+ //
3334
+
3335
+ const camelToUnderscore = (key ) => {
3336
+ if (typeof key !== 'string') {
3337
+ throw new Error('Input is not a string');
3338
+ }
3339
+ return key.charAt(0).toLowerCase() + key.substring(1).replace(/([A-Z])/g, '_$1').toLowerCase();
3340
+ };
3341
+
3342
+ //
3343
+
3344
+ const convertKeysFromCamelToUnderscore = (args ) => {
3345
+ if (!args || typeof args !== 'object' || Array.isArray(args)) {
3346
+ throw new Error('Input is not an object');
3347
+ }
3348
+
3349
+ return Object.keys(args).reduce((acc, key) => {
3350
+ acc[camelToUnderscore(key)] = typeof args[key] === 'object' && !Array.isArray(args[key])
3351
+ ? convertKeysFromCamelToUnderscore(args[key]) : args[key];
3352
+ return acc;
3353
+ }, {});
3354
+ };
3355
+
3262
3356
  /* */
3263
3357
 
3264
3358
  var confdMethods = (client , baseUrl ) => ({
@@ -3327,8 +3421,18 @@ var confdMethods = (client , baseUrl ) => ({
3327
3421
  getMyMeetings: () =>
3328
3422
  client.get(`${baseUrl}/users/me/meetings`).then(response => Meeting.parseMany(response.items)),
3329
3423
 
3330
- createMyMeeting: (name , persistent ) =>
3331
- client.post(`${baseUrl}/users/me/meetings`, { name, persistent }).then(Meeting.parse),
3424
+ createMyMeeting: (args ) =>
3425
+ client
3426
+ .post(`${baseUrl}/users/me/meetings`, convertKeysFromCamelToUnderscore(args))
3427
+ .then(Meeting.parse),
3428
+
3429
+ updateMyMeeting: (meetingUuid , data ) =>
3430
+ client.put(
3431
+ `${baseUrl}/users/me/meetings/${meetingUuid}`,
3432
+ convertKeysFromCamelToUnderscore(data),
3433
+ null,
3434
+ ApiRequester.successResponseParser,
3435
+ ),
3332
3436
 
3333
3437
  deleteMyMeeting: (meetingUuid ) =>
3334
3438
  client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
@@ -3336,8 +3440,36 @@ var confdMethods = (client , baseUrl ) => ({
3336
3440
  getMeeting: (meetingUuid ) =>
3337
3441
  client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
3338
3442
 
3443
+ meetingAuthorizations: (meetingUuid ) =>
3444
+ client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/authorizations`, null).then(MeetingAuthorization.parseMany),
3445
+
3446
+ meetingAuthorizationReject: (meetingUuid , authorizationUuid ) =>
3447
+ client.put(
3448
+ `${baseUrl}/users/me/meetings/${meetingUuid}/authorizations/${authorizationUuid}/reject`,
3449
+ {},
3450
+ null,
3451
+ ApiRequester.successResponseParser,
3452
+ ),
3453
+
3454
+ meetingAuthorizationAccept: (meetingUuid , authorizationUuid ) =>
3455
+ client.put(
3456
+ `${baseUrl}/users/me/meetings/${meetingUuid}/authorizations/${authorizationUuid}/accept`,
3457
+ {},
3458
+ null,
3459
+ ApiRequester.successResponseParser,
3460
+ ),
3461
+
3339
3462
  guestGetMeeting: (meetingUuid ) =>
3340
3463
  client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
3464
+
3465
+ guestAuthorizationRequest: (userUuid , meetingUuid , username ) =>
3466
+ client
3467
+ .post(`${baseUrl}/guests/${userUuid}/meetings/${meetingUuid}/authorizations`, { guest_name: username })
3468
+ .then(MeetingAuthorization.parse),
3469
+
3470
+ guestAuthorizationCheck: (userUuid , meetingUuid , authorizationUuid ) =>
3471
+ client.get(`${baseUrl}/guests/${userUuid}/meetings/${meetingUuid}/authorizations/${authorizationUuid}`, null),
3472
+
3341
3473
  });
3342
3474
 
3343
3475
  //
@@ -4213,6 +4345,14 @@ var calldMethods = (client , baseUrl ) => ({
4213
4345
  getMeetingParticipantsAsUser: async (meetingUuid ) =>
4214
4346
  client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
4215
4347
 
4348
+ banMeetingParticipant: (meetingUuid , participantUuid ) =>
4349
+ client.delete(
4350
+ `${baseUrl}/users/me/meetings/${meetingUuid}/participants/${participantUuid}`,
4351
+ null,
4352
+ null,
4353
+ ApiRequester.successResponseParser,
4354
+ ),
4355
+
4216
4356
  listTrunks: () => client.get(`${baseUrl}/trunks`),
4217
4357
 
4218
4358
  mute: (callId ) =>