@wazo/sdk 0.37.25 → 0.37.29

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 (125) hide show
  1. package/README.md +96 -58
  2. package/dist/wazo-sdk.js +3 -3
  3. package/esm/__tests__/api-client.test.js +2 -2
  4. package/esm/__tests__/web-rtc-client.test.js +10 -5
  5. package/esm/api/agentd.js +1 -1
  6. package/esm/api/amid.js +1 -1
  7. package/esm/api/application.js +1 -1
  8. package/esm/api/auth.js +1 -1
  9. package/esm/api/call-logd.js +1 -1
  10. package/esm/api/calld.js +1 -1
  11. package/esm/api/chatd.js +1 -1
  12. package/esm/api/confd.js +1 -1
  13. package/esm/api/ctid-ng.js +1 -1
  14. package/esm/api/dird.js +2 -2
  15. package/esm/api/webhookd.js +1 -1
  16. package/esm/api-client.js +2 -2
  17. package/esm/checker/Checker.js +10 -5
  18. package/esm/checker/checks/aor.js +2 -2
  19. package/esm/checker/checks/api.js +2 -2
  20. package/esm/checker/checks/index.js +10 -5
  21. package/esm/checker/checks/wazo-websocket.js +1 -1
  22. package/esm/checker/checks/webrtc-transport.js +10 -5
  23. package/esm/checker/checks/webrtc.js +10 -5
  24. package/esm/domain/AdHocAPIConference.js +2 -2
  25. package/esm/domain/CallSession.js +29 -2
  26. package/esm/domain/Contact.js +1 -1
  27. package/esm/domain/Features.js +2 -2
  28. package/esm/domain/Phone/CTIPhone.js +31 -4
  29. package/esm/domain/Phone/WebRTCPhone.js +55 -6
  30. package/esm/domain/SFUNotAvailableError.js +9 -0
  31. package/esm/domain/__tests__/CallSession.test.js +46 -2
  32. package/esm/domain/__tests__/Contact.test.js +1 -1
  33. package/esm/domain/__tests__/IndirectTransfer.test.js +29 -2
  34. package/esm/domain/__tests__/Room.test.js +29 -2
  35. package/esm/index.js +75 -10
  36. package/esm/lib/WazoSessionDescriptionHandler.js +9 -4
  37. package/esm/service/CallApi.js +2 -2
  38. package/esm/service/IssueReporter.js +1 -1
  39. package/esm/service/__tests__/IssueReporter.test.js +1 -1
  40. package/esm/service/getApiClient.js +2 -2
  41. package/esm/simple/Auth.js +74 -10
  42. package/esm/simple/Configuration.js +74 -10
  43. package/esm/simple/Directory.js +2 -2
  44. package/esm/simple/Phone.js +74 -10
  45. package/esm/simple/Websocket.js +1 -1
  46. package/esm/simple/index.js +74 -10
  47. package/esm/simple/room/LocalParticipant.js +74 -10
  48. package/esm/simple/room/Participant.js +74 -10
  49. package/esm/simple/room/RemoteParticipant.js +74 -10
  50. package/esm/simple/room/Room.js +74 -10
  51. package/esm/simple/room/SipRoom.js +74 -10
  52. package/esm/simple/room/Stream.js +74 -10
  53. package/esm/simple/room/__tests__/RemoteParticipant.test.js +74 -10
  54. package/esm/simple/utils.js +74 -10
  55. package/esm/utils/__tests__/api-requester.test.js +1 -1
  56. package/esm/utils/api-requester.js +1 -1
  57. package/esm/web-rtc-client.js +10 -5
  58. package/esm/websocket-client.js +1 -1
  59. package/lib/__tests__/api-client.test.js +2 -2
  60. package/lib/__tests__/web-rtc-client.test.js +10 -5
  61. package/lib/api/agentd.js +1 -1
  62. package/lib/api/amid.js +1 -1
  63. package/lib/api/application.js +1 -1
  64. package/lib/api/auth.js +1 -1
  65. package/lib/api/call-logd.js +1 -1
  66. package/lib/api/calld.js +1 -1
  67. package/lib/api/chatd.js +1 -1
  68. package/lib/api/confd.js +1 -1
  69. package/lib/api/ctid-ng.js +1 -1
  70. package/lib/api/dird.js +2 -2
  71. package/lib/api/webhookd.js +1 -1
  72. package/lib/api-client.js +2 -2
  73. package/lib/checker/Checker.js +10 -5
  74. package/lib/checker/checks/aor.js +2 -2
  75. package/lib/checker/checks/api.js +2 -2
  76. package/lib/checker/checks/index.js +10 -5
  77. package/lib/checker/checks/wazo-websocket.js +1 -1
  78. package/lib/checker/checks/webrtc-transport.js +10 -5
  79. package/lib/checker/checks/webrtc.js +10 -5
  80. package/lib/domain/AdHocAPIConference.js +2 -2
  81. package/lib/domain/CallSession.js +29 -2
  82. package/lib/domain/Contact.js +1 -1
  83. package/lib/domain/Features.js +2 -2
  84. package/lib/domain/Phone/CTIPhone.js +31 -4
  85. package/lib/domain/Phone/WebRTCPhone.js +55 -5
  86. package/lib/domain/SFUNotAvailableError.js +11 -0
  87. package/lib/domain/__tests__/CallSession.test.js +46 -2
  88. package/lib/domain/__tests__/Contact.test.js +1 -1
  89. package/lib/domain/__tests__/IndirectTransfer.test.js +29 -2
  90. package/lib/domain/__tests__/Room.test.js +29 -2
  91. package/lib/index.js +75 -10
  92. package/lib/lib/WazoSessionDescriptionHandler.js +9 -4
  93. package/lib/service/CallApi.js +2 -2
  94. package/lib/service/IssueReporter.js +1 -1
  95. package/lib/service/__tests__/IssueReporter.test.js +1 -1
  96. package/lib/service/getApiClient.js +2 -2
  97. package/lib/simple/Auth.js +74 -10
  98. package/lib/simple/Configuration.js +74 -10
  99. package/lib/simple/Directory.js +2 -2
  100. package/lib/simple/Phone.js +74 -10
  101. package/lib/simple/Websocket.js +1 -1
  102. package/lib/simple/index.js +74 -10
  103. package/lib/simple/room/LocalParticipant.js +74 -10
  104. package/lib/simple/room/Participant.js +74 -10
  105. package/lib/simple/room/RemoteParticipant.js +74 -10
  106. package/lib/simple/room/Room.js +74 -10
  107. package/lib/simple/room/SipRoom.js +74 -10
  108. package/lib/simple/room/Stream.js +74 -10
  109. package/lib/simple/room/__tests__/RemoteParticipant.test.js +74 -10
  110. package/lib/simple/utils.js +74 -10
  111. package/lib/utils/__tests__/api-requester.test.js +1 -1
  112. package/lib/utils/api-requester.js +1 -1
  113. package/lib/web-rtc-client.js +10 -5
  114. package/lib/websocket-client.js +1 -1
  115. package/package.json +1 -1
  116. package/src/domain/CallSession.js +32 -4
  117. package/src/domain/Contact.js +1 -1
  118. package/src/domain/Phone/WebRTCPhone.js +24 -2
  119. package/src/domain/SFUNotAvailableError.js +7 -0
  120. package/src/domain/__tests__/CallSession.test.js +17 -0
  121. package/src/index.js +2 -0
  122. package/src/lib/WazoSessionDescriptionHandler.js +8 -3
  123. package/src/simple/Phone.js +2 -1
  124. package/src/simple/index.js +2 -0
  125. package/src/utils/api-requester.js +1 -1
