@wazo/sdk 0.37.29 → 0.37.33

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 (81) hide show
  1. package/README.md +2 -1
  2. package/dist/wazo-sdk.js +4 -4
  3. package/esm/__tests__/api-client.test.js +30 -0
  4. package/esm/__tests__/web-rtc-client.test.js +65 -6
  5. package/esm/api/calld.js +30 -0
  6. package/esm/api-client.js +30 -0
  7. package/esm/checker/Checker.js +65 -6
  8. package/esm/checker/checks/aor.js +30 -0
  9. package/esm/checker/checks/api.js +30 -0
  10. package/esm/checker/checks/index.js +65 -6
  11. package/esm/checker/checks/webrtc-transport.js +65 -6
  12. package/esm/checker/checks/webrtc.js +65 -6
  13. package/esm/domain/AdHocAPIConference.js +30 -0
  14. package/esm/domain/CallSession.js +9 -1
  15. package/esm/domain/Features.js +30 -0
  16. package/esm/domain/MeetingStatus.js +29 -0
  17. package/esm/domain/Phone/CTIPhone.js +39 -1
  18. package/esm/domain/Phone/WebRTCPhone.js +20 -4
  19. package/esm/domain/__tests__/CallSession.test.js +41 -5
  20. package/esm/domain/__tests__/IndirectTransfer.test.js +9 -1
  21. package/esm/domain/__tests__/Room.test.js +9 -1
  22. package/esm/index.js +85 -10
  23. package/esm/service/CallApi.js +30 -0
  24. package/esm/service/getApiClient.js +30 -0
  25. package/esm/simple/Auth.js +85 -10
  26. package/esm/simple/Configuration.js +85 -10
  27. package/esm/simple/Directory.js +30 -0
  28. package/esm/simple/Phone.js +85 -10
  29. package/esm/simple/index.js +85 -10
  30. package/esm/simple/room/LocalParticipant.js +85 -10
  31. package/esm/simple/room/Participant.js +85 -10
  32. package/esm/simple/room/RemoteParticipant.js +85 -10
  33. package/esm/simple/room/Room.js +85 -10
  34. package/esm/simple/room/SipRoom.js +85 -10
  35. package/esm/simple/room/Stream.js +85 -10
  36. package/esm/simple/room/__tests__/RemoteParticipant.test.js +85 -10
  37. package/esm/simple/utils.js +85 -10
  38. package/esm/web-rtc-client.js +65 -6
  39. package/lib/__tests__/api-client.test.js +30 -0
  40. package/lib/__tests__/web-rtc-client.test.js +65 -6
  41. package/lib/api/calld.js +30 -0
  42. package/lib/api-client.js +30 -0
  43. package/lib/checker/Checker.js +65 -6
  44. package/lib/checker/checks/aor.js +30 -0
  45. package/lib/checker/checks/api.js +30 -0
  46. package/lib/checker/checks/index.js +65 -6
  47. package/lib/checker/checks/webrtc-transport.js +65 -6
  48. package/lib/checker/checks/webrtc.js +65 -6
  49. package/lib/domain/AdHocAPIConference.js +30 -0
  50. package/lib/domain/CallSession.js +9 -1
  51. package/lib/domain/Features.js +30 -0
  52. package/lib/domain/MeetingStatus.js +31 -0
  53. package/lib/domain/Phone/CTIPhone.js +39 -1
  54. package/lib/domain/Phone/WebRTCPhone.js +20 -4
  55. package/lib/domain/__tests__/CallSession.test.js +41 -5
  56. package/lib/domain/__tests__/IndirectTransfer.test.js +9 -1
  57. package/lib/domain/__tests__/Room.test.js +9 -1
  58. package/lib/index.js +85 -10
  59. package/lib/service/CallApi.js +30 -0
  60. package/lib/service/getApiClient.js +30 -0
  61. package/lib/simple/Auth.js +85 -10
  62. package/lib/simple/Configuration.js +85 -10
  63. package/lib/simple/Directory.js +30 -0
  64. package/lib/simple/Phone.js +85 -10
  65. package/lib/simple/index.js +85 -10
  66. package/lib/simple/room/LocalParticipant.js +85 -10
  67. package/lib/simple/room/Participant.js +85 -10
  68. package/lib/simple/room/RemoteParticipant.js +85 -10
  69. package/lib/simple/room/Room.js +85 -10
  70. package/lib/simple/room/SipRoom.js +85 -10
  71. package/lib/simple/room/Stream.js +85 -10
  72. package/lib/simple/room/__tests__/RemoteParticipant.test.js +85 -10
  73. package/lib/simple/utils.js +85 -10
  74. package/lib/web-rtc-client.js +65 -6
  75. package/package.json +1 -1
  76. package/src/api/calld.js +3 -0
  77. package/src/domain/CallSession.js +9 -1
  78. package/src/domain/MeetingStatus.js +27 -0
  79. package/src/domain/Phone/WebRTCPhone.js +11 -3
  80. package/src/domain/__tests__/CallSession.test.js +32 -4
  81. package/src/web-rtc-client.js +35 -6
