@wazo/sdk 0.37.31 → 0.37.35

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 (90) hide show
  1. package/dist/wazo-sdk.js +2 -2
  2. package/esm/__tests__/api-client.test.js +41 -0
  3. package/esm/__tests__/web-rtc-client.test.js +68 -6
  4. package/esm/api/auth.js +5 -0
  5. package/esm/api/call-logd.js +6 -0
  6. package/esm/api/calld.js +30 -0
  7. package/esm/api-client.js +41 -0
  8. package/esm/checker/Checker.js +68 -6
  9. package/esm/checker/checks/aor.js +41 -0
  10. package/esm/checker/checks/api.js +41 -0
  11. package/esm/checker/checks/index.js +68 -6
  12. package/esm/checker/checks/webrtc-transport.js +68 -6
  13. package/esm/checker/checks/webrtc.js +68 -6
  14. package/esm/domain/AdHocAPIConference.js +41 -0
  15. package/esm/domain/CallLog.js +6 -0
  16. package/esm/domain/CallSession.js +8 -0
  17. package/esm/domain/Features.js +41 -0
  18. package/esm/domain/MeetingStatus.js +29 -0
  19. package/esm/domain/Phone/CTIPhone.js +49 -0
  20. package/esm/domain/Phone/WebRTCPhone.js +33 -6
  21. package/esm/domain/__tests__/CallLog.test.js +6 -0
  22. package/esm/domain/__tests__/CallSession.test.js +40 -4
  23. package/esm/domain/__tests__/IndirectTransfer.test.js +8 -0
  24. package/esm/domain/__tests__/Room.test.js +8 -0
  25. package/esm/index.js +101 -12
  26. package/esm/service/CallApi.js +41 -0
  27. package/esm/service/getApiClient.js +41 -0
  28. package/esm/simple/Auth.js +101 -12
  29. package/esm/simple/Configuration.js +101 -12
  30. package/esm/simple/Directory.js +41 -0
  31. package/esm/simple/Phone.js +101 -12
  32. package/esm/simple/index.js +101 -12
  33. package/esm/simple/room/LocalParticipant.js +101 -12
  34. package/esm/simple/room/Participant.js +101 -12
  35. package/esm/simple/room/RemoteParticipant.js +101 -12
  36. package/esm/simple/room/Room.js +101 -12
  37. package/esm/simple/room/SipRoom.js +101 -12
  38. package/esm/simple/room/Stream.js +101 -12
  39. package/esm/simple/room/__tests__/RemoteParticipant.test.js +101 -12
  40. package/esm/simple/utils.js +101 -12
  41. package/esm/web-rtc-client.js +68 -6
  42. package/lib/__tests__/api-client.test.js +41 -0
  43. package/lib/__tests__/web-rtc-client.test.js +68 -6
  44. package/lib/api/auth.js +5 -0
  45. package/lib/api/call-logd.js +6 -0
  46. package/lib/api/calld.js +30 -0
  47. package/lib/api-client.js +41 -0
  48. package/lib/checker/Checker.js +68 -6
  49. package/lib/checker/checks/aor.js +41 -0
  50. package/lib/checker/checks/api.js +41 -0
  51. package/lib/checker/checks/index.js +68 -6
  52. package/lib/checker/checks/webrtc-transport.js +68 -6
  53. package/lib/checker/checks/webrtc.js +68 -6
  54. package/lib/domain/AdHocAPIConference.js +41 -0
  55. package/lib/domain/CallLog.js +6 -0
  56. package/lib/domain/CallSession.js +8 -0
  57. package/lib/domain/Features.js +41 -0
  58. package/lib/domain/MeetingStatus.js +31 -0
  59. package/lib/domain/Phone/CTIPhone.js +49 -0
  60. package/lib/domain/Phone/WebRTCPhone.js +33 -6
  61. package/lib/domain/__tests__/CallLog.test.js +6 -0
  62. package/lib/domain/__tests__/CallSession.test.js +40 -4
  63. package/lib/domain/__tests__/IndirectTransfer.test.js +8 -0
  64. package/lib/domain/__tests__/Room.test.js +8 -0
  65. package/lib/index.js +101 -12
  66. package/lib/service/CallApi.js +41 -0
  67. package/lib/service/getApiClient.js +41 -0
  68. package/lib/simple/Auth.js +101 -12
  69. package/lib/simple/Configuration.js +101 -12
  70. package/lib/simple/Directory.js +41 -0
  71. package/lib/simple/Phone.js +101 -12
  72. package/lib/simple/index.js +101 -12
  73. package/lib/simple/room/LocalParticipant.js +101 -12
  74. package/lib/simple/room/Participant.js +101 -12
  75. package/lib/simple/room/RemoteParticipant.js +101 -12
  76. package/lib/simple/room/Room.js +101 -12
  77. package/lib/simple/room/SipRoom.js +101 -12
  78. package/lib/simple/room/Stream.js +101 -12
  79. package/lib/simple/room/__tests__/RemoteParticipant.test.js +101 -12
  80. package/lib/simple/utils.js +101 -12
  81. package/lib/web-rtc-client.js +68 -6
  82. package/package.json +1 -1
  83. package/src/api/auth.js +5 -0
  84. package/src/api/calld.js +3 -0
  85. package/src/domain/CallLog.js +6 -0
  86. package/src/domain/CallSession.js +8 -0
  87. package/src/domain/MeetingStatus.js +27 -0
  88. package/src/domain/Phone/WebRTCPhone.js +25 -6
  89. package/src/domain/__tests__/CallSession.test.js +32 -4
  90. package/src/web-rtc-client.js +27 -6
