mirror of
https://github.com/element-hq/element-web
synced 2024-11-28 04:21:57 +03:00
Merge pull request #1982 from matrix-org/t3chguy/nvl/fix_set_password-email_flow
fix set password & email flow possible to get stuck and onBlur murdering your email
This commit is contained in:
commit
a0207fb7fd
6 changed files with 38 additions and 44 deletions
|
@ -429,7 +429,6 @@ module.exports = React.createClass({
|
||||||
"push notifications on other devices until you log back in to them",
|
"push notifications on other devices until you log back in to them",
|
||||||
) + ".",
|
) + ".",
|
||||||
});
|
});
|
||||||
dis.dispatch({action: 'password_changed'});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onAddEmailEditFinished: function(value, shouldSubmit) {
|
_onAddEmailEditFinished: function(value, shouldSubmit) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2017 Vector Creations Ltd
|
Copyright 2017 Vector Creations Ltd
|
||||||
|
Copyright 2018 New Vector Ltd
|
||||||
|
|
||||||
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.
|
||||||
|
@ -36,7 +37,7 @@ export default React.createClass({
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
emailAddress: null,
|
emailAddress: '',
|
||||||
emailBusy: false,
|
emailBusy: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -127,6 +128,7 @@ export default React.createClass({
|
||||||
const EditableText = sdk.getComponent('elements.EditableText');
|
const EditableText = sdk.getComponent('elements.EditableText');
|
||||||
|
|
||||||
const emailInput = this.state.emailBusy ? <Spinner /> : <EditableText
|
const emailInput = this.state.emailBusy ? <Spinner /> : <EditableText
|
||||||
|
initialValue={this.state.emailAddress}
|
||||||
className="mx_SetEmailDialog_email_input"
|
className="mx_SetEmailDialog_email_input"
|
||||||
autoFocus="true"
|
autoFocus="true"
|
||||||
placeholder={_t("Email address")}
|
placeholder={_t("Email address")}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2017 Vector Creations Ltd
|
Copyright 2017 Vector Creations Ltd
|
||||||
|
Copyright 2018 New Vector Ltd
|
||||||
|
|
||||||
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.
|
||||||
|
@ -79,15 +80,11 @@ export default React.createClass({
|
||||||
Modal.createDialog(WarmFuzzy, {
|
Modal.createDialog(WarmFuzzy, {
|
||||||
didSetEmail: res.didSetEmail,
|
didSetEmail: res.didSetEmail,
|
||||||
onFinished: () => {
|
onFinished: () => {
|
||||||
this._onContinueClicked();
|
this.props.onFinished();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_onContinueClicked: function() {
|
|
||||||
this.props.onFinished(true);
|
|
||||||
},
|
|
||||||
|
|
||||||
_onPasswordChangeError: function(err) {
|
_onPasswordChangeError: function(err) {
|
||||||
let errMsg = err.error || "";
|
let errMsg = err.error || "";
|
||||||
if (err.httpStatus === 403) {
|
if (err.httpStatus === 403) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
Copyright 2018 New Vector Ltd
|
||||||
|
|
||||||
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.
|
||||||
|
@ -14,15 +15,9 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
import React from 'react';
|
||||||
|
|
||||||
const React = require('react');
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
const KEY_TAB = 9;
|
|
||||||
const KEY_SHIFT = 16;
|
|
||||||
const KEY_WINDOWS = 91;
|
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'EditableText',
|
displayName: 'EditableText',
|
||||||
|
|
||||||
|
@ -66,9 +61,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillReceiveProps: function(nextProps) {
|
componentWillReceiveProps: function(nextProps) {
|
||||||
if (nextProps.initialValue !== this.props.initialValue ||
|
if (nextProps.initialValue !== this.props.initialValue || nextProps.initialValue !== this.value) {
|
||||||
nextProps.initialValue !== this.value
|
|
||||||
) {
|
|
||||||
this.value = nextProps.initialValue;
|
this.value = nextProps.initialValue;
|
||||||
if (this.refs.editable_div) {
|
if (this.refs.editable_div) {
|
||||||
this.showPlaceholder(!this.value);
|
this.showPlaceholder(!this.value);
|
||||||
|
@ -139,7 +132,7 @@ module.exports = React.createClass({
|
||||||
this.showPlaceholder(false);
|
this.showPlaceholder(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ev.key == "Enter") {
|
if (ev.key === "Enter") {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
}
|
}
|
||||||
|
@ -156,9 +149,9 @@ module.exports = React.createClass({
|
||||||
this.value = ev.target.textContent;
|
this.value = ev.target.textContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ev.key == "Enter") {
|
if (ev.key === "Enter") {
|
||||||
this.onFinish(ev);
|
this.onFinish(ev);
|
||||||
} else if (ev.key == "Escape") {
|
} else if (ev.key === "Escape") {
|
||||||
this.cancelEdit();
|
this.cancelEdit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +186,7 @@ module.exports = React.createClass({
|
||||||
const submit = (ev.key === "Enter") || shouldSubmit;
|
const submit = (ev.key === "Enter") || shouldSubmit;
|
||||||
this.setState({
|
this.setState({
|
||||||
phase: this.Phases.Display,
|
phase: this.Phases.Display,
|
||||||
}, function() {
|
}, () => {
|
||||||
if (this.value !== this.props.initialValue) {
|
if (this.value !== this.props.initialValue) {
|
||||||
self.onValueChanged(submit);
|
self.onValueChanged(submit);
|
||||||
}
|
}
|
||||||
|
@ -204,23 +197,35 @@ module.exports = React.createClass({
|
||||||
const sel = window.getSelection();
|
const sel = window.getSelection();
|
||||||
sel.removeAllRanges();
|
sel.removeAllRanges();
|
||||||
|
|
||||||
if (this.props.blurToCancel) {this.cancelEdit();} else {this.onFinish(ev, this.props.blurToSubmit);}
|
if (this.props.blurToCancel) {
|
||||||
|
this.cancelEdit();
|
||||||
|
} else {
|
||||||
|
this.onFinish(ev, this.props.blurToSubmit);
|
||||||
|
}
|
||||||
|
|
||||||
this.showPlaceholder(!this.value);
|
this.showPlaceholder(!this.value);
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
let editable_el;
|
const {className, editable, initialValue, label, labelClassName} = this.props;
|
||||||
|
let editableEl;
|
||||||
|
|
||||||
if (!this.props.editable || (this.state.phase == this.Phases.Display && (this.props.label || this.props.labelClassName) && !this.value)) {
|
if (!editable || (this.state.phase === this.Phases.Display && (label || labelClassName) && !this.value)) {
|
||||||
// show the label
|
// show the label
|
||||||
editable_el = <div className={this.props.className + " " + this.props.labelClassName} onClick={this.onClickDiv}>{ this.props.label || this.props.initialValue }</div>;
|
editableEl = <div className={className + " " + labelClassName} onClick={this.onClickDiv}>
|
||||||
|
{ label || initialValue }
|
||||||
|
</div>;
|
||||||
} else {
|
} else {
|
||||||
// show the content editable div, but manually manage its contents as react and contentEditable don't play nice together
|
// show the content editable div, but manually manage its contents as react and contentEditable don't play nice together
|
||||||
editable_el = <div ref="editable_div" contentEditable="true" className={this.props.className}
|
editableEl = <div ref="editable_div"
|
||||||
onKeyDown={this.onKeyDown} onKeyUp={this.onKeyUp} onFocus={this.onFocus} onBlur={this.onBlur}></div>;
|
contentEditable={true}
|
||||||
|
className={className}
|
||||||
|
onKeyDown={this.onKeyDown}
|
||||||
|
onKeyUp={this.onKeyUp}
|
||||||
|
onFocus={this.onFocus}
|
||||||
|
onBlur={this.onBlur} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return editable_el;
|
return editableEl;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2017 Vector Creations Ltd
|
Copyright 2017 Vector Creations Ltd
|
||||||
|
Copyright 2018 New Vector Ltd
|
||||||
|
|
||||||
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.
|
||||||
|
@ -14,28 +15,15 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import sdk from '../../../index';
|
import sdk from '../../../index';
|
||||||
import Modal from '../../../Modal';
|
import Modal from '../../../Modal';
|
||||||
import dis from '../../../dispatcher';
|
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
|
|
||||||
export default React.createClass({
|
export default React.createClass({
|
||||||
onUpdateClicked: function() {
|
onUpdateClicked: function() {
|
||||||
const SetPasswordDialog = sdk.getComponent('dialogs.SetPasswordDialog');
|
const SetPasswordDialog = sdk.getComponent('dialogs.SetPasswordDialog');
|
||||||
Modal.createTrackedDialog('Set Password Dialog', 'Password Nag Bar', SetPasswordDialog, {
|
Modal.createTrackedDialog('Set Password Dialog', 'Password Nag Bar', SetPasswordDialog);
|
||||||
onFinished: (passwordChanged) => {
|
|
||||||
if (!passwordChanged) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Notify SessionStore that the user's password was changed
|
|
||||||
dis.dispatch({
|
|
||||||
action: 'password_changed',
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
Copyright 2018 New Vector Ltd
|
||||||
|
|
||||||
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.
|
||||||
|
@ -14,14 +15,13 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
const MatrixClientPeg = require("../../../MatrixClientPeg");
|
const MatrixClientPeg = require("../../../MatrixClientPeg");
|
||||||
const Modal = require("../../../Modal");
|
const Modal = require("../../../Modal");
|
||||||
const sdk = require("../../../index");
|
const sdk = require("../../../index");
|
||||||
|
|
||||||
|
import dis from "../../../dispatcher";
|
||||||
import Promise from 'bluebird';
|
import Promise from 'bluebird';
|
||||||
import AccessibleButton from '../elements/AccessibleButton';
|
import AccessibleButton from '../elements/AccessibleButton';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
|
@ -143,6 +143,9 @@ module.exports = React.createClass({
|
||||||
});
|
});
|
||||||
|
|
||||||
cli.setPassword(authDict, newPassword).then(() => {
|
cli.setPassword(authDict, newPassword).then(() => {
|
||||||
|
// Notify SessionStore that the user's password was changed
|
||||||
|
dis.dispatch({action: 'password_changed'});
|
||||||
|
|
||||||
if (this.props.shouldAskForEmail) {
|
if (this.props.shouldAskForEmail) {
|
||||||
return this._optionallySetEmail().then((confirmed) => {
|
return this._optionallySetEmail().then((confirmed) => {
|
||||||
this.props.onFinished({
|
this.props.onFinished({
|
||||||
|
|
Loading…
Reference in a new issue