@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
@@ -787,6 +787,24 @@ const fixSdp = (sdp , candidates , forcePort = true)
787
787
  return fixed;
788
788
  };
789
789
 
790
+ const addIcesInAllBundles = (sdp ) => {
791
+ const parsedSdp = sdpParser__default['default'].parse(sdp);
792
+
793
+ const mediaWithCandidate = parsedSdp.media.find(media => !!media.candidates);
794
+ if (!mediaWithCandidate) {
795
+ return sdp;
796
+ }
797
+
798
+ const { candidates } = mediaWithCandidate;
799
+
800
+ parsedSdp.media = parsedSdp.media.map(media => ({
801
+ ...media,
802
+ candidates: media.candidates || candidates,
803
+ }));
804
+
805
+ return sdpParser__default['default'].write(parsedSdp);
806
+ };
807
+
790
808
  /* global RTCSessionDescriptionInit, navigator */
791
809
 
792
810
  const wazoLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-sdh') : console;
@@ -916,7 +934,10 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
916
934
 
917
935
  // Check if we got ICEs
918
936
  if (sdp.indexOf('a=candidate') !== -1) {
919
- return description;
937
+ return {
938
+ type: description.type,
939
+ sdp: addIcesInAllBundles(sdp),
940
+ };
920
941
  }
921
942
 
922
943
  wazoLogger.info('No ICE candidates found in SDP, fixing it with gathered ices', this.gatheredCandidates);