@@ -0,0 +1,27 @@
1
+ // @flow
2
+
3
+ export type MeetingStatusResponse = {
4
+ full: boolean
5
+ };
6
+
7
+ export default class MeetingStatus {
8
+ type: string;
9
+
10
+ full: boolean;
11
+
12
+ constructor({
13
+ full,
14
+ }: Object = {}) {
15
+ this.full = full;
16
+
17
+ // Useful to compare instead of instanceof with minified code
18
+ this.type = 'MeetingStatus';
19
+ }
20
+
21
+ static parse(plain: MeetingStatusResponse): MeetingStatus {
22
+ return new MeetingStatus({
23
+ full: plain.full,
24
+ });
25
+ }
26
+
27
+ }
@@ -631,6 +631,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
631
631
  }
632
632
 
633
633
  callSession.answerTime = new Date();
634
+ this._updateCallSession(callSession);
634
635
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
635
636
 
636
637
  return callSession;
@@ -847,6 +848,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
847
848
 
848
849
  this.shouldSendReinvite = false;
849
850
  callSession.answerTime = new Date();
851
+ this._updateCallSession(callSession);
850
852
  this.acceptedSessions[callSession.getId()] = true;
851
853
 
852
854
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -946,7 +948,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
946
948
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
947
949
  if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
948
950
  logger.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
949
- this.holdSipSession(this.currentSipSession, callSession);
951
+ this.holdSipSession(this.currentSipSession, this.currentCallSession);
950
952
  }
951
953
 
952
954
  const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
@@ -1157,6 +1159,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1157
1159
  }
1158
1160
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
1159
1161
  callSession.creationTime = new Date();
1162
+ this._updateCallSession(callSession);
1160
1163
 
1161
1164
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
1162
1165
 
@@ -1298,7 +1301,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1298
1301
  return this.client && this.client.isConference(callSession.sipCallId);
1299
1302
  }
1300
1303
 
1301
- async close(): Promise<void> {
1304
+ async close(force: boolean = false): Promise<void> {
1302
1305
  logger.info('WebRTC close');
1303
1306
 
1304
1307
  try {
@@ -1310,7 +1313,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1310
1313
  logger.error('WebRTC close, unregister error', e);
1311
1314
  }
1312
1315
 
1313
- this.client.close();
1316
+ this.client.close(force);
1314
1317
  this.unbind();
1315
1318
 
1316
1319
  this.incomingSessions = [];
@@ -1436,6 +1439,8 @@ export default class WebRTCPhone extends Emitter implements Phone {
1436
1439
  }
1437
1440
 
1438
1441
  callSession.creationTime = new Date();
1442
+ this._updateCallSession(callSession);
1443
+
1439
1444
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
1440
1445
  });
1441
1446
 
@@ -1479,6 +1484,8 @@ export default class WebRTCPhone extends Emitter implements Phone {
1479
1484
  logger.info('WebRTC call rejected', session.id);
1480
1485
  const callSession = this._createCallSession(session);
1481
1486
  callSession.endTime = new Date();
1487
+ this._updateCallSession(callSession);
1488
+
1482
1489
  this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
1483
1490
  });
