Skip to content

Commit

Permalink
🔥 add auth state, twitter, github oauth and strict public routes
Browse files Browse the repository at this point in the history
  • Loading branch information
heytulsiprasad committed Sep 21, 2020
1 parent 429ddc8 commit 5a7f97e
Show file tree
Hide file tree
Showing 12 changed files with 223 additions and 66 deletions.
3 changes: 0 additions & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
"editor.formatOnType": true,
"editor.formatOnPaste": true,
"eslint.alwaysShowStatus": true,
"[javascript]": {
"editor.formatOnSave": false
},
"editor.codeActionsOnSave": {
"source.fixAll": true
},
Expand Down
81 changes: 63 additions & 18 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,75 @@
import React from "react";
import React, { useEffect, useState } from "react";
import axios from "axios";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import { Provider } from "react-redux";
import { connect } from "react-redux";

import "./App.css";
import SignupContainer from "./containers/SignupContainer";
import LoginContainer from "./containers/LoginContainer";
import PrivateRoute from "./containers/PrivateRoute";
import PublicRoute from "./containers/PublicRoute";
import Dashboard from "./containers/Dashboard";
import EditProfile from "./containers/EditProfile";
import store from "./redux/store";
// import store from "./redux/store";

import { setAuthState } from "./redux/actions/authActions";

const App = ({ isAuth, setAuthState }) => {
const [isLoading, setIsLoading] = useState(true);

useEffect(() => {
axios
.get("/auth/state", { withCredentials: true })
.then((res) => {
setAuthState(res.data);
setIsLoading(false);
})
.catch((err) => {
setIsLoading(true);
throw new Error(err);
});
}, []);

function App() {
return (
<Provider store={store}>
<>
<Router>
<Switch>
<PrivateRoute exact path="/" component={Dashboard} />
<PrivateRoute exact path="/edit" component={EditProfile} />
<Route exact path="/signup" component={SignupContainer} />
<Route exact path="/login" component={LoginContainer} />
</Switch>
</Router>
</>
</Provider>
<>
<Router>
<Switch>
<PrivateRoute
exact
path="/"
isLoading={isLoading}
isAuthenticated={isAuth}
component={Dashboard}
/>
<PrivateRoute
exact
path="/edit"
isLoading={isLoading}
isAuthenticated={isAuth}
component={EditProfile}
/>
<PublicRoute
exact
isLoading={isLoading}
isAuthenticated={isAuth}
path="/signup"
component={SignupContainer}
/>
<PublicRoute
exact
isLoading={isLoading}
isAuthenticated={isAuth}
path="/login"
component={LoginContainer}
/>
</Switch>
</Router>
</>
);
}
};

const mapStateToProps = (state) => ({
isAuth: state.auth.isAuthenticated,
});

export default App;
export default connect(mapStateToProps, { setAuthState })(App);
2 changes: 0 additions & 2 deletions src/components/Profile/Dropdown.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import styled from "styled-components";
import { withRouter } from "react-router-dom";
import PropTypes from "prop-types";

import Person from "../../assets/person.jpg";

