From 2df72bfde2570e42d9960fa76dadd3a0d1450157 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Fri, 13 Dec 2019 17:57:26 +0000 Subject: [PATCH] Update room / user decoration for cross-signing --- res/css/views/rooms/_E2EIcon.scss | 16 ++++-- src/components/structures/RoomView.js | 41 ++++++++++++--- src/components/views/right_panel/UserInfo.js | 20 ++++++-- src/components/views/rooms/E2EIcon.js | 54 +++++++++++++++++--- src/i18n/strings/en_EN.json | 7 ++- 5 files changed, 114 insertions(+), 24 deletions(-) diff --git a/res/css/views/rooms/_E2EIcon.scss b/res/css/views/rooms/_E2EIcon.scss index cb99aa63f1..584ea17433 100644 --- a/res/css/views/rooms/_E2EIcon.scss +++ b/res/css/views/rooms/_E2EIcon.scss @@ -22,7 +22,9 @@ limitations under the License. display: block; } -.mx_E2EIcon_verified::after, .mx_E2EIcon_warning::after { +.mx_E2EIcon_warning::after, +.mx_E2EIcon_normal::after, +.mx_E2EIcon_verified::after { content: ""; display: block; position: absolute; @@ -34,10 +36,14 @@ limitations under the License. background-size: contain; } -.mx_E2EIcon_verified::after { - background-image: url('$(res)/img/e2e/verified.svg'); -} - .mx_E2EIcon_warning::after { background-image: url('$(res)/img/e2e/warning.svg'); } + +.mx_E2EIcon_normal::after { + background-image: url('$(res)/img/e2e/normal.svg'); +} + +.mx_E2EIcon_verified::after { + background-image: url('$(res)/img/e2e/verified.svg'); +} diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index d78c9923c2..8c05acf60a 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -792,11 +792,12 @@ module.exports = createReactClass({ this._updateE2EStatus(room); }, - _updateE2EStatus: function(room) { - if (!MatrixClientPeg.get().isRoomEncrypted(room.roomId)) { + _updateE2EStatus: async function(room) { + const cli = MatrixClientPeg.get(); + if (!cli.isRoomEncrypted(room.roomId)) { return; } - if (!MatrixClientPeg.get().isCryptoEnabled()) { + if (!cli.isCryptoEnabled()) { // If crypto is not currently enabled, we aren't tracking devices at all, // so we don't know what the answer is. Let's error on the safe side and show // a warning for this case. @@ -805,10 +806,38 @@ module.exports = createReactClass({ }); return; } - room.hasUnverifiedDevices().then((hasUnverifiedDevices) => { - this.setState({ - e2eStatus: hasUnverifiedDevices ? "warning" : "verified", + if (!SettingsStore.isFeatureEnabled("feature_cross_signing")) { + room.hasUnverifiedDevices().then((hasUnverifiedDevices) => { + this.setState({ + e2eStatus: hasUnverifiedDevices ? "warning" : "verified", + }); }); + return; + } + const e2eMembers = await room.getEncryptionTargetMembers(); + for (const member of e2eMembers) { + const { userId } = member; + const userVerified = cli.checkUserTrust(userId).isCrossSigningVerified(); + if (!userVerified) { + this.setState({ + e2eStatus: "warning", + }); + return; + } + const devices = await cli.getStoredDevicesForUser(userId); + const allDevicesVerified = devices.every(device => { + const { deviceId } = device; + return cli.checkDeviceTrust(userId, deviceId).isCrossSigningVerified(); + }); + if (!allDevicesVerified) { + this.setState({ + e2eStatus: "warning", + }); + return; + } + } + this.setState({ + e2eStatus: "verified", }); }, diff --git a/src/components/views/right_panel/UserInfo.js b/src/components/views/right_panel/UserInfo.js index ae29021e08..90bb3f3dcb 100644 --- a/src/components/views/right_panel/UserInfo.js +++ b/src/components/views/right_panel/UserInfo.js @@ -58,9 +58,20 @@ const _disambiguateDevices = (devices) => { } }; -const _getE2EStatus = (devices) => { - const hasUnverifiedDevice = devices.some((device) => device.isUnverified()); - return hasUnverifiedDevice ? "warning" : "verified"; +const _getE2EStatus = (cli, userId, devices) => { + if (!SettingsStore.isFeatureEnabled("feature_cross_signing")) { + const hasUnverifiedDevice = devices.some((device) => device.isUnverified()); + return hasUnverifiedDevice ? "warning" : "verified"; + } + const userVerified = cli.checkUserTrust(userId).isCrossSigningVerified(); + const allDevicesVerified = devices.every(device => { + const { deviceId } = device; + return cli.checkDeviceTrust(userId, deviceId).isCrossSigningVerified(); + }); + if (allDevicesVerified) { + return userVerified ? "verified" : "normal"; + } + return "warning"; }; async function unverifyUser(matrixClient, userId) { @@ -1264,7 +1275,8 @@ const UserInfo = withLegacyMatrixClient(({matrixClient: cli, user, groupId, room let e2eIcon; if (isRoomEncrypted && devices) { - e2eIcon = ; + const e2eStatus = _getE2EStatus(cli, user.userId, devices); + e2eIcon = ; } return ( diff --git a/src/components/views/rooms/E2EIcon.js b/src/components/views/rooms/E2EIcon.js index d6baa30c8e..545d1fd7ed 100644 --- a/src/components/views/rooms/E2EIcon.js +++ b/src/components/views/rooms/E2EIcon.js @@ -17,24 +17,62 @@ limitations under the License. import classNames from 'classnames'; import { _t } from '../../../languageHandler'; import AccessibleButton from '../elements/AccessibleButton'; +import SettingsStore from '../../../settings/SettingsStore'; export default function(props) { + const { isUser } = props; + const isNormal = props.status === "normal"; const isWarning = props.status === "warning"; const isVerified = props.status === "verified"; const e2eIconClasses = classNames({ mx_E2EIcon: true, mx_E2EIcon_warning: isWarning, + mx_E2EIcon_normal: isNormal, mx_E2EIcon_verified: isVerified, }, props.className); let e2eTitle; - if (isWarning) { - e2eTitle = props.isUser ? - _t("Some devices for this user are not trusted") : - _t("Some devices in this encrypted room are not trusted"); - } else if (isVerified) { - e2eTitle = props.isUser ? - _t("All devices for this user are trusted") : - _t("All devices in this encrypted room are trusted"); + + const crossSigning = SettingsStore.isFeatureEnabled("feature_cross_signing"); + if (crossSigning && isUser) { + if (isWarning) { + e2eTitle = _t( + "This user has not verified all of their devices.", + ); + } else if (isNormal) { + e2eTitle = _t( + "You have not verified this user. " + + "This user has verified all of their devices.", + ); + } else if (isVerified) { + e2eTitle = _t( + "You have verified this user. " + + "This user has verified all of their devices.", + ); + } + } else if (crossSigning && !isUser) { + if (isWarning) { + e2eTitle = _t( + "Some users in this encrypted room are not verified by you or " + + "they have not verified their own devices.", + ); + } else if (isVerified) { + e2eTitle = _t( + "All users in this encrypted room are verified by you and " + + "they have verified their own devices.", + ); + } + } else if (!crossSigning && isUser) { + if (isWarning) { + e2eTitle = _t("Some devices for this user are not trusted"); + } else if (isVerified) { + e2eTitle = _t("All devices for this user are trusted"); + } + } else if (!crossSigning && !isUser) { + if (isWarning) { + e2eTitle = _t("Some devices in this encrypted room are not trusted"); + } else if (isVerified) { + e2eTitle = _t("All devices in this encrypted room are trusted"); + } } let style = null; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 80604e9090..f801c3a5c5 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -857,9 +857,14 @@ " (unsupported)": " (unsupported)", "Join as voice or video.": "Join as voice or video.", "Ongoing conference call%(supportedText)s.": "Ongoing conference call%(supportedText)s.", + "This user has not verified all of their devices.": "This user has not verified all of their devices.", + "You have not verified this user. This user has verified all of their devices.": "You have not verified this user. This user has verified all of their devices.", + "You have verified this user. This user has verified all of their devices.": "You have verified this user. This user has verified all of their devices.", + "Some users in this encrypted room are not verified by you or they have not verified their own devices.": "Some users in this encrypted room are not verified by you or they have not verified their own devices.", + "All users in this encrypted room are verified by you and they have verified their own devices.": "All users in this encrypted room are verified by you and they have verified their own devices.", "Some devices for this user are not trusted": "Some devices for this user are not trusted", - "Some devices in this encrypted room are not trusted": "Some devices in this encrypted room are not trusted", "All devices for this user are trusted": "All devices for this user are trusted", + "Some devices in this encrypted room are not trusted": "Some devices in this encrypted room are not trusted", "All devices in this encrypted room are trusted": "All devices in this encrypted room are trusted", "Edit message": "Edit message", "This event could not be displayed": "This event could not be displayed",