1484
1491
 
@@ -1705,6 +1712,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1705
1712
  displayName: identity ? identity.displayName || number : number,
1706
1713
  startTime: fromSession ? fromSession.startTime : new Date(),
1707
1714
  creationTime: fromSession ? fromSession.creationTime : null,
1715
+ answerTime: fromSession ? fromSession.answerTime : null,
1708
1716
  endTime: fromSession ? fromSession.endTime : null,
1709
1717
  answered: state === SessionState.Established,
1710
1718
  paused: this.client.isCallHeld(sipSession),
@@ -1,5 +1,7 @@
1
1
  import CallSession from '../CallSession';
2
2
 
3
+ const stringify = cs => JSON.parse(JSON.stringify(cs));
4
+
3
5
  describe('CallSession domain', () => {
4
6
  it('should update from another CallSession without data loss', () => {
5
7
  const callSession = new CallSession({
@@ -38,7 +40,7 @@ describe('CallSession domain', () => {
38
40
  expect(cs2.is(cs1)).toBeTruthy();
39
41
  });
40
42
 
41
- it('should set answerTime when setting answered', () => {
43
+ it('should set answerTime when setting answered to true', () => {
42
44
  const cs1 = new CallSession({});
43
45
  cs1.answered = true;
44
46
 
@@ -47,11 +49,37 @@ describe('CallSession domain', () => {
47
49
 
48
50
  const cs3 = new CallSession({ answered: true });
49
51
 
50
- expect(cs1.answered).toBeTruthy();
52
+ expect(cs1.answered).toEqual(true);
51
53
  expect(cs1.answerTime).not.toBeNull();
52
- expect(cs2.answered).toBeTruthy();
54
+ expect(cs2.answered).toEqual(true);
53
55
  expect(cs2.answerTime).not.toBeNull();
54
- expect(cs3.answered).toBeTruthy();
56
+ expect(cs3.answered).toEqual(true);
55
57
  expect(cs3.answerTime).not.toBeNull();
58
+
59
+ const cs4 = stringify(cs1);
60
+ const cs5 = stringify(cs2);
61
+ const cs6 = stringify(cs3);
62
+
63
+ expect(cs4.answered).toEqual(true);
64
+ expect(cs5.answered).toEqual(true);
65
+ expect(cs6.answered).toEqual(true);
66
+ });
67
+
68
+ it('should reset answerTime when setting answered to false', () => {
69
+ const cs1 = new CallSession({});
70
+ cs1.answered = false;
71
+
72
+ const cs2 = new CallSession({ answered: false });
73
+
74
+ expect(cs1.answered).toEqual(false);
75
+ expect(cs1.answerTime).toBeNull();
76
+ expect(cs2.answered).toEqual(false);
77
+ expect(cs2.answerTime).toBeNull();
78
+
79
+ const cs4 = stringify(cs1);
80
+ const cs5 = stringify(cs2);
81
+
82
+ expect(cs4.answered).toEqual(false);
83
+ expect(cs5.answered).toEqual(false);
56
84
  });
57
85
  });
@@ -87,6 +87,7 @@ type WebRtcConfig = {
87
87
  displayName: string,
88
88
  host: string,
89
89
  port?: number,
90
+ websocketSip?: ?string,
90
91
  authorizationUser: ?string,
91
92
  password: ?string,
92
93
  uri: string,
@@ -128,6 +129,7 @@ export default class WebRTCClient extends Emitter {
128
129
  skipRegister: boolean;
129
130
  networkMonitoringInterval: { [string]: IntervalID };
130
131
  sessionNetworkStats: { [string]: Object };
132
+ forceClosed: boolean;
131
133
 
132
134
  // sugar
133
135
  ON_USER_AGENT: string;
@@ -190,6 +192,7 @@ export default class WebRTCClient extends Emitter {
190
192
  this.conferences = {};
191
193
  this.networkMonitoringInterval = {};
192
194
  this.sessionNetworkStats = {};
195
+ this.forceClosed = false;
193
196
 
194
197
  this._boundOnHeartbeat = this._onHeartbeat.bind(this);
195
198
  this.heartbeat = new Heartbeat(config.heartbeatDelay, config.heartbeatTimeout, config.maxHeartbeats);
@@ -311,6 +314,8 @@ export default class WebRTCClient extends Emitter {
311
314
  skipRegister: this.skipRegister,
312
315
  };
313
316
 
317
+ this.forceClosed = false;
318
+
314
319
  if (this.skipRegister) {
315
320
  logger.info('sdk webrtc skip register...', logInfo);
316
321
  return Promise.resolve();
@@ -335,7 +340,15 @@ export default class WebRTCClient extends Emitter {
335
340
  const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
336
341
 
337
342
  const onRegisterFailed = () => {
338
- logger.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
343
+ logger.info('sdk webrtc registering failed', {
344
+ tries,
345
+ registerer: !!this.registerer,
346
+ forceClosed: this.forceClosed,
347
+ });
348
+ if (this.forceClosed) {
349
+ return;
350
+ }
351
+
339
352
  this.connectionPromise = null;
340
353
  if (this.registerer && this.registerer.waiting) {
341
354
  this.registerer.waitingToggle(false);
@@ -613,8 +626,9 @@ export default class WebRTCClient extends Emitter {
613
626
  }
614
627
  }
615
628
 
616
- async close() {
617
- logger.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
629
+ async close(force: boolean = false) {
630
+ logger.info('sdk webrtc closing client', { userAgent: !!this.userAgent, force });
631
+ this.forceClosed = force;
618
632
  this._cleanupMedia();
619
633
  this.connectionPromise = null;
620
634
 
@@ -633,7 +647,7 @@ export default class WebRTCClient extends Emitter {
633
647
  this.userAgent.delegate = null;
634
648
  this.userAgent.stateChange.removeAllListeners();
635
649
 
636
- await this._disconnectTransport();
650
+ await this._disconnectTransport(force);
637
651
 
638
652
  this._cleanupRegister();
639
653
 
@@ -1703,6 +1717,13 @@ export default class WebRTCClient extends Emitter {
1703
1717
  }
1704
1718
 
1705
1719
  _createWebRTCConfiguration(configOverrides: Object = {}) {
1720
+ let { host } = this.config;
1721
+ let port = this.config.port || 443;
1722
+
1723
+ if (this.config.websocketSip) {
1724
+ [host, port = 443] = this.config.websocketSip.split(':');
1725
+ }
1726
+
1706
1727
  const config: Object = {
1707
1728
  authorizationUsername: this.config.authorizationUser,
1708
1729
  authorizationPassword: this.config.password,
@@ -1738,7 +1759,7 @@ export default class WebRTCClient extends Emitter {
1738
1759
  },
1739
1760
  transportOptions: {
1740
1761
  traceSip: configOverrides.traceSip || false,
1741
- wsServers: `wss://${this.config.host}:${this.config.port || 443}/api/asterisk/ws`,
1762
+ wsServers: `wss://${host}:${port}/api/asterisk/ws`,
1742
1763
  },
1743
1764
  sessionDescriptionHandlerFactoryOptions: {
1744
1765
  modifiers: [replaceLocalIpModifier],
@@ -2062,7 +2083,15 @@ export default class WebRTCClient extends Emitter {
2062
2083
  return UserAgent.makeURI(`sip:${target}@${this.config.host}`);
2063
2084
  }
2064
2085
 
2065
- async _disconnectTransport() {
2086
+ async _disconnectTransport(force: boolean = false) {
2087
+ if (force) {
2088
+ // Bypass sip.js state machine that prevent to close WS with the state `Connecting`
2089
+ this.userAgent.transport.disconnectResolve = () => {};
2090
+ // eslint-disable-next-line
2091
+ this.userAgent.transport._ws.close(1000);
2092
+ return;
2093
+ }
2094
+
2066
2095
  // Check if `disconnectPromise` is not present to avoid `Disconnect promise must not be defined` errors.
2067
2096
  if (this.userAgent && this.userAgent.transport && !this.userAgent.transport.disconnectPromise) {
2068
2097
  try {