From 7ccf77b1ada0236f35c2bd165c902f26df657254 Mon Sep 17 00:00:00 2001 From: riley Date: Tue, 28 Feb 2017 17:10:51 -0700 Subject: [PATCH] add reset password link --- client/coral-admin/src/actions/auth.js | 11 ++++ .../coral-admin/src/components/AdminLogin.js | 63 ++++++++++++++----- .../coral-admin/src/components/NotFound.css | 7 +++ client/coral-admin/src/constants/auth.js | 4 ++ .../src/containers/LayoutContainer.js | 13 +++- client/coral-admin/src/reducers/auth.js | 7 ++- 6 files changed, 85 insertions(+), 20 deletions(-) diff --git a/client/coral-admin/src/actions/auth.js b/client/coral-admin/src/actions/auth.js index 66c063d00..4fd4f3c63 100644 --- a/client/coral-admin/src/actions/auth.js +++ b/client/coral-admin/src/actions/auth.js @@ -14,6 +14,17 @@ export const handleLogin = (email, password) => dispatch => { }); }; +const forgotPassowordRequest = () => ({type: actions.FETCH_FORGOT_PASSWORD_REQUEST}); +const forgotPassowordSuccess = () => ({type: actions.FETCH_FORGOT_PASSWORD_SUCCESS}); +const forgotPassowordFailure = () => ({type: actions.FETCH_FORGOT_PASSWORD_FAILURE}); + +export const requestPasswordReset = email => dispatch => { + dispatch(forgotPassowordRequest(email)); + return coralApi('/account/password/reset', {method: 'POST', body: {email}}) + .then(() => dispatch(forgotPassowordSuccess())) + .catch(error => dispatch(forgotPassowordFailure(error))); +}; + // Check Login const checkLoginRequest = () => ({type: actions.CHECK_LOGIN_REQUEST}); diff --git a/client/coral-admin/src/components/AdminLogin.js b/client/coral-admin/src/components/AdminLogin.js index 1475ccce7..cd9bac1d4 100644 --- a/client/coral-admin/src/components/AdminLogin.js +++ b/client/coral-admin/src/components/AdminLogin.js @@ -10,7 +10,7 @@ class AdminLogin extends React.Component { constructor (props) { super(props); - this.state = {email: '', password: ''}; + this.state = {email: '', password: '', requestPassword: false}; } handleSignIn = e => { @@ -18,29 +18,57 @@ class AdminLogin extends React.Component { this.props.handleLogin(this.state.email, this.state.password); } + handleRequestPassword = e => { + e.preventDefault(); + this.props.requestPasswordReset(this.state.email); + } + render () { const {errorMessage} = this.props; + const signInForm = ( +
+ {errorMessage && {lang.t(`errors.${errorMessage}`)}} + this.setState({email: e.target.value})} /> + this.setState({password: e.target.value})} + type='password' /> + +

+ Forgot your password? { + e.preventDefault(); + this.setState({requestPassword: true}); + }}>Request a new one. +

