Catch call failures due to unknown devices

And show a specific dialog that you can then launch the UDD from
(although currently with a 'Send Anyway' button which makes little
sense for VoIP)
This commit is contained in:
David Baker 2017-11-15 10:49:29 +00:00
parent 0659ac1ccb
commit 63919befd0
4 changed files with 73 additions and 28 deletions

View file

@ -59,6 +59,7 @@ import sdk from './index';
import { _t } from './languageHandler'; import { _t } from './languageHandler';
import Matrix from 'matrix-js-sdk'; import Matrix from 'matrix-js-sdk';
import dis from './dispatcher'; import dis from './dispatcher';
import { getUnknownDevicesForRoom } from './cryptodevices';
global.mxCalls = { global.mxCalls = {
//room_id: MatrixCall //room_id: MatrixCall
@ -104,6 +105,31 @@ function _setCallListeners(call) {
console.error(err.stack); console.error(err.stack);
call.hangup(); call.hangup();
_setCallState(undefined, call.roomId, "ended"); _setCallState(undefined, call.roomId, "ended");
if (err.code === 'unknown_devices') {
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
Modal.createTrackedDialog('Call Failed', '', QuestionDialog, {
title: _t('Call Failed'),
description: _t(
"There are unknown devices in this room: "+
"if you proceed without verifying them, it will be "+
"possible for someone to eavesdrop on your call"
),
button: _t('Review Devices'),
onFinished: function(confirmed) {
if (confirmed) {
const room = MatrixClientPeg.get().getRoom(call.roomId);
getUnknownDevicesForRoom(MatrixClientPeg.get(), room).then((unknownDevices) => {
const UnknownDeviceDialog = sdk.getComponent('dialogs.UnknownDeviceDialog');
Modal.createTrackedDialog('Unknown Device Dialog', '', UnknownDeviceDialog, {
room: room,
devices: unknownDevices,
}, 'mx_Dialog_unknownDevice');
});
}
},
});
}
}); });
call.on("hangup", function() { call.on("hangup", function() {
_setCallState(undefined, call.roomId, "ended"); _setCallState(undefined, call.roomId, "ended");
@ -171,7 +197,6 @@ function _setCallState(call, roomId, status) {
function _onAction(payload) { function _onAction(payload) {
function placeCall(newCall) { function placeCall(newCall) {
_setCallListeners(newCall); _setCallListeners(newCall);
_setCallState(newCall, newCall.roomId, "ringback");
if (payload.type === 'voice') { if (payload.type === 'voice') {
newCall.placeVoiceCall(); newCall.placeVoiceCall();
} else if (payload.type === 'video') { } else if (payload.type === 'video') {

View file

@ -24,6 +24,7 @@ import MatrixClientPeg from '../../MatrixClientPeg';
import MemberAvatar from '../views/avatars/MemberAvatar'; import MemberAvatar from '../views/avatars/MemberAvatar';
import Resend from '../../Resend'; import Resend from '../../Resend';
import Modal from '../../Modal'; import Modal from '../../Modal';
import { getUnknownDevicesForRoom } from '../../cryptodevices';
const HIDE_DEBOUNCE_MS = 10000; const HIDE_DEBOUNCE_MS = 10000;
const STATUS_BAR_HIDDEN = 0; const STATUS_BAR_HIDDEN = 0;
@ -157,7 +158,9 @@ module.exports = React.createClass({
}, },
_onShowDevicesClick: function() { _onShowDevicesClick: function() {
this._getUnknownDevices().then((unknownDevices) => { getUnknownDevicesForRoom(MatrixClientPeg.get(), this.props.room).then((unknownDevices) => {
if (this._unmounted) return;
const UnknownDeviceDialog = sdk.getComponent('dialogs.UnknownDeviceDialog'); const UnknownDeviceDialog = sdk.getComponent('dialogs.UnknownDeviceDialog');
Modal.createTrackedDialog('Unknown Device Dialog', '', UnknownDeviceDialog, { Modal.createTrackedDialog('Unknown Device Dialog', '', UnknownDeviceDialog, {
room: this.props.room, room: this.props.room,
@ -166,31 +169,6 @@ module.exports = React.createClass({
}); });
}, },
_getUnknownDevices: function() {
const roomMembers = this.props.room.getJoinedMembers().map((m) => {
return m.userId;
});
return MatrixClientPeg.get().downloadKeys(roomMembers, false).then((devices) => {
if (this._unmounted) return;
const unknownDevices = {};
// This is all devices in this room, so find the unknown ones.
Object.keys(devices).forEach((userId) => {
Object.keys(devices[userId]).map((deviceId) => {
const device = devices[userId][deviceId];
if (device.isUnverified() && !device.isKnown()) {
if (unknownDevices[userId] === undefined) {
unknownDevices[userId] = {};
}
unknownDevices[userId][deviceId] = device;
}
});
});
return unknownDevices;
});
},
onRoomLocalEchoUpdated: function(event, room, oldEventId, oldStatus) { onRoomLocalEchoUpdated: function(event, room, oldEventId, oldStatus) {
if (room.roomId !== this.props.room.roomId) return; if (room.roomId !== this.props.room.roomId) return;

39
src/cryptodevices.js Normal file
View file

@ -0,0 +1,39 @@
/*
Copyright 2017 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export function getUnknownDevicesForRoom(matrixClient, room) {
const roomMembers = room.getJoinedMembers().map((m) => {
return m.userId;
});
return matrixClient.downloadKeys(roomMembers, false).then((devices) => {
const unknownDevices = {};
// This is all devices in this room, so find the unknown ones.
Object.keys(devices).forEach((userId) => {
Object.keys(devices[userId]).map((deviceId) => {
const device = devices[userId][deviceId];
if (device.isUnverified() && !device.isKnown()) {
if (unknownDevices[userId] === undefined) {
unknownDevices[userId] = {};
}
unknownDevices[userId][deviceId] = device;
}
});
});
return unknownDevices;
});
}

View file

@ -2,6 +2,9 @@
"This email address is already in use": "This email address is already in use", "This email address is already in use": "This email address is already in use",
"This phone number is already in use": "This phone number is already in use", "This phone number is already in use": "This phone number is already in use",
"Failed to verify email address: make sure you clicked the link in the email": "Failed to verify email address: make sure you clicked the link in the email", "Failed to verify email address: make sure you clicked the link in the email": "Failed to verify email address: make sure you clicked the link in the email",
"Call Failed": "Call Failed",
"There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call": "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call",
"Review Devices": "Review Devices",
"Call Timeout": "Call Timeout", "Call Timeout": "Call Timeout",
"The remote side failed to pick up": "The remote side failed to pick up", "The remote side failed to pick up": "The remote side failed to pick up",
"Unable to capture screen": "Unable to capture screen", "Unable to capture screen": "Unable to capture screen",
@ -150,7 +153,6 @@
"%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s widget modified by %(senderName)s", "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s widget modified by %(senderName)s",
"%(widgetName)s widget added by %(senderName)s": "%(widgetName)s widget added by %(senderName)s", "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s widget added by %(senderName)s",
"%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s widget removed by %(senderName)s", "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s widget removed by %(senderName)s",
"Communities": "Communities",
"Message Pinning": "Message Pinning", "Message Pinning": "Message Pinning",
"%(displayName)s is typing": "%(displayName)s is typing", "%(displayName)s is typing": "%(displayName)s is typing",
"%(names)s and %(count)s others are typing|other": "%(names)s and %(count)s others are typing", "%(names)s and %(count)s others are typing|other": "%(names)s and %(count)s others are typing",
@ -524,6 +526,7 @@
"Unverify": "Unverify", "Unverify": "Unverify",
"Verify...": "Verify...", "Verify...": "Verify...",
"No results": "No results", "No results": "No results",
"Communities": "Communities",
"Home": "Home", "Home": "Home",
"Integrations Error": "Integrations Error", "Integrations Error": "Integrations Error",
"Could not connect to the integration server": "Could not connect to the integration server", "Could not connect to the integration server": "Could not connect to the integration server",