From 23e41916cdb2304ff6022b553e921558783f26a4 Mon Sep 17 00:00:00 2001
From: Roland Bernard <rolbernard@unibz.it>
Date: Thu, 15 Apr 2021 23:16:30 +0200
Subject: [PATCH] Added some user query requests

---
 server/src/index.test.ts |  5 ---
 server/src/index.ts      |  6 +++-
 server/src/util.ts       |  6 ++--
 server/src/v1/auth.ts    | 24 +++++++++++---
 server/src/v1/index.ts   |  2 ++
 server/src/v1/user.ts    | 70 ++++++++++++++++++++++++++++++++++++++++
 6 files changed, 100 insertions(+), 13 deletions(-)
 delete mode 100644 server/src/index.test.ts
 create mode 100644 server/src/v1/user.ts

diff --git a/server/src/index.test.ts b/server/src/index.test.ts
deleted file mode 100644
index 1292256..0000000
--- a/server/src/index.test.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-
-test('dummy test case', () => {
-    expect(true).toEqual(true);
-});
-
diff --git a/server/src/index.ts b/server/src/index.ts
index 449cb1c..4c8a0dd 100644
--- a/server/src/index.ts
+++ b/server/src/index.ts
@@ -12,12 +12,16 @@ app.use(bodyJson());
 app.use('/v1', v1);
 
 app.use((_req, res) => {
-    res.sendStatus(404);
+    res.status(404).json({
+        status: 'error',
+        message: 'unknown resource',
+    });
 });
 
 app.use((_err: Error, _req: Request, res: Response, _next: NextFunction) => {
     return res.status(400).json({
         status: 'error',
+        message: 'unknown error',
     });
 });
 
diff --git a/server/src/util.ts b/server/src/util.ts
index 6ae83da..ed4ac1b 100644
--- a/server/src/util.ts
+++ b/server/src/util.ts
@@ -3,10 +3,10 @@ import { readFile } from 'fs';
 
 export const isOfType = <T>(
     varToBeChecked: any,
-    propertyToCheckFor: (keyof T)[]
+    propertyToCheckFor: [(keyof T), string][]
 ): varToBeChecked is T => {
-    for (const key of propertyToCheckFor) {
-        if (!(varToBeChecked as T)[key]) {
+    for (const [key, type] of propertyToCheckFor) {
+        if (typeof (varToBeChecked as T)[key] !== type) {
             return false;
         }
     }
diff --git a/server/src/v1/auth.ts b/server/src/v1/auth.ts
index 247d7ae..3723c24 100644
--- a/server/src/v1/auth.ts
+++ b/server/src/v1/auth.ts
@@ -16,7 +16,7 @@ interface RegisterBody {
 }
 
 auth.post('/register', async (req, res) => {
-    if (isOfType<RegisterBody>(req.body, ['username', 'password'])) {
+    if (isOfType<RegisterBody>(req.body, [['username', 'string'], ['password', 'string']])) {
         const body: RegisterBody = req.body;
         const id = uuid();
         const passwdHash = await hash(body.password, 10);
@@ -30,6 +30,7 @@ auth.post('/register', async (req, res) => {
                 status: 'success',
             });
         } catch (e) {
+            // Fails if unique constraint for username is not met
             res.status(400).json({
                 status: 'error',
                 message: 'failed to create user',
@@ -49,7 +50,7 @@ interface TokenBody {
 }
 
 auth.post('/token', async (req, res) => {
-    if (isOfType<TokenBody>(req.body, ['username', 'password'])) {
+    if (isOfType<TokenBody>(req.body, [['username', 'string'], ['password', 'string']])) {
         const body: TokenBody = req.body;
         try {
             const user = await database('users').where({ user_name: body.username });
@@ -89,6 +90,8 @@ auth.post('/token', async (req, res) => {
     }
 });
 
+auth.use(requireVerification);
+
 auth.get("/extend", async function (req, res) {
     if (req.body?.token) {
         const token = await asyncify(sign, {
@@ -112,8 +115,10 @@ export async function tokenVerification(req: Request, res: Response, next: NextF
     if (header) {
         const bearer = header.split(' ');
         token = bearer[1];
-    } else if (req.body?.token) {
-        token = req.body?.token;
+    } else if (!req.body) {
+        req.body = {};
+    } else if (req.body.token) {
+        token = req.body.token;
     }
     if (token) {
         try {
@@ -131,5 +136,16 @@ export async function tokenVerification(req: Request, res: Response, next: NextF
     }
 }
 
+export function requireVerification(req: Request, res: Response, next: NextFunction) {
+    if (req.body.token) {
+        next();
+    } else {
+        res.status(403).json({
+            status: 'error',
+            message: 'authentication failed',
+        });
+    }
+}
+
 export default auth;
 
diff --git a/server/src/v1/index.ts b/server/src/v1/index.ts
index 2a13b9b..68487de 100644
--- a/server/src/v1/index.ts
+++ b/server/src/v1/index.ts
@@ -2,11 +2,13 @@
 import express from 'express';
 
 import auth, { tokenVerification } from './auth';
+import user from './user';
 
 const v1 = express();
 
 v1.use(tokenVerification);
 v1.use('/auth', auth);
+v1.use('/user', user);
 
 export default v1;
 
diff --git a/server/src/v1/user.ts b/server/src/v1/user.ts
new file mode 100644
index 0000000..51373ad
--- /dev/null
+++ b/server/src/v1/user.ts
@@ -0,0 +1,70 @@
+
+import express from 'express';
+
+import database from '../database';
+import { isOfType } from '../util';
+import { requireVerification } from './auth';
+
+const user = express();
+
+user.get('/name/:username', async (req, res) => {
+    try {
+        const user = await database('users')
+            .select({
+                id: 'id',
+                username: 'user_name',
+                email: 'email',
+                realname: 'real_name',
+            })
+            .where({ username: req.params.username });
+        if (user.length === 1) {
+            res.status(200).json({
+                status: 'success',
+                user: user[0],
+            });
+        } else {
+            res.status(404).json({
+                status: 'error',
+                message: 'user not found',
+            });
+        }
+    } catch (e) {
+        res.status(400).json({
+            status: 'error',
+            message: 'failed get user',
+        });
+    }
+});
+
+user.use(requireVerification);
+
+user.get('/', async (req, res) => {
+    try {
+        const user = await database('users')
+            .select({
+                id: 'id',
+                username: 'user_name',
+                email: 'email',
+                realname: 'real_name',
+            })
+            .where({ id: req.body.token.id });
+        if (user.length === 1) {
+            res.status(200).json({
+                status: 'success',
+                user: user[0],
+            });
+        } else {
+            res.status(404).json({
+                status: 'error',
+                message: 'user not found',
+            });
+        }
+    } catch (e) {
+        res.status(400).json({
+            status: 'error',
+            message: 'failed get user',
+        });
+    }
+});
+
+export default user;
-- 
GitLab