Add independent set up / reset actions in Settings
This adds set up and reset actions to each of cross-signing and secure backup that do separate things, rather than mixing concerns together. (It's temporarily still a bit of lie for backup, as more changes are needed to stop resetting cross-signing as well.)
This commit is contained in:
parent
aae68f7d1a
commit
bbe2084f66
6 changed files with 90 additions and 45 deletions
|
@ -34,6 +34,10 @@ limitations under the License.
|
|||
|
||||
.mx_SecureBackupPanel_buttonRow {
|
||||
margin: 1em 0;
|
||||
|
||||
:nth-child(n + 1) {
|
||||
margin-inline-end: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SecureBackupPanel_statusList {
|
||||
|
|
|
@ -250,7 +250,7 @@ export async function accessSecretStorage(func = async () => { }, forceReset = f
|
|||
'Cross-signing keys dialog', '', InteractiveAuthDialog,
|
||||
{
|
||||
title: _t("Setting up keys"),
|
||||
matrixClient: MatrixClientPeg.get(),
|
||||
matrixClient: cli,
|
||||
makeRequest,
|
||||
},
|
||||
);
|
||||
|
|
|
@ -280,6 +280,9 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
const { forceReset } = this.props;
|
||||
|
||||
try {
|
||||
// JRS: In an upcoming change, the cross-signing steps will be
|
||||
// removed from here and this will instead be about secret storage
|
||||
// only.
|
||||
if (forceReset) {
|
||||
console.log("Forcing cross-signing and secret storage reset");
|
||||
await cli.bootstrapSecretStorage({
|
||||
|
|
|
@ -19,9 +19,9 @@ import React from 'react';
|
|||
import {MatrixClientPeg} from '../../../MatrixClientPeg';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import * as sdk from '../../../index';
|
||||
import { accessSecretStorage } from '../../../SecurityManager';
|
||||
import Modal from '../../../Modal';
|
||||
import Spinner from '../elements/Spinner';
|
||||
import InteractiveAuthDialog from '../dialogs/InteractiveAuthDialog';
|
||||
|
||||
export default class CrossSigningPanel extends React.PureComponent {
|
||||
constructor(props) {
|
||||
|
@ -66,7 +66,7 @@ export default class CrossSigningPanel extends React.PureComponent {
|
|||
};
|
||||
|
||||
_onBootstrapClick = () => {
|
||||
this._bootstrapSecureSecretStorage(false);
|
||||
this._bootstrapCrossSigning({ forceReset: false });
|
||||
};
|
||||
|
||||
onStatusChanged = () => {
|
||||
|
@ -99,35 +99,50 @@ export default class CrossSigningPanel extends React.PureComponent {
|
|||
}
|
||||
|
||||
/**
|
||||
* Bootstrapping secret storage may take one of these paths:
|
||||
* 1. Create secret storage from a passphrase and store cross-signing keys
|
||||
* in secret storage.
|
||||
* Bootstrapping cross-signing take one of these paths:
|
||||
* 1. Create cross-signing keys locally and store in secret storage (if it
|
||||
* already exists on the account).
|
||||
* 2. Access existing secret storage by requesting passphrase and accessing
|
||||
* cross-signing keys as needed.
|
||||
* 3. All keys are loaded and there's nothing to do.
|
||||
* @param {bool} [forceReset] Bootstrap again even if keys already present
|
||||
*/
|
||||
_bootstrapSecureSecretStorage = async (forceReset=false) => {
|
||||
_bootstrapCrossSigning = async ({ forceReset = false }) => {
|
||||
this.setState({ error: null });
|
||||
try {
|
||||
await accessSecretStorage(() => undefined, forceReset);
|
||||
const cli = MatrixClientPeg.get();
|
||||
await cli.bootstrapCrossSigning({
|
||||
authUploadDeviceSigningKeys: async (makeRequest) => {
|
||||
const { finished } = Modal.createTrackedDialog(
|
||||
'Cross-signing keys dialog', '', InteractiveAuthDialog,
|
||||
{
|
||||
title: _t("Setting up keys"),
|
||||
matrixClient: cli,
|
||||
makeRequest,
|
||||
},
|
||||
);
|
||||
const [confirmed] = await finished;
|
||||
if (!confirmed) {
|
||||
throw new Error("Cross-signing key upload auth canceled");
|
||||
}
|
||||
},
|
||||
setupNewCrossSigning: forceReset,
|
||||
});
|
||||
} catch (e) {
|
||||
this.setState({ error: e });
|
||||
console.error("Error bootstrapping secret storage", e);
|
||||
console.error("Error bootstrapping cross-signing", e);
|
||||
}
|
||||
if (this._unmounted) return;
|
||||
this._getUpdatedStatus();
|
||||
}
|
||||
|
||||
onDestroyStorage = (act) => {
|
||||
if (!act) return;
|
||||
this._bootstrapSecureSecretStorage(true);
|
||||
}
|
||||
|
||||
_destroySecureSecretStorage = () => {
|
||||
_resetCrossSigning = () => {
|
||||
const ConfirmDestroyCrossSigningDialog = sdk.getComponent("dialogs.ConfirmDestroyCrossSigningDialog");
|
||||
Modal.createDialog(ConfirmDestroyCrossSigningDialog, {
|
||||
onFinished: this.onDestroyStorage,
|
||||
onFinished: (act) => {
|
||||
if (!act) return;
|
||||
this._bootstrapCrossSigning({ forceReset: true });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -184,8 +199,8 @@ export default class CrossSigningPanel extends React.PureComponent {
|
|||
if (keysExistAnywhere) {
|
||||
resetButton = (
|
||||
<div className="mx_CrossSigningPanel_buttonRow">
|
||||
<AccessibleButton kind="danger" onClick={this._destroySecureSecretStorage}>
|
||||
{_t("Reset cross-signing and secret storage")}
|
||||
<AccessibleButton kind="danger" onClick={this._resetCrossSigning}>
|
||||
{_t("Reset")}
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
);
|
||||
|
@ -197,7 +212,7 @@ export default class CrossSigningPanel extends React.PureComponent {
|
|||
bootstrapButton = (
|
||||
<div className="mx_CrossSigningPanel_buttonRow">
|
||||
<AccessibleButton kind="primary" onClick={this._onBootstrapClick}>
|
||||
{_t("Bootstrap cross-signing and secret storage")}
|
||||
{_t("Set up")}
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -25,6 +25,7 @@ import Spinner from '../elements/Spinner';
|
|||
import AccessibleButton from '../elements/AccessibleButton';
|
||||
import QuestionDialog from '../dialogs/QuestionDialog';
|
||||
import RestoreKeyBackupDialog from '../dialogs/keybackup/RestoreKeyBackupDialog';
|
||||
import { accessSecretStorage } from '../../../SecurityManager';
|
||||
|
||||
export default class SecureBackupPanel extends React.PureComponent {
|
||||
constructor(props) {
|
||||
|
@ -184,6 +185,19 @@ export default class SecureBackupPanel extends React.PureComponent {
|
|||
);
|
||||
}
|
||||
|
||||
_resetSecretStorage = async () => {
|
||||
this.setState({ error: null });
|
||||
try {
|
||||
await accessSecretStorage(() => { }, /* forceReset = */ true);
|
||||
} catch (e) {
|
||||
console.error("Error resetting secret storage", e);
|
||||
if (this._unmounted) return;
|
||||
this.setState({ error: e });
|
||||
}
|
||||
if (this._unmounted) return;
|
||||
this._loadBackupStatus();
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
loading,
|
||||
|
@ -201,7 +215,7 @@ export default class SecureBackupPanel extends React.PureComponent {
|
|||
let statusDescription;
|
||||
let extraDetailsTableRows;
|
||||
let extraDetails;
|
||||
let actions;
|
||||
let actions = [];
|
||||
if (error) {
|
||||
statusDescription = (
|
||||
<div className="error">
|
||||
|
@ -335,13 +349,6 @@ export default class SecureBackupPanel extends React.PureComponent {
|
|||
trustedLocally = _t("This backup is trusted because it has been restored on this session");
|
||||
}
|
||||
|
||||
let deleteBackupButton;
|
||||
if (!isSecureBackupRequired()) {
|
||||
deleteBackupButton = <AccessibleButton kind="danger" onClick={this._deleteBackup}>
|
||||
{_t("Delete Backup")}
|
||||
</AccessibleButton>;
|
||||
}
|
||||
|
||||
extraDetailsTableRows = <>
|
||||
<tr>
|
||||
<td>{_t("Backup version:")}</td>
|
||||
|
@ -359,14 +366,19 @@ export default class SecureBackupPanel extends React.PureComponent {
|
|||
<div>{trustedLocally}</div>
|
||||
</>;
|
||||
|
||||
actions = (
|
||||
<div className="mx_SecureBackupPanel_buttonRow">
|
||||
<AccessibleButton kind="primary" onClick={this._restoreBackup}>
|
||||
{restoreButtonCaption}
|
||||
</AccessibleButton>
|
||||
{deleteBackupButton}
|
||||
</div>
|
||||
actions.push(
|
||||
<AccessibleButton kind="primary" onClick={this._restoreBackup}>
|
||||
{restoreButtonCaption}
|
||||
</AccessibleButton>,
|
||||
);
|
||||
|
||||
if (!isSecureBackupRequired()) {
|
||||
actions.push(
|
||||
<AccessibleButton kind="danger" onClick={this._deleteBackup}>
|
||||
{_t("Delete Backup")}
|
||||
</AccessibleButton>,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
statusDescription = <>
|
||||
<p>{_t(
|
||||
|
@ -375,12 +387,18 @@ export default class SecureBackupPanel extends React.PureComponent {
|
|||
)}</p>
|
||||
<p>{_t("Back up your keys before signing out to avoid losing them.")}</p>
|
||||
</>;
|
||||
actions = (
|
||||
<div className="mx_SecureBackupPanel_buttonRow">
|
||||
<AccessibleButton kind="primary" onClick={this._startNewBackup}>
|
||||
{_t("Start using Key Backup")}
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
actions.push(
|
||||
<AccessibleButton kind="primary" onClick={this._startNewBackup}>
|
||||
{_t("Set up")}
|
||||
</AccessibleButton>,
|
||||
);
|
||||
}
|
||||
|
||||
if (secretStorageKeyInAccount) {
|
||||
actions.push(
|
||||
<AccessibleButton kind="danger" onClick={this._resetSecretStorage}>
|
||||
{_t("Reset")}
|
||||
</AccessibleButton>,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -394,6 +412,13 @@ export default class SecureBackupPanel extends React.PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
let actionRow;
|
||||
if (actions.length) {
|
||||
actionRow = <div className="mx_SecureBackupPanel_buttonRow">
|
||||
{actions}
|
||||
</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p>{_t(
|
||||
|
@ -430,7 +455,7 @@ export default class SecureBackupPanel extends React.PureComponent {
|
|||
</tbody></table>
|
||||
{extraDetails}
|
||||
</details>
|
||||
{actions}
|
||||
{actionRow}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -648,8 +648,7 @@
|
|||
"Cross-signing is ready for use.": "Cross-signing is ready for use.",
|
||||
"Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.",
|
||||
"Cross-signing is not set up.": "Cross-signing is not set up.",
|
||||
"Reset cross-signing and secret storage": "Reset cross-signing and secret storage",
|
||||
"Bootstrap cross-signing and secret storage": "Bootstrap cross-signing and secret storage",
|
||||
"Reset": "Reset",
|
||||
"Cross-signing public keys:": "Cross-signing public keys:",
|
||||
"in memory": "in memory",
|
||||
"not found": "not found",
|
||||
|
@ -748,7 +747,6 @@
|
|||
"Algorithm:": "Algorithm:",
|
||||
"Your keys are <b>not being backed up from this session</b>.": "Your keys are <b>not being backed up from this session</b>.",
|
||||
"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",
|
||||
"well formed": "well formed",
|
||||
"unexpected type": "unexpected type",
|
||||
"Back up your encryption keys with your account data in case you lose access to your sessions. Your keys will be secured with a unique Recovery Key.": "Back up your encryption keys with your account data in case you lose access to your sessions. Your keys will be secured with a unique Recovery Key.",
|
||||
|
@ -948,7 +946,6 @@
|
|||
"Uploaded sound": "Uploaded sound",
|
||||
"Sounds": "Sounds",
|
||||
"Notification sound": "Notification sound",
|
||||
"Reset": "Reset",
|
||||
"Set a new custom sound": "Set a new custom sound",
|
||||
"Browse": "Browse",
|
||||
"Change room avatar": "Change room avatar",
|
||||
|
@ -1173,6 +1170,7 @@
|
|||
"%(roomName)s is not accessible at this time.": "%(roomName)s is not accessible at this time.",
|
||||
"Try again later, or ask a room admin to check if you have access.": "Try again later, or ask a room admin to check if you have access.",
|
||||
"%(errcode)s was returned while trying to access the room. If you think you're seeing this message in error, please <issueLink>submit a bug report</issueLink>.": "%(errcode)s was returned while trying to access the room. If you think you're seeing this message in error, please <issueLink>submit a bug report</issueLink>.",
|
||||
"Start using Key Backup": "Start using Key Backup",
|
||||
"Never lose encrypted messages": "Never lose encrypted messages",
|
||||
"Messages in this room are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "Messages in this room are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.",
|
||||
"Securely back up your keys to avoid losing them. <a>Learn more.</a>": "Securely back up your keys to avoid losing them. <a>Learn more.</a>",
|
||||
|
|
Loading…
Reference in a new issue