sign-in-credentials.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. import React from 'react';
  2. import Button from 'misago/components/button'; // jshint ignore:line
  3. import Form from 'misago/components/form';
  4. import FormGroup from 'misago/components/form-group'; // jshint ignore:line
  5. import misago from 'misago/index';
  6. import ajax from 'misago/services/ajax';
  7. import title from 'misago/services/page-title';
  8. import snackbar from 'misago/services/snackbar';
  9. import * as validators from 'misago/utils/validators';
  10. export class ChangeEmail extends Form {
  11. constructor(props) {
  12. super(props);
  13. this.state = {
  14. new_email: '',
  15. password: '',
  16. validators: {
  17. new_email: [
  18. validators.email()
  19. ],
  20. password: []
  21. },
  22. isLoading: false
  23. };
  24. }
  25. clean() {
  26. let errors = this.validate();
  27. let lengths = [
  28. this.state.new_email.trim().length,
  29. this.state.password.trim().length
  30. ];
  31. if (lengths.indexOf(0) !== -1) {
  32. snackbar.error(gettext("Fill out all fields."));
  33. return false;
  34. }
  35. if (errors.new_email) {
  36. snackbar.error(errors.new_email[0]);
  37. return false;
  38. }
  39. return true;
  40. }
  41. send() {
  42. return ajax.post(this.props.user.api_url.change_email, {
  43. new_email: this.state.new_email,
  44. password: this.state.password,
  45. });
  46. }
  47. handleSuccess(response) {
  48. this.setState({
  49. new_email: '',
  50. password: ''
  51. });
  52. snackbar.success(response.detail);
  53. }
  54. handleError(rejection) {
  55. if (rejection.status === 400) {
  56. if (rejection.new_email) {
  57. snackbar.error(rejection.new_email);
  58. } else {
  59. snackbar.error(rejection.password);
  60. }
  61. } else {
  62. snackbar.apiError(rejection);
  63. }
  64. }
  65. render() {
  66. /* jshint ignore:start */
  67. return <form onSubmit={this.handleSubmit} className="form-horizontal">
  68. <input type="type" style={{display: 'none'}} />
  69. <input type="password" style={{display: 'none'}} />
  70. <div className="panel panel-default panel-form">
  71. <div className="panel-heading">
  72. <h3 className="panel-title">{gettext("Change e-mail address")}</h3>
  73. </div>
  74. <div className="panel-body">
  75. <FormGroup label={gettext("New e-mail")} for="id_new_email"
  76. labelClass="col-sm-4" controlClass="col-sm-8">
  77. <input type="text" id="id_new_email" className="form-control"
  78. disabled={this.state.isLoading}
  79. onChange={this.bindInput('new_email')}
  80. value={this.state.new_email} />
  81. </FormGroup>
  82. <hr />
  83. <FormGroup label={gettext("Your current password")} for="id_password"
  84. labelClass="col-sm-4" controlClass="col-sm-8">
  85. <input type="password" id="id_password" className="form-control"
  86. disabled={this.state.isLoading}
  87. onChange={this.bindInput('password')}
  88. value={this.state.password} />
  89. </FormGroup>
  90. </div>
  91. <div className="panel-footer">
  92. <div className="row">
  93. <div className="col-sm-8 col-sm-offset-4">
  94. <Button className="btn-primary" loading={this.state.isLoading}>
  95. {gettext("Change e-mail")}
  96. </Button>
  97. </div>
  98. </div>
  99. </div>
  100. </div>
  101. </form>;
  102. /* jshint ignore:end */
  103. }
  104. }
  105. export class ChangePassword extends Form {
  106. constructor(props) {
  107. super(props);
  108. this.state = {
  109. new_password: '',
  110. repeat_password: '',
  111. password: '',
  112. validators: {
  113. new_password: [
  114. validators.passwordMinLength(misago.get('SETTINGS'))
  115. ],
  116. repeat_password: [],
  117. password: []
  118. },
  119. isLoading: false
  120. };
  121. }
  122. clean() {
  123. let errors = this.validate();
  124. let lengths = [
  125. this.state.new_password.trim().length,
  126. this.state.repeat_password.trim().length,
  127. this.state.password.trim().length
  128. ];
  129. if (lengths.indexOf(0) !== -1) {
  130. snackbar.error(gettext("Fill out all fields."));
  131. return false;
  132. }
  133. if (errors.new_password) {
  134. snackbar.error(errors.new_password[0]);
  135. return false;
  136. }
  137. if (this.state.new_password.trim() !== this.state.repeat_password.trim()) {
  138. snackbar.error(gettext("New passwords are different."));
  139. return false;
  140. }
  141. return true;
  142. }
  143. send() {
  144. return ajax.post(this.props.user.api_url.change_password, {
  145. new_password: this.state.new_password,
  146. password: this.state.password
  147. });
  148. }
  149. handleSuccess(response) {
  150. this.setState({
  151. new_password: '',
  152. repeat_password: '',
  153. password: ''
  154. });
  155. snackbar.success(response.detail);
  156. }
  157. handleError(rejection) {
  158. if (rejection.status === 400) {
  159. if (rejection.new_password) {
  160. snackbar.error(rejection.new_password);
  161. } else {
  162. snackbar.error(rejection.password);
  163. }
  164. } else {
  165. snackbar.apiError(rejection);
  166. }
  167. }
  168. render() {
  169. /* jshint ignore:start */
  170. return <form onSubmit={this.handleSubmit} className="form-horizontal">
  171. <input type="type" style={{display: 'none'}} />
  172. <input type="password" style={{display: 'none'}} />
  173. <div className="panel panel-default panel-form">
  174. <div className="panel-heading">
  175. <h3 className="panel-title">{gettext("Change password")}</h3>
  176. </div>
  177. <div className="panel-body">
  178. <FormGroup label={gettext("New password")} for="id_new_password"
  179. labelClass="col-sm-4" controlClass="col-sm-8">
  180. <input type="password" id="id_new_password" className="form-control"
  181. disabled={this.state.isLoading}
  182. onChange={this.bindInput('new_password')}
  183. value={this.state.new_password} />
  184. </FormGroup>
  185. <FormGroup label={gettext("Repeat password")} for="id_repeat_password"
  186. labelClass="col-sm-4" controlClass="col-sm-8">
  187. <input type="password" id="id_repeat_password" className="form-control"
  188. disabled={this.state.isLoading}
  189. onChange={this.bindInput('repeat_password')}
  190. value={this.state.repeat_password} />
  191. </FormGroup>
  192. <hr />
  193. <FormGroup label={gettext("Your current password")} for="id_password"
  194. labelClass="col-sm-4" controlClass="col-sm-8">
  195. <input type="password" id="id_password" className="form-control"
  196. disabled={this.state.isLoading}
  197. onChange={this.bindInput('password')}
  198. value={this.state.password} />
  199. </FormGroup>
  200. </div>
  201. <div className="panel-footer">
  202. <div className="row">
  203. <div className="col-sm-8 col-sm-offset-4">
  204. <Button className="btn-primary" loading={this.state.isLoading}>
  205. {gettext("Change password")}
  206. </Button>
  207. </div>
  208. </div>
  209. </div>
  210. </div>
  211. </form>;
  212. /* jshint ignore:end */
  213. }
  214. }
  215. export default class extends React.Component {
  216. componentDidMount() {
  217. title.set({
  218. title: gettext("Change email or password"),
  219. parent: gettext("Change your options")
  220. });
  221. }
  222. render() {
  223. /* jshint ignore:start */
  224. return <div>
  225. <ChangeEmail user={this.props.user} />
  226. <ChangePassword user={this.props.user} />
  227. <p className="message-line">
  228. <span className="material-icon">
  229. warning
  230. </span>
  231. <a href={misago.get('FORGOTTEN_PASSWORD_URL')}>
  232. {gettext("Change forgotten password")}
  233. </a>
  234. </p>
  235. </div>
  236. /* jshint ignore:end */
  237. }
  238. }