@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
@@ -132,7 +132,7 @@ const logger$c = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
132
132
 
133
133
  // Use a function here to be able to mock it in tests
134
134
  const realFetch = () => {
135
- if (typeof document !== 'undefined') {
135
+ if (typeof document !== 'undefined' && window.fetch) {
136
136
  // Browser
137
137
  return window.fetch;
138
138
  }
@@ -3274,13 +3274,16 @@ var updateFrom = (instance , from ) => {
3274
3274
 
3275
3275
 
3276
3276
 
3277
+
3277
3278
 
3278
3279
 
3279
3280
 
3280
3281
 
3281
3282
 
3283
+
3282
3284
 
3283
3285
 
3286
+
3284
3287
 
3285
3288
 
3286
3289
 
@@ -3297,6 +3300,7 @@ var updateFrom = (instance , from ) => {
3297
3300
 
3298
3301
 
3299
3302
 
3303
+
3300
3304
 
3301
3305
 
3302
3306
  class CallSession {
@@ -3316,10 +3320,14 @@ class CallSession {
3316
3320
 
3317
3321
 
3318
3322
 
3319
-
3323
+
3324
+
3325
+ // = creationTime
3320
3326
 
3321
3327
 
3322
3328
 
3329
+
3330
+
3323
3331
 
3324
3332
 
3325
3333
 
@@ -3355,6 +3363,8 @@ class CallSession {
3355
3363
 
3356
3364
 
3357
3365
 
3366
+
3367
+
3358
3368
 
3359
3369
  constructor({
3360
3370
  answered,
@@ -3368,6 +3378,8 @@ class CallSession {
3368
3378
  paused,
3369
3379
  ringing,
3370
3380
  startTime,
3381
+ creationTime,
3382
+ endTime,
3371
3383
  cameraEnabled,
3372
3384
  dialedExtension,
3373
3385
  sipCallId,
@@ -3380,12 +3392,16 @@ class CallSession {
3380
3392
  recording,
3381
3393
  recordingPaused,
3382
3394
  videoRemotelyDowngraded,
3395
+ sipSession,
3396
+ answerTime,
3383
3397
  } ) {
3384
3398
  this.callId = callId;
3385
3399
  this.sipCallId = sipCallId;
3386
3400
  this.displayName = displayName;
3387
3401
  this.number = number;
3402
+ this.creationTime = creationTime;
3388
3403
  this.startTime = startTime;
3404
+ this.endTime = endTime;
3389
3405
  this.isCaller = isCaller;
3390
3406
  this.answered = answered;
3391
3407
  this.answeredBySystem = answeredBySystem;
@@ -3404,6 +3420,8 @@ class CallSession {
3404
3420
  this.recording = recording || false;
3405
3421
  this.recordingPaused = recordingPaused || false;
3406
3422
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
3423
+ this.sipSession = sipSession;
3424
+ this.answerTime = answerTime || this.answerTime;
3407
3425
 
3408
3426
  // Useful to compare instead of instanceof with minified code
3409
3427
  this.type = 'CallSession';
@@ -3434,7 +3452,7 @@ class CallSession {
3434
3452
  }
3435
3453
 
3436
3454
  answer() {
3437
- this.answered = true;
3455
+ this.answerTime = new Date();
3438
3456
  }
3439
3457
 
3440
3458
  systemAnswer() {
@@ -3590,6 +3608,15 @@ class CallSession {
3590
3608
  return newFrom(callSession, CallSession);
3591
3609
  }
3592
3610
 
3611
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
3612
+ set answered(value ) {
3613
+ this.answerTime = value ? new Date() : null;
3614
+ }
3615
+
3616
+ get answered() {
3617
+ return !!this.answerTime;
3618
+ }
3619
+
3593
3620
  static parseCall(call ) {
3594
3621
  return new CallSession({
3595
3622
  callId: call.id,
@@ -6062,11 +6089,16 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
6062
6089
 
6063
6090
  // $FlowFixMe
6064
6091
  setRemoteSessionDescription(sessionDescription ) {
6065
- const result = super.setRemoteSessionDescription(sessionDescription);
6092
+ try {
6093
+ const result = super.setRemoteSessionDescription(sessionDescription);
6066
6094
 
6067
- this.eventEmitter.emit('setDescription', sessionDescription);
6095
+ this.eventEmitter.emit('setDescription', sessionDescription);
6068
6096
 
6069
- return result;
6097
+ return result;
6098
+ } catch (error) {
6099
+ this.logger.error('SessionDescriptionHandler.setRemoteSessionDescription error', error);
6100
+ throw error;
6101
+ }
6070
6102
  }
6071
6103
 
6072
6104
  // Overridden to avoid to fix ice-candidates missing in the SDP in react-native and chrome canary.
@@ -6605,6 +6637,7 @@ const MAX_REGISTER_TRIES = 10;
6605
6637
 
6606
6638
 
6607
6639
 
6640
+
6608
6641
 
6609
6642
 
6610
6643
 
@@ -8221,6 +8254,13 @@ class WebRTCClient extends Emitter {
8221
8254
  }
8222
8255
 
8223
8256
  _createWebRTCConfiguration(configOverrides = {}) {
8257
+ let { host } = this.config;
8258
+ let port = this.config.port || 443;
8259
+
8260
+ if (this.config.websocketSip) {
8261
+ [host, port = 443] = this.config.websocketSip.split(':');
8262
+ }
8263
+
8224
8264
  const config = {
8225
8265
  authorizationUsername: this.config.authorizationUser,
8226
8266
  authorizationPassword: this.config.password,
@@ -8256,7 +8296,7 @@ class WebRTCClient extends Emitter {
8256
8296
  },
8257
8297
  transportOptions: {
8258
8298
  traceSip: configOverrides.traceSip || false,
8259
- wsServers: `wss://${this.config.host}:${this.config.port || 443}/api/asterisk/ws`,
8299
+ wsServers: `wss://${host}:${port}/api/asterisk/ws`,
8260
8300
  },
8261
8301
  sessionDescriptionHandlerFactoryOptions: {
8262
8302
  modifiers: [replaceLocalIpModifier],
@@ -8718,6 +8758,7 @@ const ON_CAMERA_DISABLED = 'onCameraDisabled';
8718
8758
  const ON_CAMERA_RESUMED = 'onCameraResumed';
8719
8759
  const ON_CALL_CANCELED = 'onCallCanceled';
8720
8760
  const ON_CALL_FAILED = 'onCallFailed';
8761
+ const ON_CALL_REJECTED = 'onCallRejected';
8721
8762
  const ON_CALL_ENDED = 'onCallEnded';
8722
8763
  const ON_CALL_ENDING = 'onCallEnding';
8723
8764
  const ON_MESSAGE = 'onMessage';
@@ -8762,6 +8803,7 @@ const events = [
8762
8803
  ON_CAMERA_DISABLED,
8763
8804
  ON_CALL_FAILED,
8764
8805
  ON_CALL_ENDED,
8806
+ ON_CALL_REJECTED,
8765
8807
  ON_MESSAGE,
8766
8808
  ON_REINVITE,
8767
8809
  ON_TRACK,
@@ -9118,6 +9160,7 @@ class WebRTCPhone extends Emitter {
9118
9160
 
9119
9161
  // Should be called before `_onCallTerminated` or the callCount will not decrement...
9120
9162
  const callSession = this._createCallSession(sipSession);
9163
+ callSession.endTime = new Date();
9121
9164
  const wasCurrentSession = this._onCallTerminated(sipSession);
9122
9165
 
9123
9166
  return this.eventEmitter.emit(ON_CALL_ENDED, callSession, wasCurrentSession);
@@ -9313,6 +9356,7 @@ class WebRTCPhone extends Emitter {
9313
9356
  this.removeIncomingSessions(sipSessionId);
9314
9357
  }
9315
9358
 
9359
+ callSession.answerTime = new Date();
9316
9360
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
9317
9361
 
9318
9362
  return callSession;
@@ -9370,6 +9414,7 @@ class WebRTCPhone extends Emitter {
9370
9414
  _onCallTerminated(sipSession ) {
9371
9415
  logger$7.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
9372
9416
 
9417
+ const sipSessionId = this.getSipSessionId(sipSession);
9373
9418
  const callSession = this._createCallSession(sipSession);
9374
9419
  const isCurrentSession = this.isCurrentCallSipSession(callSession);
9375
9420
  const isCurrentIncomingCall = callSession.is(this.getIncomingCallSession());
@@ -9387,7 +9432,6 @@ class WebRTCPhone extends Emitter {
9387
9432
  }, 5);
9388
9433
  }
9389
9434
 
9390
- const sipSessionId = this.getSipSessionId(sipSession);
9391
9435
  if (sipSessionId) {
9392
9436
  this.removeIncomingSessions(sipSessionId);
9393
9437
  }
@@ -9528,6 +9572,7 @@ class WebRTCPhone extends Emitter {
9528
9572
  }
9529
9573
 
9530
9574
  this.shouldSendReinvite = false;
9575
+ callSession.answerTime = new Date();
9531
9576
  this.acceptedSessions[callSession.getId()] = true;
9532
9577
 
9533
9578
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -9837,6 +9882,7 @@ class WebRTCPhone extends Emitter {
9837
9882
  return Promise.resolve(null);
9838
9883
  }
9839
9884
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
9885
+ callSession.creationTime = new Date();
9840
9886
 
9841
9887
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
9842
9888
 
@@ -10032,8 +10078,12 @@ class WebRTCPhone extends Emitter {
10032
10078
  }
10033
10079
 
10034
10080
  const sessionId = this.incomingSessions[0];
10081
+ const sipSession = this.client.getSipSession(sessionId);
10082
+ if (!sipSession) {
10083
+ return null;
10084
+ }
10035
10085
 
10036
- return this._createCallSession(this.client.getSipSession(sessionId));
10086
+ return this._createCallSession(sipSession);
10037
10087
  }
10038
10088
 
10039
10089
  sendMessage(sipSession = null, body , contentType = 'text/plain') {
@@ -10111,6 +10161,7 @@ class WebRTCPhone extends Emitter {
10111
10161
  callSession);
10112
10162
  }
10113
10163
 
10164
+ callSession.creationTime = new Date();
10114
10165
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
10115
10166
  });
10116
10167
 
@@ -10150,6 +10201,13 @@ class WebRTCPhone extends Emitter {
10150
10201
  this.eventEmitter.emit(ON_CALL_ERROR, e);
10151
10202
  });
10152
10203
 
10204
+ this.client.on(this.client.REJECTED, session => {
10205
+ logger$7.info('WebRTC call rejected', session.id);
10206
+ const callSession = this._createCallSession(session);
10207
+ callSession.endTime = new Date();
10208
+ this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
10209
+ });
10210
+
10153
10211
  this.client.on(this.client.UNREGISTERED, () => {
10154
10212
  logger$7.info('WebRTC unregistered');
10155
10213
  this.eventEmitter.emit(ON_UNREGISTERED);
@@ -10362,6 +10420,7 @@ class WebRTCPhone extends Emitter {
10362
10420
  const number = identity ? identity.uri._normal.user : null;
10363
10421
  const { state } = sipSession || {};
10364
10422
  const sessionId = this.getSipSessionId(sipSession);
10423
+ fromSession = fromSession || this.callSessions[sessionId];
10365
10424
 
10366
10425
  const callSession = new CallSession({
10367
10426
  callId: fromSession && fromSession.callId,
@@ -10369,6 +10428,8 @@ class WebRTCPhone extends Emitter {
10369
10428
  sipStatus: state,
10370
10429
  displayName: identity ? identity.displayName || number : number,
10371
10430
  startTime: fromSession ? fromSession.startTime : new Date(),
10431
+ creationTime: fromSession ? fromSession.creationTime : null,
10432
+ endTime: fromSession ? fromSession.endTime : null,
10372
10433
  answered: state === SessionState.Established,
10373
10434
  paused: this.client.isCallHeld(sipSession),
10374
10435
  isCaller: 'incoming' in extra ? !extra.incoming : false,
@@ -10379,6 +10440,7 @@ class WebRTCPhone extends Emitter {
10379
10440
  videoMuted: fromSession ? fromSession.isVideoMuted() : false,
10380
10441
  recording: fromSession ? fromSession.isRecording() : false,
10381
10442
  recordingPaused: false, // @TODO
10443
+ sipSession,
10382
10444
  ...extra,
10383
10445
  });
10384
10446
 
@@ -10407,6 +10469,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10407
10469
  ON_CAMERA_RESUMED: ON_CAMERA_RESUMED,
10408
10470
  ON_CALL_CANCELED: ON_CALL_CANCELED,
10409
10471
  ON_CALL_FAILED: ON_CALL_FAILED,
10472
+ ON_CALL_REJECTED: ON_CALL_REJECTED,
10410
10473
  ON_CALL_ENDED: ON_CALL_ENDED,
10411
10474
  ON_CALL_ENDING: ON_CALL_ENDING,
10412
10475
  ON_MESSAGE: ON_MESSAGE,
@@ -10436,6 +10499,14 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10436
10499
  'default': WebRTCPhone
10437
10500
  });
10438
10501
 
10502
+ /* */
10503
+ class SFUNotAvailableError extends Error {
10504
+ constructor(message = 'Sorry your user is not configured to support video conference') {
10505
+ super(message);
10506
+ this.name = 'SFUNotAvailableError';
10507
+ }
10508
+ }
10509
+
10439
10510
  //
10440
10511
 
10441
10512
  const logger$6 = IssueReporter$1.loggerFor('simple-phone');
@@ -10820,7 +10891,7 @@ class Phone extends Emitter {
10820
10891
 
10821
10892
  checkSfu() {
10822
10893
  if (!this.hasSfu()) {
10823
- throw new Error('Sorry your user is not configured to support video conference');
10894
+ throw new SFUNotAvailableError();
10824
10895
  }
10825
10896
  }
10826
10897
 
@@ -12602,6 +12673,7 @@ const Wazo = {
12602
12673
  InvalidSubscription,
12603
12674
  InvalidAuthorization,
12604
12675
  CanceledCallError,
12676
+ SFUNotAvailableError,
12605
12677
  };
12606
12678
 
12607
12679
  if (window) {
@@ -132,7 +132,7 @@ const logger$c = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
132
132
 
133
133
  // Use a function here to be able to mock it in tests
134
134
  const realFetch = () => {
135
- if (typeof document !== 'undefined') {
135
+ if (typeof document !== 'undefined' && window.fetch) {
136
136
  // Browser
137
137
  return window.fetch;
138
138
  }
@@ -3274,13 +3274,16 @@ var updateFrom = (instance , from ) => {
3274
3274
 
3275
3275
 
3276
3276
 
3277
+
3277
3278
 
3278
3279
 
3279
3280
 
3280
3281
 
3281
3282
 
3283
+
3282
3284
 
3283
3285
 
3286
+
3284
3287
 
3285
3288
 
3286
3289
 
@@ -3297,6 +3300,7 @@ var updateFrom = (instance , from ) => {
3297
3300
 
3298
3301
 
3299
3302
 
3303
+
3300
3304
 
3301
3305
 
3302
3306
  class CallSession {
@@ -3316,10 +3320,14 @@ class CallSession {
3316
3320
 
3317
3321
 
3318
3322
 
3319
-
3323
+
3324
+
3325
+ // = creationTime
3320
3326
 
3321
3327
 
3322
3328
 
3329
+
3330
+
3323
3331
 
3324
3332
 
3325
3333
 
@@ -3355,6 +3363,8 @@ class CallSession {
3355
3363
 
3356
3364
 
3357
3365
 
3366
+
3367
+
3358
3368
 
3359
3369
  constructor({
3360
3370
  answered,
@@ -3368,6 +3378,8 @@ class CallSession {
3368
3378
  paused,
3369
3379
  ringing,
3370
3380
  startTime,
3381
+ creationTime,
3382
+ endTime,
3371
3383
  cameraEnabled,
3372
3384
  dialedExtension,
3373
3385
  sipCallId,
@@ -3380,12 +3392,16 @@ class CallSession {
3380
3392
  recording,
3381
3393
  recordingPaused,
3382
3394
  videoRemotelyDowngraded,
3395
+ sipSession,
3396
+ answerTime,
3383
3397
  } ) {
3384
3398
  this.callId = callId;
3385
3399
  this.sipCallId = sipCallId;
3386
3400
  this.displayName = displayName;
3387
3401
  this.number = number;
3402
+ this.creationTime = creationTime;
3388
3403
  this.startTime = startTime;
3404
+ this.endTime = endTime;
3389
3405
  this.isCaller = isCaller;
3390
3406
  this.answered = answered;
3391
3407
  this.answeredBySystem = answeredBySystem;
@@ -3404,6 +3420,8 @@ class CallSession {
3404
3420
  this.recording = recording || false;
3405
3421
  this.recordingPaused = recordingPaused || false;
3406
3422
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
3423
+ this.sipSession = sipSession;
3424
+ this.answerTime = answerTime || this.answerTime;
3407
3425
 
3408
3426
  // Useful to compare instead of instanceof with minified code
3409
3427
  this.type = 'CallSession';
@@ -3434,7 +3452,7 @@ class CallSession {
3434
3452
  }
3435
3453
 
3436
3454
  answer() {
3437
- this.answered = true;
3455
+ this.answerTime = new Date();
3438
3456
  }
3439
3457
 
3440
3458
  systemAnswer() {
@@ -3590,6 +3608,15 @@ class CallSession {
3590
3608
  return newFrom(callSession, CallSession);
3591
3609
  }
3592
3610
 
3611
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
3612
+ set answered(value ) {
3613
+ this.answerTime = value ? new Date() : null;
3614
+ }
3615
+
3616
+ get answered() {
3617
+ return !!this.answerTime;
3618
+ }
3619
+
3593
3620
  static parseCall(call ) {
3594
3621
  return new CallSession({
3595
3622
  callId: call.id,
@@ -6062,11 +6089,16 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
6062
6089
 
6063
6090
  // $FlowFixMe
6064
6091
  setRemoteSessionDescription(sessionDescription ) {
6065
- const result = super.setRemoteSessionDescription(sessionDescription);
6092
+ try {
6093
+ const result = super.setRemoteSessionDescription(sessionDescription);
6066
6094
 
6067
- this.eventEmitter.emit('setDescription', sessionDescription);
6095
+ this.eventEmitter.emit('setDescription', sessionDescription);
6068
6096
 
6069
- return result;
6097
+ return result;
6098
+ } catch (error) {
6099
+ this.logger.error('SessionDescriptionHandler.setRemoteSessionDescription error', error);
6100
+ throw error;
6101
+ }
6070
6102
  }
6071
6103
 
6072
6104
  // Overridden to avoid to fix ice-candidates missing in the SDP in react-native and chrome canary.
@@ -6605,6 +6637,7 @@ const MAX_REGISTER_TRIES = 10;
6605
6637
 
6606
6638
 
6607
6639
 
6640
+
6608
6641
 
6609
6642
 
6610
6643
 
@@ -8221,6 +8254,13 @@ class WebRTCClient extends Emitter {
8221
8254
  }
8222
8255
 
8223
8256
  _createWebRTCConfiguration(configOverrides = {}) {
8257
+ let { host } = this.config;
8258
+ let port = this.config.port || 443;
8259
+
8260
+ if (this.config.websocketSip) {
8261
+ [host, port = 443] = this.config.websocketSip.split(':');
8262
+ }
8263
+
8224
8264
  const config = {
8225
8265
  authorizationUsername: this.config.authorizationUser,
8226
8266
  authorizationPassword: this.config.password,
@@ -8256,7 +8296,7 @@ class WebRTCClient extends Emitter {
8256
8296
  },
8257
8297
  transportOptions: {
8258
8298
  traceSip: configOverrides.traceSip || false,
8259
- wsServers: `wss://${this.config.host}:${this.config.port || 443}/api/asterisk/ws`,
8299
+ wsServers: `wss://${host}:${port}/api/asterisk/ws`,
8260
8300
  },
8261
8301
  sessionDescriptionHandlerFactoryOptions: {
8262
8302
  modifiers: [replaceLocalIpModifier],
@@ -8718,6 +8758,7 @@ const ON_CAMERA_DISABLED = 'onCameraDisabled';
8718
8758
  const ON_CAMERA_RESUMED = 'onCameraResumed';
8719
8759
  const ON_CALL_CANCELED = 'onCallCanceled';
8720
8760
  const ON_CALL_FAILED = 'onCallFailed';
8761
+ const ON_CALL_REJECTED = 'onCallRejected';
8721
8762
  const ON_CALL_ENDED = 'onCallEnded';
8722
8763
  const ON_CALL_ENDING = 'onCallEnding';
8723
8764
  const ON_MESSAGE = 'onMessage';
@@ -8762,6 +8803,7 @@ const events = [
8762
8803
  ON_CAMERA_DISABLED,
8763
8804
  ON_CALL_FAILED,
8764
8805
  ON_CALL_ENDED,
8806
+ ON_CALL_REJECTED,
8765
8807
  ON_MESSAGE,
8766
8808
  ON_REINVITE,
8767
8809
  ON_TRACK,
@@ -9118,6 +9160,7 @@ class WebRTCPhone extends Emitter {
9118
9160
 
9119
9161
  // Should be called before `_onCallTerminated` or the callCount will not decrement...
9120
9162
  const callSession = this._createCallSession(sipSession);
9163
+ callSession.endTime = new Date();
9121
9164
  const wasCurrentSession = this._onCallTerminated(sipSession);
9122
9165
 
9123
9166
  return this.eventEmitter.emit(ON_CALL_ENDED, callSession, wasCurrentSession);
@@ -9313,6 +9356,7 @@ class WebRTCPhone extends Emitter {
9313
9356
  this.removeIncomingSessions(sipSessionId);
9314
9357
  }
9315
9358
 
9359
+ callSession.answerTime = new Date();
9316
9360
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
9317
9361
 
9318
9362
  return callSession;
@@ -9370,6 +9414,7 @@ class WebRTCPhone extends Emitter {
9370
9414
  _onCallTerminated(sipSession ) {
9371
9415
  logger$7.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
9372
9416
 
9417
+ const sipSessionId = this.getSipSessionId(sipSession);
9373
9418
  const callSession = this._createCallSession(sipSession);
9374
9419
  const isCurrentSession = this.isCurrentCallSipSession(callSession);
9375
9420
  const isCurrentIncomingCall = callSession.is(this.getIncomingCallSession());
@@ -9387,7 +9432,6 @@ class WebRTCPhone extends Emitter {
9387
9432
  }, 5);
9388
9433
  }
9389
9434
 
9390
- const sipSessionId = this.getSipSessionId(sipSession);
9391
9435
  if (sipSessionId) {
9392
9436
  this.removeIncomingSessions(sipSessionId);
9393
9437
  }
@@ -9528,6 +9572,7 @@ class WebRTCPhone extends Emitter {
9528
9572
  }
9529
9573
 
9530
9574
  this.shouldSendReinvite = false;
9575
+ callSession.answerTime = new Date();
9531
9576
  this.acceptedSessions[callSession.getId()] = true;
9532
9577
 
9533
9578
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -9837,6 +9882,7 @@ class WebRTCPhone extends Emitter {
9837
9882
  return Promise.resolve(null);
9838
9883
  }
9839
9884
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
9885
+ callSession.creationTime = new Date();
9840
9886
 
9841
9887
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
9842
9888
 
@@ -10032,8 +10078,12 @@ class WebRTCPhone extends Emitter {
10032
10078
  }
10033
10079
 
10034
10080
  const sessionId = this.incomingSessions[0];
10081
+ const sipSession = this.client.getSipSession(sessionId);
10082
+ if (!sipSession) {
10083
+ return null;
10084
+ }
10035
10085
 
10036
- return this._createCallSession(this.client.getSipSession(sessionId));
10086
+ return this._createCallSession(sipSession);
10037
10087
  }
10038
10088
 
10039
10089
  sendMessage(sipSession = null, body , contentType = 'text/plain') {
@@ -10111,6 +10161,7 @@ class WebRTCPhone extends Emitter {
10111
10161
  callSession);
10112
10162
  }
10113
10163
 
10164
+ callSession.creationTime = new Date();
10114
10165
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
10115
10166
  });
10116
10167
 
@@ -10150,6 +10201,13 @@ class WebRTCPhone extends Emitter {
10150
10201
  this.eventEmitter.emit(ON_CALL_ERROR, e);
10151
10202
  });
10152
10203
 
10204
+ this.client.on(this.client.REJECTED, session => {
10205
+ logger$7.info('WebRTC call rejected', session.id);
10206
+ const callSession = this._createCallSession(session);
10207
+ callSession.endTime = new Date();
10208
+ this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
10209
+ });
10210
+
10153
10211
  this.client.on(this.client.UNREGISTERED, () => {
10154
10212
  logger$7.info('WebRTC unregistered');
10155
10213
  this.eventEmitter.emit(ON_UNREGISTERED);
@@ -10362,6 +10420,7 @@ class WebRTCPhone extends Emitter {
10362
10420
  const number = identity ? identity.uri._normal.user : null;
10363
10421
  const { state } = sipSession || {};
10364
10422
  const sessionId = this.getSipSessionId(sipSession);
10423
+ fromSession = fromSession || this.callSessions[sessionId];
10365
10424
 
10366
10425
  const callSession = new CallSession({
10367
10426
  callId: fromSession && fromSession.callId,
@@ -10369,6 +10428,8 @@ class WebRTCPhone extends Emitter {
10369
10428
  sipStatus: state,
10370
10429
  displayName: identity ? identity.displayName || number : number,
10371
10430
  startTime: fromSession ? fromSession.startTime : new Date(),
10431
+ creationTime: fromSession ? fromSession.creationTime : null,
10432
+ endTime: fromSession ? fromSession.endTime : null,
10372
10433
  answered: state === SessionState.Established,
10373
10434
  paused: this.client.isCallHeld(sipSession),
10374
10435
  isCaller: 'incoming' in extra ? !extra.incoming : false,
@@ -10379,6 +10440,7 @@ class WebRTCPhone extends Emitter {
10379
10440
  videoMuted: fromSession ? fromSession.isVideoMuted() : false,
10380
10441
  recording: fromSession ? fromSession.isRecording() : false,
10381
10442
  recordingPaused: false, // @TODO
10443
+ sipSession,
10382
10444
  ...extra,
10383
10445
  });
10384
10446
 
@@ -10407,6 +10469,7 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10407
10469
  ON_CAMERA_RESUMED: ON_CAMERA_RESUMED,
10408
10470
  ON_CALL_CANCELED: ON_CALL_CANCELED,
10409
10471
  ON_CALL_FAILED: ON_CALL_FAILED,
10472
+ ON_CALL_REJECTED: ON_CALL_REJECTED,
10410
10473
  ON_CALL_ENDED: ON_CALL_ENDED,
10411
10474
  ON_CALL_ENDING: ON_CALL_ENDING,
10412
10475
  ON_MESSAGE: ON_MESSAGE,
@@ -10436,6 +10499,14 @@ var PHONE_EVENTS = /*#__PURE__*/Object.freeze({
10436
10499
  'default': WebRTCPhone
10437
10500
  });
10438
10501
 
10502
+ /* */
10503
+ class SFUNotAvailableError extends Error {
10504
+ constructor(message = 'Sorry your user is not configured to support video conference') {
10505
+ super(message);
10506
+ this.name = 'SFUNotAvailableError';
10507
+ }
10508
+ }
10509
+
10439
10510
  //
10440
10511
 
10441
10512
  const logger$6 = IssueReporter$1.loggerFor('simple-phone');
@@ -10820,7 +10891,7 @@ class Phone extends Emitter {
10820
10891
 
10821
10892
  checkSfu() {
10822
10893
  if (!this.hasSfu()) {
10823
- throw new Error('Sorry your user is not configured to support video conference');
10894
+ throw new SFUNotAvailableError();
10824
10895
  }
10825
10896
  }
10826
10897
 
@@ -12607,6 +12678,7 @@ const Wazo = {
12607
12678
  InvalidSubscription,
12608
12679
  InvalidAuthorization,
12609
12680
  CanceledCallError,
12681
+ SFUNotAvailableError,
12610
12682
  };
12611
12683
 
12612
12684
  if (window) {