@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
@@ -32,13 +32,16 @@ var updateFrom = (instance , from ) => {
32
32
 
33
33
 
34
34
 
35
+
35
36
 
36
37
 
37
38
 
38
39
 
39
40
 
41
+
40
42
 
41
43
 
44
+
42
45
 
43
46
 
44
47
 
@@ -55,6 +58,7 @@ var updateFrom = (instance , from ) => {
55
58
 
56
59
 
57
60
 
61
+
58
62
 
59
63
 
60
64
  class CallSession {
@@ -74,10 +78,14 @@ class CallSession {
74
78
 
75
79
 
76
80
 
77
-
81
+
82
+
83
+ // = creationTime
78
84
 
79
85
 
80
86
 
87
+
88
+
81
89
 
82
90
 
83
91
 
@@ -113,6 +121,8 @@ class CallSession {
113
121
 
114
122
 
115
123
 
124
+
125
+
116
126
 
117
127
  constructor({
118
128
  answered,
@@ -126,6 +136,8 @@ class CallSession {
126
136
  paused,
127
137
  ringing,
128
138
  startTime,
139
+ creationTime,
140
+ endTime,
129
141
  cameraEnabled,
130
142
  dialedExtension,
131
143
  sipCallId,
@@ -138,12 +150,16 @@ class CallSession {
138
150
  recording,
139
151
  recordingPaused,
140
152
  videoRemotelyDowngraded,
153
+ sipSession,
154
+ answerTime,
141
155
  } ) {
142
156
  this.callId = callId;
143
157
  this.sipCallId = sipCallId;
144
158
  this.displayName = displayName;
145
159
  this.number = number;
160
+ this.creationTime = creationTime;
146
161
  this.startTime = startTime;
162
+ this.endTime = endTime;
147
163
  this.isCaller = isCaller;
148
164
  this.answered = answered;
149
165
  this.answeredBySystem = answeredBySystem;
@@ -162,6 +178,8 @@ class CallSession {
162
178
  this.recording = recording || false;
163
179
  this.recordingPaused = recordingPaused || false;
164
180
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
181
+ this.sipSession = sipSession;
182
+ this.answerTime = answerTime || this.answerTime;
165
183
 
166
184
  // Useful to compare instead of instanceof with minified code
167
185
  this.type = 'CallSession';
@@ -192,7 +210,7 @@ class CallSession {
192
210
  }
193
211
 
194
212
  answer() {
195
- this.answered = true;
213
+ this.answerTime = new Date();
196
214
  }
197
215
 
198
216
  systemAnswer() {
@@ -348,6 +366,15 @@ class CallSession {
348
366
  return newFrom(callSession, CallSession);
349
367
  }
350
368
 
369
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
370
+ set answered(value ) {
371
+ this.answerTime = value ? this.answerTime || new Date() : null;
372
+ }
373
+
374
+ get answered() {
375
+ return !!this.answerTime;
376
+ }
377
+
351
378
  static parseCall(call ) {
352
379
  return new CallSession({
353
380
  callId: call.id,
@@ -410,4 +437,21 @@ describe('CallSession domain', () => {
410
437
  expect(cs1.is(cs2)).toBeTruthy();
411
438
  expect(cs2.is(cs1)).toBeTruthy();
412
439
  });
440
+
441
+ it('should set answerTime when setting answered', () => {
442
+ const cs1 = new CallSession({});
443
+ cs1.answered = true;
444
+
445
+ const cs2 = new CallSession({});
446
+ cs2.answer();
447
+
448
+ const cs3 = new CallSession({ answered: true });
449
+
450
+ expect(cs1.answered).toBeTruthy();
451
+ expect(cs1.answerTime).not.toBeNull();
452
+ expect(cs2.answered).toBeTruthy();
453
+ expect(cs2.answerTime).not.toBeNull();
454
+ expect(cs3.answered).toBeTruthy();
455
+ expect(cs3.answerTime).not.toBeNull();
456
+ });
413
457
  });
@@ -32,13 +32,16 @@ var updateFrom = (instance , from ) => {
32
32
 
33
33
 
34
34
 
35
+
35
36
 
36
37
 
37
38
 
38
39
 
39
40
 
41
+
40
42
 
41
43
 
44
+
42
45
 
43
46
 
44
47
 
@@ -55,6 +58,7 @@ var updateFrom = (instance , from ) => {
55
58
 
56
59
 
57
60
 
61
+
58
62
 
59
63
 
60
64
  class CallSession {
@@ -74,10 +78,14 @@ class CallSession {
74
78
 
75
79
 
76
80
 
77
-
81
+
82
+
83
+ // = creationTime
78
84
 
79
85
 
80
86
 
87
+
88
+
81
89
 
82
90
 
83
91
 
@@ -113,6 +121,8 @@ class CallSession {
113
121
 
114
122
 
115
123
 
124
+
125
+
116
126
 
117
127
  constructor({
118
128
  answered,
@@ -126,6 +136,8 @@ class CallSession {
126
136
  paused,
127
137
  ringing,
128
138
  startTime,
139
+ creationTime,
140
+ endTime,
129
141
  cameraEnabled,
130
142
  dialedExtension,
131
143
  sipCallId,
@@ -138,12 +150,16 @@ class CallSession {
138
150
  recording,
139
151
  recordingPaused,
140
152
  videoRemotelyDowngraded,
153
+ sipSession,
154
+ answerTime,
141
155
  } ) {
142
156
  this.callId = callId;
143
157
  this.sipCallId = sipCallId;
144
158
  this.displayName = displayName;
145
159
  this.number = number;
160
+ this.creationTime = creationTime;
146
161
  this.startTime = startTime;
162
+ this.endTime = endTime;
147
163
  this.isCaller = isCaller;
148
164
  this.answered = answered;
149
165
  this.answeredBySystem = answeredBySystem;
@@ -162,6 +178,8 @@ class CallSession {
162
178
  this.recording = recording || false;
163
179
  this.recordingPaused = recordingPaused || false;
164
180
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
181
+ this.sipSession = sipSession;
182
+ this.answerTime = answerTime || this.answerTime;
165
183
 
166
184
  // Useful to compare instead of instanceof with minified code
167
185
  this.type = 'CallSession';
@@ -192,7 +210,7 @@ class CallSession {
192
210
  }
193
211
 
194
212
  answer() {
195
- this.answered = true;
213
+ this.answerTime = new Date();
196
214
  }
197
215
 
198
216
  systemAnswer() {
@@ -348,6 +366,15 @@ class CallSession {
348
366
  return newFrom(callSession, CallSession);
349
367
  }
350
368
 
369
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
370
+ set answered(value ) {
371
+ this.answerTime = value ? this.answerTime || new Date() : null;
372
+ }
373
+
374
+ get answered() {
375
+ return !!this.answerTime;
376
+ }
377
+
351
378
  static parseCall(call ) {
352
379
  return new CallSession({
353
380
  callId: call.id,
@@ -32,13 +32,16 @@ var updateFrom = (instance , from ) => {
32
32
 
33
33
 
34
34
 
35
+
35
36
 
36
37
 
37
38
 
38
39
 
39
40
 
41
+
40
42
 
41
43
 
44
+
42
45
 
43
46
 
44
47
 
@@ -55,6 +58,7 @@ var updateFrom = (instance , from ) => {
55
58
 
56
59
 
57
60
 
61
+
58
62
 
59
63
 
60
64
  class CallSession {
@@ -74,10 +78,14 @@ class CallSession {
74
78
 
75
79
 
76
80
 
77
-
81
+
82
+
83
+ // = creationTime
78
84
 
79
85
 
80
86
 
87
+
88
+
81
89
 
82
90
 
83
91
 
@@ -113,6 +121,8 @@ class CallSession {
113
121
 
114
122
 
115
123
 
124
+
125
+
116
126
 
117
127
  constructor({
118
128
  answered,
@@ -126,6 +136,8 @@ class CallSession {
126
136
  paused,
127
137
  ringing,
128
138
  startTime,
139
+ creationTime,
140
+ endTime,
129
141
  cameraEnabled,
130
142
  dialedExtension,
131
143
  sipCallId,
@@ -138,12 +150,16 @@ class CallSession {
138
150
  recording,
139
151
  recordingPaused,
140
152
  videoRemotelyDowngraded,
153
+ sipSession,
154
+ answerTime,
141
155
  } ) {
142
156
  this.callId = callId;
143
157
  this.sipCallId = sipCallId;
144
158
  this.displayName = displayName;
145
159
  this.number = number;
160
+ this.creationTime = creationTime;
146
161
  this.startTime = startTime;
162
+ this.endTime = endTime;
147
163
  this.isCaller = isCaller;
148
164
  this.answered = answered;
149
165
  this.answeredBySystem = answeredBySystem;
@@ -162,6 +178,8 @@ class CallSession {
162
178
  this.recording = recording || false;
163
179
  this.recordingPaused = recordingPaused || false;
164
180
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
181
+ this.sipSession = sipSession;
182
+ this.answerTime = answerTime || this.answerTime;
165
183
 
166
184
  // Useful to compare instead of instanceof with minified code
167
185
  this.type = 'CallSession';
@@ -192,7 +210,7 @@ class CallSession {
192
210
  }
193
211
 
194
212
  answer() {
195
- this.answered = true;
213
+ this.answerTime = new Date();
196
214
  }
197
215
 
198
216
  systemAnswer() {
@@ -348,6 +366,15 @@ class CallSession {
348
366
  return newFrom(callSession, CallSession);
349
367
  }
350
368
 
369
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
370
+ set answered(value ) {
371
+ this.answerTime = value ? this.answerTime || new Date() : null;
372
+ }
373
+
374
+ get answered() {
375
+ return !!this.answerTime;
376
+ }
377
+
351
378
  static parseCall(call ) {
352
379
  return new CallSession({
353
380
  callId: call.id,
package/esm/index.js CHANGED
@@ -3249,13 +3249,16 @@ var updateFrom = (instance , from ) => {
3249
3249
 
3250
3250
 
3251
3251
 
3252
+
3252
3253
 
3253
3254
 
3254
3255
 
3255
3256
 
3256
3257
 
3258
+
3257
3259
 
3258
3260
 
3261
+
3259
3262
 
3260
3263
 
3261
3264
 
@@ -3272,6 +3275,7 @@ var updateFrom = (instance , from ) => {
3272
3275
 
3273
3276
 
3274
3277
 
3278
+
3275
3279
 
3276
3280
 
3277
3281
  class CallSession {
@@ -3291,10 +3295,14 @@ class CallSession {
3291
3295
 
3292
3296
 
3293
3297
 
3294
-
3298
+
3299
+
3300
+ // = creationTime
3295
3301
 
3296
3302
 
3297
3303
 
3304
+
3305
+
3298
3306
 
3299
3307
 
3300
3308
 
@@ -3330,6 +3338,8 @@ class CallSession {
3330
3338
 
3331
3339
 
3332
3340
 
3341
+
3342
+
3333
3343
 
3334
3344
  constructor({
3335
3345
  answered,
@@ -3343,6 +3353,8 @@ class CallSession {
3343
3353
  paused,
3344
3354
  ringing,
3345
3355
  startTime,
3356
+ creationTime,
3357
+ endTime,
3346
3358
  cameraEnabled,
3347
3359
  dialedExtension,
3348
3360
  sipCallId,
@@ -3355,12 +3367,16 @@ class CallSession {
3355
3367
  recording,
3356
3368
  recordingPaused,
3357
3369
  videoRemotelyDowngraded,
3370
+ sipSession,
3371
+ answerTime,
3358
3372
  } ) {
3359
3373
  this.callId = callId;
3360
3374
  this.sipCallId = sipCallId;
3361
3375
  this.displayName = displayName;
3362
3376
  this.number = number;
3377
+ this.creationTime = creationTime;
3363
3378
  this.startTime = startTime;
3379
+ this.endTime = endTime;
3364
3380
  this.isCaller = isCaller;
3365
3381
  this.answered = answered;
3366
3382
  this.answeredBySystem = answeredBySystem;
@@ -3379,6 +3395,8 @@ class CallSession {
3379
3395
  this.recording = recording || false;
3380
3396
  this.recordingPaused = recordingPaused || false;
3381
3397
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
3398
+ this.sipSession = sipSession;
3399
+ this.answerTime = answerTime || this.answerTime;
3382
3400
 
3383
3401
  // Useful to compare instead of instanceof with minified code
3384
3402
  this.type = 'CallSession';
@@ -3409,7 +3427,7 @@ class CallSession {
3409
3427
  }
3410
3428
 
3411
3429
  answer() {
3412
- this.answered = true;
3430
+ this.answerTime = new Date();
3413
3431
  }
3414
3432
 
3415
3433
  systemAnswer() {
@@ -3565,6 +3583,15 @@ class CallSession {
3565
3583
  return newFrom(callSession, CallSession);
3566
3584
  }
3567
3585
 
3586
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
3587
+ set answered(value ) {
3588
+ this.answerTime = value ? this.answerTime || new Date() : null;
3589
+ }
3590
+
3591
+ get answered() {
3592
+ return !!this.answerTime;
3593
+ }
3594
+
3568
3595
  static parseCall(call ) {
3569
3596
  return new CallSession({
3570
3597
  callId: call.id,
@@ -6172,6 +6199,7 @@ const MAX_REGISTER_TRIES = 10;
6172
6199
 
6173
6200
 
6174
6201
 
6202
+
6175
6203
 
6176
6204
 
6177
6205
 
@@ -7788,6 +7816,13 @@ class WebRTCClient extends Emitter {
7788
7816
  }
7789
7817
 
7790
7818
  _createWebRTCConfiguration(configOverrides = {}) {
7819
+ let { host } = this.config;
7820
+ let port = this.config.port || 443;
7821
+
7822
+ if (this.config.websocketSip) {
7823
+ [host, port = 443] = this.config.websocketSip.split(':');
7824
+ }
7825
+
7791
7826
  const config = {
7792
7827
  authorizationUsername: this.config.authorizationUser,
7793
7828
  authorizationPassword: this.config.password,
@@ -7823,7 +7858,7 @@ class WebRTCClient extends Emitter {
7823
7858
  },
7824
7859
  transportOptions: {
7825
7860
  traceSip: configOverrides.traceSip || false,
7826
- wsServers: `wss://${this.config.host}:${this.config.port || 443}/api/asterisk/ws`,
7861
+ wsServers: `wss://${host}:${port}/api/asterisk/ws`,
7827
7862
  },
7828
7863
  sessionDescriptionHandlerFactoryOptions: {
7829
7864
  modifiers: [replaceLocalIpModifier],
@@ -8781,6 +8816,14 @@ var WebSocketClient$1 = /*#__PURE__*/Object.freeze({
8781
8816
  'default': WebSocketClient
8782
8817
  });
8783
8818
 
8819
+ /* */
8820
+ class SFUNotAvailableError extends Error {
8821
+ constructor(message = 'Sorry your user is not configured to support video conference') {
8822
+ super(message);
8823
+ this.name = 'SFUNotAvailableError';
8824
+ }
8825
+ }
8826
+
8784
8827
  var COUNTRIES = {
8785
8828
  BELGIUM: 'BE',
8786
8829
  CANADA: 'CA',
@@ -9178,6 +9221,7 @@ const ON_CAMERA_DISABLED = 'onCameraDisabled';
9178
9221
  const ON_CAMERA_RESUMED = 'onCameraResumed';
9179
9222
  const ON_CALL_CANCELED = 'onCallCanceled';
9180
9223
  const ON_CALL_FAILED = 'onCallFailed';
9224
+ const ON_CALL_REJECTED = 'onCallRejected';
9181
9225
  const ON_CALL_ENDED = 'onCallEnded';
9182
9226
  const ON_CALL_ENDING = 'onCallEnding';
9183
9227
  const ON_MESSAGE = 'onMessage';
@@ -9222,6 +9266,7 @@ const events = [
9222
9266
  ON_CAMERA_DISABLED,
9223
9267
  ON_CALL_FAILED,
9224
9268
  ON_CALL_ENDED,
9269
+ ON_CALL_REJECTED,
9225
9270
  ON_MESSAGE,
9226
9271
  ON_REINVITE,
9227
9272
  ON_TRACK,
@@ -9578,6 +9623,7 @@ class WebRTCPhone extends Emitter {
9578
9623
 
9579
9624
  // Should be called before `_onCallTerminated` or the callCount will not decrement...
9580
9625
  const callSession = this._createCallSession(sipSession);
9626
+ callSession.endTime = new Date();
9581
9627
  const wasCurrentSession = this._onCallTerminated(sipSession);
9582
9628
 
9583
9629
  return this.eventEmitter.emit(ON_CALL_ENDED, callSession, wasCurrentSession);
@@ -9773,6 +9819,8 @@ class WebRTCPhone extends Emitter {
9773
9819
  this.removeIncomingSessions(sipSessionId);
9774
9820
  }
9775
9821
 
9822
+ callSession.answerTime = new Date();
9823
+ this._updateCallSession(callSession);
9776
9824
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
9777
9825
 
9778
9826
  return callSession;
@@ -9988,6 +10036,8 @@ class WebRTCPhone extends Emitter {
9988
10036
  }
9989
10037
 
9990
10038
  this.shouldSendReinvite = false;
10039
+ callSession.answerTime = new Date();
10040
+ this._updateCallSession(callSession);
9991
10041
  this.acceptedSessions[callSession.getId()] = true;
9992
10042
 
9993
10043
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -10087,7 +10137,7 @@ class WebRTCPhone extends Emitter {
10087
10137
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
10088
10138
  if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
10089
10139
  logger$7.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
10090
- this.holdSipSession(this.currentSipSession, callSession);
10140
+ this.holdSipSession(this.currentSipSession, this.currentCallSession);
10091
10141
  }
10092
10142
 
10093
10143
  const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
@@ -10297,6 +10347,8 @@ class WebRTCPhone extends Emitter {
10297
10347
  return Promise.resolve(null);
10298
10348
  }
10299
10349
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
10350
+ callSession.creationTime = new Date();
10351
+ this._updateCallSession(callSession);
10300
10352
 
10301
10353
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
10302
10354
 
@@ -10575,6 +10627,9 @@ class WebRTCPhone extends Emitter {
10575
10627
  callSession);
10576
10628
  }
10577
10629
 
10630
+ callSession.creationTime = new Date();
10631
+ this._updateCallSession(callSession);
10632
+
10578
10633
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
10579
10634
  });
10580
10635
 
@@ -10614,6 +10669,15 @@ class WebRTCPhone extends Emitter {
10614
10669
  this.eventEmitter.emit(ON_CALL_ERROR, e);
10615
10670
  });
10616
10671
 
10672
+ this.client.on(this.client.REJECTED, session => {
10673
+ logger$7.info('WebRTC call rejected', session.id);
10674
+ const callSession = this._createCallSession(session);
10675
+ callSession.endTime = new Date();
10676
+ this._updateCallSession(callSession);
10677
+
10678
+ this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
10679
+ });
10680
+
10617
10681
  this.client.on(this.client.UNREGISTERED, () => {
10618
10682
  logger$7.info('WebRTC unregistered');
10619
10683
  this.eventEmitter.emit(ON_UNREGISTERED);
@@ -10826,6 +10890,7 @@ class WebRTCPhone extends Emitter {
10826
10890
  const number = identity ? identity.uri._normal.user : null;
10827
10891
  const { state } = sipSession || {};
10828
10892
  const sessionId = this.getSipSessionId(sipSession);
10893
+ fromSession = fromSession || this.callSessions[sessionId];
10829
10894
 
10830
10895
  const callSession = new CallSession({
10831
10896
  callId: fromSession && fromSession.callId,
@@ -10833,6 +10898,9 @@ class WebRTCPhone extends Emitter {
10833
10898
  sipStatus: state,
10834
10899
  displayName: identity ? identity.displayName || number : number,
10835
10900
  startTime: fromSession ? fromSession.startTime : new Date(),
10901
+ creationTime: fromSession ? fromSession.creationTime : null,
10902
+ answerTime: fromSession ? fromSession.answerTime : null,
10903
+ endTime: fromSession ? fromSession.endTime : null,
10836
10904
  answered: state === SessionState.Established,
10837
10905
  paused: this.client.isCallHeld(sipSession),
10838
10906
  isCaller: 'incoming' in extra ? !extra.incoming : false,
@@ -10843,6 +10911,7 @@ class WebRTCPhone extends Emitter {
10843
10911
  videoMuted: fromSession ? fromSession.isVideoMuted() : false,
10844
10912
  recording: fromSession ? fromSession.isRecording() : false,
10845
10913
  recordingPaused: false, // @TODO
10914
+ sipSession,
10846
10915
  ...extra,
10847
10916
  });
10848
10917
 
@@ -10871,6 +10940,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10871
10940
  ON_CAMERA_RESUMED: ON_CAMERA_RESUMED,
10872
10941
  ON_CALL_CANCELED: ON_CALL_CANCELED,
10873
10942
  ON_CALL_FAILED: ON_CALL_FAILED,
10943
+ ON_CALL_REJECTED: ON_CALL_REJECTED,
10874
10944
  ON_CALL_ENDED: ON_CALL_ENDED,
10875
10945
  ON_CALL_ENDING: ON_CALL_ENDING,
10876
10946
  ON_MESSAGE: ON_MESSAGE,
@@ -12319,7 +12389,7 @@ class Phone extends Emitter {
12319
12389
 
12320
12390
  checkSfu() {
12321
12391
  if (!this.hasSfu()) {
12322
- throw new Error('Sorry your user is not configured to support video conference');
12392
+ throw new SFUNotAvailableError();
12323
12393
  }
12324
12394
  }
12325
12395
 
@@ -13880,6 +13950,7 @@ const Wazo = {
13880
13950
  InvalidSubscription,
13881
13951
  InvalidAuthorization,
13882
13952
  CanceledCallError,
13953
+ SFUNotAvailableError,
13883
13954
  };
13884
13955
 
13885
13956
  if (window) {
@@ -13922,6 +13993,7 @@ var index = {
13922
13993
  WazoWebSocketClient: WebSocketClient,
13923
13994
  BadResponse,
13924
13995
  ServerError,
13996
+ SFUNotAvailableError,
13925
13997
  Call,
13926
13998
  CallSession,
13927
13999
  CTIPhone,