@wazo/sdk 0.37.25 → 0.37.29

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 (125) hide show
  1. package/README.md +96 -58
  2. package/dist/wazo-sdk.js +3 -3
  3. package/esm/__tests__/api-client.test.js +2 -2
  4. package/esm/__tests__/web-rtc-client.test.js +10 -5
  5. package/esm/api/agentd.js +1 -1
  6. package/esm/api/amid.js +1 -1
  7. package/esm/api/application.js +1 -1
  8. package/esm/api/auth.js +1 -1
  9. package/esm/api/call-logd.js +1 -1
  10. package/esm/api/calld.js +1 -1
  11. package/esm/api/chatd.js +1 -1
  12. package/esm/api/confd.js +1 -1
  13. package/esm/api/ctid-ng.js +1 -1
  14. package/esm/api/dird.js +2 -2
  15. package/esm/api/webhookd.js +1 -1
  16. package/esm/api-client.js +2 -2
  17. package/esm/checker/Checker.js +10 -5
  18. package/esm/checker/checks/aor.js +2 -2
  19. package/esm/checker/checks/api.js +2 -2
  20. package/esm/checker/checks/index.js +10 -5
  21. package/esm/checker/checks/wazo-websocket.js +1 -1
  22. package/esm/checker/checks/webrtc-transport.js +10 -5
  23. package/esm/checker/checks/webrtc.js +10 -5
  24. package/esm/domain/AdHocAPIConference.js +2 -2
  25. package/esm/domain/CallSession.js +29 -2
  26. package/esm/domain/Contact.js +1 -1
  27. package/esm/domain/Features.js +2 -2
  28. package/esm/domain/Phone/CTIPhone.js +31 -4
  29. package/esm/domain/Phone/WebRTCPhone.js +55 -6
  30. package/esm/domain/SFUNotAvailableError.js +9 -0
  31. package/esm/domain/__tests__/CallSession.test.js +46 -2
  32. package/esm/domain/__tests__/Contact.test.js +1 -1
  33. package/esm/domain/__tests__/IndirectTransfer.test.js +29 -2
  34. package/esm/domain/__tests__/Room.test.js +29 -2
  35. package/esm/index.js +75 -10
  36. package/esm/lib/WazoSessionDescriptionHandler.js +9 -4
  37. package/esm/service/CallApi.js +2 -2
  38. package/esm/service/IssueReporter.js +1 -1
  39. package/esm/service/__tests__/IssueReporter.test.js +1 -1
  40. package/esm/service/getApiClient.js +2 -2
  41. package/esm/simple/Auth.js +74 -10
  42. package/esm/simple/Configuration.js +74 -10
  43. package/esm/simple/Directory.js +2 -2
  44. package/esm/simple/Phone.js +74 -10
  45. package/esm/simple/Websocket.js +1 -1
  46. package/esm/simple/index.js +74 -10
  47. package/esm/simple/room/LocalParticipant.js +74 -10
  48. package/esm/simple/room/Participant.js +74 -10
  49. package/esm/simple/room/RemoteParticipant.js +74 -10
  50. package/esm/simple/room/Room.js +74 -10
  51. package/esm/simple/room/SipRoom.js +74 -10
  52. package/esm/simple/room/Stream.js +74 -10
  53. package/esm/simple/room/__tests__/RemoteParticipant.test.js +74 -10
  54. package/esm/simple/utils.js +74 -10
  55. package/esm/utils/__tests__/api-requester.test.js +1 -1
  56. package/esm/utils/api-requester.js +1 -1
  57. package/esm/web-rtc-client.js +10 -5
  58. package/esm/websocket-client.js +1 -1
  59. package/lib/__tests__/api-client.test.js +2 -2
  60. package/lib/__tests__/web-rtc-client.test.js +10 -5
  61. package/lib/api/agentd.js +1 -1
  62. package/lib/api/amid.js +1 -1
  63. package/lib/api/application.js +1 -1
  64. package/lib/api/auth.js +1 -1
  65. package/lib/api/call-logd.js +1 -1
  66. package/lib/api/calld.js +1 -1
  67. package/lib/api/chatd.js +1 -1
  68. package/lib/api/confd.js +1 -1
  69. package/lib/api/ctid-ng.js +1 -1
  70. package/lib/api/dird.js +2 -2
  71. package/lib/api/webhookd.js +1 -1
  72. package/lib/api-client.js +2 -2
  73. package/lib/checker/Checker.js +10 -5
  74. package/lib/checker/checks/aor.js +2 -2
  75. package/lib/checker/checks/api.js +2 -2
  76. package/lib/checker/checks/index.js +10 -5
  77. package/lib/checker/checks/wazo-websocket.js +1 -1
  78. package/lib/checker/checks/webrtc-transport.js +10 -5
  79. package/lib/checker/checks/webrtc.js +10 -5
  80. package/lib/domain/AdHocAPIConference.js +2 -2
  81. package/lib/domain/CallSession.js +29 -2
  82. package/lib/domain/Contact.js +1 -1
  83. package/lib/domain/Features.js +2 -2
  84. package/lib/domain/Phone/CTIPhone.js +31 -4
  85. package/lib/domain/Phone/WebRTCPhone.js +55 -5
  86. package/lib/domain/SFUNotAvailableError.js +11 -0
  87. package/lib/domain/__tests__/CallSession.test.js +46 -2
  88. package/lib/domain/__tests__/Contact.test.js +1 -1
  89. package/lib/domain/__tests__/IndirectTransfer.test.js +29 -2
  90. package/lib/domain/__tests__/Room.test.js +29 -2
  91. package/lib/index.js +75 -10
  92. package/lib/lib/WazoSessionDescriptionHandler.js +9 -4
  93. package/lib/service/CallApi.js +2 -2
  94. package/lib/service/IssueReporter.js +1 -1
  95. package/lib/service/__tests__/IssueReporter.test.js +1 -1
  96. package/lib/service/getApiClient.js +2 -2
  97. package/lib/simple/Auth.js +74 -10
  98. package/lib/simple/Configuration.js +74 -10
  99. package/lib/simple/Directory.js +2 -2
  100. package/lib/simple/Phone.js +74 -10
  101. package/lib/simple/Websocket.js +1 -1
  102. package/lib/simple/index.js +74 -10
  103. package/lib/simple/room/LocalParticipant.js +74 -10
  104. package/lib/simple/room/Participant.js +74 -10
  105. package/lib/simple/room/RemoteParticipant.js +74 -10
  106. package/lib/simple/room/Room.js +74 -10
  107. package/lib/simple/room/SipRoom.js +74 -10
  108. package/lib/simple/room/Stream.js +74 -10
  109. package/lib/simple/room/__tests__/RemoteParticipant.test.js +74 -10
  110. package/lib/simple/utils.js +74 -10
  111. package/lib/utils/__tests__/api-requester.test.js +1 -1
  112. package/lib/utils/api-requester.js +1 -1
  113. package/lib/web-rtc-client.js +10 -5
  114. package/lib/websocket-client.js +1 -1
  115. package/package.json +1 -1
  116. package/src/domain/CallSession.js +32 -4
  117. package/src/domain/Contact.js +1 -1
  118. package/src/domain/Phone/WebRTCPhone.js +24 -2
  119. package/src/domain/SFUNotAvailableError.js +7 -0
  120. package/src/domain/__tests__/CallSession.test.js +17 -0
  121. package/src/index.js +2 -0
  122. package/src/lib/WazoSessionDescriptionHandler.js +8 -3
  123. package/src/simple/Phone.js +2 -1
  124. package/src/simple/index.js +2 -0
  125. package/src/utils/api-requester.js +1 -1
