@wazo/sdk 1.0.0-alpha.0 → 1.0.0-alpha.10

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 (162) hide show
  1. package/README.md +16 -7
  2. package/dist/wazo-sdk.js +6 -6
  3. package/esm/__tests__/__voice__/call.test.js +57 -2
  4. package/esm/__tests__/api-client.test.js +20 -1
  5. package/esm/api/auth.js +16 -2
  6. package/esm/checker/checks/webrtc.js +2 -2
  7. package/esm/domain/CallLog.js +2 -3
  8. package/esm/domain/Phone/CTIPhone.js +2 -2
  9. package/esm/domain/Phone/WebRTCPhone.js +64 -63
  10. package/esm/index.js +5 -1
  11. package/esm/service/CallApi.js +4 -4
  12. package/esm/simple/Auth.js +19 -15
  13. package/esm/simple/Phone.js +6 -5
  14. package/esm/simple/__tests__/Auth.test.js +8 -64
  15. package/esm/simple/index.js +2 -1
  16. package/esm/simple/room/Room.js +2 -2
  17. package/esm/simple/room/SipRoom.js +2 -2
  18. package/esm/state-machine/call-state-machine.js +2 -2
  19. package/esm/state-machine/softphone-state-machine.js +1 -2
  20. package/esm/state-machine/utils.js +8 -3
  21. package/esm/types/api/auth.d.ts +3 -0
  22. package/esm/types/api/auth.d.ts.map +1 -1
  23. package/esm/types/checker/checks/index.d.ts +1 -1
  24. package/esm/types/checker/checks/webrtc-transport.d.ts +2 -2
  25. package/esm/types/checker/checks/webrtc-transport.d.ts.map +1 -1
  26. package/esm/types/domain/CallLog.d.ts.map +1 -1
  27. package/esm/types/domain/CallSession.d.ts +3 -3
  28. package/esm/types/domain/CallSession.d.ts.map +1 -1
  29. package/esm/types/domain/Phone/CTIPhone.d.ts.map +1 -1
  30. package/esm/types/domain/Phone/WebRTCPhone.d.ts +22 -22
  31. package/esm/types/domain/Phone/WebRTCPhone.d.ts.map +1 -1
  32. package/esm/types/domain/types.d.ts +0 -4
  33. package/esm/types/domain/types.d.ts.map +1 -1
  34. package/esm/types/index.d.ts +5 -1
  35. package/esm/types/index.d.ts.map +1 -1
  36. package/esm/types/lib/WazoSessionDescriptionHandler.d.ts +3 -3
  37. package/esm/types/lib/WazoSessionDescriptionHandler.d.ts.map +1 -1
  38. package/esm/types/service/CallApi.d.ts +5 -5
  39. package/esm/types/service/CallApi.d.ts.map +1 -1
  40. package/esm/types/simple/Auth.d.ts +6 -1
  41. package/esm/types/simple/Auth.d.ts.map +1 -1
  42. package/esm/types/simple/Phone.d.ts +8 -8
  43. package/esm/types/simple/Phone.d.ts.map +1 -1
  44. package/esm/types/simple/index.d.ts +3 -1
  45. package/esm/types/simple/index.d.ts.map +1 -1
  46. package/esm/types/state-machine/softphone-state-machine.d.ts +1 -2
  47. package/esm/types/state-machine/softphone-state-machine.d.ts.map +1 -1
  48. package/esm/types/state-machine/utils.d.ts +2 -2
  49. package/esm/types/state-machine/utils.d.ts.map +1 -1
  50. package/esm/types/utils/api-requester.d.ts.map +1 -1
  51. package/esm/types/utils/sdp.d.ts +3 -2
  52. package/esm/types/utils/sdp.d.ts.map +1 -1
  53. package/esm/types/utils/webrtc.d.ts +1 -0
  54. package/esm/types/utils/webrtc.d.ts.map +1 -1
  55. package/esm/types/voice/call.d.ts +30 -12
  56. package/esm/types/voice/call.d.ts.map +1 -1
  57. package/esm/types/voice/softphone.d.ts +25 -13
  58. package/esm/types/voice/softphone.d.ts.map +1 -1
  59. package/esm/types/web-rtc-client.d.ts +39 -38
  60. package/esm/types/web-rtc-client.d.ts.map +1 -1
  61. package/esm/utils/__tests__/api-requester.test.js +17 -0
  62. package/esm/utils/api-requester.js +9 -1
  63. package/esm/utils/sdp.js +22 -9
  64. package/esm/utils/webrtc.js +24 -4
  65. package/esm/voice/call.js +130 -38
  66. package/esm/voice/softphone.js +145 -35
  67. package/esm/web-rtc-client.js +61 -58
  68. package/lib/__tests__/__voice__/call.test.js +56 -1
  69. package/lib/__tests__/api-client.test.js +20 -1
  70. package/lib/api/auth.js +16 -2
  71. package/lib/checker/checks/webrtc.js +1 -1
  72. package/lib/domain/CallLog.js +2 -3
  73. package/lib/domain/Phone/CTIPhone.js +2 -2
  74. package/lib/domain/Phone/WebRTCPhone.js +63 -62
  75. package/lib/index.js +11 -3
  76. package/lib/service/CallApi.js +2 -2
  77. package/lib/simple/Auth.js +21 -15
  78. package/lib/simple/Phone.js +3 -2
  79. package/lib/simple/__tests__/Auth.test.js +11 -64
  80. package/lib/simple/index.js +2 -1
  81. package/lib/simple/room/Room.js +1 -1
  82. package/lib/simple/room/SipRoom.js +1 -1
  83. package/lib/state-machine/call-state-machine.js +2 -2
  84. package/lib/state-machine/softphone-state-machine.js +1 -2
  85. package/lib/state-machine/utils.js +8 -3
  86. package/lib/types/api/auth.d.ts +3 -0
  87. package/lib/types/api/auth.d.ts.map +1 -1
  88. package/lib/types/checker/checks/index.d.ts +1 -1
  89. package/lib/types/checker/checks/webrtc-transport.d.ts +2 -2
  90. package/lib/types/checker/checks/webrtc-transport.d.ts.map +1 -1
  91. package/lib/types/domain/CallLog.d.ts.map +1 -1
  92. package/lib/types/domain/CallSession.d.ts +3 -3
  93. package/lib/types/domain/CallSession.d.ts.map +1 -1
  94. package/lib/types/domain/Phone/CTIPhone.d.ts.map +1 -1
  95. package/lib/types/domain/Phone/WebRTCPhone.d.ts +22 -22
  96. package/lib/types/domain/Phone/WebRTCPhone.d.ts.map +1 -1
  97. package/lib/types/domain/types.d.ts +0 -4
  98. package/lib/types/domain/types.d.ts.map +1 -1
  99. package/lib/types/index.d.ts +5 -1
  100. package/lib/types/index.d.ts.map +1 -1
  101. package/lib/types/lib/WazoSessionDescriptionHandler.d.ts +3 -3
  102. package/lib/types/lib/WazoSessionDescriptionHandler.d.ts.map +1 -1
  103. package/lib/types/service/CallApi.d.ts +5 -5
  104. package/lib/types/service/CallApi.d.ts.map +1 -1
  105. package/lib/types/simple/Auth.d.ts +6 -1
  106. package/lib/types/simple/Auth.d.ts.map +1 -1
  107. package/lib/types/simple/Phone.d.ts +8 -8
  108. package/lib/types/simple/Phone.d.ts.map +1 -1
  109. package/lib/types/simple/index.d.ts +3 -1
  110. package/lib/types/simple/index.d.ts.map +1 -1
  111. package/lib/types/state-machine/softphone-state-machine.d.ts +1 -2
  112. package/lib/types/state-machine/softphone-state-machine.d.ts.map +1 -1
  113. package/lib/types/state-machine/utils.d.ts +2 -2
  114. package/lib/types/state-machine/utils.d.ts.map +1 -1
  115. package/lib/types/utils/api-requester.d.ts.map +1 -1
  116. package/lib/types/utils/sdp.d.ts +3 -2
  117. package/lib/types/utils/sdp.d.ts.map +1 -1
  118. package/lib/types/utils/webrtc.d.ts +1 -0
  119. package/lib/types/utils/webrtc.d.ts.map +1 -1
  120. package/lib/types/voice/call.d.ts +30 -12
  121. package/lib/types/voice/call.d.ts.map +1 -1
  122. package/lib/types/voice/softphone.d.ts +25 -13
  123. package/lib/types/voice/softphone.d.ts.map +1 -1
  124. package/lib/types/web-rtc-client.d.ts +39 -38
  125. package/lib/types/web-rtc-client.d.ts.map +1 -1
  126. package/lib/utils/__tests__/api-requester.test.js +17 -0
  127. package/lib/utils/api-requester.js +9 -1
  128. package/lib/utils/sdp.js +25 -10
  129. package/lib/utils/webrtc.js +25 -4
  130. package/lib/voice/call.js +131 -36
  131. package/lib/voice/softphone.js +150 -35
  132. package/lib/web-rtc-client.js +59 -57
  133. package/package.json +1 -1
  134. package/src/__tests__/__voice__/call.test.ts +63 -2
  135. package/src/__tests__/api-client.test.ts +22 -1
  136. package/src/api/auth.ts +30 -3
  137. package/src/checker/checks/webrtc-transport.ts +2 -2
  138. package/src/checker/checks/webrtc.ts +2 -2
  139. package/src/domain/CallLog.ts +2 -3
  140. package/src/domain/CallSession.ts +3 -3
  141. package/src/domain/Phone/CTIPhone.ts +3 -2
  142. package/src/domain/Phone/WebRTCPhone.ts +95 -93
  143. package/src/domain/types.ts +0 -5
  144. package/src/index.ts +6 -1
  145. package/src/lib/WazoSessionDescriptionHandler.ts +3 -3
  146. package/src/service/CallApi.ts +7 -7
  147. package/src/simple/Auth.ts +21 -16
  148. package/src/simple/Phone.ts +12 -11
  149. package/src/simple/__tests__/Auth.test.ts +9 -87
  150. package/src/simple/index.ts +2 -1
  151. package/src/simple/room/Room.ts +3 -3
  152. package/src/simple/room/SipRoom.ts +3 -3
  153. package/src/state-machine/call-state-machine.ts +2 -2
  154. package/src/state-machine/softphone-state-machine.ts +1 -2
  155. package/src/state-machine/utils.ts +12 -5
  156. package/src/utils/__tests__/api-requester.test.ts +20 -0
  157. package/src/utils/api-requester.ts +9 -1
  158. package/src/utils/sdp.ts +26 -11
  159. package/src/utils/webrtc.ts +27 -5
  160. package/src/voice/call.ts +169 -50
  161. package/src/voice/softphone.ts +180 -41
  162. package/src/web-rtc-client.ts +106 -99
