@wazo/sdk 0.37.26 → 0.37.30

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 (121) hide show
  1. package/README.md +98 -59
  2. package/dist/wazo-sdk.js +3 -3
  3. package/esm/__tests__/api-client.test.js +1 -1
  4. package/esm/__tests__/web-rtc-client.test.js +18 -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 +1 -1
  15. package/esm/api/webhookd.js +1 -1
  16. package/esm/api-client.js +1 -1
  17. package/esm/checker/Checker.js +18 -5
  18. package/esm/checker/checks/aor.js +1 -1
  19. package/esm/checker/checks/api.js +1 -1
  20. package/esm/checker/checks/index.js +18 -5
  21. package/esm/checker/checks/wazo-websocket.js +1 -1
  22. package/esm/checker/checks/webrtc-transport.js +18 -5
  23. package/esm/checker/checks/webrtc.js +18 -5
  24. package/esm/domain/AdHocAPIConference.js +1 -1
  25. package/esm/domain/CallSession.js +29 -2
  26. package/esm/domain/Features.js +1 -1
  27. package/esm/domain/Phone/CTIPhone.js +30 -3
  28. package/esm/domain/Phone/WebRTCPhone.js +55 -6
  29. package/esm/domain/SFUNotAvailableError.js +9 -0
  30. package/esm/domain/__tests__/CallSession.test.js +46 -2
  31. package/esm/domain/__tests__/IndirectTransfer.test.js +29 -2
  32. package/esm/domain/__tests__/Room.test.js +29 -2
  33. package/esm/index.js +83 -10
  34. package/esm/lib/WazoSessionDescriptionHandler.js +9 -4
  35. package/esm/service/CallApi.js +1 -1
  36. package/esm/service/IssueReporter.js +1 -1
  37. package/esm/service/__tests__/IssueReporter.test.js +1 -1
  38. package/esm/service/getApiClient.js +1 -1
  39. package/esm/simple/Auth.js +82 -10
  40. package/esm/simple/Configuration.js +82 -10
  41. package/esm/simple/Directory.js +1 -1
  42. package/esm/simple/Phone.js +82 -10
  43. package/esm/simple/Websocket.js +1 -1
  44. package/esm/simple/index.js +82 -10
  45. package/esm/simple/room/LocalParticipant.js +82 -10
  46. package/esm/simple/room/Participant.js +82 -10
  47. package/esm/simple/room/RemoteParticipant.js +82 -10
  48. package/esm/simple/room/Room.js +82 -10
  49. package/esm/simple/room/SipRoom.js +82 -10
  50. package/esm/simple/room/Stream.js +82 -10
  51. package/esm/simple/room/__tests__/RemoteParticipant.test.js +82 -10
  52. package/esm/simple/utils.js +82 -10
  53. package/esm/utils/__tests__/api-requester.test.js +1 -1
  54. package/esm/utils/api-requester.js +1 -1
  55. package/esm/web-rtc-client.js +18 -5
  56. package/esm/websocket-client.js +1 -1
  57. package/lib/__tests__/api-client.test.js +1 -1
  58. package/lib/__tests__/web-rtc-client.test.js +18 -5
  59. package/lib/api/agentd.js +1 -1
  60. package/lib/api/amid.js +1 -1
  61. package/lib/api/application.js +1 -1
  62. package/lib/api/auth.js +1 -1
  63. package/lib/api/call-logd.js +1 -1
  64. package/lib/api/calld.js +1 -1
  65. package/lib/api/chatd.js +1 -1
  66. package/lib/api/confd.js +1 -1
  67. package/lib/api/ctid-ng.js +1 -1
  68. package/lib/api/dird.js +1 -1
  69. package/lib/api/webhookd.js +1 -1
  70. package/lib/api-client.js +1 -1
  71. package/lib/checker/Checker.js +18 -5
  72. package/lib/checker/checks/aor.js +1 -1
  73. package/lib/checker/checks/api.js +1 -1
  74. package/lib/checker/checks/index.js +18 -5
  75. package/lib/checker/checks/wazo-websocket.js +1 -1
  76. package/lib/checker/checks/webrtc-transport.js +18 -5
  77. package/lib/checker/checks/webrtc.js +18 -5
  78. package/lib/domain/AdHocAPIConference.js +1 -1
  79. package/lib/domain/CallSession.js +29 -2
  80. package/lib/domain/Features.js +1 -1
  81. package/lib/domain/Phone/CTIPhone.js +30 -3
  82. package/lib/domain/Phone/WebRTCPhone.js +55 -5
  83. package/lib/domain/SFUNotAvailableError.js +11 -0
  84. package/lib/domain/__tests__/CallSession.test.js +46 -2
  85. package/lib/domain/__tests__/IndirectTransfer.test.js +29 -2
  86. package/lib/domain/__tests__/Room.test.js +29 -2
  87. package/lib/index.js +83 -10
  88. package/lib/lib/WazoSessionDescriptionHandler.js +9 -4
  89. package/lib/service/CallApi.js +1 -1
  90. package/lib/service/IssueReporter.js +1 -1
  91. package/lib/service/__tests__/IssueReporter.test.js +1 -1
  92. package/lib/service/getApiClient.js +1 -1
  93. package/lib/simple/Auth.js +82 -10
  94. package/lib/simple/Configuration.js +82 -10
  95. package/lib/simple/Directory.js +1 -1
  96. package/lib/simple/Phone.js +82 -10
  97. package/lib/simple/Websocket.js +1 -1
  98. package/lib/simple/index.js +82 -10
  99. package/lib/simple/room/LocalParticipant.js +82 -10
  100. package/lib/simple/room/Participant.js +82 -10
  101. package/lib/simple/room/RemoteParticipant.js +82 -10
  102. package/lib/simple/room/Room.js +82 -10
  103. package/lib/simple/room/SipRoom.js +82 -10
  104. package/lib/simple/room/Stream.js +82 -10
  105. package/lib/simple/room/__tests__/RemoteParticipant.test.js +82 -10
  106. package/lib/simple/utils.js +82 -10
  107. package/lib/utils/__tests__/api-requester.test.js +1 -1
  108. package/lib/utils/api-requester.js +1 -1
  109. package/lib/web-rtc-client.js +18 -5
  110. package/lib/websocket-client.js +1 -1
  111. package/package.json +1 -1
  112. package/src/domain/CallSession.js +32 -4
  113. package/src/domain/Phone/WebRTCPhone.js +24 -2
  114. package/src/domain/SFUNotAvailableError.js +7 -0
  115. package/src/domain/__tests__/CallSession.test.js +17 -0
  116. package/src/index.js +2 -0
  117. package/src/lib/WazoSessionDescriptionHandler.js +8 -3
  118. package/src/simple/Phone.js +2 -1
  119. package/src/simple/index.js +2 -0
  120. package/src/utils/api-requester.js +1 -1
  121. package/src/web-rtc-client.js +9 -1
