@wazo/sdk 0.38.5 → 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 (135) hide show
  1. package/README.md +1 -1
  2. package/dist/wazo-sdk.js +2 -2
  3. package/esm/__tests__/api-client.test.js +148 -2
  4. package/esm/__tests__/web-rtc-client.test.js +303 -26
  5. package/esm/api/calld.js +14 -0
  6. package/esm/api/confd.js +134 -2
  7. package/esm/api/ctid-ng.js +6 -0
  8. package/esm/api-client.js +148 -2
  9. package/esm/checker/Checker.js +212 -26
  10. package/esm/checker/checks/aor.js +148 -2
  11. package/esm/checker/checks/api.js +148 -2
  12. package/esm/checker/checks/index.js +212 -26
  13. package/esm/checker/checks/wazo-websocket.js +2 -0
  14. package/esm/checker/checks/webrtc-transport.js +210 -26
  15. package/esm/checker/checks/webrtc.js +210 -26
  16. package/esm/domain/AdHocAPIConference.js +148 -2
  17. package/esm/domain/Call.js +6 -0
  18. package/esm/domain/CallSession.js +1 -1
  19. package/esm/domain/Features.js +148 -2
  20. package/esm/domain/Meeting.js +18 -0
  21. package/esm/domain/MeetingAuthorization.js +70 -0
  22. package/esm/domain/Phone/CTIPhone.js +149 -3
  23. package/esm/domain/Phone/WebRTCPhone.js +3 -3
  24. package/esm/domain/__tests__/Call.test.js +6 -0
  25. package/esm/domain/__tests__/CallSession.test.js +1 -1
  26. package/esm/domain/__tests__/IndirectTransfer.test.js +1 -1
  27. package/esm/domain/__tests__/Meeting.test.js +87 -1
  28. package/esm/domain/__tests__/MeetingAuthorization.test.js +109 -0
  29. package/esm/domain/__tests__/Room.test.js +1 -1
  30. package/esm/index.js +258 -32
  31. package/esm/lib/WazoSessionDescriptionHandler.js +22 -1
  32. package/esm/service/CallApi.js +148 -2
  33. package/esm/service/getApiClient.js +148 -2
  34. package/esm/simple/Auth.js +258 -32
  35. package/esm/simple/Configuration.js +258 -32
  36. package/esm/simple/Directory.js +148 -2
  37. package/esm/simple/Phone.js +258 -32
  38. package/esm/simple/Websocket.js +3 -0
  39. package/esm/simple/index.js +258 -32
  40. package/esm/simple/room/LocalParticipant.js +258 -32
  41. package/esm/simple/room/Participant.js +258 -32
  42. package/esm/simple/room/RemoteParticipant.js +258 -32
  43. package/esm/simple/room/Room.js +258 -32
  44. package/esm/simple/room/SipRoom.js +258 -32
  45. package/esm/simple/room/Stream.js +258 -32
  46. package/esm/simple/room/__tests__/Participant.test.js +14747 -0
  47. package/esm/simple/room/__tests__/RemoteParticipant.test.js +258 -32
  48. package/esm/simple/utils.js +258 -32
  49. package/esm/utils/__tests__/object.test.js +57 -0
  50. package/esm/utils/__tests__/sdp.test.js +50 -0
  51. package/esm/utils/__tests__/string.test.js +30 -0
  52. package/esm/utils/object.js +24 -0
  53. package/esm/utils/sdp.js +19 -1
  54. package/esm/utils/string.js +10 -0
  55. package/esm/web-rtc-client.js +210 -26
  56. package/esm/websocket-client.js +3 -1
  57. package/lib/__tests__/api-client.test.js +148 -2
  58. package/lib/__tests__/web-rtc-client.test.js +303 -26
  59. package/lib/api/calld.js +14 -0
  60. package/lib/api/confd.js +134 -2
  61. package/lib/api/ctid-ng.js +6 -0
  62. package/lib/api-client.js +148 -2
  63. package/lib/checker/Checker.js +212 -26
  64. package/lib/checker/checks/aor.js +148 -2
  65. package/lib/checker/checks/api.js +148 -2
  66. package/lib/checker/checks/index.js +212 -26
  67. package/lib/checker/checks/wazo-websocket.js +2 -0
  68. package/lib/checker/checks/webrtc-transport.js +210 -26
  69. package/lib/checker/checks/webrtc.js +210 -26
  70. package/lib/domain/AdHocAPIConference.js +148 -2
  71. package/lib/domain/Call.js +6 -0
  72. package/lib/domain/CallSession.js +1 -1
  73. package/lib/domain/Features.js +148 -2
  74. package/lib/domain/Meeting.js +18 -0
  75. package/lib/domain/MeetingAuthorization.js +79 -0
  76. package/lib/domain/Phone/CTIPhone.js +149 -3
  77. package/lib/domain/Phone/WebRTCPhone.js +3 -3
  78. package/lib/domain/__tests__/Call.test.js +6 -0
  79. package/lib/domain/__tests__/CallSession.test.js +1 -1
  80. package/lib/domain/__tests__/IndirectTransfer.test.js +1 -1
  81. package/lib/domain/__tests__/Meeting.test.js +87 -1
  82. package/lib/domain/__tests__/MeetingAuthorization.test.js +111 -0
  83. package/lib/domain/__tests__/Room.test.js +1 -1
  84. package/lib/index.js +258 -32
  85. package/lib/lib/WazoSessionDescriptionHandler.js +22 -1
  86. package/lib/service/CallApi.js +148 -2
  87. package/lib/service/getApiClient.js +148 -2
  88. package/lib/simple/Auth.js +258 -32
  89. package/lib/simple/Configuration.js +258 -32
  90. package/lib/simple/Directory.js +148 -2
  91. package/lib/simple/Phone.js +258 -32
  92. package/lib/simple/Websocket.js +3 -0
  93. package/lib/simple/index.js +258 -32
  94. package/lib/simple/room/LocalParticipant.js +258 -32
  95. package/lib/simple/room/Participant.js +258 -32
  96. package/lib/simple/room/RemoteParticipant.js +258 -32
  97. package/lib/simple/room/Room.js +258 -32
  98. package/lib/simple/room/SipRoom.js +258 -32
  99. package/lib/simple/room/Stream.js +258 -32
  100. package/lib/simple/room/__tests__/Participant.test.js +14757 -0
  101. package/lib/simple/room/__tests__/RemoteParticipant.test.js +258 -32
  102. package/lib/simple/utils.js +258 -32
  103. package/lib/utils/__tests__/object.test.js +59 -0
  104. package/lib/utils/__tests__/sdp.test.js +50 -0
  105. package/lib/utils/__tests__/string.test.js +32 -0
  106. package/lib/utils/object.js +28 -0
  107. package/lib/utils/sdp.js +19 -0
  108. package/lib/utils/string.js +14 -0
  109. package/lib/web-rtc-client.js +210 -26
  110. package/lib/websocket-client.js +3 -0
  111. package/package.json +2 -2
  112. package/src/__tests__/web-rtc-client.test.js +93 -0
  113. package/src/api/calld.js +8 -0
  114. package/src/api/confd.js +43 -2
  115. package/src/domain/Call.js +6 -0
  116. package/src/domain/CallSession.js +1 -1
  117. package/src/domain/Meeting.js +20 -0
  118. package/src/domain/MeetingAuthorization.js +67 -0
  119. package/src/domain/Phone/WebRTCPhone.js +2 -2
  120. package/src/domain/__tests__/Meeting.test.js +70 -1
  121. package/src/domain/__tests__/MeetingAuthorization.test.js +58 -0
  122. package/src/lib/WazoSessionDescriptionHandler.js +5 -2
  123. package/src/simple/room/Participant.js +40 -0
  124. package/src/simple/room/Room.js +2 -2
  125. package/src/simple/room/SipRoom.js +1 -1
  126. package/src/simple/room/__tests__/Participant.test.js +81 -0
  127. package/src/types/WebSocketMessage.js +7 -1
  128. package/src/utils/__tests__/object.test.js +35 -0
  129. package/src/utils/__tests__/sdp.test.js +33 -1
  130. package/src/utils/__tests__/string.test.js +23 -0
  131. package/src/utils/object.js +15 -0
  132. package/src/utils/sdp.js +18 -0
  133. package/src/utils/string.js +8 -0
  134. package/src/web-rtc-client.js +40 -23
  135. 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
  //
