Compare commits

..

No commits in common. "28671146d10497451856840388bb554d1869d176" and "91b88ea59266d35bed4b3281768a29463dabf435" have entirely different histories.

34 changed files with 1174 additions and 1716 deletions

8
.idea/biome.xml generated
View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="BiomeSettings">
<option name="configPath" value="$PROJECT_DIR$" />
<option name="configurationMode" value="MANUAL" />
<option name="formatOnSave" value="true" />
</component>
</project>

View File

@ -3,15 +3,6 @@
"organizeImports": { "organizeImports": {
"enabled": true "enabled": true
}, },
"files": {
"include": [
"./src/**/*.ts"
]
},
"vcs": {
"enabled": true,
"clientKind": "git"
},
"linter": { "linter": {
"enabled": true, "enabled": true,
"rules": { "rules": {
@ -26,8 +17,8 @@
} }
}, },
"formatter": { "formatter": {
"indentStyle": "tab", "indentStyle": "space",
"indentWidth": 2, "indentWidth": 2,
"lineWidth": 64 "lineWidth": 15
} }
} }

View File

@ -7,8 +7,7 @@
"author": "Mathis HERRIOT", "author": "Mathis HERRIOT",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"bun:dev": "bun run --watch src/app.ts", "bun:dev": "bun run --watch src/app.ts"
"bun:check": "bunx biome check --skip-errors --apply src"
}, },
"dependencies": { "dependencies": {
"@node-rs/argon2": "^1.8.3", "@node-rs/argon2": "^1.8.3",

View File

@ -1,22 +1,21 @@
import * as process from "node:process"; import express, { type Express } from 'express';
import cors from 'cors';
import compression from 'compression';
import {Logger} from "tslog";
import helmet from "helmet";
import AuthRouter from "@routes/auth/authRouter"; import AuthRouter from "@routes/auth/authRouter";
import CatalogRouter from "@routes/catalog/catalogRouter"; import CatalogRouter from "@routes/catalog/catalogRouter";
import RentRouter from "@routes/rent/rentRouter"; import RentRouter from "@routes/rent/rentRouter";
import compression from "compression"; import * as process from "node:process";
import cors from "cors";
import express, { type Express } from "express";
import helmet from "helmet";
import { Logger } from "tslog";
const logger = new Logger({
name: "App", const logger = new Logger({ name: "App" });
});
const app: Express = express(); const app: Express = express();
// enable cors // enable cors
app.use(cors()); app.use(cors());
app.options("*", cors()); app.options('*', cors());
// enable xss sanitizer // enable xss sanitizer
app.use( app.use(
@ -24,35 +23,31 @@ app.use(
xXssProtection: true, xXssProtection: true,
}), }),
); );
app.use(helmet.xXssProtection()); app.use(helmet.xXssProtection())
// parse json request body // parse json request body
app.use(express.json()); app.use(express.json());
// parse urlencoded request body // parse urlencoded request body
app.use( app.use(express.urlencoded({ extended: true }));
express.urlencoded({
extended: true,
}),
);
// gzip compression // gzip compression
app.use(compression()); app.use(compression())
try { try {
app.use("/auth", AuthRouter); app.use('/auth', AuthRouter)
app.use("/catalog", CatalogRouter); app.use('/catalog', CatalogRouter)
app.use("/rent", RentRouter); app.use('/rent', RentRouter)
logger.info("Routers loaded !"); logger.info('Routers loaded !')
} catch (err) { } catch (err) {
logger.error(err); logger.error(err)
throw null; throw null;
} }
try { try {
app.listen(process.env["APP_PORT"]); app.listen(process.env["APP_PORT"])
logger.info("Server is running !"); logger.info('Server is running !')
} catch (error) { } catch (error) {
logger.error(`Server failed to start: ${error}`); logger.error(`Server failed to start: ${error}`);
process.exit(1); process.exit(1);
} }

View File