@@ -258,13 +258,16 @@ var updateFrom = (instance , from ) => {
258
258
 
259
259
 
260
260
 
261
+
261
262
 
262
263
 
263
264
 
264
265
 
265
266
 
267
+
266
268
 
267
269
 
270
+
268
271
 
269
272
 
270
273
 
@@ -281,6 +284,7 @@ var updateFrom = (instance , from ) => {
281
284
 
282
285
 
283
286
 
287
+
284
288
 
285
289
 
286
290
  class CallSession {
@@ -300,10 +304,14 @@ class CallSession {
300
304
 
301
305
 
302
306
 
303
-
307
+
308
+
309
+ // = creationTime
304
310
 
305
311
 
306
312
 
313
+
314
+
307
315
 
308
316
 
309
317
 
@@ -339,6 +347,8 @@ class CallSession {
339
347
 
340
348
 
341
349
 
350
+
351
+
342
352
 
343
353
  constructor({
344
354
  answered,
@@ -352,6 +362,8 @@ class CallSession {
352
362
  paused,
353
363
  ringing,
354
364
  startTime,
365
+ creationTime,
366
+ endTime,
355
367
  cameraEnabled,
356
368
  dialedExtension,
357
369
  sipCallId,
@@ -364,12 +376,16 @@ class CallSession {
364
376
  recording,
365
377
  recordingPaused,
366
378
  videoRemotelyDowngraded,
379
+ sipSession,
380
+ answerTime,
367
381
  } ) {
368
382
  this.callId = callId;
369
383
  this.sipCallId = sipCallId;
370
384
  this.displayName = displayName;
371
385
  this.number = number;
386
+ this.creationTime = creationTime;
372
387
  this.startTime = startTime;
388
+ this.endTime = endTime;
373
389
  this.isCaller = isCaller;
374
390
  this.answered = answered;
375
391
  this.answeredBySystem = answeredBySystem;
@@ -388,6 +404,8 @@ class CallSession {
388
404
  this.recording = recording || false;
389
405
  this.recordingPaused = recordingPaused || false;
390
406
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
407
+ this.sipSession = sipSession;
408
+ this.answerTime = answerTime || this.answerTime;
391
409
 
392
410
  // Useful to compare instead of instanceof with minified code
393
411
  this.type = 'CallSession';
@@ -418,7 +436,7 @@ class CallSession {
418
436
  }
419
437
 
420
438
  answer() {
421
- this.answered = true;
439
+ this.answerTime = new Date();
422
440
  }
423
441
 
424
442
  systemAnswer() {
@@ -574,6 +592,15 @@ class CallSession {
574
592
  return newFrom(callSession, CallSession);
575
593
  }
576
594
 
595
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
596
+ set answered(value ) {
597
+ this.answerTime = value ? new Date() : null;
598
+ }
599
+
600
+ get answered() {
601
+ return !!this.answerTime;
602
+ }
603
+
577
604
  static parseCall(call ) {
578
605
  return new CallSession({
579
606
  callId: call.id,
@@ -1038,7 +1065,7 @@ const logger$c = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
1038
1065
 
1039
1066
  // Use a function here to be able to mock it in tests
1040
1067
  const realFetch = () => {
1041
- if (typeof document !== 'undefined') {
1068
+ if (typeof document !== 'undefined' && window.fetch) {
1042
1069
  // Browser
1043
1070
  return window.fetch;
1044
1071
  }
@@ -2487,7 +2514,7 @@ class Contact {
2487
2514
  this[key] = old[key] || this[key];
2488
2515
  });
2489
2516
 
2490
- if (old.lineState && !this.lineState) {
2517
+ if (old.lineState) {
2491
2518
  this.lineState = old.lineState;
2492
2519
  }
2493
2520
 
@@ -5808,11 +5835,16 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
5808
5835
 
5809
5836
  // $FlowFixMe
5810
5837
  setRemoteSessionDescription(sessionDescription ) {
5811
- const result = super.setRemoteSessionDescription(sessionDescription);
5838
+ try {
5839
+ const result = super.setRemoteSessionDescription(sessionDescription);
5812
5840
 
5813
- this.eventEmitter.emit('setDescription', sessionDescription);
5841
+ this.eventEmitter.emit('setDescription', sessionDescription);
5814
5842
 
5815
- return result;
5843
+ return result;
5844
+ } catch (error) {
5845
+ this.logger.error('SessionDescriptionHandler.setRemoteSessionDescription error', error);
5846
+ throw error;
5847
+ }
5816
5848
  }
5817
5849
 
5818
5850
  // Overridden to avoid to fix ice-candidates missing in the SDP in react-native and chrome canary.
@@ -8464,6 +8496,7 @@ const ON_CAMERA_DISABLED = 'onCameraDisabled';
8464
8496
  const ON_CAMERA_RESUMED = 'onCameraResumed';
8465
8497
  const ON_CALL_CANCELED = 'onCallCanceled';
8466
8498
  const ON_CALL_FAILED = 'onCallFailed';
8499
+ const ON_CALL_REJECTED = 'onCallRejected';
8467
8500
  const ON_CALL_ENDED = 'onCallEnded';
8468
8501
  const ON_CALL_ENDING = 'onCallEnding';
8469
8502
  const ON_MESSAGE = 'onMessage';
@@ -8508,6 +8541,7 @@ const events = [
8508
8541
  ON_CAMERA_DISABLED,
8509
8542
  ON_CALL_FAILED,
8510
8543
  ON_CALL_ENDED,
8544
+ ON_CALL_REJECTED,
8511
8545
  ON_MESSAGE,
8512
8546
  ON_REINVITE,
8513
8547
  ON_TRACK,
@@ -8864,6 +8898,7 @@ class WebRTCPhone extends Emitter {
8864
8898
 
8865
8899
  // Should be called before `_onCallTerminated` or the callCount will not decrement...
8866
8900
  const callSession = this._createCallSession(sipSession);
8901
+ callSession.endTime = new Date();
8867
8902
  const wasCurrentSession = this._onCallTerminated(sipSession);
8868
8903
 
8869
8904
  return this.eventEmitter.emit(ON_CALL_ENDED, callSession, wasCurrentSession);
@@ -9059,6 +9094,7 @@ class WebRTCPhone extends Emitter {
9059
9094
  this.removeIncomingSessions(sipSessionId);
9060
9095
  }
9061
9096
 
9097
+ callSession.answerTime = new Date();
9062
9098
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
9063
9099
 
9064
9100
  return callSession;
@@ -9116,6 +9152,7 @@ class WebRTCPhone extends Emitter {
9116
9152
  _onCallTerminated(sipSession ) {
9117
9153
  logger$8.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
9118
9154
 
9155
+ const sipSessionId = this.getSipSessionId(sipSession);
9119
9156
  const callSession = this._createCallSession(sipSession);
9120
9157
  const isCurrentSession = this.isCurrentCallSipSession(callSession);
9121
9158
  const isCurrentIncomingCall = callSession.is(this.getIncomingCallSession());
@@ -9133,7 +9170,6 @@ class WebRTCPhone extends Emitter {
9133
9170
  }, 5);
9134
9171
  }
9135
9172
 
9136
- const sipSessionId = this.getSipSessionId(sipSession);
9137
9173
  if (sipSessionId) {
9138
9174
  this.removeIncomingSessions(sipSessionId);
9139
9175
  }
@@ -9274,6 +9310,7 @@ class WebRTCPhone extends Emitter {
9274
9310
  }
9275
9311
 
9276
9312
  this.shouldSendReinvite = false;
9313
+ callSession.answerTime = new Date();
9277
9314
  this.acceptedSessions[callSession.getId()] = true;
9278
9315
 
9279
9316
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -9583,6 +9620,7 @@ class WebRTCPhone extends Emitter {
9583
9620
  return Promise.resolve(null);
9584
9621
  }
9585
9622
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
9623
+ callSession.creationTime = new Date();
9586
9624
 
9587
9625
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
9588
9626
 
@@ -9778,8 +9816,12 @@ class WebRTCPhone extends Emitter {
9778
9816
  }
9779
9817
 
9780
9818
  const sessionId = this.incomingSessions[0];
9819
+ const sipSession = this.client.getSipSession(sessionId);
9820
+ if (!sipSession) {
9821
+ return null;
9822
+ }
9781
9823
 
9782
- return this._createCallSession(this.client.getSipSession(sessionId));
9824
+ return this._createCallSession(sipSession);
9783
9825
  }
9784
9826
 
9785
9827
  sendMessage(sipSession = null, body , contentType = 'text/plain') {
@@ -9857,6 +9899,7 @@ class WebRTCPhone extends Emitter {
9857
9899
  callSession);
9858
9900
  }
9859
9901
 
9902
+ callSession.creationTime = new Date();
9860
9903
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
9861
9904
  });
9862
9905
 
@@ -9896,6 +9939,13 @@ class WebRTCPhone extends Emitter {
9896
9939
  this.eventEmitter.emit(ON_CALL_ERROR, e);
9897
9940
  });
9898
9941
 
9942
+ this.client.on(this.client.REJECTED, session => {
9943
+ logger$8.info('WebRTC call rejected', session.id);
9944
+ const callSession = this._createCallSession(session);
9945
+ callSession.endTime = new Date();
9946
+ this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
9947
+ });
9948
+
9899
9949
  this.client.on(this.client.UNREGISTERED, () => {
9900
9950
  logger$8.info('WebRTC unregistered');
9901
9951
  this.eventEmitter.emit(ON_UNREGISTERED);
@@ -10108,6 +10158,7 @@ class WebRTCPhone extends Emitter {
10108
10158
  const number = identity ? identity.uri._normal.user : null;
10109
10159
  const { state } = sipSession || {};
10110
10160
  const sessionId = this.getSipSessionId(sipSession);
10161
+ fromSession = fromSession || this.callSessions[sessionId];
10111
10162
 
10112
10163
  const callSession = new CallSession({
10113
10164
  callId: fromSession && fromSession.callId,
@@ -10115,6 +10166,8 @@ class WebRTCPhone extends Emitter {
10115
10166
  sipStatus: state,
10116
10167
  displayName: identity ? identity.displayName || number : number,
10117
10168
  startTime: fromSession ? fromSession.startTime : new Date(),
10169
+ creationTime: fromSession ? fromSession.creationTime : null,
10170
+ endTime: fromSession ? fromSession.endTime : null,
10118
10171
  answered: state === sessionState.SessionState.Established,
10119
10172
  paused: this.client.isCallHeld(sipSession),
10120
10173
  isCaller: 'incoming' in extra ? !extra.incoming : false,
@@ -10125,6 +10178,7 @@ class WebRTCPhone extends Emitter {
10125
10178
  videoMuted: fromSession ? fromSession.isVideoMuted() : false,
10126
10179
  recording: fromSession ? fromSession.isRecording() : false,
10127
10180
  recordingPaused: false, // @TODO
10181
+ sipSession,
10128
10182
  ...extra,
10129
10183
  });
10130
10184
 
@@ -10153,6 +10207,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10153
10207
  ON_CAMERA_RESUMED: ON_CAMERA_RESUMED,
10154
10208
  ON_CALL_CANCELED: ON_CALL_CANCELED,
10155
10209
  ON_CALL_FAILED: ON_CALL_FAILED,
10210
+ ON_CALL_REJECTED: ON_CALL_REJECTED,
10156
10211
  ON_CALL_ENDED: ON_CALL_ENDED,
10157
10212
  ON_CALL_ENDING: ON_CALL_ENDING,
10158
10213
  ON_MESSAGE: ON_MESSAGE,
@@ -12432,6 +12487,14 @@ const createLocalVideoStream = async (options ) => createLocalStream('vid
12432
12487
 
12433
12488
  const createLocalAudioStream = async (options ) => createLocalStream('audio', options);
12434
12489
 
12490
+ /* */
12491
+ class SFUNotAvailableError extends Error {
12492
+ constructor(message = 'Sorry your user is not configured to support video conference') {
12493
+ super(message);
12494
+ this.name = 'SFUNotAvailableError';
12495
+ }
12496
+ }
12497
+
12435
12498
  //
12436
12499
 
12437
12500
 
@@ -13333,6 +13396,7 @@ const Wazo = {
13333
13396
  InvalidSubscription,
13334
13397
  InvalidAuthorization,
13335
13398
  CanceledCallError,
13399
+ SFUNotAvailableError,
13336
13400
  };
13337
13401
 
13338
13402
  if (window) {
@@ -13726,7 +13790,7 @@ class Phone extends Emitter {
13726
13790
 
13727
13791
  checkSfu() {
13728
13792
  if (!this.hasSfu()) {
13729
- throw new Error('Sorry your user is not configured to support video conference');
13793
+ throw new SFUNotAvailableError();
13730
13794
  }
13731
13795
  }
13732
13796
 
@@ -47,7 +47,7 @@ IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
47
47
 
48
48
  // Use a function here to be able to mock it in tests
49
49
  const realFetch = () => {
50
- if (typeof document !== 'undefined') {
50
+ if (typeof document !== 'undefined' && window.fetch) {
51
51
  // Browser
52
52
  return window.fetch;
53
53
  }
@@ -1246,7 +1246,7 @@ class Contact {
1246
1246
  this[key] = old[key] || this[key];
1247
1247
  });
1248
1248
 
1249
- if (old.lineState && !this.lineState) {
1249
+ if (old.lineState) {
1250
1250
  this.lineState = old.lineState;
1251
1251
  }
1252
1252
 
@@ -1961,7 +1961,7 @@ const logger$c = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
1961
1961
 
1962
1962
  // Use a function here to be able to mock it in tests
1963
1963
  const realFetch = () => {
1964
- if (typeof document !== 'undefined') {
1964
+ if (typeof document !== 'undefined' && window.fetch) {
1965
1965
  // Browser
1966
1966
  return window.fetch;
1967
1967
  }
@@ -3258,13 +3258,16 @@ var updateFrom = (instance , from ) => {
3258
3258
 
3259
3259
 
3260
3260
 
3261
+
3261
3262
 
3262
3263
 
3263
3264
 
3264
3265
 
3265
3266
 
3267
+
3266
3268
 
3267
3269
 
3270
+
3268
3271
 
3269
3272
 
3270
3273
 
@@ -3281,6 +3284,7 @@ var updateFrom = (instance , from ) => {
3281
3284
 
3282
3285
 
3283
3286
 
3287
+
3284
3288
 
3285
3289
 
3286
3290
  class CallSession {
@@ -3300,10 +3304,14 @@ class CallSession {
3300
3304
 
3301
3305
 
3302
3306
 
3303
-
3307
+
3308
+
3309
+ // = creationTime
3304
3310
 
3305
3311
 
3306
3312
 
3313
+
3314
+
3307
3315
 
3308
3316
 
3309
3317
 
@@ -3339,6 +3347,8 @@ class CallSession {
3339
3347
 
3340
3348
 
3341
3349
 
3350
+
3351
+
3342
3352
 
3343
3353
  constructor({
3344
3354
  answered,
@@ -3352,6 +3362,8 @@ class CallSession {
3352
3362
  paused,
3353
3363
  ringing,
3354
3364
  startTime,
3365
+ creationTime,
3366
+ endTime,
3355
3367
  cameraEnabled,
3356
3368
  dialedExtension,
3357
3369
  sipCallId,
@@ -3364,12 +3376,16 @@ class CallSession {
3364
3376
  recording,
3365
3377
  recordingPaused,
3366
3378
  videoRemotelyDowngraded,
3379
+ sipSession,
3380
+ answerTime,
3367
3381
  } ) {
3368
3382
  this.callId = callId;
3369
3383
  this.sipCallId = sipCallId;
3370
3384
  this.displayName = displayName;
3371
3385
  this.number = number;
3386
+ this.creationTime = creationTime;
3372
3387
  this.startTime = startTime;
3388
+ this.endTime = endTime;
3373
3389
  this.isCaller = isCaller;
3374
3390
  this.answered = answered;
3375
3391
  this.answeredBySystem = answeredBySystem;
@@ -3388,6 +3404,8 @@ class CallSession {
3388
3404
  this.recording = recording || false;
3389
3405
  this.recordingPaused = recordingPaused || false;
3390
3406
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
3407
+ this.sipSession = sipSession;
3408
+ this.answerTime = answerTime || this.answerTime;
3391
3409
 
3392
3410
  // Useful to compare instead of instanceof with minified code
3393
3411
  this.type = 'CallSession';
@@ -3418,7 +3436,7 @@ class CallSession {
3418
3436
  }
3419
3437
 
3420
3438
  answer() {
3421
- this.answered = true;
3439
+ this.answerTime = new Date();
3422
3440
  }
3423
3441
 
3424
3442
  systemAnswer() {
@@ -3574,6 +3592,15 @@ class CallSession {
3574
3592
  return newFrom(callSession, CallSession);
3575
3593
  }
3576
3594
 
3595
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
3596
+ set answered(value ) {
3597
+ this.answerTime = value ? new Date() : null;
3598
+ }
3599
+
3600
+ get answered() {
3601
+ return !!this.answerTime;
3602
+ }
3603
+
3577
3604
  static parseCall(call ) {
3578
3605
  return new CallSession({
3579
3606
  callId: call.id,
@@ -6072,11 +6099,16 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
6072
6099
 
6073
6100
  // $FlowFixMe
6074
6101
  setRemoteSessionDescription(sessionDescription ) {
6075
- const result = super.setRemoteSessionDescription(sessionDescription);
6102
+ try {
6103
+ const result = super.setRemoteSessionDescription(sessionDescription);
6076
6104
 
6077
- this.eventEmitter.emit('setDescription', sessionDescription);
6105
+ this.eventEmitter.emit('setDescription', sessionDescription);
6078
6106
 
6079
- return result;
6107
+ return result;
6108
+ } catch (error) {
6109
+ this.logger.error('SessionDescriptionHandler.setRemoteSessionDescription error', error);
6110
+ throw error;
6111
+ }
6080
6112
  }
6081
6113
 
6082
6114
  // Overridden to avoid to fix ice-candidates missing in the SDP in react-native and chrome canary.
@@ -8728,6 +8760,7 @@ const ON_CAMERA_DISABLED = 'onCameraDisabled';
8728
8760
  const ON_CAMERA_RESUMED = 'onCameraResumed';
8729
8761
  const ON_CALL_CANCELED = 'onCallCanceled';
8730
8762
  const ON_CALL_FAILED = 'onCallFailed';
8763
+ const ON_CALL_REJECTED = 'onCallRejected';
8731
8764
  const ON_CALL_ENDED = 'onCallEnded';
8732
8765
  const ON_CALL_ENDING = 'onCallEnding';
8733
8766
  const ON_MESSAGE = 'onMessage';
@@ -8772,6 +8805,7 @@ const events = [
8772
8805
  ON_CAMERA_DISABLED,
8773
8806
  ON_CALL_FAILED,
8774
8807
  ON_CALL_ENDED,
8808
+ ON_CALL_REJECTED,
8775
8809
  ON_MESSAGE,
8776
8810
  ON_REINVITE,
8777
8811
  ON_TRACK,
@@ -9128,6 +9162,7 @@ class WebRTCPhone extends Emitter {
9128
9162
 
9129
9163
  // Should be called before `_onCallTerminated` or the callCount will not decrement...
9130
9164
  const callSession = this._createCallSession(sipSession);
9165
+ callSession.endTime = new Date();
9131
9166
  const wasCurrentSession = this._onCallTerminated(sipSession);
9132
9167
 
9133
9168
  return this.eventEmitter.emit(ON_CALL_ENDED, callSession, wasCurrentSession);
@@ -9323,6 +9358,7 @@ class WebRTCPhone extends Emitter {
9323
9358
  this.removeIncomingSessions(sipSessionId);
9324
9359
  }
9325
9360
 
9361
+ callSession.answerTime = new Date();
9326
9362
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
9327
9363
 
9328
9364
  return callSession;
@@ -9380,6 +9416,7 @@ class WebRTCPhone extends Emitter {
9380
9416
  _onCallTerminated(sipSession ) {
9381
9417
  logger$7.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
9382
9418
 
9419
+ const sipSessionId = this.getSipSessionId(sipSession);
9383
9420
  const callSession = this._createCallSession(sipSession);
9384
9421
  const isCurrentSession = this.isCurrentCallSipSession(callSession);
9385
9422
  const isCurrentIncomingCall = callSession.is(this.getIncomingCallSession());
@@ -9397,7 +9434,6 @@ class WebRTCPhone extends Emitter {
9397
9434
  }, 5);
9398
9435
  }
9399
9436
 
9400
- const sipSessionId = this.getSipSessionId(sipSession);
9401
9437
  if (sipSessionId) {
9402
9438
  this.removeIncomingSessions(sipSessionId);
9403
9439
  }
@@ -9538,6 +9574,7 @@ class WebRTCPhone extends Emitter {
9538
9574
  }
9539
9575
 
9540
9576
  this.shouldSendReinvite = false;
9577
+ callSession.answerTime = new Date();
9541
9578
  this.acceptedSessions[callSession.getId()] = true;
9542
9579
 
9543
9580
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -9847,6 +9884,7 @@ class WebRTCPhone extends Emitter {
9847
9884
  return Promise.resolve(null);
9848
9885
  }
9849
9886
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
9887
+ callSession.creationTime = new Date();
9850
9888
 
9851
9889
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
9852
9890
 
@@ -10042,8 +10080,12 @@ class WebRTCPhone extends Emitter {
10042
10080
  }
10043
10081
 
10044
10082
  const sessionId = this.incomingSessions[0];
10083
+ const sipSession = this.client.getSipSession(sessionId);
10084
+ if (!sipSession) {
10085
+ return null;
10086
+ }
10045
10087
 
10046
- return this._createCallSession(this.client.getSipSession(sessionId));
10088
+ return this._createCallSession(sipSession);
10047
10089
  }
10048
10090
 
10049
10091
  sendMessage(sipSession = null, body , contentType = 'text/plain') {
@@ -10121,6 +10163,7 @@ class WebRTCPhone extends Emitter {
10121
10163
  callSession);
10122
10164
  }
10123
10165
 
10166
+ callSession.creationTime = new Date();
10124
10167
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
10125
10168
  });
10126
10169
 
@@ -10160,6 +10203,13 @@ class WebRTCPhone extends Emitter {
10160
10203
  this.eventEmitter.emit(ON_CALL_ERROR, e);
10161
10204
  });
10162
10205
 
10206
+ this.client.on(this.client.REJECTED, session => {
10207
+ logger$7.info('WebRTC call rejected', session.id);
10208
+ const callSession = this._createCallSession(session);
10209
+ callSession.endTime = new Date();
10210
+ this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
10211
+ });
10212
+
10163
10213
  this.client.on(this.client.UNREGISTERED, () => {
10164
10214
  logger$7.info('WebRTC unregistered');
10165
10215
  this.eventEmitter.emit(ON_UNREGISTERED);
@@ -10372,6 +10422,7 @@ class WebRTCPhone extends Emitter {
10372
10422
  const number = identity ? identity.uri._normal.user : null;
10373
10423
  const { state } = sipSession || {};
10374
10424
  const sessionId = this.getSipSessionId(sipSession);
10425
+ fromSession = fromSession || this.callSessions[sessionId];
10375
10426
 
10376
10427
  const callSession = new CallSession({
10377
10428
  callId: fromSession && fromSession.callId,
@@ -10379,6 +10430,8 @@ class WebRTCPhone extends Emitter {
10379
10430
  sipStatus: state,
10380
10431
  displayName: identity ? identity.displayName || number : number,
10381
10432
  startTime: fromSession ? fromSession.startTime : new Date(),
10433
+ creationTime: fromSession ? fromSession.creationTime : null,
10434
+ endTime: fromSession ? fromSession.endTime : null,
10382
10435
  answered: state === sessionState.SessionState.Established,
10383
10436
  paused: this.client.isCallHeld(sipSession),
10384
10437
  isCaller: 'incoming' in extra ? !extra.incoming : false,
@@ -10389,6 +10442,7 @@ class WebRTCPhone extends Emitter {
10389
10442
  videoMuted: fromSession ? fromSession.isVideoMuted() : false,
10390
10443
  recording: fromSession ? fromSession.isRecording() : false,
10391
10444
  recordingPaused: false, // @TODO
10445
+ sipSession,
10392
10446
  ...extra,
10393
10447
  });
10394
10448
 
@@ -10417,6 +10471,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10417
10471
  ON_CAMERA_RESUMED: ON_CAMERA_RESUMED,
10418
10472
  ON_CALL_CANCELED: ON_CALL_CANCELED,
10419
10473
  ON_CALL_FAILED: ON_CALL_FAILED,
10474
+ ON_CALL_REJECTED: ON_CALL_REJECTED,
10420
10475
  ON_CALL_ENDED: ON_CALL_ENDED,
10421
10476
  ON_CALL_ENDING: ON_CALL_ENDING,
10422
10477
  ON_MESSAGE: ON_MESSAGE,
@@ -10446,6 +10501,14 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10446
10501
  'default': WebRTCPhone
10447
10502
  });
10448
10503
 
10504
+ /* */
10505
+ class SFUNotAvailableError extends Error {
10506
+ constructor(message = 'Sorry your user is not configured to support video conference') {
10507
+ super(message);
10508
+ this.name = 'SFUNotAvailableError';
10509
+ }
10510
+ }
10511
+
10449
10512
  //
10450
10513
 
10451
10514
  const logger$6 = IssueReporter$1.loggerFor('simple-phone');
@@ -10830,7 +10893,7 @@ class Phone extends Emitter {
10830
10893
 
10831
10894
  checkSfu() {
10832
10895
  if (!this.hasSfu()) {
10833
- throw new Error('Sorry your user is not configured to support video conference');
10896
+ throw new SFUNotAvailableError();
10834
10897
  }
10835
10898
  }
10836
10899
 
@@ -13743,6 +13806,7 @@ const Wazo = {
13743
13806
  InvalidSubscription,
13744
13807
  InvalidAuthorization,
13745
13808
  CanceledCallError,
13809
+ SFUNotAvailableError,
13746
13810
  };
13747
13811
 
13748
13812
  if (window) {