Added suspension mechanism.

This commit is contained in:
Harrison Deng 2022-04-07 17:56:04 -05:00
parent 2e8ba9c5b1
commit eb4e4b2444
5 changed files with 107 additions and 40 deletions

View File

@ -5,6 +5,6 @@ export const apiClient = axios.create({
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;
}
});

View File

@ -1,5 +1,6 @@
import express from "express";
import { requireAuthenticated } from "../middleware/authority.js";
import validator from "validator";
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";
@ -67,50 +68,85 @@ 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/active", requireAdmin, async (req, res) => {
try {
if (req.user.accessLevel < 3) {
res.status(401).send("You do not have the required privileges.");
return;
}
let res = await userModel.find().where("suspend").lt(Date.now);
res.status(200).send({ all: res });
} catch (error) {
console.error(error);
res.status(500).send("Internal server error");
}
});
UserController.get("/all/suspended", requireAuthenticated, async (req, res) => {
try {
let res = await userModel.find().where("suspend").gte(Date.now);
res.status(200).send({ suspended: res });
} catch (error) {
console.error(error);
res.status(500).send("Internal server error");
}
});
/* TODO: Implement middleware for removing users.
@ -136,13 +172,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;

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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) {