@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/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 ) =>
@@ -7335,7 +7475,7 @@ class WebRTCClient extends Emitter {
7335
7475
  });
7336
7476
  }
7337
7477
 
7338
- changeAudioInputDevice(id , session , force ) {
7478
+ async changeAudioInputDevice(id , session , force ) {
7339
7479
  const currentId = this.getAudioDeviceId();
7340
7480
  logger$9.info('setting audio input device', { id, currentId, session: !!session });
7341
7481
 
@@ -7343,33 +7483,50 @@ class WebRTCClient extends Emitter {
7343
7483
  return null;
7344
7484
  }
7345
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
+
7346
7504
  // let's update the local audio value
7347
7505
  if (this.audio) {
7348
7506
  this.audio = {
7349
7507
  deviceId: {
7350
- exact: id,
7508
+ exact: deviceId,
7351
7509
  },
7352
7510
  };
7353
7511
  }
7354
7512
 
7355
- if (session) {
7513
+ if (session && navigator.mediaDevices) {
7356
7514
  const sdh = session.sessionDescriptionHandler;
7357
7515
  const pc = sdh.peerConnection;
7358
7516
 
7359
- // $FlowFixMe
7360
- return navigator.mediaDevices.getUserMedia({ audio: { deviceId: { exact: id } } }).then(async stream => {
7361
- const audioTrack = stream.getAudioTracks()[0];
7362
- 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);
7363
7521
 
7364
- if (sender) {
7365
- if (sender.track) {
7366
- audioTrack.enabled = sender.track.enabled;
7367
- }
7368
- sender.replaceTrack(audioTrack);
7522
+ if (sender) {
7523
+ if (sender.track) {
7524
+ audioTrack.enabled = sender.track.enabled;
7369
7525
  }
7526
+ sender.replaceTrack(audioTrack);
7527
+ }
7370
7528
 
7371
- return stream;
7372
- });
7529
+ return stream;
7373
7530
  }
7374
7531
  }
7375
7532
 
@@ -7389,14 +7546,14 @@ class WebRTCClient extends Emitter {
7389
7546
  return null;
7390
7547
  }
7391
7548
 
7392
- // let's update the local video value
7393
- if (this.video) {
7394
- this.video = {
7395
- deviceId: {
7396
- exact: id,
7397
- },
7398
- };
7399
- }
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
+ };
7400
7557
  }
7401
7558
 