+ + ); + const requestPasswordForm = ( + this.props.passwordRequestSuccess + ?

{this.props.passwordRequestSuccess}

+ :
+ this.setState({email: e.target.value})} /> + + + ); return (

Permission Required

Sign in to interact with your community.

-
- {errorMessage && {lang.t(`errors.${errorMessage}`)}} - this.setState({email: e.target.value})} /> - this.setState({password: e.target.value})} - type='password' /> - - + { this.state.requestPassword ? requestPasswordForm : signInForm }
); @@ -49,6 +77,7 @@ class AdminLogin extends React.Component { AdminLogin.propTypes = { handleLogin: PropTypes.func.isRequired, + passwordRequestSuccess: PropTypes.string, loginError: PropTypes.string }; diff --git a/client/coral-admin/src/components/NotFound.css b/client/coral-admin/src/components/NotFound.css index e0e04e0fd..c45fbcc02 100644 --- a/client/coral-admin/src/components/NotFound.css +++ b/client/coral-admin/src/components/NotFound.css @@ -6,3 +6,10 @@ .layout h1 { font-size: 40px; } + +.passwordRequestSuccess { + padding: 8px 14px; + background: lightgreen; + border: 1px solid darkgreen; + border-radius: 4px; +} diff --git a/client/coral-admin/src/constants/auth.js b/client/coral-admin/src/constants/auth.js index 88a9c4a3f..3c47bfc45 100644 --- a/client/coral-admin/src/constants/auth.js +++ b/client/coral-admin/src/constants/auth.js @@ -11,3 +11,7 @@ export const LOGOUT_FAILURE = 'LOGOUT_FAILURE'; export const LOGIN_REQUEST = 'LOGIN_REQUEST'; export const LOGIN_SUCCESS = 'LOGIN_SUCCESS'; export const LOGIN_FAILURE = 'LOGIN_FAILURE'; + +export const FETCH_FORGOT_PASSWORD_REQUEST = 'FETCH_FORGOT_PASSWORD_REQUEST'; +export const FETCH_FORGOT_PASSWORD_SUCCESS = 'FETCH_FORGOT_PASSWORD_SUCCESS'; +export const FETCH_FORGOT_PASSWORD_FAILURE = 'FETCH_FORGOT_PASSWORD_FAILURE'; diff --git a/client/coral-admin/src/containers/LayoutContainer.js b/client/coral-admin/src/containers/LayoutContainer.js index ca9ff2e7b..d122cd23a 100644 --- a/client/coral-admin/src/containers/LayoutContainer.js +++ b/client/coral-admin/src/containers/LayoutContainer.js @@ -1,7 +1,7 @@ import React, {Component} from 'react'; import {connect} from 'react-redux'; import Layout from '../components/ui/Layout'; -import {checkLogin, handleLogin, logout} from '../actions/auth'; +import {checkLogin, handleLogin, logout, requestPasswordReset} from '../actions/auth'; import {FullLoading} from '../components/FullLoading'; import AdminLogin from '../components/AdminLogin'; @@ -11,12 +11,20 @@ class LayoutContainer extends Component { checkLogin(); } render () { - const {isAdmin, loggedIn, loadingUser, loginError} = this.props.auth; + const { + isAdmin, + loggedIn, + loadingUser, + loginError, + passwordRequestSuccess + } = this.props.auth; const {handleLogout} = this.props; if (loadingUser) { return ; } if (!isAdmin) { return ; } if (isAdmin && loggedIn) { return ; } @@ -31,6 +39,7 @@ const mapStateToProps = state => ({ const mapDispatchToProps = dispatch => ({ checkLogin: () => dispatch(checkLogin()), handleLogin: (username, password) => dispatch(handleLogin(username, password)), + requestPasswordReset: email => dispatch(requestPasswordReset(email)), handleLogout: () => dispatch(logout()) }); diff --git a/client/coral-admin/src/reducers/auth.js b/client/coral-admin/src/reducers/auth.js index d2f178773..b52efdb85 100644 --- a/client/coral-admin/src/reducers/auth.js +++ b/client/coral-admin/src/reducers/auth.js @@ -5,7 +5,8 @@ const initialState = Map({ loggedIn: false, user: null, isAdmin: false, - loginError: null + loginError: null, + passwordRequestSuccess: null }); export default function auth (state = initialState, action) { @@ -30,6 +31,10 @@ export default function auth (state = initialState, action) { return state.set('loginError', null); case actions.LOGIN_FAILURE: return state.set('loginError', action.message); + case actions.FETCH_FORGOT_PASSWORD_REQUEST: + return state.set('passwordRequestSuccess', null); + case actions.FETCH_FORGOT_PASSWORD_SUCCESS: + return state.set('passwordRequestSuccess', 'If you have a registered account, a password reset link was sent to that email.'); default : return state; }