Convert CreateKeyBackupDialog to class
This commit is contained in:
parent
d5d2f7f936
commit
af2302265a
1 changed files with 66 additions and 64 deletions
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2018, 2019 New Vector Ltd
|
Copyright 2018, 2019 New Vector Ltd
|
||||||
|
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -15,7 +16,6 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import createReactClass from 'create-react-class';
|
|
||||||
import sdk from '../../../../index';
|
import sdk from '../../../../index';
|
||||||
import MatrixClientPeg from '../../../../MatrixClientPeg';
|
import MatrixClientPeg from '../../../../MatrixClientPeg';
|
||||||
import { scorePassword } from '../../../../utils/PasswordScorer';
|
import { scorePassword } from '../../../../utils/PasswordScorer';
|
||||||
|
@ -49,9 +49,11 @@ function selectText(target) {
|
||||||
* Walks the user through the process of creating an e2e key backup
|
* Walks the user through the process of creating an e2e key backup
|
||||||
* on the server.
|
* on the server.
|
||||||
*/
|
*/
|
||||||
export default createReactClass({
|
export default class CreateKeyBackupDialog extends React.PureComponent {
|
||||||
getInitialState: function() {
|
constructor(props) {
|
||||||
return {
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
phase: PHASE_PASSPHRASE,
|
phase: PHASE_PASSPHRASE,
|
||||||
passPhrase: '',
|
passPhrase: '',
|
||||||
passPhraseConfirm: '',
|
passPhraseConfirm: '',
|
||||||
|
@ -60,25 +62,25 @@ export default createReactClass({
|
||||||
zxcvbnResult: null,
|
zxcvbnResult: null,
|
||||||
setPassPhrase: false,
|
setPassPhrase: false,
|
||||||
};
|
};
|
||||||
},
|
}
|
||||||
|
|
||||||
componentWillMount: function() {
|
componentWillMount() {
|
||||||
this._recoveryKeyNode = null;
|
this._recoveryKeyNode = null;
|
||||||
this._keyBackupInfo = null;
|
this._keyBackupInfo = null;
|
||||||
this._setZxcvbnResultTimeout = null;
|
this._setZxcvbnResultTimeout = null;
|
||||||
},
|
}
|
||||||
|
|
||||||
componentWillUnmount: function() {
|
componentWillUnmount() {
|
||||||
if (this._setZxcvbnResultTimeout !== null) {
|
if (this._setZxcvbnResultTimeout !== null) {
|
||||||
clearTimeout(this._setZxcvbnResultTimeout);
|
clearTimeout(this._setZxcvbnResultTimeout);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
_collectRecoveryKeyNode: function(n) {
|
_collectRecoveryKeyNode = (n) => {
|
||||||
this._recoveryKeyNode = n;
|
this._recoveryKeyNode = n;
|
||||||
},
|
}
|
||||||
|
|
||||||
_onCopyClick: function() {
|
_onCopyClick = () => {
|
||||||
selectText(this._recoveryKeyNode);
|
selectText(this._recoveryKeyNode);
|
||||||
const successful = document.execCommand('copy');
|
const successful = document.execCommand('copy');
|
||||||
if (successful) {
|
if (successful) {
|
||||||
|
@ -87,9 +89,9 @@ export default createReactClass({
|
||||||
phase: PHASE_KEEPITSAFE,
|
phase: PHASE_KEEPITSAFE,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
_onDownloadClick: function() {
|
_onDownloadClick = () => {
|
||||||
const blob = new Blob([this._keyBackupInfo.recovery_key], {
|
const blob = new Blob([this._keyBackupInfo.recovery_key], {
|
||||||
type: 'text/plain;charset=us-ascii',
|
type: 'text/plain;charset=us-ascii',
|
||||||
});
|
});
|
||||||
|
@ -99,9 +101,9 @@ export default createReactClass({
|
||||||
downloaded: true,
|
downloaded: true,
|
||||||
phase: PHASE_KEEPITSAFE,
|
phase: PHASE_KEEPITSAFE,
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
|
|
||||||
_createBackup: async function() {
|
_createBackup = async () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
phase: PHASE_BACKINGUP,
|
phase: PHASE_BACKINGUP,
|
||||||
error: null,
|
error: null,
|
||||||
|
@ -128,38 +130,38 @@ export default createReactClass({
|
||||||
error: e,
|
error: e,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
_onCancel: function() {
|
_onCancel = () => {
|
||||||
this.props.onFinished(false);
|
this.props.onFinished(false);
|
||||||
},
|
}
|
||||||
|
|
||||||
_onDone: function() {
|
_onDone = () => {
|
||||||
this.props.onFinished(true);
|
this.props.onFinished(true);
|
||||||
},
|
}
|
||||||
|
|
||||||
_onOptOutClick: function() {
|
_onOptOutClick = () => {
|
||||||
this.setState({phase: PHASE_OPTOUT_CONFIRM});
|
this.setState({phase: PHASE_OPTOUT_CONFIRM});
|
||||||
},
|
}
|
||||||
|
|
||||||
_onSetUpClick: function() {
|
_onSetUpClick = () => {
|
||||||
this.setState({phase: PHASE_PASSPHRASE});
|
this.setState({phase: PHASE_PASSPHRASE});
|
||||||
},
|
}
|
||||||
|
|
||||||
_onSkipPassPhraseClick: async function() {
|
_onSkipPassPhraseClick = async () => {
|
||||||
this._keyBackupInfo = await MatrixClientPeg.get().prepareKeyBackupVersion();
|
this._keyBackupInfo = await MatrixClientPeg.get().prepareKeyBackupVersion();
|
||||||
this.setState({
|
this.setState({
|
||||||
copied: false,
|
copied: false,
|
||||||
downloaded: false,
|
downloaded: false,
|
||||||
phase: PHASE_SHOWKEY,
|
phase: PHASE_SHOWKEY,
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
|
|
||||||
_onPassPhraseNextClick: function() {
|
_onPassPhraseNextClick = () => {
|
||||||
this.setState({phase: PHASE_PASSPHRASE_CONFIRM});
|
this.setState({phase: PHASE_PASSPHRASE_CONFIRM});
|
||||||
},
|
}
|
||||||
|
|
||||||
_onPassPhraseKeyPress: async function(e) {
|
_onPassPhraseKeyPress = async (e) => {
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
// If we're waiting for the timeout before updating the result at this point,
|
// If we're waiting for the timeout before updating the result at this point,
|
||||||
// skip ahead and do it now, otherwise we'll deny the attempt to proceed
|
// skip ahead and do it now, otherwise we'll deny the attempt to proceed
|
||||||
|
@ -177,9 +179,9 @@ export default createReactClass({
|
||||||
this._onPassPhraseNextClick();
|
this._onPassPhraseNextClick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
_onPassPhraseConfirmNextClick: async function() {
|
_onPassPhraseConfirmNextClick = async () => {
|
||||||
this._keyBackupInfo = await MatrixClientPeg.get().prepareKeyBackupVersion(this.state.passPhrase);
|
this._keyBackupInfo = await MatrixClientPeg.get().prepareKeyBackupVersion(this.state.passPhrase);
|
||||||
this.setState({
|
this.setState({
|
||||||
setPassPhrase: true,
|
setPassPhrase: true,
|
||||||
|
@ -187,30 +189,30 @@ export default createReactClass({
|
||||||
downloaded: false,
|
downloaded: false,
|
||||||
phase: PHASE_SHOWKEY,
|
phase: PHASE_SHOWKEY,
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
|
|
||||||
_onPassPhraseConfirmKeyPress: function(e) {
|
_onPassPhraseConfirmKeyPress = (e) => {
|
||||||
if (e.key === 'Enter' && this.state.passPhrase === this.state.passPhraseConfirm) {
|
if (e.key === 'Enter' && this.state.passPhrase === this.state.passPhraseConfirm) {
|
||||||
this._onPassPhraseConfirmNextClick();
|
this._onPassPhraseConfirmNextClick();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
_onSetAgainClick: function() {
|
_onSetAgainClick = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
passPhrase: '',
|
passPhrase: '',
|
||||||
passPhraseConfirm: '',
|
passPhraseConfirm: '',
|
||||||
phase: PHASE_PASSPHRASE,
|
phase: PHASE_PASSPHRASE,
|
||||||
zxcvbnResult: null,
|
zxcvbnResult: null,
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
|
|
||||||
_onKeepItSafeBackClick: function() {
|
_onKeepItSafeBackClick = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
phase: PHASE_SHOWKEY,
|
phase: PHASE_SHOWKEY,
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
|
|
||||||
_onPassPhraseChange: function(e) {
|
_onPassPhraseChange = (e) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
passPhrase: e.target.value,
|
passPhrase: e.target.value,
|
||||||
});
|
});
|
||||||
|
@ -227,19 +229,19 @@ export default createReactClass({
|
||||||
zxcvbnResult: scorePassword(this.state.passPhrase),
|
zxcvbnResult: scorePassword(this.state.passPhrase),
|
||||||
});
|
});
|
||||||
}, PASSPHRASE_FEEDBACK_DELAY);
|
}, PASSPHRASE_FEEDBACK_DELAY);
|
||||||
},
|
}
|
||||||
|
|
||||||
_onPassPhraseConfirmChange: function(e) {
|
_onPassPhraseConfirmChange = (e) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
passPhraseConfirm: e.target.value,
|
passPhraseConfirm: e.target.value,
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
|
|
||||||
_passPhraseIsValid: function() {
|
_passPhraseIsValid() {
|
||||||
return this.state.zxcvbnResult && this.state.zxcvbnResult.score >= PASSWORD_MIN_SCORE;
|
return this.state.zxcvbnResult && this.state.zxcvbnResult.score >= PASSWORD_MIN_SCORE;
|
||||||
},
|
}
|
||||||
|
|
||||||
_renderPhasePassPhrase: function() {
|
_renderPhasePassPhrase() {
|
||||||
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
|
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
|
||||||
|
|
||||||
let strengthMeter;
|
let strengthMeter;
|
||||||
|
@ -305,9 +307,9 @@ export default createReactClass({
|
||||||
</button></p>
|
</button></p>
|
||||||
</details>
|
</details>
|
||||||
</div>;
|
</div>;
|
||||||
},
|
}
|
||||||
|
|
||||||
_renderPhasePassPhraseConfirm: function() {
|
_renderPhasePassPhraseConfirm() {
|
||||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
||||||
|
|
||||||
let matchText;
|
let matchText;
|
||||||
|
@ -361,9 +363,9 @@ export default createReactClass({
|
||||||
disabled={this.state.passPhrase !== this.state.passPhraseConfirm}
|
disabled={this.state.passPhrase !== this.state.passPhraseConfirm}
|
||||||
/>
|
/>
|
||||||
</div>;
|
</div>;
|
||||||
},
|
}
|
||||||
|
|
||||||
_renderPhaseShowKey: function() {
|
_renderPhaseShowKey() {
|
||||||
let bodyText;
|
let bodyText;
|
||||||
if (this.state.setPassPhrase) {
|
if (this.state.setPassPhrase) {
|
||||||
bodyText = _t(
|
bodyText = _t(
|
||||||
|
@ -402,9 +404,9 @@ export default createReactClass({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
},
|
}
|
||||||
|
|
||||||
_renderPhaseKeepItSafe: function() {
|
_renderPhaseKeepItSafe() {
|
||||||
let introText;
|
let introText;
|
||||||
if (this.state.copied) {
|
if (this.state.copied) {
|
||||||
introText = _t(
|
introText = _t(
|
||||||
|
@ -431,16 +433,16 @@ export default createReactClass({
|
||||||
<button onClick={this._onKeepItSafeBackClick}>{_t("Back")}</button>
|
<button onClick={this._onKeepItSafeBackClick}>{_t("Back")}</button>
|
||||||
</DialogButtons>
|
</DialogButtons>
|
||||||
</div>;
|
</div>;
|
||||||
},
|
}
|
||||||
|
|
||||||
_renderBusyPhase: function(text) {
|
_renderBusyPhase(text) {
|
||||||
const Spinner = sdk.getComponent('views.elements.Spinner');
|
const Spinner = sdk.getComponent('views.elements.Spinner');
|
||||||
return <div>
|
return <div>
|
||||||
<Spinner />
|
<Spinner />
|
||||||
</div>;
|
</div>;
|
||||||
},
|
}
|
||||||
|
|
||||||
_renderPhaseDone: function() {
|
_renderPhaseDone() {
|
||||||
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
|
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
|
||||||
return <div>
|
return <div>
|
||||||
<p>{_t(
|
<p>{_t(
|
||||||
|
@ -451,9 +453,9 @@ export default createReactClass({
|
||||||
hasCancel={false}
|
hasCancel={false}
|
||||||
/>
|
/>
|
||||||
</div>;
|
</div>;
|
||||||
},
|
}
|
||||||
|
|
||||||
_renderPhaseOptOutConfirm: function() {
|
_renderPhaseOptOutConfirm() {
|
||||||
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
|
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
|
||||||
return <div>
|
return <div>
|
||||||
{_t(
|
{_t(
|
||||||
|
@ -467,9 +469,9 @@ export default createReactClass({
|
||||||
<button onClick={this._onCancel}>I understand, continue without</button>
|
<button onClick={this._onCancel}>I understand, continue without</button>
|
||||||
</DialogButtons>
|
</DialogButtons>
|
||||||
</div>;
|
</div>;
|
||||||
},
|
}
|
||||||
|
|
||||||
_titleForPhase: function(phase) {
|
_titleForPhase(phase) {
|
||||||
switch (phase) {
|
switch (phase) {
|
||||||
case PHASE_PASSPHRASE:
|
case PHASE_PASSPHRASE:
|
||||||
return _t('Secure your backup with a passphrase');
|
return _t('Secure your backup with a passphrase');
|
||||||
|
@ -488,9 +490,9 @@ export default createReactClass({
|
||||||
default:
|
default:
|
||||||
return _t("Create Key Backup");
|
return _t("Create Key Backup");
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
render: function() {
|
render() {
|
||||||
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
||||||
|
|
||||||
let content;
|
let content;
|
||||||
|
@ -543,5 +545,5 @@ export default createReactClass({
|
||||||
</div>
|
</div>
|
||||||
</BaseDialog>
|
</BaseDialog>
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
});
|
}
|
||||||
|
|
Loading…
Reference in a new issue