@wazo/sdk 0.37.29 → 0.37.33

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 (81) hide show
  1. package/README.md +2 -1
  2. package/dist/wazo-sdk.js +4 -4
  3. package/esm/__tests__/api-client.test.js +30 -0
  4. package/esm/__tests__/web-rtc-client.test.js +65 -6
  5. package/esm/api/calld.js +30 -0
  6. package/esm/api-client.js +30 -0
  7. package/esm/checker/Checker.js +65 -6
  8. package/esm/checker/checks/aor.js +30 -0
  9. package/esm/checker/checks/api.js +30 -0
  10. package/esm/checker/checks/index.js +65 -6
  11. package/esm/checker/checks/webrtc-transport.js +65 -6
  12. package/esm/checker/checks/webrtc.js +65 -6
  13. package/esm/domain/AdHocAPIConference.js +30 -0
  14. package/esm/domain/CallSession.js +9 -1
  15. package/esm/domain/Features.js +30 -0
  16. package/esm/domain/MeetingStatus.js +29 -0
  17. package/esm/domain/Phone/CTIPhone.js +39 -1
  18. package/esm/domain/Phone/WebRTCPhone.js +20 -4
  19. package/esm/domain/__tests__/CallSession.test.js +41 -5
  20. package/esm/domain/__tests__/IndirectTransfer.test.js +9 -1
  21. package/esm/domain/__tests__/Room.test.js +9 -1
  22. package/esm/index.js +85 -10
  23. package/esm/service/CallApi.js +30 -0
  24. package/esm/service/getApiClient.js +30 -0
  25. package/esm/simple/Auth.js +85 -10
  26. package/esm/simple/Configuration.js +85 -10
  27. package/esm/simple/Directory.js +30 -0
  28. package/esm/simple/Phone.js +85 -10
  29. package/esm/simple/index.js +85 -10
  30. package/esm/simple/room/LocalParticipant.js +85 -10
  31. package/esm/simple/room/Participant.js +85 -10
  32. package/esm/simple/room/RemoteParticipant.js +85 -10
  33. package/esm/simple/room/Room.js +85 -10
  34. package/esm/simple/room/SipRoom.js +85 -10
  35. package/esm/simple/room/Stream.js +85 -10
  36. package/esm/simple/room/__tests__/RemoteParticipant.test.js +85 -10
  37. package/esm/simple/utils.js +85 -10
  38. package/esm/web-rtc-client.js +65 -6
  39. package/lib/__tests__/api-client.test.js +30 -0
  40. package/lib/__tests__/web-rtc-client.test.js +65 -6
  41. package/lib/api/calld.js +30 -0
  42. package/lib/api-client.js +30 -0
  43. package/lib/checker/Checker.js +65 -6
  44. package/lib/checker/checks/aor.js +30 -0
  45. package/lib/checker/checks/api.js +30 -0
  46. package/lib/checker/checks/index.js +65 -6
  47. package/lib/checker/checks/webrtc-transport.js +65 -6
  48. package/lib/checker/checks/webrtc.js +65 -6
  49. package/lib/domain/AdHocAPIConference.js +30 -0
  50. package/lib/domain/CallSession.js +9 -1
  51. package/lib/domain/Features.js +30 -0
  52. package/lib/domain/MeetingStatus.js +31 -0
  53. package/lib/domain/Phone/CTIPhone.js +39 -1
  54. package/lib/domain/Phone/WebRTCPhone.js +20 -4
  55. package/lib/domain/__tests__/CallSession.test.js +41 -5
  56. package/lib/domain/__tests__/IndirectTransfer.test.js +9 -1
  57. package/lib/domain/__tests__/Room.test.js +9 -1
  58. package/lib/index.js +85 -10
  59. package/lib/service/CallApi.js +30 -0
  60. package/lib/service/getApiClient.js +30 -0
  61. package/lib/simple/Auth.js +85 -10
  62. package/lib/simple/Configuration.js +85 -10
  63. package/lib/simple/Directory.js +30 -0
  64. package/lib/simple/Phone.js +85 -10
  65. package/lib/simple/index.js +85 -10
  66. package/lib/simple/room/LocalParticipant.js +85 -10
  67. package/lib/simple/room/Participant.js +85 -10
  68. package/lib/simple/room/RemoteParticipant.js +85 -10
  69. package/lib/simple/room/Room.js +85 -10
  70. package/lib/simple/room/SipRoom.js +85 -10
  71. package/lib/simple/room/Stream.js +85 -10
  72. package/lib/simple/room/__tests__/RemoteParticipant.test.js +85 -10
  73. package/lib/simple/utils.js +85 -10
  74. package/lib/web-rtc-client.js +65 -6
  75. package/package.json +1 -1
  76. package/src/api/calld.js +3 -0
  77. package/src/domain/CallSession.js +9 -1
  78. package/src/domain/MeetingStatus.js +27 -0
  79. package/src/domain/Phone/WebRTCPhone.js +11 -3
  80. package/src/domain/__tests__/CallSession.test.js +32 -4
  81. package/src/web-rtc-client.js +35 -6
