From c103fe42738161c6a0aaf7b342af64ba29114033 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 28 Nov 2019 16:45:29 +0000 Subject: [PATCH] Add cross-signing diagnostic panel This is not part of any designs, so it may be short-lived, but it's quite handy for diagnosing issues with cross-signing at least while the feature is in development. --- res/css/_components.scss | 1 + .../views/settings/_CrossSigningPanel.scss | 31 ++++++ res/css/views/settings/_KeyBackupPanel.scss | 1 + .../views/settings/CrossSigningPanel.js | 100 ++++++++++++++++++ .../views/settings/KeyBackupPanel.js | 39 +------ .../tabs/user/SecurityUserSettingsTab.js | 20 +++- src/i18n/strings/en_EN.json | 12 ++- 7 files changed, 163 insertions(+), 41 deletions(-) create mode 100644 res/css/views/settings/_CrossSigningPanel.scss create mode 100644 src/components/views/settings/CrossSigningPanel.js diff --git a/res/css/_components.scss b/res/css/_components.scss index e39003fbec..eb0181aee1 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -171,6 +171,7 @@ @import "./views/rooms/_Stickers.scss"; @import "./views/rooms/_TopUnreadMessagesBar.scss"; @import "./views/rooms/_WhoIsTypingTile.scss"; +@import "./views/settings/_CrossSigningPanel.scss"; @import "./views/settings/_DevicesPanel.scss"; @import "./views/settings/_EmailAddresses.scss"; @import "./views/settings/_IntegrationManager.scss"; diff --git a/res/css/views/settings/_CrossSigningPanel.scss b/res/css/views/settings/_CrossSigningPanel.scss new file mode 100644 index 0000000000..fa9f76a963 --- /dev/null +++ b/res/css/views/settings/_CrossSigningPanel.scss @@ -0,0 +1,31 @@ +/* +Copyright 2019 The Matrix.org Foundation C.I.C. + +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_CrossSigningPanel_statusList { + border-spacing: 0; + + td { + padding: 0; + + &:first-of-type { + padding-inline-end: 1em; + } + } +} + +.mx_CrossSigningPanel_buttonRow { + margin: 1em 0; +} diff --git a/res/css/views/settings/_KeyBackupPanel.scss b/res/css/views/settings/_KeyBackupPanel.scss index 4c4190c604..872162caad 100644 --- a/res/css/views/settings/_KeyBackupPanel.scss +++ b/res/css/views/settings/_KeyBackupPanel.scss @@ -1,5 +1,6 @@ /* Copyright 2018 New Vector Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/components/views/settings/CrossSigningPanel.js b/src/components/views/settings/CrossSigningPanel.js new file mode 100644 index 0000000000..c4715648f9 --- /dev/null +++ b/src/components/views/settings/CrossSigningPanel.js @@ -0,0 +1,100 @@ +/* +Copyright 2019 The Matrix.org Foundation C.I.C. + +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 MatrixClientPeg from '../../../MatrixClientPeg'; +import { _t } from '../../../languageHandler'; +import sdk from '../../../index'; +import Modal from '../../../Modal'; + +export default class CrossSigningPanel extends React.PureComponent { + constructor(props) { + super(props); + this.state = this._getUpdatedStatus(); + } + + _getUpdatedStatus() { + // XXX: Add public accessors if we keep this around in production + const cli = MatrixClientPeg.get(); + const crossSigning = cli._crypto._crossSigningInfo; + const secretStorage = cli._crypto._secretStorage; + const crossSigningPublicKeysOnDevice = crossSigning.getId(); + const crossSigningPrivateKeysInStorage = crossSigning.isStoredInSecretStorage(secretStorage); + const secretStorageKeyInAccount = secretStorage.hasKey(); + + return { + crossSigningPublicKeysOnDevice, + crossSigningPrivateKeysInStorage, + secretStorageKeyInAccount, + }; + } + + _bootstrapSecureSecretStorage = async () => { + try { + const InteractiveAuthDialog = sdk.getComponent("dialogs.InteractiveAuthDialog"); + await MatrixClientPeg.get().bootstrapSecretStorage({ + doInteractiveAuthFlow: async (makeRequest) => { + const { finished } = Modal.createTrackedDialog( + 'Cross-signing keys dialog', '', InteractiveAuthDialog, + { + title: _t("Send cross-signing keys to homeserver"), + matrixClient: MatrixClientPeg.get(), + makeRequest, + }, + ); + await finished; + }, + }); + this.setState(this._getUpdatedStatus()); + } catch (e) { + console.error(e); + } + } + + render() { + const AccessibleButton = sdk.getComponent("elements.AccessibleButton"); + const { + crossSigningPublicKeysOnDevice, + crossSigningPrivateKeysInStorage, + secretStorageKeyInAccount, + } = this.state; + + return ( +
+ + + + + + + + + + + + + +
{_t("Cross-signing public keys:")}{crossSigningPublicKeysOnDevice ? _t("on device") : _t("not found")}
{_t("Cross-signing private keys:")}{crossSigningPrivateKeysInStorage ? _t("in secret storage") : _t("not found")}
{_t("Secret storage public key:")}{secretStorageKeyInAccount ? _t("in account data") : _t("not found")}
+
+ + {_t("Bootstrap Secure Secret Storage")} + +
+
+ ); + } +} diff --git a/src/components/views/settings/KeyBackupPanel.js b/src/components/views/settings/KeyBackupPanel.js index f4740ea649..c2fb3dc9db 100644 --- a/src/components/views/settings/KeyBackupPanel.js +++ b/src/components/views/settings/KeyBackupPanel.js @@ -1,5 +1,6 @@ /* Copyright 2018 New Vector Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -20,7 +21,6 @@ import sdk from '../../../index'; import MatrixClientPeg from '../../../MatrixClientPeg'; import { _t } from '../../../languageHandler'; import Modal from '../../../Modal'; -import SettingsStore from '../../../../lib/settings/SettingsStore'; export default class KeyBackupPanel extends React.PureComponent { constructor(props) { @@ -125,27 +125,6 @@ export default class KeyBackupPanel extends React.PureComponent { ); } - _bootstrapSecureSecretStorage = async () => { - try { - const InteractiveAuthDialog = sdk.getComponent("dialogs.InteractiveAuthDialog"); - await MatrixClientPeg.get().bootstrapSecretStorage({ - doInteractiveAuthFlow: async (makeRequest) => { - const { finished } = Modal.createTrackedDialog( - 'Cross-signing keys dialog', '', InteractiveAuthDialog, - { - title: _t("Send cross-signing keys to homeserver"), - matrixClient: MatrixClientPeg.get(), - makeRequest, - }, - ); - await finished; - }, - }); - } catch (e) { - console.error(e); - } - } - _deleteBackup = () => { const QuestionDialog = sdk.getComponent('dialogs.QuestionDialog'); Modal.createTrackedDialog('Delete Backup', '', QuestionDialog, { @@ -320,21 +299,6 @@ export default class KeyBackupPanel extends React.PureComponent { ; } else { - // This is a temporary button for testing SSSS. Initialising SSSS - // depends on cross-signing and is part of the same project, so we - // only show this mode when the cross-signing feature is enabled. - // TODO: Clean this up when removing the feature flag. - let bootstrapSecureSecretStorage; - if (SettingsStore.isFeatureEnabled("feature_cross_signing")) { - bootstrapSecureSecretStorage = ( -
- - {_t("Bootstrap Secure Secret Storage (MSC1946)")} - -
- ); - } - return

{_t( @@ -349,7 +313,6 @@ export default class KeyBackupPanel extends React.PureComponent { {_t("Start using Key Backup")}

- {bootstrapSecureSecretStorage}
; } } diff --git a/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js b/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js index 0732bcf926..98ec18df5a 100644 --- a/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js @@ -17,7 +17,7 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import {_t} from "../../../../../languageHandler"; -import {SettingLevel} from "../../../../../settings/SettingsStore"; +import SettingsStore, {SettingLevel} from "../../../../../settings/SettingsStore"; import MatrixClientPeg from "../../../../../MatrixClientPeg"; import * as FormattingUtils from "../../../../../utils/FormattingUtils"; import AccessibleButton from "../../../elements/AccessibleButton"; @@ -252,6 +252,23 @@ export default class SecurityUserSettingsTab extends React.Component { ); + // XXX: There's no such panel in the current cross-signing designs, but + // it's useful to have for testing the feature. If there's no interest + // in having advanced details here once all flows are implemented, we + // can remove this. + const CrossSigningPanel = sdk.getComponent('views.settings.CrossSigningPanel'); + let crossSigning; + if (SettingsStore.isFeatureEnabled("feature_cross_signing")) { + crossSigning = ( +
+ {_t("Cross-signing")} +
+ +
+
+ ); + } + return (
{_t("Security & Privacy")}
@@ -263,6 +280,7 @@ export default class SecurityUserSettingsTab extends React.Component {
{keyBackup} + {crossSigning} {this._renderCurrentDeviceInfo()}
{_t("Analytics")} diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 367450656e..80254ed54e 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -496,6 +496,15 @@ "New Password": "New Password", "Confirm password": "Confirm password", "Change Password": "Change Password", + "Send cross-signing keys to homeserver": "Send cross-signing keys to homeserver", + "Cross-signing public keys:": "Cross-signing public keys:", + "on device": "on device", + "not found": "not found", + "Cross-signing private keys:": "Cross-signing private keys:", + "in secret storage": "in secret storage", + "Secret storage public key:": "Secret storage public key:", + "in account data": "in account data", + "Bootstrap Secure Secret Storage": "Bootstrap Secure Secret Storage", "Your homeserver does not support device management.": "Your homeserver does not support device management.", "Unable to load device list": "Unable to load device list", "Authentication": "Authentication", @@ -510,7 +519,6 @@ "Connecting to integration manager...": "Connecting to integration manager...", "Cannot connect to integration manager": "Cannot connect to integration manager", "The integration manager is offline or it cannot reach your homeserver.": "The integration manager is offline or it cannot reach your homeserver.", - "Send cross-signing keys to homeserver": "Send cross-signing keys to homeserver", "Delete Backup": "Delete Backup", "Are you sure? You will lose your encrypted messages if your keys are not backed up properly.": "Are you sure? You will lose your encrypted messages if your keys are not backed up properly.", "Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.", @@ -533,7 +541,6 @@ "This backup is trusted because it has been restored on this device": "This backup is trusted because it has been restored on this device", "Backup version: ": "Backup version: ", "Algorithm: ": "Algorithm: ", - "Bootstrap Secure Secret Storage (MSC1946)": "Bootstrap Secure Secret Storage (MSC1946)", "Your keys are not being backed up from this device.": "Your keys are not being backed up from this device.", "Back up your keys before signing out to avoid losing them.": "Back up your keys before signing out to avoid losing them.", "Start using Key Backup": "Start using Key Backup", @@ -697,6 +704,7 @@ "Accept all %(invitedRooms)s invites": "Accept all %(invitedRooms)s invites", "Reject all %(invitedRooms)s invites": "Reject all %(invitedRooms)s invites", "Key backup": "Key backup", + "Cross-signing": "Cross-signing", "Security & Privacy": "Security & Privacy", "Devices": "Devices", "A device's public name is visible to people you communicate with": "A device's public name is visible to people you communicate with",