mirror of
https://github.com/element-hq/element-web
synced 2024-11-23 17:56:01 +03:00
Migrate key backups to SSSS
If there's a key backup set up when we bootstrap SSSS, use its key for SSSS and add the key backup key as a passthrough secret. Requires https://github.com/matrix-org/matrix-js-sdk/pull/1128 Fixes https://github.com/vector-im/riot-web/issues/11210
This commit is contained in:
parent
f30e919f9e
commit
6851ad04b6
2 changed files with 57 additions and 9 deletions
|
@ -23,13 +23,15 @@ import FileSaver from 'file-saver';
|
|||
import { _t } from '../../../../languageHandler';
|
||||
import Modal from '../../../../Modal';
|
||||
|
||||
const PHASE_PASSPHRASE = 0;
|
||||
const PHASE_PASSPHRASE_CONFIRM = 1;
|
||||
const PHASE_SHOWKEY = 2;
|
||||
const PHASE_KEEPITSAFE = 3;
|
||||
const PHASE_STORING = 4;
|
||||
const PHASE_DONE = 5;
|
||||
const PHASE_OPTOUT_CONFIRM = 6;
|
||||
const PHASE_LOADING = 0;
|
||||
const PHASE_MIGRATE = 1;
|
||||
const PHASE_PASSPHRASE = 2;
|
||||
const PHASE_PASSPHRASE_CONFIRM = 3;
|
||||
const PHASE_SHOWKEY = 4;
|
||||
const PHASE_KEEPITSAFE = 5;
|
||||
const PHASE_STORING = 6;
|
||||
const PHASE_DONE = 7;
|
||||
const PHASE_OPTOUT_CONFIRM = 8;
|
||||
|
||||
const PASSWORD_MIN_SCORE = 4; // So secure, many characters, much complex, wow, etc, etc.
|
||||
const PASSPHRASE_FEEDBACK_DELAY = 500; // How long after keystroke to offer passphrase feedback, ms.
|
||||
|
@ -58,7 +60,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
this._setZxcvbnResultTimeout = null;
|
||||
|
||||
this.state = {
|
||||
phase: PHASE_PASSPHRASE,
|
||||
phase: PHASE_LOADING,
|
||||
passPhrase: '',
|
||||
passPhraseConfirm: '',
|
||||
copied: false,
|
||||
|
@ -66,6 +68,8 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
zxcvbnResult: null,
|
||||
setPassPhrase: false,
|
||||
};
|
||||
|
||||
this._fetchBackupInfo();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
@ -74,10 +78,23 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
async _fetchBackupInfo() {
|
||||
const backupInfo = await MatrixClientPeg.get().getKeyBackupVersion();
|
||||
|
||||
this.setState({
|
||||
phase: backupInfo ? PHASE_MIGRATE: PHASE_PASSPHRASE,
|
||||
backupInfo,
|
||||
});
|
||||
}
|
||||
|
||||
_collectRecoveryKeyNode = (n) => {
|
||||
this._recoveryKeyNode = n;
|
||||
}
|
||||
|
||||
_onMigrateNextClick = () => {
|
||||
this._bootstrapSecretStorage();
|
||||
}
|
||||
|
||||
_onCopyClick = () => {
|
||||
selectText(this._recoveryKeyNode);
|
||||
const successful = document.execCommand('copy');
|
||||
|
@ -105,6 +122,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
this.setState({
|
||||
phase: PHASE_STORING,
|
||||
error: null,
|
||||
keyBackupInfo: this.state.backupInfo,
|
||||
});
|
||||
const cli = MatrixClientPeg.get();
|
||||
try {
|
||||
|
@ -250,6 +268,26 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
return this.state.zxcvbnResult && this.state.zxcvbnResult.score >= PASSWORD_MIN_SCORE;
|
||||
}
|
||||
|
||||
_renderPhaseMigrate() {
|
||||
// This is a temporary screen so people who have the labs flag turned on and
|
||||
// click the button are aware they're making a change to their account.
|
||||
// Once we're confident enough in this (and it's supported enough) we can do
|
||||
// it automatically.
|
||||
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
|
||||
return <div>
|
||||
<p>{_t(
|
||||
"Secret Storage will be set up using your existing key backup details." +
|
||||
"Your secret storage passphrase and recovery key will be the same as " +
|
||||
" they were for your key backup",
|
||||
)}</p>
|
||||
<DialogButtons primaryButton={_t('Next')}
|
||||
onPrimaryButtonClick={this._onMigrateNextClick}
|
||||
hasCancel={true}
|
||||
onCancel={this._onCancel}
|
||||
/>
|
||||
</div>;
|
||||
}
|
||||
|
||||
_renderPhasePassPhrase() {
|
||||
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
|
||||
|
||||
|
@ -449,7 +487,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
</div>;
|
||||
}
|
||||
|
||||
_renderBusyPhase(text) {
|
||||
_renderBusyPhase() {
|
||||
const Spinner = sdk.getComponent('views.elements.Spinner');
|
||||
return <div>
|
||||
<Spinner />
|
||||
|
@ -488,6 +526,8 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
|
||||
_titleForPhase(phase) {
|
||||
switch (phase) {
|
||||
case PHASE_MIGRATE:
|
||||
return _t('Migrate from Key Backup');
|
||||
case PHASE_PASSPHRASE:
|
||||
return _t('Secure your encrypted messages with a passphrase');
|
||||
case PHASE_PASSPHRASE_CONFIRM:
|
||||
|
@ -525,6 +565,12 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
</div>;
|
||||
} else {
|
||||
switch (this.state.phase) {
|
||||
case PHASE_LOADING:
|
||||
content = this._renderBusyPhase();
|
||||
break;
|
||||
case PHASE_MIGRATE:
|
||||
content = this._renderPhaseMigrate();
|
||||
break;
|
||||
case PHASE_PASSPHRASE:
|
||||
content = this._renderPhasePassPhrase();
|
||||
break;
|
||||
|
|
|
@ -1935,6 +1935,7 @@
|
|||
"The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.",
|
||||
"File to import": "File to import",
|
||||
"Import": "Import",
|
||||
"Secret Storage will be set up using your existing key backup details.Your secret storage passphrase and recovery key will be the same as they were for your key backup": "Secret Storage will be set up using your existing key backup details.Your secret storage passphrase and recovery key will be the same as they were for your key backup",
|
||||
"Great! This passphrase looks strong enough.": "Great! This passphrase looks strong enough.",
|
||||
"<b>Warning</b>: You should only set up secret storage from a trusted computer.": "<b>Warning</b>: You should only set up secret storage from a trusted computer.",
|
||||
"We'll use secret storage to optionally store an encrypted copy of your cross-signing identity for verifying other devices and message keys on our server. Protect your access to encrypted messages with a passphrase to keep it secure.": "We'll use secret storage to optionally store an encrypted copy of your cross-signing identity for verifying other devices and message keys on our server. Protect your access to encrypted messages with a passphrase to keep it secure.",
|
||||
|
@ -1961,6 +1962,7 @@
|
|||
"Your access to encrypted messages is now protected.": "Your access to encrypted messages is now protected.",
|
||||
"Without setting up secret storage, you won't be able to restore your access to encrypted messages or your cross-signing identity for verifying other devices if you log out or use another device.": "Without setting up secret storage, you won't be able to restore your access to encrypted messages or your cross-signing identity for verifying other devices if you log out or use another device.",
|
||||
"Set up secret storage": "Set up secret storage",
|
||||
"Migrate from Key Backup": "Migrate from Key Backup",
|
||||
"Secure your encrypted messages with a passphrase": "Secure your encrypted messages with a passphrase",
|
||||
"Confirm your passphrase": "Confirm your passphrase",
|
||||
"Recovery key": "Recovery key",
|
||||
|
|
Loading…
Reference in a new issue