@wazo/sdk 0.38.7 → 0.38.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/dist/wazo-sdk.js +2 -2
  2. package/esm/__tests__/api-client.test.js +163 -2
  3. package/esm/__tests__/web-rtc-client.test.js +248 -27
  4. package/esm/api/auth.js +12 -0
  5. package/esm/api/calld.js +8 -0
  6. package/esm/api/confd.js +134 -2
  7. package/esm/api/ctid-ng.js +1 -0
  8. package/esm/api-client.js +163 -2
  9. package/esm/checker/Checker.js +204 -24
  10. package/esm/checker/checks/aor.js +163 -2
  11. package/esm/checker/checks/api.js +163 -2
  12. package/esm/checker/checks/index.js +204 -24
  13. package/esm/checker/checks/wazo-websocket.js +2 -0
  14. package/esm/checker/checks/webrtc-transport.js +202 -24
  15. package/esm/checker/checks/webrtc.js +202 -24
  16. package/esm/domain/AdHocAPIConference.js +170 -4
  17. package/esm/domain/Features.js +170 -4
  18. package/esm/domain/Meeting.js +18 -0
  19. package/esm/domain/MeetingAuthorization.js +70 -0
  20. package/esm/domain/Phone/CTIPhone.js +170 -4
  21. package/esm/domain/Phone/WebRTCPhone.js +2 -3
  22. package/esm/domain/__tests__/Meeting.test.js +87 -1
  23. package/esm/domain/__tests__/MeetingAuthorization.test.js +109 -0
  24. package/esm/index.js +300 -36
  25. package/esm/service/CallApi.js +170 -4
  26. package/esm/service/getApiClient.js +176 -5
  27. package/esm/simple/Auth.js +301 -37
  28. package/esm/simple/Configuration.js +300 -36
  29. package/esm/simple/Directory.js +170 -4
  30. package/esm/simple/Phone.js +300 -36
  31. package/esm/simple/Softphone.js +5 -0
  32. package/esm/simple/Websocket.js +3 -0
  33. package/esm/simple/index.js +300 -36
  34. package/esm/simple/room/LocalParticipant.js +300 -36
  35. package/esm/simple/room/Participant.js +300 -36
  36. package/esm/simple/room/RemoteParticipant.js +300 -36
  37. package/esm/simple/room/Room.js +300 -36
  38. package/esm/simple/room/SipRoom.js +300 -36
  39. package/esm/simple/room/Stream.js +300 -36
  40. package/esm/simple/room/__tests__/Participant.test.js +14812 -0
  41. package/esm/simple/room/__tests__/RemoteParticipant.test.js +300 -36
  42. package/esm/simple/utils.js +300 -36
  43. package/esm/utils/__tests__/object.test.js +57 -0
  44. package/esm/utils/__tests__/string.test.js +30 -0
  45. package/esm/utils/object.js +24 -0
  46. package/esm/utils/string.js +10 -0
  47. package/esm/web-rtc-client.js +202 -24
  48. package/esm/websocket-client.js +3 -1
  49. package/lib/__tests__/api-client.test.js +163 -2
  50. package/lib/__tests__/web-rtc-client.test.js +248 -27
  51. package/lib/api/auth.js +12 -0
  52. package/lib/api/calld.js +8 -0
  53. package/lib/api/confd.js +134 -2
  54. package/lib/api/ctid-ng.js +1 -0
  55. package/lib/api-client.js +163 -2
  56. package/lib/checker/Checker.js +204 -24
  57. package/lib/checker/checks/aor.js +163 -2
  58. package/lib/checker/checks/api.js +163 -2
  59. package/lib/checker/checks/index.js +204 -24
  60. package/lib/checker/checks/wazo-websocket.js +2 -0
  61. package/lib/checker/checks/webrtc-transport.js +202 -24
  62. package/lib/checker/checks/webrtc.js +202 -24
  63. package/lib/domain/AdHocAPIConference.js +170 -4
  64. package/lib/domain/Features.js +170 -4
  65. package/lib/domain/Meeting.js +18 -0
  66. package/lib/domain/MeetingAuthorization.js +79 -0
  67. package/lib/domain/Phone/CTIPhone.js +170 -4
  68. package/lib/domain/Phone/WebRTCPhone.js +2 -3
  69. package/lib/domain/__tests__/Meeting.test.js +87 -1
  70. package/lib/domain/__tests__/MeetingAuthorization.test.js +111 -0
  71. package/lib/index.js +300 -36
  72. package/lib/service/CallApi.js +170 -4
  73. package/lib/service/getApiClient.js +176 -4
  74. package/lib/simple/Auth.js +301 -36
  75. package/lib/simple/Configuration.js +300 -36
  76. package/lib/simple/Directory.js +170 -4
  77. package/lib/simple/Phone.js +300 -36
  78. package/lib/simple/Softphone.js +5 -0
  79. package/lib/simple/Websocket.js +3 -0
  80. package/lib/simple/index.js +300 -36
  81. package/lib/simple/room/LocalParticipant.js +300 -36
  82. package/lib/simple/room/Participant.js +300 -36
  83. package/lib/simple/room/RemoteParticipant.js +300 -36
  84. package/lib/simple/room/Room.js +300 -36
  85. package/lib/simple/room/SipRoom.js +300 -36
  86. package/lib/simple/room/Stream.js +300 -36
  87. package/lib/simple/room/__tests__/Participant.test.js +14822 -0
  88. package/lib/simple/room/__tests__/RemoteParticipant.test.js +300 -36
  89. package/lib/simple/utils.js +300 -36
  90. package/lib/utils/__tests__/object.test.js +59 -0
  91. package/lib/utils/__tests__/string.test.js +32 -0
  92. package/lib/utils/object.js +28 -0
  93. package/lib/utils/string.js +14 -0
  94. package/lib/web-rtc-client.js +202 -24
  95. package/lib/websocket-client.js +3 -0
  96. package/package.json +1 -1
  97. package/src/__tests__/web-rtc-client.test.js +46 -3
  98. package/src/api/auth.js +12 -0
  99. package/src/api/calld.js +8 -0
  100. package/src/api/confd.js +43 -2
  101. package/src/api-client.js +8 -0
  102. package/src/domain/Meeting.js +20 -0
  103. package/src/domain/MeetingAuthorization.js +67 -0
  104. package/src/domain/Phone/WebRTCPhone.js +1 -3
  105. package/src/domain/__tests__/Meeting.test.js +70 -1
  106. package/src/domain/__tests__/MeetingAuthorization.test.js +58 -0
  107. package/src/service/getApiClient.js +13 -2
  108. package/src/simple/Auth.js +35 -4
  109. package/src/simple/Softphone.js +5 -0
  110. package/src/simple/index.js +2 -1
  111. package/src/simple/room/Participant.js +40 -0
  112. package/src/simple/room/Room.js +2 -2
  113. package/src/simple/room/SipRoom.js +1 -1
  114. package/src/simple/room/__tests__/Participant.test.js +81 -0
  115. package/src/types/WebSocketMessage.js +7 -1
  116. package/src/utils/__tests__/object.test.js +35 -0
  117. package/src/utils/__tests__/string.test.js +23 -0
  118. package/src/utils/object.js +15 -0
  119. package/src/utils/string.js +8 -0
  120. package/src/web-rtc-client.js +39 -22
  121. package/src/websocket-client.js +2 -0
