diff --git a/src/components/views/dialogs/keybackup/RestoreKeyBackupDialog.js b/src/components/views/dialogs/keybackup/RestoreKeyBackupDialog.js new file mode 100644 index 0000000000..a0451a9201 --- /dev/null +++ b/src/components/views/dialogs/keybackup/RestoreKeyBackupDialog.js @@ -0,0 +1,156 @@ +/* +Copyright 2018 New Vector Ltd + +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 Modal from '../../../../Modal'; +import React from 'react'; +import PropTypes from 'prop-types'; +import sdk from '../../../../index'; +import MatrixClientPeg from '../../../../MatrixClientPeg'; +import { formatCryptoKey } from '../../../../utils/FormattingUtils'; +import Promise from 'bluebird'; + +import { _t, _td } from '../../../../languageHandler'; + +/** + * Dialog for restoring e2e keys from a backup and the user's recovery key + */ +export default React.createClass({ + getInitialState: function() { + return { + backupInfo: null, + loading: false, + loadError: null, + restoreError: null, + recoveryKey: "", + recoverInfo: null, + }; + }, + + componentWillMount: function() { + this._loadBackupStatus(); + }, + + _onCancel: function() { + this.props.onFinished(false); + }, + + _onDone: function() { + this.props.onFinished(true); + }, + + _onRecoveryKeyChange: function(e) { + this.setState({recoveryKey: e.target.value}); + }, + + _onRecoverClick: async function() { + this.setState({ + loading: true, + restoreError: null, + }); + try { + const recoverInfo = await MatrixClientPeg.get().restoreKeyBackups( + this.state.recoveryKey.replace(/ /g, ''), undefined, undefined, this.state.backupInfo.version, + ); + this.setState({ + loading: false, + recoverInfo, + }); + } catch (e) { + console.log("Error restoring backup", e); + this.setState({ + loading: false, + restoreError: e, + }); + } + }, + + _loadBackupStatus: async function() { + this.setState({ + loading: true, + loadError: null, + }); + try { + const backupInfo = await MatrixClientPeg.get().getKeyBackupVersion(); + this.setState({ + loadError: null, + loading: false, + backupInfo, + }); + } catch (e) { + console.log("Error loading backup status", e); + this.setState({ + loadError: e, + loading: false, + }); + } + }, + + render: function() { + const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); + const Spinner = sdk.getComponent("elements.Spinner"); + + let content; + if (this.state.loading) { + content = ; + } else if (this.state.loadError) { + content = _t("Unable to load backup status"); + } else if (this.state.restoreError) { + content = _t("Unable to restore backup"); + } else if (this.state.backupInfo === null) { + content = _t("No backup found!"); + } else if (this.state.recoverInfo) { + let failedToDecrypt; + if (this.state.recoverInfo.total > this.state.recoverInfo.imported) { + failedToDecrypt =

{_t( + "Failed to decrypt %(failedCount)s sessions!", + {failedCount: this.state.recoverInfo.total - this.state.recoverInfo.imported}, + )}

; + } + content =
+

{_t("Restored %(sessionCount)s session keys", {sessionCount: this.state.recoverInfo.imported})}

+ {failedToDecrypt} +
; + } else { + const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); + content =
+ {_t("Please enter the recovery key generated when you set up key backup")}
+