@@ -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.
@@ -6341,6 +6373,7 @@ const MAX_REGISTER_TRIES = 10;
6341
6373
 
6342
6374
 
6343
6375
 
6376
+
6344
6377
 
6345
6378
 
6346
6379
 
@@ -7957,6 +7990,13 @@ class WebRTCClient extends Emitter {
7957
7990
  }
7958
7991
 
7959
7992
  _createWebRTCConfiguration(configOverrides = {}) {
7993
+ let { host } = this.config;
7994
+ let port = this.config.port || 443;
7995
+
7996
+ if (this.config.websocketSip) {
7997
+ [host, port = 443] = this.config.websocketSip.split(':');
7998
+ }
7999
+
7960
8000
  const config = {
7961
8001
  authorizationUsername: this.config.authorizationUser,
7962
8002
  authorizationPassword: this.config.password,
@@ -7992,7 +8032,7 @@ class WebRTCClient extends Emitter {
7992
8032
  },
7993
8033
  transportOptions: {
7994
8034
  traceSip: configOverrides.traceSip || false,
7995
- wsServers: `wss://${this.config.host}:${this.config.port || 443}/api/asterisk/ws`,
8035
+ wsServers: `wss://${host}:${port}/api/asterisk/ws`,
7996
8036
  },
7997
8037
  sessionDescriptionHandlerFactoryOptions: {
7998
8038
  modifiers: [replaceLocalIpModifier],
@@ -8454,6 +8494,7 @@ const ON_CAMERA_DISABLED = 'onCameraDisabled';
8454
8494
  const ON_CAMERA_RESUMED = 'onCameraResumed';
8455
8495
  const ON_CALL_CANCELED = 'onCallCanceled';
8456
8496
  const ON_CALL_FAILED = 'onCallFailed';
8497
+ const ON_CALL_REJECTED = 'onCallRejected';
8457
8498
  const ON_CALL_ENDED = 'onCallEnded';
8458
8499
  const ON_CALL_ENDING = 'onCallEnding';
8459
8500
  const ON_MESSAGE = 'onMessage';
@@ -8498,6 +8539,7 @@ const events = [
8498
8539
  ON_CAMERA_DISABLED,
8499
8540
  ON_CALL_FAILED,
8500
8541
  ON_CALL_ENDED,
8542
+ ON_CALL_REJECTED,
8501
8543
  ON_MESSAGE,
8502
8544
  ON_REINVITE,
8503
8545
  ON_TRACK,
@@ -8854,6 +8896,7 @@ class WebRTCPhone extends Emitter {
8854
8896
 
8855
8897
  // Should be called before `_onCallTerminated` or the callCount will not decrement...
8856
8898
  const callSession = this._createCallSession(sipSession);
8899
+ callSession.endTime = new Date();
8857
8900
  const wasCurrentSession = this._onCallTerminated(sipSession);
8858
8901
 
8859
8902
  return this.eventEmitter.emit(ON_CALL_ENDED, callSession, wasCurrentSession);
@@ -9049,6 +9092,7 @@ class WebRTCPhone extends Emitter {
9049
9092
  this.removeIncomingSessions(sipSessionId);
9050
9093
  }
9051
9094
 
9095
+ callSession.answerTime = new Date();
9052
9096
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
9053
9097
 
9054
9098
  return callSession;
@@ -9106,6 +9150,7 @@ class WebRTCPhone extends Emitter {
9106
9150
  _onCallTerminated(sipSession ) {
9107
9151
  logger$8.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
9108
9152
 
9153
+ const sipSessionId = this.getSipSessionId(sipSession);
9109
9154
  const callSession = this._createCallSession(sipSession);
9110
9155
  const isCurrentSession = this.isCurrentCallSipSession(callSession);
9111
9156
  const isCurrentIncomingCall = callSession.is(this.getIncomingCallSession());
@@ -9123,7 +9168,6 @@ class WebRTCPhone extends Emitter {
9123
9168
  }, 5);
9124
9169
  }
9125
9170
 
9126
- const sipSessionId = this.getSipSessionId(sipSession);
9127
9171
  if (sipSessionId) {
9128
9172
  this.removeIncomingSessions(sipSessionId);
9129
9173
  }
@@ -9264,6 +9308,7 @@ class WebRTCPhone extends Emitter {
9264
9308
  }
9265
9309
 
9266
9310
  this.shouldSendReinvite = false;
9311
+ callSession.answerTime = new Date();
9267
9312
  this.acceptedSessions[callSession.getId()] = true;
9268
9313
 
9269
9314
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -9573,6 +9618,7 @@ class WebRTCPhone extends Emitter {
9573
9618
  return Promise.resolve(null);
9574
9619
  }
9575
9620
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
9621
+ callSession.creationTime = new Date();
9576
9622
 
9577
9623
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
9578
9624
 
@@ -9768,8 +9814,12 @@ class WebRTCPhone extends Emitter {
9768
9814
  }
9769
9815
 
9770
9816
  const sessionId = this.incomingSessions[0];
9817
+ const sipSession = this.client.getSipSession(sessionId);
9818
+ if (!sipSession) {
9819
+ return null;
9820
+ }
9771
9821
 
9772
- return this._createCallSession(this.client.getSipSession(sessionId));
9822
+ return this._createCallSession(sipSession);
9773
9823
  }
9774
9824
 
9775
9825
  sendMessage(sipSession = null, body , contentType = 'text/plain') {
@@ -9847,6 +9897,7 @@ class WebRTCPhone extends Emitter {
9847
9897
  callSession);
9848
9898
  }
9849
9899
 
9900
+ callSession.creationTime = new Date();
9850
9901
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
9851
9902
  });
9852
9903
 
@@ -9886,6 +9937,13 @@ class WebRTCPhone extends Emitter {
9886
9937
  this.eventEmitter.emit(ON_CALL_ERROR, e);
9887
9938
  });
9888
9939
 
9940
+ this.client.on(this.client.REJECTED, session => {
9941
+ logger$8.info('WebRTC call rejected', session.id);
9942
+ const callSession = this._createCallSession(session);
9943
+ callSession.endTime = new Date();
9944
+ this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
9945
+ });
9946
+
9889
9947
  this.client.on(this.client.UNREGISTERED, () => {
9890
9948
  logger$8.info('WebRTC unregistered');
9891
9949
  this.eventEmitter.emit(ON_UNREGISTERED);
@@ -10098,6 +10156,7 @@ class WebRTCPhone extends Emitter {
10098
10156
  const number = identity ? identity.uri._normal.user : null;
10099
10157
  const { state } = sipSession || {};
10100
10158
  const sessionId = this.getSipSessionId(sipSession);
10159
+ fromSession = fromSession || this.callSessions[sessionId];
10101
10160
 
10102
10161
  const callSession = new CallSession({
10103
10162
  callId: fromSession && fromSession.callId,
@@ -10105,6 +10164,8 @@ class WebRTCPhone extends Emitter {
10105
10164
  sipStatus: state,
10106
10165
  displayName: identity ? identity.displayName || number : number,
10107
10166
  startTime: fromSession ? fromSession.startTime : new Date(),
10167
+ creationTime: fromSession ? fromSession.creationTime : null,
10168
+ endTime: fromSession ? fromSession.endTime : null,
10108
10169
  answered: state === SessionState.Established,
10109
10170
  paused: this.client.isCallHeld(sipSession),
10110
10171
  isCaller: 'incoming' in extra ? !extra.incoming : false,
@@ -10115,6 +10176,7 @@ class WebRTCPhone extends Emitter {
10115
10176
  videoMuted: fromSession ? fromSession.isVideoMuted() : false,
10116
10177
  recording: fromSession ? fromSession.isRecording() : false,
10117
10178
  recordingPaused: false, // @TODO
10179
+ sipSession,
10118
10180
  ...extra,
10119
10181
  });
10120
10182
 
@@ -10143,6 +10205,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10143
10205
  ON_CAMERA_RESUMED: ON_CAMERA_RESUMED,
10144
10206
  ON_CALL_CANCELED: ON_CALL_CANCELED,
10145
10207
  ON_CALL_FAILED: ON_CALL_FAILED,
10208
+ ON_CALL_REJECTED: ON_CALL_REJECTED,
10146
10209
  ON_CALL_ENDED: ON_CALL_ENDED,
10147
10210
  ON_CALL_ENDING: ON_CALL_ENDING,
10148
10211
  ON_MESSAGE: ON_MESSAGE,
@@ -10172,6 +10235,14 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10172
10235
  'default': WebRTCPhone
10173
10236
  });
10174
10237
 
10238
+ /* */
10239
+ class SFUNotAvailableError extends Error {
10240
+ constructor(message = 'Sorry your user is not configured to support video conference') {
10241
+ super(message);
10242
+ this.name = 'SFUNotAvailableError';
10243
+ }
10244
+ }
10245
+
10175
10246
  //
10176
10247
 
10177
10248
  const logger$7 = IssueReporter$1.loggerFor('simple-phone');
@@ -10556,7 +10627,7 @@ class Phone extends Emitter {
10556
10627
 
10557
10628
  checkSfu() {
10558
10629
  if (!this.hasSfu()) {
10559
- throw new Error('Sorry your user is not configured to support video conference');
10630
+ throw new SFUNotAvailableError();
10560
10631
  }
10561
10632
  }
10562
10633
 
@@ -13469,6 +13540,7 @@ const Wazo = {
13469
13540
  InvalidSubscription,
13470
13541
  InvalidAuthorization,
13471
13542
  CanceledCallError,
13543
+ SFUNotAvailableError,
13472
13544
  };
13473
13545
 
13474
13546
  if (window) {
@@ -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.
@@ -6341,6 +6373,7 @@ const MAX_REGISTER_TRIES = 10;
6341
6373
 
6342
6374
 
6343
6375
 
6376
+
6344
6377
 
6345
6378
 
6346
6379
 
@@ -7957,6 +7990,13 @@ class WebRTCClient extends Emitter {
7957
7990
  }
7958
7991
 
7959
7992
  _createWebRTCConfiguration(configOverrides = {}) {
7993
+ let { host } = this.config;
7994
+ let port = this.config.port || 443;
7995
+
7996
+ if (this.config.websocketSip) {
7997
+ [host, port = 443] = this.config.websocketSip.split(':');
7998
+ }
7999
+
7960
8000
  const config = {
7961
8001
  authorizationUsername: this.config.authorizationUser,
7962
8002
  authorizationPassword: this.config.password,
@@ -7992,7 +8032,7 @@ class WebRTCClient extends Emitter {
7992
8032
  },
7993
8033
  transportOptions: {
7994
8034
  traceSip: configOverrides.traceSip || false,
7995
- wsServers: `wss://${this.config.host}:${this.config.port || 443}/api/asterisk/ws`,
8035
+ wsServers: `wss://${host}:${port}/api/asterisk/ws`,
7996
8036
  },
7997
8037
  sessionDescriptionHandlerFactoryOptions: {
7998
8038
  modifiers: [replaceLocalIpModifier],
@@ -8454,6 +8494,7 @@ const ON_CAMERA_DISABLED = 'onCameraDisabled';
8454
8494
  const ON_CAMERA_RESUMED = 'onCameraResumed';
8455
8495
  const ON_CALL_CANCELED = 'onCallCanceled';
8456
8496
  const ON_CALL_FAILED = 'onCallFailed';
8497
+ const ON_CALL_REJECTED = 'onCallRejected';
8457
8498
  const ON_CALL_ENDED = 'onCallEnded';
8458
8499
  const ON_CALL_ENDING = 'onCallEnding';
8459
8500
  const ON_MESSAGE = 'onMessage';
@@ -8498,6 +8539,7 @@ const events = [
8498
8539
  ON_CAMERA_DISABLED,
8499
8540
  ON_CALL_FAILED,
8500
8541
  ON_CALL_ENDED,
8542
+ ON_CALL_REJECTED,
8501
8543
  ON_MESSAGE,
8502
8544
  ON_REINVITE,
8503
8545
  ON_TRACK,
@@ -8854,6 +8896,7 @@ class WebRTCPhone extends Emitter {
8854
8896
 
8855
8897
  // Should be called before `_onCallTerminated` or the callCount will not decrement...
8856
8898
  const callSession = this._createCallSession(sipSession);
8899
+ callSession.endTime = new Date();
8857
8900
  const wasCurrentSession = this._onCallTerminated(sipSession);
8858
8901
 
8859
8902
  return this.eventEmitter.emit(ON_CALL_ENDED, callSession, wasCurrentSession);
@@ -9049,6 +9092,7 @@ class WebRTCPhone extends Emitter {
9049
9092
  this.removeIncomingSessions(sipSessionId);
9050
9093
  }
9051
9094
 
9095
+ callSession.answerTime = new Date();
9052
9096
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
9053
9097
 
9054
9098
  return callSession;
@@ -9106,6 +9150,7 @@ class WebRTCPhone extends Emitter {
9106
9150
  _onCallTerminated(sipSession ) {
9107
9151
  logger$8.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
9108
9152
 
9153
+ const sipSessionId = this.getSipSessionId(sipSession);
9109
9154
  const callSession = this._createCallSession(sipSession);
9110
9155
  const isCurrentSession = this.isCurrentCallSipSession(callSession);
9111
9156
  const isCurrentIncomingCall = callSession.is(this.getIncomingCallSession());
@@ -9123,7 +9168,6 @@ class WebRTCPhone extends Emitter {
9123
9168
  }, 5);
9124
9169
  }
9125
9170
 
9126
- const sipSessionId = this.getSipSessionId(sipSession);
9127
9171
  if (sipSessionId) {
9128
9172
  this.removeIncomingSessions(sipSessionId);
9129
9173
  }
@@ -9264,6 +9308,7 @@ class WebRTCPhone extends Emitter {
9264
9308
  }
9265
9309
 
9266
9310
  this.shouldSendReinvite = false;
9311
+ callSession.answerTime = new Date();
9267
9312
  this.acceptedSessions[callSession.getId()] = true;
9268
9313
 
9269
9314
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -9573,6 +9618,7 @@ class WebRTCPhone extends Emitter {
9573
9618
  return Promise.resolve(null);
9574
9619
  }
9575
9620
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
9621
+ callSession.creationTime = new Date();
9576
9622
 
9577
9623
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
9578
9624
 
@@ -9768,8 +9814,12 @@ class WebRTCPhone extends Emitter {
9768
9814
  }
9769
9815
 
9770
9816
  const sessionId = this.incomingSessions[0];
9817
+ const sipSession = this.client.getSipSession(sessionId);
9818
+ if (!sipSession) {
9819
+ return null;
9820
+ }
9771
9821
 
9772
- return this._createCallSession(this.client.getSipSession(sessionId));
9822
+ return this._createCallSession(sipSession);
9773
9823
  }
9774
9824
 
9775
9825
  sendMessage(sipSession = null, body , contentType = 'text/plain') {
@@ -9847,6 +9897,7 @@ class WebRTCPhone extends Emitter {
9847
9897
  callSession);
9848
9898
  }
9849
9899
 
9900
+ callSession.creationTime = new Date();
9850
9901
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
9851
9902
  });
9852
9903
 
@@ -9886,6 +9937,13 @@ class WebRTCPhone extends Emitter {
9886
9937
  this.eventEmitter.emit(ON_CALL_ERROR, e);
9887
9938
  });
9888
9939
 
9940
+ this.client.on(this.client.REJECTED, session => {
9941
+ logger$8.info('WebRTC call rejected', session.id);
9942
+ const callSession = this._createCallSession(session);
9943
+ callSession.endTime = new Date();
9944
+ this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
9945
+ });
9946
+
9889
9947
  this.client.on(this.client.UNREGISTERED, () => {
9890
9948
  logger$8.info('WebRTC unregistered');
9891
9949
  this.eventEmitter.emit(ON_UNREGISTERED);
@@ -10098,6 +10156,7 @@ class WebRTCPhone extends Emitter {
10098
10156
  const number = identity ? identity.uri._normal.user : null;
10099
10157
  const { state } = sipSession || {};
10100
10158
  const sessionId = this.getSipSessionId(sipSession);
10159
+ fromSession = fromSession || this.callSessions[sessionId];
10101
10160
 
10102
10161
  const callSession = new CallSession({
10103
10162
  callId: fromSession && fromSession.callId,
@@ -10105,6 +10164,8 @@ class WebRTCPhone extends Emitter {
10105
10164
  sipStatus: state,
10106
10165
  displayName: identity ? identity.displayName || number : number,
10107
10166
  startTime: fromSession ? fromSession.startTime : new Date(),
10167
+ creationTime: fromSession ? fromSession.creationTime : null,
10168
+ endTime: fromSession ? fromSession.endTime : null,
10108
10169
  answered: state === SessionState.Established,
10109
10170
  paused: this.client.isCallHeld(sipSession),
10110
10171
  isCaller: 'incoming' in extra ? !extra.incoming : false,
@@ -10115,6 +10176,7 @@ class WebRTCPhone extends Emitter {
10115
10176
  videoMuted: fromSession ? fromSession.isVideoMuted() : false,
10116
10177
  recording: fromSession ? fromSession.isRecording() : false,
10117
10178
  recordingPaused: false, // @TODO
10179
+ sipSession,
10118
10180
  ...extra,
10119
10181
  });
10120
10182
 
@@ -10143,6 +10205,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10143
10205
  ON_CAMERA_RESUMED: ON_CAMERA_RESUMED,
10144
10206
  ON_CALL_CANCELED: ON_CALL_CANCELED,
10145
10207
  ON_CALL_FAILED: ON_CALL_FAILED,
10208
+ ON_CALL_REJECTED: ON_CALL_REJECTED,
10146
10209
  ON_CALL_ENDED: ON_CALL_ENDED,
10147
10210
  ON_CALL_ENDING: ON_CALL_ENDING,
10148
10211
  ON_MESSAGE: ON_MESSAGE,
@@ -10172,6 +10235,14 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10172
10235
  'default': WebRTCPhone
10173
10236
  });
10174
10237
 
10238
+ /* */
10239
+ class SFUNotAvailableError extends Error {
10240
+ constructor(message = 'Sorry your user is not configured to support video conference') {
10241
+ super(message);
10242
+ this.name = 'SFUNotAvailableError';
10243
+ }
10244
+ }
10245
+
10175
10246
  //
10176
10247
 
10177
10248
  const logger$7 = IssueReporter$1.loggerFor('simple-phone');
@@ -10556,7 +10627,7 @@ class Phone extends Emitter {
10556
10627
 
10557
10628
  checkSfu() {
10558
10629
  if (!this.hasSfu()) {
10559
- throw new Error('Sorry your user is not configured to support video conference');
10630
+ throw new SFUNotAvailableError();
10560
10631
  }
10561
10632
  }
10562
10633
 
@@ -13452,6 +13523,7 @@ const Wazo = {
13452
13523
  InvalidSubscription,
13453
13524
  InvalidAuthorization,
13454
13525
  CanceledCallError,
13526
+ SFUNotAvailableError,
13455
13527
  };
13456
13528
 
13457
13529
  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
  }