@@ -3584,13 +3584,21 @@ class CallSession {
3584
3584
 
3585
3585
  // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
3586
3586
  set answered(value ) {
3587
- this.answerTime = value ? new Date() : null;
3587
+ this.answerTime = value ? this.answerTime || new Date() : null;
3588
3588
  }
3589
3589
 
3590
3590
  get answered() {
3591
3591
  return !!this.answerTime;
3592
3592
  }
3593
3593
 
3594
+ toJSON() {
3595
+ const jsonObj = { ...this };
3596
+ // $FlowFixMe
3597
+ jsonObj.answered = this.answered;
3598
+
3599
+ return jsonObj;
3600
+ }
3601
+
3594
3602
  static parseCall(call ) {
3595
3603
  return new CallSession({
3596
3604
  callId: call.id,
@@ -4842,6 +4850,34 @@ var chatdMethods = (client , baseUrl ) => ({
4842
4850
  client.get(`${baseUrl}/users/me/rooms/messages`, options),
4843
4851
  });
4844
4852
 
4853
+ //
4854
+
4855
+
4856
+
4857
+
4858
+
4859
+ class MeetingStatus {
4860
+
4861
+
4862
+
4863
+
4864
+ constructor({
4865
+ full,
4866
+ } = {}) {
4867
+ this.full = full;
4868
+
4869
+ // Useful to compare instead of instanceof with minified code
4870
+ this.type = 'MeetingStatus';
4871
+ }
4872
+
4873
+ static parse(plain ) {
4874
+ return new MeetingStatus({
4875
+ full: plain.full,
4876
+ });
4877
+ }
4878
+
4879
+ }
4880
+
4845
4881
  /* */
4846
4882
 
4847
4883
 
@@ -5036,6 +5072,8 @@ var calldMethods = (client , baseUrl ) => ({
5036
5072
  client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
5037
5073
  ApiRequester.successResponseParser),
5038
5074
 
5075
+ guestGetMeetingStatus: (meetingUuid ) =>
5076
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
5039
5077
  });
5040
5078
 
5041
5079
  //
@@ -6373,6 +6411,7 @@ const MAX_REGISTER_TRIES = 10;
6373
6411
 
6374
6412
 
6375
6413
 
6414
+
6376
6415
 
6377
6416
 
6378
6417
 
@@ -6414,6 +6453,7 @@ class WebRTCClient extends Emitter {
6414
6453
 
6415
6454
 
6416
6455
 
6456
+
6417
6457
 
6418
6458
  // sugar
6419
6459
 
@@ -6476,6 +6516,7 @@ class WebRTCClient extends Emitter {
6476
6516
  this.conferences = {};
6477
6517
  this.networkMonitoringInterval = {};
6478
6518
  this.sessionNetworkStats = {};
6519
+ this.forceClosed = false;
6479
6520
 
6480
6521
  this._boundOnHeartbeat = this._onHeartbeat.bind(this);
6481
6522
  this.heartbeat = new Heartbeat(config.heartbeatDelay, config.heartbeatTimeout, config.maxHeartbeats);
@@ -6597,6 +6638,8 @@ class WebRTCClient extends Emitter {
6597
6638
  skipRegister: this.skipRegister,
6598
6639
  };
6599
6640
 
6641
+ this.forceClosed = false;
6642
+
6600
6643
  if (this.skipRegister) {
6601
6644
  logger$9.info('sdk webrtc skip register...', logInfo);
6602
6645
  return Promise.resolve();
@@ -6621,7 +6664,15 @@ class WebRTCClient extends Emitter {
6621
6664
  const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
6622
6665
 
6623
6666
  const onRegisterFailed = () => {
6624
- logger$9.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
6667
+ logger$9.info('sdk webrtc registering failed', {
6668
+ tries,
6669
+ registerer: !!this.registerer,
6670
+ forceClosed: this.forceClosed,
6671
+ });
6672
+ if (this.forceClosed) {
6673
+ return;
6674
+ }
6675
+
6625
6676
  this.connectionPromise = null;
6626
6677
  if (this.registerer && this.registerer.waiting) {
6627
6678
  this.registerer.waitingToggle(false);
@@ -6899,8 +6950,9 @@ class WebRTCClient extends Emitter {
6899
6950
  }
6900
6951
  }
6901
6952
 
6902
- async close() {
6903
- logger$9.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
6953
+ async close(force = false) {
6954
+ logger$9.info('sdk webrtc closing client', { userAgent: !!this.userAgent, force });
6955
+ this.forceClosed = force;
6904
6956
  this._cleanupMedia();
6905
6957
  this.connectionPromise = null;
6906
6958
 
@@ -6919,7 +6971,7 @@ class WebRTCClient extends Emitter {
6919
6971
  this.userAgent.delegate = null;
6920
6972
  this.userAgent.stateChange.removeAllListeners();
6921
6973
 
6922
- await this._disconnectTransport();
6974
+ await this._disconnectTransport(force);
6923
6975
 
6924
6976
  this._cleanupRegister();
6925
6977
 
@@ -7989,6 +8041,13 @@ class WebRTCClient extends Emitter {
7989
8041
  }
7990
8042
 
7991
8043
  _createWebRTCConfiguration(configOverrides = {}) {
8044
+ let { host } = this.config;
8045
+ let port = this.config.port || 443;
8046
+
8047
+ if (this.config.websocketSip) {
8048
+ [host, port = 443] = this.config.websocketSip.split(':');
8049
+ }
8050
+
7992
8051
  const config = {
7993
8052
  authorizationUsername: this.config.authorizationUser,
7994
8053
  authorizationPassword: this.config.password,
@@ -8024,7 +8083,7 @@ class WebRTCClient extends Emitter {
8024
8083
  },
8025
8084
  transportOptions: {
8026
8085
  traceSip: configOverrides.traceSip || false,
8027
- wsServers: `wss://${this.config.host}:${this.config.port || 443}/api/asterisk/ws`,
8086
+ wsServers: `wss://${host}:${port}/api/asterisk/ws`,
8028
8087
  },
8029
8088
  sessionDescriptionHandlerFactoryOptions: {
8030
8089
  modifiers: [replaceLocalIpModifier],
@@ -8348,7 +8407,15 @@ class WebRTCClient extends Emitter {
8348
8407
  return UserAgent.makeURI(`sip:${target}@${this.config.host}`);
8349
8408
  }
8350
8409
 
8351
- async _disconnectTransport() {
8410
+ async _disconnectTransport(force = false) {
8411
+ if (force) {
8412
+ // Bypass sip.js state machine that prevent to close WS with the state `Connecting`
8413
+ this.userAgent.transport.disconnectResolve = () => {};
8414
+ // eslint-disable-next-line
8415
+ this.userAgent.transport._ws.close(1000);
8416
+ return;
8417
+ }
8418
+
8352
8419
  // Check if `disconnectPromise` is not present to avoid `Disconnect promise must not be defined` errors.
8353
8420
  if (this.userAgent && this.userAgent.transport && !this.userAgent.transport.disconnectPromise) {
8354
8421
  try {
@@ -9085,6 +9152,7 @@ class WebRTCPhone extends Emitter {
9085
9152
  }
9086
9153
 
9087
9154
  callSession.answerTime = new Date();
9155
+ this._updateCallSession(callSession);
9088
9156
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
9089
9157
 
9090
9158
  return callSession;
@@ -9301,6 +9369,7 @@ class WebRTCPhone extends Emitter {
9301
9369
 
9302
9370
  this.shouldSendReinvite = false;
9303
9371
  callSession.answerTime = new Date();
9372
+ this._updateCallSession(callSession);
9304
9373
  this.acceptedSessions[callSession.getId()] = true;
9305
9374
 
9306
9375
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -9400,7 +9469,7 @@ class WebRTCPhone extends Emitter {
9400
9469
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
9401
9470
  if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
9402
9471
  logger$8.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
9403
- this.holdSipSession(this.currentSipSession, callSession);
9472
+ this.holdSipSession(this.currentSipSession, this.currentCallSession);
9404
9473
  }
9405
9474
 
9406
9475
  const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
@@ -9611,6 +9680,7 @@ class WebRTCPhone extends Emitter {
9611
9680
  }
9612
9681
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
9613
9682
  callSession.creationTime = new Date();
9683
+ this._updateCallSession(callSession);
9614
9684
 
9615
9685
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
9616
9686
 
@@ -9752,7 +9822,7 @@ class WebRTCPhone extends Emitter {
9752
9822
  return this.client && this.client.isConference(callSession.sipCallId);
9753
9823
  }
9754
9824
 
9755
- async close() {
9825
+ async close(force = false) {
9756
9826
  logger$8.info('WebRTC close');
9757
9827
 
9758
9828
  try {
@@ -9764,7 +9834,7 @@ class WebRTCPhone extends Emitter {
9764
9834
  logger$8.error('WebRTC close, unregister error', e);
9765
9835
  }
9766
9836
 
9767
- this.client.close();
9837
+ this.client.close(force);
9768
9838
  this.unbind();
9769
9839
 
9770
9840
  this.incomingSessions = [];
@@ -9890,6 +9960,8 @@ class WebRTCPhone extends Emitter {
9890
9960
  }
9891
9961
 
9892
9962
  callSession.creationTime = new Date();
9963
+ this._updateCallSession(callSession);
9964
+
9893
9965
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
9894
9966
  });
9895
9967
 
@@ -9933,6 +10005,8 @@ class WebRTCPhone extends Emitter {
9933
10005
  logger$8.info('WebRTC call rejected', session.id);
9934
10006
  const callSession = this._createCallSession(session);
9935
10007
  callSession.endTime = new Date();
10008
+ this._updateCallSession(callSession);
10009
+
9936
10010
  this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
9937
10011
  });
9938
10012
 
@@ -10157,6 +10231,7 @@ class WebRTCPhone extends Emitter {
10157
10231
  displayName: identity ? identity.displayName || number : number,
10158
10232
  startTime: fromSession ? fromSession.startTime : new Date(),
10159
10233
  creationTime: fromSession ? fromSession.creationTime : null,
10234
+ answerTime: fromSession ? fromSession.answerTime : null,
10160
10235
  endTime: fromSession ? fromSession.endTime : null,
10161
10236
  answered: state === SessionState.Established,
10162
10237
  paused: this.client.isCallHeld(sipSession),
@@ -4016,6 +4016,34 @@ var chatdMethods = (client , baseUrl ) => ({
4016
4016
  client.get(`${baseUrl}/users/me/rooms/messages`, options),
4017
4017
  });
4018
4018
 
4019
+ //
4020
+
4021
+
4022
+
4023
+
4024
+
4025
+ class MeetingStatus {
4026
+
4027
+
4028
+
4029
+
4030
+ constructor({
4031
+ full,
4032
+ } = {}) {
4033
+ this.full = full;
4034
+
4035
+ // Useful to compare instead of instanceof with minified code
4036
+ this.type = 'MeetingStatus';
4037
+ }
4038
+
4039
+ static parse(plain ) {
4040
+ return new MeetingStatus({
4041
+ full: plain.full,
4042
+ });
4043
+ }
4044
+
4045
+ }
4046
+
4019
4047
  /* */
4020
4048
 
4021
4049
 
@@ -4210,6 +4238,8 @@ var calldMethods = (client , baseUrl ) => ({
4210
4238
  client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
4211
4239
  ApiRequester.successResponseParser),
4212
4240
 
4241
+ guestGetMeetingStatus: (meetingUuid ) =>
4242
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
4213
4243
  });
4214
4244
 
4215
4245
  //
@@ -584,13 +584,21 @@ class CallSession {
584
584
 
585
585
  // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
586
586
  set answered(value ) {
587
- this.answerTime = value ? new Date() : null;
587
+ this.answerTime = value ? this.answerTime || new Date() : null;
588
588
  }
589
589
 
590
590
  get answered() {
591
591
  return !!this.answerTime;
592
592
  }
593
593
 
594
+ toJSON() {
595
+ const jsonObj = { ...this };
596
+ // $FlowFixMe
597
+ jsonObj.answered = this.answered;
598
+
599
+ return jsonObj;
600
+ }
601
+
594
602
  static parseCall(call ) {
595
603
  return new CallSession({
596
604
  callId: call.id,
@@ -4842,6 +4850,34 @@ var chatdMethods = (client , baseUrl ) => ({
4842
4850
  client.get(`${baseUrl}/users/me/rooms/messages`, options),
4843
4851
  });
4844
4852
 
4853
+ //
4854
+
4855
+
4856
+
4857
+
4858
+
4859
+ class MeetingStatus {
4860
+
4861
+
4862
+
4863
+
4864
+ constructor({
4865
+ full,
4866
+ } = {}) {
4867
+ this.full = full;
4868
+
4869
+ // Useful to compare instead of instanceof with minified code
4870
+ this.type = 'MeetingStatus';
4871
+ }
4872
+
4873
+ static parse(plain ) {
4874
+ return new MeetingStatus({
4875
+ full: plain.full,
4876
+ });
4877
+ }
4878
+
4879
+ }
4880
+
4845
4881
  /* */
4846
4882
 
4847
4883
 
@@ -5036,6 +5072,8 @@ var calldMethods = (client , baseUrl ) => ({
5036
5072
  client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
5037
5073
  ApiRequester.successResponseParser),
5038
5074
 
5075
+ guestGetMeetingStatus: (meetingUuid ) =>
5076
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
5039
5077
  });
5040
5078
 
5041
5079
  //
@@ -6373,6 +6411,7 @@ const MAX_REGISTER_TRIES = 10;
6373
6411
 
6374
6412
 
6375
6413
 
6414
+
6376
6415
 
6377
6416
 
6378
6417
 
@@ -6414,6 +6453,7 @@ class WebRTCClient extends Emitter {
6414
6453
 
6415
6454
 
6416
6455
 
6456
+
6417
6457
 
6418
6458
  // sugar
6419
6459
 
@@ -6476,6 +6516,7 @@ class WebRTCClient extends Emitter {
6476
6516
  this.conferences = {};
6477
6517
  this.networkMonitoringInterval = {};
6478
6518
  this.sessionNetworkStats = {};
6519
+ this.forceClosed = false;
6479
6520
 
6480
6521
  this._boundOnHeartbeat = this._onHeartbeat.bind(this);
6481
6522
  this.heartbeat = new Heartbeat(config.heartbeatDelay, config.heartbeatTimeout, config.maxHeartbeats);
@@ -6597,6 +6638,8 @@ class WebRTCClient extends Emitter {
6597
6638
  skipRegister: this.skipRegister,
6598
6639
  };
6599
6640
 
6641
+ this.forceClosed = false;
6642
+
6600
6643
  if (this.skipRegister) {
6601
6644
  logger$9.info('sdk webrtc skip register...', logInfo);
6602
6645
  return Promise.resolve();
@@ -6621,7 +6664,15 @@ class WebRTCClient extends Emitter {
6621
6664
  const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
6622
6665
 
6623
6666
  const onRegisterFailed = () => {
6624
- logger$9.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
6667
+ logger$9.info('sdk webrtc registering failed', {
6668
+ tries,
6669
+ registerer: !!this.registerer,
6670
+ forceClosed: this.forceClosed,
6671
+ });
6672
+ if (this.forceClosed) {
6673
+ return;
6674
+ }
6675
+
6625
6676
  this.connectionPromise = null;
6626
6677
  if (this.registerer && this.registerer.waiting) {
6627
6678
  this.registerer.waitingToggle(false);
@@ -6899,8 +6950,9 @@ class WebRTCClient extends Emitter {
6899
6950
  }
6900
6951
  }
6901
6952
 
6902
- async close() {
6903
- logger$9.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
6953
+ async close(force = false) {
6954
+ logger$9.info('sdk webrtc closing client', { userAgent: !!this.userAgent, force });
6955
+ this.forceClosed = force;
6904
6956
  this._cleanupMedia();
6905
6957
  this.connectionPromise = null;
6906
6958
 
@@ -6919,7 +6971,7 @@ class WebRTCClient extends Emitter {
6919
6971
  this.userAgent.delegate = null;
6920
6972
  this.userAgent.stateChange.removeAllListeners();
6921
6973
 
6922
- await this._disconnectTransport();
6974
+ await this._disconnectTransport(force);
6923
6975
 
6924
6976
  this._cleanupRegister();
6925
6977
 
@@ -7989,6 +8041,13 @@ class WebRTCClient extends Emitter {
7989
8041
  }
7990
8042
 
7991
8043
  _createWebRTCConfiguration(configOverrides = {}) {
8044
+ let { host } = this.config;
8045
+ let port = this.config.port || 443;
8046
+
8047
+ if (this.config.websocketSip) {
8048
+ [host, port = 443] = this.config.websocketSip.split(':');
8049
+ }
8050
+
7992
8051
  const config = {
7993
8052
  authorizationUsername: this.config.authorizationUser,
7994
8053
  authorizationPassword: this.config.password,
@@ -8024,7 +8083,7 @@ class WebRTCClient extends Emitter {
8024
8083
  },
8025
8084
  transportOptions: {
8026
8085
  traceSip: configOverrides.traceSip || false,
8027
- wsServers: `wss://${this.config.host}:${this.config.port || 443}/api/asterisk/ws`,
8086
+ wsServers: `wss://${host}:${port}/api/asterisk/ws`,
8028
8087
  },
8029
8088
  sessionDescriptionHandlerFactoryOptions: {
8030
8089
  modifiers: [replaceLocalIpModifier],
@@ -8348,7 +8407,15 @@ class WebRTCClient extends Emitter {
8348
8407
  return UserAgent.makeURI(`sip:${target}@${this.config.host}`);
8349
8408
  }
8350
8409
 
8351
- async _disconnectTransport() {
8410
+ async _disconnectTransport(force = false) {
8411
+ if (force) {
8412
+ // Bypass sip.js state machine that prevent to close WS with the state `Connecting`
8413
+ this.userAgent.transport.disconnectResolve = () => {};
8414
+ // eslint-disable-next-line
8415
+ this.userAgent.transport._ws.close(1000);
8416
+ return;
8417
+ }
8418
+
8352
8419
  // Check if `disconnectPromise` is not present to avoid `Disconnect promise must not be defined` errors.
8353
8420
  if (this.userAgent && this.userAgent.transport && !this.userAgent.transport.disconnectPromise) {
8354
8421
  try {
@@ -9085,6 +9152,7 @@ class WebRTCPhone extends Emitter {
9085
9152
  }
9086
9153
 
9087
9154
  callSession.answerTime = new Date();
9155
+ this._updateCallSession(callSession);
9088
9156
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
9089
9157
 
9090
9158
  return callSession;
@@ -9301,6 +9369,7 @@ class WebRTCPhone extends Emitter {
9301
9369
 
9302
9370
  this.shouldSendReinvite = false;
9303
9371
  callSession.answerTime = new Date();
9372
+ this._updateCallSession(callSession);
9304
9373
  this.acceptedSessions[callSession.getId()] = true;
9305
9374
 
9306
9375
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -9400,7 +9469,7 @@ class WebRTCPhone extends Emitter {
9400
9469
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
9401
9470
  if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
9402
9471
  logger$8.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
9403
- this.holdSipSession(this.currentSipSession, callSession);
9472
+ this.holdSipSession(this.currentSipSession, this.currentCallSession);
9404
9473
  }
9405
9474
 
9406
9475
  const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
@@ -9611,6 +9680,7 @@ class WebRTCPhone extends Emitter {
9611
9680
  }
9612
9681
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
9613
9682
  callSession.creationTime = new Date();
9683
+ this._updateCallSession(callSession);
9614
9684
 
9615
9685
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
9616
9686
 
@@ -9752,7 +9822,7 @@ class WebRTCPhone extends Emitter {
9752
9822
  return this.client && this.client.isConference(callSession.sipCallId);
9753
9823
  }
9754
9824
 
9755
- async close() {
9825
+ async close(force = false) {
9756
9826
  logger$8.info('WebRTC close');
9757
9827
 
9758
9828
  try {
@@ -9764,7 +9834,7 @@ class WebRTCPhone extends Emitter {
9764
9834
  logger$8.error('WebRTC close, unregister error', e);
9765
9835
  }
9766
9836
 
9767
- this.client.close();
9837
+ this.client.close(force);
9768
9838
  this.unbind();
9769
9839
 
9770
9840
  this.incomingSessions = [];
@@ -9890,6 +9960,8 @@ class WebRTCPhone extends Emitter {
9890
9960
  }
9891
9961
 
9892
9962
  callSession.creationTime = new Date();
9963
+ this._updateCallSession(callSession);
9964
+
9893
9965
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
9894
9966
  });
9895
9967
 
@@ -9933,6 +10005,8 @@ class WebRTCPhone extends Emitter {
9933
10005
  logger$8.info('WebRTC call rejected', session.id);
9934
10006
  const callSession = this._createCallSession(session);
9935
10007
  callSession.endTime = new Date();
10008
+ this._updateCallSession(callSession);
10009
+
9936
10010
  this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
9937
10011
  });
9938
10012
 
@@ -10157,6 +10231,7 @@ class WebRTCPhone extends Emitter {
10157
10231
  displayName: identity ? identity.displayName || number : number,
10158
10232
  startTime: fromSession ? fromSession.startTime : new Date(),
10159
10233
  creationTime: fromSession ? fromSession.creationTime : null,
10234
+ answerTime: fromSession ? fromSession.answerTime : null,
10160
10235
  endTime: fromSession ? fromSession.endTime : null,
10161
10236
  answered: state === SessionState.Established,
10162
10237
  paused: this.client.isCallHeld(sipSession),