Bring in the change password section

This also changes the layout slightly in the user settings, but nothing detrimental.
This commit is contained in:
Travis Ralston 2019-01-22 13:09:40 -07:00
parent 677b3ca7b5
commit 19de6694ca
7 changed files with 94 additions and 36 deletions

View file

@ -116,9 +116,8 @@ export default React.createClass({
<ChangePassword
className="mx_SetPasswordDialog_change_password"
rowClassName=""
rowLabelClassName=""
rowInputClassName=""
buttonClassName="mx_Dialog_primary mx_SetPasswordDialog_change_password_button"
buttonClassNames="mx_Dialog_primary mx_SetPasswordDialog_change_password_button"
buttonKind="primary"
confirm={false}
autoFocusNewPasswordInput={true}
shouldAskForEmail={true}

View file

@ -31,6 +31,11 @@ export default class Field extends React.PureComponent {
// To define options for a select, use <Field><option ... /></Field>
element: PropTypes.string,
// All other props pass through to the <input>.
};
get value() {
if (!this.refs.fieldInput) return null;
return this.refs.fieldInput.value;
}
render() {

View file

@ -15,6 +15,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import Field from "../elements/Field";
const React = require('react');
import PropTypes from 'prop-types';
const MatrixClientPeg = require("../../../MatrixClientPeg");
@ -35,9 +37,8 @@ module.exports = React.createClass({
onError: PropTypes.func,
onCheckPassword: PropTypes.func,
rowClassName: PropTypes.string,
rowLabelClassName: PropTypes.string,
rowInputClassName: PropTypes.string,
buttonClassName: PropTypes.string,
buttonKind: PropTypes.string,
confirm: PropTypes.bool,
// Whether to autoFocus the new password input
autoFocusNewPasswordInput: PropTypes.bool,
@ -203,21 +204,18 @@ module.exports = React.createClass({
},
render: function() {
// TODO: Live validation on `new pw == confirm pw`
const rowClassName = this.props.rowClassName;
const rowLabelClassName = this.props.rowLabelClassName;
const rowInputClassName = this.props.rowInputClassName;
const buttonClassName = this.props.buttonClassName;
let currentPassword = null;
if (!this.state.cachedPassword) {
currentPassword = <div className={rowClassName}>
<div className={rowLabelClassName}>
<label htmlFor="passwordold">{ _t('Current password') }</label>
currentPassword = (
<div className={rowClassName}>
<Field id="passwordold" type="password" ref="old_input" label={_t('Current password')} />
</div>
<div className={rowInputClassName}>
<input id="passwordold" type="password" ref="old_input" />
</div>
</div>;
);
}
switch (this.state.phase) {
@ -228,24 +226,13 @@ module.exports = React.createClass({
<form className={this.props.className} onSubmit={this.onClickChange}>
{ currentPassword }
<div className={rowClassName}>
<div className={rowLabelClassName}>
<label htmlFor="password1">{ passwordLabel }</label>
</div>
<div className={rowInputClassName}>
<input id="password1" type="password" ref="new_input" autoFocus={this.props.autoFocusNewPasswordInput} />
</div>
<Field id="password1" type="password" ref="new_input" label={passwordLabel}
autoFocus={this.props.autoFocusNewPasswordInput} />
</div>
<div className={rowClassName}>
<div className={rowLabelClassName}>
<label htmlFor="password2">{ _t('Confirm password') }</label>
</div>
<div className={rowInputClassName}>
<input id="password2" type="password" ref="confirm_input" />
</div>
<Field id="password2" type="password" ref="confirm_input" label={_t("Confirm password")} />
</div>
<AccessibleButton className={buttonClassName}
onClick={this.onClickChange}
element="button">
<AccessibleButton className={buttonClassName} kind={this.props.buttonKind} onClick={this.onClickChange}>
{ _t('Change Password') }
</AccessibleButton>
</form>

View file

@ -24,6 +24,8 @@ import GroupUserSettings from "../../groups/GroupUserSettings";
import PropTypes from "prop-types";
import {MatrixClient} from "matrix-js-sdk";
import { DragDropContext } from 'react-beautiful-dnd';
const sdk = require('../../../../index');
const Modal = require("../../../../Modal");
export default class GeneralSettingsTab extends React.Component {
static childContextTypes = {
@ -90,6 +92,13 @@ export default class GeneralSettingsTab extends React.Component {
this.setState(newState);
};
_changePassword = async (e) => {
e.stopPropagation();
e.preventDefault();
console.log(this.refs.currentPassword);
};
_onDisplayNameChanged = (e) => {
this.setState({
displayName: e.target.value,
@ -119,6 +128,34 @@ export default class GeneralSettingsTab extends React.Component {
reader.readAsDataURL(file);
};
_onPasswordChangeError = (err) => {
// TODO: Figure out a design that doesn't involve replacing the current dialog
let errMsg = err.error || "";
if (err.httpStatus === 403) {
errMsg = _t("Failed to change password. Is your password correct?");
} else if (err.httpStatus) {
errMsg += ` (HTTP status ${err.httpStatus})`;
}
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
console.error("Failed to change password: " + errMsg);
Modal.createTrackedDialog('Failed to change password', '', ErrorDialog, {
title: _t("Error"),
description: errMsg,
});
};
_onPasswordChanged = () => {
// TODO: Figure out a design that doesn't involve replacing the current dialog
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog('Password changed', '', ErrorDialog, {
title: _t("Success"),
description: _t(
"Your password was successfully changed. You will not receive " +
"push notifications on other devices until you log back in to them",
) + ".",
});
};
_renderProfileSection() {
// TODO: Why is rendering a box with an overlay so complicated? Can the DOM be reduced?
@ -181,10 +218,23 @@ export default class GeneralSettingsTab extends React.Component {
}
_renderAccountSection() {
const ChangePassword = sdk.getComponent("views.settings.ChangePassword");
const passwordChangeForm = (
<ChangePassword
className="mx_GeneralSettingsTab_changePassword"
rowClassName=""
buttonKind="primary"
onError={this._onPasswordChangeError}
onFinished={this._onPasswordChanged} />
);
return (
<div className="mx_SettingsTab_section">
<span className="mx_SettingsTab_subheading">{_t("Account")}</span>
<p>ACCOUNT SECTION</p>
<p className="mx_SettingsTab_subsectionText">
{_t("Set a new account password...")}
</p>
{passwordChangeForm}
</div>
);
}