forked from fr/deguapp
		
	Added: auth logout api
This commit is contained in:
		@@ -21,6 +21,7 @@
 | 
				
			|||||||
	"dependencies": {
 | 
						"dependencies": {
 | 
				
			||||||
		"bcrypt": "^5.1.1",
 | 
							"bcrypt": "^5.1.1",
 | 
				
			||||||
		"colors": "1.4.0",
 | 
							"colors": "1.4.0",
 | 
				
			||||||
 | 
							"cookie-parser": "^1.4.6",
 | 
				
			||||||
		"dotenv": "^16.4.5",
 | 
							"dotenv": "^16.4.5",
 | 
				
			||||||
		"express": "^4.19.2",
 | 
							"express": "^4.19.2",
 | 
				
			||||||
		"fs-extra": "^10.0.0",
 | 
							"fs-extra": "^10.0.0",
 | 
				
			||||||
@@ -37,6 +38,7 @@
 | 
				
			|||||||
		"@biomejs/biome": "1.7.1",
 | 
							"@biomejs/biome": "1.7.1",
 | 
				
			||||||
		"@types/bcrypt": "^5.0.2",
 | 
							"@types/bcrypt": "^5.0.2",
 | 
				
			||||||
		"@types/chai": "^4.2.22",
 | 
							"@types/chai": "^4.2.22",
 | 
				
			||||||
 | 
							"@types/cookie-parser": "^1.4.7",
 | 
				
			||||||
		"@types/express": "^4.17.21",
 | 
							"@types/express": "^4.17.21",
 | 
				
			||||||
		"@types/fs-extra": "^9.0.13",
 | 
							"@types/fs-extra": "^9.0.13",
 | 
				
			||||||
		"@types/inquirer": "^8.1.3",
 | 
							"@types/inquirer": "^8.1.3",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,8 @@
 | 
				
			|||||||
import express from "express";
 | 
					import express from "express";
 | 
				
			||||||
import morgan from "morgan";
 | 
					import morgan from "morgan";
 | 
				
			||||||
//import path from 'path'
 | 
					import path from 'path'
 | 
				
			||||||
//import cors from 'cors'
 | 
					//import cors from 'cors'
 | 
				
			||||||
//import cookieParser from 'cookie-parser'
 | 
					import cookieParser from 'cookie-parser'
 | 
				
			||||||
import { router as routes } from "./routes";
 | 
					import { router as routes } from "./routes";
 | 
				
			||||||
//import { router as middlewares } from './middlewares'
 | 
					//import { router as middlewares } from './middlewares'
 | 
				
			||||||
//import env from './config/environment'
 | 
					//import env from './config/environment'
 | 
				
			||||||
@@ -35,8 +35,8 @@ export const app = express();
 | 
				
			|||||||
app.use(morgan("dev"));
 | 
					app.use(morgan("dev"));
 | 
				
			||||||
app.use(express.urlencoded({ extended: true }));
 | 
					app.use(express.urlencoded({ extended: true }));
 | 
				
			||||||
app.use(express.json());
 | 
					app.use(express.json());
 | 
				
			||||||
//app.use(express.static(path.join(__dirname, 'public')))
 | 
					app.use(express.static(path.join(__dirname, 'public')))
 | 
				
			||||||
//app.use(cookieParser())
 | 
					app.use(cookieParser())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Routes
 | 
					// Routes
 | 
				
			||||||
app.use(routes);
 | 
					app.use(routes);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										90
									
								
								api/src/middlewares/authMiddleware.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								api/src/middlewares/authMiddleware.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
				
			|||||||
 | 
					import { Request, Response, NextFunction } from 'express';
 | 
				
			||||||
 | 
					import jwt from 'jsonwebtoken';
 | 
				
			||||||
 | 
					import env from '../config/environment';
 | 
				
			||||||
 | 
					import { Log } from 'nork';
 | 
				
			||||||
 | 
					import User from '../models/User';
 | 
				
			||||||
 | 
					import { isValidObjectId } from 'mongoose';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function requireAuth(req: Request, res: Response, next: NextFunction) {
 | 
				
			||||||
 | 
						const token = req.cookies?.jwt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (token) {
 | 
				
			||||||
 | 
							jwt.verify(token, env.JWT_SECRET, async (err: any, decodedToken: any) => {
 | 
				
			||||||
 | 
								if (err) {
 | 
				
			||||||
 | 
									// console.error(err.message)
 | 
				
			||||||
 | 
									res.status(401).send(Log.error(401, 'user is not authenticated'));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (!err) {
 | 
				
			||||||
 | 
									const user = await User.findById(decodedToken.id);
 | 
				
			||||||
 | 
									if (user === null) {
 | 
				
			||||||
 | 
										res.status(401).send(Log.error(401, 'user is not authenticated'));
 | 
				
			||||||
 | 
										return;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									res.locals.user = user;
 | 
				
			||||||
 | 
									Log.info(100, 'user is authenticated');
 | 
				
			||||||
 | 
									next();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!token) {
 | 
				
			||||||
 | 
							res.status(401).send(Log.error(401, 'user is not authenticated'));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function requireVerified(req: Request, res: Response, next: NextFunction) {
 | 
				
			||||||
 | 
						if (res.locals.user._id) {
 | 
				
			||||||
 | 
							if (res.locals.user.verified) {
 | 
				
			||||||
 | 
								Log.info(100, 'user is verified');
 | 
				
			||||||
 | 
								next();
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							res.status(403).json(Log.error(403, 'user is not verified'));
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!res.locals.user._id) {
 | 
				
			||||||
 | 
							res.status(401).send(Log.error(401, 'user is not authenticated'));
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class requireRole {
 | 
				
			||||||
 | 
						static Admin(req: Request, res: Response, next: NextFunction) {
 | 
				
			||||||
 | 
							if (res.locals.user.admin) {
 | 
				
			||||||
 | 
								Log.info(100, 'user is admin');
 | 
				
			||||||
 | 
								next();
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							res.status(403).json(Log.error(403, 'insufficient permissions'));
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						static Owner(req: Request, res: Response, next: NextFunction) {
 | 
				
			||||||
 | 
							try {
 | 
				
			||||||
 | 
								if (!isValidObjectId(req.body.domain_id)) {
 | 
				
			||||||
 | 
									throw Log.error(400, 'neznámé domain_id');
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								const domain = res.locals.user.domains.filter((domain: any) => domain.domain_id == req.body.domain_id);
 | 
				
			||||||
 | 
								console.log(domain);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (domain.length < 1) {
 | 
				
			||||||
 | 
									throw Log.error(400, 'neznámé domain_id');
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (domain[0].role == 1) {
 | 
				
			||||||
 | 
									Log.info(100, 'user is owner');
 | 
				
			||||||
 | 
									next();
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								res.status(403).json(Log.error(403, 'insufficient permissions'));
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							} catch (err: any) {
 | 
				
			||||||
 | 
								res.status(400).json(err);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						static Editor(req: Request, res: Response, next: NextFunction) {}
 | 
				
			||||||
 | 
						static Guest(req: Request, res: Response, next: NextFunction) {}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -3,7 +3,7 @@ import * as authController from "../controllers/authController";
 | 
				
			|||||||
import validate from '../middlewares/validateRequest'
 | 
					import validate from '../middlewares/validateRequest'
 | 
				
			||||||
import * as AuthVal from '../validators/authValidator'
 | 
					import * as AuthVal from '../validators/authValidator'
 | 
				
			||||||
//import handleValidation from "../middlewares/handleValidation";
 | 
					//import handleValidation from "../middlewares/handleValidation";
 | 
				
			||||||
//import { requireAuth } from "../middlewares/authMiddleware";
 | 
					import { requireAuth } from "../middlewares/authMiddleware";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const router = Router();
 | 
					const router = Router();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -11,6 +11,7 @@ const router = Router();
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
router.post("/auth/signup",validate(AuthVal.signup) , authController.signup_post);
 | 
					router.post("/auth/signup",validate(AuthVal.signup) , authController.signup_post);
 | 
				
			||||||
router.post("/auth/signin",validate(AuthVal.signin) , authController.signin_post);
 | 
					router.post("/auth/signin",validate(AuthVal.signin) , authController.signin_post);
 | 
				
			||||||
 | 
					router.post("/auth/logout", requireAuth, authController.logout_post);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//router.post(
 | 
					//router.post(
 | 
				
			||||||
//  "/login",
 | 
					//  "/login",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -190,9 +190,6 @@ describe('POST /api/v1/auth/signin', () => {
 | 
				
			|||||||
	});
 | 
						});
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Throws errors idk
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
describe('POST /api/v1/auth/logout', () => {
 | 
					describe('POST /api/v1/auth/logout', () => {
 | 
				
			||||||
	const url = '/api/v1/auth/logout';
 | 
						const url = '/api/v1/auth/logout';
 | 
				
			||||||
	test('should drop 401 error', async () => {
 | 
						test('should drop 401 error', async () => {
 | 
				
			||||||
@@ -202,18 +199,13 @@ describe('POST /api/v1/auth/logout', () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	test('should logout an user', async () => {
 | 
						test('should logout an user', async () => {
 | 
				
			||||||
		const jwt = await login();
 | 
							const jwt = await login();
 | 
				
			||||||
		const res = await request.post(url).set('Cookie', jwt).send({});
 | 
							const res = await request.post(url).set('Cookie', jwt).send();
 | 
				
			||||||
 | 
					 | 
				
			||||||
		res.headers['set-cookie'].forEach((el: any) => {
 | 
					 | 
				
			||||||
			if (el.split('=')[0] == 'jwt') {
 | 
					 | 
				
			||||||
				expect(Number(el.split('=')[2][0])).toBe(0);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		expect(res.statusCode).toBe(200);
 | 
							expect(res.statusCode).toBe(200);
 | 
				
			||||||
 | 
							expect(res.header['set-cookie'][0]).toContain("jwt=; Max-Age=0")
 | 
				
			||||||
 | 
							expect(res.header['set-cookie'][1]).toContain("auth=false")
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
describe('GET /api/v1/auth/status', () => {
 | 
					describe('GET /api/v1/auth/status', () => {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user