@wazo/sdk 0.40.9 → 0.41.1

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 (123) hide show
  1. package/dist/wazo-sdk.js +526 -598
  2. package/esm/__tests__/api-client.test.js +0 -1
  3. package/esm/domain/Phone/WebRTCPhone.js +6 -5
  4. package/esm/domain/__tests__/Session.test.js +1 -5
  5. package/esm/domain/types.js +2 -1
  6. package/esm/index.js +1 -0
  7. package/esm/service/IssueReporter.js +1 -2
  8. package/esm/service/__tests__/IssueReporter.test.js +4 -7
  9. package/esm/simple/Auth.js +16 -2
  10. package/esm/simple/Configuration.js +5 -4
  11. package/esm/simple/Directory.js +2 -1
  12. package/esm/simple/Phone.js +2 -1
  13. package/esm/simple/Websocket.js +2 -1
  14. package/esm/simple/__tests__/Auth.test.js +111 -0
  15. package/esm/simple/index.js +1 -0
  16. package/esm/simple/room/Participant.js +1 -0
  17. package/esm/simple/room/Room.js +2 -1
  18. package/esm/types/domain/Phone/WebRTCPhone.d.ts +1 -1
  19. package/esm/types/domain/Phone/WebRTCPhone.d.ts.map +1 -1
  20. package/esm/types/domain/types.d.ts +80 -0
  21. package/esm/types/domain/types.d.ts.map +1 -1
  22. package/esm/types/index.d.ts +1 -0
  23. package/esm/types/index.d.ts.map +1 -1
  24. package/esm/types/service/IssueReporter.d.ts.map +1 -1
  25. package/esm/types/simple/Auth.d.ts +51 -1
  26. package/esm/types/simple/Auth.d.ts.map +1 -1
  27. package/esm/types/simple/Configuration.d.ts +5 -1
  28. package/esm/types/simple/Configuration.d.ts.map +1 -1
  29. package/esm/types/simple/Directory.d.ts +5 -1
  30. package/esm/types/simple/Directory.d.ts.map +1 -1
  31. package/esm/types/simple/Phone.d.ts +117 -1
  32. package/esm/types/simple/Phone.d.ts.map +1 -1
  33. package/esm/types/simple/Websocket.d.ts +19 -1
  34. package/esm/types/simple/Websocket.d.ts.map +1 -1
  35. package/esm/types/simple/__tests__/Auth.test.d.ts +2 -0
  36. package/esm/types/simple/__tests__/Auth.test.d.ts.map +1 -0
  37. package/esm/types/simple/index.d.ts +5 -5
  38. package/esm/types/simple/index.d.ts.map +1 -1
  39. package/esm/types/simple/room/Participant.d.ts.map +1 -1
  40. package/esm/types/simple/room/Room.d.ts +11 -11
  41. package/esm/types/simple/room/Room.d.ts.map +1 -1
  42. package/esm/types/simple/room/SipRoom.d.ts +1 -1
  43. package/esm/types/utils/api-requester.d.ts +0 -1
  44. package/esm/types/utils/api-requester.d.ts.map +1 -1
  45. package/esm/types/web-rtc-client.d.ts +1 -1
  46. package/esm/types/web-rtc-client.d.ts.map +1 -1
  47. package/esm/types/websocket-client.d.ts +6 -6
  48. package/esm/types/websocket-client.d.ts.map +1 -1
  49. package/esm/utils/__tests__/api-requester.test.js +0 -2
  50. package/esm/utils/api-requester.js +2 -31
  51. package/esm/web-rtc-client.js +3 -1
  52. package/lib/__tests__/api-client.test.js +0 -1
  53. package/lib/domain/Phone/WebRTCPhone.js +6 -5
  54. package/lib/domain/__tests__/Session.test.js +1 -5
  55. package/lib/domain/types.js +36 -0
  56. package/lib/index.js +3 -0
  57. package/lib/service/IssueReporter.js +1 -2
  58. package/lib/service/__tests__/IssueReporter.test.js +4 -7
  59. package/lib/simple/Auth.js +16 -2
  60. package/lib/simple/Configuration.js +6 -3
  61. package/lib/simple/Directory.js +3 -0
  62. package/lib/simple/Phone.js +3 -0
  63. package/lib/simple/Websocket.js +3 -0
  64. package/lib/simple/__tests__/Auth.test.js +145 -0
  65. package/lib/simple/index.js +1 -0
  66. package/lib/simple/room/Participant.js +1 -0
  67. package/lib/simple/room/Room.js +2 -1
  68. package/lib/types/domain/Phone/WebRTCPhone.d.ts +1 -1
  69. package/lib/types/domain/Phone/WebRTCPhone.d.ts.map +1 -1
  70. package/lib/types/domain/types.d.ts +80 -0
  71. package/lib/types/domain/types.d.ts.map +1 -1
  72. package/lib/types/index.d.ts +1 -0
  73. package/lib/types/index.d.ts.map +1 -1
  74. package/lib/types/service/IssueReporter.d.ts.map +1 -1
  75. package/lib/types/simple/Auth.d.ts +51 -1
  76. package/lib/types/simple/Auth.d.ts.map +1 -1
  77. package/lib/types/simple/Configuration.d.ts +5 -1
  78. package/lib/types/simple/Configuration.d.ts.map +1 -1
  79. package/lib/types/simple/Directory.d.ts +5 -1
  80. package/lib/types/simple/Directory.d.ts.map +1 -1
  81. package/lib/types/simple/Phone.d.ts +117 -1
  82. package/lib/types/simple/Phone.d.ts.map +1 -1
  83. package/lib/types/simple/Websocket.d.ts +19 -1
  84. package/lib/types/simple/Websocket.d.ts.map +1 -1
  85. package/lib/types/simple/__tests__/Auth.test.d.ts +2 -0
  86. package/lib/types/simple/__tests__/Auth.test.d.ts.map +1 -0
  87. package/lib/types/simple/index.d.ts +5 -5
  88. package/lib/types/simple/index.d.ts.map +1 -1
  89. package/lib/types/simple/room/Participant.d.ts.map +1 -1
  90. package/lib/types/simple/room/Room.d.ts +11 -11
  91. package/lib/types/simple/room/Room.d.ts.map +1 -1
  92. package/lib/types/simple/room/SipRoom.d.ts +1 -1
  93. package/lib/types/utils/api-requester.d.ts +0 -1
  94. package/lib/types/utils/api-requester.d.ts.map +1 -1
  95. package/lib/types/web-rtc-client.d.ts +1 -1
  96. package/lib/types/web-rtc-client.d.ts.map +1 -1
  97. package/lib/types/websocket-client.d.ts +6 -6
  98. package/lib/types/websocket-client.d.ts.map +1 -1
  99. package/lib/utils/__tests__/api-requester.test.js +0 -2
  100. package/lib/utils/api-requester.js +2 -33
  101. package/lib/web-rtc-client.js +3 -1
  102. package/package.json +2 -7
  103. package/src/__tests__/api-client.test.ts +0 -1
  104. package/src/domain/Phone/WebRTCPhone.ts +9 -8
  105. package/src/domain/__tests__/Session.test.ts +1 -6
  106. package/src/domain/types.ts +9 -0
  107. package/src/index.ts +1 -0
  108. package/src/service/IssueReporter.ts +1 -2
  109. package/src/service/__tests__/IssueReporter.test.ts +4 -7
  110. package/src/simple/Auth.ts +25 -7
  111. package/src/simple/Configuration.ts +5 -4
  112. package/src/simple/Directory.ts +2 -1
  113. package/src/simple/Phone.ts +2 -1
  114. package/src/simple/Websocket.ts +4 -2
  115. package/src/simple/__tests__/Auth.test.ts +123 -0
  116. package/src/simple/index.ts +1 -0
  117. package/src/simple/room/Participant.ts +3 -1
  118. package/src/simple/room/Room.ts +4 -3
  119. package/src/types/global.d.ts +11 -5
  120. package/src/utils/__tests__/api-requester.test.ts +0 -3
  121. package/src/utils/api-requester.ts +2 -33
  122. package/src/web-rtc-client.ts +3 -1
  123. package/src/websocket-client.ts +1 -1