@ -1,13 +1,13 @@
import JwtService from "@services/jwt.service"; import JwtService from "@services/jwt.service";
import type { IReqEditUserData } from "@interfaces/IReqEditUserData";
import UserService from "@services/user.service";
import type { Request, Response } from "express";
import { Logger } from "tslog";
const logger = new Logger({ import type {IReqEditUserData} from "@interfaces/IReqEditUserData";
name: "AuthController", import UserService from "@services/user.service";
}); import type {Request, Response} from "express";
import {Logger} from "tslog";
const logger = new Logger({ name: "AuthController" });
//FIX Better return object interface //FIX Better return object interface
/** /**
@ -22,65 +22,60 @@ const logger = new Logger({
* - error: "exist" if the user already exists * - error: "exist" if the user already exists
* - Otherwise, the registered user data * - Otherwise, the registered user data
*/ */
async function registerUser( async function registerUser(req: Request, res: Response): Promise<unknown> {
req: Request,
res: Response,
): Promise<unknown> {
const body = req.body; const body = req.body;
if (!body) { if (!body) {
logger.warn(`Invalid input data (${req.ip})`); logger.warn(`Invalid input data (${req.ip})`);
return res.type("application/json").status(400).json({ return res
error: "Invalid input data", .type('application/json')
}); .status(400)
.json({ error: 'Invalid input data' });
} }
if ( if (!body.password || !body.username || !body.firstName || !body.lastName || !body.displayName) {
!body.password ||
!body.username ||
!body.firstName ||
!body.lastName ||
!body.displayName
) {
logger.warn(`Field(s) missing (${req.ip})`); logger.warn(`Field(s) missing (${req.ip})`);
return res.type("application/json").status(400).json({ return res
error: "Field(s) missing", .type('application/json')
}); .status(400)
.json({ error: 'Field(s) missing' });
} }
let gdpr = false; let gdpr = false
if (body.gdpr === true) { if (body.gdpr === true) {gdpr = true}
gdpr = true; const sanitizeData= {
} username: `${body.username}`,
const sanitizeData = { displayName: `${body.displayName}`,
username: `${body.username}`, gdpr: gdpr,
displayName: `${body.displayName}`, password: `${body.password}`,
gdpr: gdpr, firstName: `${body.firstName}`,
password: `${body.password}`, lastName: `${body.lastName}`,
firstName: `${body.firstName}`,
lastName: `${body.lastName}`,
}; };
const RegisterServiceResult = const RegisterServiceResult = await UserService.register(sanitizeData)
await UserService.register(sanitizeData);
if (RegisterServiceResult.error === "gdprNotApproved") { if (RegisterServiceResult.error === "gdprNotApproved") {
logger.warn(`GDPR not approved (${req.ip})`); logger.warn(`GDPR not approved (${req.ip})`);
return res.status(400).json({ return res
error: RegisterServiceResult.error, .status(400)
message: "GDPR not accepted.", .json({
}); error: RegisterServiceResult.error,
message: "GDPR not accepted."
});
} }
if (RegisterServiceResult.error === "exist") { if (RegisterServiceResult.error === "exist") {
logger.warn(`The user already exists (${req.ip})`); logger.warn(`The user already exists (${req.ip})`);
return res.type("application/json").status(400).json({ return res
error: RegisterServiceResult.error, .type('application/json')
message: "The user already exists.", .status(400)
}); .json({
error: RegisterServiceResult.error,
message: "The user already exists."
});
} }
// SUCCESS // SUCCESS
logger.info(`User registered successfully (${req.ip})`); logger.info(`User registered successfully (${req.ip})`);
return res return res
.type("application/json") .type('application/json')
.status(201) .status(201)
.json(RegisterServiceResult); .json(RegisterServiceResult);
} }
@ -93,352 +88,378 @@ async function registerUser(
* *
* @return {Promise<void>} A promise that resolves when the user is logged in or rejects with an error. * @return {Promise<void>} A promise that resolves when the user is logged in or rejects with an error.
*/ */
async function loginUser( async function loginUser(req: Request, res: Response): Promise<void> {
req: Request,
res: Response,
): Promise<void> {
const body = req.body; const body = req.body;
if (!body) { if (!body) {
res.type("application/json").status(400).json({ res
error: "Invalid input data", .type('application/json')
}); .status(400)
.json({ error: 'Invalid input data' });
} }
if (!body.password || !body.username) { if (!body.password || !body.username) {
logger.warn(`Field(s) missing (${req.ip})`); logger.warn(`Field(s) missing (${req.ip})`);
res.type("application/json").status(400).json({ res
error: "Field(s) missing", .type('application/json')
}); .status(400)
.json({ error: 'Field(s) missing' });
} }
const loginData = { const loginData = {
username: `${body.username}`, username: `${body.username}`,
password: `${body.password}`, password: `${body.password}`
}; };
console.log(body); console.log(body)
const LoginServiceResult = await UserService.login(loginData); const LoginServiceResult = await UserService.login(loginData);
console.log(LoginServiceResult); console.log(LoginServiceResult)
if (LoginServiceResult.error === "userNotFound") { if (LoginServiceResult.error === "userNotFound") {
console.log("POOL"); console.log('POOL')
res.type("application/json").status(404).json({ res
error: LoginServiceResult.error, .type('application/json')
message: "User not found.", .status(404)
}); .json({
error: LoginServiceResult.error,
message: "User not found."
});
} }
if (LoginServiceResult.error === "invalidPassword") { if (LoginServiceResult.error === "invalidPassword") {
res.type("application/json").status(401).json({ res
error: LoginServiceResult.error, .type('application/json')
message: "Invalid password.", .status(401)
}); .json({
error: LoginServiceResult.error,
message: "Invalid password."
});
} }
res res
.type("application/json") .type('application/json')
.status(200) .status(200)
.json(LoginServiceResult); .json(LoginServiceResult);
} }
async function getAllUsers(req: Request, res: Response) { async function getAllUsers(req: Request, res: Response) {
const authHeader = req.headers.authorization; const authHeader = req.headers.authorization;
const bearerToken = authHeader?.split(" ")[1]; const bearerToken = authHeader?.split(' ')[1];
if (!bearerToken) { if (!bearerToken) {
logger.warn(`Bearer token not provided (${req.ip})`); logger.warn(`Bearer token not provided (${req.ip})`);
return res.type("application/json").status(401).json({ return res
error: "Unauthorized", .type('application/json')
}); .status(401)
.json({ error: 'Unauthorized' });
} }
const payload = await JwtService.verify(bearerToken); const payload = await JwtService.verify(bearerToken);
if (!payload) { if (!payload) {
logger.warn(`Unauthorized access attempt (${req.ip})`); logger.warn(`Unauthorized access attempt (${req.ip})`);
return res.type("application/json").status(401).json({ return res
error: "Unauthorized", .type('application/json')
}); .status(401)
.json({ error: 'Unauthorized' });
} }
const sourceUser = await UserService.getFromId(payload.sub); const sourceUser = await UserService.getFromId(payload.sub)
if (!sourceUser) { if (!sourceUser) {
return res.type("application/json").status(404).json({ return res
error: "You dont exist anymore", .type('application/json')
}); .status(404)
.json({ error: 'You dont exist anymore' });
} }
if (!sourceUser.is_admin) { if (!sourceUser.is_admin) {
return res.type("application/json").status(403).json({ return res
error: "Unauthorized", .type('application/json')
}); .status(403)
.json({ error: 'Unauthorized' });
} }
const AllUserResponse = await UserService.getAll(); const AllUserResponse = await UserService.getAll()
if (!AllUserResponse.users) { if (!AllUserResponse.users) {
return res.type("application/json").status(500).json({ return res
error: "Internal server error", .type('application/json')
}); .status(500)
.json({ error: 'Internal server error' });
} }
return res return res
.type("application/json") .type('application/json')
.status(200) .status(200)
.json(AllUserResponse); .json(AllUserResponse);
} }
async function getUser(req: Request, res: Response) { async function getUser(req: Request, res: Response) {
const authHeader = req.headers.authorization; const authHeader = req.headers.authorization;
const bearerToken = authHeader?.split(" ")[1]; const bearerToken = authHeader?.split(' ')[1];
if (!bearerToken) { if (!bearerToken) {
logger.warn(`Bearer token not provided (${req.ip})`); logger.warn(`Bearer token not provided (${req.ip})`);
return res.type("application/json").status(401).json({ return res
error: "Unauthorized", .type('application/json')
}); .status(401)
.json({ error: 'Unauthorized' });
} }
const payload = await JwtService.verify(bearerToken); const payload = await JwtService.verify(bearerToken);
if (!payload) { if (!payload) {
logger.warn(`Unauthorized access attempt (${req.ip})`); logger.warn(`Unauthorized access attempt (${req.ip})`);
return res.type("application/json").status(401).json({ return res
error: "Unauthorized", .type('application/json')
}); .status(401)
.json({ error: 'Unauthorized' });
} }
const sourceUser = await UserService.getFromId(payload.sub); const sourceUser = await UserService.getFromId(payload.sub)
if (!sourceUser) { if (!sourceUser) {
return res.type("application/json").status(404).json({ return res
error: "You dont exist anymore", .type('application/json')
}); .status(404)
.json({ error: 'You dont exist anymore' });
} }
if (!sourceUser.is_admin) { if (!sourceUser.is_admin) {
return res.type("application/json").status(403).json({ return res
error: "Unauthorized", .type('application/json')
}); .status(403)
.json({ error: 'Unauthorized' });
} }
const userId = req.params["id"]; const userId = req.params["id"];
const dbUser = await UserService.getFromId(userId); const dbUser = await UserService.getFromId(userId);
if (!dbUser) { if (!dbUser) {
logger.warn(`User not found (${req.ip})`); logger.warn(`User not found (${req.ip})`);
return res.type("application/json").status(404).json({ return res
error: "User not found", .type('application/json')
}); .status(404)
.json({ error: 'User not found' });
} }
// @ts-ignore // @ts-ignore
delete dbUser.passwordHash; delete dbUser.passwordHash
// @ts-ignore // @ts-ignore
delete dbUser._id; delete dbUser._id
return res.type("application/json").status(200).json(dbUser); return res
.type('application/json')
.status(200)
.json(dbUser);
} }
//FEAT - Implement re-auth by current password in case of password change //FEAT - Implement re-auth by current password in case of password change
async function editUser(req: Request, res: Response) { async function editUser(req: Request, res: Response) {
const body: IReqEditUserData | null = req.body; const body: IReqEditUserData | null = req.body;
if (!body) { if (!body) {
return res.type("application/json").status(400).json({ return res
error: "Field(s) missing", .type('application/json')
}); .status(400)
.json({ error: 'Field(s) missing' });
} }
const authHeader = req.headers.authorization; const authHeader = req.headers.authorization;
const bearerToken = authHeader?.split(" ")[1]; const bearerToken = authHeader?.split(' ')[1];
if (!bearerToken) { if (!bearerToken) {
logger.warn(`Bearer token not provided (${req.ip})`); logger.warn(`Bearer token not provided (${req.ip})`);
return res.type("application/json").status(401).json({ return res
error: "Unauthorized", .type('application/json')
}); .status(401)
.json({ error: 'Unauthorized' });
} }
const payload = await JwtService.verify(bearerToken); const payload = await JwtService.verify(bearerToken);
if (!payload) { if (!payload) {
logger.warn(`Unauthorized access attempt (${req.ip})`); logger.warn(`Unauthorized access attempt (${req.ip})`);
return res.type("application/json").status(401).json({ return res
error: "Unauthorized", .type('application/json')
}); .status(401)
.json({ error: 'Unauthorized' });
} }
const sourceUser = await UserService.getFromId(payload.sub); const sourceUser = await UserService.getFromId(payload.sub)
//@ts-ignore //@ts-ignore
const targetUserId = req.params.id || payload.sub; const targetUserId = req.params.id || payload.sub
console.log(targetUserId); console.log(targetUserId)
if (!sourceUser) { if (!sourceUser) {
logger.warn(`Unauthorized access attempt (${req.ip})`); logger.warn(`Unauthorized access attempt (${req.ip})`);
return res.type("application/json").status(404).json({ return res
error: "You dont exist anymore", .type('application/json')
}); .status(404)
.json({ error: 'You dont exist anymore' });
} }
if (sourceUser.is_admin || sourceUser.id === payload.sub) { if (sourceUser.is_admin || sourceUser.id === payload.sub) {
if (sourceUser.is_admin) { if (sourceUser.is_admin) {
logger.info( logger.info(`EDIT :> Source user is an admin (${sourceUser.firstname} ${sourceUser.lastname})`)
`EDIT :> Source user is an admin (${sourceUser.firstname} ${sourceUser.lastname})`,
);
} else { } else {
logger.info( logger.info(`EDIT :> Source user modify itself (${sourceUser.firstname} ${sourceUser.lastname})`)
`EDIT :> Source user modify itself (${sourceUser.firstname} ${sourceUser.lastname})`,
);
} }
//TODO Interface //TODO Interface
const modifiedData = {}; const modifiedData = {
}
//@ts-ignore //@ts-ignore
if (body.firstName) if (body.firstName) modifiedData.firstName = `${body.firstName}`;
modifiedData.firstName = `${body.firstName}`;
//@ts-ignore //@ts-ignore
if (body.lastName) if (body.lastName) modifiedData.lastName = `${body.lastName}`;
modifiedData.lastName = `${body.lastName}`;
//@ts-ignore //@ts-ignore
if (body.displayName) if (body.displayName) modifiedData.displayName = `${body.displayName}`;
modifiedData.displayName = `${body.displayName}`;
//TODO Case handled with hashing by the service. //TODO Case handled with hashing by the service.
//if (body.password) modifiedData.password = `${body.password}`; //if (body.password) modifiedData.password = `${body.password}`;
//Call service //Call service
const EditUserServiceResult = await UserService.edit( const EditUserServiceResult = await UserService.edit(`${targetUserId}`, modifiedData);
`${targetUserId}`, if (EditUserServiceResult.error === 'userNotFound') {
modifiedData,
);
if (EditUserServiceResult.error === "userNotFound") {
logger.warn(`User not found (${req.ip})`); logger.warn(`User not found (${req.ip})`);
return res.type("application/json").status(404).json({ return res
error: "User not found", .type('application/json')
}); .status(404)
.json({ error: 'User not found' });
} }
if (EditUserServiceResult.error !== "none") { if (EditUserServiceResult.error !== 'none') {
logger.error( logger.error(`Error occurred during user edit (${req.ip})`);
`Error occurred during user edit (${req.ip})`, return res
); .type('application/json')
return res.type("application/json").status(500).json({ .status(500)
error: "Internal server error", .json({ error: 'Internal server error' });
});
} }
return res return res
.type("application/json") .type('application/json')
.status(200) .status(200)
.json(EditUserServiceResult); .json(EditUserServiceResult);
} }
//Not itself or //Not itself or
logger.warn( logger.warn(`Unauthorized access attempt, not self or admin (${req.ip})`);
`Unauthorized access attempt, not self or admin (${req.ip})`, return res
); .type('application/json')
return res.type("application/json").status(403).json({ .status(403)
error: "Unauthorized", .json({ error: 'Unauthorized' });
});
} }
async function deleteUser( async function deleteUser(req: Request, res: Response): Promise<Response> {
req: Request,
res: Response,
): Promise<Response> {
const authHeader = req.headers.authorization; const authHeader = req.headers.authorization;
const bearerToken = authHeader?.split(" ")[1]; const bearerToken = authHeader?.split(' ')[1];
if (!bearerToken) { if (!bearerToken) {
logger.warn(`Bearer token not provided (${req.ip})`); logger.warn(`Bearer token not provided (${req.ip})`);
return res.type("application/json").status(401).json({ return res
error: "Unauthorized", .type('application/json')
}); .status(401)
.json({ error: 'Unauthorized' });
} }
const payload = await JwtService.verify(bearerToken); const payload = await JwtService.verify(bearerToken);
if (!payload) { if (!payload) {
logger.warn(`Invalid token (${req.ip})`); logger.warn(`Invalid token (${req.ip})`);
return res.type("application/json").status(401).json({ return res
error: "Invalid token", .type('application/json')
}); .status(401)
.json({ error: 'Invalid token' });
} }
const sourceUser = await UserService.getFromId(payload?.sub); const sourceUser = await UserService.getFromId(payload?.sub)
const targetUserId = req.params["id"]; const targetUserId = req.params["id"]
if (!sourceUser) { if (!sourceUser) {
logger.warn(`Unauthorized access attempt (${req.ip})`); logger.warn(`Unauthorized access attempt (${req.ip})`);
return res.type("application/json").status(404).json({ return res
error: "You dont exist anymore", .type('application/json')
}); .status(404)
.json({ error: 'You dont exist anymore' });
} }
if (sourceUser.is_admin || sourceUser.id === payload.sub) { if (sourceUser.is_admin || sourceUser.id === payload.sub) {
const deleteUserServiceResult = await UserService.delete( const deleteUserServiceResult = await UserService.delete(`${targetUserId}`);
`${targetUserId}`,
);
if (!deleteUserServiceResult) { if (!deleteUserServiceResult) {
logger.error( logger.error(`Error occurred during user delete (${req.ip})`);
`Error occurred during user delete (${req.ip})`, return res
); .type('application/json')
return res.type("application/json").status(500).json({ .status(500)
error: "Internal server error", .json({ error: 'Internal server error' });
});
} }
return res.type("application/json").status(200).json({ return res
message: "User deleted successfully", .type('application/json')
}); .status(200)
.json({ message: 'User deleted successfully' });
} }
return res.type("application/json").status(403).json({ return res
error: "Unauthorized", .type('application/json')
}); .status(403)
.json({ error: 'Unauthorized' });
} }
async function deleteSelf(req: Request, res: Response) { async function deleteSelf(req: Request, res: Response) {
const authHeader = req.headers.authorization; const authHeader = req.headers.authorization;
const bearerToken = authHeader?.split(" ")[1]; const bearerToken = authHeader?.split(' ')[1];
if (!bearerToken) { if (!bearerToken) {
logger.warn(`Bearer token not provided (${req.ip})`); logger.warn(`Bearer token not provided (${req.ip})`);
return res.type("application/json").status(401).json({ return res
error: "Unauthorized", .type('application/json')
}); .status(401)
} .json({ error: 'Unauthorized' });
const payload = await JwtService.verify(bearerToken); }
if (!payload) { const payload = await JwtService.verify(bearerToken);
logger.warn(`Unauthorized access attempt (${req.ip})`); if (!payload) {
return res.type("application/json").status(401).json({ logger.warn(`Unauthorized access attempt (${req.ip})`);
error: "Unauthorized", return res
}); .type('application/json')
} .status(401)
const sourceUser = await UserService.getFromId(payload.sub); .json({ error: 'Unauthorized' });
if (!sourceUser) { }
return res.type("application/json").status(404).json({ const sourceUser = await UserService.getFromId(payload.sub)
error: "You dont exist anymore", if (!sourceUser) {
}); return res
} .type('application/json')
if (sourceUser.id !== req.params["id"]) { .status(404)
return res.type("application/json").status(403).json({ .json({ error: 'You dont exist anymore' });
error: "Unauthorized", }
}); if (sourceUser.id !== req.params["id"]) {
} return res
const deleteResult = await UserService.delete(sourceUser.id); .type('application/json')
.status(403)
.json({ error: 'Unauthorized' });
}
const deleteResult = await UserService.delete(sourceUser.id);
if (!deleteResult) { if (!deleteResult) {
logger.error(`Failed to delete user (${req.ip})`); logger.error(`Failed to delete user (${req.ip})`);
return res.type("application/json").status(500).json({ return res
error: "Failed to delete user", .type('application/json')
}); .status(500)
.json({ error: 'Failed to delete user' });
} }
return res.type("application/json").status(200).json({ return res
message: "User deleted successfully", .type('application/json')
}); .status(200)
.json({ message: 'User deleted successfully' });
} }
async function getSelf(req: Request, res: Response) { async function getSelf(req: Request, res: Response) {
const authHeader = req.headers.authorization; const authHeader = req.headers.authorization;
const bearerToken = authHeader?.split(" ")[1]; const bearerToken = authHeader?.split(' ')[1];
if (!bearerToken) { if (!bearerToken) {
return res.type("application/json").status(401).json({ return res
error: "Unauthorized", .type('application/json')
}); .status(401)
.json({ error: 'Unauthorized' });
} }
const payload = await JwtService.verify(bearerToken); const payload = await JwtService.verify(bearerToken);
if (!payload) { if (!payload) {
logger.warn(`Unauthorized access attempt (${req.ip})`); logger.warn(`Unauthorized access attempt (${req.ip})`);
return res.type("application/json").status(401).json({ return res
error: "Unauthorized", .type('application/json')
}); .status(401)
} .json({ error: 'Unauthorized' });
const dbUser = await UserService.getFromId(payload.sub); }
const dbUser = await UserService.getFromId(payload.sub)
if (!dbUser) { if (!dbUser) {
return res.type("application/json").status(404).json({ return res
error: "User not found", .type('application/json')
}); .status(404)
.json({ error: 'User not found' });
} }
return res.type("application/json").status(200).json({ return res
id: dbUser.id, .type('application/json')
username: dbUser.username, .status(200)
firstName: dbUser.firstname, .json({
lastName: dbUser.firstname, id: dbUser.id,
isAdmin: dbUser.firstname, username: dbUser.username,
}); firstName: dbUser.firstname,
lastName: dbUser.firstname,
isAdmin: dbUser.firstname
});
} }
const AuthController = { const AuthController = {
register: registerUser, register: registerUser,
login: loginUser, login: loginUser,
getAllUsers, getAllUsers,
getUser, getUser,
editUser, editUser,
deleteUser, deleteUser,
deleteSelf, deleteSelf,
getSelf, getSelf
}; }
export default AuthController; export default AuthController;

View File

@ -1,13 +1,13 @@
import type { Request, Response } from "express"; import type {Request, Response} from "express";
import { Logger } from "tslog"; import {Logger} from "tslog";
import type IDbBrand from "@interfaces/database/IDbBrand"; import type IDbBrand from "@interfaces/database/IDbBrand";
import BrandService from "@services/brand.service"; import BrandService from "@services/brand.service";
//import {body} from "express-validator"; //import {body} from "express-validator";
const logger = new Logger({
name: "BrandController", const logger = new Logger({ name: "BrandController" });
});
/** /**
* Creates a new brand. * Creates a new brand.
@ -17,37 +17,24 @@ const logger = new Logger({
* *
* @returns A Promise that resolves to the response object with a status code and a JSON message indicating the success or failure of brand creation. * @returns A Promise that resolves to the response object with a status code and a JSON message indicating the success or failure of brand creation.
*/ */
async function createBrand( async function createBrand(req: Request, res: Response): Promise<Response> {
req: Request, const body: IDbBrand = req.body
res: Response, const doesExist = await BrandService.getBySlug(`${body.slug_name}`)
): Promise<Response> {
const body: IDbBrand = req.body;
const doesExist = await BrandService.getBySlug(
`${body.slug_name}`,
);
if (doesExist) { if (doesExist) {
logger.error("Brand already exists"); logger.error("Brand already exists");
return res.status(400).json({ return res.status(400).json({ error: "Brand already exists" });
error: "Brand already exists",
});
} }
const createResult = await BrandService.create({ const createResult = await BrandService.create({
slug_name: `${body.slug_name}`, slug_name: `${body.slug_name}`,
display_name: `${body.display_name}`, display_name: `${body.display_name}`,
image_blob: `${body.image_blob}`, image_blob: `${body.image_blob}`
}); })
if (!createResult) { if (!createResult) {
logger.error("Failed to create brand"); logger.error("Failed to create brand");
return res.status(500).json({ return res.status(500).json({ error: "Failed to create brand" });
error: "Failed to create brand",
});
} }
logger.info( logger.info(`Brand created successfully ! (${body.slug_name})`)
`Brand created successfully ! (${body.slug_name})`, return res.status(201).json({ message: "Brand created successfully" });
);
return res.status(201).json({
message: "Brand created successfully",
});
} }
/** /**
@ -57,40 +44,29 @@ async function createBrand(
* @param {Response} res - The HTTP response object. * @param {Response} res - The HTTP response object.
* @return {Promise<Response>} A promise that resolves with the HTTP response. * @return {Promise<Response>} A promise that resolves with the HTTP response.
*/ */
async function updateBrand( async function updateBrand(req: Request, res: Response): Promise<Response> {
req: Request,
res: Response,
): Promise<Response> {
const body: IDbBrand = req.body; const body: IDbBrand = req.body;
const brandSlug = req.params["brandSlug"]; const brandSlug = req.params["brandSlug"];
if (!brandSlug) { if (!brandSlug) {
logger.error("Brand slug is missing"); logger.error("Brand slug is missing");
return res.status(400).json({ return res.status(400).json({ error: "Brand slug is missing" });
error: "Brand slug is missing",
});
} }
const doesExist = await BrandService.getBySlug(brandSlug); const doesExist = await BrandService.getBySlug(brandSlug);
if (!doesExist) { if (!doesExist) {
logger.error("Brand not found"); logger.error("Brand not found");
return res.status(404).json({ return res.status(404).json({ error: "Brand not found" });
error: "Brand not found", }
}); const updateResult = await BrandService.update({
} slug_name: `${body.slug_name}`,
const updateResult = await BrandService.update({ display_name: `${body.display_name}`,
slug_name: `${body.slug_name}`, image_blob: `${body.image_blob}`
display_name: `${body.display_name}`, });
image_blob: `${body.image_blob}`, if (!updateResult) {
}); logger.error("Failed to update brand");
if (!updateResult) { return res.status(500).json({ error: "Failed to update brand" });
logger.error("Failed to update brand"); }
return res.status(500).json({ logger.info(`Brand updated successfully ! (${brandSlug})`);
error: "Failed to update brand", return res.status(200).json({ message: "Brand updated successfully" });
});
}
logger.info(`Brand updated successfully ! (${brandSlug})`);
return res.status(200).json({
message: "Brand updated successfully",
});
} }
/** /**
@ -100,26 +76,19 @@ async function updateBrand(
* @param {Response} res - The response object to send the result. * @param {Response} res - The response object to send the result.
* @returns {Promise<Response>} - A promise that resolves to the response with the retrieved brand. * @returns {Promise<Response>} - A promise that resolves to the response with the retrieved brand.
*/ */
async function getBySlugBrand( async function getBySlugBrand(req: Request, res: Response): Promise<Response> {
req: Request,
res: Response,
): Promise<Response> {
const brandSlug = req.params["brandSlug"]; const brandSlug = req.params["brandSlug"];
if (!brandSlug) { if (!brandSlug) {
logger.error("Brand slug is missing"); logger.error("Brand slug is missing");
return res.status(400).json({ return res.status(400).json({ error: "Brand slug is missing" });
error: "Brand slug is missing", }
}); const brand = await BrandService.getBySlug(brandSlug);
} if (!brand) {
const brand = await BrandService.getBySlug(brandSlug); logger.error("Brand not found");
if (!brand) { return res.status(404).json({ error: "Brand not found" });
logger.error("Brand not found"); }
return res.status(404).json({ logger.info(`Brand retrieved successfully ! (${brandSlug})`);
error: "Brand not found", return res.status(200).json(brand);
});
}
logger.info(`Brand retrieved successfully ! (${brandSlug})`);
return res.status(200).json(brand);
} }
/** /**
@ -129,22 +98,17 @@ async function getBySlugBrand(
* @param {Response} res - The response object. * @param {Response} res - The response object.
* @returns {Promise<Response>} - A promise with the response object. * @returns {Promise<Response>} - A promise with the response object.
*/ */
async function getAllBrand( async function getAllBrand(_req: Request, res: Response): Promise<Response> {
_req: Request,
res: Response,
): Promise<Response> {
const brands = await BrandService.getAll(); const brands = await BrandService.getAll();
if (!brands) { if (!brands) {
logger.error("Failed to retrieve brands"); logger.error("Failed to retrieve brands");
return res.status(500).json({ return res.status(500).json({ error: "Failed to retrieve brands" });
error: "Failed to retrieve brands", }
}); logger.info("Brands retrieved successfully !");
} return res.status(200).json({
logger.info("Brands retrieved successfully !");
return res.status(200).json({
uat: Date.now(), uat: Date.now(),
brands: brands, brands: brands,
total: brands.length, total: brands.length
}); });
} }
@ -156,36 +120,25 @@ async function getAllBrand(
* @param {Response} res - The response object. * @param {Response} res - The response object.
* @returns {Promise<Response>} - The response object indicating the success or failure of the delete operation. * @returns {Promise<Response>} - The response object indicating the success or failure of the delete operation.
*/ */
async function deleteBrand( async function deleteBrand(req: Request, res: Response): Promise<Response> {
req: Request,
res: Response,
): Promise<Response> {
const brandSlug = req.params["brandSlug"]; const brandSlug = req.params["brandSlug"];
if (!brandSlug) { if (!brandSlug) {
logger.error("Brand slug is missing"); logger.error("Brand slug is missing");
return res.status(400).json({ return res.status(400).json({ error: "Brand slug is missing" });
error: "Brand slug is missing", }
});
}
//TODO verify if models linked to brand //TODO verify if models linked to brand
const doesExist = await BrandService.getBySlug(brandSlug); const doesExist = await BrandService.getBySlug(brandSlug);
if (!doesExist) { if (!doesExist) {
logger.error("Brand not found"); logger.error("Brand not found");
return res.status(404).json({ return res.status(404).json({ error: "Brand not found" });
error: "Brand not found", }
}); const deleteResult = await BrandService.delete(brandSlug);
} if (!deleteResult) {
const deleteResult = await BrandService.delete(brandSlug); logger.error("Failed to delete brand");
if (!deleteResult) { return res.status(500).json({ error: "Failed to delete brand" });
logger.error("Failed to delete brand"); }
return res.status(500).json({ logger.info(`Brand deleted successfully ! (${brandSlug})`);
error: "Failed to delete brand", return res.status(200).json({ message: "Brand deleted successfully" });
});
}
logger.info(`Brand deleted successfully ! (${brandSlug})`);
return res.status(200).json({
message: "Brand deleted successfully",
});
} }
//TODO get models of the brand //TODO get models of the brand
@ -196,6 +149,6 @@ const BrandController = {
getBySlug: getBySlugBrand, getBySlug: getBySlugBrand,
getAll: getAllBrand, getAll: getAllBrand,
delete: deleteBrand, delete: deleteBrand,
}; }
export default BrandController; export default BrandController;

View File

@ -1,12 +1,12 @@
import type {Request, Response} from "express";
import {Logger} from "tslog";
import type IDbCategory from "@interfaces/database/IDbCategory"; import type IDbCategory from "@interfaces/database/IDbCategory";
import CategoryService from "@services/category.service"; import CategoryService from "@services/category.service";
import type { Request, Response } from "express";
import { Logger } from "tslog";
//import {validationResult} from "express-validator"; //import {validationResult} from "express-validator";
const logger = new Logger({
name: "CategoryController", const logger = new Logger({ name: "CategoryController" });
});
/** /**
* Creates a new category. * Creates a new category.
@ -15,36 +15,23 @@ const logger = new Logger({
* @param {Response} res - The response object to send back to the client. * @param {Response} res - The response object to send back to the client.
* @returns {Promise<Response>} The response object indicating the outcome of the category creation. * @returns {Promise<Response>} The response object indicating the outcome of the category creation.
*/ */
async function createCategory( async function createCategory(req: Request, res: Response): Promise<Response> {
req: Request, const body: IDbCategory = req.body
res: Response, const doesExist = await CategoryService.getBySlug(`${body.slug_name}`)
): Promise<Response> {
const body: IDbCategory = req.body;
const doesExist = await CategoryService.getBySlug(
`${body.slug_name}`,
);
if (doesExist) { if (doesExist) {
logger.error("Category already exists"); logger.error("Category already exists");
return res.status(400).json({ return res.status(400).json({ error: "Category already exists" });
error: "Category already exists", }
});
}
const createResult = await CategoryService.create({ const createResult = await CategoryService.create({
display_name: `${body.display_name}`, display_name: `${body.display_name}`,
slug_name: `${body.slug_name}`, slug_name: `${body.slug_name}`
}); })
if (!createResult) { if (!createResult) {
logger.error("Failed to create category"); logger.error("Failed to create category");
return res.status(500).json({ return res.status(500).json({ error: "Failed to create category" });
error: "Failed to create category",
});
} }
logger.info( logger.info(`Category created successfully ! (${body.slug_name})`)
`Category created successfully ! (${body.slug_name})`, return res.status(201).json({ message: "Category created successfully" });
);
return res.status(201).json({
message: "Category created successfully",
});
} }
/** /**
@ -55,42 +42,29 @@ async function createCategory(
* *
* @return {Promise<Response>} - A promise that will be resolved with the result of the update operation. * @return {Promise<Response>} - A promise that will be resolved with the result of the update operation.
*/ */
async function updateCategory( async function updateCategory(req: Request, res:Response): Promise<Response> {
req: Request,
res: Response,
): Promise<Response> {
const body: IDbCategory = req.body; const body: IDbCategory = req.body;
const categoryId = req.params["categorySlug"]; const categoryId = req.params["categorySlug"];
if (!categoryId) { if (!categoryId) {
logger.error("Category slug is missing"); logger.error("Category slug is missing");
return res.status(400).json({ return res.status(400).json({ error: "Category slug is missing" });
error: "Category slug is missing",
});
} }
const doesExist = await CategoryService.getById( const doesExist = await CategoryService.getById(`${categoryId}`)
`${categoryId}`, if (!doesExist || !doesExist.id) {
); logger.error("Category not found");
if (!doesExist || !doesExist.id) { return res.status(404).json({ error: "Category not found" });
logger.error("Category not found"); }
return res.status(404).json({ const updateResult = await CategoryService.update({
error: "Category not found",
});
}
const updateResult = await CategoryService.update({
id: doesExist.id, id: doesExist.id,
slug_name: `${body.slug_name}`, slug_name: `${body.slug_name}`,
display_name: `${body.display_name}`, display_name: `${body.display_name}`
}); })
if (!updateResult) { if (!updateResult) {
logger.error("Failed to update category"); logger.error("Failed to update category");
return res.status(500).json({ return res.status(500).json({ error: "Failed to update category" });
error: "Failed to update category", }
}); logger.info(`Category updated successfully! (${categoryId})`);
} return res.status(200).json({ message: "Category updated successfully" });
logger.info(`Category updated successfully! (${categoryId})`);
return res.status(200).json({
message: "Category updated successfully",
});
} }
/** /**
@ -100,41 +74,24 @@ async function updateCategory(
* @param {Response} res - The response object to send the result. * @param {Response} res - The response object to send the result.
* @returns {Promise<Response>} A Promise that resolves to the response object. * @returns {Promise<Response>} A Promise that resolves to the response object.
*/ */
async function deleteCategory( async function deleteCategory(req: Request, res: Response): Promise<Response> {
req: Request,
res: Response,
): Promise<Response> {
const categorySlug = req.params["categorySlug"]; const categorySlug = req.params["categorySlug"];
if (!categorySlug) { if (!categorySlug) {
logger.error("Category slug is missing"); logger.error("Category slug is missing");
return res.status(400).json({ return res.status(400).json({ error: "Category slug is missing" });
error: "Category slug is missing", }
}); const doesExist = await CategoryService.getBySlug(`${categorySlug}`);
} if (!doesExist || !doesExist.id) {
const doesExist = await CategoryService.getBySlug( logger.error("Category not found");
`${categorySlug}`, return res.status(404).json({ error: "Category not found" });
); }
if (!doesExist || !doesExist.id) { const deleteResult = await CategoryService.delete(`${doesExist.id}`);
logger.error("Category not found"); if (!deleteResult) {
return res.status(404).json({ logger.error("Failed to delete category");
error: "Category not found", return res.status(500).json({ error: "Failed to delete category" });
}); }
} logger.info(`Category deleted successfully! (${categorySlug})`);
const deleteResult = await CategoryService.delete( return res.status(200).json({ message: "Category deleted successfully" });
`${doesExist.id}`,
);
if (!deleteResult) {
logger.error("Failed to delete category");
return res.status(500).json({
error: "Failed to delete category",
});
}
logger.info(
`Category deleted successfully! (${categorySlug})`,
);
return res.status(200).json({
message: "Category deleted successfully",
});
} }
/** /**
@ -144,26 +101,23 @@ async function deleteCategory(
* @param {Response} res - The response object. * @param {Response} res - The response object.
* @return {Promise<Response>} - A promise that resolves to the response object. * @return {Promise<Response>} - A promise that resolves to the response object.
*/ */
async function getAllCategory( async function getAllCategory(_req: Request, res: Response): Promise<Response> {
_req: Request,
res: Response,
): Promise<Response> {
const categories = await CategoryService.getAll(); const categories = await CategoryService.getAll();
if (!categories) { if (!categories) {
logger.error("Failed to get categories"); logger.error("Failed to get categories");
return res.status(500).json({ return res.status(500).json({ error: "Failed to get categories" });
error: "Failed to get categories", }
}); logger.info("Categories retrieved successfully");
} return res
logger.info("Categories retrieved successfully"); .status(200)
return res.status(200).json({ .json({
iat: Date.now(), iat: Date.now(),
categories: categories.map((category: IDbCategory) => ({ categories: categories.map((category: IDbCategory) => ({
id: category.id, id: category.id,
display_name: category.display_name, display_name: category.display_name,
slug_name: category.slug_name, slug_name: category.slug_name
})), })),
total: categories.length, total: categories.length
}); });
} }
@ -175,34 +129,23 @@ async function getAllCategory(
* *
* @return {Promise<Response>} - The response with category data or error message * @return {Promise<Response>} - The response with category data or error message
*/ */
async function getBySlugCategory( async function getBySlugCategory(req: Request, res:Response): Promise<Response> {
req: Request,
res: Response,
): Promise<Response> {
const categorySlug = req.params["categorySlug"]; const categorySlug = req.params["categorySlug"];
if (!categorySlug) { if (!categorySlug) {
logger.error("Category slug is missing"); logger.error("Category slug is missing");
return res.status(400).json({ return res.status(400).json({ error: "Category slug is missing" });
error: "Category slug is missing", }
}); const category = await CategoryService.getBySlug(`${categorySlug}`);
} if (!category || !category.id) {
const category = await CategoryService.getBySlug( logger.error("Category not found");
`${categorySlug}`, return res.status(404).json({ error: "Category not found" });
); }
if (!category || !category.id) { logger.info(`Category retrieved successfully! (${categorySlug})`);
logger.error("Category not found"); return res.status(200).json({
return res.status(404).json({ id: category.id,
error: "Category not found", display_name: category.display_name,
}); slug_name: category.slug_name
} });
logger.info(
`Category retrieved successfully! (${categorySlug})`,
);
return res.status(200).json({
id: category.id,
display_name: category.display_name,
slug_name: category.slug_name,
});
} }
const CategoryController = { const CategoryController = {
@ -210,7 +153,7 @@ const CategoryController = {
update: updateCategory, update: updateCategory,
delete: deleteCategory, delete: deleteCategory,
getAll: getAllCategory, getAll: getAllCategory,
getBySlug: getBySlugCategory, getBySlug: getBySlugCategory
}; }
export default CategoryController; export default CategoryController;

View File

@ -1,27 +1,20 @@
import type IDbModel from "@interfaces/database/IDbModel"; import type {Request, Response} from "express";
import {Logger} from "tslog";
import CategoryService from "@services/category.service"; import CategoryService from "@services/category.service";
import type IDbModel from "@interfaces/database/IDbModel";
import ModelService from "@services/model.service"; import ModelService from "@services/model.service";
import type { Request, Response } from "express";
import { Logger } from "tslog";
//import {validationResult} from "express-validator"; //import {validationResult} from "express-validator";
const logger = new Logger({
name: "ModelController",
});
async function createModel( const logger = new Logger({ name: "ModelController" });
req: Request,
res: Response,
): Promise<Response> { async function createModel(req: Request, res: Response): Promise<Response> {
const body: IDbModel = req.body; const body: IDbModel = req.body
const doesExist = await CategoryService.getBySlug( const doesExist = await CategoryService.getBySlug(`${body.slug_name}`)
`${body.slug_name}`,
);
if (doesExist) { if (doesExist) {
logger.error("Category already exists"); logger.error("Category already exists");
return res.status(400).json({ return res.status(400).json({ error: "Category already exists" });
error: "Category already exists",
});
} }
const createResult = await ModelService.create({ const createResult = await ModelService.create({
display_name: `${body.display_name}`, display_name: `${body.display_name}`,
@ -30,123 +23,82 @@ async function createModel(
base_price: Number.parseFloat(`${body.base_price}`), base_price: Number.parseFloat(`${body.base_price}`),
brand_id: `${body.brand_id}`, brand_id: `${body.brand_id}`,
image_blob: `${body.image_blob}`, image_blob: `${body.image_blob}`,
is_trending: !!body.is_trending, is_trending: !!body.is_trending
}); })
if (!createResult) { if (!createResult) {
logger.error("Failed to create category"); logger.error("Failed to create category");
return res.status(500).json({ return res.status(500).json({ error: "Failed to create category" });
error: "Failed to create category",
});
} }
logger.info( logger.info(`Category created successfully ! (${body.slug_name})`)
`Category created successfully ! (${body.slug_name})`, return res.status(201).json({ message: "Category created successfully" });
);
return res.status(201).json({
message: "Category created successfully",
});
} }
async function updateModel( async function updateModel(req: Request, res: Response): Promise<Response> {
req: Request,
res: Response,
): Promise<Response> {
const body: IDbModel = req.body; const body: IDbModel = req.body;
const doesExist = await ModelService.getBySlug( const doesExist = await ModelService.getBySlug(`${body.slug_name}`);
`${body.slug_name}`, if (!doesExist) {
);
if (!doesExist) {
logger.error("Model does not exist"); logger.error("Model does not exist");
return res.status(404).json({ return res.status(404).json({ error: "Model does not exist" });
error: "Model does not exist",
});
} }
const updateResult = await ModelService.update({ const updateResult = await ModelService.update({
id: `${body.id}`, id: `${body.id}`,
display_name: `${body.display_name}`, display_name: `${body.display_name}`,
slug_name: `${body.slug_name}`, slug_name: `${body.slug_name}`,
category_id: `${body.category_id}`, category_id: `${body.category_id}`,
base_price: Number.parseFloat(`${body.base_price}`), base_price: Number.parseFloat(`${body.base_price}`),
brand_id: `${body.brand_id}`, brand_id: `${body.brand_id}`,
image_blob: `${body.image_blob}`, image_blob: `${body.image_blob}`,
is_trending: !!body.is_trending, is_trending: !!body.is_trending
}); });
if (!updateResult) { if (!updateResult) {
logger.error("Failed to update model"); logger.error("Failed to update model");
return res.status(500).json({ return res.status(500).json({ error: "Failed to update model" });
error: "Failed to update model", }
}); logger.info(`Model updated successfully! (${body.slug_name})`);
} return res.status(200).json({ message: "Model updated successfully" });
logger.info(
`Model updated successfully! (${body.slug_name})`,
);
return res.status(200).json({
message: "Model updated successfully",
});
} }
async function getAllModel(res: Response): Promise<Response> { async function getAllModel(res: Response): Promise<Response> {
const models = await ModelService.getAll(); const models = await ModelService.getAll();
if (!models) { if (!models) {
logger.error("Failed to get all models"); logger.error("Failed to get all models");
return res.status(500).json({ return res.status(500).json({ error: "Failed to get all models" });
error: "Failed to get all models", }
}); return res.status(200).json({
}
return res.status(200).json({
uat: Date.now(), uat: Date.now(),
models: models, models: models,
total: models.length, total: models.length
}); });
} }
async function getModelBySlug( async function getModelBySlug(req: Request, res: Response): Promise<Response> {
req: Request,
res: Response,
): Promise<Response> {
const slug = req.params["modelSlug"]; const slug = req.params["modelSlug"];
if (!slug) { if (!slug) {
logger.error("Invalid slug"); logger.error("Invalid slug");
return res.status(400).json({ return res.status(400).json({ error: "Invalid slug" });
error: "Invalid slug",
});
} }
const model = await ModelService.getBySlug(slug); const model = await ModelService.getBySlug(slug);
if (!model) { if (!model) {
logger.error("Model not found"); logger.error("Model not found");
return res.status(404).json({ return res.status(404).json({ error: "Model not found" });
error: "Model not found", }
}); return res.status(200).json({ model });
}
return res.status(200).json({
model,
});
} }
async function deleteModel( async function deleteModel(req: Request, res: Response): Promise<Response> {
req: Request,
res: Response,
): Promise<Response> {
const modelSlug = req.params["modelSlug"]; const modelSlug = req.params["modelSlug"];
if (!modelSlug) { if (!modelSlug) {
logger.error("Invalid model slug"); logger.error("Invalid model slug");
return res.status(400).json({ return res.status(400).json({ error: "Invalid model slug" });
error: "Invalid model slug", }
});
}
//TODO Check if vehicle related to model //TODO Check if vehicle related to model
const deleteResult = await ModelService.delete(modelSlug); const deleteResult = await ModelService.delete(modelSlug);
if (!deleteResult) { if (!deleteResult) {
logger.error("Failed to delete model"); logger.error("Failed to delete model");
return res.status(500).json({ return res.status(500).json({ error: "Failed to delete model" });
error: "Failed to delete model", }
}); logger.info(`Model deleted successfully! (SLUG: ${modelSlug})`);
} return res.status(200).json({ message: "Model deleted successfully" });
logger.info(
`Model deleted successfully! (SLUG: ${modelSlug})`,
);
return res.status(200).json({
message: "Model deleted successfully",
});
} }
//TODO get all vehicles of an model by slug //TODO get all vehicles of an model by slug
@ -156,9 +108,9 @@ async function deleteModel(
const ModelController = { const ModelController = {
create: createModel, create: createModel,
update: updateModel, update: updateModel,
getAll: getAllModel, getAll: getAllModel,
getBySlug: getModelBySlug, getBySlug: getModelBySlug,
delete: deleteModel, delete: deleteModel,
}; }
export default ModelController; export default ModelController;

View File

@ -3,4 +3,4 @@ export interface IReqEditUserData {
lastName?: string; lastName?: string;
displayName?: string; displayName?: string;
password?: string; password?: string;
} }

View File

@ -12,7 +12,7 @@ interface DbUserData {
isDisabled: boolean; isDisabled: boolean;
resetPasswordToken?: string; resetPasswordToken?: string;
resetPasswordExpires?: Date; resetPasswordExpires?: Date;
dob: Date; dob: Date;
gdpr: Date; gdpr: Date;
@ -20,4 +20,4 @@ interface DbUserData {
uat: Date; uat: Date;
} }
export default DbUserData; export default DbUserData

View File

@ -1,8 +1,8 @@
export interface IDbBrand { export interface IDbBrand {
id?: string; id?: string;
slug_name: string; slug_name: string;
display_name: string; display_name: string;
image_blob: BinaryType; image_blob: BinaryType;
} }
export default IDbBrand; export default IDbBrand;

View File

@ -1,7 +1,7 @@
export interface IDbCategory { export interface IDbCategory {
id?: string; id?: string;
slug_name: string; slug_name: string;
display_name: string; display_name: string
} }
export default IDbCategory; export default IDbCategory;

View File

@ -1,12 +1,12 @@
export interface IDbModel { export interface IDbModel {
id?: string; id?: string;
slug_name: string; slug_name: string;
display_name: string; display_name: string;
brand_id: string; brand_id: string;
category_id: string; category_id: string;
image_blob: BinaryType; image_blob: BinaryType;
is_trending: boolean; is_trending: boolean;
base_price: number; base_price: number;
} }
export default IDbModel; export default IDbModel;

View File

@ -1,11 +1,11 @@
export interface IDbRent { export interface IDbRent {
vehicle_id: string; vehicle_id: string;
user_id: string; user_id: string;
active: boolean; active: boolean;
iat: Date; iat: Date;
eat: Date; eat: Date;
need_survey: boolean; need_survey: boolean;
km_at_start: number; km_at_start: number
} }
export default IDbRent; export default IDbRent;

View File

@ -6,4 +6,4 @@ export interface IDbStatusResult {
serverStatus: number; serverStatus: number;
warningStatus: number; warningStatus: number;
changedRows: number; changedRows: number;
} }

View File

@ -1,12 +1,12 @@
export interface IDbUser { export interface IDbUser {
id?: string; id?: string;
username: string; username: string;
firstname: string; firstname: string;
lastname: string; lastname: string;
dob: Date; dob: Date;
email: string; email: string;
is_mail_verified: boolean; is_mail_verified: boolean;
is_admin: boolean; is_admin: boolean;
gdpr: Date; gdpr: Date;
hash: string; hash: string
} }

View File

@ -4,4 +4,4 @@ export interface IDbVehicle {
model_id: string; model_id: string;
odometer: number; odometer: number;
health_state: number; health_state: number;
} }

View File

@ -1 +1 @@
export * from "./UserData"; export * from './UserData'

View File

@ -1,4 +1,4 @@
export interface IReqLogin { export interface IReqLogin {
username: string; username: string;
password: string; password: string;
} }

View File

@ -5,4 +5,4 @@ export interface IReqRegister {
lastName: string; lastName: string;
password: string; password: string;
gdpr?: boolean; gdpr?: boolean;
} }

View File

@ -1,39 +1,38 @@
import AuthController from "@controllers/auth.controller"; import express, {type Router} from "express";
import AdminGuard from "@validators/AdminGuard";
import UserGuard from "@validators/UserGuard"; import UserGuard from "@validators/UserGuard";
import express, { type Router } from "express"; import AdminGuard from "@validators/AdminGuard";
import AuthController from "@controllers/auth.controller";
const AuthRouter: Router = express.Router(); const AuthRouter: Router = express.Router();
AuthRouter.route("/login").post(AuthController.login); AuthRouter.route('/login').post(AuthController.login)
AuthRouter.route("/register").post(AuthController.register); AuthRouter.route('/register').post(AuthController.register)
// PATCH // PATCH
//TODO - To test //TODO - To test
AuthRouter.route("/me").patch( AuthRouter.route('/me')
UserGuard, .patch(UserGuard, AuthController.editUser)
AuthController.editUser,
);
// GET // GET
AuthRouter.route("/me").get(UserGuard, AuthController.getSelf); AuthRouter.route('/me')
.get(UserGuard, AuthController.getSelf)
// DELETE // DELETE
AuthRouter.route("/me").delete( AuthRouter.route('/me')
UserGuard, .delete(UserGuard, AuthController.deleteSelf)
AuthController.deleteSelf,
);
// GET // GET
AuthRouter.route("/all").get( AuthRouter.route('/all')
AdminGuard, .get(AdminGuard, AuthController.getAllUsers)
AuthController.getAllUsers,
);
// GET // GET
AuthRouter.route("/user/:targetId") AuthRouter.route('/user/:targetId')
.get(AdminGuard, AuthController.getUser) .get(AdminGuard, AuthController.getUser)
.patch(AdminGuard, AuthController.editUser) .patch(AdminGuard, AuthController.editUser)
.delete(AdminGuard, AuthController.deleteUser); .delete(AdminGuard, AuthController.deleteUser)
export default AuthRouter;
export default AuthRouter

View File

@ -1,52 +1,44 @@
import BrandController from "@controllers/brand.controller"; import express, {type Router} from "express";
import CategoryController from "@controllers/category.controller";
import ModelController from "@controllers/model.controller";
import AdminGuard from "@validators/AdminGuard"; import AdminGuard from "@validators/AdminGuard";
import UserGuard from "@validators/UserGuard"; import UserGuard from "@validators/UserGuard";
import express, { type Router } from "express"; import CategoryController from "@controllers/category.controller";
import ModelController from "@controllers/model.controller";
import BrandController from "@controllers/brand.controller";
const CatalogRouter: Router = express.Router(); const CatalogRouter: Router = express.Router();
//-- MODELS >> //-- MODELS >>
CatalogRouter.route("/model/new").get( CatalogRouter.route('/model/new').get(AdminGuard, ModelController.create)
AdminGuard,
ModelController.create,
);
CatalogRouter.route("/model/all").get(ModelController.getAll); CatalogRouter.route('/model/all').get(ModelController.getAll)
CatalogRouter.route("/model/:modelSlug") CatalogRouter.route('/model/:modelSlug')
.get(UserGuard, ModelController.getBySlug) .get(UserGuard, ModelController.getBySlug)
.patch(AdminGuard, ModelController.update) .patch(AdminGuard, ModelController.update)
.delete(AdminGuard, ModelController.delete); .delete(AdminGuard, ModelController.delete)
//-- CATEGORY >> //-- CATEGORY >>
CatalogRouter.route("/category/new").get( CatalogRouter.route('/category/new').get(AdminGuard, CategoryController.create)
AdminGuard,
CategoryController.create,
);
CatalogRouter.route("/category/all").get( CatalogRouter.route('/category/all').get(CategoryController.getAll)
CategoryController.getAll,
);
CatalogRouter.route("/category/:categorySlug") CatalogRouter.route('/category/:categorySlug')
.get(UserGuard, CategoryController.getBySlug) .get(UserGuard, CategoryController.getBySlug)
.patch(AdminGuard, CategoryController.update) .patch(AdminGuard, CategoryController.update)
.delete(AdminGuard, CategoryController.delete); .delete(AdminGuard, CategoryController.delete)
//-- BRAND >> //-- BRAND >>
CatalogRouter.route("/brand/new").post( CatalogRouter.route('/brand/new').post(AdminGuard, BrandController.create)
AdminGuard, CatalogRouter.route('/brand/all').get(BrandController.getAll)
BrandController.create, CatalogRouter.route('/brand/:brandSlug')
);
CatalogRouter.route("/brand/all").get(BrandController.getAll);
CatalogRouter.route("/brand/:brandSlug")
.get(UserGuard, BrandController.getBySlug) .get(UserGuard, BrandController.getBySlug)
.patch(AdminGuard, BrandController.update) .patch(AdminGuard, BrandController.update)
.delete(AdminGuard, BrandController.delete); .delete(AdminGuard, BrandController.delete)
export default CatalogRouter; export default CatalogRouter;

View File

@ -1,3 +1,3 @@
export * from "src/routes/auth/authRouter"; export * from 'src/routes/auth/authRouter'
export * from "src/routes/catalog/catalogRouter"; export * from 'src/routes/catalog/catalogRouter'
export * from "src/routes/rent/rentRouter"; export * from 'src/routes/rent/rentRouter'

View File

@ -1,27 +1,34 @@
import express, {type Router} from "express";
import AdminGuard from "@validators/AdminGuard"; import AdminGuard from "@validators/AdminGuard";
import UserGuard from "@validators/UserGuard"; import UserGuard from "@validators/UserGuard";
import express, { type Router } from "express";
const RentRouter: Router = express.Router(); const RentRouter: Router = express.Router();
// Get rent affected to the user // Get rent affected to the user
RentRouter.route("/affected").get(UserGuard); RentRouter.route('/affected')
.get(UserGuard)
// Get all vehicle in rent (admin only) // Get all vehicle in rent (admin only)
RentRouter.route("/affected/all").get(AdminGuard); RentRouter.route('/affected/all')
.get(AdminGuard)
// Add a new vehicle (admin only) // Add a new vehicle (admin only)
RentRouter.route("/veh/new").post(AdminGuard); RentRouter.route('/veh/new')
.post(AdminGuard)
// Get all vehicles // Get all vehicles
RentRouter.route("/veh/all").get(); RentRouter.route('/veh/all')
.get()
// Rent a specific vehicle // Rent a specific vehicle
RentRouter.route("/veh/rent/:vehicleId").post(UserGuard); RentRouter.route('/veh/rent/:vehicleId')
.post(UserGuard)
RentRouter.route("/veh/:vehicleId")
RentRouter.route('/veh/:vehicleId')
.get(UserGuard) .get(UserGuard)
.patch(AdminGuard) .patch(AdminGuard)
.delete(AdminGuard); .delete(AdminGuard)
export default RentRouter; export default RentRouter;

View File

@ -1,12 +1,10 @@
import type IDbBrand from "@interfaces/database/IDbBrand"; import type IDbBrand from "@interfaces/database/IDbBrand";
import MysqlService from "@services/mysql.service"; import MysqlService from "@services/mysql.service";
import { Logger } from "tslog"; import {Logger} from "tslog";
import { v4 as uuidv4 } from "uuid"; import { v4 as uuidv4 } from 'uuid';
const DbHandler = new MysqlService.Handler("BrandService"); const DbHandler = new MysqlService.Handler('BrandService')
const logger = new Logger({ const logger = new Logger({name: 'BrandService'})
name: "BrandService",
});
//SEC todo Blob validation //SEC todo Blob validation
/** /**
@ -16,39 +14,24 @@ const logger = new Logger({
* @return {Promise<unknown>} A promise that resolves to the result of the operation. * @return {Promise<unknown>} A promise that resolves to the result of the operation.
*/ */
async function createBrand(data: IDbBrand): Promise<unknown> { async function createBrand(data: IDbBrand): Promise<unknown> {
const doesExist = await MysqlService.Brand.getBySlug( const doesExist = await MysqlService.Brand.getBySlug(DbHandler, data.slug_name);
DbHandler,
data.slug_name,
);
if (doesExist) { if (doesExist) {
logger.error(`Brand already exists (${data.slug_name})`); logger.error(`Brand already exists (${data.slug_name})`)
return { return {error: 'exist'}
error: "exist",
};
} }
const brandId = uuidv4(); const brandId = uuidv4();
const createdBrand = await MysqlService.Brand.insert( const createdBrand = await MysqlService.Brand.insert(DbHandler, {
DbHandler, id: brandId,
{ slug_name: `${data.slug_name}`,
id: brandId, display_name: `${data.display_name}`,
slug_name: `${data.slug_name}`, image_blob: data.image_blob
display_name: `${data.display_name}`, });
image_blob: data.image_blob, if (createdBrand) {
}, logger.info(`Brand created successfully (${data.slug_name})`);
); return { success: true, brand: createdBrand };
if (createdBrand) { }
logger.info( logger.error(`Failed to create brand (${data.slug_name})`);
`Brand created successfully (${data.slug_name})`, return { error: 'failed' };
);
return {
success: true,
brand: createdBrand,
};
}
logger.error(`Failed to create brand (${data.slug_name})`);
return {
error: "failed",
};
} }
//SEC todo Blob validation //SEC todo Blob validation
@ -61,48 +44,38 @@ async function createBrand(data: IDbBrand): Promise<unknown> {
async function updateBrand(data: IDbBrand): Promise<boolean> { async function updateBrand(data: IDbBrand): Promise<boolean> {
if (!data.id) { if (!data.id) {
logger.error("Brand ID is missing"); logger.error("Brand ID is missing");
return false; return false;
} }
const doesExist = await MysqlService.Brand.getBySlug( const doesExist = await MysqlService.Brand.getBySlug(DbHandler, data.slug_name);
DbHandler, if (doesExist && doesExist.id !== data.id) {
data.slug_name, logger.error(`Brand already exists (${data.slug_name})`);
); return false;
if (doesExist && doesExist.id !== data.id) { }
logger.error(`Brand already exists (${data.slug_name})`); const updatedBrand = await MysqlService.Brand.update(DbHandler, {
return false; id: data.id,
} slug_name: `${data.slug_name}`,
const updatedBrand = await MysqlService.Brand.update( display_name: `${data.display_name}`,
DbHandler, image_blob: data.image_blob
{ });
id: data.id, if (updatedBrand) {
slug_name: `${data.slug_name}`, logger.info(`Brand updated successfully (${data.slug_name})`);
display_name: `${data.display_name}`, return true;
image_blob: data.image_blob, }
}, logger.error(`Failed to update brand (${data.slug_name})`);
); return false;
if (updatedBrand) {
logger.info(
`Brand updated successfully (${data.slug_name})`,
);
return true;
}
logger.error(`Failed to update brand (${data.slug_name})`);
return false;
} }
/** /**
* Retrieves all brands from the database. * Retrieves all brands from the database.
* @returns {Promise<Array<IDbBrand>|false>} - An array of IDbBrand objects if successful, false otherwise. * @returns {Promise<Array<IDbBrand>|false>} - An array of IDbBrand objects if successful, false otherwise.
*/ */
async function getAllBrand(): Promise<Array<IDbBrand> | false> { async function getAllBrand(): Promise<Array<IDbBrand>| false> {
const brands = await MysqlService.Brand.getAll(DbHandler); const brands = await MysqlService.Brand.getAll(DbHandler);
if (!brands) { if (!brands) {
logger.error("Failed to retrieve brands"); logger.error("Failed to retrieve brands");
return false; return false;
} }
logger.info( logger.info(`Retrieved all brands successfully (${brands.length})`);
`Retrieved all brands successfully (${brands.length})`,
);
return brands; return brands;
} }
@ -112,25 +85,18 @@ async function getAllBrand(): Promise<Array<IDbBrand> | false> {
* @param {string} brandSlug - The slug of the brand. * @param {string} brandSlug - The slug of the brand.
* @returns {Promise<IDbBrand|false>} - A promise that resolves to the retrieved brand object or false if the brand is not found. * @returns {Promise<IDbBrand|false>} - A promise that resolves to the retrieved brand object or false if the brand is not found.
*/ */
async function getBySlugBrand( async function getBySlugBrand(brandSlug: string): Promise<IDbBrand | false> {
brandSlug: string,
): Promise<IDbBrand | false> {
if (!brandSlug) { if (!brandSlug) {
logger.error("Brand slug is missing"); logger.error("Brand slug is missing");
return false; return false;
} }
const brand = await MysqlService.Brand.getBySlug( const brand = await MysqlService.Brand.getBySlug(DbHandler, brandSlug);
DbHandler, if (!brand) {
brandSlug, logger.error(`Brand not found (${brandSlug})`);
); return false;
if (!brand) { }
logger.error(`Brand not found (${brandSlug})`); logger.info(`Retrieved brand by slug successfully (${brandSlug})`);
return false; return brand;
}
logger.info(
`Retrieved brand by slug successfully (${brandSlug})`,
);
return brand;
} }
/** /**
@ -140,9 +106,7 @@ async function getBySlugBrand(
* *
* @returns {Promise<IDbBrand | false>} A promise that resolves to the retrieved brand object, or false if the brand is not found or the ID is invalid. * @returns {Promise<IDbBrand | false>} A promise that resolves to the retrieved brand object, or false if the brand is not found or the ID is invalid.
*/ */
async function getByIdBrand( async function getByIdBrand(brandId: string): Promise<IDbBrand | false> {
brandId: string,
): Promise<IDbBrand | false> {
if (!brandId) { if (!brandId) {
logger.error("Brand ID is missing"); logger.error("Brand ID is missing");
return false; return false;
@ -151,17 +115,12 @@ async function getByIdBrand(
logger.error("Invalid brand ID"); logger.error("Invalid brand ID");
return false; return false;
} }
const brand = await MysqlService.Brand.getById( const brand = await MysqlService.Brand.getById(DbHandler, brandId);
DbHandler,
brandId,
);
if (!brand) { if (!brand) {
logger.error(`Brand not found (${brandId})`); logger.error(`Brand not found (${brandId})`);
return false; return false;
} }
logger.info( logger.info(`Retrieved brand by ID successfully (${brandId})`);
`Retrieved brand by ID successfully (${brandId})`,
);
return brand; return brand;
} }
@ -185,14 +144,11 @@ async function deleteBrand(brandId: string): Promise<boolean> {
return false; return false;
} }
//TODO verify if as models linked //TODO verify if as models linked
const deletedBrand = await MysqlService.Brand.delete( const deletedBrand = await MysqlService.Brand.delete(DbHandler, brandId);
DbHandler, if (!deletedBrand) {
brandId,
);
if (!deletedBrand) {
logger.error(`Failed to delete brand (${brandId})`); logger.error(`Failed to delete brand (${brandId})`);
return false; return false;
} }
logger.info(`Brand deleted successfully (${brandId})`); logger.info(`Brand deleted successfully (${brandId})`);
return true; return true;
} }
@ -204,6 +160,6 @@ const BrandService = {
getBySlug: getBySlugBrand, getBySlug: getBySlugBrand,
getById: getByIdBrand, getById: getByIdBrand,
delete: deleteBrand, delete: deleteBrand,
}; }
export default BrandService; export default BrandService;