@@ -3,7 +3,7 @@ import { Invitation } from 'sip.js/lib/api';
3
3
  import CallSession from '../CallSession';
4
4
  import Emitter from '../../utils/Emitter';
5
5
  import IssueReporter from '../../service/IssueReporter';
6
- import { getSipSessionId } from '../../utils/sdp';
6
+ import { getCallDisplayName, getCallNumber, getSipCallId } from '../../utils/sdp';
7
7
  import { downgradeToAudio, getStreamFromConstraints, getWebRtcStats, setLocalMediaStream, upgradeToVideo } from '../../utils/webrtc';
8
8
  export const ON_USER_AGENT = 'onUserAgent';
9
9
  export const ON_REGISTERED = 'onRegistered';
@@ -51,6 +51,7 @@ export const MESSAGE_TYPE_CHAT = 'message/TYPE_CHAT';
51
51
  export const MESSAGE_TYPE_SIGNAL = 'message/TYPE_SIGNAL';
52
52
  export const events = [ON_USER_AGENT, ON_REGISTERED, ON_UNREGISTERED, ON_PROGRESS, ON_CALL_ACCEPTED, ON_CALL_ANSWERED, ON_CALL_INCOMING, ON_CALL_OUTGOING, ON_CALL_MUTED, ON_CALL_UNMUTED, ON_CALL_RESUMED, ON_CALL_HELD, ON_CALL_UNHELD, ON_CAMERA_DISABLED, ON_CALL_FAILED, ON_CALL_ENDED, ON_CALL_REJECTED, ON_MESSAGE, ON_REINVITE, ON_TRACK, ON_AUDIO_STREAM, ON_VIDEO_STREAM, ON_REMOVE_STREAM, ON_SHARE_SCREEN_ENDED, ON_TERMINATE_SOUND, ON_PLAY_RING_SOUND, ON_PLAY_INBOUND_CALL_SIGNAL_SOUND, ON_PLAY_HANGUP_SOUND, ON_PLAY_PROGRESS_SOUND, ON_VIDEO_INPUT_CHANGE, ON_SHARE_SCREEN_STARTED, ON_CALL_ERROR, ON_CHAT, ON_SIGNAL, ON_NETWORK_STATS, ON_DISCONNECTED, ON_EARLY_MEDIA];