@@ -0,0 +1,123 @@
1
+ import getApiClient, { setRefreshToken } from '../../service/getApiClient';
2
+ import { Auth as AuthClass } from '../Auth';
3
+
4
+ const Auth = new AuthClass();
5
+ const TOKEN = 'some-token';
6
+ const REFRESH_TOKEN = 'some-refresh-token';
7
+ const USER_UUID = 'some-user-uuid';
8
+
9
+ jest.mock('../../service/getApiClient');
10
+
11
+ describe('simple/Auth', () => {
12
+ beforeEach(() => {
13
+ const authenticate = jest.fn();
14
+ (getApiClient as any).mockImplementation(() => ({
15
+ auth: {
16
+ authenticate,
17
+ },
18
+ }));
19
+ });
20
+
21
+ afterEach(() => {
22
+ jest.restoreAllMocks();
23
+ });
24
+
25
+ describe('validateToken', () => {
26
+ it('should return undefined if nullish', async () => {
27
+ // @ts-expect-error
28
+ const result = await Auth.validateToken(null);
29
+ expect(result).toEqual(undefined);
30
+ });
31
+
32
+ it('should set refresh token if provided', async () => {
33
+ await Auth.validateToken(TOKEN, REFRESH_TOKEN);
34
+ expect(setRefreshToken).toHaveBeenCalledWith(REFRESH_TOKEN);
35
+ });
36
+
37
+ it('should set user uuid header when using edge server', async () => {
38
+ Auth.usingEdgeServer = true;
39
+ const setHttpUserUuidHeader = jest.spyOn(Auth, 'setHttpUserUuidHeader');
40
+ await Auth.validateToken(TOKEN, undefined, USER_UUID);
41
+ expect(setHttpUserUuidHeader).toHaveBeenCalledWith(USER_UUID);
42
+ });
43
+
44
+ it('should NOT set user uuid header when NOT using edge server', async () => {
45
+ Auth.usingEdgeServer = false;
46
+ const setHttpUserUuidHeader = jest.spyOn(Auth, 'setHttpUserUuidHeader');
47
+ await Auth.validateToken(TOKEN, undefined, USER_UUID);
48
+ expect(setHttpUserUuidHeader).not.toHaveBeenCalled();
49
+ });
50
+ });
51
+ describe('checkHttpUserUuidHeader', () => {
52
+ it('should return undefined if UUID is null', async () => {
53
+ const result = await Auth.checkHttpUserUuidHeader(null);
54
+ expect(result).toEqual(undefined);
55
+ });
56
+
57
+ it('should set user UUID header on successful HEAD call', async () => {
58
+ const head = jest.fn(() => Promise.resolve({ headers: { get: () => null } }));
59
+ const setHttpUserUuidHeader = jest.spyOn(Auth, 'setHttpUserUuidHeader');
60
+ Auth.onSetUsingEdgeServer = jest.fn();
61
+ (getApiClient as any).mockImplementation(() => ({
62
+ client: {
63
+ head,
64
+ },
65
+ }));
66
+ await Auth.checkHttpUserUuidHeader(USER_UUID);
67
+ expect(head).toHaveBeenCalled();
68
+ expect(setHttpUserUuidHeader).toHaveBeenCalledWith(USER_UUID);
69
+ expect(Auth.usingEdgeServer).toEqual(true);
70
+ expect(Auth.onSetUsingEdgeServer).toHaveBeenCalledWith(true);
71
+ });
72
+
73
+ it('should NOT set user UUID header on failed HEAD call', async () => {
74
+ const head = jest.fn(() => Promise.reject());
75
+ const setHttpUserUuidHeader = jest.spyOn(Auth, 'setHttpUserUuidHeader');
76
+ Auth.onSetUsingEdgeServer = jest.fn();
77
+ (getApiClient as any).mockImplementation(() => ({
78
+ client: {
79
+ head,
80
+ },
81
+ }));
82
+ await Auth.checkHttpUserUuidHeader(USER_UUID);
83
+ expect(head).toHaveBeenCalled();
84
+ expect(setHttpUserUuidHeader).not.toHaveBeenCalled();
85
+ expect(Auth.usingEdgeServer).toEqual(false);
86
+ expect(Auth.onSetUsingEdgeServer).toHaveBeenCalledWith(false);
87
+ });
88
+
89
+ it('should set user UUID header on mobile when header is present', async () => {
90
+ Auth.mobile = true;
91
+ const head = jest.fn(() => Promise.resolve({ headers: { get: () => 'X-User-UUID: something' } }));
92
+ const setHttpUserUuidHeader = jest.spyOn(Auth, 'setHttpUserUuidHeader');
93
+ Auth.onSetUsingEdgeServer = jest.fn();
94
+ (getApiClient as any).mockImplementation(() => ({
95
+ client: {
96
+ head,
97
+ },
98
+ }));
99
+ await Auth.checkHttpUserUuidHeader(USER_UUID);
100
+ expect(head).toHaveBeenCalled();
101
+ expect(setHttpUserUuidHeader).toHaveBeenCalledWith(USER_UUID);
102
+ expect(Auth.usingEdgeServer).toEqual(true);
103
+ expect(Auth.onSetUsingEdgeServer).toHaveBeenCalledWith(true);
104
+ });
105
+
106
+ it('should NOT set user UUID header on mobile when header is NOT present', async () => {
107
+ Auth.mobile = true;
108
+ const head = jest.fn(() => Promise.resolve({ headers: { get: () => 'something' } }));
109
+ const setHttpUserUuidHeader = jest.spyOn(Auth, 'setHttpUserUuidHeader');
110
+ Auth.onSetUsingEdgeServer = jest.fn();
111
+ (getApiClient as any).mockImplementation(() => ({
112
+ client: {
113
+ head,
114
+ },
115
+ }));
116
+ await Auth.checkHttpUserUuidHeader(USER_UUID);
117
+ expect(head).toHaveBeenCalled();
118
+ expect(setHttpUserUuidHeader).not.toHaveBeenCalled();
119
+ expect(Auth.usingEdgeServer).toEqual(false);
120
+ expect(Auth.onSetUsingEdgeServer).toHaveBeenCalledWith(false);
121
+ });
122
+ });
123
+ });
@@ -1,3 +1,4 @@
1
+ /* eslint-disable import/no-named-as-default */
1
2
  /* global window */
