From c450da53c3130461b64c2de443f5ba8b27b31874 Mon Sep 17 00:00:00 2001 From: Essam Date: Sun, 29 Mar 2020 23:38:24 +0300 Subject: [PATCH 01/10] Authentication Done --- src/components/Navigation/AuthButton.js | 20 +++++--- src/components/RegistrationForm.js | 18 ++++++- src/components/Welcome.js | 34 ++++++++----- src/redux/actions/actionTypes.js | 1 + src/redux/actions/authentication.js | 66 ++++++++++++++++++++++--- src/redux/index.js | 2 + src/redux/reducers/user.js | 8 +-- 7 files changed, 116 insertions(+), 33 deletions(-) diff --git a/src/components/Navigation/AuthButton.js b/src/components/Navigation/AuthButton.js index 2002d2ef..6c361620 100644 --- a/src/components/Navigation/AuthButton.js +++ b/src/components/Navigation/AuthButton.js @@ -1,6 +1,7 @@ import React from "react"; import { Link } from "react-router-dom"; import { connect } from "react-redux"; +import { logout } from "./../../redux/actions/authentication"; // Fontawesome import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; @@ -10,7 +11,7 @@ import { faUserPlus } from "@fortawesome/free-solid-svg-icons"; -const AuthButton = ({ user }) => { +const AuthButton = ({ user, logout }) => { let buttons = [
  • @@ -27,16 +28,15 @@ const AuthButton = ({ user }) => { if (user) { buttons = ( <> - {user.username} -
  • - + +
  • + Logout - +
  • ); } - return ; }; @@ -44,4 +44,10 @@ const mapStateToProps = ({ user }) => ({ user }); -export default connect(mapStateToProps)(AuthButton); +const mapDispatchToProps = dispatch => { + return { + logout: () => dispatch(logout()) + }; +}; + +export default connect(mapStateToProps, mapDispatchToProps)(AuthButton); diff --git a/src/components/RegistrationForm.js b/src/components/RegistrationForm.js index 3630c5a6..90b52322 100644 --- a/src/components/RegistrationForm.js +++ b/src/components/RegistrationForm.js @@ -1,5 +1,7 @@ import React, { Component } from "react"; import { Link } from "react-router-dom"; +import { signup, login } from "../redux/actions/authentication"; +import { connect } from "react-redux"; class RegistationForm extends Component { state = { @@ -13,11 +15,17 @@ class RegistationForm extends Component { submitHandler = e => { e.preventDefault(); - alert("I don't work yet"); + const type = this.props.match.url.substring(1); + if (type === "login") { + this.props.login(this.state, this.props.history); + } else { + this.props.signup(this.state, this.props.history); + } }; render() { const type = this.props.match.url.substring(1); + return (
    @@ -66,5 +74,11 @@ class RegistationForm extends Component { ); } } +const mapDispatchToProps = dispatch => { + return { + signup: (userData, history) => dispatch(signup(userData, history)), + login: (userData, history) => dispatch(login(userData, history)) + }; +}; -export default RegistationForm; +export default connect(null, mapDispatchToProps)(RegistationForm); diff --git a/src/components/Welcome.js b/src/components/Welcome.js index d234bf93..c21f5ad6 100644 --- a/src/components/Welcome.js +++ b/src/components/Welcome.js @@ -1,19 +1,27 @@ import React from "react"; import { Link } from "react-router-dom"; +import { connect } from "react-redux"; -const Welcome = () => ( +const Welcome = ({ user }) => (
    -
    -

    WELCOME TO CHATR

    -

    - You're gonna need to login to see the messages -

    - - Login - -
    -
    + {!user ? ( +
    +
    + + Login + +
    + ) : ( +
    +

    WELCOME TO CHATR

    +

    + You're gonna need to login to see the messages +

    +
    + )}
    ); - -export default Welcome; +const mapStateToProps = ({ user }) => ({ + user +}); +export default connect(mapStateToProps)(Welcome); diff --git a/src/redux/actions/actionTypes.js b/src/redux/actions/actionTypes.js index 9f974506..14fa711f 100644 --- a/src/redux/actions/actionTypes.js +++ b/src/redux/actions/actionTypes.js @@ -1,2 +1,3 @@ export const SET_CURRENT_USER = "SET_CURRENT_USER"; export const SET_ERRORS = "SET_ERRORS"; +export const POST_FORM = "POST_FORM" diff --git a/src/redux/actions/authentication.js b/src/redux/actions/authentication.js index 8f5d95aa..b22c949f 100644 --- a/src/redux/actions/authentication.js +++ b/src/redux/actions/authentication.js @@ -1,17 +1,69 @@ import jwt_decode from "jwt-decode"; +import { SET_CURRENT_USER } from "./actionTypes"; + import instance from "./instance"; -import {} from "./actionTypes"; +export const checkForExpiredToken = () => { + return dispatch => { + const token = localStorage.getItem("token"); + + if (token) { + const currentTime = Date.now() / 1000; + + const user = jwt_decode(token); + if (user.exp >= currentTime) { + dispatch(setCurrentUser(user)); + } else { + logout(); + } + } + }; +}; -import { setErrors } from "./errors"; +const setAuthToken = token => { + if (token) { + instance.defaults.headers.common.Authorization = `jwt ${token}`; + localStorage.setItem("token", token); + } else { + delete instance.defaults.headers.common.Authorization; + localStorage.removeItem("token"); + } +}; -export const checkForExpiredToken = () => {}; +const setCurrentUser = user => ({ + type: SET_CURRENT_USER, + payload: user +}); -export const login = userData => {}; +export const login = (userData, history) => async dispatch => { + try { + const res = await instance.post("/login/", userData); + const { token } = res.data; -export const signup = userData => {}; + const decodeUser = jwt_decode(token); + setAuthToken(token); + dispatch(setCurrentUser(decodeUser)); + history.push("/welcome"); + } catch (error) { + console.error(error.response.data); + } +}; -export const logout = () => {}; +export const signup = (userData, history) => async dispatch => { + try { + const res = await instance.post("/signup/", userData); + const { token } = res.data; + const decodeUser = jwt_decode(token); + setAuthToken(token); + dispatch(setCurrentUser(decodeUser)); + history.push("/welcome"); + } catch (error) { + console.error(error.response.data); + } +}; -const setCurrentUser = token => {}; +export const logout = () => { + setAuthToken(null); + return setCurrentUser(null); +}; diff --git a/src/redux/index.js b/src/redux/index.js index 27f95988..4787951b 100644 --- a/src/redux/index.js +++ b/src/redux/index.js @@ -1,4 +1,5 @@ import { createStore, compose, applyMiddleware } from "redux"; +import { checkForExpiredToken } from "./actions/authentication"; import thunk from "redux-thunk"; import rootReducer from "./reducers"; @@ -9,5 +10,6 @@ const store = createStore( rootReducer, composeEnhancers(applyMiddleware(thunk)) ); +store.dispatch(checkForExpiredToken()); export default store; diff --git a/src/redux/reducers/user.js b/src/redux/reducers/user.js index 76dce641..cd06f623 100644 --- a/src/redux/reducers/user.js +++ b/src/redux/reducers/user.js @@ -2,11 +2,11 @@ import { SET_CURRENT_USER } from "../actions/actionTypes"; const initialState = null; -const reducer = (state = initialState, { type, payload }) => { - switch (type) { +const reducer = (state = initialState, action) => { + switch (action.type) { case SET_CURRENT_USER: - const user = payload; - return user; + return action.payload; + default: return state; } From 820681870a5d5c713ce011a32d6655220783dee7 Mon Sep 17 00:00:00 2001 From: Essam Date: Mon, 30 Mar 2020 22:48:34 +0300 Subject: [PATCH 02/10] Errors Updated --- src/components/Footer.js | 1 + src/components/Navigation/AuthButton.js | 2 +- src/components/RegistrationForm.js | 39 +++++++++++------ src/components/Welcome.js | 56 +++++++++++++++++-------- src/redux/actions/authentication.js | 34 +++++++-------- src/redux/actions/errors.js | 1 + src/redux/actions/index.js | 3 +- src/redux/reducers/errors.js | 1 + 8 files changed, 89 insertions(+), 48 deletions(-) diff --git a/src/components/Footer.js b/src/components/Footer.js index bcc84234..4f7407af 100644 --- a/src/components/Footer.js +++ b/src/components/Footer.js @@ -4,6 +4,7 @@ const Footer = () => (