Complete change password functionality

master
Alexander Wong 7 years ago
parent 1bf1dad0b9
commit 44c6117ce1
  1. 26
      src/actions/auth/reducer.actions.js
  2. 10
      src/actions/auth/saga.actions.js
  3. 14
      src/api/auth.api.js
  4. 2
      src/api/baseApi.js
  5. 129
      src/components/Auth/Settings.jsx
  6. 2
      src/constants/auth.constants.js
  7. 11
      src/reducers/authReducer.js
  8. 32
      src/sagas/auth.sagas.js
  9. 7
      src/sagas/index.js

@ -12,7 +12,8 @@ import {
SET_FORM_EMAIL, SET_FORM_EMAIL,
SET_FORM_PASSWORD, SET_FORM_PASSWORD,
SET_FORM_PASSWORD_CONFIRMATION, SET_FORM_PASSWORD_CONFIRMATION,
SET_FORM_EMAIL_VERIFICATION SET_FORM_EMAIL_VERIFICATION,
SET_FORM_OLD_PASSWORD
} from "../../constants/auth.constants"; } from "../../constants/auth.constants";
import { parseError } from "../common.actions"; import { parseError } from "../common.actions";
@ -41,6 +42,22 @@ export function setAuthRequestError(exception) {
error["Non Field Errors"] = error.non_field_errors; error["Non Field Errors"] = error.non_field_errors;
delete error["non_field_errors"]; delete error["non_field_errors"];
} }
if (error.detail) {
error["Detail"] = error.detail;
delete error["detail"];
}
if (error.old_password) {
error["Old Password"] = error.old_password;
delete error["old_password"];
}
if (error.new_password1) {
error["New Password"] = error.new_password1;
delete error["new_password1"];
}
if (error.new_password2) {
error["Confirm New Password"] = error.new_password2;
delete error["new_password2"];
}
return { return {
type: SET_AUTH_REQUEST_ERROR, type: SET_AUTH_REQUEST_ERROR,
@ -137,3 +154,10 @@ export function setFormEmailVerification(emailKey) {
data: emailKey data: emailKey
}; };
} }
export function setFormOldPassword(oldPassword) {
return {
type: SET_FORM_OLD_PASSWORD,
data: oldPassword
};
}

@ -2,7 +2,8 @@ import {
SEND_REGISTER_REQUEST, SEND_REGISTER_REQUEST,
SEND_EMAIL_VERIFICATION_REQUEST, SEND_EMAIL_VERIFICATION_REQUEST,
SEND_LOGIN_REQUEST, SEND_LOGIN_REQUEST,
SEND_LOGOUT_REQUEST SEND_LOGOUT_REQUEST,
SEND_CHANGE_PASSWORD_REQUEST
} from "../../constants/auth.constants"; } from "../../constants/auth.constants";
export function sendRegisterRequest(postBody) { export function sendRegisterRequest(postBody) {
@ -31,3 +32,10 @@ export function sendLogoutRequest() {
type: SEND_LOGOUT_REQUEST type: SEND_LOGOUT_REQUEST
} }
} }
export function sendChangePasswordRequest(postBody) {
return {
type: SEND_CHANGE_PASSWORD_REQUEST,
data: postBody
}
}

@ -41,3 +41,17 @@ export function loginUser(email, password) {
export function logoutUser() { export function logoutUser() {
return post("/rest-auth/logout/").then(resp => Promise.resolve(resp)); return post("/rest-auth/logout/").then(resp => Promise.resolve(resp));
} }
/**
* Function wrapping POST request for change password
* @param {string} new_password1 - user new password
* @param {string} new_password2 - user new password confirmation
* @param {string} old_password - old password of user
*/
export function changePassword(new_password1, new_password2, old_password) {
return post("/rest-auth/password/change/", {
new_password1,
new_password2,
old_password
}).then(resp => Promise.resolve(resp));
}

@ -14,7 +14,7 @@ function headers() {
return { return {
Accept: "application/json", Accept: "application/json",
"Content-Type": "application/json", "Content-Type": "application/json",
Authorization: `Token: ${token}` Authorization: `Token ${token}`
}; };
} }