@@ -3190,6 +3211,70 @@ class ExternalApp {
3190
3211
 
3191
3212
  //
3192
3213
 
3214
+ class MeetingAuthorization {
3215
+
3216
+
3217
+
3218
+
3219
+
3220
+
3221
+ constructor({
3222
+ meetingUuid,
3223
+ uuid,
3224
+ userUuid,
3225
+ userName,
3226
+ } = {}) {
3227
+ this.meetingUuid = meetingUuid;
3228
+ this.uuid = uuid;
3229
+ this.userUuid = userUuid;
3230
+ this.userName = userName;
3231
+ }
3232
+
3233
+ setStatus(status ) {
3234
+ this.status = status;
3235
+ }
3236
+
3237
+ getStatus() {
3238
+ return this.status;
3239
+ }
3240
+
3241
+ static parse(plain ) {
3242
+ const {
3243
+ meeting_uuid: meetingUuid,
3244
+ uuid,
3245
+ guest_uuid: userUuid,
3246
+ guest_name: userName,
3247
+ } = plain;
3248
+
3249
+ return new MeetingAuthorization({
3250
+ meetingUuid,
3251
+ uuid,
3252
+ userUuid,
3253
+ userName,
3254
+ });
3255
+ }
3256
+
3257
+ static parseMany(items ) {
3258
+ if (!items) {
3259
+ return [];
3260
+ }
3261
+ return items.map(MeetingAuthorization.parse);
3262
+ }
3263
+ }
3264
+
3265
+ //
3266
+
3267
+
3268
+
3269
+
3270
+
3271
+
3272
+
3273
+
3274
+
3275
+
3276
+
3277
+
3193
3278
 
3194
3279
 
3195
3280
 
@@ -3200,6 +3285,7 @@ class ExternalApp {
3200
3285
 
3201
3286
 
3202
3287
 
3288
+
3203
3289
 
3204
3290
 
3205
3291
  class Meeting {
@@ -3214,6 +3300,8 @@ class Meeting {
3214
3300
 
3215
3301
 
3216
3302
 
3303
+
3304
+
3217
3305
 
3218
3306
  static parse(plain ) {
3219
3307
  return new Meeting({
@@ -3226,6 +3314,7 @@ class Meeting {
3226
3314
  extension: plain.exten,
3227
3315
  persistent: plain.persistent,
3228
3316
  creationTime: moment__default['default'](plain.creation_time).toDate(),
3317
+ requireAuthorization: plain.require_authorization,
3229
3318
  });
3230
3319
  }
3231
3320
 
@@ -3250,6 +3339,7 @@ class Meeting {
3250
3339
  extension,
3251
3340
  persistent,
3252
3341
  creationTime,
3342
+ requireAuthorization,
3253
3343
  } = {}) {
3254
3344
  this.guestSipAuthorization = guestSipAuthorization;
3255
3345
  this.uri = uri;
@@ -3260,6 +3350,7 @@ class Meeting {
3260
3350
  this.extension = extension;
3261
3351
  this.persistent = persistent;
3262
3352
  this.creationTime = creationTime;
3353
+ this.requireAuthorization = requireAuthorization;
3263
3354
 
3264
3355
  // Useful to compare instead of instanceof with minified code
3265
3356
  this.type = 'Meeting';
@@ -3270,8 +3361,32 @@ class Meeting {
3270
3361
  const [username, secret] = atob(this.guestSipAuthorization).split(':');
3271
3362
  return { username, secret };
3272
3363
  }
3364
+
3273
3365
  }
3274
3366
 
3367
+ //
3368
+
3369
+ const camelToUnderscore = (key ) => {
3370
+ if (typeof key !== 'string') {
3371
+ throw new Error('Input is not a string');
3372
+ }
3373
+ return key.charAt(0).toLowerCase() + key.substring(1).replace(/([A-Z])/g, '_$1').toLowerCase();
3374
+ };
3375
+
3376
+ //
3377
+
3378
+ const convertKeysFromCamelToUnderscore = (args ) => {
3379
+ if (!args || typeof args !== 'object' || Array.isArray(args)) {
3380
+ throw new Error('Input is not an object');
3381
+ }
3382
+
3383
+ return Object.keys(args).reduce((acc, key) => {
3384
+ acc[camelToUnderscore(key)] = typeof args[key] === 'object' && !Array.isArray(args[key])
3385
+ ? convertKeysFromCamelToUnderscore(args[key]) : args[key];
3386
+ return acc;
3387
+ }, {});
3388
+ };
3389
+
3275
3390
  /* */
3276
3391
 
3277
3392
  var confdMethods = (client , baseUrl ) => ({
@@ -3340,8 +3455,18 @@ var confdMethods = (client , baseUrl ) => ({
3340
3455
  getMyMeetings: () =>
3341
3456
  client.get(`${baseUrl}/users/me/meetings`).then(response => Meeting.parseMany(response.items)),
3342
3457
 
3343
- createMyMeeting: (name , persistent ) =>
3344
- client.post(`${baseUrl}/users/me/meetings`, { name, persistent }).then(Meeting.parse),
3458
+ createMyMeeting: (args ) =>
3459
+ client
3460
+ .post(`${baseUrl}/users/me/meetings`, convertKeysFromCamelToUnderscore(args))
3461
+ .then(Meeting.parse),
3462
+
3463
+ updateMyMeeting: (meetingUuid , data ) =>
3464
+ client.put(
3465
+ `${baseUrl}/users/me/meetings/${meetingUuid}`,
3466
+ convertKeysFromCamelToUnderscore(data),
3467
+ null,
3468
+ ApiRequester.successResponseParser,
3469
+ ),
3345
3470
 
3346
3471
  deleteMyMeeting: (meetingUuid ) =>
3347
3472
  client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
@@ -3349,8 +3474,36 @@ var confdMethods = (client , baseUrl ) => ({
3349
3474
  getMeeting: (meetingUuid ) =>
3350
3475
  client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
3351
3476
 
3477
+ meetingAuthorizations: (meetingUuid ) =>
3478
+ client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/authorizations`, null).then(MeetingAuthorization.parseMany),
3479
+
3480
+ meetingAuthorizationReject: (meetingUuid , authorizationUuid ) =>
3481
+ client.put(
3482
+ `${baseUrl}/users/me/meetings/${meetingUuid}/authorizations/${authorizationUuid}/reject`,
3483
+ {},
3484
+ null,
3485
+ ApiRequester.successResponseParser,
3486
+ ),
3487
+
3488
+ meetingAuthorizationAccept: (meetingUuid , authorizationUuid ) =>
3489
+ client.put(
3490
+ `${baseUrl}/users/me/meetings/${meetingUuid}/authorizations/${authorizationUuid}/accept`,
3491
+ {},
3492
+ null,
3493
+ ApiRequester.successResponseParser,
3494
+ ),
3495
+
3352
3496
  guestGetMeeting: (meetingUuid ) =>
3353
3497
  client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
3498
+
3499
+ guestAuthorizationRequest: (userUuid , meetingUuid , username ) =>
3500
+ client
3501
+ .post(`${baseUrl}/guests/${userUuid}/meetings/${meetingUuid}/authorizations`, { guest_name: username })
3502
+ .then(MeetingAuthorization.parse),
3503
+
3504
+ guestAuthorizationCheck: (userUuid , meetingUuid , authorizationUuid ) =>
3505
+ client.get(`${baseUrl}/guests/${userUuid}/meetings/${meetingUuid}/authorizations/${authorizationUuid}`, null),
3506
+
3354
3507
  });
3355
3508
 
3356
3509
  //
@@ -4789,6 +4942,14 @@ var calldMethods = (client , baseUrl ) => ({
4789
4942
  getMeetingParticipantsAsUser: async (meetingUuid ) =>
4790
4943
  client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
4791
4944
 
4945
+ banMeetingParticipant: (meetingUuid , participantUuid ) =>
4946
+ client.delete(
4947
+ `${baseUrl}/users/me/meetings/${meetingUuid}/participants/${participantUuid}`,
4948
+ null,
4949
+ null,
4950
+ ApiRequester.successResponseParser,
4951
+ ),
4952
+
4792
4953
  listTrunks: () => client.get(`${baseUrl}/trunks`),
4793
4954
 
4794
4955
  mute: (callId ) =>
@@ -6429,7 +6590,7 @@ class WebRTCClient extends Emitter {
6429
6590
  });
6430
6591
  }
6431
6592
 
6432
- changeAudioInputDevice(id , session , force ) {
6593
+ async changeAudioInputDevice(id , session , force ) {
6433
6594
  const currentId = this.getAudioDeviceId();
6434
6595
  logger.info('setting audio input device', { id, currentId, session: !!session });
6435
6596
 
@@ -6437,33 +6598,50 @@ class WebRTCClient extends Emitter {
6437
6598
  return null;
6438
6599
  }
6439
6600
 
6601
+ // in order to handle an audio track change for default devices
6602
+ // we need the actual id of the device (not 'default')
6603
+ let deviceId = id;
6604
+ if (id === 'default' && navigator.mediaDevices) {
6605
+ const devices = await navigator.mediaDevices.enumerateDevices();
6606
+ const defaultDevice = devices.find(device => device.deviceId === 'default');
6607
+ if (defaultDevice) {
6608
+ const deviceLabel = defaultDevice.label.replace('Default - ', '');
6609
+ const targetDevice = devices.find(device => device.label === deviceLabel);
6610
+ if (targetDevice) {
6611
+ deviceId = targetDevice.deviceId;
6612
+ if (!force && deviceId === currentId) {
6613
+ return null;
6614
+ }
6615
+ }
6616
+ }
6617
+ }
6618
+
6440
6619
  // let's update the local audio value
6441
6620
  if (this.audio) {
6442
6621
  this.audio = {
6443
6622
  deviceId: {
6444
- exact: id,
6623
+ exact: deviceId,
6445
6624
  },
6446
6625
  };
6447
6626
  }
6448
6627
 
6449
- if (session) {
6628
+ if (session && navigator.mediaDevices) {
6450
6629
  const sdh = session.sessionDescriptionHandler;
6451
6630
  const pc = sdh.peerConnection;
6452
6631
 
6453
- // $FlowFixMe
6454
- return navigator.mediaDevices.getUserMedia({ audio: { deviceId: { exact: id } } }).then(async stream => {
6455
- const audioTrack = stream.getAudioTracks()[0];
6456
- const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
6632
+ const constraints = { audio: { deviceId: { exact: deviceId } } };
6633
+ const stream = await navigator.mediaDevices.getUserMedia(constraints);
6634
+ const audioTrack = stream.getAudioTracks()[0];
6635
+ const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
6457
6636
 
6458
- if (sender) {
6459
- if (sender.track) {
6460
- audioTrack.enabled = sender.track.enabled;
6461
- }
6462
- sender.replaceTrack(audioTrack);
6637
+ if (sender) {
6638
+ if (sender.track) {
6639
+ audioTrack.enabled = sender.track.enabled;
6463
6640
  }
6641
+ sender.replaceTrack(audioTrack);
6642
+ }
6464
6643
 
6465
- return stream;
6466
- });
6644
+ return stream;
6467
6645
  }
6468
6646
  }
6469
6647
 
@@ -6483,14 +6661,14 @@ class WebRTCClient extends Emitter {
6483
6661
  return null;
6484
6662
  }
6485
6663
 
6486
- // let's update the local video value
6487
- if (this.video) {
6488
- this.video = {
6489
- deviceId: {
6490
- exact: id,
6491
- },
6492
- };
6493
- }
6664
+ // let's make sure we don't lose other video constraints settings -- width, height, frameRate...
6665
+ const videoObject = typeof this.video === 'object' ? this.video : {};
6666
+ this.video = {
6667
+ ...videoObject,
6668
+ deviceId: {
6669
+ exact: id,
6670
+ },
6671
+ };
6494
6672
  }
6495
6673
 
6496
6674
  changeSessionVideoInputDevice(id , session ) {
@@ -7643,27 +7821,70 @@ describe('changeAudioInputDevice', () => {
7643
7821
  });
7644
7822
  });
7645
7823
 
7824
+ const devices = [
7825
+ { deviceId: 'default', kind: 'audioinput', label: 'Default - Fake Microphone', groupId: 'fak3Gr0up3' },
7826
+ { deviceId: 'fak3d3v1c3', kind: 'audioinput', label: 'Fake Microphone', groupId: 'fak3Gr0up3' },
7827
+ ];
7828
+ const enumerateDevicesMock = jest.fn(async () => {
7829
+ return new Promise(resolve => {
7830
+ resolve(devices);
7831
+ });
7832
+ });
7833
+
7646
7834
  Object.defineProperty(global.navigator, 'mediaDevices', {
7647
7835
  value: {
7648
7836
  getUserMedia: getUserMediaMock,
7837
+ enumerateDevices: enumerateDevicesMock,
7649
7838
  },
7650
7839
  });
7651
7840
 
7652
7841
  it('should change the audio input track if the provided id is different', async () => {
7653
7842
  client.setMediaConstraints(constraints);
7654
7843
  expect(client.getAudioDeviceId()).toBe(defaultId);
7655
- expect(client.changeAudioInputDevice(deviceId, session)).toBeTruthy();
7844
+ const result = await client.changeAudioInputDevice(deviceId, session);
7845
+ expect(result).toBeTruthy();
7656
7846
  });
7657
7847
 
7658
7848
  it('should NOT change the audio input track if the provided id is the same', async () => {
7659
7849
  client.setMediaConstraints(constraints);
7660
7850
  expect(client.getAudioDeviceId()).toBe(defaultId);
7661
- expect(client.changeAudioInputDevice(defaultId, session)).toBeFalsy();
7851
+ const result = await client.changeAudioInputDevice(defaultId, session);
7852
+ expect(result).toBeFalsy();
7662
7853
  });
7663
7854
 
7664
7855
  it('should change the audio input track if the provided id is the same and force param is TRUE', async () => {
7665
7856
  client.setMediaConstraints(constraints);
7666
7857
  expect(client.getAudioDeviceId()).toBe(defaultId);
7667
- expect(client.changeAudioInputDevice(defaultId, session, true)).toBeTruthy();
7858
+ const result = await client.changeAudioInputDevice(defaultId, session, true);
7859
+ expect(result).toBeTruthy();
7860
+ });
7861
+
7862
+ describe('setVideoInputDevice', () => {
7863
+ it('should retain its original video values', () => {
7864
+ const video = { height: { min: 480, max: 720 }, width: { min: 640, max: 1280 } };
7865
+
7866
+ client.video = video;
7867
+ client.setVideoInputDevice(deviceId);
7868
+ expect(client.video).toEqual({ ...video, deviceId: { exact: deviceId } });
7869
+ });
7870
+
7871
+ it('should set deviceId when video\'s original value is true', () => {
7872
+ client.video = true;
7873
+ client.setVideoInputDevice(deviceId);
7874
+ expect(client.video).toEqual({ deviceId: { exact: deviceId } });
7875
+ });
7876
+
7877
+ it('should set deviceId when video\'s original value is not set', () => {
7878
+ client.video = undefined;
7879
+ client.setVideoInputDevice(deviceId);
7880
+ expect(client.video).toEqual({ deviceId: { exact: deviceId } });
7881
+ });
7882
+
7883
+ it('should NOT set deviceId when its value does not change', () => {
7884
+ client.video = { deviceId: { exact: deviceId } };
7885
+ const result = client.setVideoInputDevice(deviceId);
7886
+ expect(result).toEqual(null);
7887
+ expect(client.video).toEqual({ deviceId: { exact: deviceId } });
7888
+ });
7668
7889
  });
7669
7890
  });
package/lib/api/calld.js CHANGED
@@ -1401,6 +1401,14 @@ var calld = (client , baseUrl ) => ({
1401
1401
  getMeetingParticipantsAsUser: async (meetingUuid ) =>
1402
1402
  client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
1403
1403
 
1404
+ banMeetingParticipant: (meetingUuid , participantUuid ) =>
1405
+ client.delete(
1406
+ `${baseUrl}/users/me/meetings/${meetingUuid}/participants/${participantUuid}`,
1407
+ null,
1408
+ null,
1409
+ ApiRequester.successResponseParser,
1410
+ ),
1411
+
1404
1412
  listTrunks: () => client.get(`${baseUrl}/trunks`),
1405
1413
 
1406
1414
  mute: (callId ) =>
package/lib/api/confd.js CHANGED
@@ -1292,6 +1292,70 @@ class ExternalApp {
1292
1292
 
1293
1293
  //
1294
1294
 
1295
+ class MeetingAuthorization {
1296
+
1297
+
1298
+
1299
+
1300
+
1301
+
1302
+ constructor({
1303
+ meetingUuid,
1304
+ uuid,
1305
+ userUuid,
1306
+ userName,
1307
+ } = {}) {
1308
+ this.meetingUuid = meetingUuid;
1309
+ this.uuid = uuid;
1310
+ this.userUuid = userUuid;
1311
+ this.userName = userName;
1312
+ }
1313
+
1314
+ setStatus(status ) {
1315
+ this.status = status;
1316
+ }
1317
+
1318
+ getStatus() {
1319
+ return this.status;
1320
+ }
1321
+
1322
+ static parse(plain ) {
1323
+ const {
1324
+ meeting_uuid: meetingUuid,
1325
+ uuid,
1326
+ guest_uuid: userUuid,
1327
+ guest_name: userName,
1328
+ } = plain;
1329
+
1330
+ return new MeetingAuthorization({
1331
+ meetingUuid,
1332
+ uuid,
1333
+ userUuid,
1334
+ userName,
1335
+ });
1336
+ }
1337
+
1338
+ static parseMany(items ) {
1339
+ if (!items) {
1340
+ return [];
1341
+ }
1342
+ return items.map(MeetingAuthorization.parse);
1343
+ }
1344
+ }
1345
+
1346
+ //
1347
+
1348
+
1349
+
1350
+
1351
+
1352
+
1353
+
1354
+
1355
+
1356
+
1357
+
1358
+
1295
1359
 
1296
1360
 
1297
1361
 
@@ -1302,6 +1366,7 @@ class ExternalApp {
1302
1366
 
1303
1367
 
1304
1368
 
1369
+
1305
1370
 
1306
1371
 
1307
1372
  class Meeting {
@@ -1316,6 +1381,8 @@ class Meeting {
1316
1381
 
1317
1382
 
1318
1383
 
1384
+
1385
+
1319
1386
 
1320
1387
  static parse(plain ) {
1321
1388
  return new Meeting({
@@ -1328,6 +1395,7 @@ class Meeting {
1328
1395
  extension: plain.exten,
1329
1396
  persistent: plain.persistent,
1330
1397
  creationTime: moment__default['default'](plain.creation_time).toDate(),
1398
+ requireAuthorization: plain.require_authorization,
1331
1399
  });
1332
1400
  }
1333
1401
 
@@ -1352,6 +1420,7 @@ class Meeting {
1352
1420
  extension,
1353
1421
  persistent,
1354
1422
  creationTime,
1423
+ requireAuthorization,
1355
1424
  } = {}) {
1356
1425
  this.guestSipAuthorization = guestSipAuthorization;
1357
1426
  this.uri = uri;
@@ -1362,6 +1431,7 @@ class Meeting {
1362
1431
  this.extension = extension;
1363
1432
  this.persistent = persistent;
1364
1433
  this.creationTime = creationTime;
1434
+ this.requireAuthorization = requireAuthorization;
1365
1435
 
1366
1436
  // Useful to compare instead of instanceof with minified code
1367
1437
  this.type = 'Meeting';
@@ -1372,8 +1442,32 @@ class Meeting {
1372
1442
  const [username, secret] = atob(this.guestSipAuthorization).split(':');
1373
1443
  return { username, secret };
1374
1444
  }
1445
+
1375
1446
  }
1376
1447
 
1448
+ //
1449
+
1450
+ const camelToUnderscore = (key ) => {
1451
+ if (typeof key !== 'string') {
1452
+ throw new Error('Input is not a string');
1453
+ }
1454
+ return key.charAt(0).toLowerCase() + key.substring(1).replace(/([A-Z])/g, '_$1').toLowerCase();
1455
+ };
1456
+
1457
+ //
1458
+
1459
+ const convertKeysFromCamelToUnderscore = (args ) => {
1460
+ if (!args || typeof args !== 'object' || Array.isArray(args)) {
1461
+ throw new Error('Input is not an object');
1462
+ }
1463
+
1464
+ return Object.keys(args).reduce((acc, key) => {
1465
+ acc[camelToUnderscore(key)] = typeof args[key] === 'object' && !Array.isArray(args[key])
1466
+ ? convertKeysFromCamelToUnderscore(args[key]) : args[key];
1467
+ return acc;
1468
+ }, {});
1469
+ };
1470
+
1377
1471
  /* */
1378
1472
 
1379
1473
  var confd = (client , baseUrl ) => ({
@@ -1442,8 +1536,18 @@ var confd = (client , baseUrl ) => ({
1442
1536
  getMyMeetings: () =>
1443
1537
  client.get(`${baseUrl}/users/me/meetings`).then(response => Meeting.parseMany(response.items)),
1444
1538
 
1445
- createMyMeeting: (name , persistent ) =>
1446
- client.post(`${baseUrl}/users/me/meetings`, { name, persistent }).then(Meeting.parse),
1539
+ createMyMeeting: (args ) =>
1540
+ client
1541
+ .post(`${baseUrl}/users/me/meetings`, convertKeysFromCamelToUnderscore(args))
1542
+ .then(Meeting.parse),
1543
+
1544
+ updateMyMeeting: (meetingUuid , data ) =>
1545
+ client.put(
1546
+ `${baseUrl}/users/me/meetings/${meetingUuid}`,
1547
+ convertKeysFromCamelToUnderscore(data),
1548
+ null,
1549
+ ApiRequester.successResponseParser,
1550
+ ),
1447
1551
 
1448
1552
  deleteMyMeeting: (meetingUuid ) =>
1449
1553
  client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
@@ -1451,8 +1555,36 @@ var confd = (client , baseUrl ) => ({
1451
1555
  getMeeting: (meetingUuid ) =>
1452
1556
  client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
1453
1557
 
1558
+ meetingAuthorizations: (meetingUuid ) =>
1559
+ client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/authorizations`, null).then(MeetingAuthorization.parseMany),
1560
+
1561
+ meetingAuthorizationReject: (meetingUuid , authorizationUuid ) =>
1562
+ client.put(
1563
+ `${baseUrl}/users/me/meetings/${meetingUuid}/authorizations/${authorizationUuid}/reject`,
1564
+ {},
1565
+ null,
1566
+ ApiRequester.successResponseParser,
1567
+ ),
1568
+
1569
+ meetingAuthorizationAccept: (meetingUuid , authorizationUuid ) =>
1570
+ client.put(
1571
+ `${baseUrl}/users/me/meetings/${meetingUuid}/authorizations/${authorizationUuid}/accept`,
1572
+ {},
1573
+ null,
1574
+ ApiRequester.successResponseParser,
1575
+ ),
1576
+
1454
1577
  guestGetMeeting: (meetingUuid ) =>
1455
1578
  client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
1579
+
1580
+ guestAuthorizationRequest: (userUuid , meetingUuid , username ) =>
1581
+ client
1582
+ .post(`${baseUrl}/guests/${userUuid}/meetings/${meetingUuid}/authorizations`, { guest_name: username })
1583
+ .then(MeetingAuthorization.parse),
1584
+
1585
+ guestAuthorizationCheck: (userUuid , meetingUuid , authorizationUuid ) =>
1586
+ client.get(`${baseUrl}/guests/${userUuid}/meetings/${meetingUuid}/authorizations/${authorizationUuid}`, null),
1587
+
1456
1588
  });
1457
1589
 
1458
1590
  module.exports = confd;