mirror of https://github.com/vector-im/riot-web
Merge pull request #3800 from matrix-org/jryans/key-backup-dialogs-4s
Update key backup creation and recovery paths for SSSSpull/21833/head
commit
76f3a08909
|
@ -40,4 +40,5 @@ limitations under the License.
|
||||||
|
|
||||||
.mx_RoomRecoveryReminder_secondary {
|
.mx_RoomRecoveryReminder_secondary {
|
||||||
font-size: 90%;
|
font-size: 90%;
|
||||||
|
margin-top: 1em;
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,7 +97,7 @@ export const crossSigningCallbacks = {
|
||||||
*
|
*
|
||||||
* Additionally, the secret storage keys are cached during the scope of this function
|
* Additionally, the secret storage keys are cached during the scope of this function
|
||||||
* to ensure the user is prompted only once for their secret storage
|
* to ensure the user is prompted only once for their secret storage
|
||||||
* passphrase. The cache is then
|
* passphrase. The cache is then cleared once the provided function completes.
|
||||||
*
|
*
|
||||||
* @param {Function} [func] An operation to perform once secret storage has been
|
* @param {Function} [func] An operation to perform once secret storage has been
|
||||||
* bootstrapped. Optional.
|
* bootstrapped. Optional.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2018, 2019 New Vector Ltd
|
Copyright 2018, 2019 New Vector Ltd
|
||||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -17,11 +17,14 @@ limitations under the License.
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import FileSaver from 'file-saver';
|
import FileSaver from 'file-saver';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import sdk from '../../../../index';
|
import sdk from '../../../../index';
|
||||||
import MatrixClientPeg from '../../../../MatrixClientPeg';
|
import MatrixClientPeg from '../../../../MatrixClientPeg';
|
||||||
import { scorePassword } from '../../../../utils/PasswordScorer';
|
import { scorePassword } from '../../../../utils/PasswordScorer';
|
||||||
import { _t } from '../../../../languageHandler';
|
import { _t } from '../../../../languageHandler';
|
||||||
|
import { accessSecretStorage } from '../../../../CrossSigningManager';
|
||||||
|
import SettingsStore from '../../../../../lib/settings/SettingsStore';
|
||||||
|
|
||||||
const PHASE_PASSPHRASE = 0;
|
const PHASE_PASSPHRASE = 0;
|
||||||
const PHASE_PASSPHRASE_CONFIRM = 1;
|
const PHASE_PASSPHRASE_CONFIRM = 1;
|
||||||
|
@ -49,10 +52,20 @@ function selectText(target) {
|
||||||
* on the server.
|
* on the server.
|
||||||
*/
|
*/
|
||||||
export default class CreateKeyBackupDialog extends React.PureComponent {
|
export default class CreateKeyBackupDialog extends React.PureComponent {
|
||||||
|
static propTypes = {
|
||||||
|
secureSecretStorage: PropTypes.bool,
|
||||||
|
onFinished: PropTypes.func.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
|
this._recoveryKeyNode = null;
|
||||||
|
this._keyBackupInfo = null;
|
||||||
|
this._setZxcvbnResultTimeout = null;
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
|
secureSecretStorage: props.secureSecretStorage,
|
||||||
phase: PHASE_PASSPHRASE,
|
phase: PHASE_PASSPHRASE,
|
||||||
passPhrase: '',
|
passPhrase: '',
|
||||||
passPhraseConfirm: '',
|
passPhraseConfirm: '',
|
||||||
|
@ -61,12 +74,25 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
|
||||||
zxcvbnResult: null,
|
zxcvbnResult: null,
|
||||||
setPassPhrase: false,
|
setPassPhrase: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (this.state.secureSecretStorage === undefined) {
|
||||||
|
this.state.secureSecretStorage =
|
||||||
|
SettingsStore.isFeatureEnabled("feature_cross_signing");
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're using secret storage, skip ahead to the backing up step, as
|
||||||
|
// `accessSecretStorage` will handle passphrases as needed.
|
||||||
|
if (this.state.secureSecretStorage) {
|
||||||
|
this.state.phase = PHASE_BACKINGUP;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillMount() {
|
componentDidMount() {
|
||||||
this._recoveryKeyNode = null;
|
// If we're using secret storage, skip ahead to the backing up step, as
|
||||||
this._keyBackupInfo = null;
|
// `accessSecretStorage` will handle passphrases as needed.
|
||||||
this._setZxcvbnResultTimeout = null;
|
if (this.state.secureSecretStorage) {
|
||||||
|
this._createBackup();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
|
@ -103,15 +129,26 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
_createBackup = async () => {
|
_createBackup = async () => {
|
||||||
|
const { secureSecretStorage } = this.state;
|
||||||
this.setState({
|
this.setState({
|
||||||
phase: PHASE_BACKINGUP,
|
phase: PHASE_BACKINGUP,
|
||||||
error: null,
|
error: null,
|
||||||
});
|
});
|
||||||
let info;
|
let info;
|
||||||
try {
|
try {
|
||||||
info = await MatrixClientPeg.get().createKeyBackupVersion(
|
if (secureSecretStorage) {
|
||||||
this._keyBackupInfo,
|
await accessSecretStorage(async () => {
|
||||||
);
|
info = await MatrixClientPeg.get().prepareKeyBackupVersion(
|
||||||
|
null /* random key */,
|
||||||
|
{ secureSecretStorage: true },
|
||||||
|
);
|
||||||
|
info = await MatrixClientPeg.get().createKeyBackupVersion(info);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
info = await MatrixClientPeg.get().createKeyBackupVersion(
|
||||||
|
this._keyBackupInfo,
|
||||||
|
);
|
||||||
|
}
|
||||||
await MatrixClientPeg.get().scheduleAllGroupSessionsForBackup();
|
await MatrixClientPeg.get().scheduleAllGroupSessionsForBackup();
|
||||||
this.setState({
|
this.setState({
|
||||||
phase: PHASE_DONE,
|
phase: PHASE_DONE,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2018-2019 New Vector Ltd
|
Copyright 2018, 2019 New Vector Ltd
|
||||||
|
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -40,9 +41,11 @@ export default class NewRecoveryMethodDialog extends React.PureComponent {
|
||||||
|
|
||||||
onSetupClick = async () => {
|
onSetupClick = async () => {
|
||||||
const RestoreKeyBackupDialog = sdk.getComponent('dialogs.keybackup.RestoreKeyBackupDialog');
|
const RestoreKeyBackupDialog = sdk.getComponent('dialogs.keybackup.RestoreKeyBackupDialog');
|
||||||
Modal.createTrackedDialog('Restore Backup', '', RestoreKeyBackupDialog, {
|
Modal.createTrackedDialog(
|
||||||
onFinished: this.props.onFinished,
|
'Restore Backup', '', RestoreKeyBackupDialog, {
|
||||||
});
|
onFinished: this.props.onFinished,
|
||||||
|
}, null, /* priority = */ false, /* static = */ true,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2019 New Vector Ltd
|
Copyright 2019 New Vector Ltd
|
||||||
|
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -35,6 +36,7 @@ export default class RecoveryMethodRemovedDialog extends React.PureComponent {
|
||||||
this.props.onFinished();
|
this.props.onFinished();
|
||||||
Modal.createTrackedDialogAsync("Key Backup", "Key Backup",
|
Modal.createTrackedDialogAsync("Key Backup", "Key Backup",
|
||||||
import("./CreateKeyBackupDialog"),
|
import("./CreateKeyBackupDialog"),
|
||||||
|
null, null, /* priority = */ false, /* static = */ true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2018, 2019 New Vector Ltd
|
Copyright 2018, 2019 New Vector Ltd
|
||||||
|
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -94,10 +95,14 @@ export default class LogoutDialog extends React.Component {
|
||||||
// verified, so restore the backup which will give us the keys from it and
|
// verified, so restore the backup which will give us the keys from it and
|
||||||
// allow us to trust it (ie. upload keys to it)
|
// allow us to trust it (ie. upload keys to it)
|
||||||
const RestoreKeyBackupDialog = sdk.getComponent('dialogs.keybackup.RestoreKeyBackupDialog');
|
const RestoreKeyBackupDialog = sdk.getComponent('dialogs.keybackup.RestoreKeyBackupDialog');
|
||||||
Modal.createTrackedDialog('Restore Backup', '', RestoreKeyBackupDialog, {});
|
Modal.createTrackedDialog(
|
||||||
|
'Restore Backup', '', RestoreKeyBackupDialog, null, null,
|
||||||
|
/* priority = */ false, /* static = */ true,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
Modal.createTrackedDialogAsync("Key Backup", "Key Backup",
|
Modal.createTrackedDialogAsync("Key Backup", "Key Backup",
|
||||||
import("../../../async-components/views/dialogs/keybackup/CreateKeyBackupDialog"),
|
import("../../../async-components/views/dialogs/keybackup/CreateKeyBackupDialog"),
|
||||||
|
null, null, /* priority = */ false, /* static = */ true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2018, 2019 New Vector Ltd
|
Copyright 2018, 2019 New Vector Ltd
|
||||||
|
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -15,17 +16,18 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { MatrixClient } from 'matrix-js-sdk';
|
||||||
|
|
||||||
import sdk from '../../../../index';
|
import sdk from '../../../../index';
|
||||||
import MatrixClientPeg from '../../../../MatrixClientPeg';
|
import MatrixClientPeg from '../../../../MatrixClientPeg';
|
||||||
import Modal from '../../../../Modal';
|
import Modal from '../../../../Modal';
|
||||||
|
|
||||||
import { MatrixClient } from 'matrix-js-sdk';
|
|
||||||
|
|
||||||
import { _t } from '../../../../languageHandler';
|
import { _t } from '../../../../languageHandler';
|
||||||
import {Key} from "../../../../Keyboard";
|
import {Key} from "../../../../Keyboard";
|
||||||
|
import { accessSecretStorage } from '../../../../CrossSigningManager';
|
||||||
|
|
||||||
const RESTORE_TYPE_PASSPHRASE = 0;
|
const RESTORE_TYPE_PASSPHRASE = 0;
|
||||||
const RESTORE_TYPE_RECOVERYKEY = 1;
|
const RESTORE_TYPE_RECOVERYKEY = 1;
|
||||||
|
const RESTORE_TYPE_SECRET_STORAGE = 2;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dialog for restoring e2e keys from a backup and the user's recovery key
|
* Dialog for restoring e2e keys from a backup and the user's recovery key
|
||||||
|
@ -35,6 +37,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
backupInfo: null,
|
backupInfo: null,
|
||||||
|
backupKeyStored: null,
|
||||||
loading: false,
|
loading: false,
|
||||||
loadError: null,
|
loadError: null,
|
||||||
restoreError: null,
|
restoreError: null,
|
||||||
|
@ -73,7 +76,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
|
||||||
onFinished: () => {
|
onFinished: () => {
|
||||||
this._loadBackupStatus();
|
this._loadBackupStatus();
|
||||||
},
|
},
|
||||||
},
|
}, null, /* priority = */ false, /* static = */ true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,6 +151,32 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _restoreWithSecretStorage() {
|
||||||
|
this.setState({
|
||||||
|
loading: true,
|
||||||
|
restoreError: null,
|
||||||
|
restoreType: RESTORE_TYPE_SECRET_STORAGE,
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
// `accessSecretStorage` may prompt for storage access as needed.
|
||||||
|
const recoverInfo = await accessSecretStorage(async () => {
|
||||||
|
return MatrixClientPeg.get().restoreKeyBackupWithSecretStorage(
|
||||||
|
this.state.backupInfo,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
recoverInfo,
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.log("Error restoring backup", e);
|
||||||
|
this.setState({
|
||||||
|
restoreError: e,
|
||||||
|
loading: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async _loadBackupStatus() {
|
async _loadBackupStatus() {
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: true,
|
loading: true,
|
||||||
|
@ -155,10 +184,20 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
const backupInfo = await MatrixClientPeg.get().getKeyBackupVersion();
|
const backupInfo = await MatrixClientPeg.get().getKeyBackupVersion();
|
||||||
|
const backupKeyStored = await MatrixClientPeg.get().isKeyBackupKeyStored();
|
||||||
|
this.setState({
|
||||||
|
backupInfo,
|
||||||
|
backupKeyStored,
|
||||||
|
});
|
||||||
|
|
||||||
|
// If the backup key is stored, we can proceed directly to restore.
|
||||||
|
if (backupKeyStored) {
|
||||||
|
return this._restoreWithSecretStorage();
|
||||||
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
loadError: null,
|
loadError: null,
|
||||||
loading: false,
|
loading: false,
|
||||||
backupInfo,
|
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("Error loading backup status", e);
|
console.log("Error loading backup status", e);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2018, 2019 New Vector Ltd
|
Copyright 2018, 2019 New Vector Ltd
|
||||||
|
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -70,10 +71,14 @@ export default class RoomRecoveryReminder extends React.PureComponent {
|
||||||
// verified, so restore the backup which will give us the keys from it and
|
// verified, so restore the backup which will give us the keys from it and
|
||||||
// allow us to trust it (ie. upload keys to it)
|
// allow us to trust it (ie. upload keys to it)
|
||||||
const RestoreKeyBackupDialog = sdk.getComponent('dialogs.keybackup.RestoreKeyBackupDialog');
|
const RestoreKeyBackupDialog = sdk.getComponent('dialogs.keybackup.RestoreKeyBackupDialog');
|
||||||
Modal.createTrackedDialog('Restore Backup', '', RestoreKeyBackupDialog, {});
|
Modal.createTrackedDialog(
|
||||||
|
'Restore Backup', '', RestoreKeyBackupDialog, null, null,
|
||||||
|
/* priority = */ false, /* static = */ true,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
Modal.createTrackedDialogAsync("Key Backup", "Key Backup",
|
Modal.createTrackedDialogAsync("Key Backup", "Key Backup",
|
||||||
import("../../../async-components/views/dialogs/keybackup/CreateKeyBackupDialog"),
|
import("../../../async-components/views/dialogs/keybackup/CreateKeyBackupDialog"),
|
||||||
|
null, null, /* priority = */ false, /* static = */ true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,14 +155,14 @@ export default class RoomRecoveryReminder extends React.PureComponent {
|
||||||
onClick={this.onSetupClick}>
|
onClick={this.onSetupClick}>
|
||||||
{setupCaption}
|
{setupCaption}
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
<p><AccessibleButton className="mx_RoomRecoveryReminder_secondary mx_linkButton"
|
<AccessibleButton className="mx_RoomRecoveryReminder_secondary mx_linkButton"
|
||||||
onClick={this.onOnNotNowClick}>
|
onClick={this.onOnNotNowClick}>
|
||||||
{ _t("Not now") }
|
{ _t("Not now") }
|
||||||
</AccessibleButton></p>
|
</AccessibleButton>
|
||||||
<p><AccessibleButton className="mx_RoomRecoveryReminder_secondary mx_linkButton"
|
<AccessibleButton className="mx_RoomRecoveryReminder_secondary mx_linkButton"
|
||||||
onClick={this.onDontAskAgainClick}>
|
onClick={this.onDontAskAgainClick}>
|
||||||
{ _t("Don't ask me again") }
|
{ _t("Don't ask me again") }
|
||||||
</AccessibleButton></p>
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2018 New Vector Ltd
|
Copyright 2018 New Vector Ltd
|
||||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -22,7 +22,6 @@ import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import Modal from '../../../Modal';
|
import Modal from '../../../Modal';
|
||||||
import SettingsStore from '../../../../lib/settings/SettingsStore';
|
import SettingsStore from '../../../../lib/settings/SettingsStore';
|
||||||
import { accessSecretStorage } from '../../../CrossSigningManager';
|
|
||||||
|
|
||||||
export default class KeyBackupPanel extends React.PureComponent {
|
export default class KeyBackupPanel extends React.PureComponent {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -128,36 +127,24 @@ export default class KeyBackupPanel extends React.PureComponent {
|
||||||
Modal.createTrackedDialogAsync('Key Backup', 'Key Backup',
|
Modal.createTrackedDialogAsync('Key Backup', 'Key Backup',
|
||||||
import('../../../async-components/views/dialogs/keybackup/CreateKeyBackupDialog'),
|
import('../../../async-components/views/dialogs/keybackup/CreateKeyBackupDialog'),
|
||||||
{
|
{
|
||||||
|
secureSecretStorage: false,
|
||||||
onFinished: () => {
|
onFinished: () => {
|
||||||
this._loadBackupStatus();
|
this._loadBackupStatus();
|
||||||
},
|
},
|
||||||
},
|
}, null, /* priority = */ false, /* static = */ true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_startNewBackupWithSecureSecretStorage = async () => {
|
_startNewBackupWithSecureSecretStorage = async () => {
|
||||||
const cli = MatrixClientPeg.get();
|
Modal.createTrackedDialogAsync('Key Backup', 'Key Backup',
|
||||||
let info;
|
import('../../../async-components/views/dialogs/keybackup/CreateKeyBackupDialog'),
|
||||||
try {
|
{
|
||||||
await accessSecretStorage(async () => {
|
secureSecretStorage: true,
|
||||||
info = await cli.prepareKeyBackupVersion(
|
onFinished: () => {
|
||||||
null /* random key */,
|
this._loadBackupStatus();
|
||||||
{ secureSecretStorage: true },
|
},
|
||||||
);
|
}, null, /* priority = */ false, /* static = */ true,
|
||||||
info = await cli.createKeyBackupVersion(info);
|
);
|
||||||
});
|
|
||||||
await MatrixClientPeg.get().scheduleAllGroupSessionsForBackup();
|
|
||||||
this._loadBackupStatus();
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Error creating key backup", e);
|
|
||||||
// TODO: If creating a version succeeds, but backup fails, should we
|
|
||||||
// delete the version, disable backup, or do nothing? If we just
|
|
||||||
// disable without deleting, we'll enable on next app reload since
|
|
||||||
// it is trusted.
|
|
||||||
if (info && info.version) {
|
|
||||||
MatrixClientPeg.get().deleteKeyBackupVersion(info.version);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_deleteBackup = () => {
|
_deleteBackup = () => {
|
||||||
|
@ -181,22 +168,11 @@ export default class KeyBackupPanel extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
_restoreBackup = async () => {
|
_restoreBackup = async () => {
|
||||||
// Use legacy path if backup key not stored in secret storage
|
const RestoreKeyBackupDialog = sdk.getComponent('dialogs.keybackup.RestoreKeyBackupDialog');
|
||||||
if (!this.state.backupKeyStored) {
|
Modal.createTrackedDialog(
|
||||||
const RestoreKeyBackupDialog = sdk.getComponent('dialogs.keybackup.RestoreKeyBackupDialog');
|
'Restore Backup', '', RestoreKeyBackupDialog, null, null,
|
||||||
Modal.createTrackedDialog('Restore Backup', '', RestoreKeyBackupDialog);
|
/* priority = */ false, /* static = */ true,
|
||||||
return;
|
);
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await accessSecretStorage(async () => {
|
|
||||||
await MatrixClientPeg.get().restoreKeyBackupWithSecretStorage(
|
|
||||||
this.state.backupInfo,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
console.log("Error restoring backup", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
Loading…
Reference in New Issue