7402
7559
  changeSessionVideoInputDevice(id , session ) {
@@ -8569,6 +8726,7 @@ const AGENT_UNPAUSED = 'agent_unpaused';
8569
8726
  const CONFERENCE_ADHOC_PARTICIPANT_LEFT = 'conference_adhoc_participant_left';
8570
8727
  const CONFERENCE_ADHOC_DELETED = 'conference_adhoc_deleted';
8571
8728
  const MEETING_USER_PROGRESS = 'meeting_user_progress';
8729
+ const MEETING_USER_GUEST_AUTHORIZATION_CREATED = 'meeting_user_guest_authorization_created';
8572
8730
 
8573
8731
  const BLACKLIST_EVENTS = [
8574
8732
  CHAT_MESSAGE_SENT,
@@ -8920,6 +9078,7 @@ WebSocketClient.eventLists = [
8920
9078
  CONFERENCE_ADHOC_PARTICIPANT_LEFT,
8921
9079
  CONFERENCE_ADHOC_DELETED,
8922
9080
  MEETING_USER_PROGRESS,
9081
+ MEETING_USER_GUEST_AUTHORIZATION_CREATED,
8923
9082
  ];
8924
9083
 
8925
9084
  var WebSocketClient$1 = /*#__PURE__*/Object.freeze({
@@ -8991,6 +9150,7 @@ var WebSocketClient$1 = /*#__PURE__*/Object.freeze({
8991
9150
  CONFERENCE_ADHOC_PARTICIPANT_LEFT: CONFERENCE_ADHOC_PARTICIPANT_LEFT,
8992
9151
  CONFERENCE_ADHOC_DELETED: CONFERENCE_ADHOC_DELETED,
8993
9152
  MEETING_USER_PROGRESS: MEETING_USER_PROGRESS,
9153
+ MEETING_USER_GUEST_AUTHORIZATION_CREATED: MEETING_USER_GUEST_AUTHORIZATION_CREATED,
8994
9154
  HEARTBEAT_ENGINE_VERSION: HEARTBEAT_ENGINE_VERSION,
8995
9155
  'default': WebSocketClient
8996
9156
  });
@@ -12771,6 +12931,7 @@ class Participant extends Emitter {
12771
12931
 
12772
12932
 
12773
12933
 
12934
+
12774
12935
 
12775
12936
 
12776
12937
 
@@ -12788,6 +12949,7 @@ class Participant extends Emitter {
12788
12949
 
12789
12950
 
12790
12951
 
12952
+
12791
12953
 
12792
12954
  /**
12793
12955
  * @param room Room The room where the participant is
@@ -12811,6 +12973,7 @@ class Participant extends Emitter {
12811
12973
  this.screensharing = false;
12812
12974
  this.isOnHold = false;
12813
12975
  this.extra = extra;
12976
+ this.banned = false;
12814
12977
 
12815
12978
  this.ON_UPDATED = 'participant/ON_UPDATED';
12816
12979
  this.ON_START_TALKING = 'participant/ON_START_TALKING';
@@ -12827,6 +12990,7 @@ class Participant extends Emitter {
12827
12990
  this.ON_EXTRA_CHANGE = 'participant/ON_EXTRA_CHANGE';
12828
12991
  this.ON_HOLD = 'participant/ON_HOLD';
12829
12992
  this.ON_RESUME = 'participant/ON_RESUME';
12993
+ this.ON_BAN = 'participant/ON_BAN';
12830
12994
  }
12831
12995
 
12832
12996
  triggerEvent(name , ...args ) {
@@ -12867,6 +13031,10 @@ class Participant extends Emitter {
12867
13031
  status.extra = this.extra;
12868
13032
  break;
12869
13033
  }
13034
+ case this.ON_BAN: {
13035
+ status.banned = true;
13036
+ break;
13037
+ }
12870
13038
  }
12871
13039
 
12872
13040
  if (broadcast) {
@@ -12969,6 +13137,11 @@ class Participant extends Emitter {
12969
13137
  this.triggerUpdate(this.ON_RESUME, broadcast);
12970
13138
  }
12971
13139
 
13140
+ onBan(broadcast = true) {
13141
+ this.banned = true;
13142
+ this.triggerUpdate(this.ON_BAN, broadcast);
13143
+ }
13144
+
12972
13145
  getStatus() {
12973
13146
  return {
12974
13147
  callId: this.callId,
@@ -13015,6 +13188,10 @@ class Participant extends Emitter {
13015
13188
  }
13016
13189
  }
13017
13190
 
13191
+ if (status.banned) {
13192
+ this.onBan(false);
13193
+ }
13194
+
13018
13195
  // Poor man's object comparison
13019
13196
  if (typeof status.extra !== 'undefined' && JSON.stringify(this.extra) !== JSON.stringify(status.extra)) {
13020
13197
  this.extra = { ...this.extra, ...status.extra };
@@ -13042,6 +13219,28 @@ class Participant extends Emitter {
13042
13219
  this.streams = streams;
13043
13220
  this.videoStreams = streams;
13044
13221
  }
13222
+
13223
+ async ban(apiRequestDelay = null) {
13224
+ const { meetingUuid } = this.room;
13225
+ if (!meetingUuid) {
13226
+ throw new Error('Attempting to ban a participant without a `meetingUuid`');
13227
+ }
13228
+
13229
+ // this notifies all that someone is being banned
13230
+ this.onBan(true);
13231
+
13232
+ // this allows to delay the actual ban, in order for the banned participant as well as others to react to the situation
13233
+ if (apiRequestDelay) {
13234
+ await this.delay(apiRequestDelay);
13235
+ }
13236
+
13237
+ // proceed with the actual kick
13238
+ return getApiClient().calld.banMeetingParticipant(meetingUuid, this.callId);
13239
+ }
13240
+
13241
+ async delay(ms ) {
13242
+ return new Promise(resolve => setTimeout(resolve, ms));
13243
+ }
13045
13244
  }
13046
13245
 
13047
13246
  //
@@ -13194,7 +13393,7 @@ class Room extends Emitter {
13194
13393
  logger$1.info('connecting to room', { extension, audioOnly, room: !!room });
13195
13394
 
13196
13395
  if (!room) {
13197
- await Wazo.Phone.connect();
13396
+ await Wazo.Phone.connect({ media: constraints });
13198
13397
 
13199
13398
  const withCamera = constraints && !!constraints.video;
13200
13399
 
@@ -13639,7 +13838,7 @@ class Room extends Emitter {
13639
13838
  const participant = this._getParticipantFromCallId(status.callId);
13640
13839
 
13641
13840
  if (participant) {
13642
- // we're received, so no need to broadcast, hence the input false arg
13841
+ // we're receiving, so no need to broadcast
13643
13842
  participant.updateStatus(status, false);
13644
13843
  }
13645
13844
  break;
@@ -13906,7 +14105,7 @@ class SipRoom extends Room {
13906
14105
  logger.info('connecting to sip room', { extension, audioOnly, room: !!room });
13907
14106
 
13908
14107
  if (!room) {
13909
- await Wazo.Phone.connect();
14108
+ await Wazo.Phone.connect({ media: constraints });
13910
14109
 
13911
14110
  const withCamera = constraints && !!constraints.video;
13912
14111
 
@@ -3171,6 +3171,70 @@ class ExternalApp {
3171
3171
 
3172
3172
  //
3173
3173
 
3174
+ class MeetingAuthorization {
3175
+
3176
+
3177
+
3178
+
3179
+
3180
+
3181
+ constructor({
3182
+ meetingUuid,
3183
+ uuid,
3184
+ userUuid,
3185
+ userName,
3186
+ } = {}) {
3187
+ this.meetingUuid = meetingUuid;
3188
+ this.uuid = uuid;
3189
+ this.userUuid = userUuid;
3190
+ this.userName = userName;
3191
+ }
3192
+
3193
+ setStatus(status ) {
3194
+ this.status = status;
3195
+ }
3196
+
3197
+ getStatus() {
3198
+ return this.status;
3199
+ }
3200
+
3201
+ static parse(plain ) {
3202
+ const {
3203
+ meeting_uuid: meetingUuid,
3204
+ uuid,
3205
+ guest_uuid: userUuid,
3206
+ guest_name: userName,
3207
+ } = plain;
3208
+
3209
+ return new MeetingAuthorization({
3210
+ meetingUuid,
3211
+ uuid,
3212
+ userUuid,
3213
+ userName,
3214
+ });
3215
+ }
3216
+
3217
+ static parseMany(items ) {
3218
+ if (!items) {
3219
+ return [];
3220
+ }
3221
+ return items.map(MeetingAuthorization.parse);
3222
+ }
3223
+ }
3224
+
3225
+ //
3226
+
3227
+
3228
+
3229
+
3230
+
3231
+
3232
+
3233
+
3234
+
3235
+
3236
+
3237
+
3174
3238
 
3175
3239
 
3176
3240
 
@@ -3181,6 +3245,7 @@ class ExternalApp {
3181
3245
 
3182
3246
 
3183
3247
 
3248
+
3184
3249
 
3185
3250
 
3186
3251
  class Meeting {
@@ -3195,6 +3260,8 @@ class Meeting {
3195
3260
 
3196
3261
 
3197
3262
 
3263
+
3264
+
3198
3265
 
3199
3266
  static parse(plain ) {
3200
3267
  return new Meeting({
@@ -3207,6 +3274,7 @@ class Meeting {
3207
3274
  extension: plain.exten,
3208
3275
  persistent: plain.persistent,
3209
3276
  creationTime: moment(plain.creation_time).toDate(),
3277
+ requireAuthorization: plain.require_authorization,
3210
3278
  });
3211
3279
  }
3212
3280
 
@@ -3231,6 +3299,7 @@ class Meeting {
3231
3299
  extension,
3232
3300
  persistent,
3233
3301
  creationTime,
3302
+ requireAuthorization,
3234
3303
  } = {}) {
3235
3304
  this.guestSipAuthorization = guestSipAuthorization;
3236
3305
  this.uri = uri;
@@ -3241,6 +3310,7 @@ class Meeting {
3241
3310
  this.extension = extension;
3242
3311
  this.persistent = persistent;
3243
3312
  this.creationTime = creationTime;
3313
+ this.requireAuthorization = requireAuthorization;
3244
3314
 
3245
3315
  // Useful to compare instead of instanceof with minified code
3246
3316
  this.type = 'Meeting';
@@ -3251,8 +3321,32 @@ class Meeting {
3251
3321
  const [username, secret] = atob(this.guestSipAuthorization).split(':');
3252
3322
  return { username, secret };
3253
3323
  }
3324
+
3254
3325
  }
3255
3326
 
3327
+ //
3328
+
3329
+ const camelToUnderscore = (key ) => {
3330
+ if (typeof key !== 'string') {
3331
+ throw new Error('Input is not a string');
3332
+ }
3333
+ return key.charAt(0).toLowerCase() + key.substring(1).replace(/([A-Z])/g, '_$1').toLowerCase();
3334
+ };
3335
+
3336
+ //
3337
+
3338
+ const convertKeysFromCamelToUnderscore = (args ) => {
3339
+ if (!args || typeof args !== 'object' || Array.isArray(args)) {
3340
+ throw new Error('Input is not an object');
3341
+ }
3342
+
3343
+ return Object.keys(args).reduce((acc, key) => {
3344
+ acc[camelToUnderscore(key)] = typeof args[key] === 'object' && !Array.isArray(args[key])
3345
+ ? convertKeysFromCamelToUnderscore(args[key]) : args[key];
3346
+ return acc;
3347
+ }, {});
3348
+ };
3349
+
3256
3350
  /* */
3257
3351
 
3258
3352
  var confdMethods = (client , baseUrl ) => ({
@@ -3321,8 +3415,18 @@ var confdMethods = (client , baseUrl ) => ({
3321
3415
  getMyMeetings: () =>
3322
3416
  client.get(`${baseUrl}/users/me/meetings`).then(response => Meeting.parseMany(response.items)),
3323
3417
 
3324
- createMyMeeting: (name , persistent ) =>
3325
- client.post(`${baseUrl}/users/me/meetings`, { name, persistent }).then(Meeting.parse),
3418
+ createMyMeeting: (args ) =>
3419
+ client
3420
+ .post(`${baseUrl}/users/me/meetings`, convertKeysFromCamelToUnderscore(args))
3421
+ .then(Meeting.parse),
3422
+
3423
+ updateMyMeeting: (meetingUuid , data ) =>
3424
+ client.put(
3425
+ `${baseUrl}/users/me/meetings/${meetingUuid}`,
3426
+ convertKeysFromCamelToUnderscore(data),
3427
+ null,
3428
+ ApiRequester.successResponseParser,
3429
+ ),
3326
3430
 
3327
3431
  deleteMyMeeting: (meetingUuid ) =>
3328
3432
  client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
@@ -3330,8 +3434,36 @@ var confdMethods = (client , baseUrl ) => ({
3330
3434
  getMeeting: (meetingUuid ) =>
3331
3435
  client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
3332
3436
 
3437
+ meetingAuthorizations: (meetingUuid ) =>
3438
+ client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/authorizations`, null).then(MeetingAuthorization.parseMany),
3439
+
3440
+ meetingAuthorizationReject: (meetingUuid , authorizationUuid ) =>
3441
+ client.put(
3442
+ `${baseUrl}/users/me/meetings/${meetingUuid}/authorizations/${authorizationUuid}/reject`,
3443
+ {},
3444
+ null,
3445
+ ApiRequester.successResponseParser,
3446
+ ),
3447
+
3448
+ meetingAuthorizationAccept: (meetingUuid , authorizationUuid ) =>
3449
+ client.put(
3450
+ `${baseUrl}/users/me/meetings/${meetingUuid}/authorizations/${authorizationUuid}/accept`,
3451
+ {},
3452
+ null,
3453
+ ApiRequester.successResponseParser,
3454
+ ),
3455
+
3333
3456
  guestGetMeeting: (meetingUuid ) =>
3334
3457
  client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
3458
+
3459
+ guestAuthorizationRequest: (userUuid , meetingUuid , username ) =>
3460
+ client
3461
+ .post(`${baseUrl}/guests/${userUuid}/meetings/${meetingUuid}/authorizations`, { guest_name: username })
3462
+ .then(MeetingAuthorization.parse),
3463
+
3464
+ guestAuthorizationCheck: (userUuid , meetingUuid , authorizationUuid ) =>
3465
+ client.get(`${baseUrl}/guests/${userUuid}/meetings/${meetingUuid}/authorizations/${authorizationUuid}`, null),
3466
+
3335
3467
  });
3336
3468
 
3337
3469
  //
@@ -4207,6 +4339,14 @@ var calldMethods = (client , baseUrl ) => ({
4207
4339
  getMeetingParticipantsAsUser: async (meetingUuid ) =>
4208
4340
  client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
4209
4341
 
4342
+ banMeetingParticipant: (meetingUuid , participantUuid ) =>
4343
+ client.delete(
4344
+ `${baseUrl}/users/me/meetings/${meetingUuid}/participants/${participantUuid}`,
4345
+ null,
4346
+ null,
4347
+ ApiRequester.successResponseParser,
4348
+ ),
4349
+
4210
4350
  listTrunks: () => client.get(`${baseUrl}/trunks`),
4211
4351
 
4212
4352
  mute: (callId ) =>