diff --git a/.eslintignore.errorfiles b/.eslintignore.errorfiles
index ffc3b21181..381c7cfd70 100644
--- a/.eslintignore.errorfiles
+++ b/.eslintignore.errorfiles
@@ -9,7 +9,6 @@ src/components/structures/UploadBar.js
src/components/views/avatars/MemberAvatar.js
src/components/views/create_room/RoomAlias.js
src/components/views/dialogs/SetPasswordDialog.js
-src/components/views/dialogs/UnknownDeviceDialog.js
src/components/views/elements/AddressSelector.js
src/components/views/elements/DirectorySearchBox.js
src/components/views/elements/MemberEventListSummary.js
diff --git a/res/css/_components.scss b/res/css/_components.scss
index 44c63b9df7..37a97d27e4 100644
--- a/res/css/_components.scss
+++ b/res/css/_components.scss
@@ -81,7 +81,6 @@
@import "./views/dialogs/_SlashCommandHelpDialog.scss";
@import "./views/dialogs/_TabbedIntegrationManagerDialog.scss";
@import "./views/dialogs/_TermsDialog.scss";
-@import "./views/dialogs/_UnknownDeviceDialog.scss";
@import "./views/dialogs/_UploadConfirmDialog.scss";
@import "./views/dialogs/_UserSettingsDialog.scss";
@import "./views/dialogs/_WidgetOpenIDPermissionsDialog.scss";
diff --git a/res/css/views/dialogs/_UnknownDeviceDialog.scss b/res/css/views/dialogs/_UnknownDeviceDialog.scss
deleted file mode 100644
index daa6bd2352..0000000000
--- a/res/css/views/dialogs/_UnknownDeviceDialog.scss
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-Copyright 2016 OpenMarket 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.
-*/
-
-.mx_UnknownDeviceDialog {
- height: 100%;
- display: flex;
- flex-direction: column;
-}
-
-.mx_UnknownDeviceDialog ul {
- list-style: none;
- padding: 0;
-}
-// userid
-.mx_UnknownDeviceDialog p {
- font-weight: bold;
- font-size: $font-16px;
-}
-
-.mx_UnknownDeviceDialog .mx_DeviceVerifyButtons {
- flex-direction: row !important;
-}
-
-.mx_UnknownDeviceDialog .mx_Dialog_content {
- margin-bottom: 24px;
- overflow-y: scroll;
-}
-
-.mx_UnknownDeviceDialog_deviceList > li {
- padding: 4px;
-}
-
-.mx_UnknownDeviceDialog_deviceList > li > * {
- padding-bottom: 0;
-}
diff --git a/src/CallHandler.js b/src/CallHandler.js
index c95ed16eb3..e3916c25d6 100644
--- a/src/CallHandler.js
+++ b/src/CallHandler.js
@@ -60,7 +60,6 @@ import * as sdk from './index';
import { _t } from './languageHandler';
import Matrix from 'matrix-js-sdk';
import dis from './dispatcher/dispatcher';
-import { showUnknownDeviceDialogForCalls } from './cryptodevices';
import WidgetUtils from './utils/WidgetUtils';
import WidgetEchoStore from './stores/WidgetEchoStore';
import SettingsStore, { SettingLevel } from './settings/SettingsStore';
@@ -134,47 +133,19 @@ function _reAttemptCall(call) {
function _setCallListeners(call) {
call.on("error", function(err) {
console.error("Call error:", err);
- 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 sessions in this room: "+
- "if you proceed without verifying them, it will be "+
- "possible for someone to eavesdrop on your call.",
- ),
- button: _t('Review Sessions'),
- onFinished: function(confirmed) {
- if (confirmed) {
- const room = MatrixClientPeg.get().getRoom(call.roomId);
- showUnknownDeviceDialogForCalls(
- MatrixClientPeg.get(),
- room,
- () => {
- _reAttemptCall(call);
- },
- call.direction === 'outbound' ? _t("Call Anyway") : _t("Answer Anyway"),
- call.direction === 'outbound' ? _t("Call") : _t("Answer"),
- );
- }
- },
- });
- } else {
- if (
- MatrixClientPeg.get().getTurnServers().length === 0 &&
- SettingsStore.getValue("fallbackICEServerAllowed") === null
- ) {
- _showICEFallbackPrompt();
- return;
- }
-
- const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
- Modal.createTrackedDialog('Call Failed', '', ErrorDialog, {
- title: _t('Call Failed'),
- description: err.message,
- });
+ if (
+ MatrixClientPeg.get().getTurnServers().length === 0 &&
+ SettingsStore.getValue("fallbackICEServerAllowed") === null
+ ) {
+ _showICEFallbackPrompt();
+ return;
}
+
+ const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
+ Modal.createTrackedDialog('Call Failed', '', ErrorDialog, {
+ title: _t('Call Failed'),
+ description: err.message,
+ });
});
call.on("hangup", function() {
_setCallState(undefined, call.roomId, "ended");
diff --git a/src/components/structures/RoomStatusBar.js b/src/components/structures/RoomStatusBar.js
index ae628fd06a..dd4b9759d6 100644
--- a/src/components/structures/RoomStatusBar.js
+++ b/src/components/structures/RoomStatusBar.js
@@ -24,7 +24,6 @@ import { _t, _td } from '../../languageHandler';
import * as sdk from '../../index';
import {MatrixClientPeg} from '../../MatrixClientPeg';
import Resend from '../../Resend';
-import * as cryptodevices from '../../cryptodevices';
import dis from '../../dispatcher/dispatcher';
import {messageForResourceLimitError, messageForSendError} from '../../utils/ErrorUtils';
@@ -126,13 +125,6 @@ export default createReactClass({
});
},
- _onSendWithoutVerifyingClick: function() {
- cryptodevices.getUnknownDevicesForRoom(MatrixClientPeg.get(), this.props.room).then((devices) => {
- cryptodevices.markAllDevicesKnown(MatrixClientPeg.get(), devices);
- Resend.resendUnsentEvents(this.props.room);
- });
- },
-
_onResendAllClick: function() {
Resend.resendUnsentEvents(this.props.room);
dis.dispatch({action: 'focus_composer'});
@@ -143,10 +135,6 @@ export default createReactClass({
dis.dispatch({action: 'focus_composer'});
},
- _onShowDevicesClick: function() {
- cryptodevices.showUnknownDeviceDialogForMessages(MatrixClientPeg.get(), this.props.room);
- },
-
_onRoomLocalEchoUpdated: function(event, room, oldEventId, oldStatus) {
if (room.roomId !== this.props.room.roomId) return;
@@ -213,82 +201,65 @@ export default createReactClass({
if (!unsentMessages.length) return null;
let title;
- let content;
- const hasUDE = unsentMessages.some((m) => {
- return m.error && m.error.name === "UnknownDeviceError";
- });
-
- if (hasUDE) {
- title = _t("Message not sent due to unknown sessions being present");
- content = _t(
- "Show sessions, send anyway or cancel.",
+ let consentError = null;
+ let resourceLimitError = null;
+ for (const m of unsentMessages) {
+ if (m.error && m.error.errcode === 'M_CONSENT_NOT_GIVEN') {
+ consentError = m.error;
+ break;
+ } else if (m.error && m.error.errcode === 'M_RESOURCE_LIMIT_EXCEEDED') {
+ resourceLimitError = m.error;
+ break;
+ }
+ }
+ if (consentError) {
+ title = _t(
+ "You can't send any messages until you review and agree to " +
+ "our terms and conditions.",
{},
{
- 'showSessionsText': (sub) => { sub },
- 'sendAnywayText': (sub) => { sub },
- 'cancelText': (sub) => { sub },
+ 'consentLink': (sub) =>
+
+ { sub }
+ ,
},
);
+ } else if (resourceLimitError) {
+ title = messageForResourceLimitError(
+ resourceLimitError.data.limit_type,
+ resourceLimitError.data.admin_contact, {
+ 'monthly_active_user': _td(
+ "Your message wasn't sent because this homeserver has hit its Monthly Active User Limit. " +
+ "Please contact your service administrator to continue using the service.",
+ ),
+ '': _td(
+ "Your message wasn't sent because this homeserver has exceeded a resource limit. " +
+ "Please contact your service administrator to continue using the service.",
+ ),
+ });
+ } else if (
+ unsentMessages.length === 1 &&
+ unsentMessages[0].error &&
+ unsentMessages[0].error.data &&
+ unsentMessages[0].error.data.error
+ ) {
+ title = messageForSendError(unsentMessages[0].error.data) || unsentMessages[0].error.data.error;
} else {
- let consentError = null;
- let resourceLimitError = null;
- for (const m of unsentMessages) {
- if (m.error && m.error.errcode === 'M_CONSENT_NOT_GIVEN') {
- consentError = m.error;
- break;
- } else if (m.error && m.error.errcode === 'M_RESOURCE_LIMIT_EXCEEDED') {
- resourceLimitError = m.error;
- break;
- }
- }
- if (consentError) {
- title = _t(
- "You can't send any messages until you review and agree to " +
- "our terms and conditions.",
- {},
- {
- 'consentLink': (sub) =>
-
- { sub }
- ,
- },
- );
- } else if (resourceLimitError) {
- title = messageForResourceLimitError(
- resourceLimitError.data.limit_type,
- resourceLimitError.data.admin_contact, {
- 'monthly_active_user': _td(
- "Your message wasn't sent because this homeserver has hit its Monthly Active User Limit. " +
- "Please contact your service administrator to continue using the service.",
- ),
- '': _td(
- "Your message wasn't sent because this homeserver has exceeded a resource limit. " +
- "Please contact your service administrator to continue using the service.",
- ),
- });
- } else if (
- unsentMessages.length === 1 &&
- unsentMessages[0].error &&
- unsentMessages[0].error.data &&
- unsentMessages[0].error.data.error
- ) {
- title = messageForSendError(unsentMessages[0].error.data) || unsentMessages[0].error.data.error;
- } else {
- title = _t('%(count)s of your messages have not been sent.', { count: unsentMessages.length });
- }
- content = _t("%(count)s Resend all or cancel all now. " +
- "You can also select individual messages to resend or cancel.",
- { count: unsentMessages.length },
- {
- 'resendText': (sub) =>
- { sub },
- 'cancelText': (sub) =>
- { sub },
- },
- );
+ title = _t('%(count)s of your messages have not been sent.', { count: unsentMessages.length });
}
+ const content = _t("%(count)s Resend all or cancel all " +
+ "now. You can also select individual messages to resend or cancel.",
+ { count: unsentMessages.length },
+ {
+ 'resendText': (sub) =>
+ { sub },
+ 'cancelText': (sub) =>
+ { sub },
+ },
+ );
+
return
diff --git a/src/components/views/dialogs/UnknownDeviceDialog.js b/src/components/views/dialogs/UnknownDeviceDialog.js
deleted file mode 100644
index 4cad13b047..0000000000
--- a/src/components/views/dialogs/UnknownDeviceDialog.js
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
-Copyright 2017 Vector Creations Ltd
-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.
-*/
-
-import React from 'react';
-import createReactClass from 'create-react-class';
-import PropTypes from 'prop-types';
-import * as sdk from '../../../index';
-import {MatrixClientPeg} from '../../../MatrixClientPeg';
-import { _t } from '../../../languageHandler';
-import SettingsStore from "../../../settings/SettingsStore";
-import { markAllDevicesKnown } from '../../../cryptodevices';
-
-function UserUnknownDeviceList(props) {
- const MemberDeviceInfo = sdk.getComponent('rooms.MemberDeviceInfo');
- const {userId, userDevices} = props;
-
- const deviceListEntries = Object.keys(userDevices).map((deviceId) =>
-
,
- );
-
- return (
-
- { deviceListEntries }
-
- );
-}
-
-UserUnknownDeviceList.propTypes = {
- userId: PropTypes.string.isRequired,
-
- // map from deviceid -> deviceinfo
- userDevices: PropTypes.object.isRequired,
-};
-
-
-function UnknownDeviceList(props) {
- const {devices} = props;
-
- const userListEntries = Object.keys(devices).map((userId) =>
-
- { userId }:
-
- ,
- );
-
- return
;
-}
-
-UnknownDeviceList.propTypes = {
- // map from userid -> deviceid -> deviceinfo
- devices: PropTypes.object.isRequired,
-};
-
-
-export default createReactClass({
- displayName: 'UnknownDeviceDialog',
-
- propTypes: {
- room: PropTypes.object.isRequired,
-
- // map from userid -> deviceid -> deviceinfo or null if devices are not yet loaded
- devices: PropTypes.object,
-
- onFinished: PropTypes.func.isRequired,
-
- // Label for the button that marks all devices known and tries the send again
- sendAnywayLabel: PropTypes.string.isRequired,
-
- // Label for the button that to send the event if you've verified all devices
- sendLabel: PropTypes.string.isRequired,
-
- // function to retry the request once all devices are verified / known
- onSend: PropTypes.func.isRequired,
- },
-
- componentDidMount: function() {
- MatrixClientPeg.get().on("deviceVerificationChanged", this._onDeviceVerificationChanged);
- },
-
- componentWillUnmount: function() {
- if (MatrixClientPeg.get()) {
- MatrixClientPeg.get().removeListener("deviceVerificationChanged", this._onDeviceVerificationChanged);
- }
- },
-
- _onDeviceVerificationChanged: function(userId, deviceId, deviceInfo) {
- if (this.props.devices[userId] && this.props.devices[userId][deviceId]) {
- // XXX: Mutating props :/
- this.props.devices[userId][deviceId] = deviceInfo;
- this.forceUpdate();
- }
- },
-
- _onDismissClicked: function() {
- this.props.onFinished();
- },
-
- _onSendAnywayClicked: function() {
- markAllDevicesKnown(MatrixClientPeg.get(), this.props.devices);
-
- this.props.onFinished();
- this.props.onSend();
- },
-
- _onSendClicked: function() {
- this.props.onFinished();
- this.props.onSend();
- },
-
- render: function() {
- if (this.props.devices === null) {
- const Spinner = sdk.getComponent("elements.Spinner");
- return
;
- }
-
- let warning;
- if (SettingsStore.getValue("blacklistUnverifiedDevices", this.props.room.roomId)) {
- warning = (
-
- { _t("You are currently blacklisting unverified sessions; to send " +
- "messages to these sessions you must verify them.") }
-
- );
- } else {
- warning = (
-
-
- { _t("We recommend you go through the verification process " +
- "for each session to confirm they belong to their legitimate owner, " +
- "but you can resend the message without verifying if you prefer.") }
-
-
- );
- }
-
- let haveUnknownDevices = false;
- Object.keys(this.props.devices).forEach((userId) => {
- Object.keys(this.props.devices[userId]).map((deviceId) => {
- const device = this.props.devices[userId][deviceId];
- if (device.isUnverified() && !device.isKnown()) {
- haveUnknownDevices = true;
- }
- });
- });
- const sendButtonOnClick = haveUnknownDevices ? this._onSendAnywayClicked : this._onSendClicked;
- const sendButtonLabel = haveUnknownDevices ? this.props.sendAnywayLabel : this.props.sendAnywayLabel;
-
- const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
- const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
- return (
-
-
-
- { _t('"%(RoomName)s" contains sessions that you haven\'t seen before.', {RoomName: this.props.room.name}) }
-
- { warning }
- { _t("Unknown sessions") }:
-
-
-
-
-
- );
- // XXX: do we want to give the user the option to enable blacklistUnverifiedDevices for this room (or globally) at this point?
- // It feels like confused users will likely turn it on and then disappear in a cloud of UISIs...
- },
-});
diff --git a/src/cryptodevices.js b/src/cryptodevices.js
deleted file mode 100644
index 86b97364f9..0000000000
--- a/src/cryptodevices.js
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
-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.
-*/
-
-import Resend from './Resend';
-import * as sdk from './index';
-import dis from './dispatcher/dispatcher';
-import Modal from './Modal';
-import { _t } from './languageHandler';
-
-/**
- * Mark all given devices as 'known'
- *
- * @param {MatrixClient} matrixClient A MatrixClient
- * @param {Object} devices Map from userid -> deviceid -> deviceinfo
- */
-export function markAllDevicesKnown(matrixClient, devices) {
- Object.keys(devices).forEach((userId) => {
- Object.keys(devices[userId]).map((deviceId) => {
- matrixClient.setDeviceKnown(userId, deviceId, true);
- });
- });
-}
-
-/**
- * Gets all crypto devices in a room that are marked neither known
- * nor verified.
- *
- * @param {MatrixClient} matrixClient A MatrixClient
- * @param {Room} room js-sdk room object representing the room
- * @return {Promise} A promise which resolves to a map userId->deviceId->{@link
- * module:crypto~DeviceInfo|DeviceInfo}.
- */
-export async function getUnknownDevicesForRoom(matrixClient, room) {
- const roomMembers = (await room.getEncryptionTargetMembers()).map((m) => {
- return m.userId;
- });
- const devices = await matrixClient.downloadKeys(roomMembers, false);
- 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;
-}
-
-function focusComposer() {
- dis.dispatch({action: 'focus_composer'});
-}
-
-/**
- * Show the UnknownDeviceDialog for a given room. The dialog will inform the user
- * that messages they sent to this room have not been sent due to unknown devices
- * being present.
- *
- * @param {MatrixClient} matrixClient A MatrixClient
- * @param {Room} room js-sdk room object representing the room
- */
-export function showUnknownDeviceDialogForMessages(matrixClient, room) {
- getUnknownDevicesForRoom(matrixClient, room).then((unknownDevices) => {
- const onSendClicked = () => {
- Resend.resendUnsentEvents(room);
- };
-
- const UnknownDeviceDialog = sdk.getComponent('dialogs.UnknownDeviceDialog');
- Modal.createTrackedDialog('Unknown Device Dialog', '', UnknownDeviceDialog, {
- room: room,
- devices: unknownDevices,
- sendAnywayLabel: _t("Send anyway"),
- sendLabel: _t("Send"),
- onSend: onSendClicked,
- onFinished: focusComposer,
- }, 'mx_Dialog_unknownDevice');
- });
-}
-
-/**
- * Show the UnknownDeviceDialog for a given room. The dialog will inform the user
- * that a call they tried to place or answer in the room couldn't be placed or
- * answered due to unknown devices being present.
- *
- * @param {MatrixClient} matrixClient A MatrixClient
- * @param {Room} room js-sdk room object representing the room
- * @param {func} sendAnyway Function called when the 'call anyway' or 'call'
- * button is pressed. This should attempt to place or answer the call again.
- * @param {string} sendAnywayLabel Label for the button displayed to retry the call
- * when unknown devices are still present (eg. "Call Anyway")
- * @param {string} sendLabel Label for the button displayed to retry the call
- * after all devices have been verified (eg. "Call")
- */
-export function showUnknownDeviceDialogForCalls(matrixClient, room, sendAnyway, sendAnywayLabel, sendLabel) {
- getUnknownDevicesForRoom(matrixClient, room).then((unknownDevices) => {
- const UnknownDeviceDialog = sdk.getComponent('dialogs.UnknownDeviceDialog');
- Modal.createTrackedDialog('Unknown Device Dialog', '', UnknownDeviceDialog, {
- room: room,
- devices: unknownDevices,
- sendAnywayLabel: sendAnywayLabel,
- sendLabel: sendLabel,
- onSend: sendAnyway,
- }, 'mx_Dialog_unknownDevice');
- });
-}