diff --git a/res/css/_components.scss b/res/css/_components.scss index 6890a1ffd1..b959b1f1cd 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -186,6 +186,7 @@ @import "./views/settings/_AvatarSetting.scss"; @import "./views/settings/_CrossSigningPanel.scss"; @import "./views/settings/_DevicesPanel.scss"; +@import "./views/settings/_E2eAdvancedPanel.scss"; @import "./views/settings/_EmailAddresses.scss"; @import "./views/settings/_IntegrationManager.scss"; @import "./views/settings/_KeyBackupPanel.scss"; diff --git a/src/MatrixClientPeg.js b/src/MatrixClientPeg.js index 98fcc85d60..21f05b9759 100644 --- a/src/MatrixClientPeg.js +++ b/src/MatrixClientPeg.js @@ -148,6 +148,9 @@ class _MatrixClientPeg { // check that we have a version of the js-sdk which includes initCrypto if (!SettingsStore.getValue("lowBandwidth") && this.matrixClient.initCrypto) { await this.matrixClient.initCrypto(); + this.matrixClient.setCryptoTrustCrossSignedDevices( + !SettingsStore.getValue('e2ee.manuallyVerifyAllSessions'), + ); StorageManager.setCryptoInitialised(true); } } catch (e) { diff --git a/src/components/views/rooms/MemberTile.js b/src/components/views/rooms/MemberTile.js index 1f1d8389b1..a0e900b5fc 100644 --- a/src/components/views/rooms/MemberTile.js +++ b/src/components/views/rooms/MemberTile.js @@ -65,6 +65,7 @@ export default createReactClass({ }); if (isRoomEncrypted) { cli.on("userTrustStatusChanged", this.onUserTrustStatusChanged); + cli.on("deviceVerificationChanged", this.onDeviceVerificationChanged); this.updateE2EStatus(); } else { // Listen for room to become encrypted @@ -88,6 +89,7 @@ export default createReactClass({ if (cli) { cli.removeListener("RoomState.events", this.onRoomStateEvents); cli.removeListener("userTrustStatusChanged", this.onUserTrustStatusChanged); + cli.removeListener("deviceVerificationChanged", this.onDeviceVerificationChanged); } }, @@ -110,6 +112,11 @@ export default createReactClass({ this.updateE2EStatus(); }, + onDeviceVerificationChanged: function(userId, deviceId, deviceInfo) { + if (userId !== this.props.member.userId) return; + this.updateE2EStatus(); + }, + updateE2EStatus: async function() { const cli = MatrixClientPeg.get(); const { userId } = this.props.member; diff --git a/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js b/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js index 2e35a6bf6f..3dca6e2490 100644 --- a/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js @@ -281,6 +281,8 @@ export default class SecurityUserSettingsTab extends React.Component { ); } + const E2eAdvancedPanel = sdk.getComponent('views.settings.E2eAdvancedPanel'); + return (
{_t("Security & Privacy")}
@@ -311,6 +313,7 @@ export default class SecurityUserSettingsTab extends React.Component {
{this._renderIgnoredUsers()} {this._renderManageInvites()} + ); } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 57b39309b0..3602134f08 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -432,6 +432,7 @@ "Enable message search in encrypted rooms": "Enable message search in encrypted rooms", "Keep secret storage passphrase in memory for this session": "Keep secret storage passphrase in memory for this session", "How fast should messages be downloaded.": "How fast should messages be downloaded.", + "Manually verify all remote sessions": "Manually verify all remote sessions", "Collecting app version information": "Collecting app version information", "Collecting logs": "Collecting logs", "Uploading report": "Uploading report", @@ -598,6 +599,7 @@ "Public Name": "Public Name", "Last seen": "Last seen", "Failed to set display name": "Failed to set display name", + "Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.": "Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.", "Disable Notifications": "Disable Notifications", "Enable Notifications": "Enable Notifications", "Securely cache encrypted messages locally for them to appear in search results, using ": "Securely cache encrypted messages locally for them to appear in search results, using ", diff --git a/src/settings/Settings.js b/src/settings/Settings.js index 461761dfa2..0d72017878 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -16,6 +16,8 @@ See the License for the specific language governing permissions and limitations under the License. */ +import {MatrixClient} from 'matrix-js-sdk'; + import {_td} from '../languageHandler'; import { AudioNotificationsEnabledController, @@ -24,6 +26,7 @@ import { } from "./controllers/NotificationControllers"; import CustomStatusController from "./controllers/CustomStatusController"; import ThemeController from './controllers/ThemeController'; +import PushToMatrixClientController from './controllers/PushToMatrixClientController'; import ReloadOnChangeController from "./controllers/ReloadOnChangeController"; import {RIGHT_PANEL_PHASES} from "../stores/RightPanelStorePhases"; @@ -525,4 +528,12 @@ export const SETTINGS = { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, default: true, }, + "e2ee.manuallyVerifyAllSessions": { + supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS, + displayName: _td("Manually verify all remote sessions"), + default: false, + controller: new PushToMatrixClientController( + MatrixClient.prototype.setCryptoTrustCrossSignedDevices, true, + ), + }, };