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.
This commit is contained in:
J. Ryan Stinnett 2019-11-28 16:45:29 +00:00
parent b55a1a1077
commit c103fe4273
7 changed files with 163 additions and 41 deletions

View file

@ -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 (
<div>
<table className="mx_CrossSigningPanel_statusList">
<tr>
<td>{_t("Cross-signing public keys:")}</td>
<td>{crossSigningPublicKeysOnDevice ? _t("on device") : _t("not found")}</td>
</tr>
<tr>
<td>{_t("Cross-signing private keys:")}</td>
<td>{crossSigningPrivateKeysInStorage ? _t("in secret storage") : _t("not found")}</td>
</tr>
<tr>
<td>{_t("Secret storage public key:")}</td>
<td>{secretStorageKeyInAccount ? _t("in account data") : _t("not found")}</td>
</tr>
</table>
<div className="mx_CrossSigningPanel_buttonRow">
<AccessibleButton kind="primary" onClick={this._bootstrapSecureSecretStorage}>
{_t("Bootstrap Secure Secret Storage")}
</AccessibleButton>
</div>
</div>
);
}
}

View file

@ -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 {
</div>
</div>;
} 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 = (
<div className="mx_KeyBackupPanel_buttonRow">
<AccessibleButton kind="primary" onClick={this._bootstrapSecureSecretStorage}>
{_t("Bootstrap Secure Secret Storage (MSC1946)")}
</AccessibleButton>
</div>
);
}
return <div>
<div>
<p>{_t(
@ -349,7 +313,6 @@ export default class KeyBackupPanel extends React.PureComponent {
{_t("Start using Key Backup")}
</AccessibleButton>
</div>
{bootstrapSecureSecretStorage}
</div>;
}
}

View file

@ -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 {
</div>
);
// 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 = (
<div className='mx_SettingsTab_section'>
<span className="mx_SettingsTab_subheading">{_t("Cross-signing")}</span>
<div className='mx_SettingsTab_subsectionText'>
<CrossSigningPanel />
</div>
</div>
);
}
return (
<div className="mx_SettingsTab mx_SecurityUserSettingsTab">
<div className="mx_SettingsTab_heading">{_t("Security & Privacy")}</div>
@ -263,6 +280,7 @@ export default class SecurityUserSettingsTab extends React.Component {
</div>
</div>
{keyBackup}
{crossSigning}
{this._renderCurrentDeviceInfo()}
<div className='mx_SettingsTab_section'>
<span className="mx_SettingsTab_subheading">{_t("Analytics")}</span>