aboutsummaryrefslogtreecommitdiff
path: root/cmd/web
diff options
context:
space:
mode:
authorjloup <jeanloup.jamet@gmail.com>2018-05-04 11:55:15 +0200
committerjloup <jeanloup.jamet@gmail.com>2018-05-04 11:55:15 +0200
commit85545aba62546f219a9c9730945511412a3174ef (patch)
tree7bf7feb99c6e7e51e83c386aafb3da3b7610d6bd /cmd/web
parentb94f3416c1afe6363249b46bf2b299dfe8e4007f (diff)
downloadFront-85545aba62546f219a9c9730945511412a3174ef.tar.gz
Front-85545aba62546f219a9c9730945511412a3174ef.tar.zst
Front-85545aba62546f219a9c9730945511412a3174ef.zip
Password reset.
Diffstat (limited to 'cmd/web')
-rw-r--r--cmd/web/Makefile2
-rw-r--r--cmd/web/js/api.js21
-rw-r--r--cmd/web/js/change_password.jsx62
-rw-r--r--cmd/web/js/main.jsx34
-rw-r--r--cmd/web/js/password_reset.jsx57
-rw-r--r--cmd/web/package.json1
-rw-r--r--cmd/web/yarn.lock4
7 files changed, 180 insertions, 1 deletions
diff --git a/cmd/web/Makefile b/cmd/web/Makefile
index c6bc2bd..c5d5d62 100644
--- a/cmd/web/Makefile
+++ b/cmd/web/Makefile
@@ -4,7 +4,7 @@ export PATH := $(PATH):./node_modules/.bin
4 4
5SRC_DIR=js 5SRC_DIR=js
6BUILD_DIR=build/js 6BUILD_DIR=build/js
7JSX_SRC= main.jsx signup.jsx signin.jsx otp.jsx poloniex.jsx 7JSX_SRC= main.jsx signup.jsx signin.jsx otp.jsx poloniex.jsx password_reset.jsx change_password.jsx
8JS_SRC= cookies.js app.js api.js 8JS_SRC= cookies.js app.js api.js
9STATIC_FILES= index.html style.css 9STATIC_FILES= index.html style.css
10JSX_OBJS=$(addprefix $(BUILD_DIR)/,$(JSX_SRC:.jsx=.js)) 10JSX_OBJS=$(addprefix $(BUILD_DIR)/,$(JSX_SRC:.jsx=.js))
diff --git a/cmd/web/js/api.js b/cmd/web/js/api.js
index 5cbf5eb..c9b4ef5 100644
--- a/cmd/web/js/api.js
+++ b/cmd/web/js/api.js
@@ -43,6 +43,27 @@ var ApiEndpoints = {
43 return '/signin'; 43 return '/signin';
44 } 44 }
45 }, 45 },
46 'RESET_PASSWORD': {
47 'type': 'POST',
48 'auth': false,
49 'parameters': [
50 {'name': 'email', 'mandatory': true, 'inquery': true},
51 ],
52 'buildUrl': function() {
53 return '/passwordreset';
54 }
55 },
56 'CHANGE_PASSWORD': {
57 'type': 'POST',
58 'auth': false,
59 'parameters': [
60 {'name': 'token', 'mandatory': true, 'inquery': true},
61 {'name': 'password', 'mandatory': true, 'inquery': true},
62 ],
63 'buildUrl': function() {
64 return '/changepassword';
65 }
66 },
46 'MARKET': { 67 'MARKET': {
47 'type': 'GET', 68 'type': 'GET',
48 'auth': true, 69 'auth': true,
diff --git a/cmd/web/js/change_password.jsx b/cmd/web/js/change_password.jsx
new file mode 100644
index 0000000..aedf4af
--- /dev/null
+++ b/cmd/web/js/change_password.jsx
@@ -0,0 +1,62 @@
1import Api from './api.js';
2import App from './app.js';
3import classNames from 'classnames';
4import React from 'react';
5
6class ChangePasswordForm extends React.Component {
7 constructor(props) {
8 super(props);
9 this.state = {'hideMsg': true, 'msg': '', 'msgOk': false, 'password': ''};
10 }
11
12 handleSubmit = (e) => {
13 Api.Call(
14 'CHANGE_PASSWORD',
15 {
16 'password': this.state.password,
17 'token': this.props.token
18 },
19 function(err, status, data) {
20 if (err) {
21 console.error(err, data);
22 this.displayMessage(App.errorCodeToMessage(err.code), false);
23 return;
24 }
25
26 this.displayMessage('You password has been reset.', true);
27 this.props.onSuccess();
28
29 }.bind(this)
30);
31 e.preventDefault();
32 }
33
34 handlePasswordChange = (event) => {
35 this.setState({'password': event.target.value});
36 }
37
38 hideMessage = () => {
39 this.setState({'hideMsg': true});
40 }
41
42 displayMessage = (msg, ok) => {
43 this.setState({'msg': msg, 'msgOk': ok, 'hideMsg': false});
44 }
45
46 render = () => {
47 var cName = classNames('form-message', {'hidden': this.state.hideMsg, 'message-ok': this.state.msgOk});
48 return (
49 <div className="row sign-in">
50 <div className="offset-4 col-4 col-xs-offset-1 col-xs-10 text-center">
51 <form role="form" onSubmit={this.handleSubmit}>
52 <input className="form-control" type="password" placeholder="password" onChange={this.handlePasswordChange} />
53 <input className="form-control submit" type="submit" value="Change password" />
54 <div className={cName}>{this.state.msg}</div>
55 </form>
56 </div>
57 </div>
58 );
59 }
60}
61
62export default ChangePasswordForm;
diff --git a/cmd/web/js/main.jsx b/cmd/web/js/main.jsx
index e64adc7..909f1bd 100644
--- a/cmd/web/js/main.jsx
+++ b/cmd/web/js/main.jsx
@@ -1,11 +1,14 @@
1import SignupForm from './signup.js'; 1import SignupForm from './signup.js';
2import SigninForm from './signin.js'; 2import SigninForm from './signin.js';
3import PasswordResetForm from './password_reset.js';
4import ChangePasswordForm from './change_password.js';
3import OtpEnrollForm from './otp.js'; 5import OtpEnrollForm from './otp.js';
4import PoloniexController from './poloniex.js'; 6import PoloniexController from './poloniex.js';
5import App from './app.js'; 7import App from './app.js';
6import Api from './api.js'; 8import Api from './api.js';
7import cookies from './cookies.js'; 9import cookies from './cookies.js';
8import React from 'react'; 10import React from 'react';
11import qs from 'qs';
9 12
10class Header extends React.Component { 13class Header extends React.Component {
11 render = () => { 14 render = () => {
@@ -60,6 +63,37 @@ App.page('/signin', false, function(context) {
60 </div>); 63 </div>);
61}); 64});
62 65
66App.page('/reset-password', false, function(context) {
67 if (App.isUserSignedIn()) {
68 App.go('/me');
69 return;
70 }
71
72 App.mount(<div>
73 <Header />
74 <PasswordResetForm />
75 </div>);
76});
77
78App.page('/change-password', false, function(context) {
79 if (App.isUserSignedIn()) {
80 App.go('/me');
81 return;
82 }
83
84 var token = qs.parse(context.querystring).token;
85
86 if (token === undefined) {
87 App.go('/');
88 return;
89 }
90
91 App.mount(<div>
92 <Header />
93 <ChangePasswordForm token={token} onSuccess={App.go.bind(App, '/signin')}/>
94 </div>);
95});
96
63App.page('/signout', true, function(context) { 97App.page('/signout', true, function(context) {
64 cookies.removeItem('jwt'); 98 cookies.removeItem('jwt');
65 99
diff --git a/cmd/web/js/password_reset.jsx b/cmd/web/js/password_reset.jsx
new file mode 100644
index 0000000..8cbdc60
--- /dev/null
+++ b/cmd/web/js/password_reset.jsx
@@ -0,0 +1,57 @@
1import Api from './api.js';
2import App from './app.js';
3import classNames from 'classnames';
4import React from 'react';
5
6class PasswordResetForm extends React.Component {
7 constructor(props) {
8 super(props);
9 this.state = {'hideMsg': true, 'msg': '', 'msgOk': false, 'email': ''};
10 }
11
12 handleSubmit = (e) => {
13 Api.Call('RESET_PASSWORD', {'email': this.state.email}, function(err, status, data) {
14 if (err) {
15 console.error(err, data);
16 this.displayMessage(App.errorCodeToMessage(err.code), false);
17 return;
18 }
19
20 this.displayMessage('You will receive a reset link to reset your password.', true);
21 if (this.props.onSuccess) {
22 this.props.onSuccess();
23 }
24
25 }.bind(this));
26 e.preventDefault();
27 }
28
29 handleEmailChange = (event) => {
30 this.setState({'email': event.target.value});
31 }
32
33 hideMessage = () => {
34 this.setState({'hideMsg': true});
35 }
36
37 displayMessage = (msg, ok) => {
38 this.setState({'msg': msg, 'msgOk': ok, 'hideMsg': false});
39 }
40
41 render = () => {
42 var cName = classNames('form-message', {'hidden': this.state.hideMsg, 'message-ok': this.state.msgOk});
43 return (
44 <div className="row sign-in">
45 <div className="offset-4 col-4 col-xs-offset-1 col-xs-10 text-center">
46 <form role="form" onSubmit={this.handleSubmit}>
47 <input className="form-control" type="email" placeholder="email" onChange={this.handleEmailChange} />
48 <input className="form-control submit" type="submit" value="Reset" />
49 <div className={cName}>{this.state.msg}</div>
50 </form>
51 </div>
52 </div>
53 );
54 }
55}
56
57export default PasswordResetForm; \ No newline at end of file
diff --git a/cmd/web/package.json b/cmd/web/package.json
index c9241f1..a867313 100644
--- a/cmd/web/package.json
+++ b/cmd/web/package.json
@@ -14,6 +14,7 @@
14 "localenvify": "^1.0.1", 14 "localenvify": "^1.0.1",
15 "page": "^1.8.3", 15 "page": "^1.8.3",
16 "path-to-regexp": "^1.2.1", 16 "path-to-regexp": "^1.2.1",
17 "qs": "^6.5.1",
17 "react": "^16.2.0" 18 "react": "^16.2.0"
18 }, 19 },
19 "devDependencies": { 20 "devDependencies": {
diff --git a/cmd/web/yarn.lock b/cmd/web/yarn.lock
index 0d162a9..b2218ee 100644
--- a/cmd/web/yarn.lock
+++ b/cmd/web/yarn.lock
@@ -3536,6 +3536,10 @@ q@~1.0.0, q@~1.0.1:
3536 version "1.0.1" 3536 version "1.0.1"
3537 resolved "https://registry.yarnpkg.com/q/-/q-1.0.1.tgz#11872aeedee89268110b10a718448ffb10112a14" 3537 resolved "https://registry.yarnpkg.com/q/-/q-1.0.1.tgz#11872aeedee89268110b10a718448ffb10112a14"
3538 3538
3539qs@^6.5.1:
3540 version "6.5.1"
3541 resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
3542
3539qs@~1.2.0: 3543qs@~1.2.0:
3540 version "1.2.2" 3544 version "1.2.2"
3541 resolved "https://registry.yarnpkg.com/qs/-/qs-1.2.2.tgz#19b57ff24dc2a99ce1f8bdf6afcda59f8ef61f88" 3545 resolved "https://registry.yarnpkg.com/qs/-/qs-1.2.2.tgz#19b57ff24dc2a99ce1f8bdf6afcda59f8ef61f88"