2
3
  import Auth, { InvalidSubscription, InvalidAuthorization, NoTenantIdError, NoDomainNameError } from './Auth';
3
4
  import Phone from './Phone';
@@ -1,10 +1,12 @@
1
1
  import Emitter from '../../utils/Emitter';
2
2
  import IssueReporter from '../../service/IssueReporter';
3
+ // eslint-disable-next-line import/no-named-as-default
3
4
  import Phone from '../Phone';
4
5
  import Room, { SIGNAL_TYPE_PARTICIPANT_UPDATE } from './Room';
5
6
  import Contact from '../../domain/Contact';
6
7
  import getApiClient from '../../service/getApiClient';
7
8
  import Stream from './Stream';
9
+ import type CallSession from '../../domain/CallSession';
8
10
 
9
11
  const logger = IssueReporter.loggerFor('room');
10
12
 
@@ -362,7 +364,7 @@ class Participant extends Emitter {
362
364
 
363
365
  if (sendReinvite && !this.streams.length && Phone.phone) {
364
366
  // eslint-disable-next-line no-underscore-dangle
365
- Phone.phone._sendReinviteMessage(this.room?.callSession, false);
367
+ Phone.phone._sendReinviteMessage(this.room?.callSession as CallSession, false);
366
368
  }
367
369
 
368
370
  this.room?.sendSignal({
@@ -25,7 +25,7 @@ type ConnectArgs = {
25
25
  };
26
26
 
27
27
  class Room extends Emitter {
28
- callSession: CallSession | null | undefined;
28
+ callSession?: CallSession;
29
29
 
30
30
  name: string;
31
31
 
@@ -189,6 +189,7 @@ class Room extends Emitter {
189
189
 
190
190
  if (!room) {
191
191
  await Wazo.Phone.connect({
192
+ // @ts-ignore: Property 'audio' is missing
192
193
  media: constraints,
193
194
  });
194
195
  const withCamera = constraints && !!constraints.video;
@@ -260,7 +261,7 @@ class Room extends Emitter {
260
261
  async disconnect() {
261
262
  logger.info('disconnection to room called');
262
263
  await Wazo.Phone.hangup(this.callSession as CallSession);
263
- this.callSession = null;
264
+ this.callSession = undefined;
264
265
  this.eventEmitter.emit(this.ON_DISCONNECTED, this);
265
266
  this.connected = false;
266
267
  this.unbind();
@@ -497,7 +498,7 @@ class Room extends Emitter {
497
498
 
498
499
  if (!this.roomAudioElement) {
499
500
  const sessionId = Wazo.Phone.phone?.getSipSessionId(Wazo.Phone.phone?.currentSipSession as WazoSession);
500
- this.roomAudioElement = Wazo.Phone.phone?.createAudioElementFor(sessionId as string);
501
+ this.roomAudioElement = Wazo.Phone.phone?.createAudioElementFor(sessionId as string) as HTMLAudioElement;
501
502
  this.roomAudioElement.srcObject = stream;
502
503
  } else {
503
504
  this.roomAudioElement.srcObject = stream;
@@ -1,6 +1,12 @@
1
1
  /* eslint-disable vars-on-top */
2
2
  /* eslint-disable no-var */
3
3
 
4
+ import { WebsocketType } from '../domain/types';
5
+ import { Auth } from '../simple/Auth';
6
+ import { Configuration } from '../simple/Configuration';
7
+ import { Directory } from '../simple/Directory';
8
+ import { Phone } from '../simple/Phone';
9
+
4
10
  declare global {
5
11
  var Wazo;
6
12
  var wazoClients;
@@ -17,11 +23,11 @@ declare global {
17
23
  var wazoRequestApiTimeout;
18
24
  var wazoFetchOptions;
19
25
  var wazoCurrentServer;
20
- var wazoAuthInstance;
21
- var wazoConfigurationInstance;
22
- var wazoDirectoryInstance;
23
- var wazoTelephonyInstance;
24
- var wazoWebsocketInstance;
26
+ var wazoAuthInstance: Auth;
27
+ var wazoConfigurationInstance: Configuration;
28
+ var wazoDirectoryInstance: Directory;
29
+ var wazoTelephonyInstance: Phone;
30
+ var wazoWebsocketInstance: WebsocketType;
25
31
  }
26
32
 
27
33
  export {};
@@ -79,8 +79,6 @@ describe('Retrieving headers', () => {
79
79
  });
80
80
  describe('Calling fetch', () => {
81
81
  it('should call fetch without body but query string in get method', async () => {
82
- jest.mock('node-fetch/src/index', () => {});
83
-
84
82
  global.fetch = jest.fn(() => Promise.resolve({
85
83
  json: () => Promise.resolve({}),
86
84
  headers: {
@@ -108,7 +106,6 @@ describe('Calling fetch', () => {
108
106
 
109
107
  describe('With a refresh token', () => {
110
108
  it('should retry the call with a new token', async () => {
111
- jest.mock('node-fetch/src/index', () => {});
112
109
  let calls = 0;
113
110
 
114
111
  global.fetch = jest.fn(() => {
@@ -1,12 +1,7 @@
1
- /* global window */
2
- /* eslint-disable global-require */
3
- /* eslint-disable import/no-dynamic-require */
4
1
  import { Base64 } from 'js-base64';
5
- import { AbortController as NodeAbortController } from 'node-abort-controller';
6
2
 
7
3
  import BadResponse from '../domain/BadResponse';
8
4
  import ServerError from '../domain/ServerError';
9
- import isMobile from './isMobile';
10
5
  import type { Token } from '../domain/types';
11
6
  import IssueReporter from '../service/IssueReporter';
12
7
 
@@ -23,32 +18,6 @@ const methods = ['head', 'get', 'post', 'put', 'delete', 'options'];
23
18
  const logger = IssueReporter ? IssueReporter.loggerFor('api') : console;
24
19
  const REQUEST_TIMEOUT_MS = 300 * 1000; // 300s like the Chrome engine default value.
25
20
 
26
- // Use a function here to be able to mock it in tests
27
- export const realFetch = () => {
28
- if (typeof fetch !== 'undefined') {
29
- return fetch;
30
- }
31
-
32
- if (typeof document !== 'undefined' && window.fetch) {
33
- // Browser
34
- return window.fetch;
35
- }
36
-
37
- if (isMobile()) {
38
- // React native
39
- return fetch;
40
- }
41
-
42
- // nodejs
43
- // this package is disabled for react-native in package.json because it requires nodejs modules
44
- // Used to trick the optimizer to avoid requiring `node-fetch/lib/index` directly
45
- // It causes to require it on browsers when delivered by a nodejs engine (cf: vitejs).
46
- try {
47
- return require(Math.random() >= 0 ? 'node-fetch/lib/index' : '');
48
- } catch (e: any) {
49
- return fetch;
50
- }
51
- };
52
21
  export default class ApiRequester {
53
22
  server: string;
54
23
 
@@ -169,7 +138,7 @@ export default class ApiRequester {
169
138
  const hasEmptyResponse = method === 'delete' || isHead;
170
139
  const newParse = hasEmptyResponse && parse === ApiRequester.defaultParser ? ApiRequester.successResponseParser : parse;
171
140
  const fetchOptions = { ...(this.fetchOptions || {}) };
172
- const controller = typeof AbortController !== 'undefined' ? new AbortController() : new NodeAbortController();
141
+ const controller = new AbortController();
173
142
  const extraHeaders = fetchOptions.headers || {};
174
143
  delete fetchOptions.headers;
175
144
  const options = {
@@ -192,7 +161,7 @@ export default class ApiRequester {
192
161
  }
193
162
 
194
163
  const start = new Date();
195
- const requestPromise = realFetch()(url, options).then((response: any) => {
164
+ const requestPromise = fetch(url, options).then((response: any) => {
196
165
  const contentType = response.headers.get('content-type') || '';
197
166
  const isJson = contentType.indexOf('application/json') !== -1;
198
167
  IssueReporter.logRequest(url, options, response, start);
@@ -550,13 +550,14 @@ export default class WebRTCClient extends Emitter {
550
550
  });
551
551
  }
552
552
 
553
- call(number: string, enableVideo?: boolean, audioOnly = false, conference = false): WazoSession | null {
553
+ call(number: string, enableVideo?: boolean, audioOnly = false, conference = false, options = {}): WazoSession | null {
554
554
  logger.info('sdk webrtc creating call', {
555
555
  clientId: this.clientId,
556
556
  number,
557
557
  enableVideo,
558
558
  audioOnly,
559
559
  conference,
560
+ options,
560
561
  });
561
562
  const inviterOptions: Record<string, any> = {
562
563
  sessionDescriptionHandlerOptionsReInvite: {
@@ -564,6 +565,7 @@ export default class WebRTCClient extends Emitter {
564
565
  audioOnly,
565
566
  },
566
567
  earlyMedia: true,
568
+ options,
567
569
  };
568
570
 
569
571
  if (audioOnly) {
@@ -15,7 +15,7 @@ export const SOCKET_EVENTS = {
15
15
  ON_CLOSE: 'onclose',
16
16
  INITIALIZED: 'initialized',
17
17
  ON_AUTH_FAILED: 'on_auth_failed',
18
- };
18
+ } as const;
19
19
  type Arguments = {
20
20
  host: string;
21
21
  token: string;