@@ -1236,7 +1236,7 @@ class Contact {
1236
1236
  this[key] = old[key] || this[key];
1237
1237
  });
1238
1238
 
1239
- if (old.lineState && !this.lineState) {
1239
+ if (old.lineState) {
1240
1240
  this.lineState = old.lineState;
1241
1241
  }
1242
1242
 
@@ -1951,7 +1951,7 @@ const logger$c = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
1951
1951
 
1952
1952
  // Use a function here to be able to mock it in tests
1953
1953
  const realFetch = () => {
1954
- if (typeof document !== 'undefined') {
1954
+ if (typeof document !== 'undefined' && window.fetch) {
1955
1955
  // Browser
1956
1956
  return window.fetch;
1957
1957
  }
@@ -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 ? 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,
@@ -5798,11 +5825,16 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5798
5825
 
5799
5826
  // $FlowFixMe
5800
5827
  setRemoteSessionDescription(sessionDescription ) {
5801
- const result = super.setRemoteSessionDescription(sessionDescription);
5828
+ try {
5829
+ const result = super.setRemoteSessionDescription(sessionDescription);
5802
5830
 
5803
- this.eventEmitter.emit('setDescription', sessionDescription);
5831
+ this.eventEmitter.emit('setDescription', sessionDescription);
5804
5832
 
5805
- return result;
5833
+ return result;
5834
+ } catch (error) {
5835
+ this.logger.error('SessionDescriptionHandler.setRemoteSessionDescription error', error);
5836
+ throw error;
5837
+ }
5806
5838
  }
5807
5839
 
5808
5840
  // Overridden to avoid to fix ice-candidates missing in the SDP in react-native and chrome canary.
@@ -8454,6 +8486,7 @@ const ON_CAMERA_DISABLED = 'onCameraDisabled';
8454
8486
  const ON_CAMERA_RESUMED = 'onCameraResumed';
8455
8487
  const ON_CALL_CANCELED = 'onCallCanceled';
8456
8488
  const ON_CALL_FAILED = 'onCallFailed';
8489
+ const ON_CALL_REJECTED = 'onCallRejected';
8457
8490
  const ON_CALL_ENDED = 'onCallEnded';
8458
8491
  const ON_CALL_ENDING = 'onCallEnding';
8459
8492
  const ON_MESSAGE = 'onMessage';
@@ -8498,6 +8531,7 @@ const events = [
8498
8531
  ON_CAMERA_DISABLED,
8499
8532
  ON_CALL_FAILED,
8500
8533
  ON_CALL_ENDED,
8534
+ ON_CALL_REJECTED,
8501
8535
  ON_MESSAGE,
8502
8536
  ON_REINVITE,
8503
8537
  ON_TRACK,
@@ -8854,6 +8888,7 @@ class WebRTCPhone extends Emitter {
8854
8888
 
8855
8889
  // Should be called before `_onCallTerminated` or the callCount will not decrement...
8856
8890
  const callSession = this._createCallSession(sipSession);
8891
+ callSession.endTime = new Date();
8857
8892
  const wasCurrentSession = this._onCallTerminated(sipSession);
8858
8893
 
8859
8894
  return this.eventEmitter.emit(ON_CALL_ENDED, callSession, wasCurrentSession);
@@ -9049,6 +9084,7 @@ class WebRTCPhone extends Emitter {
9049
9084
  this.removeIncomingSessions(sipSessionId);
9050
9085
  }
9051
9086
 
9087
+ callSession.answerTime = new Date();
9052
9088
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
9053
9089
 
9054
9090
  return callSession;
@@ -9106,6 +9142,7 @@ class WebRTCPhone extends Emitter {
9106
9142
  _onCallTerminated(sipSession ) {
9107
9143
  logger$8.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
9108
9144
 
9145
+ const sipSessionId = this.getSipSessionId(sipSession);
9109
9146
  const callSession = this._createCallSession(sipSession);
9110
9147
  const isCurrentSession = this.isCurrentCallSipSession(callSession);
9111
9148
  const isCurrentIncomingCall = callSession.is(this.getIncomingCallSession());
@@ -9123,7 +9160,6 @@ class WebRTCPhone extends Emitter {
9123
9160
  }, 5);
9124
9161
  }
9125
9162
 
9126
- const sipSessionId = this.getSipSessionId(sipSession);
9127
9163
  if (sipSessionId) {
9128
9164
  this.removeIncomingSessions(sipSessionId);
9129
9165
  }
@@ -9264,6 +9300,7 @@ class WebRTCPhone extends Emitter {
9264
9300
  }
9265
9301
 
9266
9302
  this.shouldSendReinvite = false;
9303
+ callSession.answerTime = new Date();
9267
9304
  this.acceptedSessions[callSession.getId()] = true;
9268
9305
 
9269
9306
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -9573,6 +9610,7 @@ class WebRTCPhone extends Emitter {
9573
9610
  return Promise.resolve(null);
9574
9611
  }
9575
9612
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
9613
+ callSession.creationTime = new Date();
9576
9614
 
9577
9615
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
9578
9616
 
@@ -9768,8 +9806,12 @@ class WebRTCPhone extends Emitter {
9768
9806
  }
9769
9807
 
9770
9808
  const sessionId = this.incomingSessions[0];
9809
+ const sipSession = this.client.getSipSession(sessionId);
9810
+ if (!sipSession) {
9811
+ return null;
9812
+ }
9771
9813
 
9772
- return this._createCallSession(this.client.getSipSession(sessionId));
9814
+ return this._createCallSession(sipSession);
9773
9815
  }
9774
9816
 
9775
9817
  sendMessage(sipSession = null, body , contentType = 'text/plain') {
@@ -9847,6 +9889,7 @@ class WebRTCPhone extends Emitter {
9847
9889
  callSession);
9848
9890
  }
9849
9891
 
9892
+ callSession.creationTime = new Date();
9850
9893
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
9851
9894
  });
9852
9895
 
@@ -9886,6 +9929,13 @@ class WebRTCPhone extends Emitter {
9886
9929
  this.eventEmitter.emit(ON_CALL_ERROR, e);
9887
9930
  });
9888
9931
 
9932
+ this.client.on(this.client.REJECTED, session => {
9933
+ logger$8.info('WebRTC call rejected', session.id);
9934
+ const callSession = this._createCallSession(session);
9935
+ callSession.endTime = new Date();
9936
+ this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
9937
+ });
9938
+
9889
9939
  this.client.on(this.client.UNREGISTERED, () => {
9890
9940
  logger$8.info('WebRTC unregistered');
9891
9941
  this.eventEmitter.emit(ON_UNREGISTERED);
@@ -10098,6 +10148,7 @@ class WebRTCPhone extends Emitter {
10098
10148
  const number = identity ? identity.uri._normal.user : null;
10099
10149
  const { state } = sipSession || {};
10100
10150
  const sessionId = this.getSipSessionId(sipSession);
10151
+ fromSession = fromSession || this.callSessions[sessionId];
10101
10152
 
10102
10153
  const callSession = new CallSession({
10103
10154
  callId: fromSession && fromSession.callId,
@@ -10105,6 +10156,8 @@ class WebRTCPhone extends Emitter {
10105
10156
  sipStatus: state,
10106
10157
  displayName: identity ? identity.displayName || number : number,
10107
10158
  startTime: fromSession ? fromSession.startTime : new Date(),
10159
+ creationTime: fromSession ? fromSession.creationTime : null,
10160
+ endTime: fromSession ? fromSession.endTime : null,
10108
10161
  answered: state === SessionState.Established,
10109
10162
  paused: this.client.isCallHeld(sipSession),
10110
10163
  isCaller: 'incoming' in extra ? !extra.incoming : false,
@@ -10115,6 +10168,7 @@ class WebRTCPhone extends Emitter {
10115
10168
  videoMuted: fromSession ? fromSession.isVideoMuted() : false,
10116
10169
  recording: fromSession ? fromSession.isRecording() : false,
10117
10170
  recordingPaused: false, // @TODO
10171
+ sipSession,
10118
10172
  ...extra,
10119
10173
  });
10120
10174
 
@@ -10143,6 +10197,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10143
10197
  ON_CAMERA_RESUMED: ON_CAMERA_RESUMED,
10144
10198
  ON_CALL_CANCELED: ON_CALL_CANCELED,
10145
10199
  ON_CALL_FAILED: ON_CALL_FAILED,
10200
+ ON_CALL_REJECTED: ON_CALL_REJECTED,
10146
10201
  ON_CALL_ENDED: ON_CALL_ENDED,
10147
10202
  ON_CALL_ENDING: ON_CALL_ENDING,
10148
10203
  ON_MESSAGE: ON_MESSAGE,
@@ -10172,6 +10227,14 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10172
10227
  'default': WebRTCPhone
10173
10228
  });
10174
10229
 
10230
+ /* */
10231
+ class SFUNotAvailableError extends Error {
10232
+ constructor(message = 'Sorry your user is not configured to support video conference') {
10233
+ super(message);
10234
+ this.name = 'SFUNotAvailableError';
10235
+ }
10236
+ }
10237
+
10175
10238
  //
10176
10239
 
10177
10240
  const logger$7 = IssueReporter$1.loggerFor('simple-phone');
@@ -10556,7 +10619,7 @@ class Phone extends Emitter {
10556
10619
 
10557
10620
  checkSfu() {
10558
10621
  if (!this.hasSfu()) {
10559
- throw new Error('Sorry your user is not configured to support video conference');
10622
+ throw new SFUNotAvailableError();
10560
10623
  }
10561
10624
  }
10562
10625
 
@@ -13452,6 +13515,7 @@ const Wazo = {
13452
13515
  InvalidSubscription,
13453
13516
  InvalidAuthorization,
13454
13517
  CanceledCallError,
13518
+ SFUNotAvailableError,
13455
13519
  };
13456
13520
 
13457
13521
  if (window) {
@@ -444,7 +444,7 @@ const logger$1 = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
444
444
 
445
445
  // Use a function here to be able to mock it in tests
446
446
  const realFetch = () => {
447
- if (typeof document !== 'undefined') {
447
+ if (typeof document !== 'undefined' && window.fetch) {
448
448
  // Browser
449
449
  return window.fetch;
450
450
  }
@@ -1904,7 +1904,7 @@ class Contact {
1904
1904
  this[key] = old[key] || this[key];
1905
1905
  });
1906
1906
 
1907
- if (old.lineState && !this.lineState) {
1907
+ if (old.lineState) {
1908
1908
  this.lineState = old.lineState;
1909
1909
  }
1910
1910
 
@@ -248,13 +248,16 @@ var updateFrom = (instance , from ) => {
248
248
 
249
249
 
250
250
 
251
+
251
252
 
252
253
 
253
254
 
254
255
 
255
256
 
257
+
256
258
 
257
259
 
260
+
258
261
 
259
262
 
260
263
 
@@ -271,6 +274,7 @@ var updateFrom = (instance , from ) => {
271
274
 
272
275
 
273
276
 
277
+
274
278
 
275
279
 
276
280
  class CallSession {
@@ -290,10 +294,14 @@ class CallSession {
290
294
 
291
295
 
292
296
 
293
-
297
+
298
+
299
+ // = creationTime
294
300
 
295
301
 
296
302
 
303
+
304
+
297
305
 
298
306
 
299
307
 
@@ -329,6 +337,8 @@ class CallSession {
329
337
 
330
338
 
331
339
 
340
+
341
+
332
342
 
333
343
  constructor({
334
344
  answered,
@@ -342,6 +352,8 @@ class CallSession {
342
352
  paused,
343
353
  ringing,
344
354
  startTime,
355
+ creationTime,
356
+ endTime,
345
357
  cameraEnabled,
346
358
  dialedExtension,
347
359
  sipCallId,
@@ -354,12 +366,16 @@ class CallSession {
354
366
  recording,
355
367
  recordingPaused,
356
368
  videoRemotelyDowngraded,
369
+ sipSession,
370
+ answerTime,
357
371
  } ) {
358
372
  this.callId = callId;
359
373
  this.sipCallId = sipCallId;
360
374
  this.displayName = displayName;
361
375
  this.number = number;
376
+ this.creationTime = creationTime;
362
377
  this.startTime = startTime;
378
+ this.endTime = endTime;
363
379
  this.isCaller = isCaller;
364
380
  this.answered = answered;
365
381
  this.answeredBySystem = answeredBySystem;
@@ -378,6 +394,8 @@ class CallSession {
378
394
  this.recording = recording || false;
379
395
  this.recordingPaused = recordingPaused || false;
380
396
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
397
+ this.sipSession = sipSession;
398
+ this.answerTime = answerTime || this.answerTime;
381
399
 
382
400
  // Useful to compare instead of instanceof with minified code
383
401
  this.type = 'CallSession';
@@ -408,7 +426,7 @@ class CallSession {
408
426
  }
409
427
 
410
428
  answer() {
411
- this.answered = true;
429
+ this.answerTime = new Date();
412
430
  }
413
431
 
414
432
  systemAnswer() {
@@ -564,6 +582,15 @@ class CallSession {
564
582
  return newFrom(callSession, CallSession);
565
583
  }
566
584
 
585
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
586
+ set answered(value ) {
587
+ this.answerTime = value ? new Date() : null;
588
+ }
589
+
590
+ get answered() {
591
+ return !!this.answerTime;
592
+ }
593
+
567
594
  static parseCall(call ) {
568
595
  return new CallSession({
569
596
  callId: call.id,
@@ -1028,7 +1055,7 @@ const logger$c = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
1028
1055
 
1029
1056
  // Use a function here to be able to mock it in tests
1030
1057
  const realFetch = () => {
1031
- if (typeof document !== 'undefined') {
1058
+ if (typeof document !== 'undefined' && window.fetch) {
1032
1059
  // Browser
1033
1060
  return window.fetch;
1034
1061
  }
@@ -2477,7 +2504,7 @@ class Contact {
2477
2504
  this[key] = old[key] || this[key];
2478
2505
  });
2479
2506
 
2480
- if (old.lineState && !this.lineState) {
2507
+ if (old.lineState) {
2481
2508
  this.lineState = old.lineState;
2482
2509
  }
2483
2510
 
@@ -5798,11 +5825,16 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5798
5825
 
5799
5826
  // $FlowFixMe
5800
5827
  setRemoteSessionDescription(sessionDescription ) {
5801
- const result = super.setRemoteSessionDescription(sessionDescription);
5828
+ try {
5829
+ const result = super.setRemoteSessionDescription(sessionDescription);
5802
5830
 
5803
- this.eventEmitter.emit('setDescription', sessionDescription);
5831
+ this.eventEmitter.emit('setDescription', sessionDescription);
5804
5832
 
5805
- return result;
5833
+ return result;
5834
+ } catch (error) {
5835
+ this.logger.error('SessionDescriptionHandler.setRemoteSessionDescription error', error);
5836
+ throw error;
5837
+ }
5806
5838
  }
5807
5839
 
5808
5840
  // Overridden to avoid to fix ice-candidates missing in the SDP in react-native and chrome canary.
@@ -8454,6 +8486,7 @@ const ON_CAMERA_DISABLED = 'onCameraDisabled';
8454
8486
  const ON_CAMERA_RESUMED = 'onCameraResumed';
8455
8487
  const ON_CALL_CANCELED = 'onCallCanceled';
8456
8488
  const ON_CALL_FAILED = 'onCallFailed';
8489
+ const ON_CALL_REJECTED = 'onCallRejected';
8457
8490
  const ON_CALL_ENDED = 'onCallEnded';
8458
8491
  const ON_CALL_ENDING = 'onCallEnding';
8459
8492
  const ON_MESSAGE = 'onMessage';
@@ -8498,6 +8531,7 @@ const events = [
8498
8531
  ON_CAMERA_DISABLED,
8499
8532
  ON_CALL_FAILED,
8500
8533
  ON_CALL_ENDED,
8534
+ ON_CALL_REJECTED,
8501
8535
  ON_MESSAGE,
8502
8536
  ON_REINVITE,
8503
8537
  ON_TRACK,
@@ -8854,6 +8888,7 @@ class WebRTCPhone extends Emitter {
8854
8888
 
8855
8889
  // Should be called before `_onCallTerminated` or the callCount will not decrement...
8856
8890
  const callSession = this._createCallSession(sipSession);
8891
+ callSession.endTime = new Date();
8857
8892
  const wasCurrentSession = this._onCallTerminated(sipSession);
8858
8893
 
8859
8894
  return this.eventEmitter.emit(ON_CALL_ENDED, callSession, wasCurrentSession);
@@ -9049,6 +9084,7 @@ class WebRTCPhone extends Emitter {
9049
9084
  this.removeIncomingSessions(sipSessionId);
9050
9085
  }
9051
9086
 
9087
+ callSession.answerTime = new Date();
9052
9088
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
9053
9089
 
9054
9090
  return callSession;
@@ -9106,6 +9142,7 @@ class WebRTCPhone extends Emitter {
9106
9142
  _onCallTerminated(sipSession ) {
9107
9143
  logger$8.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
9108
9144
 
9145
+ const sipSessionId = this.getSipSessionId(sipSession);
9109
9146
  const callSession = this._createCallSession(sipSession);
9110
9147
  const isCurrentSession = this.isCurrentCallSipSession(callSession);
9111
9148
  const isCurrentIncomingCall = callSession.is(this.getIncomingCallSession());
@@ -9123,7 +9160,6 @@ class WebRTCPhone extends Emitter {
9123
9160
  }, 5);
9124
9161
  }
9125
9162
 
9126
- const sipSessionId = this.getSipSessionId(sipSession);
9127
9163
  if (sipSessionId) {
9128
9164
  this.removeIncomingSessions(sipSessionId);
9129
9165
  }
@@ -9264,6 +9300,7 @@ class WebRTCPhone extends Emitter {
9264
9300
  }
9265
9301
 
9266
9302
  this.shouldSendReinvite = false;
9303
+ callSession.answerTime = new Date();
9267
9304
  this.acceptedSessions[callSession.getId()] = true;
9268
9305
 
9269
9306
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -9573,6 +9610,7 @@ class WebRTCPhone extends Emitter {
9573
9610
  return Promise.resolve(null);
9574
9611
  }
9575
9612
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
9613
+ callSession.creationTime = new Date();
9576
9614
 
9577
9615
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
9578
9616
 
@@ -9768,8 +9806,12 @@ class WebRTCPhone extends Emitter {
9768
9806
  }
9769
9807
 
9770
9808
  const sessionId = this.incomingSessions[0];
9809
+ const sipSession = this.client.getSipSession(sessionId);
9810
+ if (!sipSession) {
9811
+ return null;
9812
+ }
9771
9813
 
9772
- return this._createCallSession(this.client.getSipSession(sessionId));
9814
+ return this._createCallSession(sipSession);
9773
9815
  }
9774
9816
 
9775
9817
  sendMessage(sipSession = null, body , contentType = 'text/plain') {
@@ -9847,6 +9889,7 @@ class WebRTCPhone extends Emitter {
9847
9889
  callSession);
9848
9890
  }
9849
9891
 
9892
+ callSession.creationTime = new Date();
9850
9893
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
9851
9894
  });
9852
9895
 
@@ -9886,6 +9929,13 @@ class WebRTCPhone extends Emitter {
9886
9929
  this.eventEmitter.emit(ON_CALL_ERROR, e);
9887
9930
  });
9888
9931
 
9932
+ this.client.on(this.client.REJECTED, session => {
9933
+ logger$8.info('WebRTC call rejected', session.id);
9934
+ const callSession = this._createCallSession(session);
9935
+ callSession.endTime = new Date();
9936
+ this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
9937
+ });
9938
+
9889
9939
  this.client.on(this.client.UNREGISTERED, () => {
9890
9940
  logger$8.info('WebRTC unregistered');
9891
9941
  this.eventEmitter.emit(ON_UNREGISTERED);
@@ -10098,6 +10148,7 @@ class WebRTCPhone extends Emitter {
10098
10148
  const number = identity ? identity.uri._normal.user : null;
10099
10149
  const { state } = sipSession || {};
10100
10150
  const sessionId = this.getSipSessionId(sipSession);
10151
+ fromSession = fromSession || this.callSessions[sessionId];
10101
10152
 
10102
10153
  const callSession = new CallSession({
10103
10154
  callId: fromSession && fromSession.callId,
@@ -10105,6 +10156,8 @@ class WebRTCPhone extends Emitter {
10105
10156
  sipStatus: state,
10106
10157
  displayName: identity ? identity.displayName || number : number,
10107
10158
  startTime: fromSession ? fromSession.startTime : new Date(),
10159
+ creationTime: fromSession ? fromSession.creationTime : null,
10160
+ endTime: fromSession ? fromSession.endTime : null,
10108
10161
  answered: state === SessionState.Established,
10109
10162
  paused: this.client.isCallHeld(sipSession),
10110
10163
  isCaller: 'incoming' in extra ? !extra.incoming : false,
@@ -10115,6 +10168,7 @@ class WebRTCPhone extends Emitter {
10115
10168
  videoMuted: fromSession ? fromSession.isVideoMuted() : false,
10116
10169
  recording: fromSession ? fromSession.isRecording() : false,
10117
10170
  recordingPaused: false, // @TODO
10171
+ sipSession,
10118
10172
  ...extra,
10119
10173
  });
10120
10174
 
@@ -10143,6 +10197,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10143
10197
  ON_CAMERA_RESUMED: ON_CAMERA_RESUMED,
10144
10198
  ON_CALL_CANCELED: ON_CALL_CANCELED,
10145
10199
  ON_CALL_FAILED: ON_CALL_FAILED,
10200
+ ON_CALL_REJECTED: ON_CALL_REJECTED,
10146
10201
  ON_CALL_ENDED: ON_CALL_ENDED,
10147
10202
  ON_CALL_ENDING: ON_CALL_ENDING,
10148
10203
  ON_MESSAGE: ON_MESSAGE,
@@ -12422,6 +12477,14 @@ const createLocalVideoStream = async (options ) => createLocalStream('vid
12422
12477
 
12423
12478
  const createLocalAudioStream = async (options ) => createLocalStream('audio', options);
12424
12479
 
12480
+ /* */
12481
+ class SFUNotAvailableError extends Error {
12482
+ constructor(message = 'Sorry your user is not configured to support video conference') {
12483
+ super(message);
12484
+ this.name = 'SFUNotAvailableError';
12485
+ }
12486
+ }
12487
+
12425
12488
  //
12426
12489
 
12427
12490
 
@@ -13323,6 +13386,7 @@ const Wazo = {
13323
13386
  InvalidSubscription,
13324
13387
  InvalidAuthorization,
13325
13388
  CanceledCallError,
13389
+ SFUNotAvailableError,
13326
13390
  };
13327
13391
 
13328
13392
  if (window) {
@@ -13716,7 +13780,7 @@ class Phone extends Emitter {
13716
13780
 
13717
13781
  checkSfu() {
13718
13782
  if (!this.hasSfu()) {
13719
- throw new Error('Sorry your user is not configured to support video conference');
13783
+ throw new SFUNotAvailableError();
13720
13784
  }
13721
13785
  }
13722
13786
 
@@ -39,7 +39,7 @@ IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
39
39
 
40
40
  // Use a function here to be able to mock it in tests
41
41
  const realFetch = () => {
42
- if (typeof document !== 'undefined') {
42
+ if (typeof document !== 'undefined' && window.fetch) {
43
43
  // Browser
44
44
  return window.fetch;
45
45
  }