@@ -3616,6 +3769,7 @@ const RECORD_STATE_ACTIVE = 'active';
3616
3769
 
3617
3770
 
3618
3771
 
3772
+
3619
3773
 
3620
3774
 
3621
3775
 
@@ -3626,6 +3780,7 @@ const RECORD_STATE_ACTIVE = 'active';
3626
3780
 
3627
3781
 
3628
3782
 
3783
+
3629
3784
 
3630
3785
 
3631
3786
 
@@ -3654,6 +3809,7 @@ class Call {
3654
3809
 
3655
3810
 
3656
3811
 
3812
+
3657
3813
 
3658
3814
 
3659
3815
 
@@ -3678,6 +3834,7 @@ class Call {
3678
3834
  calleeNumber: plain.peer_caller_id_number,
3679
3835
  dialedExtension: plain.dialed_extension,
3680
3836
  isCaller: plain.is_caller,
3837
+ isVideo: plain.is_video,
3681
3838
  muted: plain.muted,
3682
3839
  onHold: plain.on_hold,
3683
3840
  status: plain.status,
@@ -3701,6 +3858,7 @@ class Call {
3701
3858
  calleeNumber,
3702
3859
  dialedExtension,
3703
3860
  isCaller,
3861
+ isVideo,
3704
3862
  lineId,
3705
3863
  muted,
3706
3864
  onHold,
@@ -3724,6 +3882,7 @@ class Call {
3724
3882
  this.startingTime = startingTime;
3725
3883
  this.talkingToIds = talkingToIds || [];
3726
3884
  this.recording = recording;
3885
+ this.isVideo = !!isVideo;
3727
3886
 
3728
3887
  // Useful to compare instead of instanceof with minified code
3729
3888
  this.type = 'Call';
@@ -4783,6 +4942,14 @@ var calldMethods = (client , baseUrl ) => ({
4783
4942
  getMeetingParticipantsAsUser: async (meetingUuid ) =>
4784
4943
  client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
4785
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
+
4786
4953
  listTrunks: () => client.get(`${baseUrl}/trunks`),
4787
4954
 
4788
4955
  mute: (callId ) =>
@@ -6423,41 +6590,58 @@ class WebRTCClient extends Emitter {
6423
6590
  });
6424
6591
  }
6425
6592
 
6426
- changeAudioInputDevice(id , session ) {
6593
+ async changeAudioInputDevice(id , session , force ) {
6427
6594
  const currentId = this.getAudioDeviceId();
6428
6595
  logger.info('setting audio input device', { id, currentId, session: !!session });
6429
6596
 
6430
- if (id === currentId) {
6597
+ if (!force && id === currentId) {
6431
6598
  return null;
6432
6599
  }
6433
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
+
6434
6619
  // let's update the local audio value
6435
6620
  if (this.audio) {
6436
6621
  this.audio = {
6437
6622
  deviceId: {
6438
- exact: id,
6623
+ exact: deviceId,
6439
6624
  },
6440
6625
  };
6441
6626
  }
6442
6627
 
6443
- if (session) {
6628
+ if (session && navigator.mediaDevices) {
6444
6629
  const sdh = session.sessionDescriptionHandler;
6445
6630
  const pc = sdh.peerConnection;
6446
6631
 
6447
- // $FlowFixMe
6448
- return navigator.mediaDevices.getUserMedia({ audio: { deviceId: { exact: id } } }).then(async stream => {
6449
- const audioTrack = stream.getAudioTracks()[0];
6450
- 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);
6451
6636
 
6452
- if (sender) {
6453
- if (sender.track) {
6454
- audioTrack.enabled = sender.track.enabled;
6455
- }
6456
- sender.replaceTrack(audioTrack);
6637
+ if (sender) {
6638
+ if (sender.track) {
6639
+ audioTrack.enabled = sender.track.enabled;
6457
6640
  }
6641
+ sender.replaceTrack(audioTrack);
6642
+ }
6458
6643
 
6459
- return stream;
6460
- });
6644
+ return stream;
6461
6645
  }
6462
6646
  }
6463
6647
 
@@ -6477,14 +6661,14 @@ class WebRTCClient extends Emitter {
6477
6661
  return null;
6478
6662
  }
6479
6663
 
6480
- // let's update the local video value
6481
- if (this.video) {
6482
- this.video = {
6483
- deviceId: {
6484
- exact: id,
6485
- },
6486
- };
6487
- }
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
+ };
6488
6672
  }
6489
6673
 
6490
6674
  changeSessionVideoInputDevice(id , session ) {