Allow key backup restore to get the key backup passphrase

And pass this in as the new callback to bootstrap to get the old
key backup passphrase.
pull/21833/head
David Baker 2020-03-19 20:42:16 +00:00
parent 9bfc19f367
commit c8691c73ff
3 changed files with 33 additions and 0 deletions

View File

@ -162,6 +162,20 @@ export const crossSigningCallbacks = {
onSecretRequested, onSecretRequested,
}; };
export async function promptForBackupPassphrase() {
let key;
const RestoreKeyBackupDialog = sdk.getComponent('dialogs.keybackup.RestoreKeyBackupDialog');
const { finished } = Modal.createTrackedDialog('Restore Backup', '', RestoreKeyBackupDialog, {
showSummary: false, keyCallback: k => key = k,
}, null, /* priority = */ false, /* static = */ false);
const success = await finished;
if (!success) throw new Error("Key backup prompt cancelled");
return key;
}
/** /**
* This helper should be used whenever you need to access secret storage. It * This helper should be used whenever you need to access secret storage. It
* ensures that secret storage (and also cross-signing since they each depend on * ensures that secret storage (and also cross-signing since they each depend on
@ -218,6 +232,7 @@ export async function accessSecretStorage(func = async () => { }, force = false)
throw new Error("Cross-signing key upload auth canceled"); throw new Error("Cross-signing key upload auth canceled");
} }
}, },
getBackupPassphrase: promptForBackupPassphrase,
}); });
} }

View File

@ -23,6 +23,7 @@ import { scorePassword } from '../../../../utils/PasswordScorer';
import FileSaver from 'file-saver'; import FileSaver from 'file-saver';
import { _t } from '../../../../languageHandler'; import { _t } from '../../../../languageHandler';
import Modal from '../../../../Modal'; import Modal from '../../../../Modal';
import { promptForBackupPassphrase } from '../../../../CrossSigningManager';
const PHASE_LOADING = 0; const PHASE_LOADING = 0;
const PHASE_MIGRATE = 1; const PHASE_MIGRATE = 1;
@ -243,6 +244,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
createSecretStorageKey: async () => this._keyInfo, createSecretStorageKey: async () => this._keyInfo,
keyBackupInfo: this.state.backupInfo, keyBackupInfo: this.state.backupInfo,
setupNewKeyBackup: !this.state.backupInfo && this.state.useKeyBackup, setupNewKeyBackup: !this.state.backupInfo && this.state.useKeyBackup,
getKeyBackupPassphrase: promptForBackupPassphrase,
}); });
} }
this.setState({ this.setState({

View File

@ -36,6 +36,9 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
// if false, will close the dialog as soon as the restore completes succesfully // if false, will close the dialog as soon as the restore completes succesfully
// default: true // default: true
showSummary: PropTypes.bool, showSummary: PropTypes.bool,
// If specified, gather the key from the user but then call the function with the backup
// key rather than actually (necessarily) restoring the backup.
keyCallback: PropTypes.func,
}; };
static defaultProps = { static defaultProps = {
@ -103,9 +106,18 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
restoreType: RESTORE_TYPE_PASSPHRASE, restoreType: RESTORE_TYPE_PASSPHRASE,
}); });
try { try {
// We do still restore the key backup: we must ensure that the key backup key
// is the right one and restoring it is currently the only way we can do this.
const recoverInfo = await MatrixClientPeg.get().restoreKeyBackupWithPassword( const recoverInfo = await MatrixClientPeg.get().restoreKeyBackupWithPassword(
this.state.passPhrase, undefined, undefined, this.state.backupInfo, this.state.passPhrase, undefined, undefined, this.state.backupInfo,
); );
if (this.props.keyCallback) {
const key = await MatrixClientPeg.get().keyBackupKeyFromPassword(
this.state.passPhrase, this.state.backupInfo,
);
this.props.keyCallback(key);
}
if (!this.props.showSummary) { if (!this.props.showSummary) {
this.props.onFinished(true); this.props.onFinished(true);
return; return;
@ -135,6 +147,10 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
const recoverInfo = await MatrixClientPeg.get().restoreKeyBackupWithRecoveryKey( const recoverInfo = await MatrixClientPeg.get().restoreKeyBackupWithRecoveryKey(
this.state.recoveryKey, undefined, undefined, this.state.backupInfo, this.state.recoveryKey, undefined, undefined, this.state.backupInfo,
); );
if (this.props.keyCallback) {
const key = MatrixClientPeg.get().keyBackupKeyFromRecoveryKey(this.state.recoveryKey);
this.props.keyCallback(key);
}
if (!this.props.showSummary) { if (!this.props.showSummary) {
this.props.onFinished(true); this.props.onFinished(true);
return; return;