@@ -2058,6 +2058,14 @@ class CallSession {
2058
2058
  return !!this.answerTime;
2059
2059
  }
2060
2060
 
2061
+ toJSON() {
2062
+ const jsonObj = { ...this };
2063
+ // $FlowFixMe
2064
+ jsonObj.answered = this.answered;
2065
+
2066
+ return jsonObj;
2067
+ }
2068
+
2061
2069
  static parseCall(call ) {
2062
2070
  return new CallSession({
2063
2071
  callId: call.id,
@@ -2168,11 +2176,13 @@ class Recording {
2168
2176
 
2169
2177
 
2170
2178
 
2179
+
2171
2180
 
2172
2181
 
2173
2182
 
2174
2183
 
2175
2184
 
2185
+
2176
2186
 
2177
2187
 
2178
2188
 
@@ -2193,10 +2203,12 @@ class Recording {
2193
2203
 
2194
2204
 
2195
2205
 
2206
+
2196
2207
 
2197
2208
 
2198
2209
 
2199
2210
 
2211
+
2200
2212
 
2201
2213
 
2202
2214
 
@@ -2258,10 +2270,12 @@ class CallLog {
2258
2270
  || plain.destination_extension
2259
2271
  || `meeting-${plain.requested_name || plain.destination_name || ''}`,
2260
2272
  name: plain.requested_name || plain.destination_name || '',
2273
+ uuid: plain.destination_user_uuid,
2261
2274
  },
2262
2275
  source: {
2263
2276
  extension: plain.source_extension,
2264
2277
  name: plain.source_name,
2278
+ uuid: plain.source_user_uuid,
2265
2279
  },
2266
2280
  id: plain.id,
2267
2281
  duration: (plain.duration || 0) * 1000, // duration is in seconds
@@ -3138,6 +3152,7 @@ var authMethods = (client , baseUrl ) => ({
3138
3152
 
3139
3153
 
3140
3154
 
3155
+
3141
3156
  ) {
3142
3157
  const body = {
3143
3158
  backend: params.backend || DEFAULT_BACKEND_USER,
@@ -3157,6 +3172,10 @@ var authMethods = (client , baseUrl ) => ({
3157
3172
  headers['Wazo-Session-Type'] = 'mobile';
3158
3173
  }
3159
3174
 
3175
+ if (params.tenantId) {
3176
+ body.tenant_id = params.tenantId;
3177
+ }
3178
+
3160
3179
  return client.post(`${baseUrl}/token`, body, headers).then(response => Session.parse(response));
3161
3180
  },
3162
3181
 
@@ -4416,6 +4435,34 @@ class IndirectTransfer {
4416
4435
  }
4417
4436
  }
4418
4437
 
4438
+ //
4439
+
4440
+
4441
+
4442
+
4443
+
4444
+ class MeetingStatus {
4445
+
4446
+
4447
+
4448
+
4449
+ constructor({
4450
+ full,
4451
+ } = {}) {
4452
+ this.full = full;
4453
+
4454
+ // Useful to compare instead of instanceof with minified code
4455
+ this.type = 'MeetingStatus';
4456
+ }
4457
+
4458
+ static parse(plain ) {
4459
+ return new MeetingStatus({
4460
+ full: plain.full,
4461
+ });
4462
+ }
4463
+
4464
+ }
4465
+
4419
4466
  /* */
4420
4467
 
4421
4468
 
@@ -4610,6 +4657,8 @@ var calldMethods = (client , baseUrl ) => ({
4610
4657
  client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
4611
4658
  ApiRequester.successResponseParser),
4612
4659
 
4660
+ guestGetMeetingStatus: (meetingUuid ) =>
4661
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
4613
4662
  });
4614
4663
 
4615
4664
  //
@@ -406,6 +406,14 @@ class CallSession {
406
406
  return !!this.answerTime;
407
407
  }
408
408
 
409
+ toJSON() {
410
+ const jsonObj = { ...this };
411
+ // $FlowFixMe
412
+ jsonObj.answered = this.answered;
413
+
414
+ return jsonObj;
415
+ }
416
+
409
417
  static parseCall(call ) {
410
418
  return new CallSession({
411
419
  callId: call.id,
@@ -1723,6 +1731,12 @@ class WebRTCPhone extends Emitter {
1723
1731
  return Promise.resolve(null);
1724
1732
  }
1725
1733
 
1734
+ const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
1735
+ if (sipSessionId && !(sipSessionId in this.callSessions)) {
1736
+ logger.warn('Call session already ended or not found, can\'t accept it.', { sipSessionId });
1737
+ return Promise.resolve(null);
1738
+ }
1739
+
1726
1740
  if (callSession.getId() in this.acceptedSessions) {
1727
1741
  logger.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
1728
1742
  return Promise.resolve(callSession.sipCallId);
@@ -2183,7 +2197,7 @@ class WebRTCPhone extends Emitter {
2183
2197
  return this.client && this.client.isConference(callSession.sipCallId);
2184
2198
  }
2185
2199
 
2186
- async close() {
2200
+ async close(force = false) {
2187
2201
  logger.info('WebRTC close');
2188
2202
 
2189
2203
  try {
@@ -2195,7 +2209,7 @@ class WebRTCPhone extends Emitter {
2195
2209
  logger.error('WebRTC close, unregister error', e);
2196
2210
  }
2197
2211
 
2198
- this.client.close();
2212
+ this.client.close(force);
2199
2213
  this.unbind();
2200
2214
 
2201
2215
  this.incomingSessions = [];
@@ -2347,9 +2361,17 @@ class WebRTCPhone extends Emitter {
2347
2361
  });
2348
2362
 
2349
2363
  this.client.on(this.client.ACCEPTED, (sipSession ) => {
2350
- logger.info('WebRTC call accepted', { sipId: sipSession.id });
2364
+ const sessionId = this.getSipSessionId(sipSession);
2365
+ const hasSession = sessionId in this.callSessions;
2351
2366
 
2352
- this._onCallAccepted(sipSession, this.client.hasVideo(this.getSipSessionId(sipSession)));
2367
+ logger.info('WebRTC call accepted', { sipId: sessionId, hasSession });
2368
+
2369
+ if (!hasSession) {
2370
+ logger.warn('Call accepted ignored, session is no longer present in the WebRtcPhone', { sessionId });
2371
+ return;
2372
+ }
2373
+
2374
+ this._onCallAccepted(sipSession, this.client.hasVideo(sessionId));
2353
2375
 
2354
2376
  if (this.audioOutputDeviceId) {
2355
2377
  this.client.changeAudioOutputDevice(this.audioOutputDeviceId);
@@ -2485,9 +2507,14 @@ class WebRTCPhone extends Emitter {
2485
2507
  return this.client.getSipSessionId(sipSession);
2486
2508
  }
2487
2509
 
2488
- _updateCallSession(callSession ) {
2510
+ getSipSessionIdFromCallSession(callSession ) {
2489
2511
  const sipSession = this.findSipSession(callSession);
2490
- const sipSessionId = sipSession ? this.getSipSessionId(sipSession) : null;
2512
+
2513
+ return sipSession ? this.getSipSessionId(sipSession) : null;
2514
+ }
2515
+
2516
+ _updateCallSession(callSession ) {
2517
+ const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
2491
2518
 
2492
2519
  if (sipSessionId) {
2493
2520
  this.callSessions[sipSessionId] = callSession;
@@ -93,11 +93,13 @@ class Recording {
93
93
 
94
94
 
95
95
 
96
+
96
97
 
97
98
 
98
99
 
99
100
 
100
101
 
102
+
101
103
 
102
104
 
103
105
 
@@ -118,10 +120,12 @@ class Recording {
118
120
 
119
121
 
120
122
 
123
+
121
124
 
122
125
 
123
126
 
124
127
 
128
+
125
129
 
126
130
 
127
131
 
@@ -183,10 +187,12 @@ class CallLog {
183
187
  || plain.destination_extension
184
188
  || `meeting-${plain.requested_name || plain.destination_name || ''}`,
185
189
  name: plain.requested_name || plain.destination_name || '',
190
+ uuid: plain.destination_user_uuid,
186
191
  },
187
192
  source: {
188
193
  extension: plain.source_extension,
189
194
  name: plain.source_name,
195
+ uuid: plain.source_user_uuid,
190
196
  },
191
197
  id: plain.id,
192
198
  duration: (plain.duration || 0) * 1000, // duration is in seconds
@@ -377,6 +377,14 @@ class CallSession {
377
377
  return !!this.answerTime;
378
378
  }
379
379
 
380
+ toJSON() {
381
+ const jsonObj = { ...this };
382
+ // $FlowFixMe
383
+ jsonObj.answered = this.answered;
384
+
385
+ return jsonObj;
386
+ }
387
+
380
388
  static parseCall(call ) {
381
389
  return new CallSession({
382
390
  callId: call.id,
@@ -402,6 +410,8 @@ class CallSession {
402
410
  }
403
411
  }
404
412
 
413
+ const stringify = cs => JSON.parse(JSON.stringify(cs));
414
+
405
415
  describe('CallSession domain', () => {
406
416
  it('should update from another CallSession without data loss', () => {
407
417
  const callSession = new CallSession({
@@ -440,7 +450,7 @@ describe('CallSession domain', () => {
440
450
  expect(cs2.is(cs1)).toBeTruthy();
441
451
  });
442
452
 
443
- it('should set answerTime when setting answered', () => {
453
+ it('should set answerTime when setting answered to true', () => {
444
454
  const cs1 = new CallSession({});
445
455
  cs1.answered = true;
446
456
 
@@ -449,11 +459,37 @@ describe('CallSession domain', () => {
449
459
 
450
460
  const cs3 = new CallSession({ answered: true });
451
461
 
452
- expect(cs1.answered).toBeTruthy();
462
+ expect(cs1.answered).toEqual(true);
453
463
  expect(cs1.answerTime).not.toBeNull();
454
- expect(cs2.answered).toBeTruthy();
464
+ expect(cs2.answered).toEqual(true);
455
465
  expect(cs2.answerTime).not.toBeNull();
456
- expect(cs3.answered).toBeTruthy();
466
+ expect(cs3.answered).toEqual(true);
457
467
  expect(cs3.answerTime).not.toBeNull();
468
+
469
+ const cs4 = stringify(cs1);
470
+ const cs5 = stringify(cs2);
471
+ const cs6 = stringify(cs3);
472
+
473
+ expect(cs4.answered).toEqual(true);
474
+ expect(cs5.answered).toEqual(true);
475
+ expect(cs6.answered).toEqual(true);
476
+ });
477
+
478
+ it('should reset answerTime when setting answered to false', () => {
479
+ const cs1 = new CallSession({});
480
+ cs1.answered = false;
481
+
482
+ const cs2 = new CallSession({ answered: false });
483
+
484
+ expect(cs1.answered).toEqual(false);
485
+ expect(cs1.answerTime).toBeNull();
486
+ expect(cs2.answered).toEqual(false);
487
+ expect(cs2.answerTime).toBeNull();
488
+
489
+ const cs4 = stringify(cs1);
490
+ const cs5 = stringify(cs2);
491
+
492
+ expect(cs4.answered).toEqual(false);
493
+ expect(cs5.answered).toEqual(false);
458
494
  });
459
495
  });
@@ -377,6 +377,14 @@ class CallSession {
377
377
  return !!this.answerTime;
378
378
  }
379
379
 
380
+ toJSON() {
381
+ const jsonObj = { ...this };
382
+ // $FlowFixMe
383
+ jsonObj.answered = this.answered;
384
+
385
+ return jsonObj;
386
+ }
387
+
380
388
  static parseCall(call ) {
381
389
  return new CallSession({
382
390
  callId: call.id,
@@ -377,6 +377,14 @@ class CallSession {
377
377
  return !!this.answerTime;
378
378
  }
379
379
 
380
+ toJSON() {
381
+ const jsonObj = { ...this };
382
+ // $FlowFixMe
383
+ jsonObj.answered = this.answered;
384
+
385
+ return jsonObj;
386
+ }
387
+
380
388
  static parseCall(call ) {
381
389
  return new CallSession({
382
390
  callId: call.id,
package/lib/index.js CHANGED
@@ -2228,6 +2228,7 @@ var authMethods = (client , baseUrl ) => ({
2228
2228
 
2229
2229
 
2230
2230
 
2231
+
2231
2232
  ) {
2232
2233
  const body = {
2233
2234
  backend: params.backend || DEFAULT_BACKEND_USER,
@@ -2247,6 +2248,10 @@ var authMethods = (client , baseUrl ) => ({
2247
2248
  headers['Wazo-Session-Type'] = 'mobile';
2248
2249
  }
2249
2250
 
2251
+ if (params.tenantId) {
2252
+ body.tenant_id = params.tenantId;
2253
+ }
2254
+
2250
2255
  return client.post(`${baseUrl}/token`, body, headers).then(response => Session.parse(response));
2251
2256
  },
2252
2257
 
@@ -3603,6 +3608,14 @@ class CallSession {
3603
3608
  return !!this.answerTime;
3604
3609
  }
3605
3610
 
3611
+ toJSON() {
3612
+ const jsonObj = { ...this };
3613
+ // $FlowFixMe
3614
+ jsonObj.answered = this.answered;
3615
+
3616
+ return jsonObj;
3617
+ }
3618
+
3606
3619
  static parseCall(call ) {
3607
3620
  return new CallSession({
3608
3621
  callId: call.id,
@@ -3713,11 +3726,13 @@ class Recording {
3713
3726
 
3714
3727
 
3715
3728
 
3729
+
3716
3730
 
3717
3731
 
3718
3732
 
3719
3733
 
3720
3734
 
3735
+
3721
3736
 
3722
3737
 
3723
3738
 
@@ -3738,10 +3753,12 @@ class Recording {
3738
3753
 
3739
3754
 
3740
3755
 
3756
+
3741
3757
 
3742
3758
 
3743
3759
 
3744
3760
 
3761
+
3745
3762
 
3746
3763
 
3747
3764
 
@@ -3803,10 +3820,12 @@ class CallLog {
3803
3820
  || plain.destination_extension
3804
3821
  || `meeting-${plain.requested_name || plain.destination_name || ''}`,
3805
3822
  name: plain.requested_name || plain.destination_name || '',
3823
+ uuid: plain.destination_user_uuid,
3806
3824
  },
3807
3825
  source: {
3808
3826
  extension: plain.source_extension,
3809
3827
  name: plain.source_name,
3828
+ uuid: plain.source_user_uuid,
3810
3829
  },
3811
3830
  id: plain.id,
3812
3831
  duration: (plain.duration || 0) * 1000, // duration is in seconds
@@ -4937,6 +4956,34 @@ var chatdMethods = (client , baseUrl ) => ({
4937
4956
  client.get(`${baseUrl}/users/me/rooms/messages`, options),
4938
4957
  });
4939
4958
 
4959
+ //
4960
+
4961
+
4962
+
4963
+
4964
+
4965
+ class MeetingStatus {
4966
+
4967
+
4968
+
4969
+
4970
+ constructor({
4971
+ full,
4972
+ } = {}) {
4973
+ this.full = full;
4974
+
4975
+ // Useful to compare instead of instanceof with minified code
4976
+ this.type = 'MeetingStatus';
4977
+ }
4978
+
4979
+ static parse(plain ) {
4980
+ return new MeetingStatus({
4981
+ full: plain.full,
4982
+ });
4983
+ }
4984
+
4985
+ }
4986
+
4940
4987
  /* */
4941
4988
 
4942
4989
 
@@ -5131,6 +5178,8 @@ var calldMethods = (client , baseUrl ) => ({
5131
5178
  client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
5132
5179
  ApiRequester.successResponseParser),
5133
5180
 
5181
+ guestGetMeetingStatus: (meetingUuid ) =>
5182
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
5134
5183
  });
5135
5184
 
5136
5185
  //
@@ -6198,7 +6247,7 @@ const events$1 = [REGISTERED, UNREGISTERED, REGISTRATION_FAILED, INVITE];
6198
6247
  const transportEvents = [CONNECTED, DISCONNECTED, TRANSPORT_ERROR, MESSAGE];
6199
6248
  class CanceledCallError extends Error {}
6200
6249
 
6201
- const MAX_REGISTER_TRIES = 10;
6250
+ const MAX_REGISTER_TRIES = 5;
6202
6251
 
6203
6252
 
6204
6253
 
@@ -6252,6 +6301,7 @@ class WebRTCClient extends Emitter {
6252
6301
 
6253
6302
 
6254
6303
 
6304
+
6255
6305
 
6256
6306
  // sugar
6257
6307
 
@@ -6314,6 +6364,7 @@ class WebRTCClient extends Emitter {
6314
6364
  this.conferences = {};
6315
6365
  this.networkMonitoringInterval = {};
6316
6366
  this.sessionNetworkStats = {};
6367
+ this.forceClosed = false;
6317
6368
 
6318
6369
  this._boundOnHeartbeat = this._onHeartbeat.bind(this);
6319
6370
  this.heartbeat = new Heartbeat(config.heartbeatDelay, config.heartbeatTimeout, config.maxHeartbeats);
@@ -6435,6 +6486,8 @@ class WebRTCClient extends Emitter {
6435
6486
  skipRegister: this.skipRegister,
6436
6487
  };
6437
6488
 
6489
+ this.forceClosed = false;
6490
+
6438
6491
  if (this.skipRegister) {
6439
6492
  logger$9.info('sdk webrtc skip register...', logInfo);
6440
6493
  return Promise.resolve();
@@ -6459,7 +6512,15 @@ class WebRTCClient extends Emitter {
6459
6512
  const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
6460
6513
 
6461
6514
  const onRegisterFailed = () => {
6462
- logger$9.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
6515
+ logger$9.info('sdk webrtc registering failed', {
6516
+ tries,
6517
+ registerer: !!this.registerer,
6518
+ forceClosed: this.forceClosed,
6519
+ });
6520
+ if (this.forceClosed) {
6521
+ return;
6522
+ }
6523
+
6463
6524
  this.connectionPromise = null;
6464
6525
  if (this.registerer && this.registerer.waiting) {
6465
6526
  this.registerer.waitingToggle(false);
@@ -6737,8 +6798,9 @@ class WebRTCClient extends Emitter {
6737
6798
  }
6738
6799
  }
6739
6800
 
6740
- async close() {
6741
- logger$9.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
6801
+ async close(force = false) {
6802
+ logger$9.info('sdk webrtc closing client', { userAgent: !!this.userAgent, force });
6803
+ this.forceClosed = force;
6742
6804
  this._cleanupMedia();
6743
6805
  this.connectionPromise = null;
6744
6806
 
@@ -6757,7 +6819,7 @@ class WebRTCClient extends Emitter {
6757
6819
  this.userAgent.delegate = null;
6758
6820
  this.userAgent.stateChange.removeAllListeners();
6759
6821
 
6760
- await this._disconnectTransport();
6822
+ await this._disconnectTransport(force);
6761
6823
 
6762
6824
  this._cleanupRegister();
6763
6825
 
@@ -8193,7 +8255,15 @@ class WebRTCClient extends Emitter {
8193
8255
  return userAgent.UserAgent.makeURI(`sip:${target}@${this.config.host}`);
8194
8256
  }
8195
8257
 
8196
- async _disconnectTransport() {
8258
+ async _disconnectTransport(force = false) {
8259
+ if (force) {
8260
+ // Bypass sip.js state machine that prevent to close WS with the state `Connecting`
8261
+ this.userAgent.transport.disconnectResolve = () => {};
8262
+ // eslint-disable-next-line
8263
+ this.userAgent.transport._ws.close(1000);
8264
+ return;
8265
+ }
8266
+
8197
8267
  // Check if `disconnectPromise` is not present to avoid `Disconnect promise must not be defined` errors.
8198
8268
  if (this.userAgent && this.userAgent.transport && !this.userAgent.transport.disconnectPromise) {
8199
8269
  try {
@@ -10041,6 +10111,12 @@ class WebRTCPhone extends Emitter {
10041
10111
  return Promise.resolve(null);
10042
10112
  }
10043
10113
 
10114
+ const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
10115
+ if (sipSessionId && !(sipSessionId in this.callSessions)) {
10116
+ logger$7.warn('Call session already ended or not found, can\'t accept it.', { sipSessionId });
10117
+ return Promise.resolve(null);
10118
+ }
10119
+
10044
10120
  if (callSession.getId() in this.acceptedSessions) {
10045
10121
  logger$7.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
10046
10122
  return Promise.resolve(callSession.sipCallId);
@@ -10501,7 +10577,7 @@ class WebRTCPhone extends Emitter {
10501
10577
  return this.client && this.client.isConference(callSession.sipCallId);
10502
10578
  }
10503
10579
 
10504
- async close() {
10580
+ async close(force = false) {
10505
10581
  logger$7.info('WebRTC close');
10506
10582
 
10507
10583
  try {
@@ -10513,7 +10589,7 @@ class WebRTCPhone extends Emitter {
10513
10589
  logger$7.error('WebRTC close, unregister error', e);
10514
10590
  }
10515
10591
 
10516
- this.client.close();
10592
+ this.client.close(force);
10517
10593
  this.unbind();
10518
10594
 
10519
10595
  this.incomingSessions = [];
@@ -10665,9 +10741,17 @@ class WebRTCPhone extends Emitter {
10665
10741
  });
10666
10742
 
10667
10743
  this.client.on(this.client.ACCEPTED, (sipSession ) => {
10668
- logger$7.info('WebRTC call accepted', { sipId: sipSession.id });
10744
+ const sessionId = this.getSipSessionId(sipSession);
10745
+ const hasSession = sessionId in this.callSessions;
10746
+
10747
+ logger$7.info('WebRTC call accepted', { sipId: sessionId, hasSession });
10748
+
10749
+ if (!hasSession) {
10750
+ logger$7.warn('Call accepted ignored, session is no longer present in the WebRtcPhone', { sessionId });
10751
+ return;
10752
+ }
10669
10753
 
10670
- this._onCallAccepted(sipSession, this.client.hasVideo(this.getSipSessionId(sipSession)));
10754
+ this._onCallAccepted(sipSession, this.client.hasVideo(sessionId));
10671
10755
 
10672
10756
  if (this.audioOutputDeviceId) {
10673
10757
  this.client.changeAudioOutputDevice(this.audioOutputDeviceId);
@@ -10803,9 +10887,14 @@ class WebRTCPhone extends Emitter {
10803
10887
  return this.client.getSipSessionId(sipSession);
10804
10888
  }
10805
10889
 
10806
- _updateCallSession(callSession ) {
10890
+ getSipSessionIdFromCallSession(callSession ) {
10807
10891
  const sipSession = this.findSipSession(callSession);
10808
- const sipSessionId = sipSession ? this.getSipSessionId(sipSession) : null;
10892
+
10893
+ return sipSession ? this.getSipSessionId(sipSession) : null;
10894
+ }
10895
+
10896
+ _updateCallSession(callSession ) {
10897
+ const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
10809
10898
 
10810
10899
  if (sipSessionId) {
10811
10900
  this.callSessions[sipSessionId] = callSession;