diff --git a/src/async-components/views/dialogs/keybackup/NewRecoveryMethodDialog.js b/src/async-components/views/dialogs/keybackup/NewRecoveryMethodDialog.js index 28281af771..147f109113 100644 --- a/src/async-components/views/dialogs/keybackup/NewRecoveryMethodDialog.js +++ b/src/async-components/views/dialogs/keybackup/NewRecoveryMethodDialog.js @@ -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"); 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 () => { const RestoreKeyBackupDialog = sdk.getComponent('dialogs.keybackup.RestoreKeyBackupDialog'); - Modal.createTrackedDialog('Restore Backup', '', RestoreKeyBackupDialog, { - onFinished: this.props.onFinished, - }); + Modal.createTrackedDialog( + 'Restore Backup', '', RestoreKeyBackupDialog, { + onFinished: this.props.onFinished, + }, null, /* priority = */ false, /* static = */ true, + ); } render() { diff --git a/src/components/views/dialogs/LogoutDialog.js b/src/components/views/dialogs/LogoutDialog.js index 47d4153494..6e4f950830 100644 --- a/src/components/views/dialogs/LogoutDialog.js +++ b/src/components/views/dialogs/LogoutDialog.js @@ -1,5 +1,6 @@ /* 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"); you may not use this file except in compliance with the License. @@ -94,7 +95,10 @@ export default class LogoutDialog extends React.Component { // verified, so restore the backup which will give us the keys from it and // allow us to trust it (ie. upload keys to it) const RestoreKeyBackupDialog = sdk.getComponent('dialogs.keybackup.RestoreKeyBackupDialog'); - Modal.createTrackedDialog('Restore Backup', '', RestoreKeyBackupDialog, {}); + Modal.createTrackedDialog( + 'Restore Backup', '', RestoreKeyBackupDialog, null, null, + /* priority = */ false, /* static = */ true, + ); } else { Modal.createTrackedDialogAsync("Key Backup", "Key Backup", import("../../../async-components/views/dialogs/keybackup/CreateKeyBackupDialog"), diff --git a/src/components/views/dialogs/keybackup/RestoreKeyBackupDialog.js b/src/components/views/dialogs/keybackup/RestoreKeyBackupDialog.js index 45168c381e..2881cc920c 100644 --- a/src/components/views/dialogs/keybackup/RestoreKeyBackupDialog.js +++ b/src/components/views/dialogs/keybackup/RestoreKeyBackupDialog.js @@ -1,5 +1,6 @@ /* 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"); 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 { MatrixClient } from 'matrix-js-sdk'; + import sdk from '../../../../index'; import MatrixClientPeg from '../../../../MatrixClientPeg'; import Modal from '../../../../Modal'; - -import { MatrixClient } from 'matrix-js-sdk'; - import { _t } from '../../../../languageHandler'; import {Key} from "../../../../Keyboard"; +import { accessSecretStorage } from '../../../../CrossSigningManager'; const RESTORE_TYPE_PASSPHRASE = 0; 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 @@ -35,6 +37,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent { super(props); this.state = { backupInfo: null, + backupKeyStored: null, loading: false, loadError: null, restoreError: null, @@ -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() { this.setState({ loading: true, @@ -155,10 +184,20 @@ export default class RestoreKeyBackupDialog extends React.PureComponent { }); try { 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({ loadError: null, loading: false, - backupInfo, }); } catch (e) { console.log("Error loading backup status", e); diff --git a/src/components/views/rooms/RoomRecoveryReminder.js b/src/components/views/rooms/RoomRecoveryReminder.js index 6b7366bc4f..495364bf4c 100644 --- a/src/components/views/rooms/RoomRecoveryReminder.js +++ b/src/components/views/rooms/RoomRecoveryReminder.js @@ -1,5 +1,6 @@ /* 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"); you may not use this file except in compliance with the License. @@ -70,7 +71,10 @@ export default class RoomRecoveryReminder extends React.PureComponent { // verified, so restore the backup which will give us the keys from it and // allow us to trust it (ie. upload keys to it) const RestoreKeyBackupDialog = sdk.getComponent('dialogs.keybackup.RestoreKeyBackupDialog'); - Modal.createTrackedDialog('Restore Backup', '', RestoreKeyBackupDialog, {}); + Modal.createTrackedDialog( + 'Restore Backup', '', RestoreKeyBackupDialog, null, null, + /* priority = */ false, /* static = */ true, + ); } else { Modal.createTrackedDialogAsync("Key Backup", "Key Backup", import("../../../async-components/views/dialogs/keybackup/CreateKeyBackupDialog"), diff --git a/src/components/views/settings/KeyBackupPanel.js b/src/components/views/settings/KeyBackupPanel.js index 559b1e0ba1..55bfadba88 100644 --- a/src/components/views/settings/KeyBackupPanel.js +++ b/src/components/views/settings/KeyBackupPanel.js @@ -1,6 +1,6 @@ /* 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"); you may not use this file except in compliance with the License. @@ -181,22 +181,11 @@ export default class KeyBackupPanel extends React.PureComponent { } _restoreBackup = async () => { - // Use legacy path if backup key not stored in secret storage - if (!this.state.backupKeyStored) { - const RestoreKeyBackupDialog = sdk.getComponent('dialogs.keybackup.RestoreKeyBackupDialog'); - Modal.createTrackedDialog('Restore Backup', '', RestoreKeyBackupDialog); - return; - } - - try { - await accessSecretStorage(async () => { - await MatrixClientPeg.get().restoreKeyBackupWithSecretStorage( - this.state.backupInfo, - ); - }); - } catch (e) { - console.log("Error restoring backup", e); - } + const RestoreKeyBackupDialog = sdk.getComponent('dialogs.keybackup.RestoreKeyBackupDialog'); + Modal.createTrackedDialog( + 'Restore Backup', '', RestoreKeyBackupDialog, null, null, + /* priority = */ false, /* static = */ true, + ); } render() {