<td>id=change-password</td>
<td></td>
</tr>
-<tr>
- <td>click</td>
- <td>id=change-password</td>
- <td></td>
-</tr>
-<tr>
- <td>waitForElementPresent</td>
- <td>id=old_password</td>
- <td></td>
-</tr>
<tr>
<td>type</td>
<td>id=old_password</td>
</tr>
<tr>
<td>click</td>
- <td>commit</td>
+ <td>id=change-password</td>
+ <td></td>
+</tr>
+<tr>
+ <td>waitForElementPresent</td>
+ <td>css=.alert-success</td>
<td></td>
</tr>
<tr>
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import $ from 'jquery';
+import { post, postJSON } from '../helpers/request.js';
export function getCurrentUser () {
const url = baseUrl + '/api/users/current';
return $.get(url);
}
+
+export function changePassword (login, password, previousPassword) {
+ const url = window.baseUrl + '/api/users/change_password';
+ const data = { login, password };
+
+ if (previousPassword != null) {
+ data.previousPassword = previousPassword;
+ }
+
+ return post(url, data);
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import $ from 'jquery';
-import ModalForm from '../../components/common/modal-form';
-import Template from './templates/account-change-password.hbs';
-import { translate } from '../../helpers/l10n';
-
-export default ModalForm.extend({
- template: Template,
-
- onFormSubmit: function () {
- ModalForm.prototype.onFormSubmit.apply(this, arguments);
- if (this.checkPasswords()) {
- this.sendRequest();
- } else {
- this.showErrors([{ msg: translate('user.password_doesnt_match_confirmation') }]);
- }
- },
-
- checkPasswords: function () {
- var p1 = this.$('#password').val(),
- p2 = this.$('#password_confirmation').val();
- return p1 === p2;
- },
-
- sendRequest: function () {
- var that = this;
- var data = {
- login: window.SS.user,
- password: this.$('#password').val(),
- previousPassword: this.$('#old_password').val()
- };
- var opts = {
- type: 'POST',
- url: baseUrl + '/api/users/change_password',
- data: data,
- statusCode: {
- // do not show global error
- 400: null
- }
- };
- this.disableForm();
- $.ajax(opts).done(function () {
- that.destroy();
- }).fail(function (jqXHR) {
- that.enableForm();
- that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings);
- });
- }
-});
*/
import React, { Component } from 'react';
-import ChangePasswordView from '../change-password-view';
+import { changePassword } from '../../../api/users';
+import { translate } from '../../../helpers/l10n';
export default class Password extends Component {
- handleChangePassword () {
- new ChangePasswordView().render();
+ state = {
+ success: false,
+ errors: null
+ }
+
+ handleSuccessfulChange () {
+ this.refs.oldPassword.value = '';
+ this.refs.password.value = '';
+ this.refs.passwordConfirmation.value = '';
+ this.setState({ success: true, errors: null });
+ }
+
+ handleFailedChange (e) {
+ e.response.json().then(r => {
+ this.refs.oldPassword.focus();
+ this.setErrors(r.errors.map(e => e.msg));
+ });
+ }
+
+ setErrors (errors) {
+ this.setState({
+ success: false,
+ errors
+ });
+ }
+
+ handleChangePassword (e) {
+ e.preventDefault();
+
+ const { user } = this.props;
+ const oldPassword = this.refs.oldPassword.value;
+ const password = this.refs.password.value;
+ const passwordConfirmation = this.refs.passwordConfirmation.value;
+
+ if (password !== passwordConfirmation) {
+ this.refs.password.focus();
+ this.setErrors([translate('user.password_doesnt_match_confirmation')]);
+ } else {
+ changePassword(user.login, password, oldPassword)
+ .then(this.handleSuccessfulChange.bind(this))
+ .catch(this.handleFailedChange.bind(this));
+ }
}
render () {
+ const { success, errors } = this.state;
+
return (
<section>
- <h2 className="spacer-bottom">Password</h2>
- <button
- id="change-password"
- onClick={this.handleChangePassword.bind(this)}
- type="submit">
- Change Password
- </button>
+ <h2 className="spacer-bottom">
+ {translate('my_profile.password.title')}
+ </h2>
+
+ <form onSubmit={this.handleChangePassword.bind(this)}>
+ {success && (
+ <div className="alert alert-success">
+ {translate('my_profile.password.changed')}
+ </div>
+ )}
+
+ {errors && errors.map((e, i) => (
+ <div key={i} className="alert alert-danger">{e}</div>
+ ))}
+
+ <div className="modal-field">
+ <label htmlFor="old_password">
+ {translate('my_profile.password.old')}
+ <em className="mandatory">*</em>
+ </label>
+ <input
+ ref="oldPassword"
+ autoComplete="off"
+ id="old_password"
+ name="old_password"
+ required={true}
+ type="password"/>
+ </div>
+ <div className="modal-field">
+ <label htmlFor="password">
+ {translate('my_profile.password.new')}
+ <em className="mandatory">*</em>
+ </label>
+ <input
+ ref="password"
+ autoComplete="off"
+ id="password"
+ name="password"
+ required={true}
+ type="password"/>
+ </div>
+ <div className="modal-field">
+ <label htmlFor="password_confirmation">
+ {translate('my_profile.password.confirm')}
+ <em className="mandatory">*</em>
+ </label>
+ <input
+ ref="passwordConfirmation"
+ autoComplete="off"
+ id="password_confirmation"
+ name="password_confirmation"
+ required={true}
+ type="password"/>
+ </div>
+ <div className="modal-field">
+ <button id="change-password" type="submit">
+ {translate('my_profile.password.submit')}
+ </button>
+ </div>
+ </form>
</section>
);
}
{user.canChangePassword && (
<div className="column-half">
- <Password/>
+ <Password user={user}/>
</div>
)}
</div>
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import React from 'react';
+import { connect } from 'react-redux';
import Security from './../components/Security';
-export default function SecurityContainer () {
- const { user } = window.sonarqube;
-
- return <Security user={user}/>;
+function mapStateToProps (state) {
+ return {
+ user: state.user
+ };
}
+
+export default connect(mapStateToProps)(Security);
}
export const initialState = {
+ user: window.sonarqube.user,
projectNotifications: window.sonarqube.notifications.project
};
+++ /dev/null
-<form id="pass_form_tag" name="pass_form_tag">
- <div class="modal-head">
- <h2>{{t 'my_profile.password.title'}}</h2>
- </div>
-
- <div class="modal-body">
- <div class="js-modal-messages"></div>
- <div class="modal-field">
- <label for="old_password">{{t 'my_profile.password.old'}}<em class="mandatory">*</em></label>
- <input autocomplete="off" id="old_password" name="old_password" required type="password">
- </div>
- <div class="modal-field">
- <label for="password">{{t 'my_profile.password.new'}}<em class="mandatory">*</em></label>
- <input autocomplete="off" id="password" name="password" required type="password">
- </div>
- <div class="modal-field">
- <label for="password_confirmation">{{t 'my_profile.password.confirm'}}<em class="mandatory">*</em></label>
- <input autocomplete="off" id="password_confirmation" name="password_confirmation" required type="password">
- </div>
- </div>
-
- <div class="modal-foot">
- <input name="commit" type="submit" value="{{t 'my_profile.password.submit'}}">
- <a class="js-modal-close" href="#">{{t 'cancel'}}</a>
- </div>
-</form>
my_profile.groups=Groups
my_profile.scm_accounts=SCM Accounts
my_profile.password.title=Change password
-my_profile.password.old=Old value
-my_profile.password.new=New value
-my_profile.password.confirm=Confirm new value
+my_profile.password.old=Old Password
+my_profile.password.new=New Password
+my_profile.password.confirm=Confirm Password
my_profile.password.submit=Change password
-my_profile.password.changed=Password changed
+my_profile.password.changed=The password has been changed!
my_profile.password.empty=Password can not be empty
my_profile.password.wrong_old=Wrong old password
my_profile.notifications.submit=Save changes