const Container = styled.div`
position: relative;
user-select: none;
Expand Down
3 changes: 2 additions & 1 deletion src/containers/LoginContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from "react";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import styled from "styled-components";
import { withRouter } from "react-router-dom";

import CenterBox from "../components/CenterBox";
import LogoBox from "../components/LogoBox";
Expand Down Expand Up @@ -91,5 +92,5 @@ const mapStateToProps = (state) => ({
});

export default connect(mapStateToProps, { loginUser, clearErrors })(
LoginContainer
withRouter(LoginContainer)
);
54 changes: 20 additions & 34 deletions src/containers/PrivateRoute.jsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,31 @@
/* eslint-disable no-nested-ternary */
/* eslint-disable implicit-arrow-linebreak */

import React, { useState, useEffect } from "react";
import React from "react";
import { Route, Redirect } from "react-router-dom";
import axios from "axios";
import PropTypes from "prop-types";

import Loading from "../components/Loading";

const PrivateRoute = ({ component: Component, ...rest }) => {
const [isAuthenticated, setIsAuthenticated] = useState(false);
const [isLoading, setIsLoading] = useState(true);

useEffect(() => {
axios
.get("/auth/state", { withCredentials: true })
.then((res) => {
setIsAuthenticated(res.data);
setIsLoading(false);
})
.catch((err) => {
setIsLoading(true);
throw new Error(err);
});
}, []);

return (
<Route
{...rest}
render={(props) =>
isLoading ? (
<Loading />
) : isAuthenticated ? (
<Component {...props} />
) : (
<Redirect to="/login" />
)
}
/>
);
};
const PrivateRoute = ({
component: Component,
isLoading,
isAuthenticated,
...rest
}) => (
<Route
{...rest}
render={(props) =>
isLoading ? (
<Loading />
) : isAuthenticated ? (
<Component {...props} />
) : (
<Redirect to="/login" />
)
}
/>
);

PrivateRoute.propTypes = {
component: PropTypes.oneOfType([PropTypes.object, PropTypes.func]).isRequired,
Expand Down
34 changes: 34 additions & 0 deletions src/containers/PublicRoute.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/* eslint-disable no-nested-ternary */
/* eslint-disable implicit-arrow-linebreak */

import React from "react";
import { Route, Redirect } from "react-router-dom";
import PropTypes from "prop-types";

import Loading from "../components/Loading";

const PublicRoute = ({
component: Component,
isLoading,
isAuthenticated,
...rest
}) => (
<Route
{...rest}
render={(props) =>
isLoading ? (
<Loading />
) : !isAuthenticated ? (
<Component {...props} />
) : (
<Redirect to="/" />
)
}
/>
);

PublicRoute.propTypes = {
component: PropTypes.oneOfType([PropTypes.object, PropTypes.func]).isRequired,
};

export default PublicRoute;
3 changes: 2 additions & 1 deletion src/containers/SignupContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from "react";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import styled from "styled-components";
import { withRouter } from "react-router-dom";

import CenterBox from "../components/CenterBox";
import LogoBox from "../components/LogoBox";
Expand Down Expand Up @@ -93,5 +94,5 @@ const mapStateToProps = (state) => ({
});

export default connect(mapStateToProps, { registerUser, clearErrors })(
SignupContainer
withRouter(SignupContainer)
);
11 changes: 10 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";

import store from "./redux/store";

import App from "./App";

ReactDOM.render(<App />, document.getElementById("root"));
const Index = () => (
<Provider store={store}>
<App />
</Provider>
);

ReactDOM.render(<Index />, document.getElementById("root"));
70 changes: 67 additions & 3 deletions src/redux/actions/authActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
GET_ERRORS,
CLEAR_ERRORS,
CLEAR_CURRENT_USER,
SET_AUTH_STATE,
} from "./types";

export const setCurrentUser = (newUser) => ({
Expand All @@ -28,7 +29,32 @@ export const registerUser = (userData, history) => (dispatch) => {

axios
.post("/auth/signup", userData)
.then(() => {
.then((res) => {
// console.log(res);

const {
name,
bio,
phone,
local,
google,
facebook,
email,
image,
} = res.data.user;

const user = {
name,
email,
bio,
phone,
image,
local: local[0],
google: google[0],
facebook: facebook[0],
};

dispatch(setCurrentUser(user));
history.push("/");
})
.catch((err) => {
Expand All @@ -43,7 +69,31 @@ export const loginUser = (userData, history) => (dispatch) => {

axios
.post("/auth/login", userData)
.then(() => {
.then((res) => {
const {
name,
bio,
phone,
local,
google,
facebook,
email,
image,
} = res.data.user;

const user = {
name,
email,
bio,
phone,
image,
local: local[0],
google: google[0],
facebook: facebook[0],
};

dispatch(setCurrentUser(user));

history.push("/");
})
.catch((err) => {
Expand All @@ -57,7 +107,14 @@ export const fetchUserProfile = (callback) => (dispatch) => {
.get("/profile", { withCredentials: true })
.then((res) => {
const {
name, bio, phone, local, google, facebook, email, image,
name,
bio,
phone,
local,
google,
facebook,
email,
image,
} = res.data;

const user = {
Expand All @@ -81,6 +138,9 @@ export const fetchUserProfile = (callback) => (dispatch) => {

// Edit user profile
export const editUserProfile = (userdata, history) => (dispatch) => {
// Clear previous errors
dispatch(clearErrors());

axios
.post("/profile/edit", userdata, { withCredentials: true })
.then(() => history.push("/"))
Expand All @@ -103,3 +163,7 @@ export const logoutUser = (history) => (dispatch) => {
throw new Error(err);
});
};

export const setAuthState = (isAuth) => (dispatch) => {
dispatch({ type: SET_AUTH_STATE, payload: isAuth });
};
3 changes: 1 addition & 2 deletions src/redux/actions/types.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
export const SET_CURRENT_USER = "SET_CURRENT_USER";
export const CLEAR_CURRENT_USER = "CLEAR_CURRENT_USER";
export const USER_LOADING = "USER_LOADING";

export const SET_AUTH_STATE = "SET_AUTH_STATE";
export const EDIT_USER = "EDIT_USER";
export const DELETE_USER = "DELETE_USER";
export const SET_AUTH_STATE = "SET_AUTH_STATE";

export const GET_ERRORS = "GET_ERRORS";
export const CLEAR_ERRORS = "CLEAR_ERRORS";
Loading

0 comments on commit 5a7f97e

Please sign in to comment.