@wazo/sdk 0.37.27 → 0.37.31

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 (63) hide show
  1. package/README.md +3 -2
  2. package/dist/wazo-sdk.js +4 -4
  3. package/esm/__tests__/web-rtc-client.test.js +9 -1
  4. package/esm/checker/Checker.js +9 -1
  5. package/esm/checker/checks/index.js +9 -1
  6. package/esm/checker/checks/webrtc-transport.js +9 -1
  7. package/esm/checker/checks/webrtc.js +9 -1
  8. package/esm/domain/CallSession.js +29 -2
  9. package/esm/domain/Phone/CTIPhone.js +29 -2
  10. package/esm/domain/Phone/WebRTCPhone.js +57 -4
  11. package/esm/domain/SFUNotAvailableError.js +9 -0
  12. package/esm/domain/__tests__/CallSession.test.js +46 -2
  13. package/esm/domain/__tests__/IndirectTransfer.test.js +29 -2
  14. package/esm/domain/__tests__/Room.test.js +29 -2
  15. package/esm/index.js +77 -5
  16. package/esm/simple/Auth.js +76 -5
  17. package/esm/simple/Configuration.js +76 -5
  18. package/esm/simple/Phone.js +76 -5
  19. package/esm/simple/index.js +76 -5
  20. package/esm/simple/room/LocalParticipant.js +76 -5
  21. package/esm/simple/room/Participant.js +76 -5
  22. package/esm/simple/room/RemoteParticipant.js +76 -5
  23. package/esm/simple/room/Room.js +76 -5
  24. package/esm/simple/room/SipRoom.js +76 -5
  25. package/esm/simple/room/Stream.js +76 -5
  26. package/esm/simple/room/__tests__/RemoteParticipant.test.js +76 -5
  27. package/esm/simple/utils.js +76 -5
  28. package/esm/web-rtc-client.js +9 -1
  29. package/lib/__tests__/web-rtc-client.test.js +9 -1
  30. package/lib/checker/Checker.js +9 -1
  31. package/lib/checker/checks/index.js +9 -1
  32. package/lib/checker/checks/webrtc-transport.js +9 -1
  33. package/lib/checker/checks/webrtc.js +9 -1
  34. package/lib/domain/CallSession.js +29 -2
  35. package/lib/domain/Phone/CTIPhone.js +29 -2
  36. package/lib/domain/Phone/WebRTCPhone.js +57 -3
  37. package/lib/domain/SFUNotAvailableError.js +11 -0
  38. package/lib/domain/__tests__/CallSession.test.js +46 -2
  39. package/lib/domain/__tests__/IndirectTransfer.test.js +29 -2
  40. package/lib/domain/__tests__/Room.test.js +29 -2
  41. package/lib/index.js +77 -5
  42. package/lib/simple/Auth.js +76 -5
  43. package/lib/simple/Configuration.js +76 -5
  44. package/lib/simple/Phone.js +76 -5
  45. package/lib/simple/index.js +76 -5
  46. package/lib/simple/room/LocalParticipant.js +76 -5
  47. package/lib/simple/room/Participant.js +76 -5
  48. package/lib/simple/room/RemoteParticipant.js +76 -5
  49. package/lib/simple/room/Room.js +76 -5
  50. package/lib/simple/room/SipRoom.js +76 -5
  51. package/lib/simple/room/Stream.js +76 -5
  52. package/lib/simple/room/__tests__/RemoteParticipant.test.js +76 -5
  53. package/lib/simple/utils.js +76 -5
  54. package/lib/web-rtc-client.js +9 -1
  55. package/package.json +1 -1
  56. package/src/domain/CallSession.js +32 -4
  57. package/src/domain/Phone/WebRTCPhone.js +27 -1
  58. package/src/domain/SFUNotAvailableError.js +7 -0
  59. package/src/domain/__tests__/CallSession.test.js +17 -0
  60. package/src/index.js +2 -0
  61. package/src/simple/Phone.js +2 -1
  62. package/src/simple/index.js +2 -0
  63. package/src/web-rtc-client.js +9 -1
