From 0d35ae8d87ed1593074ff277146cc0694d590612 Mon Sep 17 00:00:00 2001 From: Filip Borum Poulsen Date: Sun, 16 Apr 2023 18:48:46 +0200 Subject: [PATCH] Removed user type from token --- server/src/interfaces/auth.ts | 6 ++++-- server/src/interfaces/user.ts | 4 ---- server/src/middlewares/auth.ts | 22 +++++++++++++++------- server/src/routes/login.ts | 19 +++++++++++++------ server/src/routes/register.ts | 6 +++--- 5 files changed, 35 insertions(+), 22 deletions(-) diff --git a/server/src/interfaces/auth.ts b/server/src/interfaces/auth.ts index d379fa0..a9c2587 100644 --- a/server/src/interfaces/auth.ts +++ b/server/src/interfaces/auth.ts @@ -1,10 +1,12 @@ import { Request } from "express"; -import User, { UserType } from './user' +import User from './user' import { JwtPayload } from "jsonwebtoken"; export interface UserTokenData { userId: User["id"] - user_type: UserType + isAdmin?: boolean + isTrainer?: boolean + tokenType: "User" } export interface AuthedRequest extends Request { diff --git a/server/src/interfaces/user.ts b/server/src/interfaces/user.ts index 65b1659..205d567 100644 --- a/server/src/interfaces/user.ts +++ b/server/src/interfaces/user.ts @@ -1,12 +1,8 @@ -type UserType = 'Admin' | 'Trainer' | 'User'; -export type { UserType } - interface User { email: string id: number first_name: string last_name: string password_hash: string - user_type: UserType } export default User; \ No newline at end of file diff --git a/server/src/middlewares/auth.ts b/server/src/middlewares/auth.ts index bd35343..67ae934 100644 --- a/server/src/middlewares/auth.ts +++ b/server/src/middlewares/auth.ts @@ -1,15 +1,15 @@ import { Response, NextFunction } from "express"; import jsonwebtoken, { JsonWebTokenError } from "jsonwebtoken"; -import { AuthedRequest } from "../interfaces/auth"; +import { AuthedRequest, UserTokenData } from "../interfaces/auth"; import { public_key } from "../environment" export const UserAuth = (req: AuthedRequest, res: Response, next: NextFunction) => { if (req.cookies["auth-token"] === undefined) return res.sendStatus(401); try { - const data: any = jsonwebtoken.verify(req.cookies["auth-token"], public_key); + const data: UserTokenData | any = jsonwebtoken.verify(req.cookies["auth-token"], public_key); - if (data.user_type !== "User") { + if (data.tokenType !== "User") { return res.sendStatus(403); } @@ -25,9 +25,13 @@ export const TrainerAuth = (req: AuthedRequest, res: Response, next: NextFunctio if (req.cookies["auth-token"] === undefined) return res.sendStatus(401); try { - const data: any = jsonwebtoken.verify(req.cookies["auth-token"], public_key); + const data: UserTokenData | any = jsonwebtoken.verify(req.cookies["auth-token"], public_key); - if (data.user_type !== "Trainer") { + if (data.tokenType !== "User") { + return res.sendStatus(403); + } + + if (data.isTrainer !== true) { return res.sendStatus(403); } @@ -43,9 +47,13 @@ export const AdminAuth = (req: AuthedRequest, res: Response, next: NextFunction) if (req.cookies["auth-token"] === undefined) return res.sendStatus(401); try { - const data: any = jsonwebtoken.verify(req.cookies["auth-token"], public_key); + const data: UserTokenData | any = jsonwebtoken.verify(req.cookies["auth-token"], public_key); + + if (data.tokenType !== "User") { + return res.sendStatus(403); + } - if (data.user_type !== "Admin") { + if (data.isAdmin !== true) { return res.sendStatus(403); } diff --git a/server/src/routes/login.ts b/server/src/routes/login.ts index 03644df..83d1215 100644 --- a/server/src/routes/login.ts +++ b/server/src/routes/login.ts @@ -19,7 +19,8 @@ const loginSchema = Joi.object({ interface DatabaseResult { id: User['id'] - user_type: User['user_type'] + is_admin: boolean + is_trainer: boolean password_hash: string } @@ -29,14 +30,18 @@ router.post("/login", async (req: Request, res: Response) => { return res.status(400).send(validation.error.details); } - const userData: LoginBody = req.body; + const userData: LoginBody = validation.value; try { const databaseResult = await client.query(` -SELECT id, user_type, password_hash FROM users WHERE email = $1; + SELECT users.id, password_hash, admins.user_id IS NOT NULL as is_admin, trainers.user_id IS NOT NULL as is_trainer + FROM users + LEFT JOIN admins ON admins.user_id = users.id + LEFT JOIN trainers ON trainers.user_id = users.id + WHERE email = $1; `, [userData.email]); - if (databaseResult.rowCount !== 1) { + if (databaseResult.rows.length !== 1) { return res.status(400).send([{ message: "Invalid email or password", type: "login.invalid" }]); } @@ -47,13 +52,15 @@ SELECT id, user_type, password_hash FROM users WHERE email = $1; } const jwtData: UserTokenData = { - user_type: user.user_type, + tokenType: "User", + isAdmin: user.is_admin ? true : undefined, + isTrainer: user.is_trainer ? true : undefined, userId: user.id }; const jwt: string = jsonwebtoken.sign(jwtData, private_key, { algorithm: "RS256", expiresIn: "4h" }); - res.cookie("auth-token", jwt, { httpOnly: true, maxAge: 60 * 60 * 4 }); + res.cookie("auth-token", jwt, { httpOnly: true, maxAge: 1000 * 60 * 60 * 4 }); return res.sendStatus(204); } catch (error: DatabaseError | Error | any) { diff --git a/server/src/routes/register.ts b/server/src/routes/register.ts index fab3414..9a9b295 100644 --- a/server/src/routes/register.ts +++ b/server/src/routes/register.ts @@ -24,7 +24,7 @@ router.post("/register", async (req: Request, res: Response) => { return res.status(400).send(validation.error.details); } - const userData: RegisterBody = req.body; + const userData: RegisterBody = validation.value; const password_hash: String = await Bcrypt.hash(userData.password, 10); @@ -32,13 +32,13 @@ router.post("/register", async (req: Request, res: Response) => { const insertResult = await client.query(` INSERT INTO users (first_name, last_name, email, password_hash) VALUES ($1, $2, $3, $4) -RETURNING id, user_type; +RETURNING id; `, [userData.first_name, userData.last_name, userData.email, password_hash]); const user = insertResult.rows[0]; const jwtData: UserTokenData = { - user_type: user.user_type, + tokenType: "User", userId: user.id };