Update backup creation paths for SSSS

This updates the various backup creation entry points to ensure they support
creating with secret storage if the feature flag is enabled.
This commit is contained in:
J. Ryan Stinnett 2020-01-03 15:34:03 +00:00
parent 4211ec5063
commit b8683462e8
6 changed files with 61 additions and 32 deletions

View file

@ -1,6 +1,6 @@
/*
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");
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 FileSaver from 'file-saver';
import PropTypes from 'prop-types';
import sdk from '../../../../index';
import MatrixClientPeg from '../../../../MatrixClientPeg';
import { scorePassword } from '../../../../utils/PasswordScorer';
import { _t } from '../../../../languageHandler';
import { accessSecretStorage } from '../../../../CrossSigningManager';
import SettingsStore from '../../../../../lib/settings/SettingsStore';
const PHASE_PASSPHRASE = 0;
const PHASE_PASSPHRASE_CONFIRM = 1;
@ -49,10 +52,20 @@ function selectText(target) {
* on the server.
*/
export default class CreateKeyBackupDialog extends React.PureComponent {
static propTypes = {
secureSecretStorage: PropTypes.bool,
onFinished: PropTypes.func.isRequired,
}
constructor(props) {
super(props);
this._recoveryKeyNode = null;
this._keyBackupInfo = null;
this._setZxcvbnResultTimeout = null;
this.state = {
secureSecretStorage: props.secureSecretStorage,
phase: PHASE_PASSPHRASE,
passPhrase: '',
passPhraseConfirm: '',
@ -61,12 +74,25 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
zxcvbnResult: null,
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() {
this._recoveryKeyNode = null;
this._keyBackupInfo = null;
this._setZxcvbnResultTimeout = null;
componentDidMount() {
// 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._createBackup();
}
}
componentWillUnmount() {
@ -103,15 +129,26 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
}
_createBackup = async () => {
const { secureSecretStorage } = this.state;
this.setState({
phase: PHASE_BACKINGUP,
error: null,
});
let info;
try {
info = await MatrixClientPeg.get().createKeyBackupVersion(
this._keyBackupInfo,
);
if (secureSecretStorage) {
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();
this.setState({
phase: PHASE_DONE,

View file

@ -1,5 +1,6 @@
/*
Copyright 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.
@ -35,6 +36,7 @@ export default class RecoveryMethodRemovedDialog extends React.PureComponent {
this.props.onFinished();
Modal.createTrackedDialogAsync("Key Backup", "Key Backup",
import("./CreateKeyBackupDialog"),
null, null, /* priority = */ false, /* static = */ true,
);
}

View file

@ -102,6 +102,7 @@ export default class LogoutDialog extends React.Component {
} else {
Modal.createTrackedDialogAsync("Key Backup", "Key Backup",
import("../../../async-components/views/dialogs/keybackup/CreateKeyBackupDialog"),
null, null, /* priority = */ false, /* static = */ true,
);
}

View file

@ -76,7 +76,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
onFinished: () => {
this._loadBackupStatus();
},
},
}, null, /* priority = */ false, /* static = */ true,
);
}

View file

@ -78,6 +78,7 @@ export default class RoomRecoveryReminder extends React.PureComponent {
} else {
Modal.createTrackedDialogAsync("Key Backup", "Key Backup",
import("../../../async-components/views/dialogs/keybackup/CreateKeyBackupDialog"),
null, null, /* priority = */ false, /* static = */ true,
);
}
}

View file

@ -128,36 +128,24 @@ export default class KeyBackupPanel extends React.PureComponent {
Modal.createTrackedDialogAsync('Key Backup', 'Key Backup',
import('../../../async-components/views/dialogs/keybackup/CreateKeyBackupDialog'),
{
secureSecretStorage: false,
onFinished: () => {
this._loadBackupStatus();
},
},
}, null, /* priority = */ false, /* static = */ true,
);
}
_startNewBackupWithSecureSecretStorage = async () => {
const cli = MatrixClientPeg.get();
let info;
try {
await accessSecretStorage(async () => {
info = await cli.prepareKeyBackupVersion(
null /* random key */,
{ secureSecretStorage: 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);
}
}
Modal.createTrackedDialogAsync('Key Backup', 'Key Backup',
import('../../../async-components/views/dialogs/keybackup/CreateKeyBackupDialog'),
{
secureSecretStorage: true,
onFinished: () => {
this._loadBackupStatus();
},
}, null, /* priority = */ false, /* static = */ true,
);
}
_deleteBackup = () => {