From 85545aba62546f219a9c9730945511412a3174ef Mon Sep 17 00:00:00 2001 From: jloup Date: Fri, 4 May 2018 11:55:15 +0200 Subject: Password reset. --- cmd/web/Makefile | 2 +- cmd/web/js/api.js | 21 ++++++++++++++ cmd/web/js/change_password.jsx | 62 ++++++++++++++++++++++++++++++++++++++++++ cmd/web/js/main.jsx | 34 +++++++++++++++++++++++ cmd/web/js/password_reset.jsx | 57 ++++++++++++++++++++++++++++++++++++++ cmd/web/package.json | 1 + cmd/web/yarn.lock | 4 +++ 7 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 cmd/web/js/change_password.jsx create mode 100644 cmd/web/js/password_reset.jsx (limited to 'cmd/web') 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 SRC_DIR=js BUILD_DIR=build/js -JSX_SRC= main.jsx signup.jsx signin.jsx otp.jsx poloniex.jsx +JSX_SRC= main.jsx signup.jsx signin.jsx otp.jsx poloniex.jsx password_reset.jsx change_password.jsx JS_SRC= cookies.js app.js api.js STATIC_FILES= index.html style.css JSX_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 = { return '/signin'; } }, + 'RESET_PASSWORD': { + 'type': 'POST', + 'auth': false, + 'parameters': [ + {'name': 'email', 'mandatory': true, 'inquery': true}, + ], + 'buildUrl': function() { + return '/passwordreset'; + } + }, + 'CHANGE_PASSWORD': { + 'type': 'POST', + 'auth': false, + 'parameters': [ + {'name': 'token', 'mandatory': true, 'inquery': true}, + {'name': 'password', 'mandatory': true, 'inquery': true}, + ], + 'buildUrl': function() { + return '/changepassword'; + } + }, 'MARKET': { 'type': 'GET', '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 @@ +import Api from './api.js'; +import App from './app.js'; +import classNames from 'classnames'; +import React from 'react'; + +class ChangePasswordForm extends React.Component { + constructor(props) { + super(props); + this.state = {'hideMsg': true, 'msg': '', 'msgOk': false, 'password': ''}; + } + + handleSubmit = (e) => { + Api.Call( + 'CHANGE_PASSWORD', + { + 'password': this.state.password, + 'token': this.props.token + }, + function(err, status, data) { + if (err) { + console.error(err, data); + this.displayMessage(App.errorCodeToMessage(err.code), false); + return; + } + + this.displayMessage('You password has been reset.', true); + this.props.onSuccess(); + + }.bind(this) +); + e.preventDefault(); + } + + handlePasswordChange = (event) => { + this.setState({'password': event.target.value}); + } + + hideMessage = () => { + this.setState({'hideMsg': true}); + } + + displayMessage = (msg, ok) => { + this.setState({'msg': msg, 'msgOk': ok, 'hideMsg': false}); + } + + render = () => { + var cName = classNames('form-message', {'hidden': this.state.hideMsg, 'message-ok': this.state.msgOk}); + return ( +
+
+
+ + +
{this.state.msg}
+
+
+
+ ); + } +} + +export 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 @@ import SignupForm from './signup.js'; import SigninForm from './signin.js'; +import PasswordResetForm from './password_reset.js'; +import ChangePasswordForm from './change_password.js'; import OtpEnrollForm from './otp.js'; import PoloniexController from './poloniex.js'; import App from './app.js'; import Api from './api.js'; import cookies from './cookies.js'; import React from 'react'; +import qs from 'qs'; class Header extends React.Component { render = () => { @@ -60,6 +63,37 @@ App.page('/signin', false, function(context) { ); }); +App.page('/reset-password', false, function(context) { + if (App.isUserSignedIn()) { + App.go('/me'); + return; + } + + App.mount(
+
+ +
); +}); + +App.page('/change-password', false, function(context) { + if (App.isUserSignedIn()) { + App.go('/me'); + return; + } + + var token = qs.parse(context.querystring).token; + + if (token === undefined) { + App.go('/'); + return; + } + + App.mount(
+
+ +
); +}); + App.page('/signout', true, function(context) { cookies.removeItem('jwt'); 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 @@ +import Api from './api.js'; +import App from './app.js'; +import classNames from 'classnames'; +import React from 'react'; + +class PasswordResetForm extends React.Component { + constructor(props) { + super(props); + this.state = {'hideMsg': true, 'msg': '', 'msgOk': false, 'email': ''}; + } + + handleSubmit = (e) => { + Api.Call('RESET_PASSWORD', {'email': this.state.email}, function(err, status, data) { + if (err) { + console.error(err, data); + this.displayMessage(App.errorCodeToMessage(err.code), false); + return; + } + + this.displayMessage('You will receive a reset link to reset your password.', true); + if (this.props.onSuccess) { + this.props.onSuccess(); + } + + }.bind(this)); + e.preventDefault(); + } + + handleEmailChange = (event) => { + this.setState({'email': event.target.value}); + } + + hideMessage = () => { + this.setState({'hideMsg': true}); + } + + displayMessage = (msg, ok) => { + this.setState({'msg': msg, 'msgOk': ok, 'hideMsg': false}); + } + + render = () => { + var cName = classNames('form-message', {'hidden': this.state.hideMsg, 'message-ok': this.state.msgOk}); + return ( +
+
+
+ + +
{this.state.msg}
+
+
+
+ ); + } +} + +export 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 @@ "localenvify": "^1.0.1", "page": "^1.8.3", "path-to-regexp": "^1.2.1", + "qs": "^6.5.1", "react": "^16.2.0" }, "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: version "1.0.1" resolved "https://registry.yarnpkg.com/q/-/q-1.0.1.tgz#11872aeedee89268110b10a718448ffb10112a14" +qs@^6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" + qs@~1.2.0: version "1.2.2" resolved "https://registry.yarnpkg.com/qs/-/qs-1.2.2.tgz#19b57ff24dc2a99ce1f8bdf6afcda59f8ef61f88" -- cgit v1.2.3