2022-04-05 01:15:43 +00:00
|
|
|
import express from "express";
|
|
|
|
import { authenticationGuard } from "../middleware/authority.js";
|
|
|
|
import { needDatabase } from "../middleware/database.js";
|
|
|
|
import matchModel from "../schemas/matchModel.js";
|
|
|
|
import sportModel from "../schemas/sportModel.js";
|
|
|
|
import userModel from "../schemas/userModel.js";
|
|
|
|
const MatchController = express.Router();
|
|
|
|
|
|
|
|
MatchController.get("/search/:sport", needDatabase, async (req, res) => {
|
|
|
|
try {
|
|
|
|
let sport = sportModel.findByName(req.params.sport);
|
|
|
|
let query = matchModel.find({ sport: sport._id });
|
|
|
|
query.where("when").gte(Date.now); // We don't want to return any results of matches that have already occurred.
|
|
|
|
if (req.session.userId) query.where("publicity").gte(1).where("friends").in(req.session.userId);
|
|
|
|
if (req.query.within) query.where("location").within({ center: req.query.location.split(","), radius: req.query.within });
|
|
|
|
if (req.query.minDifficulty) query.where("difficulty").gte(req.query.minDifficulty);
|
|
|
|
if (req.query.maxDifficulty) query.where("difficulty").lte(req.query.maxDifficulty);
|
|
|
|
if (req.query.beforeDate) query.where("when").lte(req.query.beforeDate);
|
|
|
|
|
|
|
|
let queryResults = await query;
|
|
|
|
res.send({ queryResults });
|
|
|
|
} catch (error) {
|
|
|
|
console.error(error);
|
|
|
|
res.status(500).send("Internal server error.");
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
MatchController.get("/recent/:limit?", needDatabase, async (req, res) => {
|
2022-04-05 05:21:34 +00:00
|
|
|
const user = req.user;
|
2022-04-05 08:28:12 +00:00
|
|
|
let limit = parseInt(req.params.limit);
|
|
|
|
if (!req.params.limit) limit = 10;
|
|
|
|
if (isNaN(limit)) {
|
|
|
|
console.log(typeof (limit));
|
2022-04-05 05:21:34 +00:00
|
|
|
res.status(400).send("Limit parameter is not a number.");
|
2022-04-05 08:28:12 +00:00
|
|
|
return;
|
2022-04-05 05:21:34 +00:00
|
|
|
}
|
2022-04-05 01:15:43 +00:00
|
|
|
if (isNaN(limit)) {
|
|
|
|
res.status(400).send("Limit parameter not a number.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (limit > 50) {
|
|
|
|
res.status(400).send("Limit greater than maximum limit of 50.");
|
|
|
|
return;
|
|
|
|
}
|
2022-04-05 08:41:20 +00:00
|
|
|
let recent = null;
|
2022-04-05 01:15:43 +00:00
|
|
|
try {
|
2022-04-05 08:41:20 +00:00
|
|
|
if (user) {
|
|
|
|
await user.populate("participatingMatches").populate("participatingMatches.participants").populate("participatingMatches.sport");
|
|
|
|
recent = user.participatingMatches;
|
|
|
|
} else {
|
|
|
|
recent = await matchModel.find().where("publicity").gte(2).limit(limit).sort({ createDate: -1 });
|
|
|
|
}
|
|
|
|
await recent.populate("members.$"); // Populates all references.
|
2022-04-05 01:15:43 +00:00
|
|
|
res.status(200).send({ recent: recent });
|
|
|
|
} catch (err) {
|
|
|
|
console.error(err);
|
|
|
|
res.status(500).send("Internal server error.");
|
|
|
|
// TODO: Check and improve error handling.
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
MatchController.post("/", needDatabase, authenticationGuard, async (req, res) => {
|
|
|
|
try {
|
|
|
|
const userId = req.session.userId;
|
|
|
|
const user = await userModel.findById(userId);
|
|
|
|
const match = new matchModel({
|
|
|
|
title: req.body.title,
|
|
|
|
when: req.body.when,
|
|
|
|
public: req.body.public,
|
|
|
|
location: req.body.location,
|
|
|
|
creator: userId,
|
|
|
|
difficulty: req.body.difficulty,
|
|
|
|
sport: await sportModel.findByName(req.body.sport),
|
|
|
|
participants: [user._id]
|
|
|
|
});
|
|
|
|
await match.save();
|
|
|
|
user.createdMatches.push(match._id);
|
|
|
|
user.participatingMatches.push(match._id);
|
|
|
|
await user.save();
|
|
|
|
res.status(201).send(match);
|
|
|
|
} catch (error) {
|
|
|
|
console.error(error);
|
|
|
|
res.status(500).send("Internal server error.");
|
|
|
|
// TODO: Develop the error handling.
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2022-04-05 03:50:26 +00:00
|
|
|
MatchController.patch("/:id", needDatabase, authenticationGuard, async (req, res) => {
|
|
|
|
const match = await matchModel.findById(req.params.id);
|
|
|
|
if (!match) {
|
|
|
|
res.status(400).send("Invalid match ID provided.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (req.user._id !== match.creator && req.user.accessLevel < 3) {
|
|
|
|
res.status(401).send("Not authorized.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (req.body._id) {
|
|
|
|
res.status(400).send("Cannot change ID of match.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (req.body.creator) {
|
|
|
|
res.status(400).send("Cannot change creator of match.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
await match.updateOne(req.body);
|
|
|
|
res.status(200).send(match);
|
|
|
|
});
|
|
|
|
|
|
|
|
MatchController.delete("/:id", needDatabase, authenticationGuard, async (req, res) => {
|
|
|
|
const match = await matchModel.findById(req.params.id);
|
|
|
|
if (!match) {
|
|
|
|
res.status(400).send("Invalid match ID provided.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (req.user._id !== match.creator && req.user.accessLevel < 3) {
|
|
|
|
res.status(401).send("Not authorized.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
await match.deleteOne();
|
2022-04-05 08:41:20 +00:00
|
|
|
res.status(200).send("Deleted.");
|
2022-04-05 03:50:26 +00:00
|
|
|
});
|
|
|
|
|
2022-04-05 08:28:12 +00:00
|
|
|
MatchController.get("/:id", needDatabase, async (req, res) => {
|
|
|
|
if (!req.params.id) {
|
2022-04-05 01:15:43 +00:00
|
|
|
res.status(404).send("Id must be provided to retrieve match");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
try {
|
2022-04-05 08:28:12 +00:00
|
|
|
const match = await matchModel.findById(req.params.id).populate("sport");
|
2022-04-05 01:15:43 +00:00
|
|
|
if (match) {
|
|
|
|
res.status(200).send(match);
|
|
|
|
} else {
|
2022-04-05 08:28:12 +00:00
|
|
|
res.status(404).send("Could not find match with ID: " + req.params.id);
|
2022-04-05 01:15:43 +00:00
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
res.status(500).send("Internal server error.");
|
|
|
|
// TODO: Develop the error handling.
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2022-04-05 03:50:26 +00:00
|
|
|
MatchController.get("/join/:id", needDatabase, authenticationGuard, async (req, res) => {
|
|
|
|
const match = await matchModel.findById(req.params.id);
|
|
|
|
const user = req.user;
|
|
|
|
if (!match) {
|
|
|
|
res.status(400).send("Invalid match ID provided.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (user.participatingMatches.includes(match._id)) {
|
|
|
|
res.status(400).send("Already participating in match.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
match.participants.push(user._id);
|
|
|
|
user.participatingMatches.push(match._id);
|
|
|
|
|
|
|
|
await match.save();
|
|
|
|
await user.save();
|
|
|
|
|
|
|
|
res.status(200).send("Joined.");
|
|
|
|
});
|
|
|
|
|
|
|
|
MatchController.get("/leave/:id", needDatabase, authenticationGuard, async (req, res) => {
|
|
|
|
const match = await matchModel.findById(req.params.id);
|
|
|
|
const user = req.user;
|
|
|
|
|
|
|
|
if (!match) {
|
|
|
|
res.status(400).send("Invalid match ID provided.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!user.participatingMatches.includes(match._id)) {
|
|
|
|
res.status(400).send("Not part of match.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const userIndex = match.participants.indexOf(user._id);
|
|
|
|
match.participants.splice(userIndex, 1);
|
|
|
|
await match.save();
|
|
|
|
|
|
|
|
const matchIndex = user.participatingMatches.indexOf(match._id);
|
|
|
|
user.participatingMatches.splice(matchIndex, 1);
|
|
|
|
await user.save();
|
|
|
|
|
|
|
|
res.status(200).send("Left match.");
|
|
|
|
});
|
|
|
|
|
2022-04-05 01:15:43 +00:00
|
|
|
export default MatchController;
|