@wazo/sdk 0.38.7 → 0.38.8
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 +227 -27
- 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 +183 -24
- package/esm/checker/checks/aor.js +142 -2
- package/esm/checker/checks/api.js +142 -2
- package/esm/checker/checks/index.js +183 -24
- package/esm/checker/checks/wazo-websocket.js +2 -0
- package/esm/checker/checks/webrtc-transport.js +181 -24
- package/esm/checker/checks/webrtc.js +181 -24
- 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/__tests__/Meeting.test.js +87 -1
- package/esm/domain/__tests__/MeetingAuthorization.test.js +109 -0
- package/esm/index.js +226 -27
- package/esm/service/CallApi.js +142 -2
- package/esm/service/getApiClient.js +142 -2
- package/esm/simple/Auth.js +226 -27
- package/esm/simple/Configuration.js +226 -27
- package/esm/simple/Directory.js +142 -2
- package/esm/simple/Phone.js +226 -27
- package/esm/simple/Websocket.js +3 -0
- package/esm/simple/index.js +226 -27
- package/esm/simple/room/LocalParticipant.js +226 -27
- package/esm/simple/room/Participant.js +226 -27
- package/esm/simple/room/RemoteParticipant.js +226 -27
- package/esm/simple/room/Room.js +226 -27
- package/esm/simple/room/SipRoom.js +226 -27
- package/esm/simple/room/Stream.js +226 -27
- package/esm/simple/room/__tests__/Participant.test.js +14747 -0
- package/esm/simple/room/__tests__/RemoteParticipant.test.js +226 -27
- package/esm/simple/utils.js +226 -27
- package/esm/utils/__tests__/object.test.js +57 -0
- package/esm/utils/__tests__/string.test.js +30 -0
- package/esm/utils/object.js +24 -0
- package/esm/utils/string.js +10 -0
- package/esm/web-rtc-client.js +181 -24
- package/esm/websocket-client.js +3 -1
- package/lib/__tests__/api-client.test.js +142 -2
- package/lib/__tests__/web-rtc-client.test.js +227 -27
- 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 +183 -24
- package/lib/checker/checks/aor.js +142 -2
- package/lib/checker/checks/api.js +142 -2
- package/lib/checker/checks/index.js +183 -24
- package/lib/checker/checks/wazo-websocket.js +2 -0
- package/lib/checker/checks/webrtc-transport.js +181 -24
- package/lib/checker/checks/webrtc.js +181 -24
- 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/__tests__/Meeting.test.js +87 -1
- package/lib/domain/__tests__/MeetingAuthorization.test.js +111 -0
- package/lib/index.js +226 -27
- package/lib/service/CallApi.js +142 -2
- package/lib/service/getApiClient.js +142 -2
- package/lib/simple/Auth.js +226 -27
- package/lib/simple/Configuration.js +226 -27
- package/lib/simple/Directory.js +142 -2
- package/lib/simple/Phone.js +226 -27
- package/lib/simple/Websocket.js +3 -0
- package/lib/simple/index.js +226 -27
- package/lib/simple/room/LocalParticipant.js +226 -27
- package/lib/simple/room/Participant.js +226 -27
- package/lib/simple/room/RemoteParticipant.js +226 -27
- package/lib/simple/room/Room.js +226 -27
- package/lib/simple/room/SipRoom.js +226 -27
- package/lib/simple/room/Stream.js +226 -27
- package/lib/simple/room/__tests__/Participant.test.js +14757 -0
- package/lib/simple/room/__tests__/RemoteParticipant.test.js +226 -27
- package/lib/simple/utils.js +226 -27
- package/lib/utils/__tests__/object.test.js +59 -0
- package/lib/utils/__tests__/string.test.js +32 -0
- package/lib/utils/object.js +28 -0
- package/lib/utils/string.js +14 -0
- package/lib/web-rtc-client.js +181 -24
- 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/__tests__/Meeting.test.js +70 -1
- package/src/domain/__tests__/MeetingAuthorization.test.js +58 -0
- 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__/string.test.js +23 -0
- package/src/utils/object.js +15 -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/web-rtc-client.js
CHANGED
|
@@ -3213,6 +3213,70 @@ class ExternalApp {
|
|
|
3213
3213
|
|
|
3214
3214
|
//
|
|
3215
3215
|
|
|
3216
|
+
class MeetingAuthorization {
|
|
3217
|
+
|
|
3218
|
+
|
|
3219
|
+
|
|
3220
|
+
|
|
3221
|
+
|
|
3222
|
+
|
|
3223
|
+
constructor({
|
|
3224
|
+
meetingUuid,
|
|
3225
|
+
uuid,
|
|
3226
|
+
userUuid,
|
|
3227
|
+
userName,
|
|
3228
|
+
} = {}) {
|
|
3229
|
+
this.meetingUuid = meetingUuid;
|
|
3230
|
+
this.uuid = uuid;
|
|
3231
|
+
this.userUuid = userUuid;
|
|
3232
|
+
this.userName = userName;
|
|
3233
|
+
}
|
|
3234
|
+
|
|
3235
|
+
setStatus(status ) {
|
|
3236
|
+
this.status = status;
|
|
3237
|
+
}
|
|
3238
|
+
|
|
3239
|
+
getStatus() {
|
|
3240
|
+
return this.status;
|
|
3241
|
+
}
|
|
3242
|
+
|
|
3243
|
+
static parse(plain ) {
|
|
3244
|
+
const {
|
|
3245
|
+
meeting_uuid: meetingUuid,
|
|
3246
|
+
uuid,
|
|
3247
|
+
guest_uuid: userUuid,
|
|
3248
|
+
guest_name: userName,
|
|
3249
|
+
} = plain;
|
|
3250
|
+
|
|
3251
|
+
return new MeetingAuthorization({
|
|
3252
|
+
meetingUuid,
|
|
3253
|
+
uuid,
|
|
3254
|
+
userUuid,
|
|
3255
|
+
userName,
|
|
3256
|
+
});
|
|
3257
|
+
}
|
|
3258
|
+
|
|
3259
|
+
static parseMany(items ) {
|
|
3260
|
+
if (!items) {
|
|
3261
|
+
return [];
|
|
3262
|
+
}
|
|
3263
|
+
return items.map(MeetingAuthorization.parse);
|
|
3264
|
+
}
|
|
3265
|
+
}
|
|
3266
|
+
|
|
3267
|
+
//
|
|
3268
|
+
|
|
3269
|
+
|
|
3270
|
+
|
|
3271
|
+
|
|
3272
|
+
|
|
3273
|
+
|
|
3274
|
+
|
|
3275
|
+
|
|
3276
|
+
|
|
3277
|
+
|
|
3278
|
+
|
|
3279
|
+
|
|
3216
3280
|
|
|
3217
3281
|
|
|
3218
3282
|
|
|
@@ -3223,6 +3287,7 @@ class ExternalApp {
|
|
|
3223
3287
|
|
|
3224
3288
|
|
|
3225
3289
|
|
|
3290
|
+
|
|
3226
3291
|
|
|
3227
3292
|
|
|
3228
3293
|
class Meeting {
|
|
@@ -3237,6 +3302,8 @@ class Meeting {
|
|
|
3237
3302
|
|
|
3238
3303
|
|
|
3239
3304
|
|
|
3305
|
+
|
|
3306
|
+
|
|
3240
3307
|
|
|
3241
3308
|
static parse(plain ) {
|
|
3242
3309
|
return new Meeting({
|
|
@@ -3249,6 +3316,7 @@ class Meeting {
|
|
|
3249
3316
|
extension: plain.exten,
|
|
3250
3317
|
persistent: plain.persistent,
|
|
3251
3318
|
creationTime: moment__default['default'](plain.creation_time).toDate(),
|
|
3319
|
+
requireAuthorization: plain.require_authorization,
|
|
3252
3320
|
});
|
|
3253
3321
|
}
|
|
3254
3322
|
|
|
@@ -3273,6 +3341,7 @@ class Meeting {
|
|
|
3273
3341
|
extension,
|
|
3274
3342
|
persistent,
|
|
3275
3343
|
creationTime,
|
|
3344
|
+
requireAuthorization,
|
|
3276
3345
|
} = {}) {
|
|
3277
3346
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
3278
3347
|
this.uri = uri;
|
|
@@ -3283,6 +3352,7 @@ class Meeting {
|
|
|
3283
3352
|
this.extension = extension;
|
|
3284
3353
|
this.persistent = persistent;
|
|
3285
3354
|
this.creationTime = creationTime;
|
|
3355
|
+
this.requireAuthorization = requireAuthorization;
|
|
3286
3356
|
|
|
3287
3357
|
// Useful to compare instead of instanceof with minified code
|
|
3288
3358
|
this.type = 'Meeting';
|
|
@@ -3293,8 +3363,32 @@ class Meeting {
|
|
|
3293
3363
|
const [username, secret] = atob(this.guestSipAuthorization).split(':');
|
|
3294
3364
|
return { username, secret };
|
|
3295
3365
|
}
|
|
3366
|
+
|
|
3296
3367
|
}
|
|
3297
3368
|
|
|
3369
|
+
//
|
|
3370
|
+
|
|
3371
|
+
const camelToUnderscore = (key ) => {
|
|
3372
|
+
if (typeof key !== 'string') {
|
|
3373
|
+
throw new Error('Input is not a string');
|
|
3374
|
+
}
|
|
3375
|
+
return key.charAt(0).toLowerCase() + key.substring(1).replace(/([A-Z])/g, '_$1').toLowerCase();
|
|
3376
|
+
};
|
|
3377
|
+
|
|
3378
|
+
//
|
|
3379
|
+
|
|
3380
|
+
const convertKeysFromCamelToUnderscore = (args ) => {
|
|
3381
|
+
if (!args || typeof args !== 'object' || Array.isArray(args)) {
|
|
3382
|
+
throw new Error('Input is not an object');
|
|
3383
|
+
}
|
|
3384
|
+
|
|
3385
|
+
return Object.keys(args).reduce((acc, key) => {
|
|
3386
|
+
acc[camelToUnderscore(key)] = typeof args[key] === 'object' && !Array.isArray(args[key])
|
|
3387
|
+
? convertKeysFromCamelToUnderscore(args[key]) : args[key];
|
|
3388
|
+
return acc;
|
|
3389
|
+
}, {});
|
|
3390
|
+
};
|
|
3391
|
+
|
|
3298
3392
|
/* */
|
|
3299
3393
|
|
|
3300
3394
|
var confdMethods = (client , baseUrl ) => ({
|
|
@@ -3363,8 +3457,18 @@ var confdMethods = (client , baseUrl ) => ({
|
|
|
3363
3457
|
getMyMeetings: () =>
|
|
3364
3458
|
client.get(`${baseUrl}/users/me/meetings`).then(response => Meeting.parseMany(response.items)),
|
|
3365
3459
|
|
|
3366
|
-
createMyMeeting: (
|
|
3367
|
-
client
|
|
3460
|
+
createMyMeeting: (args ) =>
|
|
3461
|
+
client
|
|
3462
|
+
.post(`${baseUrl}/users/me/meetings`, convertKeysFromCamelToUnderscore(args))
|
|
3463
|
+
.then(Meeting.parse),
|
|
3464
|
+
|
|
3465
|
+
updateMyMeeting: (meetingUuid , data ) =>
|
|
3466
|
+
client.put(
|
|
3467
|
+
`${baseUrl}/users/me/meetings/${meetingUuid}`,
|
|
3468
|
+
convertKeysFromCamelToUnderscore(data),
|
|
3469
|
+
null,
|
|
3470
|
+
ApiRequester.successResponseParser,
|
|
3471
|
+
),
|
|
3368
3472
|
|
|
3369
3473
|
deleteMyMeeting: (meetingUuid ) =>
|
|
3370
3474
|
client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
|
|
@@ -3372,8 +3476,36 @@ var confdMethods = (client , baseUrl ) => ({
|
|
|
3372
3476
|
getMeeting: (meetingUuid ) =>
|
|
3373
3477
|
client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
|
|
3374
3478
|
|
|
3479
|
+
meetingAuthorizations: (meetingUuid ) =>
|
|
3480
|
+
client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/authorizations`, null).then(MeetingAuthorization.parseMany),
|
|
3481
|
+
|
|
3482
|
+
meetingAuthorizationReject: (meetingUuid , authorizationUuid ) =>
|
|
3483
|
+
client.put(
|
|
3484
|
+
`${baseUrl}/users/me/meetings/${meetingUuid}/authorizations/${authorizationUuid}/reject`,
|
|
3485
|
+
{},
|
|
3486
|
+
null,
|
|
3487
|
+
ApiRequester.successResponseParser,
|
|
3488
|
+
),
|
|
3489
|
+
|
|
3490
|
+
meetingAuthorizationAccept: (meetingUuid , authorizationUuid ) =>
|
|
3491
|
+
client.put(
|
|
3492
|
+
`${baseUrl}/users/me/meetings/${meetingUuid}/authorizations/${authorizationUuid}/accept`,
|
|
3493
|
+
{},
|
|
3494
|
+
null,
|
|
3495
|
+
ApiRequester.successResponseParser,
|
|
3496
|
+
),
|
|
3497
|
+
|
|
3375
3498
|
guestGetMeeting: (meetingUuid ) =>
|
|
3376
3499
|
client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
|
|
3500
|
+
|
|
3501
|
+
guestAuthorizationRequest: (userUuid , meetingUuid , username ) =>
|
|
3502
|
+
client
|
|
3503
|
+
.post(`${baseUrl}/guests/${userUuid}/meetings/${meetingUuid}/authorizations`, { guest_name: username })
|
|
3504
|
+
.then(MeetingAuthorization.parse),
|
|
3505
|
+
|
|
3506
|
+
guestAuthorizationCheck: (userUuid , meetingUuid , authorizationUuid ) =>
|
|
3507
|
+
client.get(`${baseUrl}/guests/${userUuid}/meetings/${meetingUuid}/authorizations/${authorizationUuid}`, null),
|
|
3508
|
+
|
|
3377
3509
|
});
|
|
3378
3510
|
|
|
3379
3511
|
//
|
|
@@ -4812,6 +4944,14 @@ var calldMethods = (client , baseUrl ) => ({
|
|
|
4812
4944
|
getMeetingParticipantsAsUser: async (meetingUuid ) =>
|
|
4813
4945
|
client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
|
|
4814
4946
|
|
|
4947
|
+
banMeetingParticipant: (meetingUuid , participantUuid ) =>
|
|
4948
|
+
client.delete(
|
|
4949
|
+
`${baseUrl}/users/me/meetings/${meetingUuid}/participants/${participantUuid}`,
|
|
4950
|
+
null,
|
|
4951
|
+
null,
|
|
4952
|
+
ApiRequester.successResponseParser,
|
|
4953
|
+
),
|
|
4954
|
+
|
|
4815
4955
|
listTrunks: () => client.get(`${baseUrl}/trunks`),
|
|
4816
4956
|
|
|
4817
4957
|
mute: (callId ) =>
|
|
@@ -6455,7 +6595,7 @@ class WebRTCClient extends Emitter {
|
|
|
6455
6595
|
});
|
|
6456
6596
|
}
|
|
6457
6597
|
|
|
6458
|
-
changeAudioInputDevice(id , session , force ) {
|
|
6598
|
+
async changeAudioInputDevice(id , session , force ) {
|
|
6459
6599
|
const currentId = this.getAudioDeviceId();
|
|
6460
6600
|
logger.info('setting audio input device', { id, currentId, session: !!session });
|
|
6461
6601
|
|
|
@@ -6463,33 +6603,50 @@ class WebRTCClient extends Emitter {
|
|
|
6463
6603
|
return null;
|
|
6464
6604
|
}
|
|
6465
6605
|
|
|
6606
|
+
// in order to handle an audio track change for default devices
|
|
6607
|
+
// we need the actual id of the device (not 'default')
|
|
6608
|
+
let deviceId = id;
|
|
6609
|
+
if (id === 'default' && navigator.mediaDevices) {
|
|
6610
|
+
const devices = await navigator.mediaDevices.enumerateDevices();
|
|
6611
|
+
const defaultDevice = devices.find(device => device.deviceId === 'default');
|
|
6612
|
+
if (defaultDevice) {
|
|
6613
|
+
const deviceLabel = defaultDevice.label.replace('Default - ', '');
|
|
6614
|
+
const targetDevice = devices.find(device => device.label === deviceLabel);
|
|
6615
|
+
if (targetDevice) {
|
|
6616
|
+
deviceId = targetDevice.deviceId;
|
|
6617
|
+
if (!force && deviceId === currentId) {
|
|
6618
|
+
return null;
|
|
6619
|
+
}
|
|
6620
|
+
}
|
|
6621
|
+
}
|
|
6622
|
+
}
|
|
6623
|
+
|
|
6466
6624
|
// let's update the local audio value
|
|
6467
6625
|
if (this.audio) {
|
|
6468
6626
|
this.audio = {
|
|
6469
6627
|
deviceId: {
|
|
6470
|
-
exact:
|
|
6628
|
+
exact: deviceId,
|
|
6471
6629
|
},
|
|
6472
6630
|
};
|
|
6473
6631
|
}
|
|
6474
6632
|
|
|
6475
|
-
if (session) {
|
|
6633
|
+
if (session && navigator.mediaDevices) {
|
|
6476
6634
|
const sdh = session.sessionDescriptionHandler;
|
|
6477
6635
|
const pc = sdh.peerConnection;
|
|
6478
6636
|
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6637
|
+
const constraints = { audio: { deviceId: { exact: deviceId } } };
|
|
6638
|
+
const stream = await navigator.mediaDevices.getUserMedia(constraints);
|
|
6639
|
+
const audioTrack = stream.getAudioTracks()[0];
|
|
6640
|
+
const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
|
|
6483
6641
|
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
6487
|
-
}
|
|
6488
|
-
sender.replaceTrack(audioTrack);
|
|
6642
|
+
if (sender) {
|
|
6643
|
+
if (sender.track) {
|
|
6644
|
+
audioTrack.enabled = sender.track.enabled;
|
|
6489
6645
|
}
|
|
6646
|
+
sender.replaceTrack(audioTrack);
|
|
6647
|
+
}
|
|
6490
6648
|
|
|
6491
|
-
|
|
6492
|
-
});
|
|
6649
|
+
return stream;
|
|
6493
6650
|
}
|
|
6494
6651
|
}
|
|
6495
6652
|
|
|
@@ -6509,14 +6666,14 @@ class WebRTCClient extends Emitter {
|
|
|
6509
6666
|
return null;
|
|
6510
6667
|
}
|
|
6511
6668
|
|
|
6512
|
-
// let's
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
}
|
|
6519
|
-
}
|
|
6669
|
+
// let's make sure we don't lose other video constraints settings -- width, height, frameRate...
|
|
6670
|
+
const videoObject = typeof this.video === 'object' ? this.video : {};
|
|
6671
|
+
this.video = {
|
|
6672
|
+
...videoObject,
|
|
6673
|
+
deviceId: {
|
|
6674
|
+
exact: id,
|
|
6675
|
+
},
|
|
6676
|
+
};
|
|
6520
6677
|
}
|
|
6521
6678
|
|
|
6522
6679
|
changeSessionVideoInputDevice(id , session ) {
|
package/lib/websocket-client.js
CHANGED
|
@@ -617,6 +617,7 @@ const AGENT_UNPAUSED = 'agent_unpaused';
|
|
|
617
617
|
const CONFERENCE_ADHOC_PARTICIPANT_LEFT = 'conference_adhoc_participant_left';
|
|
618
618
|
const CONFERENCE_ADHOC_DELETED = 'conference_adhoc_deleted';
|
|
619
619
|
const MEETING_USER_PROGRESS = 'meeting_user_progress';
|
|
620
|
+
const MEETING_USER_GUEST_AUTHORIZATION_CREATED = 'meeting_user_guest_authorization_created';
|
|
620
621
|
|
|
621
622
|
const BLACKLIST_EVENTS = [
|
|
622
623
|
CHAT_MESSAGE_SENT,
|
|
@@ -968,6 +969,7 @@ WebSocketClient.eventLists = [
|
|
|
968
969
|
CONFERENCE_ADHOC_PARTICIPANT_LEFT,
|
|
969
970
|
CONFERENCE_ADHOC_DELETED,
|
|
970
971
|
MEETING_USER_PROGRESS,
|
|
972
|
+
MEETING_USER_GUEST_AUTHORIZATION_CREATED,
|
|
971
973
|
];
|
|
972
974
|
|
|
973
975
|
exports.AGENT_PAUSED = AGENT_PAUSED;
|
|
@@ -1021,6 +1023,7 @@ exports.FAX_OUTBOUND_USER_FAILED = FAX_OUTBOUND_USER_FAILED;
|
|
|
1021
1023
|
exports.FAX_OUTBOUND_USER_SUCCEEDED = FAX_OUTBOUND_USER_SUCCEEDED;
|
|
1022
1024
|
exports.HEARTBEAT_ENGINE_VERSION = HEARTBEAT_ENGINE_VERSION;
|
|
1023
1025
|
exports.LINE_STATUS_UPDATED = LINE_STATUS_UPDATED;
|
|
1026
|
+
exports.MEETING_USER_GUEST_AUTHORIZATION_CREATED = MEETING_USER_GUEST_AUTHORIZATION_CREATED;
|
|
1024
1027
|
exports.MEETING_USER_PARTICIPANT_JOINED = MEETING_USER_PARTICIPANT_JOINED;
|
|
1025
1028
|
exports.MEETING_USER_PARTICIPANT_LEFT = MEETING_USER_PARTICIPANT_LEFT;
|
|
1026
1029
|
exports.MEETING_USER_PROGRESS = MEETING_USER_PROGRESS;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wazo/sdk",
|
|
3
|
-
"version": "0.38.
|
|
3
|
+
"version": "0.38.8",
|
|
4
4
|
"description": "Wazo's JavaScript Software Development Kit.",
|
|
5
5
|
"main": "dist/wazo-sdk.js",
|
|
6
6
|
"author": "Wazo (http://wazo.io)",
|
|
@@ -100,4 +100,4 @@
|
|
|
100
100
|
"react-native": {
|
|
101
101
|
"node-fetch/lib/index": false
|
|
102
102
|
}
|
|
103
|
-
}
|
|
103
|
+
}
|
|
@@ -69,27 +69,70 @@ describe('changeAudioInputDevice', () => {
|
|
|
69
69
|
});
|
|
70
70
|
});
|
|
71
71
|
|
|
72
|
+
const devices = [
|
|
73
|
+
{ deviceId: 'default', kind: 'audioinput', label: 'Default - Fake Microphone', groupId: 'fak3Gr0up3' },
|
|
74
|
+
{ deviceId: 'fak3d3v1c3', kind: 'audioinput', label: 'Fake Microphone', groupId: 'fak3Gr0up3' },
|
|
75
|
+
];
|
|
76
|
+
const enumerateDevicesMock = jest.fn(async () => {
|
|
77
|
+
return new Promise(resolve => {
|
|
78
|
+
resolve(devices);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
72
82
|
Object.defineProperty(global.navigator, 'mediaDevices', {
|
|
73
83
|
value: {
|
|
74
84
|
getUserMedia: getUserMediaMock,
|
|
85
|
+
enumerateDevices: enumerateDevicesMock,
|
|
75
86
|
},
|
|
76
87
|
});
|
|
77
88
|
|
|
78
89
|
it('should change the audio input track if the provided id is different', async () => {
|
|
79
90
|
client.setMediaConstraints(constraints);
|
|
80
91
|
expect(client.getAudioDeviceId()).toBe(defaultId);
|
|
81
|
-
|
|
92
|
+
const result = await client.changeAudioInputDevice(deviceId, session);
|
|
93
|
+
expect(result).toBeTruthy();
|
|
82
94
|
});
|
|
83
95
|
|
|
84
96
|
it('should NOT change the audio input track if the provided id is the same', async () => {
|
|
85
97
|
client.setMediaConstraints(constraints);
|
|
86
98
|
expect(client.getAudioDeviceId()).toBe(defaultId);
|
|
87
|
-
|
|
99
|
+
const result = await client.changeAudioInputDevice(defaultId, session);
|
|
100
|
+
expect(result).toBeFalsy();
|
|
88
101
|
});
|
|
89
102
|
|
|
90
103
|
it('should change the audio input track if the provided id is the same and force param is TRUE', async () => {
|
|
91
104
|
client.setMediaConstraints(constraints);
|
|
92
105
|
expect(client.getAudioDeviceId()).toBe(defaultId);
|
|
93
|
-
|
|
106
|
+
const result = await client.changeAudioInputDevice(defaultId, session, true);
|
|
107
|
+
expect(result).toBeTruthy();
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
describe('setVideoInputDevice', () => {
|
|
111
|
+
it('should retain its original video values', () => {
|
|
112
|
+
const video = { height: { min: 480, max: 720 }, width: { min: 640, max: 1280 } };
|
|
113
|
+
|
|
114
|
+
client.video = video;
|
|
115
|
+
client.setVideoInputDevice(deviceId);
|
|
116
|
+
expect(client.video).toEqual({ ...video, deviceId: { exact: deviceId } });
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('should set deviceId when video\'s original value is true', () => {
|
|
120
|
+
client.video = true;
|
|
121
|
+
client.setVideoInputDevice(deviceId);
|
|
122
|
+
expect(client.video).toEqual({ deviceId: { exact: deviceId } });
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('should set deviceId when video\'s original value is not set', () => {
|
|
126
|
+
client.video = undefined;
|
|
127
|
+
client.setVideoInputDevice(deviceId);
|
|
128
|
+
expect(client.video).toEqual({ deviceId: { exact: deviceId } });
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('should NOT set deviceId when its value does not change', () => {
|
|
132
|
+
client.video = { deviceId: { exact: deviceId } };
|
|
133
|
+
const result = client.setVideoInputDevice(deviceId);
|
|
134
|
+
expect(result).toEqual(null);
|
|
135
|
+
expect(client.video).toEqual({ deviceId: { exact: deviceId } });
|
|
136
|
+
});
|
|
94
137
|
});
|
|
95
138
|
});
|
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: (
|
|
76
|
-
client
|
|
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/domain/Meeting.js
CHANGED
|
@@ -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
|
+
}
|