package/src/api/calld.js CHANGED
@@ -137,6 +137,14 @@ export default (client: ApiRequester, baseUrl: string) => ({
137
137
  getMeetingParticipantsAsUser: async (meetingUuid: string): Promise<Object> =>
138
138
  client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
139
139
 
140
+ banMeetingParticipant: (meetingUuid: string, participantUuid: string) =>
141
+ client.delete(
142
+ `${baseUrl}/users/me/meetings/${meetingUuid}/participants/${participantUuid}`,
143
+ null,
144
+ null,
145
+ ApiRequester.successResponseParser,
146
+ ),
147
+
140
148
  listTrunks: () => client.get(`${baseUrl}/trunks`),
141
149
 
142
150
  mute: (callId: string) =>
package/src/api/confd.js CHANGED
@@ -1,10 +1,13 @@
1
1
  /* @flow */
2
2
  import ApiRequester from '../utils/api-requester';
3
3
  import type { UUID, ListConfdUsersResponse, ListApplicationsResponse } from '../domain/types';
4
+ import type { MeetingCreateArguments, MeetingUpdateArguments } from '../domain/Meeting';
4
5
  import Profile from '../domain/Profile';
5
6
  import SipLine from '../domain/SipLine';
6
7
  import ExternalApp from '../domain/ExternalApp';
7
8
  import Meeting from '../domain/Meeting';
9
+ import MeetingAuthorization from '../domain/MeetingAuthorization';
10
+ import { convertKeysFromCamelToUnderscore } from '../utils/object';
8
11
 
9
12
  export default (client: ApiRequester, baseUrl: string) => ({
10
13
  listUsers: (): Promise<ListConfdUsersResponse> => client.get(`${baseUrl}/users`, null),
@@ -72,8 +75,18 @@ export default (client: ApiRequester, baseUrl: string) => ({
72
75
  getMyMeetings: (): Promise<Meeting> =>
73
76
  client.get(`${baseUrl}/users/me/meetings`).then(response => Meeting.parseMany(response.items)),
74
77
 
75
- createMyMeeting: (name: string, persistent: boolean): Promise<Meeting> =>
76
- client.post(`${baseUrl}/users/me/meetings`, { name, persistent }).then(Meeting.parse),
78
+ createMyMeeting: (args: MeetingCreateArguments): Promise<Meeting> =>
79
+ client
80
+ .post(`${baseUrl}/users/me/meetings`, convertKeysFromCamelToUnderscore(args))
81
+ .then(Meeting.parse),
82
+
83
+ updateMyMeeting: (meetingUuid: string, data: MeetingUpdateArguments): Promise<Boolean> =>
84
+ client.put(
85
+ `${baseUrl}/users/me/meetings/${meetingUuid}`,
86
+ convertKeysFromCamelToUnderscore(data),
87
+ null,
88
+ ApiRequester.successResponseParser,
89
+ ),
77
90
 
78
91
  deleteMyMeeting: (meetingUuid: string): Promise<Meeting> =>
79
92
  client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
@@ -81,6 +94,34 @@ export default (client: ApiRequester, baseUrl: string) => ({
81
94
  getMeeting: (meetingUuid: string): Promise<Meeting> =>
82
95
  client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
83
96
 
97
+ meetingAuthorizations: (meetingUuid: string): Promise<Array<MeetingAuthorization>> =>
98
+ client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/authorizations`, null).then(MeetingAuthorization.parseMany),
99
+
100
+ meetingAuthorizationReject: (meetingUuid: string, authorizationUuid: string): Promise<Boolean> =>
101
+ client.put(
102
+ `${baseUrl}/users/me/meetings/${meetingUuid}/authorizations/${authorizationUuid}/reject`,
103
+ {},
104
+ null,
105
+ ApiRequester.successResponseParser,
106
+ ),
107
+
108
+ meetingAuthorizationAccept: (meetingUuid: string, authorizationUuid: string): Promise<Boolean> =>
109
+ client.put(
110
+ `${baseUrl}/users/me/meetings/${meetingUuid}/authorizations/${authorizationUuid}/accept`,
111
+ {},
112
+ null,
113
+ ApiRequester.successResponseParser,
114
+ ),
115
+
84
116
  guestGetMeeting: (meetingUuid: string): Promise<Meeting> =>
85
117
  client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
118
+
119
+ guestAuthorizationRequest: (userUuid: string, meetingUuid: string, username: string): Promise<> =>
120
+ client
121
+ .post(`${baseUrl}/guests/${userUuid}/meetings/${meetingUuid}/authorizations`, { guest_name: username })
122
+ .then(MeetingAuthorization.parse),
123
+
124
+ guestAuthorizationCheck: (userUuid: string, meetingUuid: string, authorizationUuid: string): Promise<> =>
125
+ client.get(`${baseUrl}/guests/${userUuid}/meetings/${meetingUuid}/authorizations/${authorizationUuid}`, null),
126
+
86
127
  });
package/src/api-client.js CHANGED
@@ -57,6 +57,7 @@ export default class ApiClient {
57
57
  refreshExpiration: ?number;
58
58
  refreshBackend: ?string;
59
59
  refreshTenantId: ?string;
60
+ refreshDomainName: ?string;
60
61
  isMobile: boolean;
61
62
  fetchOptions: Object;
62
63
 
@@ -98,6 +99,7 @@ export default class ApiClient {
98
99
  refreshToken: this.refreshToken,
99
100
  refreshBackend: this.refreshBackend,
100
101
  refreshTenantId: this.refreshTenantId,
102
+ refreshDomainName: this.refreshDomainName,
101
103
  refreshExpiration: this.refreshExpiration,
102
104
  isMobile: this.isMobile,
103
105
  });
@@ -113,6 +115,7 @@ export default class ApiClient {
113
115
  this.refreshExpiration,
114
116
  this.isMobile,
115
117
  this.refreshTenantId,
118
+ this.refreshDomainName,
116
119
  );
117
120
 
118
121
  logger.info('token refreshed', { token: session.token });
@@ -166,9 +169,14 @@ export default class ApiClient {
166
169
  }
167
170
 
168
171
  setRefreshTenantId(tenantId: ?string) {
172
+ console.warn('Use of `setRefreshTenantId` is deprecated, use `setRefreshDomainName` instead');
169
173
  this.refreshTenantId = tenantId;
170
174
  }
171
175
 
176
+ setRefreshDomainName(domainName: ?string) {
177
+ this.refreshDomainName = domainName;
178
+ }
179
+
172
180
  setIsMobile(isMobile: boolean) {
173
181
  this.isMobile = isMobile;
174
182
  }
@@ -3,6 +3,19 @@ import moment from 'moment';
3
3
 
4
4
  import newFrom from '../utils/new-from';
5
5
 
6
+ import MeetingAuthorization from './MeetingAuthorization';
7
+
8
+ export type MeetingCreateArguments = {
9
+ name: string,
10
+ requireAuthorization: boolean,
11
+ persistent: boolean,
12
+ }
13
+
14
+ export type MeetingUpdateArguments = {
15
+ name?: string,
16
+ requireAuthorization?: boolean,
17
+ }
18
+
6
19
  export type MeetingCreationResponse = {
7
20
  guest_sip_authorization: string,
8
21
  ingress_http_uri: string,
@@ -13,6 +26,7 @@ export type MeetingCreationResponse = {
13
26
  exten: string,
14
27
  persistent: boolean,
15
28
  creation_time: string,
29
+ require_authorization: boolean,
16
30
  }
17
31
 
18
32
  export default class Meeting {
@@ -27,6 +41,8 @@ export default class Meeting {
27
41
  persistent: boolean;
28
42
  ownerUuids: Array<string>;
29
43
  creationTime: Date;
44
+ pendingAuthorizations: Array<MeetingAuthorization>
45
+ requireAuthorization: boolean;
30
46
 
31
47
  static parse(plain: MeetingCreationResponse): Meeting {
32
48
  return new Meeting({
@@ -39,6 +55,7 @@ export default class Meeting {
39
55
  extension: plain.exten,
40
56
  persistent: plain.persistent,
41
57
  creationTime: moment(plain.creation_time).toDate(),
58
+ requireAuthorization: plain.require_authorization,
42
59
  });
43
60
  }
44
61
 
@@ -63,6 +80,7 @@ export default class Meeting {
63
80
  extension,
64
81
  persistent,
65
82
  creationTime,
83
+ requireAuthorization,
66
84
  }: Object = {}) {
67
85
  this.guestSipAuthorization = guestSipAuthorization;
68
86
  this.uri = uri;
@@ -73,6 +91,7 @@ export default class Meeting {
73
91
  this.extension = extension;
74
92
  this.persistent = persistent;
75
93
  this.creationTime = creationTime;
94
+ this.requireAuthorization = requireAuthorization;
76
95
 
77
96
  // Useful to compare instead of instanceof with minified code
78
97
  this.type = 'Meeting';
@@ -83,4 +102,5 @@ export default class Meeting {
83
102
  const [username, secret] = atob(this.guestSipAuthorization).split(':');
84
103
  return { username, secret };
85
104
  }
105
+
86
106
  }
@@ -0,0 +1,67 @@
1
+ // @flow
2
+
3
+ export type RawMeetingAuthorization = {
4
+ created_at: string,
5
+ meeting_uuid: string,
6
+ uuid: string,
7
+ guest_uuid: string,
8
+ guest_name: string,
9
+ }
10
+
11
+ export const PENDING = 'pending';
12
+ export const ACCEPTED = 'accepted';
13
+ export const REJECTED = 'rejected';
14
+ export const POST_PROCESSING = 'post_processing';
15
+ export const POST_PROCESSED_SUCCESS = 'post_processed_success';
16
+ export const POST_PROCESSED_ERROR = 'post_processed_error';
17
+
18
+ export default class MeetingAuthorization {
19
+ meetingUuid: string;
20
+ uuid: string;
21
+ userUuid: string;
22
+ userName: string;
23
+ status: string;
24
+
25
+ constructor({
26
+ meetingUuid,
27
+ uuid,
28
+ userUuid,
29
+ userName,
30
+ }: Object = {}) {
31
+ this.meetingUuid = meetingUuid;
32
+ this.uuid = uuid;
33
+ this.userUuid = userUuid;
34
+ this.userName = userName;
35
+ }
36
+
37
+ setStatus(status: string) {
38
+ this.status = status;
39
+ }
40
+
41
+ getStatus() {
42
+ return this.status;
43
+ }
44
+
45
+ static parse(plain: RawMeetingAuthorization) {
46
+ const {
47
+ meeting_uuid: meetingUuid,
48
+ uuid,
49
+ guest_uuid: userUuid,
50
+ guest_name: userName,
51
+ } = plain;
52
+
53
+ return new MeetingAuthorization({
54
+ meetingUuid,
55
+ uuid,
56
+ userUuid,
57
+ userName,
58
+ });
59
+ }
60
+
61
+ static parseMany(items: RawMeetingAuthorization[]): Array<MeetingAuthorization> {
62
+ if (!items) {
63
+ return [];
64
+ }
65
+ return items.map(MeetingAuthorization.parse);
66
+ }
67
+ }
@@ -531,9 +531,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
531
531
 
532
532
  try {
533
533
  if (this.currentScreenShare.stream) {
534
- this.currentScreenShare.stream.getTracks()
535
- .filter(track => track.kind === 'video')
536
- .forEach(track => track.stop());
534
+ this.currentScreenShare.stream.getTracks().forEach(track => track.stop());
537
535
  }
538
536
 
539
537
  if (restoreLocalStream) {
@@ -1,9 +1,76 @@
1
1
  // @flow
2
2
  /* global btoa */
3
3
 
4
+ import moment from 'moment';
4
5
  import Meeting from '../Meeting';
5
6
 
7
+ const rawCreationTime = '2021-12-21T15:56:42.880Z';
8
+
6
9
  describe('Meeting domain', () => {
10
+ it('should retain its values when parsed', () => {
11
+ const args = {
12
+ guest_sip_authorization: 'some-guest-sip-authorization',
13
+ ingress_http_uri: 'some-uri',
14
+ name: 'some-name',
15
+ owner_uuids: ['some-owner-uuid'],
16
+ port: 'some-port',
17
+ uuid: 'some-uuid',
18
+ exten: 'some-exten',
19
+ persistent: true,
20
+ creation_time: rawCreationTime,
21
+ require_authorization: true,
22
+ };
23
+
24
+ const meeting = Meeting.parse(args);
25
+ const {
26
+ uri,
27
+ uuid,
28
+ name,
29
+ port,
30
+ extension,
31
+ persistent,
32
+ ownerUuids,
33
+ creationTime,
34
+ requireAuthorization,
35
+ } = meeting;
36
+
37
+ expect(uri).toEqual(args.ingress_http_uri);
38
+ expect(uuid).toEqual(args.uuid);
39
+ expect(name).toEqual(args.name);
40
+ expect(port).toEqual(args.port);
41
+ expect(extension).toEqual(args.exten);
42
+ expect(persistent).toEqual(args.persistent);
43
+ expect(ownerUuids).toEqual(args.owner_uuids);
44
+ expect(creationTime).toEqual(moment(rawCreationTime).toDate());
45
+ expect(requireAuthorization).toEqual(args.require_authorization);
46
+ });
47
+
48
+ it('should retain its values when instantiated', () => {
49
+ const keys = [
50
+ 'uuid',
51
+ 'name',
52
+ 'guestSipAuthorization',
53
+ 'ownerUuids',
54
+ 'port',
55
+ 'uri',
56
+ 'extension',
57
+ 'persistent',
58
+ 'creationTime',
59
+ 'requireAuthorization',
60
+ ];
61
+
62
+ const args = keys.reduce((acc, key) => {
63
+ acc[key] = `some-${key}`;
64
+ return acc;
65
+ }, {});
66
+
67
+ const meeting = new Meeting(args);
68
+
69
+ keys.forEach(key =>
70
+ // $FlowFixMe
71
+ expect(meeting[key]).toEqual(`some-${key}`));
72
+ });
73
+
7
74
  it('can return username and secret from an base64 encrypted string', () => {
8
75
  const USERNAME = 'username';
9
76
  const SECRET = 'secret';
@@ -18,6 +85,7 @@ describe('Meeting domain', () => {
18
85
  uuid: '',
19
86
  exten: '',
20
87
  persistent: false,
88
+ require_authorization: false,
21
89
  };
22
90
 
23
91
  const meeting = Meeting.parse(args);
@@ -30,7 +98,7 @@ describe('Meeting domain', () => {
30
98
 
31
99
  it('should return a date from a string', () => {
32
100
  const args = {
33
- creation_time: '2021-12-21T15:56:42.880Z',
101
+ creation_time: rawCreationTime,
34
102
  guest_sip_authorization: '',
35
103
  ingress_http_uri: '',
36
104
  name: '',
@@ -39,6 +107,7 @@ describe('Meeting domain', () => {
39
107
  uuid: '',
40
108
  exten: '',
41
109
  persistent: false,
110
+ require_authorization: false,
42
111
  };
43
112
 
44
113
  const { creationTime } = Meeting.parse(args);
@@ -0,0 +1,58 @@
1
+ import MeetingAuthorization from '../MeetingAuthorization';
2
+
3
+ describe('MeetingAuthorization', () => {
4
+ describe('parse', () => {
5
+ it('should parse a raw input', () => {
6
+ const rawAuthorization = {
7
+ created_at: 'today',
8
+ meeting_uuid: 'meeting_uuid',
9
+ uuid: 'uuid',
10
+ guest_uuid: 'guest_uuid',
11
+ guest_name: 'guest_name',
12
+ };
13
+
14
+ const authorization = {
15
+ meetingUuid: rawAuthorization.meeting_uuid,
16
+ uuid: rawAuthorization.uuid,
17
+ userUuid: rawAuthorization.guest_uuid,
18
+ userName: rawAuthorization.guest_name,
19
+ status: undefined,
20
+ };
21
+
22
+ const response = MeetingAuthorization.parse(rawAuthorization);
23
+ expect(response).toEqual(authorization);
24
+ });
25
+ });
26
+
27
+ describe('parseMany', () => {
28
+ it('should parse multiple raw inputs', () => {
29
+ const rawAuthorizations = [
30
+ {
31
+ created_at: 'today1',
32
+ meeting_uuid: 'meeting_uuid1',
33
+ uuid: 'uuid1',
34
+ guest_uuid: 'guest_uuid1',
35
+ guest_name: 'guest_name1',
36
+ },
37
+ {
38
+ created_at: 'today2',
39
+ meeting_uuid: 'meeting_uuid2',
40
+ uuid: 'uuid2',
41
+ guest_uuid: 'guest_uuid2',
42
+ guest_name: 'guest_name2',
43
+ },
44
+ ];
45
+
46
+ const authorizations = rawAuthorizations.map(rawAuthorization => ({
47
+ meetingUuid: rawAuthorization.meeting_uuid,
48
+ uuid: rawAuthorization.uuid,
49
+ userUuid: rawAuthorization.guest_uuid,
50
+ userName: rawAuthorization.guest_name,
51
+ status: undefined,
52
+ }));
53
+
54
+ const response = MeetingAuthorization.parseMany(rawAuthorizations);
55
+ expect(response).toEqual(authorizations);
56
+ });
57
+ });
58
+ });
@@ -11,6 +11,7 @@ global.wazoClientId = global.wazoClientId || {};
11
11
  global.wazoClientToken = global.wazoClientToken || {};
12
12
  global.wazoRefreshToken = global.wazoRefreshToken || {};
13
13
  global.wazoRefreshTenantId = global.wazoRefreshTenantId || {};
14
+ global.wazoRefreshDomainName = global.wazoRefreshDomainName || {};
14
15
  global.wazoOnRefreshToken = global.wazoOnRefreshToken || {};
15
16
  global.wazoOnRefreshTokenError = global.wazoOnRefreshTokenError || {};
16
17
  global.wazoRefreshExpiration = global.wazoRefreshExpiration || {};
@@ -35,9 +36,14 @@ export const setRefreshToken = (newRefreshToken: ?string, forServer: ?string = n
35
36
  };
36
37
 
37
38
  export const setRefreshTenantId = (refreshTenantId: ?string, forServer: ?string = null) => {
39
+ console.warn('Use of `setRefreshTenantId` is deprecated, please use `setRefreshDomainName` instead');
38
40
  global.wazoRefreshTenantId[forServer] = refreshTenantId;
39
41
  };
40
42
 
43
+ export const setRefreshDomainName = (refreshDomainName: ?string, forServer: ?string = null) => {
44
+ global.wazoRefreshDomainName[forServer] = refreshDomainName;
45
+ };
46
+
41
47
  export const setOnRefreshToken = (onRefreshToken: Function, forServer: ?string = null) => {
42
48
  global.wazoOnRefreshToken[forServer] = onRefreshToken;
43
49
  };
@@ -64,6 +70,7 @@ export const setFetchOptions = (fetchOptions: Object, forServer: ?string = null)
64
70
 
65
71
  const fillClient = (apiClient: WazoApiClient) => {
66
72
  const { server, token, clientId } = apiClient.client;
73
+ const tenantId = global.wazoRefreshTenantId[server] || global.wazoRefreshTenantId[null] || apiClient.refreshTenantId;
67
74
 
68
75
  // try with null server when dealing with non-related server info
69
76
  apiClient.setToken(global.wazoClientToken[server] || global.wazoClientToken[null] || token);
@@ -72,8 +79,12 @@ const fillClient = (apiClient: WazoApiClient) => {
72
79
 
73
80
  apiClient.setRefreshToken(global.wazoRefreshToken[server] || global.wazoRefreshToken[null] || apiClient.refreshToken);
74
81
 
75
- apiClient.setRefreshTenantId(
76
- global.wazoRefreshTenantId[server] || global.wazoRefreshTenantId[null] || apiClient.refreshTenantId,
82
+ if (tenantId) {
83
+ apiClient.setRefreshTenantId(tenantId);
84
+ }
85
+
86
+ apiClient.setRefreshDomainName(
87
+ global.wazoRefreshDomainName[server] || global.wazoRefreshDomainName[null] || apiClient.refreshDomainName,
77
88
  );
78
89
 
79
90
  apiClient.setFetchOptions(global.wazoFetchOptions[server] || global.wazoFetchOptions[null] || apiClient.fetchOptions);
@@ -11,6 +11,7 @@ import getApiClient, {
11
11
  setOnRefreshToken,
12
12
  setFetchOptions,
13
13
  setRefreshTenantId,
14
+ setRefreshDomainName,
14
15
  setOnRefreshTokenError,
15
16
  } from '../service/getApiClient';
16
17
  import IssueReporter from '../service/IssueReporter';
@@ -20,6 +21,7 @@ import Wazo from './index';
20
21
  export class InvalidSubscription extends Error {}
21
22
  export class InvalidAuthorization extends Error {}
22
23
  export class NoTenantIdError extends Error {}
24
+ export class NoDomainNameError extends Error {}
23
25
 
24
26
  const logger = IssueReporter.loggerFor('simple-auth');
25
27
 
@@ -83,9 +85,24 @@ class Auth {
83
85
  setFetchOptions(options);
84
86
  }
85
87
 
86
- async logIn(username: string, password: string, backend?: string, tenantId?: string) {
87
- if (backend && backend !== this.BACKEND_WAZO && !tenantId) {
88
- throw new NoTenantIdError('No tenant id');
88
+ async logIn(username: string, password: string, backend?: string, extra?: string | Object) {
89
+ let tenantId = null;
90
+ let domainName = null;
91
+ if (typeof extra === 'string') {
92
+ tenantId = extra;
93
+ }
94
+ if (extra && typeof extra === 'object') {
95
+ domainName = extra.domainName;
96
+ }
97
+
98
+ if (backend && backend !== this.BACKEND_WAZO && !tenantId && !domainName) {
99
+ if (!tenantId) {
100
+ throw new NoTenantIdError('No tenant id');
101
+ }
102
+
103
+ if (!domainName) {
104
+ throw new NoDomainNameError('No domain name');
105
+ }
89
106
  }
90
107
 
91
108
  this.authenticated = false;
@@ -95,6 +112,7 @@ class Auth {
95
112
  password,
96
113
  backend,
97
114
  tenantId,
115
+ domainName,
98
116
  expiration: this.expiration,
99
117
  mobile: this.mobile,
100
118
  });
@@ -103,7 +121,13 @@ class Auth {
103
121
  getApiClient().setRefreshBackend(backend);
104
122
  }
105
123
 
106
- getApiClient().setRefreshTenantId(tenantId);
124
+ if (tenantId) {
125
+ getApiClient().setRefreshTenantId(tenantId);
126
+ }
127
+
128
+ if (domainName) {
129
+ getApiClient().setRefreshDomainName(domainName);
130
+ }
107
131
 
108
132
  return this._onAuthenticated(rawSession);
109
133
  }
@@ -202,11 +226,18 @@ class Auth {
202
226
  }
203
227
 
204
228
  setRefreshTenantId(refreshTenantId: string) {
229
+ console.warn('Use of `setRefreshTenantId` is deprecated, use `setRefreshDomainName` instead.');
205
230
  setRefreshTenantId(refreshTenantId);
206
231
 
207
232
  getApiClient().setRefreshTenantId(refreshTenantId);
208
233
  }
209
234
 
235
+ setRefreshDomainName(domainName: string) {
236
+ setRefreshDomainName(domainName);
237
+
238
+ getApiClient().setRefreshDomainName(domainName);
239
+ }
240
+
210
241
  forceRefreshToken() {
211
242
  getApiClient().forceRefreshToken();
212
243
  }
@@ -107,6 +107,7 @@ class Softphone {
107
107
  wrapUpDuration,
108
108
  enableAgent = true,
109
109
  tenantId,
110
+ domainName,
110
111
  debug = false,
111
112
  }: Object = {}) {
112
113
  this.url = url || 'https://softphone.wazo.io';
@@ -131,8 +132,12 @@ class Softphone {
131
132
  config.port = port;
132
133
  }
133
134
  if (tenantId) {
135
+ console.warn('Use of `tenantId` is deprecated when calling `Softphone.init()`, use `domainName` instead');
134
136
  config.tenantId = tenantId;
135
137
  }
138
+ if (domainName) {
139
+ config.domainName = domainName;
140
+ }
136
141
  if (wrapUpDuration) {
137
142
  config.wrapUpDuration = wrapUpDuration;
138
143
  }
@@ -1,5 +1,5 @@
1
1
  /* global window */
2
- import Auth, { InvalidSubscription, InvalidAuthorization, NoTenantIdError } from './Auth';
2
+ import Auth, { InvalidSubscription, InvalidAuthorization, NoTenantIdError, NoDomainNameError } from './Auth';
3
3
  import Phone from './Phone';
4
4
  import Websocket from './Websocket';
5
5
  import Room from './room/Room';
@@ -106,6 +106,7 @@ const Wazo = {
106
106
  CanceledCallError,
107
107
  SFUNotAvailableError,
108
108
  NoTenantIdError,
109
+ NoDomainNameError,
109
110
  };
110
111
 
111
112
  if (window) {
@@ -4,6 +4,7 @@ import IssueReporter from '../../service/IssueReporter';
4
4
 
5
5
  import Room, { SIGNAL_TYPE_PARTICIPANT_UPDATE } from './Room';
6
6
  import Contact from '../../domain/Contact';
7
+ import getApiClient from '../../service/getApiClient';
7
8
 
8
9
  const logger = IssueReporter.loggerFor('room');
9
10
 
@@ -20,6 +21,7 @@ class Participant extends Emitter {
20
21
  videoMuted: boolean;
21
22
  screensharing: boolean;
22
23
  isOnHold: boolean;
24
+ banned: boolean;
23
25
  extra: Object;
24
26
 
25
27
  ON_UPDATED: string;
@@ -37,6 +39,7 @@ class Participant extends Emitter {
37
39
  ON_EXTRA_CHANGE: string;
38
40
  ON_HOLD: string;
39
41
  ON_RESUME: string;
42
+ ON_BAN: string;
40
43
 
41
44
  /**
42
45
  * @param room Room The room where the participant is
@@ -60,6 +63,7 @@ class Participant extends Emitter {
60
63
  this.screensharing = false;
61
64
  this.isOnHold = false;
62
65
  this.extra = extra;
66
+ this.banned = false;
63
67
 
64
68
  this.ON_UPDATED = 'participant/ON_UPDATED';
65
69
  this.ON_START_TALKING = 'participant/ON_START_TALKING';
@@ -76,6 +80,7 @@ class Participant extends Emitter {
76
80
  this.ON_EXTRA_CHANGE = 'participant/ON_EXTRA_CHANGE';
77
81
  this.ON_HOLD = 'participant/ON_HOLD';
78
82
  this.ON_RESUME = 'participant/ON_RESUME';
83
+ this.ON_BAN = 'participant/ON_BAN';
79
84
  }
80
85
 
81
86
  triggerEvent(name: string, ...args: any[]) {
@@ -116,6 +121,10 @@ class Participant extends Emitter {
116
121
  status.extra = this.extra;
117
122
  break;
118
123
  }
124
+ case this.ON_BAN: {
125
+ status.banned = true;
126
+ break;
127
+ }
119
128
  default:
120
129
  break;
121
130
  }
@@ -220,6 +229,11 @@ class Participant extends Emitter {
220
229
  this.triggerUpdate(this.ON_RESUME, broadcast);
221
230
  }
222
231
 
232
+ onBan(broadcast: boolean = true) {
233
+ this.banned = true;
234
+ this.triggerUpdate(this.ON_BAN, broadcast);
235
+ }
236
+
223
237
  getStatus() {
224
238
  return {
225
239
  callId: this.callId,
@@ -266,6 +280,10 @@ class Participant extends Emitter {
266
280
  }
267
281
  }
268
282
 
283
+ if (status.banned) {
284
+ this.onBan(false);
285
+ }
286
+
269
287
  // Poor man's object comparison
270
288
  if (typeof status.extra !== 'undefined' && JSON.stringify(this.extra) !== JSON.stringify(status.extra)) {
271
289
  this.extra = { ...this.extra, ...status.extra };
@@ -293,6 +311,28 @@ class Participant extends Emitter {
293
311
  this.streams = streams;
294
312
  this.videoStreams = streams;
295
313
  }
314
+
315
+ async ban(apiRequestDelay: ?number = null) {
316
+ const { meetingUuid } = this.room;
317
+ if (!meetingUuid) {
318
+ throw new Error('Attempting to ban a participant without a `meetingUuid`');
319
+ }
320
+
321
+ // this notifies all that someone is being banned
322
+ this.onBan(true);
323
+
324
+ // this allows to delay the actual ban, in order for the banned participant as well as others to react to the situation
325
+ if (apiRequestDelay) {
326
+ await this.delay(apiRequestDelay);
327
+ }
328
+
329
+ // proceed with the actual kick
330
+ return getApiClient().calld.banMeetingParticipant(meetingUuid, this.callId);
331
+ }
332
+
333
+ async delay(ms: number) {
334
+ return new Promise(resolve => setTimeout(resolve, ms));
335
+ }
296
336
  }
297
337
 
298
338
  export default Participant;