View File

@ -1,12 +1,12 @@
import type { IDbCategory } from "@interfaces/database/IDbCategory"; import type { IDbCategory } from "@interfaces/database/IDbCategory";
import MysqlService from "@services/mysql.service"; import MysqlService from "@services/mysql.service";
import { Logger } from "tslog"; import {Logger} from "tslog";
import { v4 as uuidv4 } from "uuid"; import { v4 as uuidv4 } from 'uuid';
const DbHandler = new MysqlService.Handler('CategoryService')
const logger = new Logger({name: 'CategoryService'})
const DbHandler = new MysqlService.Handler("CategoryService");
const logger = new Logger({
name: "CategoryService",
});
/** /**
* Creates a new category with the given data. * Creates a new category with the given data.
@ -15,23 +15,19 @@ const logger = new Logger({
* @returns {Promise<boolean>} A promise that resolves with the created category. * @returns {Promise<boolean>} A promise that resolves with the created category.
* If an error occurs, the promise will reject with the error. * If an error occurs, the promise will reject with the error.
*/ */
async function createCategory( async function createCategory(data: IDbCategory): Promise<boolean> {
data: IDbCategory, logger.info(`Creating a new category... (${data.display_name})`)
): Promise<boolean> {
logger.info(
`Creating a new category... (${data.display_name})`,
);
try { try {
await MysqlService.Category.insert(DbHandler, { await MysqlService.Category.insert(DbHandler, {
id: uuidv4(), id: uuidv4(),
display_name: data.display_name, display_name: data.display_name,
slug_name: data.slug_name, slug_name: data.slug_name
}); })
//TODO Return the new id //TODO Return the new id
return true; return true;
} catch (error) { } catch (error) {
logger.error(`Error creating category: ${error}`); logger.error(`Error creating category: ${error}`);
return false; return false;
} }
} }
@ -47,19 +43,19 @@ async function createCategory(
*/ */
async function updateCategory(data: IDbCategory) { async function updateCategory(data: IDbCategory) {
if (!data.id) { if (!data.id) {
logger.error("Category id is missing."); logger.error("Category id is missing.")
return false; return false
} }
try { try {
await MysqlService.Category.update(DbHandler, { await MysqlService.Category.update(DbHandler, {
id: data.id, id: data.id,
slug_name: data.slug_name, slug_name: data.slug_name,
display_name: data.display_name, display_name: data.display_name
}); });
//TODO Return id //TODO Return id
return true; return true;
} catch (err) { } catch (err) {
logger.error(err); logger.error(err)
return false; return false;
} }
} }
@ -69,37 +65,31 @@ async function updateCategory(data: IDbCategory) {
* *
* @returns {Promise<Array<IDbCategory>> | null} Promise that resolves to an array of IDbCategory objects or null if an error occurred. * @returns {Promise<Array<IDbCategory>> | null} Promise that resolves to an array of IDbCategory objects or null if an error occurred.
*/ */
async function getAll(): Promise<Promise< async function getAll(): Promise<Promise<Array<IDbCategory>> | null> {
Array<IDbCategory>
> | null> {
try { try {
logger.info("Getting all categories..."); logger.info("Getting all categories...");
return await MysqlService.Category.getAll(DbHandler); return await MysqlService.Category.getAll(DbHandler);
} catch (error) { } catch (error) {
logger.error(`Error getting all categories: ${error}`); logger.error(`Error getting all categories: ${error}`);
return null; return null;
} }
} }
/** /**
* Gets a category by its slug * Gets a category by its slug
* *
* @param {string} slug - The slug of the category * @param {string} slug - The slug of the category
* @return {Promise<IDbCategory|null>} - A promise that resolves to the category object or null if not found * @return {Promise<IDbCategory|null>} - A promise that resolves to the category object or null if not found
*/ */
async function getBySlug( async function getBySlug(slug: string): Promise<IDbCategory | null> {
slug: string,
): Promise<IDbCategory | null> {
try { try {
logger.info(`Getting category by slug... (${slug})`); logger.info(`Getting category by slug... (${slug})`);
return await MysqlService.Category.getBySlug( return await MysqlService.Category.getBySlug(DbHandler, slug);
DbHandler, } catch (error) {
slug, logger.error(`Error getting category by slug: ${error}`);
); return null;
} catch (error) { }
logger.error(`Error getting category by slug: ${error}`);
return null;
}
} }
/** /**
@ -108,36 +98,35 @@ async function getBySlug(
* @param {string} id - The id of the category to retrieve. * @param {string} id - The id of the category to retrieve.
* @returns {Promise<IDbCategory | null>} - A Promise that resolves with the retrieved category object or null if not found. * @returns {Promise<IDbCategory | null>} - A Promise that resolves with the retrieved category object or null if not found.
*/ */
async function getById( async function getById(id: string):Promise<IDbCategory | null> {
id: string,
): Promise<IDbCategory | null> {
try { try {
logger.info(`Getting category by id... (${id})`); logger.info(`Getting category by id... (${id})`);
return await MysqlService.Category.getById(DbHandler, id); return await MysqlService.Category.getById(DbHandler, id);
} catch (error) { } catch (error) {
logger.error(`Error getting category by id: ${error}`); logger.error(`Error getting category by id: ${error}`);
return null; return null;
} }
} }
//FEAT Get all models in category (slug) //FEAT Get all models in category (slug)
/** /**
* Deletes a category with the given ID from the database. * Deletes a category with the given ID from the database.
* *
* @param {string} id - The ID of the category to delete. * @param {string} id - The ID of the category to delete.
* @return {Promise} - A Promise that resolves to the deleted category if successful, or null if an error occurs. * @return {Promise} - A Promise that resolves to the deleted category if successful, or null if an error occurs.
*/ */
async function deleteCategory(id: string): Promise<unknown> { async function deleteCategory(id:string): Promise<unknown> {
//TODO Verify if exist //TODO Verify if exist
//TODO Verify if element linked to category //TODO Verify if element linked to category
try { try {
logger.info(`Deleting category... (${id})`); logger.info(`Deleting category... (${id})`);
return await MysqlService.Category.delete(DbHandler, id); return await MysqlService.Category.delete(DbHandler, id);
} catch (error) { } catch (error) {
logger.error(`Error deleting category: ${error}`); logger.error(`Error deleting category: ${error}`);
return null; return null;
} }
} }
const CategoryService = { const CategoryService = {
@ -146,7 +135,7 @@ const CategoryService = {
update: updateCategory, update: updateCategory,
getAll, getAll,
getBySlug, getBySlug,
getById, getById
}; }
export default CategoryService; export default CategoryService;

View File

@ -2,26 +2,23 @@ import Argon2id from "@node-rs/argon2";
//ToTest //ToTest
export async function getHashFromPassword(password: string) { export async function getHashFromPassword(password: string) {
return await Argon2id.hash(password, { return await Argon2id.hash(password,{
secret: Buffer.from(`${process.env["HASH_SECRET"]}`), secret: Buffer.from(`${process.env["HASH_SECRET"]}`),
algorithm: 2, algorithm: 2
}); })
} }
//ToTest //ToTest
export async function comparePassword( export async function comparePassword(password: string, hash: string) {
password: string,
hash: string,
) {
return await Argon2id.verify(hash, password, { return await Argon2id.verify(hash, password, {
secret: Buffer.from(`${process.env["HASH_SECRET"]}`), secret: Buffer.from(`${process.env["HASH_SECRET"]}`),
algorithm: 2, algorithm: 2
}); });
} }
const CredentialService = { const CredentialService = {
compare: comparePassword, compare: comparePassword,
hash: getHashFromPassword, hash: getHashFromPassword,
}; }
export default CredentialService; export default CredentialService;

View File

@ -1,2 +1,2 @@
export * from "./jwt.service"; export * from './jwt.service';
export * as MySqlService from "./mysql.service"; export * as MySqlService from './mysql.service'

View File

@ -1,14 +1,7 @@
import { import {type JWTHeaderParameters, type JWTPayload, jwtVerify, SignJWT} from "jose";
type JWTHeaderParameters, import {Logger} from "tslog";
type JWTPayload,
SignJWT,
jwtVerify,
} from "jose";
import { Logger } from "tslog";
const logger = new Logger({ const logger = new Logger({ name: "JwtService" });
name: "JwtService",
});
/** /**
* Verify a JWT token. * Verify a JWT token.
@ -18,22 +11,22 @@ const logger = new Logger({
* @returns {Promise<null | JWTPayload>} * @returns {Promise<null | JWTPayload>}
* - The payload of the verified JWT token or null if verification fails. * - The payload of the verified JWT token or null if verification fails.
*/ */
async function JwtVerifyService( async function JwtVerifyService(jwt: string | Uint8Array): Promise<null | JWTPayload> {
jwt: string | Uint8Array, try {
): Promise<null | JWTPayload> { const result = await jwtVerify(
try { jwt,
const result = await jwtVerify( new TextEncoder()
jwt, .encode(`${process.env["JWT_SECRET"]}`),
new TextEncoder().encode(`${process.env["JWT_SECRET"]}`), {
{}, })
); return result.payload;
return result.payload; } catch (error) {
} catch (error) { logger.error(error)
logger.error(error); return null
return null; }
}
} }
/** /**
* Asynchronously signs a JWT token using the provided payload, header, expiration time, and audience. * Asynchronously signs a JWT token using the provided payload, header, expiration time, and audience.
* *
@ -49,26 +42,19 @@ async function JwtVerifyService(
* @returns {Promise<string>} * @returns {Promise<string>}
* - A promise that resolves with the signed JWT token. * - A promise that resolves with the signed JWT token.
*/ */
async function JwtSignService( async function JwtSignService(payload: JWTPayload, pHeader: JWTHeaderParameters, expTime: string | number | Date, audience: string | string[]): Promise<string> {
payload: JWTPayload, return await new SignJWT(payload)
pHeader: JWTHeaderParameters, .setProtectedHeader(pHeader)
expTime: string | number | Date, .setIssuedAt(new Date())
audience: string | string[], .setIssuer(`${process.env["JWT_SECRET"]} - Mathis HERRIOT`)
): Promise<string> { .setAudience(audience)
return await new SignJWT(payload) .setExpirationTime(expTime)
.setProtectedHeader(pHeader) .sign(new TextEncoder().encode(`${process.env["JWT_SECRET"]}`))
.setIssuedAt(new Date())
.setIssuer(`${process.env["JWT_SECRET"]} - Mathis HERRIOT`)
.setAudience(audience)
.setExpirationTime(expTime)
.sign(
new TextEncoder().encode(`${process.env["JWT_SECRET"]}`),
);
} }
const JwtService = { const JwtService = {
verify: JwtVerifyService, verify: JwtVerifyService,
sign: JwtSignService, sign: JwtSignService
}; }
export default JwtService; export default JwtService

View File

@ -1,12 +1,10 @@
import type IDbModel from "@interfaces/database/IDbModel"; import type IDbModel from "@interfaces/database/IDbModel";
import MysqlService from "@services/mysql.service"; import MysqlService from "@services/mysql.service";
import { Logger } from "tslog"; import {Logger} from "tslog";
import { v4 as uuidv4 } from "uuid"; import { v4 as uuidv4 } from 'uuid';
const DbHandler = new MysqlService.Handler("ModelService"); const DbHandler = new MysqlService.Handler('ModelService')
const logger = new Logger({ const logger = new Logger({name: 'ModelService'})
name: "ModelService",
});
//SEC TODO validate blob //SEC TODO validate blob
/** /**
@ -17,7 +15,7 @@ const logger = new Logger({
* @return {Promise<boolean>} - Indicates whether the model was created successfully. * @return {Promise<boolean>} - Indicates whether the model was created successfully.
*/ */
async function createModel(data: IDbModel): Promise<boolean> { async function createModel(data: IDbModel): Promise<boolean> {
logger.info(`Creating a new model... (${data.display_name})`); logger.info(`Creating a new model... (${data.display_name})`)
//TODO Validate IDbModel data //TODO Validate IDbModel data
try { try {
await MysqlService.Model.insert(DbHandler, { await MysqlService.Model.insert(DbHandler, {
@ -28,10 +26,10 @@ async function createModel(data: IDbModel): Promise<boolean> {
brand_id: data.brand_id, brand_id: data.brand_id,
category_id: data.category_id, category_id: data.category_id,
base_price: data.base_price, base_price: data.base_price,
is_trending: data.is_trending, is_trending: data.is_trending
}); })
//TODO Return the new id //TODO Return the new id
logger.info("Success !"); logger.info('Success !')
return true; return true;
} catch (error) { } catch (error) {
logger.error(`Error creating category: ${error}`); logger.error(`Error creating category: ${error}`);
@ -72,22 +70,17 @@ async function updateModel(data: IDbModel): Promise<boolean> {
* @param {string} modelSlug - The slug of the model to be deleted. * @param {string} modelSlug - The slug of the model to be deleted.
* @return {Promise<boolean>} - A promise that resolves to true if the deletion is successful, else false. * @return {Promise<boolean>} - A promise that resolves to true if the deletion is successful, else false.
*/ */
async function deleteModel( async function deleteModel(modelSlug: string): Promise<boolean> {
modelSlug: string,
): Promise<boolean> {
if (!modelSlug) { if (!modelSlug) {
logger.error("Model slug is missing"); logger.error("Model slug is missing");
return false; return false
} }
logger.info(`Deleting model with ID: ${modelSlug}`); logger.info(`Deleting model with ID: ${modelSlug}`);
const doesExist = await MysqlService.Model.getBySlug( const doesExist = await MysqlService.Model.getBySlug(DbHandler, modelSlug);
DbHandler,
modelSlug,
);
if (!doesExist || !doesExist.id) { if (!doesExist || !doesExist.id) {
logger.warn(`Model with slug ${modelSlug} not found`); logger.warn(`Model with slug ${modelSlug} not found`);
return false; return false;
} }
try { try {
await MysqlService.Model.delete(DbHandler, doesExist.id); await MysqlService.Model.delete(DbHandler, doesExist.id);
logger.info("Deletion Successful !"); logger.info("Deletion Successful !");
@ -98,21 +91,17 @@ async function deleteModel(
} }
} }
/** /**
* Fetches a model by slug from the database. * Fetches a model by slug from the database.
* *
* @param {string} modelSlug - The slug of the model to be fetched. * @param {string} modelSlug - The slug of the model to be fetched.
* @return {Promise<IDbModel | null>} - A promise that resolves to the model if found, else null. * @return {Promise<IDbModel | null>} - A promise that resolves to the model if found, else null.
*/ */
async function getBySlugModel( async function getBySlugModel(modelSlug: string): Promise<IDbModel | null> {
modelSlug: string,
): Promise<IDbModel | null> {
logger.info(`Fetching model with slug: ${modelSlug}`); logger.info(`Fetching model with slug: ${modelSlug}`);
try { try {
const model = await MysqlService.Model.getBySlug( const model = await MysqlService.Model.getBySlug(DbHandler, modelSlug);
DbHandler,
modelSlug,
);
if (!model) { if (!model) {
logger.warn(`Model with slug ${modelSlug} not found`); logger.warn(`Model with slug ${modelSlug} not found`);
return null; return null;
@ -124,6 +113,7 @@ async function getBySlugModel(
} }
} }
/** /**
* Fetches all models from the database. * Fetches all models from the database.
* *
@ -137,7 +127,7 @@ async function getAllModels(): Promise<IDbModel[] | null> {
logger.warn("No models found on the database"); logger.warn("No models found on the database");
return null; return null;
} }
logger.info(`Found ${models.length} model(s)`); logger.info(`Found ${models.length} model(s)`)
return models; return models;
} catch (error) { } catch (error) {
logger.error(`Error fetching all models: ${error}`); logger.error(`Error fetching all models: ${error}`);
@ -145,6 +135,8 @@ async function getAllModels(): Promise<IDbModel[] | null> {
} }
} }
/** /**
* ModelService is responsible for managing models. * ModelService is responsible for managing models.
* @namespace * @namespace
@ -157,6 +149,6 @@ const ModelService = {
getAll: getAllModels, getAll: getAllModels,
//getByCategory: getByCategoryModel, //getByCategory: getByCategoryModel,
//getByBrand: getModelsByBrand, //getByBrand: getModelsByBrand,
}; }
export default ModelService; export default ModelService;

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,15 @@
import type { IReqLogin } from "@interfaces/requests/IReqLogin"; import {Logger} from "tslog";
import type { IReqRegister } from "@interfaces/requests/IReqRegister"; import MySqlService from "@services/mysql.service";
import CredentialService from "@services/credential.service"; import CredentialService from "@services/credential.service";
import JwtService from "@services/jwt.service"; import JwtService from "@services/jwt.service";
import MySqlService from "@services/mysql.service";
import MysqlService from "@services/mysql.service"; import MysqlService from "@services/mysql.service";
import { Logger } from "tslog"; import type {IReqRegister} from "@interfaces/requests/IReqRegister";
import {IReqLogin} from "@interfaces/requests/IReqLogin";
const logger = new Logger({
name: "UserService",
});
const DbHandler = new MySqlService.Handler("UserService"); const logger = new Logger({ name: "UserService" });
const DbHandler = new MySqlService.Handler('UserService')
/** /**
* Retrieves a user object from the database based on the given username. * Retrieves a user object from the database based on the given username.
@ -18,84 +17,55 @@ const DbHandler = new MySqlService.Handler("UserService");
* @param {string} username - The username of the user to retrieve. * @param {string} username - The username of the user to retrieve.
* @returns {Promise<Object | null>} - The user object if found, or null if not found. * @returns {Promise<Object | null>} - The user object if found, or null if not found.
*/ */
async function getUserFromUsername( async function getUserFromUsername(username: string): Promise<object | null> {
username: string, const dbUser = await MySqlService.User.getByUsername(DbHandler, username)
): Promise<object | null> {
const dbUser = await MySqlService.User.getByUsername(
DbHandler,
username,
);
if (dbUser === undefined) return null; if (dbUser === undefined) return null;
return dbUser; return dbUser;
} }
async function getUserFromIdService(id: string | undefined) { async function getUserFromIdService(id: string | undefined) {
const dbUser = await MySqlService.User.getById(DbHandler, id); const dbUser = await MySqlService.User.getById(DbHandler, id);
if (dbUser === undefined) return null; if (dbUser === undefined) return null;
return dbUser; return dbUser;
} }
async function register(ReqData: IReqRegister) { async function register(ReqData: IReqRegister) {
if (ReqData.password.length < 6) { if (ReqData.password.length < 6) {
logger.info( logger.info(`REGISTER :> Invalid password (${ReqData.username})`)
`REGISTER :> Invalid password (${ReqData.username})`, return { error: "invalidPassword" };
);
return {
error: "invalidPassword",
};
} }
const passwordHash = await CredentialService.hash( const passwordHash = await CredentialService.hash(ReqData.password)
ReqData.password,
);
// Does the new user has accepted GDPR ? // Does the new user has accepted GDPR ?
if (ReqData.gdpr !== true) { if (ReqData.gdpr !== true) {
logger.info( logger.info(`REGISTER :> GDPR not validated (${ReqData.username})`)
`REGISTER :> GDPR not validated (${ReqData.username})`, return { error: "gdprNotApproved" }
);
return {
error: "gdprNotApproved",
};
} }
// Check if exist and return // Check if exist and return
const dbUserIfExist = await getUserFromUsername( const dbUserIfExist = await getUserFromUsername(ReqData.username)
ReqData.username,
);
if (dbUserIfExist) { if (dbUserIfExist) {
logger.info( logger.info(`REGISTER :> User exist (${dbUserIfExist.username})\n ID:${dbUserIfExist.id}`)
`REGISTER :> User exist (${dbUserIfExist.username})\n ID:${dbUserIfExist.id}`, return { error: "exist" }
);
return {
error: "exist",
};
} }
const currentDate = new Date(); const currentDate = new Date();
// New UserService (class) // New UserService (class)
const NewUser = new User( const NewUser = new User(ReqData.username, ReqData.displayName, passwordHash, currentDate);
ReqData.username,
ReqData.displayName,
passwordHash,
currentDate,
);
NewUser.setFirstName(ReqData.firstName); NewUser.setFirstName(ReqData.firstName);
NewUser.setLastName(ReqData.lastName); NewUser.setLastName(ReqData.lastName);
// JWT // JWT
const alg = "HS512"; const alg = 'HS512'
const token = await JwtService.sign( const token = await JwtService.sign({
{ sub: NewUser.id
sub: NewUser.id, }, alg,
}, '1d',
alg, 'user')
"1d",
"user",
);
const userData = { const userData = {
error: "none", error: "none",
@ -105,74 +75,45 @@ async function register(ReqData: IReqRegister) {
username: NewUser.username, username: NewUser.username,
displayName: NewUser.displayName, displayName: NewUser.displayName,
firstName: NewUser.firstName, firstName: NewUser.firstName,
lastName: NewUser.lastName, lastName: NewUser.lastName
}, }};
}; logger.info(userData)
logger.info(userData);
await Db.collection("users").insertOne(NewUser); await Db.collection("users").insertOne(NewUser);
logger.info( logger.info(`REGISTER :> Inserted new user (${NewUser.username})`)
`REGISTER :> Inserted new user (${NewUser.username})`, return userData
);
return userData;
} }
async function login(ReqData: IReqLogin) { async function login(ReqData: IReqLogin) {
//const passwordHash = await getHashFromPassword(sanitizedData.password); //const passwordHash = await getHashFromPassword(sanitizedData.password);
const dbUser = await MysqlService.User.getByUsername( const dbUser = await MysqlService.User.getByUsername(DbHandler, ReqData.username);
DbHandler,
ReqData.username,
);
if (!dbUser) { if (!dbUser) {
console.log( console.log(`LoginService :> User does not exist (${ReqData.username})`);
`LoginService :> User does not exist (${ReqData.username})`, return { error: "userNotFound" };
);
return {
error: "userNotFound",
};
} }
if (ReqData.password.length < 6) { if (ReqData.password.length < 6) {
console.log("X"); console.log('X')
console.log( console.log(`LoginService :> Invalid password (${ReqData.username})`);
`LoginService :> Invalid password (${ReqData.username})`, return { error: "invalidPassword" };
);
return {
error: "invalidPassword",
};
} }
const isPasswordValid = await CredentialService.compare( const isPasswordValid = await CredentialService.compare(ReqData.password, dbUser.hash)
ReqData.password,
dbUser.hash,
);
if (!isPasswordValid) { if (!isPasswordValid) {
console.log(isPasswordValid); console.log(isPasswordValid)
console.log( console.log(`LoginService :> Invalid password (${ReqData.username})`);
`LoginService :> Invalid password (${ReqData.username})`, return { error: "invalidPassword" };
);
return {
error: "invalidPassword",
};
} }
// biome-ignore lint/style/useConst: <explanation> // biome-ignore lint/style/useConst: <explanation>
let userData = { let userData = {
error: "none", error: "none",
jwt: "", jwt: '',
user: { user: {
id: dbUser.id, id: dbUser.id,
username: dbUser.username, username: dbUser.username,
displayName: dbUser.displayName, displayName: dbUser.displayName,
}, }
}; };
userData.jwt = await JwtService.sign( userData.jwt = await JwtService.sign({sub: dbUser.id}, {alg: 'HS512'}, '7d', 'user')
{
sub: dbUser.id,
},
{
alg: "HS512",
},
"7d",
"user",
);
console.log("USERDATA :>"); console.log("USERDATA :>");
console.log(userData); console.log(userData);
@ -189,17 +130,17 @@ async function login(ReqData: IReqLogin) {
async function getAllUsersService() { async function getAllUsersService() {
const users = await Db.collection("users").find().toArray(); const users = await Db.collection("users").find().toArray();
// biome-ignore lint/complexity/noForEach: <explanation> // biome-ignore lint/complexity/noForEach: <explanation>
users.forEach((user) => { users.forEach(user => {
delete user.passwordHash; delete user.passwordHash
delete user._id; delete user._id
delete user.gdpr; delete user.gdpr
}); });
logger.info(`Query ${users.length} user(s)`); logger.info(`Query ${users.length} user(s)`)
return { return {
iat: Date.now(), iat: Date.now(),
users: users, users: users,
length: users.length, length: users.length
}; }
} }
/** /**
@ -213,34 +154,19 @@ async function getAllUsersService() {
*/ */
async function editUserService(targetId, sanitizedData) { async function editUserService(targetId, sanitizedData) {
if (sanitizedData.password) { if (sanitizedData.password) {
const passwordHash = await getHashFromPassword( const passwordHash = await getHashFromPassword(sanitizedData.password)
sanitizedData.password, delete sanitizedData.password
); logger.info(`Changing password for user "${targetId}"`)
delete sanitizedData.password; sanitizedData.passwordHash = passwordHash
logger.info(`Changing password for user "${targetId}"`);
sanitizedData.passwordHash = passwordHash;
} }
const updatedUserResult = await Db.collection( const updatedUserResult = await Db.collection("users").updateOne({id: targetId}, {$set: sanitizedData});
"users",
).updateOne(
{
id: targetId,
},
{
$set: sanitizedData,
},
);
if (updatedUserResult.modifiedCount === 0) { if (updatedUserResult.modifiedCount === 0) {
logger.info(`EDIT :> User not found (${targetId})`); logger.info(`EDIT :> User not found (${targetId})`);
return { return { error: "userNotFound" };
error: "userNotFound",
};
} }
logger.info(`EDIT :> User updated (${targetId})`); logger.info(`EDIT :> User updated (${targetId})`);
return { return { error: "none" };
error: "none",
};
} }
/** /**
@ -250,15 +176,13 @@ async function editUserService(targetId, sanitizedData) {
* @return {Promise<boolean>} - A promise that resolves to true if the user is successfully deleted, or false if an error occurs. * @return {Promise<boolean>} - A promise that resolves to true if the user is successfully deleted, or false if an error occurs.
*/ */
async function deleteUserService(targetId) { async function deleteUserService(targetId) {
logger.info(`Deleting user ${targetId}`); logger.info(`Deleting user ${targetId}`)
try { try {
await Db.collection("users").deleteOne({ await Db.collection("users").deleteOne({id: targetId});
id: targetId, return true
});
return true;
} catch (e) { } catch (e) {
logger.warn(e); logger.warn(e)
return false; return false
} }
} }
@ -268,7 +192,7 @@ const UserService = {
getAll: getAllUsersService, getAll: getAllUsersService,
getFromId: getUserFromIdService, getFromId: getUserFromIdService,
edit: editUserService, edit: editUserService,
delete: deleteUserService, delete: deleteUserService
}; }
export default UserService; export default UserService;

View File

@ -1,58 +1,39 @@
import JwtService from "@services/jwt.service"; import JwtService from "@services/jwt.service";
import type {NextFunction, Request, Response} from "express";
import MySqlService from "@services/mysql.service"; import MySqlService from "@services/mysql.service";
import MysqlService from "@services/mysql.service"; import MysqlService from "@services/mysql.service";
import type { NextFunction, Request, Response } from "express"; import {Logger} from "tslog";
import { Logger } from "tslog";
const DbHandler = new MySqlService.Handler("AdminGuard"); const DbHandler = new MySqlService.Handler('AdminGuard')
const logger = new Logger({ const logger = new Logger({name: 'AdminGuard'})
name: "AdminGuard",
});
const UNAUTHORIZED = 401; const UNAUTHORIZED = 401;
const FORBIDDEN = 403; const FORBIDDEN = 403;
const UNAUTH_MESSAGE = "Missing Authorization Header"; const UNAUTH_MESSAGE = 'Missing Authorization Header';
const INVALID_TOKEN_MESSAGE = "Invalid or expired token."; const INVALID_TOKEN_MESSAGE = 'Invalid or expired token.';
const PERMISSON_NOT_VALID = const PERMISSON_NOT_VALID = 'You are missing the required permission.'
"You are missing the required permission.";
async function AdminGuard( async function AdminGuard(req: Request, res: Response, next: NextFunction) {
req: Request,
res: Response,
next: NextFunction,
) {
const authHeader = req.headers.authorization; const authHeader = req.headers.authorization;
if (!authHeader) { if (!authHeader) {
logger.warn(`Invalid header (${req.ip})`); logger.warn(`Invalid header (${req.ip})`)
return res.status(UNAUTHORIZED).json({ return res.status(UNAUTHORIZED).json({message: UNAUTH_MESSAGE});
message: UNAUTH_MESSAGE,
});
} }
const bearerToken = authHeader.split(" ")[1]; const bearerToken = authHeader.split(' ')[1];
if (!bearerToken) if (!bearerToken) return res.status(FORBIDDEN).json({message: INVALID_TOKEN_MESSAGE});
return res.status(FORBIDDEN).json({
message: INVALID_TOKEN_MESSAGE,
});
const token = await JwtService.verify(bearerToken); const token = await JwtService.verify(bearerToken);
if (token) { if (token) {
// @ts-ignore // @ts-ignore
const isSourceAdmin = const isSourceAdmin = await MysqlService.User.getAdminStateForId(DbHandler, token.sub)
await MysqlService.User.getAdminStateForId(
DbHandler,
token.sub,
);
if (isSourceAdmin === true) next(); if (isSourceAdmin === true) next();
return res.status(FORBIDDEN).json({ return res.status(FORBIDDEN).json({message: PERMISSON_NOT_VALID});
message: PERMISSON_NOT_VALID,
});
} }
return res.status(FORBIDDEN).json({ return res.status(FORBIDDEN).json({message: INVALID_TOKEN_MESSAGE});
message: INVALID_TOKEN_MESSAGE,
});
} }
export default AdminGuard; export default AdminGuard

View File

@ -1,37 +1,26 @@
import JwtService from "@services/jwt.service"; import JwtService from "@services/jwt.service";
import type {NextFunction, Request, Response} from "express";
import MySqlService from "@services/mysql.service"; import MySqlService from "@services/mysql.service";
import type { NextFunction, Request, Response } from "express"; import {Logger} from "tslog";
import { Logger } from "tslog";
const DbHandler = new MySqlService.Handler("UserGuard"); const DbHandler = new MySqlService.Handler('UserGuard')
const logger = new Logger({ const logger = new Logger({name: 'UserGuard'})
name: "UserGuard",
});
const UNAUTHORIZED = 401; const UNAUTHORIZED = 401;
const FORBIDDEN = 403; const FORBIDDEN = 403;
const UNAUTH_MESSAGE = "Missing Authorization Header"; const UNAUTH_MESSAGE = 'Missing Authorization Header';
const INVALID_TOKEN_MESSAGE = "Invalid or expired token."; const INVALID_TOKEN_MESSAGE = 'Invalid or expired token.';
const USER_NOT_EXIST = "You dont exist anymore"; const USER_NOT_EXIST = 'You dont exist anymore'
async function UserGuard( async function UserGuard(req: Request, res: Response, next: NextFunction) {
req: Request,
res: Response,
next: NextFunction,
) {
const authHeader = req.headers.authorization; const authHeader = req.headers.authorization;
if (!authHeader) { if (!authHeader) {
return res.status(UNAUTHORIZED).json({ return res.status(UNAUTHORIZED).json({message: UNAUTH_MESSAGE});
message: UNAUTH_MESSAGE,
});
} }
const bearerToken = authHeader.split(" ")[1]; const bearerToken = authHeader.split(' ')[1];
if (!bearerToken) if (!bearerToken) return res.status(FORBIDDEN).json({message: INVALID_TOKEN_MESSAGE});
return res.status(FORBIDDEN).json({
message: INVALID_TOKEN_MESSAGE,
});
const token = await JwtService.verify(bearerToken); const token = await JwtService.verify(bearerToken);
@ -40,25 +29,16 @@ async function UserGuard(
const userId = token.sub; const userId = token.sub;
if (!userId) { if (!userId) {
logger.error(USER_NOT_EXIST); logger.error(USER_NOT_EXIST);
return res.status(UNAUTHORIZED).json({ return res.status(UNAUTHORIZED).json({message: USER_NOT_EXIST});
message: USER_NOT_EXIST,
});
} }
const user = await MySqlService.User.getById( const user= await MySqlService.User.getById(DbHandler, userId);
DbHandler, if (user) {
userId, logger.info(`An user do a request. (${user?.username})`)
); next()
if (user) {
logger.info(`An user do a request. (${user?.username})`);
next();
} }
return res.status(UNAUTHORIZED).json({ return res.status(UNAUTHORIZED).json({message: USER_NOT_EXIST});
message: USER_NOT_EXIST,
});
} }
return res.status(FORBIDDEN).json({ return res.status(FORBIDDEN).json({message: INVALID_TOKEN_MESSAGE});
message: INVALID_TOKEN_MESSAGE,
});
} }
export default UserGuard; export default UserGuard