53
53
  const logger = IssueReporter.loggerFor('webrtc-phone');
54
+ // @deprecated: Use Wazo.Voice.Softphone instead
54
55
  export default class WebRTCPhone extends Emitter {
55
56
  client;
56
57
  allowVideo;
@@ -125,7 +126,7 @@ export default class WebRTCPhone extends Emitter {
125
126
  async sendReinvite(callSession, constraints = null, conference = false, audioOnly = false, iceRestart = false) {
126
127
  const sipSession = this.findSipSession(callSession);
127
128
  logger.info('WebRTC phone - send reinvite', {
128
- sessionId: sipSession ? sipSession.id : null,
129
+ sessionId: getSipCallId(sipSession),
129
130
  constraints,
130
131
  audioOnly,
131
132
  conference,
@@ -279,7 +280,7 @@ export default class WebRTCPhone extends Emitter {
279
280
  content: {
280
281
  type: ON_MESSAGE_TRACK_UPDATED,
281
282
  update: isUpgrade ? 'upgrade' : 'downgrade',
282
- sipCallId: sipSession && getSipSessionId(sipSession),
283
+ sipCallId: sipSession && getSipCallId(sipSession),
283
284
  callId: callSession ? callSession.callId : null,
284
285
  number: callSession ? callSession.number : null,
285
286
  },
@@ -287,7 +288,7 @@ export default class WebRTCPhone extends Emitter {
287
288
  }, 2500);
288
289
  }
289
290
  _bindEvents(sipSession) {
290
- const sipSessionId = getSipSessionId(sipSession);
291
+ const sipSessionId = getSipCallId(sipSession);
291
292
  if (sipSession instanceof Invitation) {
292
293
  // Monkey patch to know when canceled with the CANCEL message
293
294
  const onCancel = sipSession._onCancel.bind(sipSession);
@@ -299,7 +300,9 @@ export default class WebRTCPhone extends Emitter {
299
300
  onCancel(message);
300
301
  const elsewhere = message.data.indexOf('cause=26') !== -1 && message.data.indexOf('completed elsewhere') !== -1;
301
302
  const callSession = this._createCallSession(sipSession);
302
- delete this.callSessions[sipSessionId];
303
+ if (sipSessionId) {
304
+ delete this.callSessions[sipSessionId];
305
+ }
303
306
  this.eventEmitter.emit(ON_CALL_CANCELED, callSession, elsewhere);
304
307
  };
305
308
  }
@@ -307,14 +310,14 @@ export default class WebRTCPhone extends Emitter {
307
310
  switch (newState) {
308
311
  case SessionState.Terminating:
309
312
  logger.info('WebRTC phone - call terminating', {
310
- sipId: sipSession.id,
313
+ sipId: getSipCallId(sipSession),
311
314
  });
312
315
  this.eventEmitter.emit(ON_CALL_ENDING, this._createCallSession(sipSession));
313
316
  break;
314
317
  case SessionState.Terminated:
315
318
  {
316
319
  logger.info('WebRTC phone - call terminated', {
317
- sipId: sipSession.id,
320
+ sipId: getSipCallId(sipSession),
318
321
  });
319
322
  // Should be called before `_onCallTerminated` or the callCount will not decrement...
320
323
  const callSession = this._createCallSession(sipSession);
@@ -341,7 +344,7 @@ export default class WebRTCPhone extends Emitter {
341
344
  const [stream] = event.streams;
342
345
  const kind = event && event.track && event.track.kind;
343
346
  logger.info('on track stream called on the peer connection', {
344
- callId: getSipSessionId(sipSession),
347
+ callId: getSipCallId(sipSession),
345
348
  streamId: stream ? stream.id : null,
346
349
  tracks: stream ? stream.getTracks() : null,
347
350
  kind,
@@ -370,9 +373,9 @@ export default class WebRTCPhone extends Emitter {
370
373
  }
371
374
  const screenTrack = screenShareStream.getVideoTracks()[0];
372
375
  const sipSession = this.currentSipSession;
373
- const pc = sipSession && this.client.getPeerConnection(getSipSessionId(sipSession));
376
+ const pc = sipSession && this.client.getPeerConnection(getSipCallId(sipSession));
374
377
  const sender = pc && pc.getSenders && pc.getSenders().find((s) => s && s.track && s.track.kind === 'video');
375
- const localStream = sipSession && this.client.getLocalStream(getSipSessionId(sipSession));
378
+ const localStream = sipSession && this.client.getLocalStream(getSipCallId(sipSession));
376
379
  const videoTrack = localStream ? localStream.getTracks().find(track => track.kind === 'video') : null;
377
380
  const hadVideo = !!videoTrack;
378
381
  // Stop local video tracks
@@ -434,19 +437,19 @@ export default class WebRTCPhone extends Emitter {
434
437
  }
435
438
  _onScreenSharing(screenStream, sipSession, callSession, hadVideo, desktop) {
436
439
  const screenTrack = screenStream.getVideoTracks()[0];
437
- const sipSessionId = getSipSessionId(sipSession);
440
+ const sipSessionId = getSipCallId(sipSession);
438
441
  const pc = this.client.getPeerConnection(sipSessionId);
439
442
  const sender = pc && pc.getSenders && pc.getSenders().find((s) => s && s.track && s.track.kind === 'video');
440
443
  logger.info('WebRTC phone - on screensharing', {
441
444
  hadVideo,
442
- id: getSipSessionId(sipSession),
445
+ id: getSipCallId(sipSession),
443
446
  screenTrack,
444
447
  });
445
448
  if (screenTrack) {
446
449
  screenTrack.onended = () => {
447
450
  logger.info('WebRTC phone - on screenshare ended', {
448
451
  hadVideo,
449
- id: getSipSessionId(sipSession),
452
+ id: getSipCallId(sipSession),
450
453
  screenTrack,
451
454
  });
452
455
  this.eventEmitter.emit(ON_SHARE_SCREEN_ENDING, this._createCallSession(sipSession, callSession));
@@ -466,13 +469,13 @@ export default class WebRTCPhone extends Emitter {
466
469
  }
467
470
  _onCallAccepted(sipSession, cameraEnabled) {
468
471
  logger.info('WebRTC phone - on call accepted', {
469
- sipId: sipSession.id,
472
+ sipId: getSipCallId(sipSession),
470
473
  cameraEnabled,
471
474
  });
472
475
  const callSession = this._createAcceptedCallSession(sipSession, cameraEnabled);
473
476
  if (this.currentSipSession && !this.isCurrentCallSipSession(callSession)) {
474
477
  logger.info('WebRTC phone - on call accepted with another ongoing call, holding it', {
475
- sipId: sipSession.id,
478
+ sipId: getSipCallId(sipSession),
476
479
  cameraEnabled,
477
480
  });
478
481
  this.holdSipSession(this.currentSipSession, this.currentCallSession, true);
@@ -480,7 +483,7 @@ export default class WebRTCPhone extends Emitter {
480
483
  this.currentSipSession = sipSession;
481
484
  this.currentCallSession = callSession;
482
485
  this.eventEmitter.emit(ON_TERMINATE_SOUND, callSession, 'call accepted');
483
- const sipSessionId = getSipSessionId(sipSession);
486
+ const sipSessionId = getSipCallId(sipSession);
484
487
  if (sipSessionId) {
485
488
  this.removeIncomingSessions(sipSessionId);
486
489
  }
@@ -539,9 +542,9 @@ export default class WebRTCPhone extends Emitter {
539
542
  return this.currentSipSession && this.client.changeSessionVideoInputDevice(id, this.currentSipSession);
540
543
  }
541
544
  _onCallTerminated(sipSession) {
542
- const sipSessionId = getSipSessionId(sipSession);
545
+ const sipSessionId = getSipCallId(sipSession);
543
546
  logger.info('WebRTC phone - on call terminated', {
544
- sipId: sipSession.id,
547
+ sipId: getSipCallId(sipSession),
545
548
  sipSessionId,
546
549
  ids: Object.keys(this.callSessions),
547
550
  });
@@ -561,8 +564,8 @@ export default class WebRTCPhone extends Emitter {
561
564
  }
562
565
  if (sipSessionId) {
563
566
  this.removeIncomingSessions(sipSessionId);
567
+ delete this.callSessions[sipSessionId];
564
568
  }
565
- delete this.callSessions[sipSessionId];
566
569
  if (isCurrentSession) {
567
570
  this.currentSipSession = undefined;
568
571
  this.currentCallSession = undefined;
@@ -570,7 +573,7 @@ export default class WebRTCPhone extends Emitter {
570
573
  const hasIncomingCallSession = this.hasIncomingCallSession();
571
574
  // Re-trigger incoming call event for remaining incoming calls
572
575
  logger.info('WebRTC phone - check to re-trigger incoming call', {
573
- sipId: sipSession.id,
576
+ sipId: getSipCallId(sipSession),
574
577
  shouldRetrigger,
575
578
  hasIncomingCallSession,
576
579
  });
@@ -631,7 +634,7 @@ export default class WebRTCPhone extends Emitter {
631
634
  if (!this.currentSipSession) {
632
635
  return false;
633
636
  }
634
- return this.currentSipSession && getSipSessionId(this.currentSipSession) === callSession.getId();
637
+ return this.currentSipSession && getSipCallId(this.currentSipSession) === callSession.getId();
635
638
  }
636
639
  hasVideo(callSession) {
637
640
  return this.client.hasVideo(callSession.getId());
@@ -665,7 +668,7 @@ export default class WebRTCPhone extends Emitter {
665
668
  logger.warn('no CallSession to accept.');
666
669
  return Promise.resolve(null);
667
670
  }
668
- const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
671
+ const sipSessionId = this.getSipCallIdFromCallSession(callSession);
669
672
  if (sipSessionId && !(sipSessionId in this.callSessions)) {
670
673
  logger.warn('Call session already ended or not found, can\'t accept it.', {
671
674
  sipSessionId,
@@ -685,7 +688,7 @@ export default class WebRTCPhone extends Emitter {
685
688
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
686
689
  const sipSession = this.client.getSipSession(callSession.getId());
687
690
  if (sipSession) {
688
- logger.info('accept call, session found', { sipId: sipSession.id });
691
+ logger.info('accept call, session found', { sipId: getSipCallId(sipSession) });
689
692
  return this.client.answer(sipSession, this.allowVideo ? cameraEnabled : false).then(() => {
690
693
  return callSession.sipCallId;
691
694
  }).catch(e => {
@@ -697,7 +700,7 @@ export default class WebRTCPhone extends Emitter {
697
700
  const error = 'No CallSession found to accept.';
698
701
  logger.warn(error, {
699
702
  id: callSession ? callSession.getId() : 'n/a',
700
- ids: this.client.getSipSessionIds(),
703
+ ids: this.client.getSipCallIds(),
701
704
  });
702
705
  if (callSession) {
703
706
  this.eventEmitter.emit(ON_CALL_ERROR, new Error(error), callSession);
@@ -720,7 +723,7 @@ export default class WebRTCPhone extends Emitter {
720
723
  const sipSession = this.findSipSession(callSession);
721
724
  if (sipSession) {
722
725
  logger.info('WebRTC rejecting', {
723
- sipId: sipSession.id,
726
+ sipId: getSipCallId(sipSession),
724
727
  });
725
728
  this.client.hangup(sipSession);
726
729
  }
@@ -738,7 +741,7 @@ export default class WebRTCPhone extends Emitter {
738
741
  const sipSession = this.findSipSession(callSession);
739
742
  if (sipSession) {
740
743
  logger.info('WebRTC atxfer', {
741
- sipId: sipSession.id,
744
+ sipId: getSipCallId(sipSession),
742
745
  });
743
746
  return this.client.atxfer(sipSession);
744
747
  }
@@ -764,12 +767,12 @@ export default class WebRTCPhone extends Emitter {
764
767
  return new Promise((resolve, reject) => reject(new Error('No session to resume')));
765
768
  }
766
769
  logger.info('WebRTC resuming', {
767
- sipId: sipSession.id,
770
+ sipId: getSipCallId(sipSession),
768
771
  });
769
772
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
770
- if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
773
+ if (this.currentSipSession && getSipCallId(this.currentSipSession) !== getSipCallId(sipSession)) {
771
774
  logger.info('WebRTC hold call after resume', {
772
- id: this.currentSipSession.id,
775
+ id: getSipCallId(this.currentSipSession),
773
776
  });
774
777
  this.holdSipSession(this.currentSipSession, this.currentCallSession, withEvent);
775
778
  }
@@ -784,10 +787,10 @@ export default class WebRTCPhone extends Emitter {
784
787
  if (!sipSession) {
785
788
  return new Promise((resolve, reject) => reject(new Error('No session to hold')));
786
789
  }
787
- const sessionId = getSipSessionId(sipSession);
790
+ const sessionId = getSipCallId(sipSession);
788
791
  const hasVideo = this.client.hasLocalVideo(sessionId);
789
792
  logger.info('WebRTC hold sip session', {
790
- sipId: sipSession.id,
793
+ sipId: getSipCallId(sipSession),
791
794
  hasVideo,
792
795
  });
793
796
  // Stop screenshare if needed
@@ -811,7 +814,7 @@ export default class WebRTCPhone extends Emitter {
811
814
  return new Promise((resolve, reject) => reject(new Error('No session to unhold')));
812
815
  }
813
816
  const isConference = !!callSession && callSession.isConference();
814
- const sessionId = getSipSessionId(sipSession);
817
+ const sessionId = getSipCallId(sipSession);
815
818
  logger.info('WebRTC unhold sip session', {
816
819
  sessionId,
817
820
  isConference,
@@ -863,7 +866,7 @@ export default class WebRTCPhone extends Emitter {
863
866
  return;
864
867
  }
865
868
  logger.info('WebRTC muting', {
866
- sipId: sipSession.id,
869
+ sipId: getSipCallId(sipSession),
867
870
  });
868
871
  this.client.mute(sipSession);
869
872
  const newCallSession = this._createCallSession(sipSession, callSession, {
@@ -885,7 +888,7 @@ export default class WebRTCPhone extends Emitter {
885
888
  return;
886
889
  }
887
890
  logger.info('WebRTC unmuting', {
888
- sipId: sipSession.id,
891
+ sipId: getSipCallId(sipSession),
889
892
  });
890
893
  this.client.unmute(sipSession);
891
894
  const newCallSession = this._createCallSession(sipSession, callSession, {
@@ -911,7 +914,7 @@ export default class WebRTCPhone extends Emitter {
911
914
  return;
912
915
  }
913
916
  logger.info('WebRTC turn camera on', {
914
- sipId: sipSession.id,
917
+ sipId: getSipCallId(sipSession),
915
918
  });
916
919
  this.client.toggleCameraOn(sipSession);
917
920
  this.eventEmitter.emit(ON_CAMERA_RESUMED, this._createCameraResumedCallSession(sipSession, callSession));
@@ -922,7 +925,7 @@ export default class WebRTCPhone extends Emitter {
922
925
  return;
923
926
  }
924
927
  logger.info('WebRTC turn camera off', {
925
- sipId: sipSession.id,
928
+ sipId: getSipCallId(sipSession),
926
929
  });
927
930
  this.client.toggleCameraOff(sipSession);
928
931
  this.eventEmitter.emit(ON_CAMERA_DISABLED, this._createCameraDisabledCallSession(sipSession, callSession));
@@ -933,7 +936,7 @@ export default class WebRTCPhone extends Emitter {
933
936
  return;
934
937
  }
935
938
  logger.info('WebRTC send key', {
936
- sipId: sipSession.id,
939
+ sipId: getSipCallId(sipSession),
937
940
  tone,
938
941
  });
939
942
  this.client.sendDTMF(sipSession, tone);
@@ -996,7 +999,7 @@ export default class WebRTCPhone extends Emitter {
996
999
  return;
997
1000
  }
998
1001
  logger.info('WebRTC transfer', {
999
- sipId: sipSession.id,
1002
+ sipId: getSipCallId(sipSession),
1000
1003
  target,
1001
1004
  });
1002
1005
  this.client.transfer(sipSession, target);
@@ -1005,8 +1008,8 @@ export default class WebRTCPhone extends Emitter {
1005
1008
  const sipSession = this.client.getSipSession(source.sipCallId);
1006
1009
  const sipSessionTarget = this.client.getSipSession(destination.sipCallId);
1007
1010
  logger.info('WebRTC indirect transfer', {
1008
- sipId: sipSession ? sipSession.id : null,
1009
- target: sipSessionTarget ? sipSessionTarget.id : null,
1011
+ sipId: sipSession ? getSipCallId(sipSession) : null,
1012
+ target: sipSessionTarget ? getSipCallId(sipSessionTarget) : null,
1010
1013
  });
1011
1014
  if (!sipSessionTarget) {
1012
1015
  return Promise.reject();
@@ -1034,9 +1037,9 @@ export default class WebRTCPhone extends Emitter {
1034
1037
  console.error('Call is unknown to the WebRTC phone', callSession ? callSession.sipCallId : null, callSession ? callSession.callId : null);
1035
1038
  return false;
1036
1039
  }
1037
- const sipSessionId = getSipSessionId(sipSession);
1040
+ const sipSessionId = getSipCallId(sipSession);
1038
1041
  logger.info('WebRTC hangup', {
1039
- sipId: sipSession.id,
1042
+ sipId: getSipCallId(sipSession),
1040
1043
  sipSessionId,
1041
1044
  });
1042
1045
  await this.client.hangup(sipSession);
@@ -1189,7 +1192,7 @@ export default class WebRTCPhone extends Emitter {
1189
1192
  const autoAnswer = sipSession.request.getHeader('Answer-Mode') === 'Auto';
1190
1193
  const withVideo = this.allowVideo ? wantsToDoVideo : false;
1191
1194
  logger.info('WebRTC invite received', {
1192
- sipId: sipSession.id,
1195
+ sipId: getSipCallId(sipSession),
1193
1196
  withVideo,
1194
1197
  autoAnswer,
1195
1198
  });
@@ -1221,12 +1224,12 @@ export default class WebRTCPhone extends Emitter {
1221
1224
  // if `_createCallSession` is called too soon `hasVideo` will return false because the stream doesn't exists yet
1222
1225
  setTimeout(() => {
1223
1226
  // Update callSession
1224
- this._createCallSession(sipSession, this.callSessions[getSipSessionId(sipSession)]);
1227
+ this._createCallSession(sipSession, this.callSessions[getSipCallId(sipSession)]);
1225
1228
  this.eventEmitter.emit.apply(this.eventEmitter, [this.client.ON_REINVITE, ...args]);
1226
1229
  }, 2000);
1227
1230
  });
1228
1231
  this.client.on(this.client.ACCEPTED, async (sipSession) => {
1229
- const sessionId = getSipSessionId(sipSession);
1232
+ const sessionId = getSipCallId(sipSession);
1230
1233
  const hasSession = (sessionId in this.callSessions);
1231
1234
  logger.info('WebRTC call accepted', {
1232
1235
  sipId: sessionId,
@@ -1249,11 +1252,11 @@ export default class WebRTCPhone extends Emitter {
1249
1252
  this.eventEmitter.emit(ON_CALL_ERROR, e);
1250
1253
  });
1251
1254
  this.client.on(this.client.REJECTED, session => {
1252
- logger.info('WebRTC call rejected', session.id);
1255
+ logger.info('WebRTC call rejected', { id: getSipCallId(session) });
1253
1256
  const callSession = this._createCallSession(session);
1254
1257
  // `_createCallSession` add the CallSession in `this.callSessions`.
1255
1258
  // so we have to remove it or `callCount` will always return 1 even if the call was rejected
1256
- delete this.callSessions[getSipSessionId(session)];
1259
+ delete this.callSessions[getSipCallId(session)];
1257
1260
  callSession.endTime = new Date();
1258
1261
  this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
1259
1262
  });
@@ -1270,7 +1273,7 @@ export default class WebRTCPhone extends Emitter {
1270
1273
  const callSession = this._createCallSession(session, null, {
1271
1274
  incoming: false,
1272
1275
  ringing: true,
1273
- callId: getSipSessionId(session),
1276
+ callId: getSipCallId(session),
1274
1277
  });
1275
1278
  this.eventEmitter.emit(ON_PROGRESS, callSession, this.audioOutputDeviceId, this.audioOutputVolume);
1276
1279
  });
@@ -1279,7 +1282,7 @@ export default class WebRTCPhone extends Emitter {
1279
1282
  const callSession = this._createCallSession(session, null, {
1280
1283
  incoming: false,
1281
1284
  ringing: true,
1282
- callId: getSipSessionId(session),
1285
+ callId: getSipCallId(session),
1283
1286
  });
1284
1287
  this.eventEmitter.emit(ON_EARLY_MEDIA, callSession, this.audioOutputDeviceId, this.audioOutputVolume);
1285
1288
  });
@@ -1335,12 +1338,12 @@ export default class WebRTCPhone extends Emitter {
1335
1338
  this.eventEmitter.emit(ON_MESSAGE, message);
1336
1339
  });
1337
1340
  this.client.on(this.client.ON_NETWORK_STATS, (session, stats, previousStats) => {
1338
- const callSession = this.getCallSession(getSipSessionId(session));
1341
+ const callSession = this.getCallSession(getSipCallId(session));
1339
1342
  this.eventEmitter.emit(ON_NETWORK_STATS, callSession, stats, previousStats);
1340
1343
  });
1341
1344
  // Used when upgrading directly in screenshare mode
1342
1345
  this.client.on(this.client.ON_SCREEN_SHARING_REINVITE, (sipSession, response, desktop) => {
1343
- const sipSessionId = getSipSessionId(sipSession);
1346
+ const sipSessionId = getSipCallId(sipSession);
1344
1347
  const localStream = this.client.getLocalStream(sipSessionId);
1345
1348
  const callSession = this.callSessions[sipSessionId];
1346
1349
  logger.info('Updrading directly in screensharing mode', {
@@ -1352,10 +1355,10 @@ export default class WebRTCPhone extends Emitter {
1352
1355
  }
1353
1356
  // Find a corresponding sipSession from a CallSession
1354
1357
  findSipSession(callSession) {
1355
- const keys = this.client.getSipSessionIds();
1358
+ const keys = this.client.getSipCallIds();
1356
1359
  const keyIndex = keys.findIndex(sessionId => callSession && callSession.isId(sessionId));
1357
1360
  if (keyIndex === -1) {
1358
- const currentSipSessionId = this.currentSipSession ? getSipSessionId(this.currentSipSession) : this.client.getSipSessionIds()[0];
1361
+ const currentSipSessionId = this.currentSipSession ? getSipCallId(this.currentSipSession) : this.client.getSipCallIds()[0];
1359
1362
  return currentSipSessionId ? this.client.getSipSession(currentSipSessionId) : null;
1360
1363
  }
1361
1364
  return this.client.getSipSession(keys[keyIndex]);
@@ -1363,12 +1366,12 @@ export default class WebRTCPhone extends Emitter {
1363
1366
  getCallSession(sipSessionId) {
1364
1367
  return this.callSessions[sipSessionId];
1365
1368
  }
1366
- getSipSessionIdFromCallSession(callSession) {
1369
+ getSipCallIdFromCallSession(callSession) {
1367
1370
  const sipSession = this.findSipSession(callSession);
1368
- return sipSession ? getSipSessionId(sipSession) : null;
1371
+ return sipSession ? getSipCallId(sipSession) : null;
1369
1372
  }
1370
1373
  _updateCallSession(callSession) {
1371
- const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
1374
+ const sipSessionId = this.getSipCallIdFromCallSession(callSession);
1372
1375
  if (sipSessionId) {
1373
1376
  this.callSessions[sipSessionId] = callSession;
1374
1377
  }
@@ -1438,18 +1441,16 @@ export default class WebRTCPhone extends Emitter {
1438
1441
  });
1439
1442
  }
1440
1443
  _createCallSession(sipSession, fromSession, extra = {}) {
1441
- // eslint-disable-next-line
1442
- const identity = sipSession ? sipSession.remoteIdentity || sipSession.assertedIdentity : null;
1443
- // @ts-ignore: private
1444
- const number = identity ? identity.uri._normal.user : null;
1445
- const { state, } = sipSession || {};
1446
- const sessionId = getSipSessionId(sipSession);
1444
+ const number = getCallNumber(sipSession);
1445
+ const displayName = getCallDisplayName(sipSession);
1446
+ const { state } = sipSession || {};
1447
+ const sessionId = getSipCallId(sipSession);
1447
1448
  fromSession = fromSession || this.callSessions[sessionId];
1448
1449
  const callSession = new CallSession({
1449
1450
  callId: fromSession && fromSession.callId,
1450
1451
  sipCallId: sessionId,
1451
1452
  sipStatus: state,
1452
- displayName: identity ? identity.displayName || number : number,
1453
+ displayName,
1453
1454
  // @ts-ignore: date / number
1454
1455
  startTime: fromSession ? fromSession.startTime : new Date(),
1455
1456
  creationTime: fromSession ? fromSession.creationTime : null,
package/esm/index.js CHANGED
@@ -3,8 +3,10 @@ export { default as Emitter } from './utils/Emitter';
3
3
  export { default as IssueReporter } from './service/IssueReporter';
4
4
  export { default as BadResponse } from './domain/BadResponse';
5
5
  export { default as ServerError } from './domain/ServerError';
6
+ export { default as InvalidStateTransition } from './domain/InvalidStateTransition';
7
+ export { default as InvalidState } from './domain/InvalidState';
6
8
  export { default as SFUNotAvailableError } from './domain/SFUNotAvailableError';
7
- export { default as Call } from './domain/Call';
9
+ export { default as ApiCall } from './domain/Call';
8
10
  export { default as CallLog } from './domain/CallLog';
9
11
  export { default as Recording } from './domain/Recording';
10
12
  export { default as ChatMessage } from './domain/ChatMessage';
@@ -43,6 +45,8 @@ export { default as WazoApiClient } from './api-client';
43
45
  export { default as Agent } from './domain/Agent';
44
46
  export { default as ExternalApp } from './domain/ExternalApp';
45
47
  export { default as SessionDescriptionHandler } from './lib/WazoSessionDescriptionHandler';
48
+ export { default as Call } from './voice/call';
49
+ export { Softphone } from './voice/softphone';
46
50
  export * from './types/WebSocketMessage';
47
51
  export * from './utils/PhoneNumberUtil';
48
52
  export * from './utils/string';
@@ -1,4 +1,4 @@
1
- import Call from '../domain/Call';
1
+ import ApiCall from '../domain/Call';
2
2
  import getApiClient from './getApiClient';
3
3
  export default class CallApi {
4
4
  static async fetchCallLogs(offset, limit) {
@@ -23,13 +23,13 @@ export default class CallApi {
23
23
  const lineToUse = line || session.primaryLine();
24
24
  return getApiClient().confd.getUserLineSip(session.uuid, lineToUse ? lineToUse.id : '');
25
25
  }
26
- static async cancelCall(callSession) {
27
- return getApiClient().calld.cancelCall(callSession.callId);
26
+ static async cancelCall(call) {
27
+ return getApiClient().calld.cancelCall(call.apiId || '');
28
28
  }
29
29
  static async makeCall(callFromLine, extension, isMobile = false, callbackAllLines = false) {
30
30
  const lineId = callFromLine ? callFromLine.id : null;
31
31
  const response = await getApiClient().calld.makeCall(extension, isMobile, lineId, callbackAllLines);
32
- return Call.parse(response);
32
+ return ApiCall.parse(response);
33
33
  }
34
34
  static async relocateCall(callId, line, contactIdentifier) {
35
35
  return getApiClient().calld.relocateCall(callId, 'line', line, contactIdentifier);
@@ -121,26 +121,23 @@ export class Auth {
121
121
  const rawSession = await getApiClient().auth.samlLogIn(samlSessionId);
122
122
  return this._onAuthenticated(rawSession);
123
123
  }
124
+ async samlLogOut() {
125
+ return await this.logout(false, true);
126
+ }
124
127
  async initiateIdpAuthentication(domain, redirectUrl) {
125
- let response;
126
128
  try {
127
- response = await getApiClient().auth.initiateIdpAuthentication(domain, redirectUrl);
129
+ return await getApiClient().auth.initiateIdpAuthentication(domain, redirectUrl);
128
130
  }
129
131
  catch (e) {
130
- logger.error('Error during IdP authentication initiation:', e.message);
131
- return;
132
- }
133
- if (!response.ok) {
134
- if (response.status === 404) {
135
- throw new NoSamlRouteError('No route found for saml sso');
132
+ logger.error('Error during IdP authentication initialization:', e.message);
133
+ if (e.status === 404) {
134
+ throw new NoSamlRouteError('No route found for SAML SSO');
136
135
  }
137
- if (response.status === 500) {
136
+ if (e.status === 500) {
138
137
  throw new SamlConfigError('SAML/server configuration error');
139
138
  }
140
- const error = await response.json();
141
- throw new Error(error.message || error.reason);
139
+ throw e;
142
140
  }
143
- return response.json();
144
141
  }
145
142
  async logInViaRefreshToken(refreshToken) {
146
143
  const rawSession = await getApiClient().auth.refreshToken(refreshToken, '', this.expiration, this.mobile);
@@ -170,19 +167,25 @@ export class Auth {
170
167
  async generateNewToken(refreshToken) {
171
168
  return getApiClient().auth.refreshToken(refreshToken, '', this.expiration);
172
169
  }
173
- async logout(deleteRefreshToken = true) {
170
+ async logout(deleteRefreshToken = true, saml = false) {
174
171
  try {
175
172
  Wazo.Websocket.close(true);
176
- if (this.clientId && deleteRefreshToken) {
173
+ if (!saml && this.clientId && deleteRefreshToken) {
177
174
  await getApiClient().auth.deleteRefreshToken(this.clientId);
178
175
  }
179
176
  }
180
177
  catch (e) {
181
178
  // Nothing to
182
179
  }
180
+ let response;
183
181
  try {
184
182
  if (this.session?.token) {
185
- await getApiClient().auth.logOut(this.session.token);
183
+ if (saml) {
184
+ response = await getApiClient().auth.samlLogOut();
185
+ }
186
+ else {
187
+ await getApiClient().auth.logOut(this.session.token);
188
+ }
186
189
  }
187
190
  }
188
191
  catch (e) {
@@ -194,6 +197,7 @@ export class Auth {
194
197
  this.authenticated = false;
195
198
  this.usingEdgeServer = undefined;
196
199
  setFetchOptions({});
200
+ return response;
197
201
  }
198
202
  setOnHostFromHeaders(callback) {
199
203
  this.onHostFromHeadersCallback = callback;
@@ -2,16 +2,17 @@ import { SessionState } from 'sip.js/lib/api/session-state';
2
2
  import AdHocAPIConference from '../domain/AdHocAPIConference';
3
3
  import WebRTCPhone, * as PHONE_EVENTS from '../domain/Phone/WebRTCPhone';
4
4
  import { MESSAGE_TYPE_CHAT, MESSAGE_TYPE_SIGNAL } from '../domain/Phone/WebRTCPhone';
5
- import WazoWebRTCClient, { events as clientEvents, transportEvents } from '../web-rtc-client';
5
+ import WebRTCClient, { events as clientEvents, transportEvents } from '../web-rtc-client';
6
6
  import IssueReporter from '../service/IssueReporter';
7
7
  import Emitter from '../utils/Emitter';
8
8
  import Wazo from './index';
9
9
  import SFUNotAvailableError from '../domain/SFUNotAvailableError';
10
- import { getSipSessionId } from '../utils/sdp';
10
+ import { getSipCallId } from '../utils/sdp';
11
11
  const logger = IssueReporter.loggerFor('simple-phone');
12
12
  const sipLogger = IssueReporter.loggerFor('sip.js');
13
13
  const protocolLogger = IssueReporter.loggerFor('sip');
14
14
  const protocolDebugMessages = ['Received WebSocket text message:', 'Sending WebSocket message:'];
15
+ // @deprecated: Use Wazo.Voice.Softphone instead
15
16
  export class Phone extends Emitter {
16
17
  client;
17
18
  phone;
@@ -113,7 +114,7 @@ export class Phone extends Emitter {
113
114
  options.log.logLevel = 'debug';
114
115
  options.log.connector = this._logConnector;
115
116
  }
116
- this.client = new WazoWebRTCClient({
117
+ this.client = new WebRTCClient({
117
118
  host,
118
119
  port: typeof port === 'string' ? parseInt(port, 10) : port,
119
120
  displayName,
@@ -227,11 +228,11 @@ export class Phone extends Emitter {
227
228
  stopNetworkMonitoring(callSession) {
228
229
  return this.phone ? this.phone.stopNetworkMonitoring(callSession) : null;
229
230
  }
230
- getSipSessionId(sipSession) {
231
+ getSipCallId(sipSession) {
231
232
  if (!sipSession || !this.phone) {
232
233
  return null;
233
234
  }
234
- return getSipSessionId(sipSession);
235
+ return getSipCallId(sipSession);
235
236
  }
236
237
  sendMessage(body, sipSession, contentType = 'text/plain') {
237
238
  const toSipSession = sipSession || this.getCurrentSipSession();