@@ -3274,13 +3274,16 @@ var updateFrom = (instance , from ) => {
3274
3274
 
3275
3275
 
3276
3276
 
3277
+
3277
3278
 
3278
3279
 
3279
3280
 
3280
3281
 
3281
3282
 
3283
+
3282
3284
 
3283
3285
 
3286
+
3284
3287
 
3285
3288
 
3286
3289
 
@@ -3297,6 +3300,7 @@ var updateFrom = (instance , from ) => {
3297
3300
 
3298
3301
 
3299
3302
 
3303
+
3300
3304
 
3301
3305
 
3302
3306
  class CallSession {
@@ -3316,10 +3320,14 @@ class CallSession {
3316
3320
 
3317
3321
 
3318
3322
 
3319
-
3323
+
3324
+
3325
+ // = creationTime
3320
3326
 
3321
3327
 
3322
3328
 
3329
+
3330
+
3323
3331
 
3324
3332
 
3325
3333
 
@@ -3355,6 +3363,8 @@ class CallSession {
3355
3363
 
3356
3364
 
3357
3365
 
3366
+
3367
+
3358
3368
 
3359
3369
  constructor({
3360
3370
  answered,
@@ -3368,6 +3378,8 @@ class CallSession {
3368
3378
  paused,
3369
3379
  ringing,
3370
3380
  startTime,
3381
+ creationTime,
3382
+ endTime,
3371
3383
  cameraEnabled,
3372
3384
  dialedExtension,
3373
3385
  sipCallId,
@@ -3380,12 +3392,16 @@ class CallSession {
3380
3392
  recording,
3381
3393
  recordingPaused,
3382
3394
  videoRemotelyDowngraded,
3395
+ sipSession,
3396
+ answerTime,
3383
3397
  } ) {
3384
3398
  this.callId = callId;
3385
3399
  this.sipCallId = sipCallId;
3386
3400
  this.displayName = displayName;
3387
3401
  this.number = number;
3402
+ this.creationTime = creationTime;
3388
3403
  this.startTime = startTime;
3404
+ this.endTime = endTime;
3389
3405
  this.isCaller = isCaller;
3390
3406
  this.answered = answered;
3391
3407
  this.answeredBySystem = answeredBySystem;
@@ -3404,6 +3420,8 @@ class CallSession {
3404
3420
  this.recording = recording || false;
3405
3421
  this.recordingPaused = recordingPaused || false;
3406
3422
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
3423
+ this.sipSession = sipSession;
3424
+ this.answerTime = answerTime || this.answerTime;
3407
3425
 
3408
3426
  // Useful to compare instead of instanceof with minified code
3409
3427
  this.type = 'CallSession';
@@ -3434,7 +3452,7 @@ class CallSession {
3434
3452
  }
3435
3453
 
3436
3454
  answer() {
3437
- this.answered = true;
3455
+ this.answerTime = new Date();
3438
3456
  }
3439
3457
 
3440
3458
  systemAnswer() {
@@ -3590,6 +3608,15 @@ class CallSession {
3590
3608
  return newFrom(callSession, CallSession);
3591
3609
  }
3592
3610
 
3611
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
3612
+ set answered(value ) {
3613
+ this.answerTime = value ? this.answerTime || new Date() : null;
3614
+ }
3615
+
3616
+ get answered() {
3617
+ return !!this.answerTime;
3618
+ }
3619
+
3593
3620
  static parseCall(call ) {
3594
3621
  return new CallSession({
3595
3622
  callId: call.id,
@@ -6610,6 +6637,7 @@ const MAX_REGISTER_TRIES = 10;
6610
6637
 
6611
6638
 
6612
6639
 
6640
+
6613
6641
 
6614
6642
 
6615
6643
 
@@ -8226,6 +8254,13 @@ class WebRTCClient extends Emitter {
8226
8254
  }
8227
8255
 
8228
8256
  _createWebRTCConfiguration(configOverrides = {}) {
8257
+ let { host } = this.config;
8258
+ let port = this.config.port || 443;
8259
+
8260
+ if (this.config.websocketSip) {
8261
+ [host, port = 443] = this.config.websocketSip.split(':');
8262
+ }
8263
+
8229
8264
  const config = {
8230
8265
  authorizationUsername: this.config.authorizationUser,
8231
8266
  authorizationPassword: this.config.password,
@@ -8261,7 +8296,7 @@ class WebRTCClient extends Emitter {
8261
8296
  },
8262
8297
  transportOptions: {
8263
8298
  traceSip: configOverrides.traceSip || false,
8264
- wsServers: `wss://${this.config.host}:${this.config.port || 443}/api/asterisk/ws`,
8299
+ wsServers: `wss://${host}:${port}/api/asterisk/ws`,
8265
8300
  },
8266
8301
  sessionDescriptionHandlerFactoryOptions: {
8267
8302
  modifiers: [replaceLocalIpModifier],
@@ -8723,6 +8758,7 @@ const ON_CAMERA_DISABLED = 'onCameraDisabled';
8723
8758
  const ON_CAMERA_RESUMED = 'onCameraResumed';
8724
8759
  const ON_CALL_CANCELED = 'onCallCanceled';
8725
8760
  const ON_CALL_FAILED = 'onCallFailed';
8761
+ const ON_CALL_REJECTED = 'onCallRejected';
8726
8762
  const ON_CALL_ENDED = 'onCallEnded';
8727
8763
  const ON_CALL_ENDING = 'onCallEnding';
8728
8764
  const ON_MESSAGE = 'onMessage';
@@ -8767,6 +8803,7 @@ const events = [
8767
8803
  ON_CAMERA_DISABLED,
8768
8804
  ON_CALL_FAILED,
8769
8805
  ON_CALL_ENDED,
8806
+ ON_CALL_REJECTED,
8770
8807
  ON_MESSAGE,
8771
8808
  ON_REINVITE,
8772
8809
  ON_TRACK,
@@ -9123,6 +9160,7 @@ class WebRTCPhone extends Emitter {
9123
9160
 
9124
9161
  // Should be called before `_onCallTerminated` or the callCount will not decrement...
9125
9162
  const callSession = this._createCallSession(sipSession);
9163
+ callSession.endTime = new Date();
9126
9164
  const wasCurrentSession = this._onCallTerminated(sipSession);
9127
9165
 
9128
9166
  return this.eventEmitter.emit(ON_CALL_ENDED, callSession, wasCurrentSession);
@@ -9318,6 +9356,8 @@ class WebRTCPhone extends Emitter {
9318
9356
  this.removeIncomingSessions(sipSessionId);
9319
9357
  }
9320
9358
 
9359
+ callSession.answerTime = new Date();
9360
+ this._updateCallSession(callSession);
9321
9361
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
9322
9362
 
9323
9363
  return callSession;
@@ -9533,6 +9573,8 @@ class WebRTCPhone extends Emitter {
9533
9573
  }
9534
9574
 
9535
9575
  this.shouldSendReinvite = false;
9576
+ callSession.answerTime = new Date();
9577
+ this._updateCallSession(callSession);
9536
9578
  this.acceptedSessions[callSession.getId()] = true;
9537
9579
 
9538
9580
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -9632,7 +9674,7 @@ class WebRTCPhone extends Emitter {
9632
9674
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
9633
9675
  if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
9634
9676
  logger$7.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
9635
- this.holdSipSession(this.currentSipSession, callSession);
9677
+ this.holdSipSession(this.currentSipSession, this.currentCallSession);
9636
9678
  }
9637
9679
 
9638
9680
  const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
@@ -9842,6 +9884,8 @@ class WebRTCPhone extends Emitter {
9842
9884
  return Promise.resolve(null);
9843
9885
  }
9844
9886
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
9887
+ callSession.creationTime = new Date();
9888
+ this._updateCallSession(callSession);
9845
9889
 
9846
9890
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
9847
9891
 
@@ -10120,6 +10164,9 @@ class WebRTCPhone extends Emitter {
10120
10164
  callSession);
10121
10165
  }
10122
10166
 
10167
+ callSession.creationTime = new Date();
10168
+ this._updateCallSession(callSession);
10169
+
10123
10170
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
10124
10171
  });
10125
10172
 
@@ -10159,6 +10206,15 @@ class WebRTCPhone extends Emitter {
10159
10206
  this.eventEmitter.emit(ON_CALL_ERROR, e);
10160
10207
  });
10161
10208
 
10209
+ this.client.on(this.client.REJECTED, session => {
10210
+ logger$7.info('WebRTC call rejected', session.id);
10211
+ const callSession = this._createCallSession(session);
10212
+ callSession.endTime = new Date();
10213
+ this._updateCallSession(callSession);
10214
+
10215
+ this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
10216
+ });
10217
+
10162
10218
  this.client.on(this.client.UNREGISTERED, () => {
10163
10219
  logger$7.info('WebRTC unregistered');
10164
10220
  this.eventEmitter.emit(ON_UNREGISTERED);
@@ -10371,6 +10427,7 @@ class WebRTCPhone extends Emitter {
10371
10427
  const number = identity ? identity.uri._normal.user : null;
10372
10428
  const { state } = sipSession || {};
10373
10429
  const sessionId = this.getSipSessionId(sipSession);
10430
+ fromSession = fromSession || this.callSessions[sessionId];
10374
10431
 
10375
10432
  const callSession = new CallSession({
10376
10433
  callId: fromSession && fromSession.callId,
@@ -10378,6 +10435,9 @@ class WebRTCPhone extends Emitter {
10378
10435
  sipStatus: state,
10379
10436
  displayName: identity ? identity.displayName || number : number,
10380
10437
  startTime: fromSession ? fromSession.startTime : new Date(),
10438
+ creationTime: fromSession ? fromSession.creationTime : null,
10439
+ answerTime: fromSession ? fromSession.answerTime : null,
10440
+ endTime: fromSession ? fromSession.endTime : null,
10381
10441
  answered: state === SessionState.Established,
10382
10442
  paused: this.client.isCallHeld(sipSession),
10383
10443
  isCaller: 'incoming' in extra ? !extra.incoming : false,
@@ -10388,6 +10448,7 @@ class WebRTCPhone extends Emitter {
10388
10448
  videoMuted: fromSession ? fromSession.isVideoMuted() : false,
10389
10449
  recording: fromSession ? fromSession.isRecording() : false,
10390
10450
  recordingPaused: false, // @TODO
10451
+ sipSession,
10391
10452
  ...extra,
10392
10453
  });
10393
10454
 
@@ -10416,6 +10477,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10416
10477
  ON_CAMERA_RESUMED: ON_CAMERA_RESUMED,
10417
10478
  ON_CALL_CANCELED: ON_CALL_CANCELED,
10418
10479
  ON_CALL_FAILED: ON_CALL_FAILED,
10480
+ ON_CALL_REJECTED: ON_CALL_REJECTED,
10419
10481
  ON_CALL_ENDED: ON_CALL_ENDED,
10420
10482
  ON_CALL_ENDING: ON_CALL_ENDING,
10421
10483
  ON_MESSAGE: ON_MESSAGE,
@@ -10445,6 +10507,14 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10445
10507
  'default': WebRTCPhone
10446
10508
  });
10447
10509
 
10510
+ /* */
10511
+ class SFUNotAvailableError extends Error {
10512
+ constructor(message = 'Sorry your user is not configured to support video conference') {
10513
+ super(message);
10514
+ this.name = 'SFUNotAvailableError';
10515
+ }
10516
+ }
10517
+
10448
10518
  //
10449
10519
 
10450
10520
  const logger$6 = IssueReporter$1.loggerFor('simple-phone');
@@ -10829,7 +10899,7 @@ class Phone extends Emitter {
10829
10899
 
10830
10900
  checkSfu() {
10831
10901
  if (!this.hasSfu()) {
10832
- throw new Error('Sorry your user is not configured to support video conference');
10902
+ throw new SFUNotAvailableError();
10833
10903
  }
10834
10904
  }
10835
10905
 
@@ -12611,6 +12681,7 @@ const Wazo = {
12611
12681
  InvalidSubscription,
12612
12682
  InvalidAuthorization,
12613
12683
  CanceledCallError,
12684
+ SFUNotAvailableError,
12614
12685
  };
12615
12686
 
12616
12687
  if (window) {
@@ -3274,13 +3274,16 @@ var updateFrom = (instance , from ) => {
3274
3274
 
3275
3275
 
3276
3276
 
3277
+
3277
3278
 
3278
3279
 
3279
3280
 
3280
3281
 
3281
3282
 
3283
+
3282
3284
 
3283
3285
 
3286
+
3284
3287
 
3285
3288
 
3286
3289
 
@@ -3297,6 +3300,7 @@ var updateFrom = (instance , from ) => {
3297
3300
 
3298
3301
 
3299
3302
 
3303
+
3300
3304
 
3301
3305
 
3302
3306
  class CallSession {
@@ -3316,10 +3320,14 @@ class CallSession {
3316
3320
 
3317
3321
 
3318
3322
 
3319
-
3323
+
3324
+
3325
+ // = creationTime
3320
3326
 
3321
3327
 
3322
3328
 
3329
+
3330
+
3323
3331
 
3324
3332
 
3325
3333
 
@@ -3355,6 +3363,8 @@ class CallSession {
3355
3363
 
3356
3364
 
3357
3365
 
3366
+
3367
+
3358
3368
 
3359
3369
  constructor({
3360
3370
  answered,
@@ -3368,6 +3378,8 @@ class CallSession {
3368
3378
  paused,
3369
3379
  ringing,
3370
3380
  startTime,
3381
+ creationTime,
3382
+ endTime,
3371
3383
  cameraEnabled,
3372
3384
  dialedExtension,
3373
3385
  sipCallId,
@@ -3380,12 +3392,16 @@ class CallSession {
3380
3392
  recording,
3381
3393
  recordingPaused,
3382
3394
  videoRemotelyDowngraded,
3395
+ sipSession,
3396
+ answerTime,
3383
3397
  } ) {
3384
3398
  this.callId = callId;
3385
3399
  this.sipCallId = sipCallId;
3386
3400
  this.displayName = displayName;
3387
3401
  this.number = number;
3402
+ this.creationTime = creationTime;
3388
3403
  this.startTime = startTime;
3404
+ this.endTime = endTime;
3389
3405
  this.isCaller = isCaller;
3390
3406
  this.answered = answered;
3391
3407
  this.answeredBySystem = answeredBySystem;
@@ -3404,6 +3420,8 @@ class CallSession {
3404
3420
  this.recording = recording || false;
3405
3421
  this.recordingPaused = recordingPaused || false;
3406
3422
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
3423
+ this.sipSession = sipSession;
3424
+ this.answerTime = answerTime || this.answerTime;
3407
3425
 
3408
3426
  // Useful to compare instead of instanceof with minified code
3409
3427
  this.type = 'CallSession';
@@ -3434,7 +3452,7 @@ class CallSession {
3434
3452
  }
3435
3453
 
3436
3454
  answer() {
3437
- this.answered = true;
3455
+ this.answerTime = new Date();
3438
3456
  }
3439
3457
 
3440
3458
  systemAnswer() {
@@ -3590,6 +3608,15 @@ class CallSession {
3590
3608
  return newFrom(callSession, CallSession);
3591
3609
  }
3592
3610
 
3611
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
3612
+ set answered(value ) {
3613
+ this.answerTime = value ? this.answerTime || new Date() : null;
3614
+ }
3615
+
3616
+ get answered() {
3617
+ return !!this.answerTime;
3618
+ }
3619
+
3593
3620
  static parseCall(call ) {
3594
3621
  return new CallSession({
3595
3622
  callId: call.id,
@@ -6610,6 +6637,7 @@ const MAX_REGISTER_TRIES = 10;
6610
6637
 
6611
6638
 
6612
6639
 
6640
+
6613
6641
 
6614
6642
 
6615
6643
 
@@ -8226,6 +8254,13 @@ class WebRTCClient extends Emitter {
8226
8254
  }
8227
8255
 
8228
8256
  _createWebRTCConfiguration(configOverrides = {}) {
8257
+ let { host } = this.config;
8258
+ let port = this.config.port || 443;
8259
+
8260
+ if (this.config.websocketSip) {
8261
+ [host, port = 443] = this.config.websocketSip.split(':');
8262
+ }
8263
+
8229
8264
  const config = {
8230
8265
  authorizationUsername: this.config.authorizationUser,
8231
8266
  authorizationPassword: this.config.password,
@@ -8261,7 +8296,7 @@ class WebRTCClient extends Emitter {
8261
8296
  },
8262
8297
  transportOptions: {
8263
8298
  traceSip: configOverrides.traceSip || false,
8264
- wsServers: `wss://${this.config.host}:${this.config.port || 443}/api/asterisk/ws`,
8299
+ wsServers: `wss://${host}:${port}/api/asterisk/ws`,
8265
8300
  },
8266
8301
  sessionDescriptionHandlerFactoryOptions: {
8267
8302
  modifiers: [replaceLocalIpModifier],
@@ -8723,6 +8758,7 @@ const ON_CAMERA_DISABLED = 'onCameraDisabled';
8723
8758
  const ON_CAMERA_RESUMED = 'onCameraResumed';
8724
8759
  const ON_CALL_CANCELED = 'onCallCanceled';
8725
8760
  const ON_CALL_FAILED = 'onCallFailed';
8761
+ const ON_CALL_REJECTED = 'onCallRejected';
8726
8762
  const ON_CALL_ENDED = 'onCallEnded';
8727
8763
  const ON_CALL_ENDING = 'onCallEnding';
8728
8764
  const ON_MESSAGE = 'onMessage';
@@ -8767,6 +8803,7 @@ const events = [
8767
8803
  ON_CAMERA_DISABLED,
8768
8804
  ON_CALL_FAILED,
8769
8805
  ON_CALL_ENDED,
8806
+ ON_CALL_REJECTED,
8770
8807
  ON_MESSAGE,
8771
8808
  ON_REINVITE,
8772
8809
  ON_TRACK,
@@ -9123,6 +9160,7 @@ class WebRTCPhone extends Emitter {
9123
9160
 
9124
9161
  // Should be called before `_onCallTerminated` or the callCount will not decrement...
9125
9162
  const callSession = this._createCallSession(sipSession);
9163
+ callSession.endTime = new Date();
9126
9164
  const wasCurrentSession = this._onCallTerminated(sipSession);
9127
9165
 
9128
9166
  return this.eventEmitter.emit(ON_CALL_ENDED, callSession, wasCurrentSession);
@@ -9318,6 +9356,8 @@ class WebRTCPhone extends Emitter {
9318
9356
  this.removeIncomingSessions(sipSessionId);
9319
9357
  }
9320
9358
 
9359
+ callSession.answerTime = new Date();
9360
+ this._updateCallSession(callSession);
9321
9361
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
9322
9362
 
9323
9363
  return callSession;
@@ -9533,6 +9573,8 @@ class WebRTCPhone extends Emitter {
9533
9573
  }
9534
9574
 
9535
9575
  this.shouldSendReinvite = false;
9576
+ callSession.answerTime = new Date();
9577
+ this._updateCallSession(callSession);
9536
9578
  this.acceptedSessions[callSession.getId()] = true;
9537
9579
 
9538
9580
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -9632,7 +9674,7 @@ class WebRTCPhone extends Emitter {
9632
9674
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
9633
9675
  if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
9634
9676
  logger$7.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
9635
- this.holdSipSession(this.currentSipSession, callSession);
9677
+ this.holdSipSession(this.currentSipSession, this.currentCallSession);
9636
9678
  }
9637
9679
 
9638
9680
  const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
@@ -9842,6 +9884,8 @@ class WebRTCPhone extends Emitter {
9842
9884
  return Promise.resolve(null);
9843
9885
  }
9844
9886
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
9887
+ callSession.creationTime = new Date();
9888
+ this._updateCallSession(callSession);
9845
9889
 
9846
9890
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
9847
9891
 
@@ -10120,6 +10164,9 @@ class WebRTCPhone extends Emitter {
10120
10164
  callSession);
10121
10165
  }
10122
10166
 
10167
+ callSession.creationTime = new Date();
10168
+ this._updateCallSession(callSession);
10169
+
10123
10170
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
10124
10171
  });
10125
10172
 
@@ -10159,6 +10206,15 @@ class WebRTCPhone extends Emitter {
10159
10206
  this.eventEmitter.emit(ON_CALL_ERROR, e);
10160
10207
  });
10161
10208
 
10209
+ this.client.on(this.client.REJECTED, session => {
10210
+ logger$7.info('WebRTC call rejected', session.id);
10211
+ const callSession = this._createCallSession(session);
10212
+ callSession.endTime = new Date();
10213
+ this._updateCallSession(callSession);
10214
+
10215
+ this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
10216
+ });
10217
+
10162
10218
  this.client.on(this.client.UNREGISTERED, () => {
10163
10219
  logger$7.info('WebRTC unregistered');
10164
10220
  this.eventEmitter.emit(ON_UNREGISTERED);
@@ -10371,6 +10427,7 @@ class WebRTCPhone extends Emitter {
10371
10427
  const number = identity ? identity.uri._normal.user : null;
10372
10428
  const { state } = sipSession || {};
10373
10429
  const sessionId = this.getSipSessionId(sipSession);
10430
+ fromSession = fromSession || this.callSessions[sessionId];
10374
10431
 
10375
10432
  const callSession = new CallSession({
10376
10433
  callId: fromSession && fromSession.callId,
@@ -10378,6 +10435,9 @@ class WebRTCPhone extends Emitter {
10378
10435
  sipStatus: state,
10379
10436
  displayName: identity ? identity.displayName || number : number,
10380
10437
  startTime: fromSession ? fromSession.startTime : new Date(),
10438
+ creationTime: fromSession ? fromSession.creationTime : null,
10439
+ answerTime: fromSession ? fromSession.answerTime : null,
10440
+ endTime: fromSession ? fromSession.endTime : null,
10381
10441
  answered: state === SessionState.Established,
10382
10442
  paused: this.client.isCallHeld(sipSession),
10383
10443
  isCaller: 'incoming' in extra ? !extra.incoming : false,
@@ -10388,6 +10448,7 @@ class WebRTCPhone extends Emitter {
10388
10448
  videoMuted: fromSession ? fromSession.isVideoMuted() : false,
10389
10449
  recording: fromSession ? fromSession.isRecording() : false,
10390
10450
  recordingPaused: false, // @TODO
10451
+ sipSession,
10391
10452
  ...extra,
10392
10453
  });
10393
10454
 
@@ -10416,6 +10477,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10416
10477
  ON_CAMERA_RESUMED: ON_CAMERA_RESUMED,
10417
10478
  ON_CALL_CANCELED: ON_CALL_CANCELED,
10418
10479
  ON_CALL_FAILED: ON_CALL_FAILED,
10480
+ ON_CALL_REJECTED: ON_CALL_REJECTED,
10419
10481
  ON_CALL_ENDED: ON_CALL_ENDED,
10420
10482
  ON_CALL_ENDING: ON_CALL_ENDING,
10421
10483
  ON_MESSAGE: ON_MESSAGE,
@@ -10445,6 +10507,14 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10445
10507
  'default': WebRTCPhone
10446
10508
  });
10447
10509
 
10510
+ /* */
10511
+ class SFUNotAvailableError extends Error {
10512
+ constructor(message = 'Sorry your user is not configured to support video conference') {
10513
+ super(message);
10514
+ this.name = 'SFUNotAvailableError';
10515
+ }
10516
+ }
10517
+
10448
10518
  //
10449
10519
 
10450
10520
  const logger$6 = IssueReporter$1.loggerFor('simple-phone');
@@ -10829,7 +10899,7 @@ class Phone extends Emitter {
10829
10899
 
10830
10900
  checkSfu() {
10831
10901
  if (!this.hasSfu()) {
10832
- throw new Error('Sorry your user is not configured to support video conference');
10902
+ throw new SFUNotAvailableError();
10833
10903
  }
10834
10904
  }
10835
10905
 
@@ -12616,6 +12686,7 @@ const Wazo = {
12616
12686
  InvalidSubscription,
12617
12687
  InvalidAuthorization,
12618
12688
  CanceledCallError,
12689
+ SFUNotAvailableError,
12619
12690
  };
12620
12691
 
12621
12692
  if (window) {