@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
@@ -3248,13 +3248,16 @@ var updateFrom = (instance , from ) => {
3248
3248
 
3249
3249
 
3250
3250
 
3251
+
3251
3252
 
3252
3253
 
3253
3254
 
3254
3255
 
3255
3256
 
3257
+
3256
3258
 
3257
3259
 
3260
+
3258
3261
 
3259
3262
 
3260
3263
 
@@ -3271,6 +3274,7 @@ var updateFrom = (instance , from ) => {
3271
3274
 
3272
3275
 
3273
3276
 
3277
+
3274
3278
 
3275
3279
 
3276
3280
  class CallSession {
@@ -3290,10 +3294,14 @@ class CallSession {
3290
3294
 
3291
3295
 
3292
3296
 
3293
-
3297
+
3298
+
3299
+ // = creationTime
3294
3300
 
3295
3301
 
3296
3302
 
3303
+
3304
+
3297
3305
 
3298
3306
 
3299
3307
 
@@ -3329,6 +3337,8 @@ class CallSession {
3329
3337
 
3330
3338
 
3331
3339
 
3340
+
3341
+
3332
3342
 
3333
3343
  constructor({
3334
3344
  answered,
@@ -3342,6 +3352,8 @@ class CallSession {
3342
3352
  paused,
3343
3353
  ringing,
3344
3354
  startTime,
3355
+ creationTime,
3356
+ endTime,
3345
3357
  cameraEnabled,
3346
3358
  dialedExtension,
3347
3359
  sipCallId,
@@ -3354,12 +3366,16 @@ class CallSession {
3354
3366
  recording,
3355
3367
  recordingPaused,
3356
3368
  videoRemotelyDowngraded,
3369
+ sipSession,
3370
+ answerTime,
3357
3371
  } ) {
3358
3372
  this.callId = callId;
3359
3373
  this.sipCallId = sipCallId;
3360
3374
  this.displayName = displayName;
3361
3375
  this.number = number;
3376
+ this.creationTime = creationTime;
3362
3377
  this.startTime = startTime;
3378
+ this.endTime = endTime;
3363
3379
  this.isCaller = isCaller;
3364
3380
  this.answered = answered;
3365
3381
  this.answeredBySystem = answeredBySystem;
@@ -3378,6 +3394,8 @@ class CallSession {
3378
3394
  this.recording = recording || false;
3379
3395
  this.recordingPaused = recordingPaused || false;
3380
3396
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
3397
+ this.sipSession = sipSession;
3398
+ this.answerTime = answerTime || this.answerTime;
3381
3399
 
3382
3400
  // Useful to compare instead of instanceof with minified code
3383
3401
  this.type = 'CallSession';
@@ -3408,7 +3426,7 @@ class CallSession {
3408
3426
  }
3409
3427
 
3410
3428
  answer() {
3411
- this.answered = true;
3429
+ this.answerTime = new Date();
3412
3430
  }
3413
3431
 
3414
3432
  systemAnswer() {
@@ -3564,6 +3582,15 @@ class CallSession {
3564
3582
  return newFrom(callSession, CallSession);
3565
3583
  }
3566
3584
 
3585
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
3586
+ set answered(value ) {
3587
+ this.answerTime = value ? this.answerTime || new Date() : null;
3588
+ }
3589
+
3590
+ get answered() {
3591
+ return !!this.answerTime;
3592
+ }
3593
+
3567
3594
  static parseCall(call ) {
3568
3595
  return new CallSession({
3569
3596
  callId: call.id,
@@ -6346,6 +6373,7 @@ const MAX_REGISTER_TRIES = 10;
6346
6373
 
6347
6374
 
6348
6375
 
6376
+
6349
6377
 
6350
6378
 
6351
6379
 
@@ -7962,6 +7990,13 @@ class WebRTCClient extends Emitter {
7962
7990
  }
7963
7991
 
7964
7992
  _createWebRTCConfiguration(configOverrides = {}) {
7993
+ let { host } = this.config;
7994
+ let port = this.config.port || 443;
7995
+
7996
+ if (this.config.websocketSip) {
7997
+ [host, port = 443] = this.config.websocketSip.split(':');
7998
+ }
7999
+
7965
8000
  const config = {
7966
8001
  authorizationUsername: this.config.authorizationUser,
7967
8002
  authorizationPassword: this.config.password,
@@ -7997,7 +8032,7 @@ class WebRTCClient extends Emitter {
7997
8032
  },
7998
8033
  transportOptions: {
7999
8034
  traceSip: configOverrides.traceSip || false,
8000
- wsServers: `wss://${this.config.host}:${this.config.port || 443}/api/asterisk/ws`,
8035
+ wsServers: `wss://${host}:${port}/api/asterisk/ws`,
8001
8036
  },
8002
8037
  sessionDescriptionHandlerFactoryOptions: {
8003
8038
  modifiers: [replaceLocalIpModifier],
@@ -8459,6 +8494,7 @@ const ON_CAMERA_DISABLED = 'onCameraDisabled';
8459
8494
  const ON_CAMERA_RESUMED = 'onCameraResumed';
8460
8495
  const ON_CALL_CANCELED = 'onCallCanceled';
8461
8496
  const ON_CALL_FAILED = 'onCallFailed';
8497
+ const ON_CALL_REJECTED = 'onCallRejected';
8462
8498
  const ON_CALL_ENDED = 'onCallEnded';
8463
8499
  const ON_CALL_ENDING = 'onCallEnding';
8464
8500
  const ON_MESSAGE = 'onMessage';
@@ -8503,6 +8539,7 @@ const events = [
8503
8539
  ON_CAMERA_DISABLED,
8504
8540
  ON_CALL_FAILED,
8505
8541
  ON_CALL_ENDED,
8542
+ ON_CALL_REJECTED,
8506
8543
  ON_MESSAGE,
8507
8544
  ON_REINVITE,
8508
8545
  ON_TRACK,
@@ -8859,6 +8896,7 @@ class WebRTCPhone extends Emitter {
8859
8896
 
8860
8897
  // Should be called before `_onCallTerminated` or the callCount will not decrement...
8861
8898
  const callSession = this._createCallSession(sipSession);
8899
+ callSession.endTime = new Date();
8862
8900
  const wasCurrentSession = this._onCallTerminated(sipSession);
8863
8901
 
8864
8902
  return this.eventEmitter.emit(ON_CALL_ENDED, callSession, wasCurrentSession);
@@ -9054,6 +9092,8 @@ class WebRTCPhone extends Emitter {
9054
9092
  this.removeIncomingSessions(sipSessionId);
9055
9093
  }
9056
9094
 
9095
+ callSession.answerTime = new Date();
9096
+ this._updateCallSession(callSession);
9057
9097
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
9058
9098
 
9059
9099
  return callSession;
@@ -9269,6 +9309,8 @@ class WebRTCPhone extends Emitter {
9269
9309
  }
9270
9310
 
9271
9311
  this.shouldSendReinvite = false;
9312
+ callSession.answerTime = new Date();
9313
+ this._updateCallSession(callSession);
9272
9314
  this.acceptedSessions[callSession.getId()] = true;
9273
9315
 
9274
9316
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -9368,7 +9410,7 @@ class WebRTCPhone extends Emitter {
9368
9410
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
9369
9411
  if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
9370
9412
  logger$8.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
9371
- this.holdSipSession(this.currentSipSession, callSession);
9413
+ this.holdSipSession(this.currentSipSession, this.currentCallSession);
9372
9414
  }
9373
9415
 
9374
9416
  const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
@@ -9578,6 +9620,8 @@ class WebRTCPhone extends Emitter {
9578
9620
  return Promise.resolve(null);
9579
9621
  }
9580
9622
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
9623
+ callSession.creationTime = new Date();
9624
+ this._updateCallSession(callSession);
9581
9625
 
9582
9626
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
9583
9627
 
@@ -9856,6 +9900,9 @@ class WebRTCPhone extends Emitter {
9856
9900
  callSession);
9857
9901
  }
9858
9902
 
9903
+ callSession.creationTime = new Date();
9904
+ this._updateCallSession(callSession);
9905
+
9859
9906
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
9860
9907
  });
9861
9908
 
@@ -9895,6 +9942,15 @@ class WebRTCPhone extends Emitter {
9895
9942
  this.eventEmitter.emit(ON_CALL_ERROR, e);
9896
9943
  });
9897
9944
 
9945
+ this.client.on(this.client.REJECTED, session => {
9946
+ logger$8.info('WebRTC call rejected', session.id);
9947
+ const callSession = this._createCallSession(session);
9948
+ callSession.endTime = new Date();
9949
+ this._updateCallSession(callSession);
9950
+
9951
+ this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
9952
+ });
9953
+
9898
9954
  this.client.on(this.client.UNREGISTERED, () => {
9899
9955
  logger$8.info('WebRTC unregistered');
9900
9956
  this.eventEmitter.emit(ON_UNREGISTERED);
@@ -10107,6 +10163,7 @@ class WebRTCPhone extends Emitter {
10107
10163
  const number = identity ? identity.uri._normal.user : null;
10108
10164
  const { state } = sipSession || {};
10109
10165
  const sessionId = this.getSipSessionId(sipSession);
10166
+ fromSession = fromSession || this.callSessions[sessionId];
10110
10167
 
10111
10168
  const callSession = new CallSession({
10112
10169
  callId: fromSession && fromSession.callId,
@@ -10114,6 +10171,9 @@ class WebRTCPhone extends Emitter {
10114
10171
  sipStatus: state,
10115
10172
  displayName: identity ? identity.displayName || number : number,
10116
10173
  startTime: fromSession ? fromSession.startTime : new Date(),
10174
+ creationTime: fromSession ? fromSession.creationTime : null,
10175
+ answerTime: fromSession ? fromSession.answerTime : null,
10176
+ endTime: fromSession ? fromSession.endTime : null,
10117
10177
  answered: state === SessionState.Established,
10118
10178
  paused: this.client.isCallHeld(sipSession),
10119
10179
  isCaller: 'incoming' in extra ? !extra.incoming : false,
@@ -10124,6 +10184,7 @@ class WebRTCPhone extends Emitter {
10124
10184
  videoMuted: fromSession ? fromSession.isVideoMuted() : false,
10125
10185
  recording: fromSession ? fromSession.isRecording() : false,
10126
10186
  recordingPaused: false, // @TODO
10187
+ sipSession,
10127
10188
  ...extra,
10128
10189
  });
10129
10190
 
@@ -10152,6 +10213,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10152
10213
  ON_CAMERA_RESUMED: ON_CAMERA_RESUMED,
10153
10214
  ON_CALL_CANCELED: ON_CALL_CANCELED,
10154
10215
  ON_CALL_FAILED: ON_CALL_FAILED,
10216
+ ON_CALL_REJECTED: ON_CALL_REJECTED,
10155
10217
  ON_CALL_ENDED: ON_CALL_ENDED,
10156
10218
  ON_CALL_ENDING: ON_CALL_ENDING,
10157
10219
  ON_MESSAGE: ON_MESSAGE,
@@ -10181,6 +10243,14 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10181
10243
  'default': WebRTCPhone
10182
10244
  });
10183
10245
 
10246
+ /* */
10247
+ class SFUNotAvailableError extends Error {
10248
+ constructor(message = 'Sorry your user is not configured to support video conference') {
10249
+ super(message);
10250
+ this.name = 'SFUNotAvailableError';
10251
+ }
10252
+ }
10253
+
10184
10254
  //
10185
10255
 
10186
10256
  const logger$7 = IssueReporter$1.loggerFor('simple-phone');
@@ -10565,7 +10635,7 @@ class Phone extends Emitter {
10565
10635
 
10566
10636
  checkSfu() {
10567
10637
  if (!this.hasSfu()) {
10568
- throw new Error('Sorry your user is not configured to support video conference');
10638
+ throw new SFUNotAvailableError();
10569
10639
  }
10570
10640
  }
10571
10641
 
@@ -13478,6 +13548,7 @@ const Wazo = {
13478
13548
  InvalidSubscription,
13479
13549
  InvalidAuthorization,
13480
13550
  CanceledCallError,
13551
+ SFUNotAvailableError,
13481
13552
  };
13482
13553
 
13483
13554
  if (window) {
@@ -3248,13 +3248,16 @@ var updateFrom = (instance , from ) => {
3248
3248
 
3249
3249
 
3250
3250
 
3251
+
3251
3252
 
3252
3253
 
3253
3254
 
3254
3255
 
3255
3256
 
3257
+
3256
3258
 
3257
3259
 
3260
+
3258
3261
 
3259
3262
 
3260
3263
 
@@ -3271,6 +3274,7 @@ var updateFrom = (instance , from ) => {
3271
3274
 
3272
3275
 
3273
3276
 
3277
+
3274
3278
 
3275
3279
 
3276
3280
  class CallSession {
@@ -3290,10 +3294,14 @@ class CallSession {
3290
3294
 
3291
3295
 
3292
3296
 
3293
-
3297
+
3298
+
3299
+ // = creationTime
3294
3300
 
3295
3301
 
3296
3302
 
3303
+
3304
+
3297
3305
 
3298
3306
 
3299
3307
 
@@ -3329,6 +3337,8 @@ class CallSession {
3329
3337
 
3330
3338
 
3331
3339
 
3340
+
3341
+
3332
3342
 
3333
3343
  constructor({
3334
3344
  answered,
@@ -3342,6 +3352,8 @@ class CallSession {
3342
3352
  paused,
3343
3353
  ringing,
3344
3354
  startTime,
3355
+ creationTime,
3356
+ endTime,
3345
3357
  cameraEnabled,
3346
3358
  dialedExtension,
3347
3359
  sipCallId,
@@ -3354,12 +3366,16 @@ class CallSession {
3354
3366
  recording,
3355
3367
  recordingPaused,
3356
3368
  videoRemotelyDowngraded,
3369
+ sipSession,
3370
+ answerTime,
3357
3371
  } ) {
3358
3372
  this.callId = callId;
3359
3373
  this.sipCallId = sipCallId;
3360
3374
  this.displayName = displayName;
3361
3375
  this.number = number;
3376
+ this.creationTime = creationTime;
3362
3377
  this.startTime = startTime;
3378
+ this.endTime = endTime;
3363
3379
  this.isCaller = isCaller;
3364
3380
  this.answered = answered;
3365
3381
  this.answeredBySystem = answeredBySystem;
@@ -3378,6 +3394,8 @@ class CallSession {
3378
3394
  this.recording = recording || false;
3379
3395
  this.recordingPaused = recordingPaused || false;
3380
3396
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
3397
+ this.sipSession = sipSession;
3398
+ this.answerTime = answerTime || this.answerTime;
3381
3399
 
3382
3400
  // Useful to compare instead of instanceof with minified code
3383
3401
  this.type = 'CallSession';
@@ -3408,7 +3426,7 @@ class CallSession {
3408
3426
  }
3409
3427
 
3410
3428
  answer() {
3411
- this.answered = true;
3429
+ this.answerTime = new Date();
3412
3430
  }
3413
3431
 
3414
3432
  systemAnswer() {
@@ -3564,6 +3582,15 @@ class CallSession {
3564
3582
  return newFrom(callSession, CallSession);
3565
3583
  }
3566
3584
 
3585
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
3586
+ set answered(value ) {
3587
+ this.answerTime = value ? this.answerTime || new Date() : null;
3588
+ }
3589
+
3590
+ get answered() {
3591
+ return !!this.answerTime;
3592
+ }
3593
+
3567
3594
  static parseCall(call ) {
3568
3595
  return new CallSession({
3569
3596
  callId: call.id,
@@ -6346,6 +6373,7 @@ const MAX_REGISTER_TRIES = 10;
6346
6373
 
6347
6374
 
6348
6375
 
6376
+
6349
6377
 
6350
6378
 
6351
6379
 
@@ -7962,6 +7990,13 @@ class WebRTCClient extends Emitter {
7962
7990
  }
7963
7991
 
7964
7992
  _createWebRTCConfiguration(configOverrides = {}) {
7993
+ let { host } = this.config;
7994
+ let port = this.config.port || 443;
7995
+
7996
+ if (this.config.websocketSip) {
7997
+ [host, port = 443] = this.config.websocketSip.split(':');
7998
+ }
7999
+
7965
8000
  const config = {
7966
8001
  authorizationUsername: this.config.authorizationUser,
7967
8002
  authorizationPassword: this.config.password,
@@ -7997,7 +8032,7 @@ class WebRTCClient extends Emitter {
7997
8032
  },
7998
8033
  transportOptions: {
7999
8034
  traceSip: configOverrides.traceSip || false,
8000
- wsServers: `wss://${this.config.host}:${this.config.port || 443}/api/asterisk/ws`,
8035
+ wsServers: `wss://${host}:${port}/api/asterisk/ws`,
8001
8036
  },
8002
8037
  sessionDescriptionHandlerFactoryOptions: {
8003
8038
  modifiers: [replaceLocalIpModifier],
@@ -8459,6 +8494,7 @@ const ON_CAMERA_DISABLED = 'onCameraDisabled';
8459
8494
  const ON_CAMERA_RESUMED = 'onCameraResumed';
8460
8495
  const ON_CALL_CANCELED = 'onCallCanceled';
8461
8496
  const ON_CALL_FAILED = 'onCallFailed';
8497
+ const ON_CALL_REJECTED = 'onCallRejected';
8462
8498
  const ON_CALL_ENDED = 'onCallEnded';
8463
8499
  const ON_CALL_ENDING = 'onCallEnding';
8464
8500
  const ON_MESSAGE = 'onMessage';
@@ -8503,6 +8539,7 @@ const events = [
8503
8539
  ON_CAMERA_DISABLED,
8504
8540
  ON_CALL_FAILED,
8505
8541
  ON_CALL_ENDED,
8542
+ ON_CALL_REJECTED,
8506
8543
  ON_MESSAGE,
8507
8544
  ON_REINVITE,
8508
8545
  ON_TRACK,
@@ -8859,6 +8896,7 @@ class WebRTCPhone extends Emitter {
8859
8896
 
8860
8897
  // Should be called before `_onCallTerminated` or the callCount will not decrement...
8861
8898
  const callSession = this._createCallSession(sipSession);
8899
+ callSession.endTime = new Date();
8862
8900
  const wasCurrentSession = this._onCallTerminated(sipSession);
8863
8901
 
8864
8902
  return this.eventEmitter.emit(ON_CALL_ENDED, callSession, wasCurrentSession);
@@ -9054,6 +9092,8 @@ class WebRTCPhone extends Emitter {
9054
9092
  this.removeIncomingSessions(sipSessionId);
9055
9093
  }
9056
9094
 
9095
+ callSession.answerTime = new Date();
9096
+ this._updateCallSession(callSession);
9057
9097
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
9058
9098
 
9059
9099
  return callSession;
@@ -9269,6 +9309,8 @@ class WebRTCPhone extends Emitter {
9269
9309
  }
9270
9310
 
9271
9311
  this.shouldSendReinvite = false;
9312
+ callSession.answerTime = new Date();
9313
+ this._updateCallSession(callSession);
9272
9314
  this.acceptedSessions[callSession.getId()] = true;
9273
9315
 
9274
9316
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -9368,7 +9410,7 @@ class WebRTCPhone extends Emitter {
9368
9410
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
9369
9411
  if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
9370
9412
  logger$8.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
9371
- this.holdSipSession(this.currentSipSession, callSession);
9413
+ this.holdSipSession(this.currentSipSession, this.currentCallSession);
9372
9414
  }
9373
9415
 
9374
9416
  const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
@@ -9578,6 +9620,8 @@ class WebRTCPhone extends Emitter {
9578
9620
  return Promise.resolve(null);
9579
9621
  }
9580
9622
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
9623
+ callSession.creationTime = new Date();
9624
+ this._updateCallSession(callSession);
9581
9625
 
9582
9626
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
9583
9627
 
@@ -9856,6 +9900,9 @@ class WebRTCPhone extends Emitter {
9856
9900
  callSession);
9857
9901
  }
9858
9902
 
9903
+ callSession.creationTime = new Date();
9904
+ this._updateCallSession(callSession);
9905
+
9859
9906
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
9860
9907
  });
9861
9908
 
@@ -9895,6 +9942,15 @@ class WebRTCPhone extends Emitter {
9895
9942
  this.eventEmitter.emit(ON_CALL_ERROR, e);
9896
9943
  });
9897
9944
 
9945
+ this.client.on(this.client.REJECTED, session => {
9946
+ logger$8.info('WebRTC call rejected', session.id);
9947
+ const callSession = this._createCallSession(session);
9948
+ callSession.endTime = new Date();
9949
+ this._updateCallSession(callSession);
9950
+
9951
+ this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
9952
+ });
9953
+
9898
9954
  this.client.on(this.client.UNREGISTERED, () => {
9899
9955
  logger$8.info('WebRTC unregistered');
9900
9956
  this.eventEmitter.emit(ON_UNREGISTERED);
@@ -10107,6 +10163,7 @@ class WebRTCPhone extends Emitter {
10107
10163
  const number = identity ? identity.uri._normal.user : null;
10108
10164
  const { state } = sipSession || {};
10109
10165
  const sessionId = this.getSipSessionId(sipSession);
10166
+ fromSession = fromSession || this.callSessions[sessionId];
10110
10167
 
10111
10168
  const callSession = new CallSession({
10112
10169
  callId: fromSession && fromSession.callId,
@@ -10114,6 +10171,9 @@ class WebRTCPhone extends Emitter {
10114
10171
  sipStatus: state,
10115
10172
  displayName: identity ? identity.displayName || number : number,
10116
10173
  startTime: fromSession ? fromSession.startTime : new Date(),
10174
+ creationTime: fromSession ? fromSession.creationTime : null,
10175
+ answerTime: fromSession ? fromSession.answerTime : null,
10176
+ endTime: fromSession ? fromSession.endTime : null,
10117
10177
  answered: state === SessionState.Established,
10118
10178
  paused: this.client.isCallHeld(sipSession),
10119
10179
  isCaller: 'incoming' in extra ? !extra.incoming : false,
@@ -10124,6 +10184,7 @@ class WebRTCPhone extends Emitter {
10124
10184
  videoMuted: fromSession ? fromSession.isVideoMuted() : false,
10125
10185
  recording: fromSession ? fromSession.isRecording() : false,
10126
10186
  recordingPaused: false, // @TODO
10187
+ sipSession,
10127
10188
  ...extra,
10128
10189
  });
10129
10190
 
@@ -10152,6 +10213,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10152
10213
  ON_CAMERA_RESUMED: ON_CAMERA_RESUMED,
10153
10214
  ON_CALL_CANCELED: ON_CALL_CANCELED,
10154
10215
  ON_CALL_FAILED: ON_CALL_FAILED,
10216
+ ON_CALL_REJECTED: ON_CALL_REJECTED,
10155
10217
  ON_CALL_ENDED: ON_CALL_ENDED,
10156
10218
  ON_CALL_ENDING: ON_CALL_ENDING,
10157
10219
  ON_MESSAGE: ON_MESSAGE,
@@ -10181,6 +10243,14 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10181
10243
  'default': WebRTCPhone
10182
10244
  });
10183
10245
 
10246
+ /* */
10247
+ class SFUNotAvailableError extends Error {
10248
+ constructor(message = 'Sorry your user is not configured to support video conference') {
10249
+ super(message);
10250
+ this.name = 'SFUNotAvailableError';
10251
+ }
10252
+ }
10253
+
10184
10254
  //
10185
10255
 
10186
10256
  const logger$7 = IssueReporter$1.loggerFor('simple-phone');
@@ -10565,7 +10635,7 @@ class Phone extends Emitter {
10565
10635
 
10566
10636
  checkSfu() {
10567
10637
  if (!this.hasSfu()) {
10568
- throw new Error('Sorry your user is not configured to support video conference');
10638
+ throw new SFUNotAvailableError();
10569
10639
  }
10570
10640
  }
10571
10641
 
@@ -13461,6 +13531,7 @@ const Wazo = {
13461
13531
  InvalidSubscription,
13462
13532
  InvalidAuthorization,
13463
13533
  CanceledCallError,
13534
+ SFUNotAvailableError,
13464
13535
  };
13465
13536
 
13466
13537
  if (window) {