@wazo/sdk 1.0.0-alpha.1 → 1.0.0-alpha.11
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.
- package/README.md +16 -7
- package/dist/wazo-sdk.js +6 -6
- package/esm/__tests__/__voice__/call.test.js +57 -2
- package/esm/api/auth.js +3 -0
- package/esm/checker/checks/webrtc.js +2 -2
- package/esm/domain/CallLog.js +2 -3
- package/esm/domain/Phone/CTIPhone.js +2 -2
- package/esm/domain/Phone/WebRTCPhone.js +64 -63
- package/esm/index.js +3 -1
- package/esm/service/CallApi.js +4 -4
- package/esm/simple/Auth.js +13 -3
- package/esm/simple/Phone.js +6 -5
- package/esm/simple/index.js +2 -1
- package/esm/simple/room/Room.js +2 -2
- package/esm/simple/room/SipRoom.js +2 -2
- package/esm/state-machine/call-state-machine.js +2 -2
- package/esm/state-machine/softphone-state-machine.js +1 -2
- package/esm/state-machine/utils.js +10 -4
- package/esm/types/api/auth.d.ts +3 -0
- package/esm/types/api/auth.d.ts.map +1 -1
- package/esm/types/checker/checks/index.d.ts +1 -1
- package/esm/types/checker/checks/webrtc-transport.d.ts +2 -2
- package/esm/types/checker/checks/webrtc-transport.d.ts.map +1 -1
- package/esm/types/domain/CallLog.d.ts.map +1 -1
- package/esm/types/domain/CallSession.d.ts +3 -3
- package/esm/types/domain/CallSession.d.ts.map +1 -1
- package/esm/types/domain/Phone/CTIPhone.d.ts.map +1 -1
- package/esm/types/domain/Phone/WebRTCPhone.d.ts +22 -22
- package/esm/types/domain/Phone/WebRTCPhone.d.ts.map +1 -1
- package/esm/types/domain/types.d.ts +0 -4
- package/esm/types/domain/types.d.ts.map +1 -1
- package/esm/types/index.d.ts +3 -1
- package/esm/types/index.d.ts.map +1 -1
- package/esm/types/lib/WazoSessionDescriptionHandler.d.ts +3 -3
- package/esm/types/lib/WazoSessionDescriptionHandler.d.ts.map +1 -1
- package/esm/types/service/CallApi.d.ts +5 -5
- package/esm/types/service/CallApi.d.ts.map +1 -1
- package/esm/types/simple/Auth.d.ts +6 -1
- package/esm/types/simple/Auth.d.ts.map +1 -1
- package/esm/types/simple/Phone.d.ts +8 -8
- package/esm/types/simple/Phone.d.ts.map +1 -1
- package/esm/types/simple/index.d.ts +3 -1
- package/esm/types/simple/index.d.ts.map +1 -1
- package/esm/types/state-machine/softphone-state-machine.d.ts +1 -2
- package/esm/types/state-machine/softphone-state-machine.d.ts.map +1 -1
- package/esm/types/state-machine/utils.d.ts +2 -2
- package/esm/types/state-machine/utils.d.ts.map +1 -1
- package/esm/types/utils/sdp.d.ts +3 -2
- package/esm/types/utils/sdp.d.ts.map +1 -1
- package/esm/types/utils/webrtc.d.ts +1 -0
- package/esm/types/utils/webrtc.d.ts.map +1 -1
- package/esm/types/voice/call.d.ts +30 -12
- package/esm/types/voice/call.d.ts.map +1 -1
- package/esm/types/voice/softphone.d.ts +25 -13
- package/esm/types/voice/softphone.d.ts.map +1 -1
- package/esm/types/web-rtc-client.d.ts +39 -38
- package/esm/types/web-rtc-client.d.ts.map +1 -1
- package/esm/utils/sdp.js +22 -9
- package/esm/utils/webrtc.js +23 -3
- package/esm/voice/call.js +131 -38
- package/esm/voice/softphone.js +145 -35
- package/esm/web-rtc-client.js +61 -58
- package/lib/__tests__/__voice__/call.test.js +56 -1
- package/lib/api/auth.js +3 -0
- package/lib/checker/checks/webrtc.js +1 -1
- package/lib/domain/CallLog.js +2 -3
- package/lib/domain/Phone/CTIPhone.js +2 -2
- package/lib/domain/Phone/WebRTCPhone.js +63 -62
- package/lib/index.js +7 -3
- package/lib/service/CallApi.js +2 -2
- package/lib/simple/Auth.js +15 -3
- package/lib/simple/Phone.js +3 -2
- package/lib/simple/index.js +2 -1
- package/lib/simple/room/Room.js +1 -1
- package/lib/simple/room/SipRoom.js +1 -1
- package/lib/state-machine/call-state-machine.js +2 -2
- package/lib/state-machine/softphone-state-machine.js +1 -2
- package/lib/state-machine/utils.js +10 -4
- package/lib/types/api/auth.d.ts +3 -0
- package/lib/types/api/auth.d.ts.map +1 -1
- package/lib/types/checker/checks/index.d.ts +1 -1
- package/lib/types/checker/checks/webrtc-transport.d.ts +2 -2
- package/lib/types/checker/checks/webrtc-transport.d.ts.map +1 -1
- package/lib/types/domain/CallLog.d.ts.map +1 -1
- package/lib/types/domain/CallSession.d.ts +3 -3
- package/lib/types/domain/CallSession.d.ts.map +1 -1
- package/lib/types/domain/Phone/CTIPhone.d.ts.map +1 -1
- package/lib/types/domain/Phone/WebRTCPhone.d.ts +22 -22
- package/lib/types/domain/Phone/WebRTCPhone.d.ts.map +1 -1
- package/lib/types/domain/types.d.ts +0 -4
- package/lib/types/domain/types.d.ts.map +1 -1
- package/lib/types/index.d.ts +3 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/lib/WazoSessionDescriptionHandler.d.ts +3 -3
- package/lib/types/lib/WazoSessionDescriptionHandler.d.ts.map +1 -1
- package/lib/types/service/CallApi.d.ts +5 -5
- package/lib/types/service/CallApi.d.ts.map +1 -1
- package/lib/types/simple/Auth.d.ts +6 -1
- package/lib/types/simple/Auth.d.ts.map +1 -1
- package/lib/types/simple/Phone.d.ts +8 -8
- package/lib/types/simple/Phone.d.ts.map +1 -1
- package/lib/types/simple/index.d.ts +3 -1
- package/lib/types/simple/index.d.ts.map +1 -1
- package/lib/types/state-machine/softphone-state-machine.d.ts +1 -2
- package/lib/types/state-machine/softphone-state-machine.d.ts.map +1 -1
- package/lib/types/state-machine/utils.d.ts +2 -2
- package/lib/types/state-machine/utils.d.ts.map +1 -1
- package/lib/types/utils/sdp.d.ts +3 -2
- package/lib/types/utils/sdp.d.ts.map +1 -1
- package/lib/types/utils/webrtc.d.ts +1 -0
- package/lib/types/utils/webrtc.d.ts.map +1 -1
- package/lib/types/voice/call.d.ts +30 -12
- package/lib/types/voice/call.d.ts.map +1 -1
- package/lib/types/voice/softphone.d.ts +25 -13
- package/lib/types/voice/softphone.d.ts.map +1 -1
- package/lib/types/web-rtc-client.d.ts +39 -38
- package/lib/types/web-rtc-client.d.ts.map +1 -1
- package/lib/utils/sdp.js +25 -10
- package/lib/utils/webrtc.js +24 -3
- package/lib/voice/call.js +132 -36
- package/lib/voice/softphone.js +150 -35
- package/lib/web-rtc-client.js +59 -57
- package/package.json +1 -1
- package/src/__tests__/__voice__/call.test.ts +63 -2
- package/src/api/auth.ts +5 -0
- package/src/checker/checks/webrtc-transport.ts +2 -2
- package/src/checker/checks/webrtc.ts +2 -2
- package/src/domain/CallLog.ts +2 -3
- package/src/domain/CallSession.ts +3 -3
- package/src/domain/Phone/CTIPhone.ts +3 -2
- package/src/domain/Phone/WebRTCPhone.ts +95 -93
- package/src/domain/types.ts +0 -5
- package/src/index.ts +4 -1
- package/src/lib/WazoSessionDescriptionHandler.ts +3 -3
- package/src/service/CallApi.ts +7 -7
- package/src/simple/Auth.ts +15 -3
- package/src/simple/Phone.ts +12 -11
- package/src/simple/index.ts +2 -1
- package/src/simple/room/Room.ts +3 -3
- package/src/simple/room/SipRoom.ts +3 -3
- package/src/state-machine/call-state-machine.ts +2 -2
- package/src/state-machine/softphone-state-machine.ts +1 -2
- package/src/state-machine/utils.ts +14 -6
- package/src/utils/sdp.ts +26 -11
- package/src/utils/webrtc.ts +26 -4
- package/src/voice/call.ts +170 -50
- package/src/voice/softphone.ts +180 -41
- package/src/web-rtc-client.ts +106 -99
package/lib/web-rtc-client.js
CHANGED
|
@@ -51,6 +51,7 @@ const logger = IssueReporter_1.default ? IssueReporter_1.default.loggerFor('webr
|
|
|
51
51
|
const statsLogger = IssueReporter_1.default ? IssueReporter_1.default.loggerFor('webrtc-stats') : console;
|
|
52
52
|
// events
|
|
53
53
|
const REGISTERED = 'registered';
|
|
54
|
+
const REGISTERING = 'registering';
|
|
54
55
|
const UNREGISTERED = 'unregistered';
|
|
55
56
|
const REGISTRATION_FAILED = 'registrationFailed';
|
|
56
57
|
const INVITE = 'invite';
|
|
@@ -68,7 +69,7 @@ const ON_ERROR = 'onError';
|
|
|
68
69
|
const ON_SCREEN_SHARING_REINVITE = 'onScreenSharingReinvite';
|
|
69
70
|
const ON_NETWORK_STATS = 'onNetworkStats';
|
|
70
71
|
const ON_DISCONNECTED = 'onDisconnected';
|
|
71
|
-
exports.events = [REGISTERED, UNREGISTERED, REGISTRATION_FAILED, INVITE];
|
|
72
|
+
exports.events = [REGISTERED, REGISTERING, UNREGISTERED, REGISTRATION_FAILED, INVITE];
|
|
72
73
|
exports.transportEvents = [CONNECTED, DISCONNECTED, TRANSPORT_ERROR, MESSAGE];
|
|
73
74
|
class CanceledCallError extends Error {
|
|
74
75
|
}
|
|
@@ -85,7 +86,9 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
85
86
|
this.skipRegister = config.skipRegister;
|
|
86
87
|
this._buildConfig(config, session).then((newConfig) => {
|
|
87
88
|
this.config = newConfig;
|
|
88
|
-
this.userAgent
|
|
89
|
+
if (!this.userAgent) {
|
|
90
|
+
this.userAgent = this.createUserAgent(uaConfigOverrides);
|
|
91
|
+
}
|
|
89
92
|
});
|
|
90
93
|
this.audioOutputDeviceId = config.audioDeviceOutput;
|
|
91
94
|
this.audioOutputVolume = config.audioOutputVolume || 1;
|
|
@@ -110,6 +113,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
110
113
|
this.heartbeat.setOnHeartbeatTimeout(this._onHeartbeatTimeout.bind(this));
|
|
111
114
|
// sugar
|
|
112
115
|
this.REGISTERED = REGISTERED;
|
|
116
|
+
this.REGISTERING = REGISTERING;
|
|
113
117
|
this.UNREGISTERED = UNREGISTERED;
|
|
114
118
|
this.REGISTRATION_FAILED = REGISTRATION_FAILED;
|
|
115
119
|
this.INVITE = INVITE;
|
|
@@ -151,7 +155,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
151
155
|
logger.info('sdk webrtc on invite', {
|
|
152
156
|
method: 'delegate.onInvite',
|
|
153
157
|
clientId: this.clientId,
|
|
154
|
-
id: invitation
|
|
158
|
+
id: (0, sdp_1.getSipCallId)(invitation),
|
|
155
159
|
remoteURI: invitation.remoteURI,
|
|
156
160
|
});
|
|
157
161
|
this._setupSession(invitation);
|
|
@@ -218,7 +222,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
218
222
|
// @ts-ignore: private
|
|
219
223
|
this.registerer.waitingToggle(false);
|
|
220
224
|
}
|
|
221
|
-
this.eventEmitter.emit(UNREGISTERED);
|
|
225
|
+
this.eventEmitter.emit(UNREGISTERED, error);
|
|
222
226
|
}
|
|
223
227
|
});
|
|
224
228
|
}
|
|
@@ -242,6 +246,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
242
246
|
return Promise.resolve();
|
|
243
247
|
}
|
|
244
248
|
logger.info('sdk webrtc registering...', logInfo);
|
|
249
|
+
this.eventEmitter.emit(REGISTERING);
|
|
245
250
|
if (!this.userAgent) {
|
|
246
251
|
logger.info('sdk webrtc recreating User Agent');
|
|
247
252
|
this.userAgent = this.createUserAgent(this.uaConfigOverrides);
|
|
@@ -425,7 +430,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
425
430
|
this._setupSession(session);
|
|
426
431
|
}
|
|
427
432
|
if (conference) {
|
|
428
|
-
this.conferences[(0, sdp_1.
|
|
433
|
+
this.conferences[(0, sdp_1.getSipCallId)(session)] = true;
|
|
429
434
|
}
|
|
430
435
|
const inviteOptions = {
|
|
431
436
|
requestDelegate: {
|
|
@@ -441,7 +446,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
441
446
|
},
|
|
442
447
|
onReject: (response) => {
|
|
443
448
|
logger.info('on call rejected', {
|
|
444
|
-
id:
|
|
449
|
+
id: (0, sdp_1.getSipCallId)(session),
|
|
445
450
|
// @ts-ignore: fromTag does not exist
|
|
446
451
|
fromTag: session === null || session === void 0 ? void 0 : session.fromTag,
|
|
447
452
|
});
|
|
@@ -471,7 +476,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
471
476
|
answer(session, enableVideo) {
|
|
472
477
|
logger.info('sdk webrtc answer call', {
|
|
473
478
|
clientId: this.clientId,
|
|
474
|
-
id: session
|
|
479
|
+
id: (0, sdp_1.getSipCallId)(session),
|
|
475
480
|
enableVideo,
|
|
476
481
|
});
|
|
477
482
|
if (!session || !session.accept) {
|
|
@@ -487,7 +492,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
487
492
|
if (session.isCanceled) {
|
|
488
493
|
const message = 'accepted a canceled session (or was canceled during the accept phase).';
|
|
489
494
|
logger.error(message, {
|
|
490
|
-
id: session
|
|
495
|
+
id: (0, sdp_1.getSipCallId)(session),
|
|
491
496
|
});
|
|
492
497
|
this.onCallEnded(session);
|
|
493
498
|
throw new CanceledCallError(message);
|
|
@@ -495,7 +500,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
495
500
|
logger.info('sdk webrtc answer, accepted.');
|
|
496
501
|
this._onAccepted(session);
|
|
497
502
|
}).catch(e => {
|
|
498
|
-
logger.error(`answer call error for ${
|
|
503
|
+
logger.error(`answer call error for ${(0, sdp_1.getSipCallId)(session)}`, e);
|
|
499
504
|
throw e;
|
|
500
505
|
});
|
|
501
506
|
}
|
|
@@ -506,7 +511,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
506
511
|
try {
|
|
507
512
|
this._stopSendingStats(session);
|
|
508
513
|
this._cleanupMedia(session);
|
|
509
|
-
delete this.sipSessions[(0, sdp_1.
|
|
514
|
+
delete this.sipSessions[(0, sdp_1.getSipCallId)(session)];
|
|
510
515
|
// Check if Invitation or Inviter (Invitation = incoming call)
|
|
511
516
|
const isInviter = session instanceof api_1.Inviter;
|
|
512
517
|
// @see github.com/onsip/SIP.js/blob/f11dfd584bc9788ccfc94e03034020672b738975/src/platform/web/simple-user/simple-user.ts#L1004
|
|
@@ -529,7 +534,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
529
534
|
}
|
|
530
535
|
// Fetch and emit an event at `interval` with session network stats
|
|
531
536
|
startNetworkMonitoring(session, interval = 1000) {
|
|
532
|
-
const sessionId = (0, sdp_1.
|
|
537
|
+
const sessionId = (0, sdp_1.getSipCallId)(session);
|
|
533
538
|
logger.info('starting network inspection', {
|
|
534
539
|
id: sessionId,
|
|
535
540
|
clientId: this.clientId,
|
|
@@ -538,7 +543,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
538
543
|
this.networkMonitoringInterval[sessionId] = setInterval(() => this._fetchNetworkStats(sessionId), interval);
|
|
539
544
|
}
|
|
540
545
|
stopNetworkMonitoring(session) {
|
|
541
|
-
const sessionId = (0, sdp_1.
|
|
546
|
+
const sessionId = (0, sdp_1.getSipCallId)(session);
|
|
542
547
|
const exists = (sessionId in this.networkMonitoringInterval);
|
|
543
548
|
logger.info('stopping network inspection', {
|
|
544
549
|
clientId: this.clientId,
|
|
@@ -555,7 +560,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
555
560
|
return __awaiter(this, void 0, void 0, function* () {
|
|
556
561
|
logger.info('sdk webrtc reject call', {
|
|
557
562
|
clientId: this.clientId,
|
|
558
|
-
id: session
|
|
563
|
+
id: (0, sdp_1.getSipCallId)(session),
|
|
559
564
|
});
|
|
560
565
|
try {
|
|
561
566
|
if (session instanceof api_1.Invitation) {
|
|
@@ -612,13 +617,13 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
612
617
|
}
|
|
613
618
|
mute(session) {
|
|
614
619
|
logger.info('sdk webrtc mute', {
|
|
615
|
-
id: session
|
|
620
|
+
id: (0, sdp_1.getSipCallId)(session),
|
|
616
621
|
});
|
|
617
622
|
(0, webrtc_1.toggleAudio)(session, true);
|
|
618
623
|
}
|
|
619
624
|
unmute(session) {
|
|
620
625
|
logger.info('sdk webrtc unmute', {
|
|
621
|
-
id: session
|
|
626
|
+
id: (0, sdp_1.getSipCallId)(session),
|
|
622
627
|
});
|
|
623
628
|
(0, webrtc_1.toggleAudio)(session, false);
|
|
624
629
|
}
|
|
@@ -655,18 +660,18 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
655
660
|
}
|
|
656
661
|
toggleCameraOn(session) {
|
|
657
662
|
logger.info('sdk webrtc toggle camera on', {
|
|
658
|
-
id: session
|
|
663
|
+
id: (0, sdp_1.getSipCallId)(session),
|
|
659
664
|
});
|
|
660
665
|
(0, webrtc_1.toggleVideo)(session, false);
|
|
661
666
|
}
|
|
662
667
|
toggleCameraOff(session) {
|
|
663
668
|
logger.info('sdk webrtc toggle camera off', {
|
|
664
|
-
id: session
|
|
669
|
+
id: (0, sdp_1.getSipCallId)(session),
|
|
665
670
|
});
|
|
666
671
|
(0, webrtc_1.toggleVideo)(session, true);
|
|
667
672
|
}
|
|
668
673
|
hold(session, isConference = false, hadVideo = false) {
|
|
669
|
-
const sessionId = (0, sdp_1.
|
|
674
|
+
const sessionId = (0, sdp_1.getSipCallId)(session);
|
|
670
675
|
const hasVideo = hadVideo || this.hasLocalVideo(sessionId);
|
|
671
676
|
logger.info('sdk webrtc hold', {
|
|
672
677
|
sessionId,
|
|
@@ -714,7 +719,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
714
719
|
});
|
|
715
720
|
}
|
|
716
721
|
unhold(session, isConference = false) {
|
|
717
|
-
const sessionId = (0, sdp_1.
|
|
722
|
+
const sessionId = (0, sdp_1.getSipCallId)(session);
|
|
718
723
|
const hasVideo = sessionId in this.heldSessions && this.heldSessions[sessionId].hasVideo;
|
|
719
724
|
logger.info('sdk webrtc unhold', {
|
|
720
725
|
sessionId,
|
|
@@ -729,7 +734,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
729
734
|
return Promise.resolve();
|
|
730
735
|
}
|
|
731
736
|
this.unmute(session);
|
|
732
|
-
delete this.heldSessions[(0, sdp_1.
|
|
737
|
+
delete this.heldSessions[(0, sdp_1.getSipCallId)(session)];
|
|
733
738
|
session.sessionDescriptionHandlerOptionsReInvite = {
|
|
734
739
|
hold: false,
|
|
735
740
|
conference: isConference,
|
|
@@ -754,7 +759,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
754
759
|
return this.heldSessions[sessionId];
|
|
755
760
|
}
|
|
756
761
|
isCallHeld(session) {
|
|
757
|
-
return (0, sdp_1.
|
|
762
|
+
return (0, sdp_1.getSipCallId)(session) in this.heldSessions;
|
|
758
763
|
}
|
|
759
764
|
isVideoRemotelyHeld(sessionId) {
|
|
760
765
|
return (0, webrtc_1.isVideoRemotelyHeld)(this.heldSessions[sessionId]);
|
|
@@ -764,7 +769,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
764
769
|
return false;
|
|
765
770
|
}
|
|
766
771
|
logger.info('Sending DTMF', {
|
|
767
|
-
id: (0, sdp_1.
|
|
772
|
+
id: (0, sdp_1.getSipCallId)(session),
|
|
768
773
|
tone,
|
|
769
774
|
});
|
|
770
775
|
return session.sessionDescriptionHandler.sendDtmf(tone);
|
|
@@ -781,7 +786,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
781
786
|
transfer(session, target) {
|
|
782
787
|
this.hold(session);
|
|
783
788
|
logger.info('Transfering a session', {
|
|
784
|
-
id: (0, sdp_1.
|
|
789
|
+
id: (0, sdp_1.getSipCallId)(session),
|
|
785
790
|
target,
|
|
786
791
|
});
|
|
787
792
|
const options = {
|
|
@@ -804,21 +809,21 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
804
809
|
atxfer(session) {
|
|
805
810
|
this.hold(session);
|
|
806
811
|
logger.info('webrtc transfer started', {
|
|
807
|
-
id: (0, sdp_1.
|
|
812
|
+
id: (0, sdp_1.getSipCallId)(session),
|
|
808
813
|
});
|
|
809
814
|
const result = {
|
|
810
815
|
newSession: null,
|
|
811
816
|
init: (target) => __awaiter(this, void 0, void 0, function* () {
|
|
812
817
|
logger.info('webrtc transfer initialized', {
|
|
813
|
-
id: (0, sdp_1.
|
|
818
|
+
id: (0, sdp_1.getSipCallId)(session),
|
|
814
819
|
target,
|
|
815
820
|
});
|
|
816
821
|
result.newSession = yield this.call(target);
|
|
817
822
|
}),
|
|
818
823
|
complete: () => {
|
|
819
824
|
logger.info('webrtc transfer completed', {
|
|
820
|
-
id: (0, sdp_1.
|
|
821
|
-
referId: (0, sdp_1.
|
|
825
|
+
id: (0, sdp_1.getSipCallId)(session),
|
|
826
|
+
referId: (0, sdp_1.getSipCallId)(result.newSession),
|
|
822
827
|
});
|
|
823
828
|
session.refer(result.newSession);
|
|
824
829
|
},
|
|
@@ -835,7 +840,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
835
840
|
return;
|
|
836
841
|
}
|
|
837
842
|
logger.info('send WebRTC message', {
|
|
838
|
-
sipId: sipSession
|
|
843
|
+
sipId: (0, sdp_1.getSipCallId)(sipSession),
|
|
839
844
|
contentType,
|
|
840
845
|
});
|
|
841
846
|
try {
|
|
@@ -990,7 +995,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
990
995
|
}
|
|
991
996
|
const sdh = session.sessionDescriptionHandler;
|
|
992
997
|
const pc = sdh.peerConnection;
|
|
993
|
-
const sessionId = (0, sdp_1.
|
|
998
|
+
const sessionId = (0, sdp_1.getSipCallId)(session);
|
|
994
999
|
const localStream = this.getLocalStream(sessionId);
|
|
995
1000
|
logger.info('changing video input device', {
|
|
996
1001
|
id,
|
|
@@ -1053,7 +1058,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
1053
1058
|
const desktop = newConstraints && newConstraints.desktop;
|
|
1054
1059
|
logger.info('Sending reinvite', {
|
|
1055
1060
|
clientId: this.clientId,
|
|
1056
|
-
id: (0, sdp_1.
|
|
1061
|
+
id: (0, sdp_1.getSipCallId)(sipSession),
|
|
1057
1062
|
newConstraints,
|
|
1058
1063
|
conference,
|
|
1059
1064
|
audioOnly,
|
|
@@ -1085,7 +1090,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
1085
1090
|
sipSession.incomingInviteRequest.message.body = response.message.body;
|
|
1086
1091
|
}
|
|
1087
1092
|
logger.info('on re-INVITE accepted', {
|
|
1088
|
-
id: (0, sdp_1.
|
|
1093
|
+
id: (0, sdp_1.getSipCallId)(sipSession),
|
|
1089
1094
|
wasMuted,
|
|
1090
1095
|
shouldDoScreenSharing,
|
|
1091
1096
|
});
|
|
@@ -1200,7 +1205,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
1200
1205
|
}
|
|
1201
1206
|
onCallEnded(session) {
|
|
1202
1207
|
this._cleanupMedia(session);
|
|
1203
|
-
delete this.sipSessions[(0, sdp_1.
|
|
1208
|
+
delete this.sipSessions[(0, sdp_1.getSipCallId)(session)];
|
|
1204
1209
|
this._stopSendingStats(session);
|
|
1205
1210
|
this.stopNetworkMonitoring(session);
|
|
1206
1211
|
}
|
|
@@ -1213,14 +1218,14 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
1213
1218
|
this.userAgent.attemptReconnection();
|
|
1214
1219
|
}
|
|
1215
1220
|
storeSipSession(session) {
|
|
1216
|
-
const id = (0, sdp_1.
|
|
1221
|
+
const id = (0, sdp_1.getSipCallId)(session);
|
|
1217
1222
|
logger.info('storing sip session', { id, clientId: this.clientId });
|
|
1218
1223
|
this.sipSessions[id] = session;
|
|
1219
1224
|
}
|
|
1220
1225
|
getSipSession(id) {
|
|
1221
|
-
return id in this.sipSessions ? this.sipSessions[id
|
|
1226
|
+
return id in this.sipSessions ? this.sipSessions[id] : null;
|
|
1222
1227
|
}
|
|
1223
|
-
|
|
1228
|
+
getSipCallIds() {
|
|
1224
1229
|
return Object.keys(this.sipSessions);
|
|
1225
1230
|
}
|
|
1226
1231
|
updateLocalStream(sipSessionId, newStream) {
|
|
@@ -1263,8 +1268,8 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
1263
1268
|
return audio;
|
|
1264
1269
|
});
|
|
1265
1270
|
}
|
|
1266
|
-
_onTransportError() {
|
|
1267
|
-
logger.
|
|
1271
|
+
_onTransportError(reason) {
|
|
1272
|
+
logger.warn('on transport error', { reason });
|
|
1268
1273
|
this.eventEmitter.emit(TRANSPORT_ERROR);
|
|
1269
1274
|
this.attemptReconnection();
|
|
1270
1275
|
}
|
|
@@ -1319,7 +1324,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
1319
1324
|
}
|
|
1320
1325
|
}
|
|
1321
1326
|
// We can invoke disconnect() with an error that can be catcher by `onDisconnect`, so we have to trigger it here.
|
|
1322
|
-
this._onTransportError();
|
|
1327
|
+
this._onTransportError('heartbeat timeout');
|
|
1323
1328
|
}
|
|
1324
1329
|
});
|
|
1325
1330
|
}
|
|
@@ -1377,7 +1382,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
1377
1382
|
}
|
|
1378
1383
|
// Invitation and Inviter extends Session
|
|
1379
1384
|
_setupSession(session) {
|
|
1380
|
-
const sipSessionId = (0, sdp_1.
|
|
1385
|
+
const sipSessionId = (0, sdp_1.getSipCallId)(session);
|
|
1381
1386
|
// When receiving an Invitation, the delegate is not defined.
|
|
1382
1387
|
if (!session.delegate) {
|
|
1383
1388
|
session.delegate = {};
|
|
@@ -1441,19 +1446,16 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
1441
1446
|
_onProgress(session_1) {
|
|
1442
1447
|
return __awaiter(this, arguments, void 0, function* (session, early = false) {
|
|
1443
1448
|
yield this._setupMedias(session);
|
|
1444
|
-
const sessionId = (0, sdp_1.
|
|
1449
|
+
const sessionId = (0, sdp_1.getSipCallId)(session);
|
|
1445
1450
|
(0, webrtc_1.updateRemoteStream)(session);
|
|
1446
|
-
logger.info('progress received', {
|
|
1447
|
-
sessionId,
|
|
1448
|
-
early,
|
|
1449
|
-
});
|
|
1451
|
+
logger.info('progress received', { sessionId, early });
|
|
1450
1452
|
this.eventEmitter.emit(early ? ON_EARLY_MEDIA : ON_PROGRESS, session);
|
|
1451
1453
|
});
|
|
1452
1454
|
}
|
|
1453
1455
|
_onAccepted(session_1, sessionDialog_1) {
|
|
1454
1456
|
return __awaiter(this, arguments, void 0, function* (session, sessionDialog, withEvent = true, initAllTracks = true) {
|
|
1455
1457
|
logger.info('on call accepted', {
|
|
1456
|
-
id: session
|
|
1458
|
+
id: (0, sdp_1.getSipCallId)(session),
|
|
1457
1459
|
clientId: this.clientId,
|
|
1458
1460
|
remoteTag: session.remoteTag,
|
|
1459
1461
|
});
|
|
@@ -1499,7 +1501,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
1499
1501
|
return;
|
|
1500
1502
|
}
|
|
1501
1503
|
// Safari hack, because you cannot call .play() from a non user action
|
|
1502
|
-
const sessionId = (0, sdp_1.
|
|
1504
|
+
const sessionId = (0, sdp_1.getSipCallId)(session);
|
|
1503
1505
|
const isConference = this.isConference(sessionId);
|
|
1504
1506
|
if (sessionId in this.audioElements) {
|
|
1505
1507
|
logger.info('html element already exists for session', {
|
|
@@ -1545,7 +1547,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
1545
1547
|
});
|
|
1546
1548
|
}
|
|
1547
1549
|
_cleanupMedia(session) {
|
|
1548
|
-
const sessionId = (0, sdp_1.
|
|
1550
|
+
const sessionId = (0, sdp_1.getSipCallId)(session);
|
|
1549
1551
|
const localStream = this.getLocalStream(sessionId);
|
|
1550
1552
|
if (localStream) {
|
|
1551
1553
|
(0, webrtc_1.cleanupStream)(localStream);
|
|
@@ -1564,7 +1566,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
1564
1566
|
};
|
|
1565
1567
|
if (this._hasAudio() && (0, webrtc_1.isWeb)()) {
|
|
1566
1568
|
if (session) {
|
|
1567
|
-
cleanLocalElement((0, sdp_1.
|
|
1569
|
+
cleanLocalElement((0, sdp_1.getSipCallId)(session));
|
|
1568
1570
|
}
|
|
1569
1571
|
else {
|
|
1570
1572
|
Object.keys(this.audioElements).forEach(id => cleanLocalElement(id));
|
|
@@ -1584,7 +1586,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
1584
1586
|
if (!pc) {
|
|
1585
1587
|
return;
|
|
1586
1588
|
}
|
|
1587
|
-
const sessionId = (0, sdp_1.
|
|
1589
|
+
const sessionId = (0, sdp_1.getSipCallId)(session);
|
|
1588
1590
|
(0, getstats_1.default)(pc, (result) => {
|
|
1589
1591
|
const { results, internal, nomore } = result, stats = __rest(result, ["results", "internal", "nomore"]);
|
|
1590
1592
|
this.statsIntervals[sessionId] = nomore;
|
|
@@ -1592,7 +1594,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
1592
1594
|
}, SEND_STATS_DELAY);
|
|
1593
1595
|
}
|
|
1594
1596
|
_stopSendingStats(session) {
|
|
1595
|
-
const sessionId = (0, sdp_1.
|
|
1597
|
+
const sessionId = (0, sdp_1.getSipCallId)(session);
|
|
1596
1598
|
logger.trace('Check for stopping stats', {
|
|
1597
1599
|
sessionId,
|
|
1598
1600
|
ids: Object.keys(this.statsIntervals),
|
|
@@ -1649,18 +1651,18 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
1649
1651
|
return __awaiter(this, arguments, void 0, function* (session, options = {}) {
|
|
1650
1652
|
if (session.state === session_state_1.SessionState.Terminated || session.state === session_state_1.SessionState.Terminating) {
|
|
1651
1653
|
const error = 'Trying to accept a terminated sipSession.';
|
|
1652
|
-
logger.warn(error, { state: session.state, sessionId: session
|
|
1654
|
+
logger.warn(error, { state: session.state, sessionId: (0, sdp_1.getSipCallId)(session) });
|
|
1653
1655
|
throw new Error(error);
|
|
1654
1656
|
}
|
|
1655
1657
|
if (session.state !== session_state_1.SessionState.Initial) {
|
|
1656
1658
|
const error = 'Trying to accept a non Initial sipSession.';
|
|
1657
|
-
logger.warn(error, { state: session.state, sessionId: session
|
|
1659
|
+
logger.warn(error, { state: session.state, sessionId: (0, sdp_1.getSipCallId)(session) });
|
|
1658
1660
|
throw new Error(error);
|
|
1659
1661
|
}
|
|
1660
1662
|
// @ts-ignore: private
|
|
1661
1663
|
if (!session.incomingInviteRequest.acceptable) {
|
|
1662
1664
|
const error = 'Trying to reject a non `acceptable` session';
|
|
1663
|
-
logger.warn(error, { state: session.state, sessionId: session
|
|
1665
|
+
logger.warn(error, { state: session.state, sessionId: (0, sdp_1.getSipCallId)(session) });
|
|
1664
1666
|
throw new Error(error);
|
|
1665
1667
|
}
|
|
1666
1668
|
try {
|
|
@@ -1674,12 +1676,12 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
1674
1676
|
_reject(session_1) {
|
|
1675
1677
|
return __awaiter(this, arguments, void 0, function* (session, options = {}) {
|
|
1676
1678
|
if (session.state !== session_state_1.SessionState.Initial && session.state !== session_state_1.SessionState.Establishing) {
|
|
1677
|
-
logger.warn('Trying to reject a session in a wrong state', { state: session.state, sessionId: session
|
|
1679
|
+
logger.warn('Trying to reject a session in a wrong state', { state: session.state, sessionId: (0, sdp_1.getSipCallId)(session) });
|
|
1678
1680
|
return;
|
|
1679
1681
|
}
|
|
1680
1682
|
// @ts-ignore: private
|
|
1681
1683
|
if (!session.incomingInviteRequest.rejectable) {
|
|
1682
|
-
logger.warn('Trying to reject a non `rejectable` session', { state: session.state, sessionId: session
|
|
1684
|
+
logger.warn('Trying to reject a non `rejectable` session', { state: session.state, sessionId: (0, sdp_1.getSipCallId)(session) });
|
|
1683
1685
|
return;
|
|
1684
1686
|
}
|
|
1685
1687
|
try {
|
|
@@ -1693,7 +1695,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
1693
1695
|
_cancel(session_1) {
|
|
1694
1696
|
return __awaiter(this, arguments, void 0, function* (session, options = {}) {
|
|
1695
1697
|
if (session.state !== session_state_1.SessionState.Initial && session.state !== session_state_1.SessionState.Establishing) {
|
|
1696
|
-
logger.warn('Trying to cancel a session in a wrong state', { state: session.state, sessionId: session
|
|
1698
|
+
logger.warn('Trying to cancel a session in a wrong state', { state: session.state, sessionId: (0, sdp_1.getSipCallId)(session) });
|
|
1697
1699
|
return;
|
|
1698
1700
|
}
|
|
1699
1701
|
try {
|
|
@@ -1707,7 +1709,7 @@ class WebRTCClient extends Emitter_1.default {
|
|
|
1707
1709
|
_bye(session_1) {
|
|
1708
1710
|
return __awaiter(this, arguments, void 0, function* (session, options = {}) {
|
|
1709
1711
|
if (session.state !== session_state_1.SessionState.Established) {
|
|
1710
|
-
logger.warn('Trying to end a session in a wrong state', { state: session.state, sessionId: session
|
|
1712
|
+
logger.warn('Trying to end a session in a wrong state', { state: session.state, sessionId: (0, sdp_1.getSipCallId)(session) });
|
|
1711
1713
|
return null;
|
|
1712
1714
|
}
|
|
1713
1715
|
try {
|
package/package.json
CHANGED
|
@@ -3,8 +3,9 @@ import { Inviter, UserAgent, type URI } from 'sip.js';
|
|
|
3
3
|
|
|
4
4
|
import softphone from '../../voice/softphone';
|
|
5
5
|
import Call from '../../voice/call';
|
|
6
|
-
import { Actions, States } from '../../state-machine/call-state-machine';
|
|
6
|
+
import { Actions, EstablishedStates, States } from '../../state-machine/call-state-machine';
|
|
7
7
|
import { Actions as SoftphoneActions } from '../../state-machine/softphone-state-machine';
|
|
8
|
+
import ApiCall from '../../domain/Call';
|
|
8
9
|
|
|
9
10
|
import InvalidStateTransition from '../../domain/InvalidStateTransition';
|
|
10
11
|
|
|
@@ -33,6 +34,7 @@ jest.mock('../../web-rtc-client', () => jest.fn().mockImplementation(() => ({
|
|
|
33
34
|
answer: jest.fn(() => Promise.resolve()),
|
|
34
35
|
hangup: jest.fn(() => Promise.resolve()),
|
|
35
36
|
register: jest.fn(() => Promise.resolve()),
|
|
37
|
+
onCallEnded: jest.fn(() => Promise.resolve()),
|
|
36
38
|
setOnHeartbeatTimeout: jest.fn(() => Promise.resolve()),
|
|
37
39
|
setOnHeartbeatCallback: jest.fn(() => Promise.resolve()),
|
|
38
40
|
on: jest.fn(),
|
|
@@ -42,11 +44,45 @@ const ua = new UserAgent(uaOptions);
|
|
|
42
44
|
const sipCall = new Inviter(ua, UserAgent.makeURI('sip:1234@my.stack.io') as URI);
|
|
43
45
|
|
|
44
46
|
softphone.connect();
|
|
47
|
+
// @ts-ignore: private method
|
|
45
48
|
softphone._sendAction(SoftphoneActions.REGISTER_DONE);
|
|
46
49
|
|
|
47
50
|
const invalidStateTransition = (state: string, action: string) => new InvalidStateTransition(`Invalid state transition from ${state} with action ${action}`, state, action);
|
|
48
51
|
|
|
49
52
|
describe('Call', () => {
|
|
53
|
+
describe('parsing an API call', () => {
|
|
54
|
+
it('Should parse an API call and transform it to a Call instance', async () => {
|
|
55
|
+
const apiCall = new ApiCall({
|
|
56
|
+
id: '1234',
|
|
57
|
+
sipCallId: 'abcd',
|
|
58
|
+
isCaller: false,
|
|
59
|
+
isVideo: true,
|
|
60
|
+
recording: true,
|
|
61
|
+
callerName: '',
|
|
62
|
+
callerNumber: '',
|
|
63
|
+
calleeName: '',
|
|
64
|
+
calleeNumber: '0123423223',
|
|
65
|
+
dialedExtension: '',
|
|
66
|
+
lineId: null,
|
|
67
|
+
muted: true,
|
|
68
|
+
onHold: false,
|
|
69
|
+
startingTime: new Date(),
|
|
70
|
+
status: 'Up',
|
|
71
|
+
talkingToIds: [],
|
|
72
|
+
});
|
|
73
|
+
const call = Call.parseCall(apiCall);
|
|
74
|
+
|
|
75
|
+
expect(call.recording).toBeTruthy();
|
|
76
|
+
expect(call.id).toBe(apiCall.sipCallId);
|
|
77
|
+
expect(call.apiId).toBe(apiCall.id);
|
|
78
|
+
expect(call.number).toBe(apiCall.calleeNumber);
|
|
79
|
+
expect(call.answerTime).toStrictEqual(apiCall.startingTime);
|
|
80
|
+
expect(call.isMuted()).toBeTruthy();
|
|
81
|
+
expect(call.state).toStrictEqual({ [States.ESTABLISHED]: EstablishedStates.MUTED });
|
|
82
|
+
expect(call.isEstablished()).toBeTruthy();
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
50
86
|
describe('accept', () => {
|
|
51
87
|
it('Should throw an error when accepting a not ringing call', async () => {
|
|
52
88
|
const call = new Call(sipCall, softphone);
|
|
@@ -54,16 +90,24 @@ describe('Call', () => {
|
|
|
54
90
|
await expect(call.accept()).rejects.toThrowError(invalidStateTransition(States.IDLE, Actions.ACCEPT));
|
|
55
91
|
});
|
|
56
92
|
|
|
57
|
-
it
|
|
93
|
+
it('Should throw an error when the softphone is not registered', async () => {
|
|
58
94
|
const call = new Call(sipCall, softphone);
|
|
95
|
+
// @ts-ignore: private method
|
|
59
96
|
call._sendAction(Actions.INCOMING_CALL);
|
|
97
|
+
// @ts-ignore: private method
|
|
60
98
|
softphone._sendAction(SoftphoneActions.TRANSPORT_CLOSED);
|
|
61
99
|
|
|
62
100
|
await expect(call.accept()).rejects.toThrowError(invalidStateTransition(States.RINGING, Actions.ACCEPT));
|
|
101
|
+
|
|
102
|
+
// Revert softphone state
|
|
103
|
+
softphone.connect();
|
|
104
|
+
// @ts-ignore: private method
|
|
105
|
+
softphone._sendAction(SoftphoneActions.REGISTER_DONE);
|
|
63
106
|
});
|
|
64
107
|
|
|
65
108
|
it('Should not throw an error when accepting a not ringing call', async () => {
|
|
66
109
|
const call = new Call(sipCall, softphone);
|
|
110
|
+
// @ts-ignore: private method
|
|
67
111
|
call._sendAction(Actions.INCOMING_CALL);
|
|
68
112
|
|
|
69
113
|
await call.accept();
|
|
@@ -80,11 +124,28 @@ describe('Call', () => {
|
|
|
80
124
|
|
|
81
125
|
it('Should not throw an error when terminating an established call', async () => {
|
|
82
126
|
const call = new Call(sipCall, softphone);
|
|
127
|
+
// @ts-ignore: private method
|
|
83
128
|
call._sendAction(Actions.MAKE_CALL);
|
|
129
|
+
// @ts-ignore: private method
|
|
84
130
|
call._sendAction(Actions.REMOTLY_ACCEPTED);
|
|
85
131
|
|
|
86
132
|
await call.hangup();
|
|
87
133
|
expect(softphone.client.hangup).toHaveBeenCalled();
|
|
88
134
|
});
|
|
89
135
|
});
|
|
136
|
+
|
|
137
|
+
describe('state propagation', () => {
|
|
138
|
+
it('Should update the call state in events', (done) => {
|
|
139
|
+
const call = new Call(sipCall, softphone);
|
|
140
|
+
// @ts-ignore: private method
|
|
141
|
+
call._sendAction(Actions.MAKE_CALL);
|
|
142
|
+
|
|
143
|
+
call.on('remotelyAccepted', () => {
|
|
144
|
+
expect(call.state).toStrictEqual({ [States.ESTABLISHED]: EstablishedStates.ONGOING });
|
|
145
|
+
done();
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
call.onAccepted();
|
|
149
|
+
});
|
|
150
|
+
});
|
|
90
151
|
});
|
package/src/api/auth.ts
CHANGED
|
@@ -33,6 +33,7 @@ export interface AuthD {
|
|
|
33
33
|
logIn(params: LoginParams): Promise<Session | null | undefined> ;
|
|
34
34
|
logOut: (token: Token) => Promise<LogoutResponse>;
|
|
35
35
|
samlLogIn: (samlSessionId: string) => Promise<Session | null | undefined>;
|
|
36
|
+
samlLogOut: () => Promise<void | { location:string }>;
|
|
36
37
|
initiateIdpAuthentication(domain: string, redirectUrl: string): Promise<any>;
|
|
37
38
|
refreshToken: (refreshToken: string, backend: string, expiration: number, isMobile?: boolean, tenantId?: string, domainName?: string) => Promise<Session | null | undefined>;
|
|
38
39
|
deleteRefreshToken: (clientId: string) => Promise<boolean>;
|
|
@@ -139,6 +140,10 @@ export default ((client: ApiRequester, baseUrl: string): AuthD => ({
|
|
|
139
140
|
return client.post(`${baseUrl}/token`, body, headers).then(Session.parse);
|
|
140
141
|
},
|
|
141
142
|
|
|
143
|
+
samlLogOut() {
|
|
144
|
+
return client.get(`${baseUrl}/saml/logout`, null, null);
|
|
145
|
+
},
|
|
146
|
+
|
|
142
147
|
initiateIdpAuthentication: async (domain: string, redirectUrl: string) => {
|
|
143
148
|
const body = {
|
|
144
149
|
domain,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import WebRTCClient from '../../web-rtc-client';
|
|
2
|
-
import {
|
|
2
|
+
import { SipCall } from '../../domain/types';
|
|
3
3
|
|
|
4
4
|
export default {
|
|
5
5
|
name: 'WebRTC Transport (WS) ~30s',
|
|
6
|
-
check: (server: string, session:
|
|
6
|
+
check: (server: string, session: SipCall): Promise<void> => new Promise((resolve, reject) => {
|
|
7
7
|
const [host, port = 443] = server.split(':');
|
|
8
8
|
|
|
9
9
|
const client = new WebRTCClient({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* global MediaStream */
|
|
2
|
-
import {
|
|
2
|
+
import { getSipCallId } from '../../utils/sdp';
|
|
3
3
|
import WebRTCClient from '../../web-rtc-client';
|
|
4
4
|
|
|
5
5
|
export default {
|
|
@@ -36,7 +36,7 @@ export default {
|
|
|
36
36
|
client.on(client.REGISTERED, () => {
|
|
37
37
|
const sipSession = client.call('*10');
|
|
38
38
|
|
|
39
|
-
if (!sipSession || !
|
|
39
|
+
if (!sipSession || !getSipCallId(sipSession)) {
|
|
40
40
|
return handleError('Unable to make call through WebRTC');
|
|
41
41
|
}
|
|
42
42
|
|
package/src/domain/CallLog.ts
CHANGED
|
@@ -118,8 +118,7 @@ export default class CallLog {
|
|
|
118
118
|
|
|
119
119
|
static parseNew(plain: CallLogResponse, session: Session): CallLog {
|
|
120
120
|
const callLog: CallLog = CallLog.parse(plain);
|
|
121
|
-
|
|
122
|
-
callLog.newMissedCall = session && session.hasExtension((plain.requested_extension || plain.destination_extension) as string) && !plain.answered;
|
|
121
|
+
callLog.newMissedCall = session && plain.destination_user_uuid === session.uuid && !plain.answered;
|
|
123
122
|
return callLog;
|
|
124
123
|
}
|
|
125
124
|
|
|
@@ -203,7 +202,7 @@ export default class CallLog {
|
|
|
203
202
|
}
|
|
204
203
|
|
|
205
204
|
isAnOutgoingCall(session: Session): boolean {
|
|
206
|
-
console.warn(`@wazo/sdk
|
|
205
|
+
console.warn(`@wazo/sdk
|
|
207
206
|
CallLog.isAnOutgoingcall(session) method is obsolete.
|
|
208
207
|
Please use CallLog.isOutgoing(session).
|
|
209
208
|
`);
|