Login endpoint now returns the user profile.

This commit is contained in:
Harrison Deng 2022-04-06 22:53:20 -05:00
parent f98b003808
commit b575fc7fde
8 changed files with 51 additions and 30 deletions

View File

@ -1,6 +1,6 @@
import "./styles/Layout.css"; import "./styles/Layout.css";
import "./styles/extra.css"; import "./styles/extra.css";
import { useContext } from "react"; import { useEffect, useState } from "react";
import { NavLink, Route, Routes, useNavigate } from "react-router-dom"; import { NavLink, Route, Routes, useNavigate } from "react-router-dom";
import Welcome from "./pages/Welcome"; import Welcome from "./pages/Welcome";
import Navbar from "react-bootstrap/Navbar"; import Navbar from "react-bootstrap/Navbar";
@ -8,14 +8,22 @@ import { Container, Nav, NavbarBrand } from "react-bootstrap";
import NavbarToggle from "react-bootstrap/esm/NavbarToggle"; import NavbarToggle from "react-bootstrap/esm/NavbarToggle";
import NavbarCollapse from "react-bootstrap/esm/NavbarCollapse"; import NavbarCollapse from "react-bootstrap/esm/NavbarCollapse";
import Dashboard from "./pages/Dashboard"; import Dashboard from "./pages/Dashboard";
import Logout from "./pages/Logout";
import Login from "./pages/Login"; import Login from "./pages/Login";
import { globalContext } from "./context.js"; import Context from "./globals.js";
export default function layout() { export default function layout() {
const navigate = useNavigate(); const [state, setState] = useState({
user: null,
setUser: setUser,
navigate: useNavigate()
});
function setUser(user) {
setState({ user: user });
}
const context = useContext(globalContext);
let identityDisplay = ( let identityDisplay = (
<Nav> <Nav>
<li className="nav-item"> <li className="nav-item">
@ -27,11 +35,11 @@ export default function layout() {
</Nav> </Nav>
); );
if (context.user) { if (state.user) {
identityDisplay = ( identityDisplay = (
<Nav> <Nav>
<li className="nav-item"> <li className="nav-item">
<NavLink className="nav-link" to="/" >Hi, {this.state.user.firstName}</NavLink> <NavLink className="nav-link" to="/" >Hi, {state.user.firstName}</NavLink>
</li> </li>
<li className="nav-item"> <li className="nav-item">
<NavLink className="nav-link" to="/logout" >Logout</NavLink> <NavLink className="nav-link" to="/logout" >Logout</NavLink>
@ -42,7 +50,7 @@ export default function layout() {
return ( return (
<div id="app"> <div id="app">
<globalContext.Provider value={{ navigate: navigate, user: null }}> <Context.Provider value={state}>
<header> <header>
<Navbar bg="light" expand="md"> <Navbar bg="light" expand="md">
<Container> <Container>
@ -64,12 +72,13 @@ export default function layout() {
<Route path="/" element={<Welcome />} /> <Route path="/" element={<Welcome />} />
<Route path="/dashboard" element={<Dashboard />} /> <Route path="/dashboard" element={<Dashboard />} />
<Route path="/login" element={<Login />} /> <Route path="/login" element={<Login />} />
<Route path="/logout" element={<Logout />} />
</Routes> </Routes>
</main> </main>
<footer> <footer>
</footer> </footer>
</globalContext.Provider> </Context.Provider>
</div> </div>
); );
} }

View File

@ -1,30 +1,34 @@
import React from "react"; import React from "react";
import { Navigate } from "react-router-dom"; import { Navigate } from "react-router-dom";
import { globalContext } from "../context"; import context from "../globals";
import { apiClient } from "../utils/httpClients"; import { apiClient } from "../utils/httpClients";
export default class AuthenticationGuard extends React.Component { export default class AuthenticationGuard extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
} }
static contextType = context;
async componentDidMount() { async componentDidMount() {
if (!this.context.user) { if (!this.context.user) {
let userDataResponse = await apiClient.get("/user/"); let userDataResponse = await apiClient.get("/user/");
if (userDataResponse.status === 200) { if (userDataResponse.status === 200) {
this.context.user = userDataResponse.data; this.context.setUser(userDataResponse.data);
} }
} }
} }
static contextType = globalContext;
render() { render() {
if (!this.context.user) { return (
return ( <context.Consumer>
<Navigate to="/signup" replace="true" /> {val => {
); if (!val.user) {
} console.log(val);
return; return <Navigate to="/signup" replace="true" />;
}
}}
</context.Consumer>
);
} }
} }

View File

@ -1,3 +0,0 @@
import React from "react";
export const globalContext = React.createContext({});

View File

@ -0,0 +1,7 @@
import React from "react";
export default React.createContext({
user: null,
setUser: () => { },
navigate: () => { }
});

View File

@ -4,8 +4,8 @@ import "../styles/Dashboard.css";
import { apiClient } from "../utils/httpClients.js"; import { apiClient } from "../utils/httpClients.js";
import MatchInfoCardDisplay from "../components/MatchInfoCardDisplay"; import MatchInfoCardDisplay from "../components/MatchInfoCardDisplay";
import SportInfoCardDisplay from "../components/SportInfoCardDisplay"; import SportInfoCardDisplay from "../components/SportInfoCardDisplay";
import { globalContext } from "../context";
import AuthenticationGuard from "../components/AuthenticationGuard"; import AuthenticationGuard from "../components/AuthenticationGuard";
import context from "../globals";
export default class Dashboard extends React.Component { export default class Dashboard extends React.Component {
constructor(props) { constructor(props) {
@ -18,7 +18,7 @@ export default class Dashboard extends React.Component {
}; };
} }
static contextType = globalContext; static contextType = context;
async componentDidMount() { async componentDidMount() {
this.setState({ user: this.context.user }); this.setState({ user: this.context.user });

View File

@ -1,8 +1,7 @@
import React from "react"; import React from "react";
import { Alert, Button, Card, Container, Form } from "react-bootstrap"; import { Alert, Button, Card, Container, Form } from "react-bootstrap";
import { globalContext } from "../context"; import context from "../globals";
import { apiClient } from "../utils/httpClients"; import { apiClient } from "../utils/httpClients";
import AuthenticationGuard from "../components/AuthenticationGuard";
export default class Login extends React.Component { export default class Login extends React.Component {
constructor(props) { constructor(props) {
@ -16,7 +15,7 @@ export default class Login extends React.Component {
this.attemptLogin = this.attemptLogin.bind(this); this.attemptLogin = this.attemptLogin.bind(this);
} }
static contextType = globalContext; static contextType = context;
async componentDidMount() { async componentDidMount() {
} }
@ -32,6 +31,7 @@ export default class Login extends React.Component {
} }
}); });
if (loginResponse.status === 200) { if (loginResponse.status === 200) {
this.context.user = loginResponse.data;
this.context.navigate("/dashboard", { replace: true }); this.context.navigate("/dashboard", { replace: true });
} else if (loginResponse.status === 401) { } else if (loginResponse.status === 401) {
this.setState({ errorDisplayed: true }); this.setState({ errorDisplayed: true });

View File

@ -1,5 +1,5 @@
import React from "react"; import React from "react";
import { useNavigate } from "react-router-dom"; import globals from "../globals";
import { apiClient } from "../utils/httpClients"; import { apiClient } from "../utils/httpClients";
export default class Logout extends React.Component { export default class Logout extends React.Component {
@ -7,16 +7,19 @@ export default class Logout extends React.Component {
super(props); super(props);
} }
static contextType = globals;
async componentDidMount() { async componentDidMount() {
const logoutResponse = await apiClient.get("/user/logout"); const logoutResponse = await apiClient.get("/user/logout");
let navigation = useNavigate();
if (logoutResponse.status === 401) { if (logoutResponse.status === 401) {
navigation("/dashboard", { replace: true }); globals.navigate("/dashboard", { replace: true });
} else { } else {
this.redirectTimer = setTimeout(() => { this.redirectTimer = setTimeout(() => {
navigation("/", { replace: true }); globals.navigate("/", { replace: true });
}, 2000); }, 2000);
} }
globals.setUser(null);
} }
async componentWillUnmount() { async componentWillUnmount() {

View File

@ -16,7 +16,8 @@ UserController.post("/login", needDatabase, async (req, res) => {
} else { } else {
req.session.userId = user._id; req.session.userId = user._id;
req.session.email = user.email; req.session.email = user.email;
res.status(200).send("Authenticated."); user.password = undefined;
res.status(200).send(user);
} }
} catch (error) { } catch (error) {
if (error.name === "TypeError") { if (error.name === "TypeError") {