This repository has been archived on 2022-03-12. You can view files and clone it, but cannot push or open issues or pull requests.
Lateinicus/backend/src/api/user.ts

203 lines
4.9 KiB
TypeScript
Raw Normal View History

2018-09-23 20:17:35 +00:00
import * as express from "express";
import * as bodyparser from "body-parser";
import { authRoute } from "../security/token";
2018-09-29 13:06:14 +00:00
import { userFromSession } from "../utils/user";
import { IUser } from "../models/user";
2018-09-29 17:10:27 +00:00
import { LRequest } from "../types/express";
import { Db } from "mongodb";
2018-09-29 13:06:14 +00:00
2018-09-23 20:17:35 +00:00
const userRouter = express.Router();
userRouter.use(authRoute);
2018-09-29 12:23:09 +00:00
userRouter.use(bodyparser.json());
2018-09-23 20:17:35 +00:00
// Return the user object if the user is still authenticated
2018-09-29 17:10:27 +00:00
userRouter.get("/me", async (req: LRequest, res) => {
2018-09-29 12:23:09 +00:00
const { db, token } = req;
2018-09-23 20:17:35 +00:00
2018-09-29 12:23:09 +00:00
const session = await db.collection("sessions").findOne({ token, });
if (session !== null) {
const user = await db.collection("users").findOne({ username: session.username });
2018-09-29 13:06:14 +00:00
// Copy and strip unneeded attributes
let copy = Object.assign({}, user, {
sessionToken: token,
});
delete copy._id;
delete copy.hash;
delete copy.salt;
2018-09-29 12:23:09 +00:00
res.send({
error: "0",
2018-09-29 13:06:14 +00:00
data: copy,
2018-09-29 12:23:09 +00:00
});
} else {
res.send({
error: "404",
data: {},
});
}
2018-09-23 20:17:35 +00:00
});
// Removes the user's session
2018-09-29 17:10:27 +00:00
userRouter.get("/logout", async (req: LRequest, res) => {
2018-09-29 12:23:09 +00:00
// Try to remove the session
2018-09-29 17:10:27 +00:00
const { db, token } = req;
await db.collection("sessions").findOneAndDelete({ token, });
2018-09-23 20:17:35 +00:00
res.send({
error: "0",
data: {},
});
});
2018-09-24 11:53:20 +00:00
// TODO: This should be shared with the frontend, to remove code duplication
export enum VocabType {
NOMEN = 0,
VERB = 1,
ADJEKTIV = 2,
ADVERB = 3,
};
2018-09-23 20:17:35 +00:00
// Gets the user's review queue
userRouter.get("/queue", async (req, res) => {
console.log("STUB: /user/queue");
// TODO: Stub
res.send({
error: "0",
2018-09-24 11:53:20 +00:00
data: {
queue: [{
german: ["Wein"],
hint: "Worte auf '-um' sind meistens NeutrUM",
type: VocabType.NOMEN,
latin: {
grundform: "Vinum",
genitiv: "Vini",
genus: "Neutrum"
},
id: 0
}]
},
2018-09-23 20:17:35 +00:00
});
});
// Get ot set the last review results
2018-09-29 17:10:27 +00:00
userRouter.get("/lastReview", async (req: LRequest, res) => {
// TODO: if(user)
const { token, db } = req;
const user = await userFromSession(token, db);
2018-09-23 20:17:35 +00:00
res.send({
error: "0",
2018-09-29 17:10:27 +00:00
data: user.lastReview,
2018-09-23 20:17:35 +00:00
});
});
2018-09-29 17:10:27 +00:00
userRouter.post("/lastReview", async (req: LRequest, res) => {
// TODO: Check if we get the correct data
// TODO: if(user)
const { token, db } = req;
const user = await userFromSession(token, db);
// TODO: Error handling
await db.collection("users").updateOne({
username: user.username,
}, {
$set: {
lastReview: req.body.meta,
},
});
2018-09-23 20:17:35 +00:00
res.send({
error: "0",
data: {},
});
});
2018-09-29 17:10:27 +00:00
// Returns the next level (level + 1) or the current level, if no higher level
// can be found
async function getNextLevel(token: string, db: Db): Promise<any> {
// TODO: if(user)
const user = await userFromSession(token, db);
const { lastLevel } = user;
2018-09-23 20:17:35 +00:00
2018-09-29 17:10:27 +00:00
// Try to find a level, which level is lastLevel + 1
const level = await db.collection("levels").findOne({
level: lastLevel + 1,
});
if (level) {
return level;
} else {
// TODO: Send different data, so that the Client can say "Hey, no more levels"
return await db.collection("levels").findOne({
level: lastLevel
});
}
}
// Get the next level
userRouter.get("/nextLevel", async (req: LRequest, res) => {
const level = await getNextLevel(req.token, req.db);
2018-09-23 20:17:35 +00:00
res.send({
error: "0",
2018-09-29 17:10:27 +00:00
data: level,
2018-09-23 20:17:35 +00:00
});
});
// Mark a level as done
userRouter.post("/level/:id", async (req, res) => {
console.log("STUB(post): /user/level/:id");
// TODO: Stub
res.send({
error: "0",
data: {},
});
});
// Get the data needed for the dashboard
2018-09-29 17:10:27 +00:00
userRouter.get("/dashboard", async (req: LRequest, res) => {
2018-09-29 13:06:14 +00:00
const { db, token } = req;
// Get the user
// TODO: if (user)
2018-09-29 17:10:27 +00:00
const user = await userFromSession(token, db);
2018-09-29 13:06:14 +00:00
const { classId } = user;
// Fetch the top ten of the class
const rawTopTen = await db.collection("users").find({
classId,
}, {
sort: {
score: -1,
},
limit: 10,
}).toArray();
let nr = 1;
const topTen = rawTopTen.map((user: IUser) => {
return {
username: user.username,
score: user.score,
2018-09-29 17:10:27 +00:00
// TODO: Calculate on the client?
2018-09-29 13:06:14 +00:00
level: 1,
nr: nr++,
};
});
2018-09-24 16:29:29 +00:00
2018-09-29 17:10:27 +00:00
const nextLevel = await getNextLevel(token, db);
2018-09-23 20:17:35 +00:00
res.send({
2018-09-24 16:29:29 +00:00
error: "200",
2018-09-23 20:17:35 +00:00
data: {
2018-09-29 17:10:27 +00:00
nextLevel,
2018-09-29 13:06:14 +00:00
topTen,
lastReview: user.lastReview,
2018-09-23 20:17:35 +00:00
},
});
});
export default userRouter;