-
Available Matches
-
+
+
+
+
+
+
+
+
+
+
Available Matches
+
+
+
+
Available Sports
+
+
+
-
-
Available Sports
-
-
-
-
-
+
);
}
}
\ No newline at end of file
diff --git a/sports-matcher/client/src/pages/Login.js b/sports-matcher/client/src/pages/Login.js
index 526852e..3a8d265 100644
--- a/sports-matcher/client/src/pages/Login.js
+++ b/sports-matcher/client/src/pages/Login.js
@@ -1,8 +1,7 @@
import React from "react";
import { Alert, Button, Card, Container, Form } from "react-bootstrap";
-import { globalContext } from "../context";
+import globals from "../globals";
import { apiClient } from "../utils/httpClients";
-import { guard } from "../utils/routing";
export default class Login extends React.Component {
constructor(props) {
@@ -16,16 +15,14 @@ export default class Login extends React.Component {
this.attemptLogin = this.attemptLogin.bind(this);
}
- static contextType = globalContext;
+ static contextType = globals;
async componentDidMount() {
- try {
- const getUserResponse = await apiClient.get("/user");
- guard(this.context.navigate, () => getUserResponse.status === 401, "/dashboard"); // If it's not 401, then we redirect to dashboard.
- } catch (error) {
- if (error.message !== "Request failed with status code 401") {
- throw error;
- }
+ }
+
+ componentDidUpdate() {
+ if (this.context.user) {
+ this.context.navigate("/dashboard");
}
}
@@ -34,13 +31,9 @@ export default class Login extends React.Component {
const loginResponse = await apiClient.post("/user/login", {
email: this.state.email,
password: this.state.password,
- }, {
- validateStatus: function (status) {
- return status === 200 || status === 401 || status === 400;
- }
});
if (loginResponse.status === 200) {
- this.context.navigate("/dashboard", { replace: true });
+ this.context.update({ user: loginResponse.data });
} else if (loginResponse.status === 401) {
this.setState({ errorDisplayed: true });
}
diff --git a/sports-matcher/client/src/pages/Logout.js b/sports-matcher/client/src/pages/Logout.js
index 517d95c..b9e098c 100644
--- a/sports-matcher/client/src/pages/Logout.js
+++ b/sports-matcher/client/src/pages/Logout.js
@@ -1,5 +1,5 @@
import React from "react";
-import { useNavigate } from "react-router-dom";
+import globals from "../globals";
import { apiClient } from "../utils/httpClients";
export default class Logout extends React.Component {
@@ -7,19 +7,22 @@ export default class Logout extends React.Component {
super(props);
}
+ static contextType = globals;
+
async componentDidMount() {
const logoutResponse = await apiClient.get("/user/logout");
- let navigation = useNavigate();
- if (logoutResponse.status === 401) {
- navigation("/dashboard", { replace: true });
- } else {
+ if (logoutResponse.status === 200) {
this.redirectTimer = setTimeout(() => {
- navigation("/", { replace: true });
+ this.context.navigate("/", { replace: true });
}, 2000);
+ } else if (logoutResponse.status == 401) {
+ this.context.navigate("/", { replace: true });
}
+
+ this.context.update({ user: null });
}
- async componentWillUnmount() {
+ componentWillUnmount() {
clearTimeout(this.redirectTimer);
}
diff --git a/sports-matcher/client/src/pages/Profile.js b/sports-matcher/client/src/pages/Profile.js
new file mode 100644
index 0000000..e7c6433
--- /dev/null
+++ b/sports-matcher/client/src/pages/Profile.js
@@ -0,0 +1,14 @@
+import React from "react";
+import { Container } from "react-bootstrap";
+
+export default class Profile extends React.Component {
+ render() {
+ return (
+
+
+
+
+
+ );
+ }
+}
\ No newline at end of file
diff --git a/sports-matcher/client/src/pages/Rentals.js b/sports-matcher/client/src/pages/Rentals.js
new file mode 100644
index 0000000..abfe5ad
--- /dev/null
+++ b/sports-matcher/client/src/pages/Rentals.js
@@ -0,0 +1,89 @@
+import React from "react";
+import { Button, InputGroup, FormControl } from "react-bootstrap";
+import "../styles/Dashboard.css";
+// import { apiClient } from "../utils/httpClients.js";
+// import MatchInfoCardDisplay from "../components/MatchInfoCardDisplay";
+// import SportInfoCardDisplay from "../components/SportInfoCardDisplay";
+import RentalInfoCard from "../components/RentalInfoCard";
+// import AuthenticationGuard from "../components/AuthenticationGuard";
+// import globals from "../globals";
+
+export default class Rentals extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ rentals: [
+ { id: 9, creator: "Person5", createDate: "05/21/2022", title: "Horse", rate: "$1000/day", description: "This is an amazing horse, has won many races", contact: "647 765 1234" },
+ { id: 7, creator: "Person1", createDate: "05/05/2022", title: "Tennis Racquet", rate: "$300/day", description: "This is an amazing tennis racquet, used by Roger Federer to win Wimbledon in 2003", contact: "123 456 7890" },
+ { id: 3, creator: "Person2", createDate: "05/11/2022", title: "Soccer Ball", rate: "$70/day", description: "This is an amazing soccer ball, signed by Messi", contact: "647 822 4321" },
+ { id: 2, creator: "Person3", createDate: "05/13/2022", title: "Basket Ball", rate: "$7/day", description: "This is an amazing basketball, same model as the ones used in the NBA", contact: "467 279 4321" },
+ { id: 1, creator: "Person4", createDate: "05/18/2022", title: "Table Tennis Racquet", rate: "$7/day", description: "This is an amazing table tennis racquet, it's very good", contact: "326 111 4321" },
+
+ ]
+ };
+ }
+
+ // static contextType = globals;
+
+ // async componentDidMount() {
+ // this.setState({ user: this.context.user });
+ // await this.latestMatches();
+ // await this.availableSports();
+ // }
+ // async latestMatches() {
+ // let recentMatchesRes = await apiClient.get("/match/recent/user/15");
+ // if (recentMatchesRes.status === 200) {
+ // this.setState({ displayedMatches: recentMatchesRes.data.recent });
+ // }
+ // }
+
+ // async availableSports() {
+ // let availableSportsRes = await apiClient.get("/sport");
+ // if (availableSportsRes.status === 200) {
+ // this.setState({ displayedSports: availableSportsRes.data });
+ // }
+ // }
+
+ // renderRentals() {
+ // let matches = null;
+ // if (this.props.recommendedmatches.length > 0) {
+ // matches = this.props.recommendedmatches.map((match) =>
);
+ // }
+ // return (
+ //
+ // {matches}
+ //
+ // );
+ // }
+
+ rentalsCards() {
+ return this.state.rentals.map((rental) => {
+ return (
);
+ });
+ }
+
+ render() {
+ return (
+
+
+
+
+
+
+
+
+
+
Available Rentals
+ {this.rentalsCards()}
+
+
+
+ );
+ }
+}
\ No newline at end of file
diff --git a/sports-matcher/client/src/pages/SIgnup.js b/sports-matcher/client/src/pages/SIgnup.js
deleted file mode 100644
index c603579..0000000
--- a/sports-matcher/client/src/pages/SIgnup.js
+++ /dev/null
@@ -1,88 +0,0 @@
-import React from "react";
-import { Button, Card, Form } from "react-bootstrap";
-import { apiClient } from "../utils/httpClients";
-import { guard } from "../utils/routing";
-
-export default class Signup extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- user: null,
- alertShow: false,
- alertKey: null,
- alertMsg: null
- }
- this.state.user = {
- email: null,
- firstName: null,
- lastName: null,
- phone: null,
- password: null
- }
- }
-
- async registerUser() {
- const res = await apiClient.post("/user", this.state);
- if (res.status === 200) {
- this.warnUser("You are successfully signed up!", "success")
- } else if (res === 409) {
- this.warnUser("This user already exists. Try logging in instead.", "danger")
- } else if (res === 400) {
- this.warnUser("Missing required fields.", "danger")
- } else {
- this.warnUser("Internal server error. Please try again later.", "danger")
- }
- }
-
- setUserState(event) {
- newUser = this.state.user;
- newUser[event.target.controlId] = event.target.value
- this.setState({user: newUser})
- }
-
- warnUser(msg, key) {
- this.setState({alertMsg: msg})
- this.setState({show: true})
- }
-
- render() {
- return (
-
-
- {this.state.alertMsg}
-
-
-
- Login
- Welcome to Sports Matcher!
-
- First name
-
-
-
- Last name
-
-
-
- E-mail
-
-
-
- Phone number
-
-
-
- Password
-
-
-
-
-
-
-
- );
- }
-}
diff --git a/sports-matcher/client/src/pages/Signup.js b/sports-matcher/client/src/pages/Signup.js
new file mode 100644
index 0000000..b5fa2b0
--- /dev/null
+++ b/sports-matcher/client/src/pages/Signup.js
@@ -0,0 +1,147 @@
+import React from "react";
+import { Alert, Button, Card, Container, Form } from "react-bootstrap";
+import { Link } from "react-router-dom";
+import validator from "validator";
+import globals from "../globals";
+import { apiClient } from "../utils/httpClients";
+
+export default class Signup extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ user: {
+ email: null,
+ firstName: null,
+ lastName: null,
+ phone: null,
+ password: null
+ },
+ alert: {
+ show: false,
+ variant: null,
+ headerMsg: null,
+ content: null
+ }
+ };
+
+ this.registerUser = this.registerUser.bind(this);
+ this.setUserState = this.setUserState.bind(this);
+ }
+
+ static contextType = globals;
+
+ async registerUser(event) {
+ event.preventDefault();
+ let formIssues = this.validateCurrentForm();
+ if (formIssues.length > 0) {
+ this.notifyUser("Oops there were issue(s)", (
+
+ {formIssues.map((issue) => {
+ return (
+ - {issue}
+ );
+ })}
+
+ ), "danger");
+ return;
+ }
+
+ const res = await apiClient.post("/user", this.state.user);
+ if (res.status === 201) {
+ this.notifyUser("Success!",
You are successfully signed up! You wil be directed to login now.
, "success");
+ this.redirectTimer = setTimeout(() => {
+ this.context.navigate("/signin", { replace: true });
+ }, 1000);
+ } else if (res.status === 409) {
+ this.notifyUser("User exists!",
This user already exists. Try logging in instead.
, "danger");
+ } else if (res.status === 400) {
+ this.notifyUser("There were errors in the submitted info.",
Double check to see if everything is inputted is valid.
, "danger");
+ } else {
+ this.notifyUser("Error",
Internal server error. Please try again later.
, "danger");
+ }
+ }
+
+ componentWillUnmount() {
+ clearTimeout(this.redirectTimer);
+ }
+
+ validateCurrentForm() {
+ let formIssues = [];
+ if (!validator.isEmail(this.state.user.email)) {
+ formIssues.push("The email submitted is invalid.");
+ }
+
+ if (this.state.user.password.length < 8) {
+ formIssues.push("The password submitted must have a minimum length of 8 characters.");
+ }
+
+ return formIssues;
+ }
+
+ setUserState(event) {
+ this.setState((state) => {
+ state.user[event.target.id] = event.target.value;
+ return state;
+ });
+ }
+
+ notifyUser(headerMsg, content, key) {
+ this.setState((state) => {
+ state.alert.show = true;
+ state.alert.headerMsg = headerMsg;
+ state.alert.content = content;
+ state.alert.key = key;
+ return state;
+ });
+ }
+
+ componentDidMount() {
+ if (this.context.user) {
+ this.context.navigate("/dashboard");
+ }
+ }
+
+ render() {
+ return (
+
+
+ this.setState((state) => { state.alert.show = false; return state; })} dismissible>
+ {this.state.alert.headerMsg}
+ {this.state.alert.content}
+
+
+
+ Sign up!
+ Welcome to Sports Matcher! Already have an account?
+
+ First name
+
+
+
+ Last name
+
+
+
+ E-mail
+
+
+
+ Phone number
+
+
+
+ Password
+
+
+
+
+
+
+
+
+ );
+ }
+}
diff --git a/sports-matcher/client/src/styles/Admin.css b/sports-matcher/client/src/styles/Admin.css
new file mode 100644
index 0000000..abbcc9b
--- /dev/null
+++ b/sports-matcher/client/src/styles/Admin.css
@@ -0,0 +1,15 @@
+
+.MainTable {
+ padding : 20px;
+}
+
+.center {
+ text-align: center;
+ padding: 21px;
+}
+
+
+.somespace {
+ padding: 17px;
+}
+
diff --git a/sports-matcher/client/src/utils/httpClients.js b/sports-matcher/client/src/utils/httpClients.js
index 6cff00c..4e2ddcc 100644
--- a/sports-matcher/client/src/utils/httpClients.js
+++ b/sports-matcher/client/src/utils/httpClients.js
@@ -1,10 +1,10 @@
import axios from "axios";
export const apiClient = axios.create({
- baseURL: process.env.REACT_APP_API_HOST || "" + "/api/",
+ baseURL: (process.env.REACT_APP_API_HOST || "") + "/api/",
timeout: 5000,
withCredentials: process.env.NODE_ENV === "development",
validateStatus: function (status) {
- return status === 401 || status == 200;
+ return status === 401 || status === 200 || status === 400 || status === 201;
}
});
\ No newline at end of file
diff --git a/sports-matcher/client/src/utils/routing.js b/sports-matcher/client/src/utils/routing.js
deleted file mode 100644
index 46caad9..0000000
--- a/sports-matcher/client/src/utils/routing.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import { apiClient } from "./httpClients";
-
-export function guard(navigator, evaluator, redirect, navigateOptions, onRedirect) {
- if (!evaluator) throw new Error("evaluator required.");
- if (!redirect) throw new Error("redirect required.");
- if (!navigateOptions) {
- navigateOptions = {
- replace: true
- };
- }
- let redirecting = !evaluator();
- if (redirecting) {
- if (onRedirect) onRedirect();
- navigator(redirect, navigateOptions);
- }
-}
-
-export async function needUser(navigator) {
- let userDataResponse = await apiClient.get("/user");
- guard(navigator, () => userDataResponse.status === 200, "/login");
- return userDataResponse.data;
-}
\ No newline at end of file
diff --git a/sports-matcher/server/.eslintrc.json b/sports-matcher/server/.eslintrc.json
index 0806fb5..e296e45 100644
--- a/sports-matcher/server/.eslintrc.json
+++ b/sports-matcher/server/.eslintrc.json
@@ -14,7 +14,7 @@
4
],
"linebreak-style": [
- "error",
+ "warn",
"unix"
],
"quotes": [
@@ -24,6 +24,7 @@
"semi": [
"error",
"always"
- ]
+ ],
+ "no-unused-vars": "warn"
}
}
\ No newline at end of file
diff --git a/sports-matcher/server/controllers/matchController.js b/sports-matcher/server/controllers/matchController.js
index 53cc013..6667744 100644
--- a/sports-matcher/server/controllers/matchController.js
+++ b/sports-matcher/server/controllers/matchController.js
@@ -1,5 +1,5 @@
import express from "express";
-import { requireAuthenticated } from "../middleware/authority.js";
+import { requireAdmin, requireAuthenticated } from "../middleware/authority.js";
import { needDatabase } from "../middleware/database.js";
import matchModel from "../schemas/matchModel.js";
import sportModel from "../schemas/sportModel.js";
@@ -27,17 +27,8 @@ MatchController.get("/search/:sport", needDatabase, async (req, res) => {
MatchController.get("/recent/:limit?", needDatabase, async (req, res) => {
try {
- let user = null;
- if (req.session.userId) {
- user = await userModel.findById(req.session.userId);
- }
let limit = parseInt(req.params.limit);
if (!req.params.limit) limit = 10;
- if (isNaN(limit)) {
- console.log(typeof (limit));
- res.status(400).send("Limit parameter is not a number.");
- return;
- }
if (isNaN(limit)) {
res.status(400).send("Limit parameter not a number.");
return;
@@ -46,18 +37,39 @@ MatchController.get("/recent/:limit?", needDatabase, async (req, res) => {
res.status(400).send("Limit greater than maximum limit of 50.");
return;
}
- let recent = null;
- if (user) {
- recent = matchModel.find({ creator: user._id });
- } else {
- recent = matchModel.find().where("publicity").gte(2);
- }
+ let recent = matchModel.find().where("publicity").gte(2);
recent = await recent.sort({ createDate: -1 }).limit(limit).populate(["sport", "participants"]);
res.status(200).send({ recent: recent });
} catch (error) {
console.error(error);
res.status(500).send("Internal server error.");
- // TODO: Check and improve error handling.
+ }
+});
+
+MatchController.get("/all", requireAdmin, async (req, res) => {
+ try {
+ const allmatches = await matchModel.find().populate("sport");
+ res.status(200).send({ all: allmatches });
+ } catch (error) {
+ console.error(error);
+ res.status(500).send("Internal server error.");
+ }
+});
+
+MatchController.get("/recent/user/:limit", needDatabase, requireAuthenticated, async (req, res) => {
+ try {
+ let user = req.user;
+ let limit = parseInt(req.params.limit);
+ if (!req.params.limit) limit = 10;
+ if (isNaN(limit)) {
+ res.status(400).send("Limit parameter not a number.");
+ return;
+ }
+ let recent = await matchModel.find({ creator: user._id }).sort({ createDate: -1 }).limit(limit).populate(["sport", "participants"]);
+ res.status(200).send({ recent: recent });
+ } catch (error) {
+ console.error(error);
+ res.status(500).send("Internal server error.");
}
});
diff --git a/sports-matcher/server/controllers/rentalController.js b/sports-matcher/server/controllers/rentalController.js
index 616c09b..b1b55c0 100644
--- a/sports-matcher/server/controllers/rentalController.js
+++ b/sports-matcher/server/controllers/rentalController.js
@@ -39,7 +39,6 @@ rentalController.get("/recent/:limit?", needDatabase, async (req, res) => {
let limit = parseInt(req.params.limit);
if (!req.params.limit) limit = 10;
if (isNaN(limit)) {
- console.log(typeof (limit));
res.status(400).send("Limit parameter is not a number.");
return;
}
diff --git a/sports-matcher/server/controllers/userController.js b/sports-matcher/server/controllers/userController.js
index 520b788..47029b3 100644
--- a/sports-matcher/server/controllers/userController.js
+++ b/sports-matcher/server/controllers/userController.js
@@ -1,5 +1,5 @@
import express from "express";
-import { requireAuthenticated } from "../middleware/authority.js";
+import { requireAdmin, requireAuthenticated } from "../middleware/authority.js";
import { needDatabase } from "../middleware/database.js";
import userModel from "../schemas/userModel.js";
import User from "../schemas/userModel.js";
@@ -16,7 +16,8 @@ UserController.post("/login", needDatabase, async (req, res) => {
} else {
req.session.userId = user._id;
req.session.email = user.email;
- res.status(200).send("Authenticated.");
+ user.password = undefined;
+ res.status(200).send(user);
}
} catch (error) {
if (error.name === "TypeError") {
@@ -66,50 +67,91 @@ UserController.get("/:id?", needDatabase, requireAuthenticated, async (req, res)
res.status(200).send(user);
});
+
UserController.patch("/:id?", needDatabase, requireAuthenticated, async (req, res) => {
- let user = null;
- if (req.params.id) {
- if (req.user.accessLevel > 2) {
- user = await userModel.findById(req.params.id);
+ try {
+ let user = null;
+ if (req.params.id) {
+ if (req.user.accessLevel > 2) {
+ user = await userModel.findById(req.params.id);
+ } else {
+ res.status(401).send("Unauthorized.");
+ return;
+ }
} else {
- res.status(401).send("Unauthorized.");
+ user = req.user;
+ }
+ if (req.body._id) {
+ res.status(400).send("Cannot change user ID.");
return;
}
- } else {
- user = req.user;
- }
- if (req.body._id) {
- res.status(400).send("Cannot change user ID.");
- return;
- }
- if (req.body.createdMatches) {
- res.status(400).send("Cannot directly change the list of created matches.");
- return;
- }
+ if (req.body.createdMatches) {
+ res.status(400).send("Cannot directly change the list of created matches.");
+ return;
+ }
- if (req.body.password) {
- res.status(400).send("Cannot directly change user password.");
- return;
- }
+ if (req.body.password) {
+ res.status(400).send("Cannot directly change user password.");
+ return;
+ }
- if (req.body.participatingMatches) {
- res.status(400).send("Cannot directly change the list of participating matches.");
- return;
- }
+ if (req.body.participatingMatches) {
+ res.status(400).send("Cannot directly change the list of participating matches.");
+ return;
+ }
- if (req.body.joinDate) {
- res.status(400).send("Cannot change the join date.");
- return;
- }
+ if (req.body.joinDate) {
+ res.status(400).send("Cannot change the join date.");
+ return;
+ }
- if (req.body.accessLevel && req.user.accessLevel < 3) {
- res.status(401).send("Unauthorized to change the access level of this user.");
- return;
- }
+ if (req.body.accessLevel && req.user.accessLevel < 3) {
+ res.status(401).send("Unauthorized to change the access level of this user.");
+ return;
+ }
- await user.updateOne(req.body);
- res.status(200).send("Updated.");
+ if (req.body.suspend && req.user.accessLevel < 3) {
+ res.status(401).send("Unauthorized to change the accounts disabled date. ");
+ return;
+ }
+
+ await user.updateOne(req.body);
+ res.status(200).send("Updated.");
+ } catch (error) {
+ console.error(error);
+ res.status(500).send("Internal server error");
+ }
+});
+
+UserController.get("/all", requireAdmin, async (req, res) => {
+ try {
+ let all = await userModel.find();
+ res.status(200).send({ all: all });
+ } catch (error) {
+ console.error(error);
+ res.status(500).send("Internal server error");
+ }
+});
+
+UserController.get("/all/active", requireAdmin, async (req, res) => {
+ try {
+ let active = await userModel.find().where("suspend").lt(Date.now());
+ res.status(200).send({ active: active });
+ } catch (error) {
+ console.error(error);
+ res.status(500).send("Internal server error");
+ }
+});
+
+UserController.get("/all/suspended", requireAuthenticated, async (req, res) => {
+ try {
+ let suspended = await userModel.find().where("suspend").gte(Date.now());
+ res.status(200).send({ suspended: suspended });
+ } catch (error) {
+ console.error(error);
+ res.status(500).send("Internal server error");
+ }
});
/* TODO: Implement middleware for removing users.
@@ -135,13 +177,15 @@ UserController.delete("/:id?", needDatabase, requireAuthenticated, async (req, r
UserController.post("/", needDatabase, async (req, res) => {
try {
- let createdUser = new User({
+ const data = {
email: req.body.email,
firstName: req.body.firstName,
lastName: req.body.lastName,
phone: req.body.phone,
password: req.body.password,
- });
+ };
+
+ let createdUser = new User(data);
await createdUser.save();
res.sendStatus(201);
return;
diff --git a/sports-matcher/server/middleware/authority.js b/sports-matcher/server/middleware/authority.js
index 9c09f66..f7ff1b5 100644
--- a/sports-matcher/server/middleware/authority.js
+++ b/sports-matcher/server/middleware/authority.js
@@ -2,6 +2,7 @@ import MongoStore from "connect-mongo";
import session from "express-session";
import { mongooseDbName, mongoURI } from "../database/mongoose.js";
import userModel from "../schemas/userModel.js";
+import { checkDatabaseConnection } from "./database.js";
const sessionConf = {
secret: process.env.SESSION_SECRET || "super duper secret string.",
cookie: {
@@ -18,6 +19,10 @@ if (process.env.NODE_ENV === "production") {
export const userSession = session(sessionConf);
export async function requireAuthenticated(req, res, next) {
+ if (!checkDatabaseConnection()) {
+ req.status(500).send("Internal server error.");
+ return;
+ }
if (req.session.userId) {
req.user = await userModel.findById(req.session.userId);
next();
@@ -26,3 +31,22 @@ export async function requireAuthenticated(req, res, next) {
return;
}
}
+
+
+export async function requireAdmin(req, res, next) {
+ if (!checkDatabaseConnection()) {
+ req.status(500).send("Internal server error.");
+ return;
+ }
+ if (req.session.userId) {
+ req.user = await userModel.findById(req.session.userId);
+ if (req.user.accessLevel < 3) {
+ res.status(401).send("Not authorized");
+ return;
+ }
+ next();
+ } else {
+ res.status(401).send("Not authorized.");
+ return;
+ }
+}
\ No newline at end of file
diff --git a/sports-matcher/server/middleware/database.js b/sports-matcher/server/middleware/database.js
index 149344a..08cdf68 100644
--- a/sports-matcher/server/middleware/database.js
+++ b/sports-matcher/server/middleware/database.js
@@ -1,9 +1,13 @@
import mongoose from "mongoose";
-export function needDatabase(res, req, next) {
- if (mongoose.connection.readyState != 1) {
+export function needDatabase(req, res, next) {
+ if (!checkDatabaseConnection()) {
res.status(500).send("Internal server error: Database connection faulty.");
} else {
next();
}
+}
+
+export function checkDatabaseConnection() {
+ return mongoose.connection.readyState == 1;
}
\ No newline at end of file
diff --git a/sports-matcher/server/schemas/matchModel.js b/sports-matcher/server/schemas/matchModel.js
index 85c55ee..0e0dae5 100644
--- a/sports-matcher/server/schemas/matchModel.js
+++ b/sports-matcher/server/schemas/matchModel.js
@@ -21,7 +21,7 @@ const matchSchema = new mongoose.Schema({
participants: { type: [{ type: Types.ObjectId, ref: ModelNameRegister.User }], required: true, default: [] },
difficulty: { type: Number, required: true },
sport: { type: Types.ObjectId, ref: ModelNameRegister.Sport },
- createDate: { type: Date, required: true, default: Date.now }
+ createDate: { type: Date, required: true, default: Date.now() }
});
matchSchema.pre("remove", function (next) {
diff --git a/sports-matcher/server/schemas/rentalModel.js b/sports-matcher/server/schemas/rentalModel.js
index 31e2d24..409d059 100644
--- a/sports-matcher/server/schemas/rentalModel.js
+++ b/sports-matcher/server/schemas/rentalModel.js
@@ -8,7 +8,7 @@ const rentalSchema = new mongoose.Schema({
rate: { type: String, required: true, trim: true },
description: { type: String, required: true },
contact: { type: String, required: true },
- createDate: { type: Date, required: true, default: Date.now },
+ createDate: { type: Date, required: true, default: Date.now() },
creator: { type: Types.ObjectId, ref: modelNameRegister.User }
});
diff --git a/sports-matcher/server/schemas/userModel.js b/sports-matcher/server/schemas/userModel.js
index 28a2be5..0bf9195 100644
--- a/sports-matcher/server/schemas/userModel.js
+++ b/sports-matcher/server/schemas/userModel.js
@@ -19,7 +19,7 @@ const userSchema = new mongoose.Schema({
},
firstName: { type: String, required: true, trim: true },
lastName: { type: String, required: true, trim: true },
- joinDate: { type: Date, default: Date.now, required: true },
+ joinDate: { type: Date, default: Date.now(), required: true },
phone: { type: Number, required: false, min: 0 },
password: {
type: String,
@@ -36,6 +36,7 @@ const userSchema = new mongoose.Schema({
participatingMatchesPublicity: { type: Boolean, required: true, default: false },
friends: { type: Types.ObjectId, ref: modelNameRegister.User },
accessLevel: { type: Number, required: true, default: 0 },
+ suspend: { type: Date, required: true, default: Date.now() } // suspend the user until the when the user was created.
});
userSchema.statics.credentialsExist = async function (email, password) {