@ -1,10 +1,76 @@
import React, { Component } from "react"; import React, { Component } from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { Container } from "semantic-ui-react"; import { Container, Form, Header, Message, Segment } from "semantic-ui-react";
import {
clearAuthRequestError,
clearAuthRequestSuccess,
setFormPassword,
setFormPasswordConfirmation,
setFormOldPassword
} from "../../actions/auth/reducer.actions";
import { sendChangePasswordRequest } from "../../actions/auth/saga.actions";
import Error from "../Shared/Error";
class Settings extends Component { class Settings extends Component {
constructor(props) {
super(props);
this.props.dispatch(clearAuthRequestError());
this.props.dispatch(clearAuthRequestSuccess());
}
changePassword = event => {
this.props.dispatch(setFormPassword(event.target.value));
};
changePasswordConfirmation = event => {
this.props.dispatch(setFormPasswordConfirmation(event.target.value));
};
changeOldPassword = event => {
this.props.dispatch(setFormOldPassword(event.target.value));
};
onSubmitChangePassword = event => {
event.preventDefault();
const {
dispatch,
password,
passwordConfirmation,
oldPassword
} = this.props;
dispatch(
sendChangePasswordRequest({
new_password1: password,
new_password2: passwordConfirmation,
old_password: oldPassword
})
);
};
render() { render() {
return <SettingsView />; const {
isSendingAuthRequest,
authRequestError,
authRequestSuccess,
password,
passwordConfirmation,
oldPassword
} = this.props;
return (
<SettingsView
isSendingAuthRequest={isSendingAuthRequest}
authRequestError={authRequestError}
authRequestSuccess={authRequestSuccess}
password={password}
passwordConfirmation={passwordConfirmation}
oldPassword={oldPassword}
changePassword={this.changePassword}
changePasswordConfirmation={this.changePasswordConfirmation}
changeOldPassword={this.changeOldPassword}
onSubmitChangePassword={this.onSubmitChangePassword}
/>
);
} }
} }
@ -12,10 +78,63 @@ function mapStateToProps(state) {
return { ...state.auth }; return { ...state.auth };
} }
const SettingsView = () => ( const SettingsView = ({
isSendingAuthRequest,
authRequestError,
authRequestSuccess,
password,
passwordConfirmation,
oldPassword,
changePassword,
changePasswordConfirmation,
changeOldPassword,
onSubmitChangePassword
}) => (
<Container> <Container>
<h1>Settings</h1> <Header>Settings</Header>
<p>todo, change password</p> <Header attached="top"> Change Password </Header>
<Segment attached>
<Form
loading={isSendingAuthRequest}
onSubmit={onSubmitChangePassword}
error={!!authRequestError}
success={!!authRequestSuccess}
>
<Form.Field>
<label>Old Password</label>
<input
placeholder="••••••••"
type="password"
value={oldPassword}
onChange={changeOldPassword}
/>
</Form.Field>
<Form.Field>
<label>New Password</label>
<input
placeholder="••••••••"
type="password"
value={password}
onChange={changePassword}
/>
</Form.Field>
<Form.Field>
<label>Confirm New Password</label>
<input
placeholder="••••••••"
type="password"
value={passwordConfirmation}
onChange={changePasswordConfirmation}
/>
</Form.Field>
<Error header="Change Password failed!" error={authRequestError} />
<Message success>
<Message.Header>Password Successfully Changed!</Message.Header>
<p>New password has been set.</p>
</Message>
<Form.Button>Change Password</Form.Button>
</Form>
</Segment>
</Container> </Container>
); );

@ -14,6 +14,7 @@ export const SET_FORM_EMAIL = "SET_FORM_EMAIL";
export const SET_FORM_PASSWORD = "SET_FORM_PASSWORD"; export const SET_FORM_PASSWORD = "SET_FORM_PASSWORD";
export const SET_FORM_PASSWORD_CONFIRMATION = "SET_FORM_PASSWORD_CONFIRMATION"; export const SET_FORM_PASSWORD_CONFIRMATION = "SET_FORM_PASSWORD_CONFIRMATION";
export const SET_FORM_EMAIL_VERIFICATION = "SET_FORM_EMAIL_VERIFICATION"; export const SET_FORM_EMAIL_VERIFICATION = "SET_FORM_EMAIL_VERIFICATION";
export const SET_FORM_OLD_PASSWORD = "SET_FORM_OLD_PASSWORD";
// Saga Auth Action Constants // Saga Auth Action Constants
export const SEND_REGISTER_REQUEST = "SEND_REGISTER_REQUEST"; export const SEND_REGISTER_REQUEST = "SEND_REGISTER_REQUEST";
@ -21,3 +22,4 @@ export const SEND_EMAIL_VERIFICATION_REQUEST =
"SEND_EMAIL_VERIFICATION_REQUEST"; "SEND_EMAIL_VERIFICATION_REQUEST";
export const SEND_LOGIN_REQUEST = "SEND_LOGIN_REQUEST"; export const SEND_LOGIN_REQUEST = "SEND_LOGIN_REQUEST";
export const SEND_LOGOUT_REQUEST = "SEND_LOGOUT_REQUEST"; export const SEND_LOGOUT_REQUEST = "SEND_LOGOUT_REQUEST";
export const SEND_CHANGE_PASSWORD_REQUEST = "SEND_CHANGE_PASSWORD_REQUEST";

