From 2c4011f6311515acada00d9e062ee72b0a7207c9 Mon Sep 17 00:00:00 2001 From: Alexander Polynomdivision Date: Sun, 23 Sep 2018 22:17:35 +0200 Subject: [PATCH] refactor: Create a better API scheme --- backend/src/api/class.ts | 42 +++++++++++++ backend/src/api/level.ts | 42 +++++++++++++ backend/src/api/user.ts | 108 ++++++++++++++++++++++++++++++++++ backend/src/main.ts | 90 ++++------------------------ backend/src/security/token.ts | 23 ++++++++ backend/tsconfig.json | 1 + 6 files changed, 226 insertions(+), 80 deletions(-) create mode 100644 backend/src/api/class.ts create mode 100644 backend/src/api/level.ts create mode 100644 backend/src/api/user.ts create mode 100644 backend/src/security/token.ts diff --git a/backend/src/api/class.ts b/backend/src/api/class.ts new file mode 100644 index 0000000..e6e823e --- /dev/null +++ b/backend/src/api/class.ts @@ -0,0 +1,42 @@ +import { Router, Request, Response } from "express"; +import * as bodyparser from "body-parser"; + +import { authRoute } from "../security/token"; + +const classRouter = Router(); +classRouter.use(bodyparser.json()); +classRouter.use(authRoute); + +classRouter.get("/:id/topTen", async (req: Request, res: Response) => { + if (!req.params) { + res.send({ + error: "400", + data: { + msg: "No class specified", + }, + }); + return; + } + + console.log("Stub(get): /class/:id/topTen"); + + let users: any[] = []; + let nr = 10; + for (let i = 0; i < 10; i++) + users = users.concat({ + username: `Test User ${i}`, + score: 100 * i, + level: Math.floor(Math.random() * Math.floor(10)), + nr: nr--, + }); + + // TODO: Implement + res.send({ + error: "0", + data: { + topTen: users, + } + }); +}); + +export default classRouter; diff --git a/backend/src/api/level.ts b/backend/src/api/level.ts new file mode 100644 index 0000000..b177f2e --- /dev/null +++ b/backend/src/api/level.ts @@ -0,0 +1,42 @@ +import { Router, Request, Response } from "express"; +import * as bodyparser from "body-parser"; + +import { authRoute } from "../security/token"; + +const levelRouter = Router(); +levelRouter.use(bodyparser.json()); +levelRouter.use(authRoute); + +levelRouter.get("/:id/vocab", async (req: Request, res: Response) => { + // TODO: Implement + console.log("Stub(get): /level/:id/vocab"); + + if (!req.params) { + res.send({ + error: "400", + data: { + msg: "No level specified", + }, + }); + return; + } + + res.send({ + error: "0", + data: { + vocab: [{ + german: ["Wein"], + hint: "Worte auf '-um' sind meistens NeutrUM", + type: 0, + latin: { + grundform: "Vinum", + genitiv: "Vini", + genus: "Neutrum" + }, + id: 0 + }], + } + }); +}); + +export default levelRouter; diff --git a/backend/src/api/user.ts b/backend/src/api/user.ts new file mode 100644 index 0000000..7db1c77 --- /dev/null +++ b/backend/src/api/user.ts @@ -0,0 +1,108 @@ +import * as express from "express"; +import * as bodyparser from "body-parser"; + +import { authRoute } from "../security/token"; + +const userRouter = express.Router(); +userRouter.use(bodyparser.json()); +userRouter.use(authRoute); + +// Return the user object if the user is still authenticated +userRouter.get("/get", async (req, res) => { + console.log("STUB: /user/get"); + + // TODO: Stub + res.send({ + error: "0", + data: { + test: 0, + }, + }); +}); + +// Removes the user's session +userRouter.get("/logout", async (req, res) => { + console.log("STUB: /user/logout"); + + // TODO: Stub + res.send({ + error: "0", + data: {}, + }); +}); + +// Gets the user's review queue +userRouter.get("/queue", async (req, res) => { + console.log("STUB: /user/queue"); + + // TODO: Stub + res.send({ + error: "0", + data: {}, + }); +}); + +// Get ot set the last review results +userRouter.get("/lastReview", async (req, res) => { + console.log("STUB(get): /user/lastReview"); + + // TODO: Stub + res.send({ + error: "0", + data: {}, + }); +}); +userRouter.post("/lastReview", async (req, res) => { + console.log("STUB(post): /user/lastReview"); + + // TODO: Stub + res.send({ + error: "0", + data: {}, + }); +}); + +// Get the next level +userRouter.get("/nextLevel", async (req, res) => { + console.log("STUB: /user/nextLevel"); + + // TODO: Stub + res.send({ + error: "0", + data: { + name: "Test level", + desc: "Just a test", + level: 3, + + done: false, + }, + }); +}); + +// 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 +userRouter.post("/dashboard", async (req, res) => { + console.log("STUB(post): /user/dashboard"); + + // TODO: Stub + res.send({ + error: "0", + data: { + nextLevel: {}, + topTen: {}, + lastReview: {}, + }, + }); +}); + +export default userRouter; diff --git a/backend/src/main.ts b/backend/src/main.ts index 4feb5bf..76dd1f9 100644 --- a/backend/src/main.ts +++ b/backend/src/main.ts @@ -4,6 +4,10 @@ import * as bodyparser from "body-parser"; import { isAuthenticated, performLogin } from "./security/auth"; +import UserRouter from "./api/user"; +import ClassRouter from "./api/class"; +import LevelRouter from "./api/level"; + const baseRouter = express.Router(); const authRouter = express.Router(); @@ -27,94 +31,20 @@ authRouter.use(async (req, res, next) => { }); } }); -authRouter.get("/class/:id/topTen", async (req, res) => { - if (!req.params) { - res.send({ - error: "400", - data: { - msg: "No class specified", - }, - }); - return; - } - - console.log("Stub: /auth/class/:id/topTen"); - - let users: any[] = []; - let nr = 10; - for (let i = 0; i < 10; i++) - users = users.concat({ - username: `Test User ${i}`, - score: 100 * i, - level: Math.floor(Math.random() * Math.floor(10)), - nr: nr--, - }); - - // TODO: Implement - res.send({ - error: "0", - data: { - topTen: users, - } - }); -}); -authRouter.get("/level/:id/vocab", async (req, res) => { - // TODO: Implement - console.log("Stub: /auth/level/:id/vocab"); - - if (!req.params) { - res.send({ - error: "400", - data: { - msg: "No level specified", - }, - }); - return; - } - - res.send({ - error: "0", - data: { - vocab: [{ - german: ["Wein"], - hint: "Worte auf '-um' sind meistens NeutrUM", - type: 0, - latin: { - grundform: "Vinum", - genitiv: "Vini", - genus: "Neutrum" - }, - id: 0 - }], - } - }); -}); -authRouter.get("/user/nextLevel", async (req, res) => { - console.log("Stub: /auth/user/nextLevel"); - - res.send({ - error: "0", - data: { - name: "Test level", - desc: "Just a test", - level: 3, - - done: false, - }, - }); -}); const app = express(); app.use(bodyparser.json()); - app.use((req, res, next) => { // TODO: Change this to our domain res.append("Access-Control-Allow-Origin", "*"); res.append("Access-Control-Allow-Headers", "Content-Type,Token"); next(); }); -app.use("/auth", authRouter); -app.get("/health", (req, res) => { + +app.use("/api/level", LevelRouter); +app.use("/api/class", ClassRouter); +app.use("/api/user", UserRouter); +app.get("/api/health", (req, res) => { res.send({ error: "0", data: { @@ -122,7 +52,7 @@ app.get("/health", (req, res) => { }, }); }); -app.post("/login", async (req, res) => { +app.post("/api/login", async (req, res) => { const { body } = req; console.log("Stub: /login"); diff --git a/backend/src/security/token.ts b/backend/src/security/token.ts new file mode 100644 index 0000000..29b685d --- /dev/null +++ b/backend/src/security/token.ts @@ -0,0 +1,23 @@ +import { Request, Response } from "express"; + +import { isAuthenticated } from "../security/auth"; + +export async function authRoute(req: Request, res: Response, next: () => void) { + const token = req.get("Token"); + if (token) { + // Check if were authenticated + const auth = await isAuthenticated(token); + if (auth) + next(); + else + res.send({ + error: "401", + data: {}, + }); + } else { + res.send({ + error: "401", + data: {}, + }); + } +}; diff --git a/backend/tsconfig.json b/backend/tsconfig.json index 4ba990f..4131165 100644 --- a/backend/tsconfig.json +++ b/backend/tsconfig.json @@ -1,6 +1,7 @@ { "compilerOptions": { "target": "ESnext", + "lib": ["ES2015"], "module": "CommonJS", "noImplicitAny": true, "removeComments": true,