mirror of
https://github.com/vector-im/element-web.git
synced 2024-11-16 13:14:58 +08:00
Key backup: Debounce passphrase feedback
https://github.com/vector-im/riot-web/issues/8066
This commit is contained in:
parent
1c42f4f5a0
commit
e50f15ac15
@ -32,6 +32,7 @@ const PHASE_DONE = 5;
|
|||||||
const PHASE_OPTOUT_CONFIRM = 6;
|
const PHASE_OPTOUT_CONFIRM = 6;
|
||||||
|
|
||||||
const PASSWORD_MIN_SCORE = 4; // So secure, many characters, much complex, wow, etc, etc.
|
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.
|
||||||
|
|
||||||
// XXX: copied from ShareDialog: factor out into utils
|
// XXX: copied from ShareDialog: factor out into utils
|
||||||
function selectText(target) {
|
function selectText(target) {
|
||||||
@ -63,6 +64,13 @@ export default React.createClass({
|
|||||||
componentWillMount: function() {
|
componentWillMount: function() {
|
||||||
this._recoveryKeyNode = null;
|
this._recoveryKeyNode = null;
|
||||||
this._keyBackupInfo = null;
|
this._keyBackupInfo = null;
|
||||||
|
this._setZxcvbnResultTimeout = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
componentWillUnmount: function() {
|
||||||
|
if (this._setZxcvbnResultTimeout !== null) {
|
||||||
|
clearTimeout(this._setZxcvbnResultTimeout);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_collectRecoveryKeyNode: function(n) {
|
_collectRecoveryKeyNode: function(n) {
|
||||||
@ -150,9 +158,23 @@ export default React.createClass({
|
|||||||
this.setState({phase: PHASE_PASSPHRASE_CONFIRM});
|
this.setState({phase: PHASE_PASSPHRASE_CONFIRM});
|
||||||
},
|
},
|
||||||
|
|
||||||
_onPassPhraseKeyPress: function(e) {
|
_onPassPhraseKeyPress: async function(e) {
|
||||||
if (e.key === 'Enter' && this._passPhraseIsValid()) {
|
if (e.key === 'Enter') {
|
||||||
this._onPassPhraseNextClick();
|
// 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
|
||||||
|
// even if the user enetered a valid passphrase
|
||||||
|
if (this._setZxcvbnResultTimeout !== null) {
|
||||||
|
clearTimeout(this._setZxcvbnResultTimeout);
|
||||||
|
this._setZxcvbnResultTimeout = null;
|
||||||
|
await new Promise((resolve) => {
|
||||||
|
this.setState({
|
||||||
|
zxcvbnResult: scorePassword(this.state.passPhrase),
|
||||||
|
}, resolve);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (this._passPhraseIsValid()) {
|
||||||
|
this._onPassPhraseNextClick();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -189,11 +211,20 @@ export default React.createClass({
|
|||||||
_onPassPhraseChange: function(e) {
|
_onPassPhraseChange: function(e) {
|
||||||
this.setState({
|
this.setState({
|
||||||
passPhrase: e.target.value,
|
passPhrase: e.target.value,
|
||||||
// precompute this and keep it in state: zxcvbn is fast but
|
|
||||||
// we use it in a couple of different places so no point recomputing
|
|
||||||
// it unnecessarily.
|
|
||||||
zxcvbnResult: scorePassword(e.target.value),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (this._setZxcvbnResultTimeout !== null) {
|
||||||
|
clearTimeout(this._setZxcvbnResultTimeout);
|
||||||
|
}
|
||||||
|
this._setZxcvbnResultTimeout = setTimeout(() => {
|
||||||
|
this._setZxcvbnResultTimeout = null;
|
||||||
|
this.setState({
|
||||||
|
// precompute this and keep it in state: zxcvbn is fast but
|
||||||
|
// we use it in a couple of different places so no point recomputing
|
||||||
|
// it unnecessarily.
|
||||||
|
zxcvbnResult: scorePassword(this.state.passPhrase),
|
||||||
|
});
|
||||||
|
}, PASSPHRASE_FEEDBACK_DELAY);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onPassPhraseConfirmChange: function(e) {
|
_onPassPhraseConfirmChange: function(e) {
|
||||||
|
Loading…
Reference in New Issue
Block a user