diff --git a/API/db/app.db b/API/db/app.db index 918b6e267f795f9e97beb6aa37d825f69d9d17ce..64c90b46e77bf7c6bb80320c2b8304adf8bf2b65 100644 Binary files a/API/db/app.db and b/API/db/app.db differ diff --git a/API/src/database/Database.ts b/API/src/database/Database.ts index 42c744fa4b3e48494093c30cd219bfdb5123f8d5..5bb06e63c00ea43e5643ac86c7f05e480cfdcf10 100644 --- a/API/src/database/Database.ts +++ b/API/src/database/Database.ts @@ -33,7 +33,6 @@ export type Answer_t = { } export type Category_t = { - id: number; category: string; }; @@ -59,7 +58,7 @@ class DBHandler { if (usernameInDB.length == 0) return false; - return (usernameInDB[0].username == username); + return (usernameInDB[0].username === username); } async verifyQuestionExistence(question:string) : Promise<boolean> { @@ -76,6 +75,12 @@ class DBHandler { return (password[0].password == user.password); } + async getUserById(id: number) : Promise<User_t> { + const query = "SELECT username, password, admin FROM users WHERE id="+id; + const user = await asyncdb.get<User_t>(query); + return user; + } + async getUsers(res:express.Response) { const query = "SELECT id, username, admin FROM users"; asyncdb.all(query) @@ -92,7 +97,7 @@ class DBHandler { a.admin = false; const query = "INSERT INTO users (username, password, admin) \ - VALUES ('" + a.username + "','" + a.password + "','" + a.admin +"')"; + VALUES ('" + a.username + "','" + a.password + "'," + a.admin +")"; asyncdb.all(query) .then( () => res.status(StatusCodes.OK)) @@ -103,7 +108,7 @@ class DBHandler { const a = req.body as User_t; const request = "UPDATE users \ - SET username = '"+ a.username + "', admin = '" + a.admin + "' WHERE id = " + req.params.id; + SET username = '"+ a.username + "', admin =" + a.admin + " WHERE id = " + req.params.id; asyncdb.all(request) .then(() => res.status(StatusCodes.OK).end()) @@ -158,7 +163,7 @@ class DBHandler { let questions = await asyncdb.all(query); - let ans = await asyncdb.all(query_answers); + // let ans = await asyncdb.all(query_answers); // let payload = { // QUESTIONS: questions, @@ -205,7 +210,7 @@ class DBHandler { async deleteCategory(req:express.Request, res:express.Response) { const a = req.body as Category_t; - const request = "DELETE FROM category WHERE id = " + a.id; + const request = "DELETE FROM category WHERE title = '" + a.category + "'"; asyncdb.all(request) .then(() => res.status(StatusCodes.OK).end()) .catch(e => console.log(e)); diff --git a/API/src/express/Server.ts b/API/src/express/Server.ts index 208e72840ac93a128c80d589a8464880f702fb45..877b0c3969a6477485ab1fe22ec8ef94637499df 100644 --- a/API/src/express/Server.ts +++ b/API/src/express/Server.ts @@ -10,7 +10,6 @@ import multer from 'multer'; import Config from '../config/Config'; import BaseRoutes from '../routes/BaseRoutes'; import ServerIO from '../socket.io/ServerIO'; -import DBHandler from '../database/Database'; export class Server { private readonly backend: Express; diff --git a/API/src/routes/BaseRoutes.ts b/API/src/routes/BaseRoutes.ts index bbff290626d4961dc2b6ec22974c71d86239996e..a5cfef4e2b2b33864ec4559bb0458ddb9e866f24 100644 --- a/API/src/routes/BaseRoutes.ts +++ b/API/src/routes/BaseRoutes.ts @@ -2,8 +2,8 @@ import express from 'express'; import { StatusCodes } from 'http-status-codes'; import DBHandler from '../database/Database'; import { User_t, Question_t } from '../database/Database'; -import { Jwt } from 'jsonwebtoken'; -import { userInfo } from 'os'; +import { param } from 'express-validator'; + const ROUTE:string = '/API/v1'; @@ -21,8 +21,8 @@ function generateToken(user: User_t) { return jwt.sign(payload, process.env.TOKEN_SECRET); } -function isAdmin(token: string): Boolean { - let adminToken: Boolean; +function isAdmin(token: string): boolean { + let adminToken: boolean; if (token == null) return false; jwt.verify(token, process.env.TOKEN_SECRET, (err:any, user:User_t) => { @@ -41,7 +41,6 @@ function tokenDecode(req: express.Request): User_t { const token = req.headers['authorization'] && req.headers['authorization'].split(' ')[1] jwt.verify(token, process.env.TOKEN_SECRET, (err:any, user:User_t) => { - // console.log(err); if (err) user_data = undefined; else @@ -55,7 +54,11 @@ function tokenDecode(req: express.Request): User_t { router.post(ROUTE+'/user', (req: express.Request, res: express.Response) => { const a = req.body as User_t; - + const token = req.headers['authorization'] && req.headers['authorization'].split(' ')[1] + + if (a.admin && !isAdmin(token)) + return res.status(StatusCodes.UNAUTHORIZED).end(); + if (a.username === undefined || a.password === undefined) { @@ -87,36 +90,48 @@ router.get(ROUTE+'/user', (req: express.Request, res: express.Response) => { router.patch(ROUTE+'/user/:id', (req: express.Request, res: express.Response) => { const a = req.body as User_t; + const token = req.headers['authorization'] && req.headers['authorization'].split(' ')[1] + const id: number = +req.params.id; - // if (a.username === undefined || - // a.password === undefined || - // a.type === undefined) { - - // res.statusMessage = "invalid JSON"; - // res.status(StatusCodes.BAD_REQUEST).end(); - // return; - // } + if (a.admin && !isAdmin(token)) + res.status(StatusCodes.UNAUTHORIZED).end(); + + if (a.username === undefined || + a.admin === undefined) { - console.log(a); + res.statusMessage = "invalid JSON"; + res.status(StatusCodes.BAD_REQUEST).end(); + return; + } - if (a.admin === true) - if (!isAdmin(req.headers['authorization'] && req.headers['authorization'].split(' ')[1])) - res.status(StatusCodes.UNAUTHORIZED).end(); - const user = tokenDecode(req); - - if (a.username != user.username) - DBHandler.verifyUsernameExistence(a.username) - .then(exists => { - if(exists) - return res.status(StatusCodes.CONFLICT).end(); + DBHandler.getUserById(id).then(user => { + if (!isAdmin(token)) + user = tokenDecode(req); + + if (a.username !== user.username) + DBHandler.verifyUsernameExistence(a.username) + .then(exists => { + if(exists) + return res.status(StatusCodes.CONFLICT).end(); + }) - DBHandler.updateUser(req, res); - }) - + DBHandler.updateUser(req, res); + }) }); router.delete(ROUTE+"/user/:id", (req: express.Request, res: express.Response) => { + const token = req.headers['authorization'] && req.headers['authorization'].split(' ')[1]; + const id: number = +req.params.id; + + if(!isAdmin(token)) { + DBHandler.getUserById(id) + .then(user => { + if (user.username !== tokenDecode(req).username) + return res.status(StatusCodes.UNAUTHORIZED).end(); + }) + } + DBHandler.deleteUser(req, res); }) @@ -127,11 +142,10 @@ router.post(ROUTE+'/question', (req: express.Request, res: express.Response) => if (a.question === undefined || a.category === undefined) { - res.statusCode = 400; res.statusMessage = "invalid JSON"; - res.end(); - return; + return res.status(StatusCodes.BAD_REQUEST).end(); } + DBHandler.verifyQuestionExistence(a.question) .then(exists => { @@ -151,10 +165,19 @@ router.get(ROUTE+'/question', (req: express.Request, res: express.Response) => { }) router.patch(ROUTE+'/question/:id', (req: express.Request, res: express.Response) => { + const token = req.headers['authorization'] && req.headers['authorization'].split(' ')[1]; + + if(!isAdmin(token)) + return res.status(StatusCodes.UNAUTHORIZED).end() + DBHandler.updateQuestion(req, res); }) router.delete(ROUTE+'/question/:id', (req: express.Request, res: express.Response) => { + const token = req.headers['authorization'] && req.headers['authorization'].split(' ')[1]; + if(!isAdmin(token)) + return res.status(StatusCodes.UNAUTHORIZED).end(); + DBHandler.deleteQuestion(req, res); }) @@ -165,12 +188,20 @@ router.get(ROUTE+'/answer/:questionId', (req: express.Request, res: express.Resp }) router.post(ROUTE+'/answer', (req: express.Request, res: express.Response) => { + const token = req.headers['authorization'] && req.headers['authorization'].split(' ')[1]; + if(!isAdmin(token)) + return res.status(StatusCodes.UNAUTHORIZED).end(); + DBHandler.postAnwsers(req, res); }) // CATEGORIES CRUD router.post(ROUTE+'/category', (req: express.Request, res: express.Response) => { + const token = req.headers['authorization'] && req.headers['authorization'].split(' ')[1]; + if(!isAdmin(token)) + return res.status(StatusCodes.UNAUTHORIZED).end(); + DBHandler.postCategory(req, res); }) @@ -179,6 +210,10 @@ router.get(ROUTE+'/category', (req: express.Request, res: express.Response) => { }) router.delete(ROUTE+"/category", (req: express.Request, res: express.Response) => { + const token = req.headers['authorization'] && req.headers['authorization'].split(' ')[1]; + if(!isAdmin(token)) + return res.status(StatusCodes.UNAUTHORIZED).end(); + DBHandler.deleteCategory(req, res); }) diff --git a/frontend/src/app/admin/admin.component.ts b/frontend/src/app/admin/admin.component.ts index 33e62978f3ad26afbf36ee3ad38184ac2cc3e93e..a09535bf6c0a099544545d911e45287305c38493 100644 --- a/frontend/src/app/admin/admin.component.ts +++ b/frontend/src/app/admin/admin.component.ts @@ -4,6 +4,8 @@ import { Answer, QandA, Question, User } from '../Types/types'; import { UsersService } from '../services/users.service'; import { QuestionsService } from '../services/questions.service'; import { Subscription } from 'rxjs'; +import { AuthenticationService } from '../services/authentication.service'; +import { Router } from '@angular/router'; @Component({ selector: 'app-admin', @@ -15,8 +17,6 @@ export class AdminComponent implements OnInit { public users!: User[]; public questions!: Question[]; public answers!: Answer[]; - private usersSub!: Subscription; - private questionsSub!: Subscription; userToEdit!: User; modalUpdate: boolean = false; @@ -24,19 +24,22 @@ export class AdminComponent implements OnInit { modalQuestionCreate: boolean = false; constructor( - private http: HttpClient, + private router: Router, private userController: UsersService, - private questionController: QuestionsService) { } + private questionController: QuestionsService, + private auth: AuthenticationService) { } ngOnInit(): void { + if(!this.auth.isAdmin()) + this.router.navigateByUrl("/"); - this.usersSub = this.userController.users.subscribe(userList => { + this.userController.users.subscribe(userList => { this.users = userList; }); this.userController.fetchUsers(); - this.questionsSub = this.questionController.questions.subscribe(questionList => { + this.questionController.questions.subscribe(questionList => { this.questions = questionList; }) diff --git a/frontend/src/app/app.component.html b/frontend/src/app/app.component.html index ae3f9f44012c65c334b11b3e6eda347fde4d090b..7acbaf104a60a108a93c6f5a3e4435fdc3ee25b2 100644 --- a/frontend/src/app/app.component.html +++ b/frontend/src/app/app.component.html @@ -4,7 +4,7 @@ <h2 class="mr-6 border-2 border-transparent font-bold">Navbar</h2> <div> <button class="mr-4 border-2 border-transparent hover:border-solid hover:border-white hover:border-2 hover:rounded-lg px-2" (click)="router.navigateByUrl('/');">Home</button> - <button class="border-2 border-transparent hover:border-solid hover:border-white hover:border-2 hover:rounded-lg px-2" *ngIf="auth.isAdmin()" (click)="router.navigateByUrl('/admin')">Dashboard</button> + <button class="border-2 border-transparent hover:border-solid hover:border-white hover:border-2 hover:rounded-lg px-2" *ngIf="this.auth.isAdmin()" (click)="router.navigateByUrl('/admin')">Dashboard</button> </div> </div> <div class="flex flex-row"> diff --git a/frontend/src/app/app.component.ts b/frontend/src/app/app.component.ts index 0e30aeb4cae4d70cacc3954f4eb7435d14494240..312da32390f5447fd50408407356a37910604a54 100644 --- a/frontend/src/app/app.component.ts +++ b/frontend/src/app/app.component.ts @@ -13,4 +13,10 @@ export class AppComponent { constructor( public router: Router, public auth: AuthenticationService) {} + + + dashboardButton(): boolean { + console.log(this.auth.isAdmin()) + return this.auth.isAdmin(); + } } diff --git a/frontend/src/app/services/authentication.service.ts b/frontend/src/app/services/authentication.service.ts index ab540bc734ddc49b4f690227c5533b03ca9928e2..e58e3f7c79f6cf65ce8938300c3558f04ae2d872 100644 --- a/frontend/src/app/services/authentication.service.ts +++ b/frontend/src/app/services/authentication.service.ts @@ -20,10 +20,6 @@ export class AuthenticationService { username, password } - const headers = new Headers({ - 'Content-Type': 'application/json' - }); - this.http.post('http://0.0.0.0:30992/API/v1/login', body, {observe: 'response'}) .subscribe(res => { if(res.ok) { @@ -54,7 +50,7 @@ export class AuthenticationService { } } - isAdmin(): Boolean { + isAdmin(): boolean { const user = this.getDecodedAccessToken() as User; if (user === null) diff --git a/frontend/src/app/services/users.service.ts b/frontend/src/app/services/users.service.ts index ec3ff594f1ca7ba0d4b9db57cb656871ced8c674..7ceb9a34cee6fe06135122d896a8fbf308d41110 100644 --- a/frontend/src/app/services/users.service.ts +++ b/frontend/src/app/services/users.service.ts @@ -24,6 +24,7 @@ export class UsersService { } addUser(user: User) { + this.http.post<User>(ROUTE, user).subscribe(() => { this.auth.login(user.username, user.password); });