Finished functionally complete email confirmation workflow
This commit is contained in:
		@@ -13,12 +13,12 @@ Now you can visit `localhost:3000` from your browser.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## Environment Variables
 | 
					## Environment Variables
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The environment variables are embedded during the build time. For more information, please refer to the [docs](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-custom-environment-variables.
 | 
					The environment variables are embedded during the build time. For more information, please refer to the [docs](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-custom-environment-variables).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| Environment Variable      | Default Value             | Description         |
 | 
					| Environment Variable      | Default Value             | Description         |
 | 
				
			||||||
| ------------------------- |:-------------------------:| -------------------:|
 | 
					| ------------------------- |:-------------------------:| -------------------:|
 | 
				
			||||||
| `REACT_APP_API_ENDPOINT`  | `"http://localhost:8000"` | Server API endpoint |
 | 
					| `REACT_APP_API_ENDPOINT`  | `"http://localhost:8000"` | Server API endpoint |
 | 
				
			||||||
| `REACT_APP_REDUX_LOGGING` | ``                        | Set for Redux Log   |
 | 
					| `REACT_APP_REDUX_LOGGING` | ` `                       | Set for Redux Log   |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Testing
 | 
					## Testing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,10 +4,15 @@ import {
 | 
				
			|||||||
  CLEAR_AUTH_REQUEST_ERROR,
 | 
					  CLEAR_AUTH_REQUEST_ERROR,
 | 
				
			||||||
  SET_AUTH_REQUEST_SUCCESS,
 | 
					  SET_AUTH_REQUEST_SUCCESS,
 | 
				
			||||||
  CLEAR_AUTH_REQUEST_SUCCESS,
 | 
					  CLEAR_AUTH_REQUEST_SUCCESS,
 | 
				
			||||||
 | 
					  SET_EMAIL_VERIFICATION_SUCCESS,
 | 
				
			||||||
 | 
					  CLEAR_EMAIL_VERIFICATION_SUCCESS,
 | 
				
			||||||
 | 
					  SET_EMAIL_VERIFICATION_ERROR,
 | 
				
			||||||
 | 
					  CLEAR_EMAIL_VERIFICATION_ERROR,
 | 
				
			||||||
  SET_SELF_USER,
 | 
					  SET_SELF_USER,
 | 
				
			||||||
  SET_FORM_EMAIL,
 | 
					  SET_FORM_EMAIL,
 | 
				
			||||||
  SET_FORM_PASSWORD,
 | 
					  SET_FORM_PASSWORD,
 | 
				
			||||||
  SET_FORM_PASSWORD_CONFIRMATION
 | 
					  SET_FORM_PASSWORD_CONFIRMATION,
 | 
				
			||||||
 | 
					  SET_FORM_EMAIL_VERIFICATION
 | 
				
			||||||
} from "../../constants/auth.constants";
 | 
					} from "../../constants/auth.constants";
 | 
				
			||||||
