@wazo/sdk 0.38.6 → 0.38.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.
- package/dist/wazo-sdk.js +2 -2
- package/esm/__tests__/api-client.test.js +142 -2
- package/esm/__tests__/web-rtc-client.test.js +249 -28
- package/esm/api/calld.js +8 -0
- package/esm/api/confd.js +134 -2
- package/esm/api-client.js +142 -2
- package/esm/checker/Checker.js +205 -25
- package/esm/checker/checks/aor.js +142 -2
- package/esm/checker/checks/api.js +142 -2
- package/esm/checker/checks/index.js +205 -25
- package/esm/checker/checks/wazo-websocket.js +2 -0
- package/esm/checker/checks/webrtc-transport.js +203 -25
- package/esm/checker/checks/webrtc.js +203 -25
- package/esm/domain/AdHocAPIConference.js +142 -2
- package/esm/domain/Features.js +142 -2
- package/esm/domain/Meeting.js +18 -0
- package/esm/domain/MeetingAuthorization.js +70 -0
- package/esm/domain/Phone/CTIPhone.js +142 -2
- package/esm/domain/Phone/WebRTCPhone.js +1 -3
- package/esm/domain/__tests__/Meeting.test.js +87 -1
- package/esm/domain/__tests__/MeetingAuthorization.test.js +109 -0
- package/esm/index.js +249 -31
- package/esm/lib/WazoSessionDescriptionHandler.js +22 -1
- package/esm/service/CallApi.js +142 -2
- package/esm/service/getApiClient.js +142 -2
- package/esm/simple/Auth.js +249 -31
- package/esm/simple/Configuration.js +249 -31
- package/esm/simple/Directory.js +142 -2
- package/esm/simple/Phone.js +249 -31
- package/esm/simple/Websocket.js +3 -0
- package/esm/simple/index.js +249 -31
- package/esm/simple/room/LocalParticipant.js +249 -31
- package/esm/simple/room/Participant.js +249 -31
- package/esm/simple/room/RemoteParticipant.js +249 -31
- package/esm/simple/room/Room.js +249 -31
- package/esm/simple/room/SipRoom.js +249 -31
- package/esm/simple/room/Stream.js +249 -31
- package/esm/simple/room/__tests__/Participant.test.js +14745 -0
- package/esm/simple/room/__tests__/RemoteParticipant.test.js +249 -31
- package/esm/simple/utils.js +249 -31
- package/esm/utils/__tests__/object.test.js +57 -0
- package/esm/utils/__tests__/sdp.test.js +50 -0
- package/esm/utils/__tests__/string.test.js +30 -0
- package/esm/utils/object.js +24 -0
- package/esm/utils/sdp.js +19 -1
- package/esm/utils/string.js +10 -0
- package/esm/web-rtc-client.js +203 -25
- package/esm/websocket-client.js +3 -1
- package/lib/__tests__/api-client.test.js +142 -2
- package/lib/__tests__/web-rtc-client.test.js +249 -28
- package/lib/api/calld.js +8 -0
- package/lib/api/confd.js +134 -2
- package/lib/api-client.js +142 -2
- package/lib/checker/Checker.js +205 -25
- package/lib/checker/checks/aor.js +142 -2
- package/lib/checker/checks/api.js +142 -2
- package/lib/checker/checks/index.js +205 -25
- package/lib/checker/checks/wazo-websocket.js +2 -0
- package/lib/checker/checks/webrtc-transport.js +203 -25
- package/lib/checker/checks/webrtc.js +203 -25
- package/lib/domain/AdHocAPIConference.js +142 -2
- package/lib/domain/Features.js +142 -2
- package/lib/domain/Meeting.js +18 -0
- package/lib/domain/MeetingAuthorization.js +79 -0
- package/lib/domain/Phone/CTIPhone.js +142 -2
- package/lib/domain/Phone/WebRTCPhone.js +1 -3
- package/lib/domain/__tests__/Meeting.test.js +87 -1
- package/lib/domain/__tests__/MeetingAuthorization.test.js +111 -0
- package/lib/index.js +249 -31
- package/lib/lib/WazoSessionDescriptionHandler.js +22 -1
- package/lib/service/CallApi.js +142 -2
- package/lib/service/getApiClient.js +142 -2
- package/lib/simple/Auth.js +249 -31
- package/lib/simple/Configuration.js +249 -31
- package/lib/simple/Directory.js +142 -2
- package/lib/simple/Phone.js +249 -31
- package/lib/simple/Websocket.js +3 -0
- package/lib/simple/index.js +249 -31
- package/lib/simple/room/LocalParticipant.js +249 -31
- package/lib/simple/room/Participant.js +249 -31
- package/lib/simple/room/RemoteParticipant.js +249 -31
- package/lib/simple/room/Room.js +249 -31
- package/lib/simple/room/SipRoom.js +249 -31
- package/lib/simple/room/Stream.js +249 -31
- package/lib/simple/room/__tests__/Participant.test.js +14755 -0
- package/lib/simple/room/__tests__/RemoteParticipant.test.js +249 -31
- package/lib/simple/utils.js +249 -31
- package/lib/utils/__tests__/object.test.js +59 -0
- package/lib/utils/__tests__/sdp.test.js +50 -0
- package/lib/utils/__tests__/string.test.js +32 -0
- package/lib/utils/object.js +28 -0
- package/lib/utils/sdp.js +19 -0
- package/lib/utils/string.js +14 -0
- package/lib/web-rtc-client.js +203 -25
- package/lib/websocket-client.js +3 -0
- package/package.json +2 -2
- package/src/__tests__/web-rtc-client.test.js +46 -3
- package/src/api/calld.js +8 -0
- package/src/api/confd.js +43 -2
- package/src/domain/Meeting.js +20 -0
- package/src/domain/MeetingAuthorization.js +67 -0
- package/src/domain/Phone/WebRTCPhone.js +1 -3
- package/src/domain/__tests__/Meeting.test.js +70 -1
- package/src/domain/__tests__/MeetingAuthorization.test.js +58 -0
- package/src/lib/WazoSessionDescriptionHandler.js +5 -2
- package/src/simple/room/Participant.js +40 -0
- package/src/simple/room/Room.js +2 -2
- package/src/simple/room/SipRoom.js +1 -1
- package/src/simple/room/__tests__/Participant.test.js +81 -0
- package/src/types/WebSocketMessage.js +7 -1
- package/src/utils/__tests__/object.test.js +35 -0
- package/src/utils/__tests__/sdp.test.js +33 -1
- package/src/utils/__tests__/string.test.js +23 -0
- package/src/utils/object.js +15 -0
- package/src/utils/sdp.js +18 -0
- package/src/utils/string.js +8 -0
- package/src/web-rtc-client.js +39 -22
- package/src/websocket-client.js +2 -0
package/lib/simple/utils.js
CHANGED
|
@@ -2657,6 +2657,70 @@ class ExternalApp {
|
|
|
2657
2657
|
|
|
2658
2658
|
//
|
|
2659
2659
|
|
|
2660
|
+
class MeetingAuthorization {
|
|
2661
|
+
|
|
2662
|
+
|
|
2663
|
+
|
|
2664
|
+
|
|
2665
|
+
|
|
2666
|
+
|
|
2667
|
+
constructor({
|
|
2668
|
+
meetingUuid,
|
|
2669
|
+
uuid,
|
|
2670
|
+
userUuid,
|
|
2671
|
+
userName,
|
|
2672
|
+
} = {}) {
|
|
2673
|
+
this.meetingUuid = meetingUuid;
|
|
2674
|
+
this.uuid = uuid;
|
|
2675
|
+
this.userUuid = userUuid;
|
|
2676
|
+
this.userName = userName;
|
|
2677
|
+
}
|
|
2678
|
+
|
|
2679
|
+
setStatus(status ) {
|
|
2680
|
+
this.status = status;
|
|
2681
|
+
}
|
|
2682
|
+
|
|
2683
|
+
getStatus() {
|
|
2684
|
+
return this.status;
|
|
2685
|
+
}
|
|
2686
|
+
|
|
2687
|
+
static parse(plain ) {
|
|
2688
|
+
const {
|
|
2689
|
+
meeting_uuid: meetingUuid,
|
|
2690
|
+
uuid,
|
|
2691
|
+
guest_uuid: userUuid,
|
|
2692
|
+
guest_name: userName,
|
|
2693
|
+
} = plain;
|
|
2694
|
+
|
|
2695
|
+
return new MeetingAuthorization({
|
|
2696
|
+
meetingUuid,
|
|
2697
|
+
uuid,
|
|
2698
|
+
userUuid,
|
|
2699
|
+
userName,
|
|
2700
|
+
});
|
|
2701
|
+
}
|
|
2702
|
+
|
|
2703
|
+
static parseMany(items ) {
|
|
2704
|
+
if (!items) {
|
|
2705
|
+
return [];
|
|
2706
|
+
}
|
|
2707
|
+
return items.map(MeetingAuthorization.parse);
|
|
2708
|
+
}
|
|
2709
|
+
}
|
|
2710
|
+
|
|
2711
|
+
//
|
|
2712
|
+
|
|
2713
|
+
|
|
2714
|
+
|
|
2715
|
+
|
|
2716
|
+
|
|
2717
|
+
|
|
2718
|
+
|
|
2719
|
+
|
|
2720
|
+
|
|
2721
|
+
|
|
2722
|
+
|
|
2723
|
+
|
|
2660
2724
|
|
|
2661
2725
|
|
|
2662
2726
|
|
|
@@ -2667,6 +2731,7 @@ class ExternalApp {
|
|
|
2667
2731
|
|
|
2668
2732
|
|
|
2669
2733
|
|
|
2734
|
+
|
|
2670
2735
|
|
|
2671
2736
|
|
|
2672
2737
|
class Meeting {
|
|
@@ -2681,6 +2746,8 @@ class Meeting {
|
|
|
2681
2746
|
|
|
2682
2747
|
|
|
2683
2748
|
|
|
2749
|
+
|
|
2750
|
+
|
|
2684
2751
|
|
|
2685
2752
|
static parse(plain ) {
|
|
2686
2753
|
return new Meeting({
|
|
@@ -2693,6 +2760,7 @@ class Meeting {
|
|
|
2693
2760
|
extension: plain.exten,
|
|
2694
2761
|
persistent: plain.persistent,
|
|
2695
2762
|
creationTime: moment__default['default'](plain.creation_time).toDate(),
|
|
2763
|
+
requireAuthorization: plain.require_authorization,
|
|
2696
2764
|
});
|
|
2697
2765
|
}
|
|
2698
2766
|
|
|
@@ -2717,6 +2785,7 @@ class Meeting {
|
|
|
2717
2785
|
extension,
|
|
2718
2786
|
persistent,
|
|
2719
2787
|
creationTime,
|
|
2788
|
+
requireAuthorization,
|
|
2720
2789
|
} = {}) {
|
|
2721
2790
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
2722
2791
|
this.uri = uri;
|
|
@@ -2727,6 +2796,7 @@ class Meeting {
|
|
|
2727
2796
|
this.extension = extension;
|
|
2728
2797
|
this.persistent = persistent;
|
|
2729
2798
|
this.creationTime = creationTime;
|
|
2799
|
+
this.requireAuthorization = requireAuthorization;
|
|
2730
2800
|
|
|
2731
2801
|
// Useful to compare instead of instanceof with minified code
|
|
2732
2802
|
this.type = 'Meeting';
|
|
@@ -2737,8 +2807,32 @@ class Meeting {
|
|
|
2737
2807
|
const [username, secret] = atob(this.guestSipAuthorization).split(':');
|
|
2738
2808
|
return { username, secret };
|
|
2739
2809
|
}
|
|
2810
|
+
|
|
2740
2811
|
}
|
|
2741
2812
|
|
|
2813
|
+
//
|
|
2814
|
+
|
|
2815
|
+
const camelToUnderscore = (key ) => {
|
|
2816
|
+
if (typeof key !== 'string') {
|
|
2817
|
+
throw new Error('Input is not a string');
|
|
2818
|
+
}
|
|
2819
|
+
return key.charAt(0).toLowerCase() + key.substring(1).replace(/([A-Z])/g, '_$1').toLowerCase();
|
|
2820
|
+
};
|
|
2821
|
+
|
|
2822
|
+
//
|
|
2823
|
+
|
|
2824
|
+
const convertKeysFromCamelToUnderscore = (args ) => {
|
|
2825
|
+
if (!args || typeof args !== 'object' || Array.isArray(args)) {
|
|
2826
|
+
throw new Error('Input is not an object');
|
|
2827
|
+
}
|
|
2828
|
+
|
|
2829
|
+
return Object.keys(args).reduce((acc, key) => {
|
|
2830
|
+
acc[camelToUnderscore(key)] = typeof args[key] === 'object' && !Array.isArray(args[key])
|
|
2831
|
+
? convertKeysFromCamelToUnderscore(args[key]) : args[key];
|
|
2832
|
+
return acc;
|
|
2833
|
+
}, {});
|
|
2834
|
+
};
|
|
2835
|
+
|
|
2742
2836
|
/* */
|
|
2743
2837
|
|
|
2744
2838
|
var confdMethods = (client , baseUrl ) => ({
|
|
@@ -2807,8 +2901,18 @@ var confdMethods = (client , baseUrl ) => ({
|
|
|
2807
2901
|
getMyMeetings: () =>
|
|
2808
2902
|
client.get(`${baseUrl}/users/me/meetings`).then(response => Meeting.parseMany(response.items)),
|
|
2809
2903
|
|
|
2810
|
-
createMyMeeting: (
|
|
2811
|
-
client
|
|
2904
|
+
createMyMeeting: (args ) =>
|
|
2905
|
+
client
|
|
2906
|
+
.post(`${baseUrl}/users/me/meetings`, convertKeysFromCamelToUnderscore(args))
|
|
2907
|
+
.then(Meeting.parse),
|
|
2908
|
+
|
|
2909
|
+
updateMyMeeting: (meetingUuid , data ) =>
|
|
2910
|
+
client.put(
|
|
2911
|
+
`${baseUrl}/users/me/meetings/${meetingUuid}`,
|
|
2912
|
+
convertKeysFromCamelToUnderscore(data),
|
|
2913
|
+
null,
|
|
2914
|
+
ApiRequester.successResponseParser,
|
|
2915
|
+
),
|
|
2812
2916
|
|
|
2813
2917
|
deleteMyMeeting: (meetingUuid ) =>
|
|
2814
2918
|
client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
|
|
@@ -2816,8 +2920,36 @@ var confdMethods = (client , baseUrl ) => ({
|
|
|
2816
2920
|
getMeeting: (meetingUuid ) =>
|
|
2817
2921
|
client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
|
|
2818
2922
|
|
|
2923
|
+
meetingAuthorizations: (meetingUuid ) =>
|
|
2924
|
+
client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/authorizations`, null).then(MeetingAuthorization.parseMany),
|
|
2925
|
+
|
|
2926
|
+
meetingAuthorizationReject: (meetingUuid , authorizationUuid ) =>
|
|
2927
|
+
client.put(
|
|
2928
|
+
`${baseUrl}/users/me/meetings/${meetingUuid}/authorizations/${authorizationUuid}/reject`,
|
|
2929
|
+
{},
|
|
2930
|
+
null,
|
|
2931
|
+
ApiRequester.successResponseParser,
|
|
2932
|
+
),
|
|
2933
|
+
|
|
2934
|
+
meetingAuthorizationAccept: (meetingUuid , authorizationUuid ) =>
|
|
2935
|
+
client.put(
|
|
2936
|
+
`${baseUrl}/users/me/meetings/${meetingUuid}/authorizations/${authorizationUuid}/accept`,
|
|
2937
|
+
{},
|
|
2938
|
+
null,
|
|
2939
|
+
ApiRequester.successResponseParser,
|
|
2940
|
+
),
|
|
2941
|
+
|
|
2819
2942
|
guestGetMeeting: (meetingUuid ) =>
|
|
2820
2943
|
client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
|
|
2944
|
+
|
|
2945
|
+
guestAuthorizationRequest: (userUuid , meetingUuid , username ) =>
|
|
2946
|
+
client
|
|
2947
|
+
.post(`${baseUrl}/guests/${userUuid}/meetings/${meetingUuid}/authorizations`, { guest_name: username })
|
|
2948
|
+
.then(MeetingAuthorization.parse),
|
|
2949
|
+
|
|
2950
|
+
guestAuthorizationCheck: (userUuid , meetingUuid , authorizationUuid ) =>
|
|
2951
|
+
client.get(`${baseUrl}/guests/${userUuid}/meetings/${meetingUuid}/authorizations/${authorizationUuid}`, null),
|
|
2952
|
+
|
|
2821
2953
|
});
|
|
2822
2954
|
|
|
2823
2955
|
//
|
|
@@ -5068,6 +5200,14 @@ var calldMethods = (client , baseUrl ) => ({
|
|
|
5068
5200
|
getMeetingParticipantsAsUser: async (meetingUuid ) =>
|
|
5069
5201
|
client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
|
|
5070
5202
|
|
|
5203
|
+
banMeetingParticipant: (meetingUuid , participantUuid ) =>
|
|
5204
|
+
client.delete(
|
|
5205
|
+
`${baseUrl}/users/me/meetings/${meetingUuid}/participants/${participantUuid}`,
|
|
5206
|
+
null,
|
|
5207
|
+
null,
|
|
5208
|
+
ApiRequester.successResponseParser,
|
|
5209
|
+
),
|
|
5210
|
+
|
|
5071
5211
|
listTrunks: () => client.get(`${baseUrl}/trunks`),
|
|
5072
5212
|
|
|
5073
5213
|
mute: (callId ) =>
|
|
@@ -6216,6 +6356,24 @@ const fixSdp = (sdp , candidates , forcePort = true)
|
|
|
6216
6356
|
return fixed;
|
|
6217
6357
|
};
|
|
6218
6358
|
|
|
6359
|
+
const addIcesInAllBundles = (sdp ) => {
|
|
6360
|
+
const parsedSdp = sdpParser__default['default'].parse(sdp);
|
|
6361
|
+
|
|
6362
|
+
const mediaWithCandidate = parsedSdp.media.find(media => !!media.candidates);
|
|
6363
|
+
if (!mediaWithCandidate) {
|
|
6364
|
+
return sdp;
|
|
6365
|
+
}
|
|
6366
|
+
|
|
6367
|
+
const { candidates } = mediaWithCandidate;
|
|
6368
|
+
|
|
6369
|
+
parsedSdp.media = parsedSdp.media.map(media => ({
|
|
6370
|
+
...media,
|
|
6371
|
+
candidates: media.candidates || candidates,
|
|
6372
|
+
}));
|
|
6373
|
+
|
|
6374
|
+
return sdpParser__default['default'].write(parsedSdp);
|
|
6375
|
+
};
|
|
6376
|
+
|
|
6219
6377
|
/* global RTCSessionDescriptionInit, navigator */
|
|
6220
6378
|
|
|
6221
6379
|
const wazoLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-sdh') : console;
|
|
@@ -6345,7 +6503,10 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
6345
6503
|
|
|
6346
6504
|
// Check if we got ICEs
|
|
6347
6505
|
if (sdp.indexOf('a=candidate') !== -1) {
|
|
6348
|
-
return
|
|
6506
|
+
return {
|
|
6507
|
+
type: description.type,
|
|
6508
|
+
sdp: addIcesInAllBundles(sdp),
|
|
6509
|
+
};
|
|
6349
6510
|
}
|
|
6350
6511
|
|
|
6351
6512
|
wazoLogger.info('No ICE candidates found in SDP, fixing it with gathered ices', this.gatheredCandidates);
|
|
@@ -7805,7 +7966,7 @@ class WebRTCClient extends Emitter {
|
|
|
7805
7966
|
});
|
|
7806
7967
|
}
|
|
7807
7968
|
|
|
7808
|
-
changeAudioInputDevice(id , session , force ) {
|
|
7969
|
+
async changeAudioInputDevice(id , session , force ) {
|
|
7809
7970
|
const currentId = this.getAudioDeviceId();
|
|
7810
7971
|
logger$8.info('setting audio input device', { id, currentId, session: !!session });
|
|
7811
7972
|
|
|
@@ -7813,33 +7974,50 @@ class WebRTCClient extends Emitter {
|
|
|
7813
7974
|
return null;
|
|
7814
7975
|
}
|
|
7815
7976
|
|
|
7977
|
+
// in order to handle an audio track change for default devices
|
|
7978
|
+
// we need the actual id of the device (not 'default')
|
|
7979
|
+
let deviceId = id;
|
|
7980
|
+
if (id === 'default' && navigator.mediaDevices) {
|
|
7981
|
+
const devices = await navigator.mediaDevices.enumerateDevices();
|
|
7982
|
+
const defaultDevice = devices.find(device => device.deviceId === 'default');
|
|
7983
|
+
if (defaultDevice) {
|
|
7984
|
+
const deviceLabel = defaultDevice.label.replace('Default - ', '');
|
|
7985
|
+
const targetDevice = devices.find(device => device.label === deviceLabel);
|
|
7986
|
+
if (targetDevice) {
|
|
7987
|
+
deviceId = targetDevice.deviceId;
|
|
7988
|
+
if (!force && deviceId === currentId) {
|
|
7989
|
+
return null;
|
|
7990
|
+
}
|
|
7991
|
+
}
|
|
7992
|
+
}
|
|
7993
|
+
}
|
|
7994
|
+
|
|
7816
7995
|
// let's update the local audio value
|
|
7817
7996
|
if (this.audio) {
|
|
7818
7997
|
this.audio = {
|
|
7819
7998
|
deviceId: {
|
|
7820
|
-
exact:
|
|
7999
|
+
exact: deviceId,
|
|
7821
8000
|
},
|
|
7822
8001
|
};
|
|
7823
8002
|
}
|
|
7824
8003
|
|
|
7825
|
-
if (session) {
|
|
8004
|
+
if (session && navigator.mediaDevices) {
|
|
7826
8005
|
const sdh = session.sessionDescriptionHandler;
|
|
7827
8006
|
const pc = sdh.peerConnection;
|
|
7828
8007
|
|
|
7829
|
-
|
|
7830
|
-
|
|
7831
|
-
|
|
7832
|
-
|
|
8008
|
+
const constraints = { audio: { deviceId: { exact: deviceId } } };
|
|
8009
|
+
const stream = await navigator.mediaDevices.getUserMedia(constraints);
|
|
8010
|
+
const audioTrack = stream.getAudioTracks()[0];
|
|
8011
|
+
const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
|
|
7833
8012
|
|
|
7834
|
-
|
|
7835
|
-
|
|
7836
|
-
|
|
7837
|
-
}
|
|
7838
|
-
sender.replaceTrack(audioTrack);
|
|
8013
|
+
if (sender) {
|
|
8014
|
+
if (sender.track) {
|
|
8015
|
+
audioTrack.enabled = sender.track.enabled;
|
|
7839
8016
|
}
|
|
8017
|
+
sender.replaceTrack(audioTrack);
|
|
8018
|
+
}
|
|
7840
8019
|
|
|
7841
|
-
|
|
7842
|
-
});
|
|
8020
|
+
return stream;
|
|
7843
8021
|
}
|
|
7844
8022
|
}
|
|
7845
8023
|
|
|
@@ -7859,14 +8037,14 @@ class WebRTCClient extends Emitter {
|
|
|
7859
8037
|
return null;
|
|
7860
8038
|
}
|
|
7861
8039
|
|
|
7862
|
-
// let's
|
|
7863
|
-
|
|
7864
|
-
|
|
7865
|
-
|
|
7866
|
-
|
|
7867
|
-
|
|
7868
|
-
}
|
|
7869
|
-
}
|
|
8040
|
+
// let's make sure we don't lose other video constraints settings -- width, height, frameRate...
|
|
8041
|
+
const videoObject = typeof this.video === 'object' ? this.video : {};
|
|
8042
|
+
this.video = {
|
|
8043
|
+
...videoObject,
|
|
8044
|
+
deviceId: {
|
|
8045
|
+
exact: id,
|
|
8046
|
+
},
|
|
8047
|
+
};
|
|
7870
8048
|
}
|
|
7871
8049
|
|
|
7872
8050
|
changeSessionVideoInputDevice(id , session ) {
|
|
@@ -9468,9 +9646,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9468
9646
|
|
|
9469
9647
|
try {
|
|
9470
9648
|
if (this.currentScreenShare.stream) {
|
|
9471
|
-
this.currentScreenShare.stream.getTracks()
|
|
9472
|
-
.filter(track => track.kind === 'video')
|
|
9473
|
-
.forEach(track => track.stop());
|
|
9649
|
+
this.currentScreenShare.stream.getTracks().forEach(track => track.stop());
|
|
9474
9650
|
}
|
|
9475
9651
|
|
|
9476
9652
|
if (restoreLocalStream) {
|
|
@@ -11261,6 +11437,7 @@ const AGENT_UNPAUSED = 'agent_unpaused';
|
|
|
11261
11437
|
const CONFERENCE_ADHOC_PARTICIPANT_LEFT = 'conference_adhoc_participant_left';
|
|
11262
11438
|
const CONFERENCE_ADHOC_DELETED = 'conference_adhoc_deleted';
|
|
11263
11439
|
const MEETING_USER_PROGRESS = 'meeting_user_progress';
|
|
11440
|
+
const MEETING_USER_GUEST_AUTHORIZATION_CREATED = 'meeting_user_guest_authorization_created';
|
|
11264
11441
|
|
|
11265
11442
|
const BLACKLIST_EVENTS = [
|
|
11266
11443
|
CHAT_MESSAGE_SENT,
|
|
@@ -11612,6 +11789,7 @@ WebSocketClient.eventLists = [
|
|
|
11612
11789
|
CONFERENCE_ADHOC_PARTICIPANT_LEFT,
|
|
11613
11790
|
CONFERENCE_ADHOC_DELETED,
|
|
11614
11791
|
MEETING_USER_PROGRESS,
|
|
11792
|
+
MEETING_USER_GUEST_AUTHORIZATION_CREATED,
|
|
11615
11793
|
];
|
|
11616
11794
|
|
|
11617
11795
|
var WebSocketClient$1 = /*#__PURE__*/Object.freeze({
|
|
@@ -11683,6 +11861,7 @@ var WebSocketClient$1 = /*#__PURE__*/Object.freeze({
|
|
|
11683
11861
|
CONFERENCE_ADHOC_PARTICIPANT_LEFT: CONFERENCE_ADHOC_PARTICIPANT_LEFT,
|
|
11684
11862
|
CONFERENCE_ADHOC_DELETED: CONFERENCE_ADHOC_DELETED,
|
|
11685
11863
|
MEETING_USER_PROGRESS: MEETING_USER_PROGRESS,
|
|
11864
|
+
MEETING_USER_GUEST_AUTHORIZATION_CREATED: MEETING_USER_GUEST_AUTHORIZATION_CREATED,
|
|
11686
11865
|
HEARTBEAT_ENGINE_VERSION: HEARTBEAT_ENGINE_VERSION,
|
|
11687
11866
|
'default': WebSocketClient
|
|
11688
11867
|
});
|
|
@@ -11787,6 +11966,7 @@ class Participant extends Emitter {
|
|
|
11787
11966
|
|
|
11788
11967
|
|
|
11789
11968
|
|
|
11969
|
+
|
|
11790
11970
|
|
|
11791
11971
|
|
|
11792
11972
|
|
|
@@ -11804,6 +11984,7 @@ class Participant extends Emitter {
|
|
|
11804
11984
|
|
|
11805
11985
|
|
|
11806
11986
|
|
|
11987
|
+
|
|
11807
11988
|
|
|
11808
11989
|
/**
|
|
11809
11990
|
* @param room Room The room where the participant is
|
|
@@ -11827,6 +12008,7 @@ class Participant extends Emitter {
|
|
|
11827
12008
|
this.screensharing = false;
|
|
11828
12009
|
this.isOnHold = false;
|
|
11829
12010
|
this.extra = extra;
|
|
12011
|
+
this.banned = false;
|
|
11830
12012
|
|
|
11831
12013
|
this.ON_UPDATED = 'participant/ON_UPDATED';
|
|
11832
12014
|
this.ON_START_TALKING = 'participant/ON_START_TALKING';
|
|
@@ -11843,6 +12025,7 @@ class Participant extends Emitter {
|
|
|
11843
12025
|
this.ON_EXTRA_CHANGE = 'participant/ON_EXTRA_CHANGE';
|
|
11844
12026
|
this.ON_HOLD = 'participant/ON_HOLD';
|
|
11845
12027
|
this.ON_RESUME = 'participant/ON_RESUME';
|
|
12028
|
+
this.ON_BAN = 'participant/ON_BAN';
|
|
11846
12029
|
}
|
|
11847
12030
|
|
|
11848
12031
|
triggerEvent(name , ...args ) {
|
|
@@ -11883,6 +12066,10 @@ class Participant extends Emitter {
|
|
|
11883
12066
|
status.extra = this.extra;
|
|
11884
12067
|
break;
|
|
11885
12068
|
}
|
|
12069
|
+
case this.ON_BAN: {
|
|
12070
|
+
status.banned = true;
|
|
12071
|
+
break;
|
|
12072
|
+
}
|
|
11886
12073
|
}
|
|
11887
12074
|
|
|
11888
12075
|
if (broadcast) {
|
|
@@ -11985,6 +12172,11 @@ class Participant extends Emitter {
|
|
|
11985
12172
|
this.triggerUpdate(this.ON_RESUME, broadcast);
|
|
11986
12173
|
}
|
|
11987
12174
|
|
|
12175
|
+
onBan(broadcast = true) {
|
|
12176
|
+
this.banned = true;
|
|
12177
|
+
this.triggerUpdate(this.ON_BAN, broadcast);
|
|
12178
|
+
}
|
|
12179
|
+
|
|
11988
12180
|
getStatus() {
|
|
11989
12181
|
return {
|
|
11990
12182
|
callId: this.callId,
|
|
@@ -12031,6 +12223,10 @@ class Participant extends Emitter {
|
|
|
12031
12223
|
}
|
|
12032
12224
|
}
|
|
12033
12225
|
|
|
12226
|
+
if (status.banned) {
|
|
12227
|
+
this.onBan(false);
|
|
12228
|
+
}
|
|
12229
|
+
|
|
12034
12230
|
// Poor man's object comparison
|
|
12035
12231
|
if (typeof status.extra !== 'undefined' && JSON.stringify(this.extra) !== JSON.stringify(status.extra)) {
|
|
12036
12232
|
this.extra = { ...this.extra, ...status.extra };
|
|
@@ -12058,6 +12254,28 @@ class Participant extends Emitter {
|
|
|
12058
12254
|
this.streams = streams;
|
|
12059
12255
|
this.videoStreams = streams;
|
|
12060
12256
|
}
|
|
12257
|
+
|
|
12258
|
+
async ban(apiRequestDelay = null) {
|
|
12259
|
+
const { meetingUuid } = this.room;
|
|
12260
|
+
if (!meetingUuid) {
|
|
12261
|
+
throw new Error('Attempting to ban a participant without a `meetingUuid`');
|
|
12262
|
+
}
|
|
12263
|
+
|
|
12264
|
+
// this notifies all that someone is being banned
|
|
12265
|
+
this.onBan(true);
|
|
12266
|
+
|
|
12267
|
+
// this allows to delay the actual ban, in order for the banned participant as well as others to react to the situation
|
|
12268
|
+
if (apiRequestDelay) {
|
|
12269
|
+
await this.delay(apiRequestDelay);
|
|
12270
|
+
}
|
|
12271
|
+
|
|
12272
|
+
// proceed with the actual kick
|
|
12273
|
+
return getApiClient().calld.banMeetingParticipant(meetingUuid, this.callId);
|
|
12274
|
+
}
|
|
12275
|
+
|
|
12276
|
+
async delay(ms ) {
|
|
12277
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
12278
|
+
}
|
|
12061
12279
|
}
|
|
12062
12280
|
|
|
12063
12281
|
//
|
|
@@ -12210,7 +12428,7 @@ class Room$1 extends Emitter {
|
|
|
12210
12428
|
logger$2.info('connecting to room', { extension, audioOnly, room: !!room });
|
|
12211
12429
|
|
|
12212
12430
|
if (!room) {
|
|
12213
|
-
await Wazo.Phone.connect();
|
|
12431
|
+
await Wazo.Phone.connect({ media: constraints });
|
|
12214
12432
|
|
|
12215
12433
|
const withCamera = constraints && !!constraints.video;
|
|
12216
12434
|
|
|
@@ -12655,7 +12873,7 @@ class Room$1 extends Emitter {
|
|
|
12655
12873
|
const participant = this._getParticipantFromCallId(status.callId);
|
|
12656
12874
|
|
|
12657
12875
|
if (participant) {
|
|
12658
|
-
// we're
|
|
12876
|
+
// we're receiving, so no need to broadcast
|
|
12659
12877
|
participant.updateStatus(status, false);
|
|
12660
12878
|
}
|
|
12661
12879
|
break;
|
|
@@ -12922,7 +13140,7 @@ class SipRoom extends Room$1 {
|
|
|
12922
13140
|
logger$1.info('connecting to sip room', { extension, audioOnly, room: !!room });
|
|
12923
13141
|
|
|
12924
13142
|
if (!room) {
|
|
12925
|
-
await Wazo.Phone.connect();
|
|
13143
|
+
await Wazo.Phone.connect({ media: constraints });
|
|
12926
13144
|
|
|
12927
13145
|
const withCamera = constraints && !!constraints.video;
|
|
12928
13146
|
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
const camelToUnderscore = (key ) => {
|
|
6
|
+
if (typeof key !== 'string') {
|
|
7
|
+
throw new Error('Input is not a string');
|
|
8
|
+
}
|
|
9
|
+
return key.charAt(0).toLowerCase() + key.substring(1).replace(/([A-Z])/g, '_$1').toLowerCase();
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
//
|
|
13
|
+
|
|
14
|
+
const convertKeysFromCamelToUnderscore = (args ) => {
|
|
15
|
+
if (!args || typeof args !== 'object' || Array.isArray(args)) {
|
|
16
|
+
throw new Error('Input is not an object');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return Object.keys(args).reduce((acc, key) => {
|
|
20
|
+
acc[camelToUnderscore(key)] = typeof args[key] === 'object' && !Array.isArray(args[key])
|
|
21
|
+
? convertKeysFromCamelToUnderscore(args[key]) : args[key];
|
|
22
|
+
return acc;
|
|
23
|
+
}, {});
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
//
|
|
27
|
+
|
|
28
|
+
describe('object utils', () => {
|
|
29
|
+
describe('convertKeysFromCamelToUnderscore', () => {
|
|
30
|
+
it('should throw an error when input is not an object', () => {
|
|
31
|
+
const msg = 'Input is not an object';
|
|
32
|
+
expect(() => convertKeysFromCamelToUnderscore(true)).toThrow(msg);
|
|
33
|
+
expect(() => convertKeysFromCamelToUnderscore(null)).toThrow(msg);
|
|
34
|
+
expect(() => convertKeysFromCamelToUnderscore(undefined)).toThrow(msg);
|
|
35
|
+
expect(() => convertKeysFromCamelToUnderscore([])).toThrow(msg);
|
|
36
|
+
expect(() => convertKeysFromCamelToUnderscore('some-string')).toThrow(msg);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should convert camel-cased keys to underscore', () => {
|
|
40
|
+
let value = Math.random();
|
|
41
|
+
expect(convertKeysFromCamelToUnderscore({ LoremIpsum: value })).toEqual({ lorem_ipsum: value });
|
|
42
|
+
value = Math.random();
|
|
43
|
+
expect(convertKeysFromCamelToUnderscore({ loremIpsum: value })).toEqual({ lorem_ipsum: value });
|
|
44
|
+
value = Math.random();
|
|
45
|
+
expect(convertKeysFromCamelToUnderscore({ 'lorem-ipsum': value })).toEqual({ 'lorem-ipsum': value });
|
|
46
|
+
value = Math.random();
|
|
47
|
+
expect(convertKeysFromCamelToUnderscore({ L123: value })).toEqual({ l123: value });
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('should handle multi-leveled object', () => {
|
|
51
|
+
const value = Math.random();
|
|
52
|
+
expect(convertKeysFromCamelToUnderscore({ LoremIpsum: { DoloreSit: { Amet: value }, regular: 'reg' } }))
|
|
53
|
+
.toEqual({ lorem_ipsum: { dolore_sit: { amet: value }, regular: 'reg' } });
|
|
54
|
+
|
|
55
|
+
expect(convertKeysFromCamelToUnderscore({ LoremIpsum: { DoloreSit: { Amet: [value] }, regular: ['something'] } }))
|
|
56
|
+
.toEqual({ lorem_ipsum: { dolore_sit: { amet: [value] }, regular: ['something'] } });
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
});
|
|
@@ -104,6 +104,24 @@ const fixSdp = (sdp , candidates , forcePort = true)
|
|
|
104
104
|
return fixed;
|
|
105
105
|
};
|
|
106
106
|
|
|
107
|
+
const addIcesInAllBundles = (sdp ) => {
|
|
108
|
+
const parsedSdp = sdpParser__default['default'].parse(sdp);
|
|
109
|
+
|
|
110
|
+
const mediaWithCandidate = parsedSdp.media.find(media => !!media.candidates);
|
|
111
|
+
if (!mediaWithCandidate) {
|
|
112
|
+
return sdp;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const { candidates } = mediaWithCandidate;
|
|
116
|
+
|
|
117
|
+
parsedSdp.media = parsedSdp.media.map(media => ({
|
|
118
|
+
...media,
|
|
119
|
+
candidates: media.candidates || candidates,
|
|
120
|
+
}));
|
|
121
|
+
|
|
122
|
+
return sdpParser__default['default'].write(parsedSdp);
|
|
123
|
+
};
|
|
124
|
+
|
|
107
125
|
/* eslint-disable max-len */
|
|
108
126
|
|
|
109
127
|
const goodSdp = `
|
|
@@ -268,4 +286,36 @@ describe('SDP utils', () => {
|
|
|
268
286
|
expect(hasAnActiveVideo(inactiveVideo)).toBeFalsy();
|
|
269
287
|
});
|
|
270
288
|
});
|
|
289
|
+
|
|
290
|
+
describe('Adding candidate in all bundles ', () => {
|
|
291
|
+
it('should add candidate everywhere', async () => {
|
|
292
|
+
const audioWithoutCandidate = `
|
|
293
|
+
c=IN IP4 203.0.113.1
|
|
294
|
+
m=audio 54400 RTP/SAVPF 0 96
|
|
295
|
+
m=video 54400 RTP/SAVPF 0 96
|
|
296
|
+
a=candidate:0 1 UDP 2113667327 203.0.113.1 54400 typ host
|
|
297
|
+
a=candidate:3996450952 1 udp 41819903 14.72.21.2 65092 typ relay raddr 0.0.0.0 rport 0 generation 0 network-id 3 network-cost 10
|
|
298
|
+
`;
|
|
299
|
+
const fixedAudioWithoutCandidate = sdpParser__default['default'].parse(addIcesInAllBundles(audioWithoutCandidate));
|
|
300
|
+
|
|
301
|
+
expect(fixedAudioWithoutCandidate.media[0].candidates[0].type).toBe('host');
|
|
302
|
+
expect(fixedAudioWithoutCandidate.media[0].candidates[1].type).toBe('relay');
|
|
303
|
+
expect(fixedAudioWithoutCandidate.media[1].candidates[0].type).toBe('host');
|
|
304
|
+
expect(fixedAudioWithoutCandidate.media[1].candidates[1].type).toBe('relay');
|
|
305
|
+
|
|
306
|
+
// It should not add candidate if already present
|
|
307
|
+
const audioWithCandidate = `
|
|
308
|
+
c=IN IP4 203.0.113.1
|
|
309
|
+
m=audio 54400 RTP/SAVPF 0 96
|
|
310
|
+
a=candidate:0 1 UDP 2113667327 203.0.113.1 54400 typ srflx
|
|
311
|
+
|
|
312
|
+
m=video 54400 RTP/SAVPF 0 96
|
|
313
|
+
a=candidate:0 1 UDP 2113667327 203.0.113.1 54400 typ host
|
|
314
|
+
`;
|
|
315
|
+
const fixedAudioWithCandidate = sdpParser__default['default'].parse(addIcesInAllBundles(audioWithCandidate));
|
|
316
|
+
|
|
317
|
+
expect(fixedAudioWithCandidate.media[0].candidates[0].type).toBe('srflx');
|
|
318
|
+
expect(fixedAudioWithCandidate.media[1].candidates[0].type).toBe('host');
|
|
319
|
+
});
|
|
320
|
+
});
|
|
271
321
|
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
const camelToUnderscore = (key ) => {
|
|
6
|
+
if (typeof key !== 'string') {
|
|
7
|
+
throw new Error('Input is not a string');
|
|
8
|
+
}
|
|
9
|
+
return key.charAt(0).toLowerCase() + key.substring(1).replace(/([A-Z])/g, '_$1').toLowerCase();
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
describe('string utils', () => {
|
|
13
|
+
describe('camelToUnderscore', () => {
|
|
14
|
+
it('', () => {
|
|
15
|
+
expect(() => camelToUnderscore(null)).toThrow('Input is not a string');
|
|
16
|
+
expect(() => camelToUnderscore(undefined)).toThrow('Input is not a string');
|
|
17
|
+
expect(() => camelToUnderscore({})).toThrow('Input is not a string');
|
|
18
|
+
expect(() => camelToUnderscore([])).toThrow('Input is not a string');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should convert camel-cased string to underscore', () => {
|
|
22
|
+
expect(camelToUnderscore('loremIpsum')).toEqual('lorem_ipsum');
|
|
23
|
+
expect(camelToUnderscore('lorem-ipsum')).toEqual('lorem-ipsum');
|
|
24
|
+
expect(camelToUnderscore('')).toEqual('');
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('should not prefix string with an underscore', () => {
|
|
28
|
+
expect(camelToUnderscore('LoremIpsum')).toEqual('lorem_ipsum');
|
|
29
|
+
expect(camelToUnderscore('L123')).toEqual('l123');
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
//
|
|
6
|
+
|
|
7
|
+
const camelToUnderscore = (key ) => {
|
|
8
|
+
if (typeof key !== 'string') {
|
|
9
|
+
throw new Error('Input is not a string');
|
|
10
|
+
}
|
|
11
|
+
return key.charAt(0).toLowerCase() + key.substring(1).replace(/([A-Z])/g, '_$1').toLowerCase();
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
//
|
|
15
|
+
|
|
16
|
+
const convertKeysFromCamelToUnderscore = (args ) => {
|
|
17
|
+
if (!args || typeof args !== 'object' || Array.isArray(args)) {
|
|
18
|
+
throw new Error('Input is not an object');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return Object.keys(args).reduce((acc, key) => {
|
|
22
|
+
acc[camelToUnderscore(key)] = typeof args[key] === 'object' && !Array.isArray(args[key])
|
|
23
|
+
? convertKeysFromCamelToUnderscore(args[key]) : args[key];
|
|
24
|
+
return acc;
|
|
25
|
+
}, {});
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
exports.convertKeysFromCamelToUnderscore = convertKeysFromCamelToUnderscore;
|