@wazo/sdk 1.0.0-alpha.7 → 1.0.0-alpha.9

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 (64) hide show
  1. package/README.md +16 -7
  2. package/dist/wazo-sdk.js +2 -2
  3. package/esm/api/auth.js +3 -0
  4. package/esm/domain/CallLog.js +2 -3
  5. package/esm/domain/Phone/WebRTCPhone.js +29 -27
  6. package/esm/simple/Auth.js +13 -3
  7. package/esm/simple/Phone.js +2 -2
  8. package/esm/state-machine/softphone-state-machine.js +1 -2
  9. package/esm/types/api/auth.d.ts +3 -0
  10. package/esm/types/api/auth.d.ts.map +1 -1
  11. package/esm/types/domain/CallLog.d.ts.map +1 -1
  12. package/esm/types/domain/Phone/WebRTCPhone.d.ts +3 -3
  13. package/esm/types/domain/Phone/WebRTCPhone.d.ts.map +1 -1
  14. package/esm/types/simple/Auth.d.ts +6 -1
  15. package/esm/types/simple/Auth.d.ts.map +1 -1
  16. package/esm/types/simple/Phone.d.ts +2 -2
  17. package/esm/types/simple/Phone.d.ts.map +1 -1
  18. package/esm/types/state-machine/softphone-state-machine.d.ts +0 -1
  19. package/esm/types/state-machine/softphone-state-machine.d.ts.map +1 -1
  20. package/esm/types/utils/sdp.d.ts.map +1 -1
  21. package/esm/types/voice/call.d.ts.map +1 -1
  22. package/esm/types/voice/softphone.d.ts.map +1 -1
  23. package/esm/types/web-rtc-client.d.ts +2 -1
  24. package/esm/types/web-rtc-client.d.ts.map +1 -1
  25. package/esm/utils/sdp.js +8 -7
  26. package/esm/voice/call.js +3 -2
  27. package/esm/voice/softphone.js +23 -6
  28. package/esm/web-rtc-client.js +31 -30
  29. package/lib/api/auth.js +3 -0
  30. package/lib/domain/CallLog.js +2 -3
  31. package/lib/domain/Phone/WebRTCPhone.js +29 -27
  32. package/lib/simple/Auth.js +15 -3
  33. package/lib/state-machine/softphone-state-machine.js +1 -2
  34. package/lib/types/api/auth.d.ts +3 -0
  35. package/lib/types/api/auth.d.ts.map +1 -1
  36. package/lib/types/domain/CallLog.d.ts.map +1 -1
  37. package/lib/types/domain/Phone/WebRTCPhone.d.ts +3 -3
  38. package/lib/types/domain/Phone/WebRTCPhone.d.ts.map +1 -1
  39. package/lib/types/simple/Auth.d.ts +6 -1
  40. package/lib/types/simple/Auth.d.ts.map +1 -1
  41. package/lib/types/simple/Phone.d.ts +2 -2
  42. package/lib/types/simple/Phone.d.ts.map +1 -1
  43. package/lib/types/state-machine/softphone-state-machine.d.ts +0 -1
  44. package/lib/types/state-machine/softphone-state-machine.d.ts.map +1 -1
  45. package/lib/types/utils/sdp.d.ts.map +1 -1
  46. package/lib/types/voice/call.d.ts.map +1 -1
  47. package/lib/types/voice/softphone.d.ts.map +1 -1
  48. package/lib/types/web-rtc-client.d.ts +2 -1
  49. package/lib/types/web-rtc-client.d.ts.map +1 -1
  50. package/lib/utils/sdp.js +7 -6
  51. package/lib/voice/call.js +3 -2
  52. package/lib/voice/softphone.js +24 -6
  53. package/lib/web-rtc-client.js +29 -29
  54. package/package.json +1 -1
  55. package/src/api/auth.ts +5 -0
  56. package/src/domain/CallLog.ts +2 -3
  57. package/src/domain/Phone/WebRTCPhone.ts +33 -31
  58. package/src/simple/Auth.ts +15 -3
  59. package/src/simple/Phone.ts +3 -3
  60. package/src/state-machine/softphone-state-machine.ts +1 -2
  61. package/src/utils/sdp.ts +9 -8
  62. package/src/voice/call.ts +4 -3
  63. package/src/voice/softphone.ts +30 -7
  64. package/src/web-rtc-client.ts +34 -29