@ -12,7 +12,8 @@ import {
SET_FORM_EMAIL, SET_FORM_EMAIL,
SET_FORM_PASSWORD, SET_FORM_PASSWORD,
SET_FORM_PASSWORD_CONFIRMATION, SET_FORM_PASSWORD_CONFIRMATION,
SET_FORM_EMAIL_VERIFICATION SET_FORM_EMAIL_VERIFICATION,
SET_FORM_OLD_PASSWORD
} from "../constants/auth.constants"; } from "../constants/auth.constants";
/** /**
@ -37,7 +38,8 @@ const initialState = {
email: "", email: "",
password: "", password: "",
passwordConfirmation: "", passwordConfirmation: "",
emailVerificationString: "" emailVerificationString: "",
oldPassword: "" // used for change password functionality
}; };
function authReducer(state = initialState, action) { function authReducer(state = initialState, action) {
@ -112,6 +114,11 @@ function authReducer(state = initialState, action) {
...state, ...state,
emailVerificationString: action.data emailVerificationString: action.data
}; };
case SET_FORM_OLD_PASSWORD:
return {
...state,
oldPassword: action.data
}
default: default:
return state; return state;
} }

@ -9,17 +9,19 @@ import {
clearEmailVerificationError, clearEmailVerificationError,
clearAuthRequestSuccess, clearAuthRequestSuccess,
clearEmailVerificationSuccess, clearEmailVerificationSuccess,
setSelfUserToken,
setFormEmail, setFormEmail,
setFormPassword, setFormPassword,
setFormPasswordConfirmation, setFormPasswordConfirmation,
setFormEmailVerification, setFormEmailVerification,
setSelfUserToken setFormOldPassword,
} from "../actions/auth/reducer.actions"; } from "../actions/auth/reducer.actions";
import { import {
registerUser, registerUser,
verifyEmail, verifyEmail,
loginUser, loginUser,
logoutUser logoutUser,
changePassword
} from "../api/auth.api"; } from "../api/auth.api";
function* registerUserCall(postBody) { function* registerUserCall(postBody) {
@ -65,6 +67,19 @@ function* logoutUserCall() {
yield effects.call(logoutUser); yield effects.call(logoutUser);
} }
function* changePasswordCall(postBody) {
yield effects.put(isSendingAuthRequest(true));
const { new_password1, new_password2, old_password } = postBody;
try {
return yield effects.call(changePassword, new_password1, new_password2, old_password);
} catch (exception) {
yield effects.put(setAuthRequestError(exception));
return false;
} finally {
yield effects.put(isSendingAuthRequest(false));
}
}
export function* registerUserFlow(request) { export function* registerUserFlow(request) {
yield effects.put(clearAuthRequestSuccess()); yield effects.put(clearAuthRequestSuccess());
yield effects.put(clearAuthRequestError()); yield effects.put(clearAuthRequestError());
@ -109,3 +124,16 @@ export function* logoutUserFlow(request) {
yield effects.call(logoutUserCall); yield effects.call(logoutUserCall);
yield effects.put(setSelfUserToken("")); yield effects.put(setSelfUserToken(""));
} }
export function* changePasswordFlow(request) {
yield effects.put(clearAuthRequestSuccess());
yield effects.put(clearAuthRequestError());
const wasSuccessful = yield effects.call(changePasswordCall, request.data);
if (wasSuccessful) {
yield effects.put(setAuthRequestSuccess(wasSuccessful));
yield effects.put(clearAuthRequestError());
yield effects.put(setFormOldPassword(""));
yield effects.put(setFormPassword(""));
yield effects.put(setFormPasswordConfirmation(""));
}
}

@ -3,13 +3,15 @@ import {
SEND_REGISTER_REQUEST, SEND_REGISTER_REQUEST,
SEND_EMAIL_VERIFICATION_REQUEST, SEND_EMAIL_VERIFICATION_REQUEST,
SEND_LOGIN_REQUEST, SEND_LOGIN_REQUEST,
SEND_LOGOUT_REQUEST SEND_LOGOUT_REQUEST,
SEND_CHANGE_PASSWORD_REQUEST
} from "../constants/auth.constants"; } from "../constants/auth.constants";
import { import {
registerUserFlow, registerUserFlow,
verifyEmailFlow, verifyEmailFlow,
loginUserFlow, loginUserFlow,
logoutUserFlow logoutUserFlow,
changePasswordFlow
} from "./auth.sagas"; } from "./auth.sagas";
export default function* rootSaga() { export default function* rootSaga() {
@ -17,4 +19,5 @@ export default function* rootSaga() {
yield takeLatest(SEND_EMAIL_VERIFICATION_REQUEST, verifyEmailFlow); yield takeLatest(SEND_EMAIL_VERIFICATION_REQUEST, verifyEmailFlow);
yield takeLatest(SEND_LOGIN_REQUEST, loginUserFlow); yield takeLatest(SEND_LOGIN_REQUEST, loginUserFlow);
yield takeLatest(SEND_LOGOUT_REQUEST, logoutUserFlow); yield takeLatest(SEND_LOGOUT_REQUEST, logoutUserFlow);
yield takeLatest(SEND_CHANGE_PASSWORD_REQUEST, changePasswordFlow);
} }

Loading…
Cancel
Save