import { parseError } from "../common.actions";
 | 
					import { parseError } from "../common.actions";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -19,27 +24,27 @@ export function isSendingAuthRequest(sendingRequest) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function setAuthRequestError(exception) {
 | 
					export function setAuthRequestError(exception) {
 | 
				
			||||||
  let rawError = parseError(exception);
 | 
					  let error = parseError(exception);
 | 
				
			||||||
  if (rawError.email) {
 | 
					  if (error.email) {
 | 
				
			||||||
    rawError["Email"] = rawError.email;
 | 
					    error["Email"] = error.email;
 | 
				
			||||||
    delete rawError["email"];
 | 
					    delete error["email"];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (rawError.password1) {
 | 
					  if (error.password1) {
 | 
				
			||||||
    rawError["Password"] = rawError.password1;
 | 
					    error["Password"] = error.password1;
 | 
				
			||||||
    delete rawError["password1"];
 | 
					    delete error["password1"];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (rawError.password2) {
 | 
					  if (error.password2) {
 | 
				
			||||||
    rawError["Password Confirmation"] = rawError.password2;
 | 
					    error["Password Confirmation"] = error.password2;
 | 
				
			||||||
    delete rawError["password2"];
 | 
					    delete error["password2"];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (rawError.non_field_errors) {
 | 
					  if (error.non_field_errors) {
 | 
				
			||||||
    rawError["Non Field Errors"] = rawError.non_field_errors;
 | 
					    error["Non Field Errors"] = error.non_field_errors;
 | 
				
			||||||
    delete rawError["non_field_errors"];
 | 
					    delete error["non_field_errors"];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return {
 | 
					  return {
 | 
				
			||||||
    type: SET_AUTH_REQUEST_ERROR,
 | 
					    type: SET_AUTH_REQUEST_ERROR,
 | 
				
			||||||
    data: parseError(exception)
 | 
					    data: error
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -53,13 +58,49 @@ export function setAuthRequestSuccess(response) {
 | 
				
			|||||||
  return {
 | 
					  return {
 | 
				
			||||||
    type: SET_AUTH_REQUEST_SUCCESS,
 | 
					    type: SET_AUTH_REQUEST_SUCCESS,
 | 
				
			||||||
    data: response.detail || response
 | 
					    data: response.detail || response
 | 
				
			||||||
  }
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function clearAuthRequestSuccess() {
 | 
					export function clearAuthRequestSuccess() {
 | 
				
			||||||
  return {
 | 
					  return {
 | 
				
			||||||
    type: CLEAR_AUTH_REQUEST_SUCCESS
 | 
					    type: CLEAR_AUTH_REQUEST_SUCCESS
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function setEmailVerificationError(exception) {
 | 
				
			||||||
 | 
					  let error = parseError(exception);
 | 
				
			||||||
 | 
					  if (error.detail) {
 | 
				
			||||||
 | 
					    error["Email"] = error.detail;
 | 
				
			||||||
 | 
					    delete error["detail"];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  if (error.key) {
 | 
				
			||||||
 | 
					    error["Verification Key"] = error.key;
 | 
				
			||||||
 | 
					    delete error["key"];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    type: SET_EMAIL_VERIFICATION_ERROR,
 | 
				
			||||||
 | 
					    data: error
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function clearEmailVerificationError() {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    type: CLEAR_EMAIL_VERIFICATION_ERROR
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function setEmailVerificationSuccess(response) {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    type: SET_EMAIL_VERIFICATION_SUCCESS,
 | 
				
			||||||
 | 
					    data: response.detail || response
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function clearEmailVerificationSuccess() {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    type: CLEAR_EMAIL_VERIFICATION_SUCCESS
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function setSelfUser(selfUser) {
 | 
					export function setSelfUser(selfUser) {
 | 
				
			||||||
@@ -89,3 +130,10 @@ export function setFormPasswordConfirmation(passwordConfirmation) {
 | 
				
			|||||||
    data: passwordConfirmation
 | 
					    data: passwordConfirmation
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function setFormEmailVerification(emailKey) {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    type: SET_FORM_EMAIL_VERIFICATION,
 | 
				
			||||||
 | 
					    data: emailKey
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,18 @@
 | 
				
			|||||||
import {
 | 
					import {
 | 
				
			||||||
  SEND_REGISTER_REQUEST
 | 
					  SEND_REGISTER_REQUEST,
 | 
				
			||||||
 | 
					  SEND_EMAIL_VERIFICATION_REQUEST
 | 
				
			||||||
} from "../../constants/auth.constants";
 | 
					} from "../../constants/auth.constants";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function sendRegisterRequest(postbody) {
 | 
					export function sendRegisterRequest(postbody) {
 | 
				
			||||||
  return {
 | 
					  return {
 | 
				
			||||||
    type: SEND_REGISTER_REQUEST,
 | 
					    type: SEND_REGISTER_REQUEST,
 | 
				
			||||||
    data: postbody
 | 
					    data: postbody
 | 
				
			||||||
  }
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function sendEmailVerificationRequest(postbody) {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    type: SEND_EMAIL_VERIFICATION_REQUEST,
 | 
				
			||||||
 | 
					    data: postbody
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,3 +15,11 @@ export function registerUser(email, password1, password2) {
 | 
				
			|||||||
    return Promise.resolve(response);
 | 
					    return Promise.resolve(response);
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function verifyEmail(emailKey) {
 | 
				
			||||||
 | 
					  return post("/rest-auth/registration/verify-email/", {
 | 
				
			||||||
 | 
					    key: emailKey
 | 
				
			||||||
 | 
					  }).then(response => {
 | 
				
			||||||
 | 
					    return Promise.resolve(response);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,7 @@ import { Route, Switch } from "react-router-dom";
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import Login from "./Auth/Login";
 | 
					import Login from "./Auth/Login";
 | 
				
			||||||
import Register from "./Auth/Register";
 | 
					import Register from "./Auth/Register";
 | 
				
			||||||
 | 
					import VerifyEmail from "./Auth/VerifyEmail";
 | 
				
			||||||
import About from "./Static/About";
 | 
					import About from "./Static/About";
 | 
				
			||||||
import Footer from "./Static/Footer";
 | 
					import Footer from "./Static/Footer";
 | 
				
			||||||
import Home from "./Static/Home";
 | 
					import Home from "./Static/Home";
 | 
				
			||||||
@@ -26,6 +27,10 @@ class App extends Component {
 | 
				
			|||||||
              <Route path="/about" component={About} />
 | 
					              <Route path="/about" component={About} />
 | 
				
			||||||
              <Route path="/auth/login" component={Login} />
 | 
					              <Route path="/auth/login" component={Login} />
 | 
				
			||||||
              <Route path="/auth/register" component={Register} />
 | 
					              <Route path="/auth/register" component={Register} />
 | 
				
			||||||
 | 
					              <Route
 | 
				
			||||||
 | 
					                path="/auth/verify-email/:emailKey"
 | 
				
			||||||
 | 
					                component={VerifyEmail}
 | 
				
			||||||
 | 
					              />
 | 
				
			||||||
              <Route component={NoMatch} />
 | 
					              <Route component={NoMatch} />
 | 
				
			||||||
            </Switch>
 | 
					            </Switch>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,10 @@
 | 
				
			|||||||
import React, { Component } from "react";
 | 
					import React, { Component } from "react";
 | 
				
			||||||
import { connect } from "react-redux";
 | 
					import { connect } from "react-redux";
 | 
				
			||||||
import { Container, Form, Header, Message  } from "semantic-ui-react";
 | 
					import { Container, Form, Header, Message } from "semantic-ui-react";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  clearAuthRequestError,
 | 
					  clearAuthRequestError,
 | 
				
			||||||
 | 
					  clearAuthRequestSuccess,
 | 
				
			||||||
  setFormEmail,
 | 
					  setFormEmail,
 | 
				
			||||||
  setFormPassword,
 | 
					  setFormPassword,
 | 
				
			||||||
  setFormPasswordConfirmation
 | 
					  setFormPasswordConfirmation
 | 
				
			||||||
@@ -15,6 +16,7 @@ class Register extends Component {
 | 
				
			|||||||
  constructor(props) {
 | 
					  constructor(props) {
 | 
				
			||||||
    super(props);
 | 
					    super(props);
 | 
				
			||||||
    this.props.dispatch(clearAuthRequestError());
 | 
					    this.props.dispatch(clearAuthRequestError());
 | 
				
			||||||
 | 
					    this.props.dispatch(clearAuthRequestSuccess());
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  changeEmail = event => {
 | 
					  changeEmail = event => {
 | 
				
			||||||
@@ -122,12 +124,11 @@ const RegisterView = ({
 | 
				
			|||||||
        />
 | 
					        />
 | 
				
			||||||
      </Form.Field>
 | 
					      </Form.Field>
 | 
				
			||||||
      <Error header="Register failed!" error={authRequestError} />
 | 
					      <Error header="Register failed!" error={authRequestError} />
 | 
				
			||||||
      <Message
 | 
					      <Message success>
 | 
				
			||||||
        success
 | 
					        <Message.Header>Confirmation Email Sent!</Message.Header>
 | 
				
			||||||
        header="Registration Sent"
 | 
					        <p>Please check your email to confirm your registration.</p>
 | 
				
			||||||
        content="A confirmation email has been sent to confirm your registration."
 | 
					      </Message>
 | 
				
			||||||
      />
 | 
					      <Form.Button>Register</Form.Button>
 | 
				
			||||||
      <Form.Button>Submit</Form.Button>
 | 
					 | 
				
			||||||
    </Form>
 | 
					    </Form>
 | 
				
			||||||
  </Container>
 | 
					  </Container>
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										97
									
								
								src/components/Auth/VerifyEmail.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								src/components/Auth/VerifyEmail.jsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
				
			|||||||
 | 
					import React, { Component } from "react";
 | 
				
			||||||
 | 
					import { connect } from "react-redux";
 | 
				
			||||||
 | 
					import { Link } from "react-router-dom";
 | 
				
			||||||
 | 
					import { Container, Form, Header, Message } from "semantic-ui-react";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  clearEmailVerificationError,
 | 
				
			||||||
 | 
					  clearEmailVerificationSuccess,
 | 
				
			||||||
 | 
					  setFormEmailVerification
 | 
				
			||||||
 | 
					} from "../../actions/auth/reducer.actions";
 | 
				
			||||||
 | 
					import { sendEmailVerificationRequest } from "../../actions/auth/saga.actions";
 | 
				
			||||||
 | 
					import Error from "../Shared/Error";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class VerifyEmail extends Component {
 | 
				
			||||||
 | 
					  constructor(props) {
 | 
				
			||||||
 | 
					    super(props);
 | 
				
			||||||
 | 
					    const emailKey = this.props.match.params.emailKey;
 | 
				
			||||||
 | 
					    this.props.dispatch(clearEmailVerificationError());
 | 
				
			||||||
 | 
					    this.props.dispatch(clearEmailVerificationSuccess());
 | 
				
			||||||
 | 
					    this.props.dispatch(setFormEmailVerification(emailKey));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  changeEmailKey = event => {
 | 
				
			||||||
 | 
					    this.props.dispatch(setFormEmailVerification(event.target.value));
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onSubmitEmailVerification = event => {
 | 
				
			||||||
 | 
					    event.preventDefault();
 | 
				
			||||||
 | 
					    const { dispatch, emailVerificationString } = this.props;
 | 
				
			||||||
 | 
					    dispatch(
 | 
				
			||||||
 | 
					      sendEmailVerificationRequest({ emailKey: emailVerificationString })
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  render() {
 | 
				
			||||||
 | 
					    const {
 | 
				
			||||||
 | 
					      isSendingAuthRequest,
 | 
				
			||||||
 | 
					      emailVerificationRequestError,
 | 
				
			||||||
 | 
					      emailVerificationRequestSuccess,
 | 
				
			||||||
 | 
					      emailVerificationString
 | 
				
			||||||
 | 
					    } = this.props;
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <VerifyEmailView
 | 
				
			||||||
 | 
					        isSendingAuthRequest={isSendingAuthRequest}
 | 
				
			||||||
 | 
					        emailVerificationRequestError={emailVerificationRequestError}
 | 
				
			||||||
 | 
					        emailVerificationRequestSuccess={emailVerificationRequestSuccess}
 | 
				
			||||||
 | 
					        emailVerificationString={emailVerificationString}
 | 
				
			||||||
 | 
					        changeEmailKey={this.changeEmailKey}
 | 
				
			||||||
 | 
					        onSubmitEmailVerification={this.onSubmitEmailVerification}
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function mapStateToProps(state) {
 | 
				
			||||||
 | 
					  return { ...state.auth };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const VerifyEmailView = ({
 | 
				
			||||||
 | 
					  isSendingAuthRequest,
 | 
				
			||||||
 | 
					  emailVerificationRequestError,
 | 
				
			||||||
 | 
					  emailVerificationRequestSuccess,
 | 
				
			||||||
 | 
					  emailVerificationString,
 | 
				
			||||||
 | 
					  changeEmailKey,
 | 
				
			||||||
 | 
					  onSubmitEmailVerification
 | 
				
			||||||
 | 
					}) => (
 | 
				
			||||||
 | 
					  <Container>
 | 
				
			||||||
 | 
					    <Header>Verify Email</Header>
 | 
				
			||||||
 | 
					    <Form
 | 
				
			||||||
 | 
					      loading={isSendingAuthRequest}
 | 
				
			||||||
 | 
					      onSubmit={onSubmitEmailVerification}
 | 
				
			||||||
 | 
					      error={!!emailVerificationRequestError}
 | 
				
			||||||
 | 
					      success={!!emailVerificationRequestSuccess}
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
 | 
					      <Form.Field>
 | 
				
			||||||
 | 
					        <label>Email Verification Key</label>
 | 
				
			||||||
 | 
					        <input
 | 
				
			||||||
 | 
					          placeholder=""
 | 
				
			||||||
 | 
					          type="text"
 | 
				
			||||||
 | 
					          value={emailVerificationString}
 | 
				
			||||||
 | 
					          onChange={changeEmailKey}
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					      </Form.Field>
 | 
				
			||||||
 | 
					      <Error
 | 
				
			||||||
 | 
					        header="Email Verification failed!"
 | 
				
			||||||
 | 
					        error={emailVerificationRequestError}
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					      <Message success>
 | 
				
			||||||
 | 
					        <Message.Header>Email Verified!</Message.Header>
 | 
				
			||||||
 | 
					        <p>Please proceed to <Link to="/auth/login">log in</Link>.</p>
 | 
				
			||||||
 | 
					      </Message>
 | 
				
			||||||
 | 
					      <Form.Button>Verify Email</Form.Button>
 | 
				
			||||||
 | 
					    </Form>
 | 
				
			||||||
 | 
					  </Container>
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default connect(mapStateToProps)(VerifyEmail);
 | 
				
			||||||
@@ -4,10 +4,18 @@ export const SET_AUTH_REQUEST_ERROR = "SET_AUTH_REQUEST_ERROR";
 | 
				
			|||||||
export const CLEAR_AUTH_REQUEST_ERROR = "CLEAR_AUTH_REQUEST_ERROR";
 | 
					export const CLEAR_AUTH_REQUEST_ERROR = "CLEAR_AUTH_REQUEST_ERROR";
 | 
				
			||||||
export const SET_AUTH_REQUEST_SUCCESS = "SET_AUTH_REQUEST_SUCCESS";
 | 
					export const SET_AUTH_REQUEST_SUCCESS = "SET_AUTH_REQUEST_SUCCESS";
 | 
				
			||||||
export const CLEAR_AUTH_REQUEST_SUCCESS = "CLEAR_AUTH_REQUEST_SUCCESS";
 | 
					export const CLEAR_AUTH_REQUEST_SUCCESS = "CLEAR_AUTH_REQUEST_SUCCESS";
 | 
				
			||||||
 | 
					export const SET_EMAIL_VERIFICATION_SUCCESS = "SET_EMAIL_VERIFICATION_SUCCESS";
 | 
				
			||||||
 | 
					export const CLEAR_EMAIL_VERIFICATION_SUCCESS =
 | 
				
			||||||
 | 
					  "CLEAR_EMAIL_VERIFICATION_SUCCESS";
 | 
				
			||||||
 | 
					export const SET_EMAIL_VERIFICATION_ERROR = "SET_EMAIL_VERIFICATION_ERROR";
 | 
				
			||||||
 | 
					export const CLEAR_EMAIL_VERIFICATION_ERROR = "CLEAR_EMAIL_VERIFICATION_ERROR";
 | 
				
			||||||
export const SET_SELF_USER = "SET_SELF_USER";
 | 
					export const SET_SELF_USER = "SET_SELF_USER";
 | 
				
			||||||
export const SET_FORM_EMAIL = "SET_FORM_EMAIL";
 | 
					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";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Saga Auth Action Constants
 | 
					// Saga Auth Action Constants
 | 
				
			||||||
export const SEND_REGISTER_REQUEST = "SEND_REGISTER_REQUEST";
 | 
					export const SEND_REGISTER_REQUEST = "SEND_REGISTER_REQUEST";
 | 
				
			||||||
 | 
					export const SEND_EMAIL_VERIFICATION_REQUEST =
 | 
				
			||||||
 | 
					  "SEND_EMAIL_VERIFICATION_REQUEST";
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,20 +4,28 @@ import {
 | 
				
			|||||||
  CLEAR_AUTH_REQUEST_ERROR,
 | 
					  CLEAR_AUTH_REQUEST_ERROR,
 | 
				
			||||||
  SET_AUTH_REQUEST_SUCCESS,
 | 
					  SET_AUTH_REQUEST_SUCCESS,
 | 
				
			||||||
  CLEAR_AUTH_REQUEST_SUCCESS,
 | 
					  CLEAR_AUTH_REQUEST_SUCCESS,
 | 
				
			||||||
 | 
					  SET_EMAIL_VERIFICATION_ERROR,
 | 
				
			||||||
 | 
					  CLEAR_EMAIL_VERIFICATION_ERROR,
 | 
				
			||||||
 | 
					  SET_EMAIL_VERIFICATION_SUCCESS,
 | 
				
			||||||
 | 
					  CLEAR_EMAIL_VERIFICATION_SUCCESS,
 | 
				
			||||||
  SET_SELF_USER,
 | 
					  SET_SELF_USER,
 | 
				
			||||||
  SET_FORM_EMAIL,
 | 
					  SET_FORM_EMAIL,
 | 
				
			||||||
  SET_FORM_PASSWORD,
 | 
					  SET_FORM_PASSWORD,
 | 
				
			||||||
  SET_FORM_PASSWORD_CONFIRMATION
 | 
					  SET_FORM_PASSWORD_CONFIRMATION,
 | 
				
			||||||
 | 
					  SET_FORM_EMAIL_VERIFICATION
 | 
				
			||||||
} from "../constants/auth.constants";
 | 
					} from "../constants/auth.constants";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const initialState = {
 | 
					const initialState = {
 | 
				
			||||||
  isSendingAuthRequest: false,
 | 
					  isSendingAuthRequest: false,
 | 
				
			||||||
  authRequestError: "",
 | 
					  authRequestError: "",
 | 
				
			||||||
  authRequestSuccess: "",
 | 
					  authRequestSuccess: "",
 | 
				
			||||||
 | 
					  emailVerificationRequestError: "",
 | 
				
			||||||
 | 
					  emailVerificationRequestSuccess: "",
 | 
				
			||||||
  currentUser: {},
 | 
					  currentUser: {},
 | 
				
			||||||
  email: "",
 | 
					  email: "",
 | 
				
			||||||
  password: "",
 | 
					  password: "",
 | 
				
			||||||
  passwordConfirmation: ""
 | 
					  passwordConfirmation: "",
 | 
				
			||||||
 | 
					  emailVerificationString: ""
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function authReducer(state = initialState, action) {
 | 
					function authReducer(state = initialState, action) {
 | 
				
			||||||
@@ -47,6 +55,26 @@ function authReducer(state = initialState, action) {
 | 
				
			|||||||
        ...state,
 | 
					        ...state,
 | 
				
			||||||
        authRequestSuccess: ""
 | 
					        authRequestSuccess: ""
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
 | 
					    case SET_EMAIL_VERIFICATION_ERROR:
 | 
				
			||||||
 | 
					      return {
 | 
				
			||||||
 | 
					        ...state,
 | 
				
			||||||
 | 
					        emailVerificationRequestError: action.data
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					    case CLEAR_EMAIL_VERIFICATION_ERROR:
 | 
				
			||||||
 | 
					      return {
 | 
				
			||||||
 | 
					        ...state,
 | 
				
			||||||
 | 
					        emailVerificationRequestError: ""
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					    case SET_EMAIL_VERIFICATION_SUCCESS:
 | 
				
			||||||
 | 
					      return {
 | 
				
			||||||
 | 
					        ...state,
 | 
				
			||||||
 | 
					        emailVerificationRequestSuccess: action.data
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					    case CLEAR_EMAIL_VERIFICATION_SUCCESS:
 | 
				
			||||||
 | 
					      return {
 | 
				
			||||||
 | 
					        ...state,
 | 
				
			||||||
 | 
					        emailVerificationRequestSuccess: ""
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
    case SET_SELF_USER:
 | 
					    case SET_SELF_USER:
 | 
				
			||||||
      return {
 | 
					      return {
 | 
				
			||||||
        ...state,
 | 
					        ...state,
 | 
				
			||||||
@@ -67,6 +95,11 @@ function authReducer(state = initialState, action) {
 | 
				
			|||||||
        ...state,
 | 
					        ...state,
 | 
				
			||||||
        passwordConfirmation: action.data
 | 
					        passwordConfirmation: action.data
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
 | 
					    case SET_FORM_EMAIL_VERIFICATION:
 | 
				
			||||||
 | 
					      return {
 | 
				
			||||||
 | 
					        ...state,
 | 
				
			||||||
 | 
					        emailVerificationString: action.data
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
      return state;
 | 
					      return state;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,17 +3,19 @@ import {
 | 
				
			|||||||
  isSendingAuthRequest,
 | 
					  isSendingAuthRequest,
 | 
				
			||||||
  setAuthRequestError,
 | 
					  setAuthRequestError,
 | 
				
			||||||
  setAuthRequestSuccess,
 | 
					  setAuthRequestSuccess,
 | 
				
			||||||
 | 
					  setEmailVerificationError,
 | 
				
			||||||
 | 
					  setEmailVerificationSuccess,
 | 
				
			||||||
  clearAuthRequestError,
 | 
					  clearAuthRequestError,
 | 
				
			||||||
 | 
					  clearEmailVerificationError,
 | 
				
			||||||
 | 
					  clearAuthRequestSuccess,
 | 
				
			||||||
 | 
					  clearEmailVerificationSuccess,
 | 
				
			||||||
  setFormEmail,
 | 
					  setFormEmail,
 | 
				
			||||||
  setFormPassword,
 | 
					  setFormPassword,
 | 
				
			||||||
  setFormPasswordConfirmation
 | 
					  setFormPasswordConfirmation,
 | 
				
			||||||
 | 
					  setFormEmailVerification
 | 
				
			||||||
} from "../actions/auth/reducer.actions";
 | 
					} from "../actions/auth/reducer.actions";
 | 
				
			||||||
import { registerUser } from "../api/auth.api";
 | 
					import { registerUser, verifyEmail } from "../api/auth.api";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Saga for registering a new user.
 | 
					 | 
				
			||||||
 * @param {*} postBody 
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
function* registerUserCall(postBody) {
 | 
					function* registerUserCall(postBody) {
 | 
				
			||||||
  yield effects.put(isSendingAuthRequest(true));
 | 
					  yield effects.put(isSendingAuthRequest(true));
 | 
				
			||||||
  const { email, password1, password2 } = postBody;
 | 
					  const { email, password1, password2 } = postBody;
 | 
				
			||||||
@@ -27,7 +29,22 @@ function* registerUserCall(postBody) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function* verifyEmailCall(postBody) {
 | 
				
			||||||
 | 
					  yield effects.put(isSendingAuthRequest(true));
 | 
				
			||||||
 | 
					  const { emailKey } = postBody;
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    return yield effects.call(verifyEmail, emailKey);
 | 
				
			||||||
 | 
					  } catch (exception) {
 | 
				
			||||||
 | 
					    yield effects.put(setEmailVerificationError(exception));
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					  } finally {
 | 
				
			||||||
 | 
					    yield effects.put(isSendingAuthRequest(false));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function* registerUserFlow(request) {
 | 
					export function* registerUserFlow(request) {
 | 
				
			||||||
 | 
					  yield effects.put(clearAuthRequestSuccess());
 | 
				
			||||||
 | 
					  yield effects.put(clearAuthRequestError());
 | 
				
			||||||
  const wasSucessful = yield effects.call(registerUserCall, request.data);
 | 
					  const wasSucessful = yield effects.call(registerUserCall, request.data);
 | 
				
			||||||
  if (wasSucessful) {
 | 
					  if (wasSucessful) {
 | 
				
			||||||
    yield effects.put(setAuthRequestSuccess(wasSucessful));
 | 
					    yield effects.put(setAuthRequestSuccess(wasSucessful));
 | 
				
			||||||
@@ -37,3 +54,14 @@ export function* registerUserFlow(request) {
 | 
				
			|||||||
    yield effects.put(setFormPasswordConfirmation(""));
 | 
					    yield effects.put(setFormPasswordConfirmation(""));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function* verifyEmailFlow(request) {
 | 
				
			||||||
 | 
					  yield effects.put(clearEmailVerificationSuccess());
 | 
				
			||||||
 | 
					  yield effects.put(clearEmailVerificationError());
 | 
				
			||||||
 | 
					  const wasSucessful = yield effects.call(verifyEmailCall, request.data);
 | 
				
			||||||
 | 
					  if (wasSucessful) {
 | 
				
			||||||
 | 
					    yield effects.put(setEmailVerificationSuccess(wasSucessful));
 | 
				
			||||||
 | 
					    yield effects.put(clearEmailVerificationError());
 | 
				
			||||||
 | 
					    yield effects.put(setFormEmailVerification(""));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,8 @@
 | 
				
			|||||||
import { takeLatest } from "redux-saga/effects";
 | 
					import { takeLatest } from "redux-saga/effects";
 | 
				
			||||||
import { SEND_REGISTER_REQUEST } from "../constants/auth.constants";
 | 
					import { SEND_REGISTER_REQUEST, SEND_EMAIL_VERIFICATION_REQUEST } from "../constants/auth.constants";
 | 
				
			||||||
import { registerUserFlow } from "./auth.sagas";
 | 
					import { registerUserFlow, verifyEmailFlow } from "./auth.sagas";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function* rootSaga() {
 | 
					export default function* rootSaga() {
 | 
				
			||||||
  yield takeLatest(SEND_REGISTER_REQUEST, registerUserFlow);
 | 
					  yield takeLatest(SEND_REGISTER_REQUEST, registerUserFlow);
 | 
				
			||||||
 | 
					  yield takeLatest(SEND_EMAIL_VERIFICATION_REQUEST, verifyEmailFlow);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user