@@ -8,7 +8,7 @@ import { Inviter, Invitation, Session, SessionDescriptionHandlerOptions } from '
8
8
  import { SessionDescriptionHandler } from 'sip.js/lib/platform/web';
9
9
  import CallSession from '../CallSession';
10
10
  import type { Phone, AvailablePhoneOptions } from './Phone';
11
- import WazoWebRTCClient from '../../web-rtc-client';
11
+ import WebRTCClient from '../../web-rtc-client';
12
12
  import Emitter from '../../utils/Emitter';
13
13
  import IssueReporter from '../../service/IssueReporter';
14
14
  import { PeerConnection, WazoSession } from '../types';
@@ -64,7 +64,7 @@ const logger = IssueReporter.loggerFor('webrtc-phone');
64
64
 
65
65
  // @deprecated: Use Wazo.Voice.Softphone instead
66
66
  export default class WebRTCPhone extends Emitter implements Phone {
67
- client: WazoWebRTCClient;
67
+ client: WebRTCClient;
68
68
 
69
69
  allowVideo: boolean;
70
70
 
@@ -98,7 +98,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
98
98
 
99
99
  shouldSendReinvite: boolean;
100
100
 
101
- constructor(client: WazoWebRTCClient, audioOutputDeviceId: string | undefined, allowVideo = false, audioRingDeviceId?: string) {
101
+ constructor(client: WebRTCClient, audioOutputDeviceId: string | undefined, allowVideo = false, audioRingDeviceId?: string) {
102
102
  super();
103
103
  this.client = client;
104
104
  this.allowVideo = allowVideo;
@@ -163,7 +163,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
163
163
  async sendReinvite(callSession?: CallSession, constraints: Record<string, any> | null | undefined = null, conference = false, audioOnly = false, iceRestart = false): Promise<OutgoingInviteRequest | void> {
164
164
  const sipSession = this.findSipSession(callSession);
165
165
  logger.info('WebRTC phone - send reinvite', {
166
- sessionId: sipSession ? sipSession.id : null,
166
+ sessionId: getSipCallId(sipSession),
167
167
  constraints,
168
168
  audioOnly,
169
169
  conference,
@@ -384,7 +384,9 @@ export default class WebRTCPhone extends Emitter implements Phone {
384
384
  const elsewhere = message.data.indexOf('cause=26') !== -1 && message.data.indexOf('completed elsewhere') !== -1;
385
385
  const callSession = this._createCallSession(sipSession);
386
386
 
387
- delete this.callSessions[sipSessionId];
387
+ if (sipSessionId) {
388
+ delete this.callSessions[sipSessionId];
389
+ }
388
390
  this.eventEmitter.emit(ON_CALL_CANCELED, callSession, elsewhere);
389
391
  };
390
392
  }
@@ -393,7 +395,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
393
395
  switch (newState) {
394
396
  case SessionState.Terminating:
395
397
  logger.info('WebRTC phone - call terminating', {
396
- sipId: sipSession.id,
398
+ sipId: getSipCallId(sipSession),
397
399
  });
398
400
  this.eventEmitter.emit(ON_CALL_ENDING, this._createCallSession(sipSession));
399
401
  break;
@@ -401,7 +403,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
401
403
  case SessionState.Terminated:
402
404
  {
403
405
  logger.info('WebRTC phone - call terminated', {
404
- sipId: sipSession.id,
406
+ sipId: getSipCallId(sipSession),
405
407
  });
406
408
 
407
409
  // Should be called before `_onCallTerminated` or the callCount will not decrement...
@@ -584,7 +586,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
584
586
 
585
587
  _onCallAccepted(sipSession: WazoSession, cameraEnabled: boolean): CallSession {
586
588
  logger.info('WebRTC phone - on call accepted', {
587
- sipId: sipSession.id,
589
+ sipId: getSipCallId(sipSession),
588
590
  cameraEnabled,
589
591
  });
590
592
 
@@ -592,7 +594,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
592
594
 
593
595
  if (this.currentSipSession && !this.isCurrentCallSipSession(callSession)) {
594
596
  logger.info('WebRTC phone - on call accepted with another ongoing call, holding it', {
595
- sipId: sipSession.id,
597
+ sipId: getSipCallId(sipSession),
596
598
  cameraEnabled,
597
599
  });
598
600
 
@@ -677,7 +679,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
677
679
  const sipSessionId = getSipCallId(sipSession);
678
680
 
679
681
  logger.info('WebRTC phone - on call terminated', {
680
- sipId: sipSession.id,
682
+ sipId: getSipCallId(sipSession),
681
683
  sipSessionId,
682
684
  ids: Object.keys(this.callSessions),
683
685
  });
@@ -701,9 +703,9 @@ export default class WebRTCPhone extends Emitter implements Phone {
701
703
 
702
704
  if (sipSessionId) {
703
705
  this.removeIncomingSessions(sipSessionId);
704
- }
705
706
 
706
- delete this.callSessions[sipSessionId];
707
+ delete this.callSessions[sipSessionId];
708
+ }
707
709
 
708
710
  if (isCurrentSession) {
709
711
  this.currentSipSession = undefined;
@@ -713,7 +715,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
713
715
  const hasIncomingCallSession = this.hasIncomingCallSession();
714
716
  // Re-trigger incoming call event for remaining incoming calls
715
717
  logger.info('WebRTC phone - check to re-trigger incoming call', {
716
- sipId: sipSession.id,
718
+ sipId: getSipCallId(sipSession),
717
719
  shouldRetrigger,
718
720
  hasIncomingCallSession,
719
721
  });
@@ -857,7 +859,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
857
859
  const sipSession = this.client.getSipSession(callSession.getId()) as Invitation;
858
860
 
859
861
  if (sipSession) {
860
- logger.info('accept call, session found', { sipId: sipSession.id });
862
+ logger.info('accept call, session found', { sipId: getSipCallId(sipSession) });
861
863
 
862
864
  return this.client.answer(sipSession, this.allowVideo ? cameraEnabled : false).then(() => {
863
865
  return callSession.sipCallId;
@@ -902,7 +904,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
902
904
 
903
905
  if (sipSession) {
904
906
  logger.info('WebRTC rejecting', {
905
- sipId: sipSession.id,
907
+ sipId: getSipCallId(sipSession),
906
908
  });
907
909
  this.client.hangup(sipSession);
908
910
  }
@@ -923,7 +925,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
923
925
 
924
926
  if (sipSession) {
925
927
  logger.info('WebRTC atxfer', {
926
- sipId: sipSession.id,
928
+ sipId: getSipCallId(sipSession),
927
929
  });
928
930
  return this.client.atxfer(sipSession);
929
931
  }
@@ -954,13 +956,13 @@ export default class WebRTCPhone extends Emitter implements Phone {
954
956
  }
955
957
 
956
958
  logger.info('WebRTC resuming', {
957
- sipId: sipSession.id,
959
+ sipId: getSipCallId(sipSession),
958
960
  });
959
961
 
960
962
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
961
- if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
963
+ if (this.currentSipSession && getSipCallId(this.currentSipSession) !== getSipCallId(sipSession)) {
962
964
  logger.info('WebRTC hold call after resume', {
963
- id: this.currentSipSession.id,
965
+ id: getSipCallId(this.currentSipSession),
964
966
  });
965
967
  this.holdSipSession(this.currentSipSession, this.currentCallSession, withEvent);
966
968
  }
@@ -983,7 +985,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
983
985
  const sessionId = getSipCallId(sipSession);
984
986
  const hasVideo = this.client.hasLocalVideo(sessionId);
985
987
  logger.info('WebRTC hold sip session', {
986
- sipId: sipSession.id,
988
+ sipId: getSipCallId(sipSession),
987
989
  hasVideo,
988
990
  });
989
991
 
@@ -1080,7 +1082,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1080
1082
  }
1081
1083
 
1082
1084
  logger.info('WebRTC muting', {
1083
- sipId: sipSession.id,
1085
+ sipId: getSipCallId(sipSession),
1084
1086
  });
1085
1087
  this.client.mute(sipSession);
1086
1088
 
@@ -1108,7 +1110,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1108
1110
  }
1109
1111
 
1110
1112
  logger.info('WebRTC unmuting', {
1111
- sipId: sipSession.id,
1113
+ sipId: getSipCallId(sipSession),
1112
1114
  });
1113
1115
  this.client.unmute(sipSession);
1114
1116
 
@@ -1143,7 +1145,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1143
1145
  }
1144
1146
 
1145
1147
  logger.info('WebRTC turn camera on', {
1146
- sipId: sipSession.id,
1148
+ sipId: getSipCallId(sipSession),
1147
1149
  });
1148
1150
  this.client.toggleCameraOn(sipSession);
1149
1151
  this.eventEmitter.emit(ON_CAMERA_RESUMED, this._createCameraResumedCallSession(sipSession, callSession));
@@ -1157,7 +1159,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1157
1159
  }
1158
1160
 
1159
1161
  logger.info('WebRTC turn camera off', {
1160
- sipId: sipSession.id,
1162
+ sipId: getSipCallId(sipSession),
1161
1163
  });
1162
1164
  this.client.toggleCameraOff(sipSession);
1163
1165
  this.eventEmitter.emit(ON_CAMERA_DISABLED, this._createCameraDisabledCallSession(sipSession, callSession));
@@ -1171,7 +1173,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1171
1173
  }
1172
1174
 
1173
1175
  logger.info('WebRTC send key', {
1174
- sipId: sipSession.id,
1176
+ sipId: getSipCallId(sipSession),
1175
1177
  tone,
1176
1178
  });
1177
1179
  this.client.sendDTMF(sipSession, tone);
@@ -1249,7 +1251,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1249
1251
  }
1250
1252
 
1251
1253
  logger.info('WebRTC transfer', {
1252
- sipId: sipSession.id,
1254
+ sipId: getSipCallId(sipSession),
1253
1255
  target,
1254
1256
  });
1255
1257
  this.client.transfer(sipSession, target);
@@ -1259,8 +1261,8 @@ export default class WebRTCPhone extends Emitter implements Phone {
1259
1261
  const sipSession = this.client.getSipSession(source.sipCallId);
1260
1262
  const sipSessionTarget = this.client.getSipSession(destination.sipCallId);
1261
1263
  logger.info('WebRTC indirect transfer', {
1262
- sipId: sipSession ? sipSession.id : null,
1263
- target: sipSessionTarget ? sipSessionTarget.id : null,
1264
+ sipId: sipSession ? getSipCallId(sipSession) : null,
1265
+ target: sipSessionTarget ? getSipCallId(sipSessionTarget) : null,
1264
1266
  });
1265
1267
 
1266
1268
  if (!sipSessionTarget) {
@@ -1299,7 +1301,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1299
1301
  const sipSessionId = getSipCallId(sipSession);
1300
1302
 
1301
1303
  logger.info('WebRTC hangup', {
1302
- sipId: sipSession.id,
1304
+ sipId: getSipCallId(sipSession),
1303
1305
  sipSessionId,
1304
1306
  });
1305
1307
  await this.client.hangup(sipSession);
@@ -1488,7 +1490,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1488
1490
  const autoAnswer = sipSession.request.getHeader('Answer-Mode') === 'Auto';
1489
1491
  const withVideo = this.allowVideo ? wantsToDoVideo : false;
1490
1492
  logger.info('WebRTC invite received', {
1491
- sipId: sipSession.id,
1493
+ sipId: getSipCallId(sipSession),
1492
1494
  withVideo,
1493
1495
  autoAnswer,
1494
1496
  });
@@ -1559,7 +1561,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1559
1561
  this.eventEmitter.emit(ON_CALL_ERROR, e);
1560
1562
  });
1561
1563
  this.client.on(this.client.REJECTED, session => {
1562
- logger.info('WebRTC call rejected', session.id);
1564
+ logger.info('WebRTC call rejected', { id: getSipCallId(session) });
1563
1565
 
1564
1566
  const callSession = this._createCallSession(session);
1565
1567
 
@@ -167,6 +167,10 @@ export class Auth {
167
167
  return this._onAuthenticated(rawSession as Session);
168
168
  }
169
169
 
170
+ async samlLogOut(): Promise<void | { location: string }> {
171
+ return await this.logout(false, true);
172
+ }
173
+
170
174
  async initiateIdpAuthentication(domain: string, redirectUrl: string): Promise<{ location: string, saml_session_id: string } | undefined> {
171
175
  try {
172
176
  return await getApiClient().auth.initiateIdpAuthentication(domain, redirectUrl);
@@ -218,20 +222,26 @@ export class Auth {
218
222
  return getApiClient().auth.refreshToken(refreshToken, '', this.expiration);
219
223
  }
220
224
 
221
- async logout(deleteRefreshToken = true): Promise<void> {
225
+ async logout(deleteRefreshToken = true, saml = false): Promise<void | { location: string }> {
222
226
  try {
223
227
  Wazo.Websocket.close(true);
224
228
 
225
- if (this.clientId && deleteRefreshToken) {
229
+ if (!saml && this.clientId && deleteRefreshToken) {
226
230
  await getApiClient().auth.deleteRefreshToken(this.clientId);
227
231
  }
228
232
  } catch (e: any) {
229
233
  // Nothing to
230
234
  }
231
235
 
236
+ let response;
237
+
232
238
  try {
233
239
  if (this.session?.token) {
234
- await getApiClient().auth.logOut(this.session.token);
240
+ if (saml) {
241
+ response = await getApiClient().auth.samlLogOut();
242
+ } else {
243
+ await getApiClient().auth.logOut(this.session.token);
244
+ }
235
245
  }
236
246
  } catch (e: any) {
237
247
  // Nothing to
@@ -243,6 +253,8 @@ export class Auth {
243
253
  this.authenticated = false;
244
254
  this.usingEdgeServer = undefined;
245
255
  setFetchOptions({});
256
+
257
+ return response;
246
258
  }
247
259
 
248
260
  setOnHostFromHeaders(callback: (hostFromHeaders: string) => void) {
@@ -6,7 +6,7 @@ import type CallSession from '../domain/CallSession';
6
6
  import AdHocAPIConference from '../domain/AdHocAPIConference';
7
7
  import WebRTCPhone, * as PHONE_EVENTS from '../domain/Phone/WebRTCPhone';
8
8
  import { MESSAGE_TYPE_CHAT, MESSAGE_TYPE_SIGNAL } from '../domain/Phone/WebRTCPhone';
9
- import WazoWebRTCClient, { events as clientEvents, transportEvents } from '../web-rtc-client';
9
+ import WebRTCClient, { events as clientEvents, transportEvents } from '../web-rtc-client';
10
10
  import IssueReporter from '../service/IssueReporter';
11
11
  import Emitter from '../utils/Emitter';
12
12
  import Wazo from './index';
@@ -21,7 +21,7 @@ const protocolDebugMessages = ['Received WebSocket text message:', 'Sending WebS
21
21
 
22
22
  // @deprecated: Use Wazo.Voice.Softphone instead
23
23
  export class Phone extends Emitter {
24
- client: WazoWebRTCClient;
24
+ client: WebRTCClient;
25
25
 
26
26
  phone: WebRTCPhone | null | undefined;
27
27
 
@@ -188,7 +188,7 @@ export class Phone extends Emitter {
188
188
  options.log.connector = this._logConnector;
189
189
  }
190
190
 
191
- this.client = new WazoWebRTCClient({
191
+ this.client = new WebRTCClient({
192
192
  host,
193
193
  port: typeof port === 'string' ? parseInt(port, 10) : port,
194
194
  displayName,
@@ -12,7 +12,6 @@ export const Actions = {
12
12
  REGISTER: 'register',
13
13
  REGISTER_DONE: 'registerDone',
14
14
  UNREGISTER: 'unregister',
15
- UNREGISTERED: 'unregistered',
16
15
  TRANSPORT_CLOSED: 'transportClosed',
17
16
  } as const;
18
17
 
@@ -32,7 +31,7 @@ const softphoneMachine = setup({}).createMachine({
32
31
  on: {
33
32
  [Actions.REGISTER_DONE]: States.REGISTERED,
34
33
  [Actions.TRANSPORT_CLOSED]: States.UNREGISTERED,
35
- [Actions.UNREGISTERED]: States.UNREGISTERED,
34
+ [Actions.UNREGISTER]: States.UNREGISTERED,
36
35
  },
37
36
  },
38
37
  [States.REGISTERED]: {
package/src/utils/sdp.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable no-underscore-dangle */
2
2
  import sdpParser from 'sdp-transform';
3
3
  import { UserAgent } from 'sip.js/lib/api/user-agent';
4
- import { Inviter } from 'sip.js/lib/api';
4
+ import { Inviter, Invitation } from 'sip.js/lib/api';
5
5
  import { URI } from 'sip.js/lib/grammar/uri';
6
6
 
7
7
  import type { SipCall } from '../domain/types';
@@ -152,20 +152,21 @@ export const getSipCallId = (sipSession: SipCall | null | undefined): string =>
152
152
  return '';
153
153
  }
154
154
 
155
- const message = sipSession.message as Partial<{ callId?: string }>;
156
- if (message?.callId) {
157
- return message.callId.substring(0, SIP_ID_MIN_LENGTH);
158
- }
159
-
160
155
  // For Inviter
161
156
  // @ts-ignore: private
162
157
  if (sipSession instanceof Inviter && sipSession.outgoingRequestMessage) {
163
158
  // @ts-ignore: private
164
- return sipSession.outgoingRequestMessage.callId.substring(0, SIP_ID_MIN_LENGTH);
159
+ return sipSession.outgoingRequestMessage.callId;
165
160
  }
166
161
 
167
162
  // For Invitation
168
- return (sipSession.id || '').substring(0, SIP_ID_MIN_LENGTH);
163
+ // @ts-ignore: private
164
+ if (sipSession instanceof Invitation && sipSession.incomingInviteRequest.message) {
165
+ // @ts-ignore: private
166
+ return sipSession.incomingInviteRequest.message.callId;
167
+ }
168
+
169
+ return sipSession.id;
169
170
  };
170
171
 
171
172
  // We need to replace 0.0.0.0 to 127.0.0.1 in the sdp to avoid MOH during a createOffer.
package/src/voice/call.ts CHANGED
@@ -116,7 +116,6 @@ class Call extends EventEmitter {
116
116
  } as any;
117
117
 
118
118
  const call = new Call(sipCall, softphone);
119
- // call._sendAction(Actions.ES);
120
119
  call.apiId = apiCall.id;
121
120
  call.answerTime = new Date(+apiCall.startingTime);
122
121
 
@@ -158,8 +157,6 @@ class Call extends EventEmitter {
158
157
 
159
158
  this.number = getCallNumber(sipCall);
160
159
  this.displayName = getCallDisplayName(sipCall);
161
-
162
- this._bindEvents();
163
160
  }
164
161
 
165
162
  async accept(options: AcceptOptions = {}): Promise<string | null> {
@@ -551,6 +548,8 @@ class Call extends EventEmitter {
551
548
  }
552
549
 
553
550
  onMakeCall() {
551
+ this._bindEvents();
552
+
554
553
  this._sendAction(Actions.MAKE_CALL);
555
554
  }
556
555
 
@@ -820,7 +819,9 @@ class Call extends EventEmitter {
820
819
  }
821
820
 
822
821
  private _sendAction(action: ActionTypes | EstablishedActionTypes) {
822
+ const was = this.state;
823
823
  this.callActor.send({ type: action });
824
+ logger.trace('call - send action', { action, was, state: this.state });
824
825
  }
825
826
  }
826
827
 
@@ -93,6 +93,8 @@ export class Softphone extends EventEmitter {
93
93
  const server = Wazo.Auth.getHost();
94
94
  const session = Wazo.Auth.getSession();
95
95
 
96
+ logger.info('softphone - connect', { server, session: !!session });
97
+
96
98
  if (!server || !session) {
97
99
  throw new Error('Please connect to the server using `Wazo.Auth.logIn` or `Wazo.Auth.authenticate` before using Room.connect().');
98
100
  }
@@ -116,6 +118,7 @@ export class Softphone extends EventEmitter {
116
118
  async disconnect() {
117
119
  assertCan(this.softphoneActor, Actions.UNREGISTER);
118
120
  if (!this.client) {
121
+ logger.info('softphone - disconnect, not client to disconnect, bailing');
119
122
  return null;
120
123
  }
121
124
 
@@ -137,7 +140,9 @@ export class Softphone extends EventEmitter {
137
140
  ): Promise<void> {
138
141
  assertCan(this.softphoneActor, Actions.REGISTER);
139
142
 
140
- this.softphoneActor.send({ type: Actions.REGISTER });
143
+ logger.info('softphone - connect with credentials', { server, username: sipLine.username, displayName, options: rawOptions });
144
+
145
+ this._sendAction(Actions.REGISTER);
141
146
 
142
147
  const [host, port = 443] = server.split(':');
143
148
  let options = { ...rawOptions };
@@ -291,7 +296,7 @@ export class Softphone extends EventEmitter {
291
296
  }
292
297
 
293
298
  startHeartbeat() {
294
- logger.info('softphone - start heartbeat', { client: !!this.client, hasHeartbeat: this.client.hasHeartbeat() });
299
+ logger.info('softphone - start heartbeat', { client: !!this.client, hasHeartbeat: this.client?.hasHeartbeat() });
295
300
  if (!this.client || this.client.hasHeartbeat()) {
296
301
  return;
297
302
  }
@@ -456,22 +461,32 @@ export class Softphone extends EventEmitter {
456
461
 
457
462
  this.client.on(this.client.UNREGISTERED, () => {
458
463
  logger.info('softphone - unregistered');
459
- this.emit(EVENT_UNREGISTERED);
464
+ if (!can(this.softphoneActor, Actions.UNREGISTER)) {
465
+ logger.warn('softphone - cannot unregister', { state: this.state });
466
+ return;
467
+ }
468
+
469
+ this._sendAction(Actions.UNREGISTER);
460
470
 
461
- this._sendAction(Actions.UNREGISTERED);
471
+ this.emit(EVENT_UNREGISTERED);
462
472
  });
463
473
 
464
474
  this.client.on(this.client.ON_DISCONNECTED, () => {
465
475
  logger.info('softphone - disconnected');
466
- this.emit(EVENT_DISCONNECTED);
476
+ if (!can(this.softphoneActor, Actions.TRANSPORT_CLOSED)) {
477
+ logger.warn('softphone - cannot disconnected', { state: this.state });
478
+ return;
479
+ }
467
480
 
468
481
  this._sendAction(Actions.TRANSPORT_CLOSED);
482
+
483
+ this.emit(EVENT_DISCONNECTED);
469
484
  });
470
485
 
471
486
  this.client.on(this.client.REGISTERED, () => {
472
487
  logger.info('softphone - registered', { state: getState(this.softphoneActor) });
473
488
  if (!can(this.softphoneActor, Actions.REGISTER_DONE)) {
474
- logger.warn('softphone - registered but not in REGISTERING state', { state: getState(this.softphoneActor) });
489
+ logger.warn('softphone - registered but not in REGISTERING state', { state: this.state });
475
490
  return;
476
491
  }
477
492
 
@@ -492,10 +507,16 @@ export class Softphone extends EventEmitter {
492
507
  });
493
508
 
494
509
  this.client.on(this.client.CONNECTED, () => {
495
- logger.info('softphone - connected');
510
+ logger.info('softphone - connected', { state: this.state });
496
511
  this.stopHeartbeat();
497
512
  });
498
513
 
514
+ this.client.on(this.client.REGISTERING, () => {
515
+ logger.info('softphone - registering', { state: this.state });
516
+
517
+ this._sendAction(Actions.REGISTER);
518
+ });
519
+
499
520
  this.client.on(this.client.DISCONNECTED, () => {
500
521
  logger.info('softphone - disconnected');
501
522
  this.emit(EVENT_DISCONNECTED);
@@ -529,7 +550,9 @@ export class Softphone extends EventEmitter {
529
550
  }
530
551
 
531
552
  private _sendAction(action: ActionTypes) {
553
+ const was = this.state;
532
554
  this.softphoneActor.send({ type: action });
555
+ logger.trace('softphone - send action', { action, was, state: this.state });
533
556
  }
534
557
 
535
558
  private _getCall(sipCall: SipCall): Call | undefined {