Compare commits

...

3 Commits

Author SHA1 Message Date
cdc5970b3a Added: api auth status 2024-05-02 01:19:44 +02:00
de8ff025fa Added: auth logout api 2024-05-02 01:15:55 +02:00
09c30d28d4 Added: signin api 2024-05-02 00:37:59 +02:00
5 changed files with 110 additions and 46 deletions

View File

@ -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",

View File

@ -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);

View 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) {}
}

View File

@ -2,36 +2,13 @@ import { Router } from "express";
import * as authController from "../controllers/authController"; 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 { requireAuth } from "../middlewares/authMiddleware";
//import { requireAuth } from "../middlewares/authMiddleware";
const router = Router(); const router = Router();
//const mws = [requireAuth, handleValidation.handleValidationError];
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/logout", requireAuth, authController.logout_post);
router.get("/auth/status", requireAuth, authController.status_get);
//router.post( export default router;
// "/login",
// authValidator.checkUserLogin(),
// handleValidation.handleValidationError,
// userController.login_post
//);
//router.post(
// "/register",
// authValidator.checkUserRegister(),
// handleValidation.handleValidationError,
// userController.register_post
//);
//router.post("/logout", userController.logout_post);
//router.post(
// "/edit",
// [requireAuth],
// authValidator.checkChange(),
// userController.edit_post
//);
export default router;

View File

@ -172,7 +172,10 @@ describe('POST /api/v1/auth/signin', () => {
email: 'thisistest@host.local', email: 'thisistest@host.local',
password: 'Test12365465132' password: 'Test12365465132'
}); });
expect(res.statusCode).toBe(401); expect(res.statusCode).toBe(401);
expect(res.header['set-cookie'][0]).toContain("jwt=; Max-Age=0")
expect(res.header['set-cookie'][1]).toContain("auth=false")
}); });
test('should login an user', async () => { test('should login an user', async () => {
@ -182,12 +185,11 @@ describe('POST /api/v1/auth/signin', () => {
}); });
expect(res.statusCode).toBe(200); expect(res.statusCode).toBe(200);
expect(res.header['set-cookie'][0]).toContain("jwt=")
expect(res.header['set-cookie'][1]).toContain("auth=true")
}); });
}); });
/**
* 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 () => {
@ -197,20 +199,14 @@ 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', () => {
const url = '/api/v1/auth/status'; const url = '/api/v1/auth/status';
test('should return login status 401', async () => { test('should return login status 401', async () => {
@ -222,5 +218,4 @@ describe('GET /api/v1/auth/status', () => {
const res = await request.get(url).set('Cookie', jwt).send(); const res = await request.get(url).set('Cookie', jwt).send();
expect(res.statusCode).toBe(200); expect(res.statusCode).toBe(200);
}); });
}); });
*/