From 79de47f12216753b0a2d36e519997ee7046f1b5d Mon Sep 17 00:00:00 2001 From: "narindra.rajohnso" <narindra-hasimanjaka-david.rajohnson@etu.hesge.ch> Date: Thu, 8 Jun 2023 10:29:32 +0200 Subject: [PATCH] add token sign and verify --- API/.env | 2 ++ API/src/database/database.sqlite | Bin 20480 -> 20480 bytes API/src/routes/BaseRoutes.ts | 2 +- API/src/routes/middleware.ts | 31 ++++++++++++++++-- API/src/routes/router-admin.ts | 28 +++++++--------- API/src/routes/router-gamer.ts | 6 ++-- API/src/routes/router-guest.ts | 9 ++++- .../quizz-game/src/app/login/session-model.ts | 0 8 files changed, 55 insertions(+), 23 deletions(-) create mode 100644 Frontend/quizz-game/src/app/login/session-model.ts diff --git a/API/.env b/API/.env index 48e75ec..c2da4ed 100644 --- a/API/.env +++ b/API/.env @@ -1,3 +1,5 @@ ########################### Server env vars API_PORT=30992 +########################### (openssl rand -hex 32) +SECRET_KEY="d8e730bd53c2cb0b9271bded343dd19ceef04e58e6a10eafe29c8f4a9a99f488" diff --git a/API/src/database/database.sqlite b/API/src/database/database.sqlite index e7da284434d84742aed929297a91ca2b3b886e74..ed7be32ccd95fadcfdba4d8983a6d5731c58f8a2 100644 GIT binary patch delta 412 zcmZozz}T>Wae_2s-b5K^#=MOQOZcVOd88TmmH68E`*`2-hVX3Xk>>8_`ofjQd0}JY zR?f|rC3i5^Gfa|BWnf_F5l$5ql^6B&EKW)D()M?9H7ZZ{4GpOZwRH7xbV}AX^Uc*x z4oUS1bxKRpH!>}8v^4Q7PxrJ<EKW%S;o`)UGzSn-TAW&BWME{hYhb2pV6I?jVr6P< zWon^kW?`bBZD3$!V1Od4jv?JB$-$|ZDk-Th?&(=vl3JFPSXi1`GC5OLCpfqywJbHy z3oHN;cF0IA)=SPvOv%m6gPUszw$;SS*i_Hl$Q0dHh^(cRk(r*ciP`22G9k=T?EJGC z_%HLn<KMx5hkrKzD*j{q$N1-i;ATOGVE)O4`f^hIKNxt*@-uT14NW-tm=zh3+_q9b in58%+jdPQM13#a+f}xp}shO3Lg`TB}(PlsUO#%R2n00ah delta 364 zcmZozz}T>Wae_2s`a~IL#`KK|OZcVOc(ya}EAh4S_wl~v4dL0&qs%>t>kC&J=Y@@p zTRAshmfXQuKU*?YSz4Kafq`M7c&enRqNt~5aY~wnsaI8~ep#t!Wm=)BnQ3{LcD`?M zNK&S6V!5_KxuLOvlSgWSQJ7_9g{hmXZE;FkN^x3oN?LJoN}5A)N}66?YH4w5k&%Is zv95usu92yNp{bRDrInG1o}q=Yg0_Kym4N|RRvTH`*j&%h)D$Ysz`!s?GF4JsS=7_B zEI%_R(P(m&l#W1ZUUGg>YGP?gQEG8wN?P$`K3Pc)3oBDIJtG72$@;QlaL(opG9k=T zZ2YSj_%HLn<KMx5hkq6SG5+~5xLMF4n16DizMNEAxrHegKmQK~F0j`*`F}8QL#<q? YAIy@Hm{zjMz=40VlD+8WQ2W&a0M$Bb6aWAK diff --git a/API/src/routes/BaseRoutes.ts b/API/src/routes/BaseRoutes.ts index aeb0f7a..7c76bdf 100644 --- a/API/src/routes/BaseRoutes.ts +++ b/API/src/routes/BaseRoutes.ts @@ -4,7 +4,7 @@ import { StatusCodes } from 'http-status-codes'; const router: express.Router = express.Router(); -router.get('/', (req: express.Request, res: express.Response) => res.status(StatusCodes.OK).json({message: "Base route"})); +router.get('/token/login', (req: express.Request, res: express.Response) => res.status(StatusCodes.OK).json({message: "Base route"})); diff --git a/API/src/routes/middleware.ts b/API/src/routes/middleware.ts index 0c49da6..3c3164c 100644 --- a/API/src/routes/middleware.ts +++ b/API/src/routes/middleware.ts @@ -1,8 +1,10 @@ -import express from 'express'; -import { StatusCodes } from 'http-status-codes'; +import express from 'express'; +import {StatusCodes} from 'http-status-codes'; import {userType} from '../database/models/User' import {Database} from "../database/Database"; +const jwt = require('jsonwebtoken'); + export function checkUserFields(req: express.Request, res: express.Response, next: express.NextFunction) { if (!req.body.username && !req.body.password && !req.body.accountType) { return res.status(400).json({ error: '"username", "password" and "accountType" required' }); @@ -41,6 +43,31 @@ export async function checkExistingUser(req: express.Request, res: express.Respo } +export interface TokenRequest extends express.Request { + user?: any; +} + +export async function verifyToken(req: TokenRequest, res: express.Response, next: express.NextFunction) { + const authHeader = req.headers['authorization']; + + if (!authHeader) { + return res.status(401).json({message: 'Token not provided', header: req.headers}); + } + const token = authHeader.split(" ")[1]; + + const secretKey = process.env.SECRET_KEY; + + try { + req.user = jwt.verify(token, secretKey); + if(req.user.username !== req.params.admin) + return res.status(403).json({message: 'Invalid token user'}); + //check if admin or user + next(); + } catch (error) { + return res.status(403).json({message: 'Invalid token'}); + } +} + export function checkQuestionFields(req: express.Request, res: express.Response, next: express.NextFunction) { diff --git a/API/src/routes/router-admin.ts b/API/src/routes/router-admin.ts index 3a7672a..a8a1842 100644 --- a/API/src/routes/router-admin.ts +++ b/API/src/routes/router-admin.ts @@ -9,22 +9,18 @@ import { checkQuestionFields, checkUserFields, checkUsernameField, - createAccountCheck + createAccountCheck, verifyToken } from './middleware' import {Database} from "../database/Database"; const router: express.Router = express.Router(); -router.get('/', (req: express.Request, res: express.Response) => { - res.status(StatusCodes.OK).json({ message: 'Admins route' }) -}); -router.get('/:admin', checkExistingUser, (req: express.Request, res: express.Response) => { - res.status(StatusCodes.OK).json({ message: 'Admin id route' }) -}); -router.get('/:admin/list-users', checkExistingUser,async (req: express.Request, res: express.Response) => { + + +router.get('/:admin/list-users', checkExistingUser, verifyToken, async (req: express.Request, res: express.Response) => { try { const users = await Database.getAllUsers(); res.status(StatusCodes.OK).json({users}); @@ -33,7 +29,7 @@ router.get('/:admin/list-users', checkExistingUser,async (req: express.Request, } }); -router.get('/:admin/list-questions', checkExistingUser, async (req: express.Request, res: express.Response) => { +router.get('/:admin/list-questions', checkExistingUser, verifyToken, async (req: express.Request, res: express.Response) => { try { const questions = await Database.getAllQuestions(); questions.forEach(q => { @@ -48,11 +44,11 @@ router.get('/:admin/list-questions', checkExistingUser, async (req: express.Req } }); -router.post('/:admin/create-user-account', checkExistingUser, checkUserFields, (req: express.Request, res: express.Response) => { +router.post('/:admin/create-user-account', checkExistingUser, checkUserFields, verifyToken, (req: express.Request, res: express.Response) => { createAccountCheck(req, res); }); -router.post('/:admin/create-question', checkExistingUser, checkQuestionFields,async (req: express.Request, res: express.Response) => { +router.post('/:admin/create-question', checkExistingUser, checkQuestionFields, verifyToken, async (req: express.Request, res: express.Response) => { const data = req.body; const correctResponse: string = data.possibleResponse[data.correctResponse]; if (correctResponse !== undefined) { @@ -78,7 +74,7 @@ router.post('/:admin/create-question', checkExistingUser, checkQuestionFields,as } }); -router.put('/:admin/update-user-account', checkExistingUser, checkUsernameField, async (req: express.Request, res: express.Response) => { +router.put('/:admin/update-user-account', checkExistingUser, checkUsernameField, verifyToken, async (req: express.Request, res: express.Response) => { const data=req.body; const username = data.username; try{ @@ -109,7 +105,7 @@ router.put('/:admin/update-user-account', checkExistingUser, checkUsernameField, }); -router.put('/:admin/update-question', checkExistingUser,checkIdField,async (req: express.Request, res: express.Response) => { +router.put('/:admin/update-question', checkExistingUser,checkIdField, verifyToken, async (req: express.Request, res: express.Response) => { const data=req.body; const id = data.id; try{ @@ -135,7 +131,7 @@ router.put('/:admin/update-question', checkExistingUser,checkIdField,async (req: -router.delete('/:admin/delete-user-account', checkExistingUser, checkUsernameField, async (req: express.Request, res: express.Response) => { +router.delete('/:admin/delete-user-account', checkExistingUser, checkUsernameField, verifyToken, async (req: express.Request, res: express.Response) => { let data=req.body if(req.params.admin !== data.username) { try{ @@ -157,7 +153,7 @@ router.delete('/:admin/delete-user-account', checkExistingUser, checkUsernameFie }); -router.delete('/:admin/delete-question', checkExistingUser, checkIdField, async (req: express.Request, res: express.Response) => { +router.delete('/:admin/delete-question', checkExistingUser, checkIdField, verifyToken, async (req: express.Request, res: express.Response) => { let data = req.body try { let questionDelete = await Database.deleteQuestion(data.id); @@ -176,7 +172,7 @@ router.delete('/:admin/delete-question', checkExistingUser, checkIdField, async }); -router.post('/:admin/get-user', checkExistingUser, async (req: express.Request, res: express.Response) => { +router.post('/:admin/get-user', checkExistingUser, verifyToken, async (req: express.Request, res: express.Response) => { const data = req.body let user=await Database.infoUser(data.username); user.dataValues.password="CONFIDENTIAL!!!" diff --git a/API/src/routes/router-gamer.ts b/API/src/routes/router-gamer.ts index cf91582..4159296 100644 --- a/API/src/routes/router-gamer.ts +++ b/API/src/routes/router-gamer.ts @@ -1,6 +1,6 @@ import express from 'express'; import { StatusCodes } from 'http-status-codes'; -import {checkExistingUser} from "./middleware"; +import {checkExistingUser, TokenRequest, verifyToken} from "./middleware"; const router: express.Router = express.Router(); @@ -9,8 +9,8 @@ router.get('/', (req: express.Request, res: express.Response) => { res.status(StatusCodes.OK).json({ message: 'Gamers route' }) }); -router.get('/:username', checkExistingUser, (req: express.Request, res: express.Response) => { - +router.get('/:username', checkExistingUser, verifyToken, (req: TokenRequest, res: express.Response) => { + res.status(StatusCodes.OK).json({access_user: req.user}); }); diff --git a/API/src/routes/router-guest.ts b/API/src/routes/router-guest.ts index 79500bc..ad6875e 100644 --- a/API/src/routes/router-guest.ts +++ b/API/src/routes/router-guest.ts @@ -2,6 +2,9 @@ import express from 'express'; import { StatusCodes } from 'http-status-codes'; import {checkExistingUser, checkUserFields, createAccountCheck} from './middleware' import {Database} from "../database/Database"; +import * as process from "process"; +import {userType} from "../database/models/User"; +const jwt = require('jsonwebtoken'); @@ -25,7 +28,11 @@ router.post('/:username', checkExistingUser, async (req: express.Request, res: e if(user){ let usertype=user.dataValues.type === "user"?"USER":"ADMIN" if (user.dataValues.password === data.password) { - res.status(StatusCodes.OK).json({message: usertype+"_ALLOWED"}) + // Génération du token JWT + const userInfo={ type: userType, username: req.params.username, firstname: user.dataValues.firstname, lastname: user.dataValues.lastname } + const secretKey=process.env.SECRET_KEY; + const token = jwt.sign(userInfo, secretKey); + res.status(StatusCodes.OK).json({message: usertype+"_ALLOWED", token: token, firstname: user.dataValues.firstname, lastname: user.dataValues.lastname}); }else{ res.status(StatusCodes.BAD_REQUEST).json({message: "USER_PASSWORD_FALSE"}) } diff --git a/Frontend/quizz-game/src/app/login/session-model.ts b/Frontend/quizz-game/src/app/login/session-model.ts new file mode 100644 index 0000000..e69de29 -- GitLab