diff --git a/biome.json b/biome.json index 018253b..a599672 100644 --- a/biome.json +++ b/biome.json @@ -3,6 +3,15 @@ "organizeImports": { "enabled": true }, + "files": { + "include": [ + "./src/**/*.ts" + ] + }, + "vcs": { + "enabled": true, + "clientKind": "git" + }, "linter": { "enabled": true, "rules": { @@ -17,8 +26,8 @@ } }, "formatter": { - "indentStyle": "space", + "indentStyle": "tab", "indentWidth": 2, - "lineWidth": 15 + "lineWidth": 64 } } diff --git a/package.json b/package.json index f569640..b75452e 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "author": "Mathis HERRIOT", "license": "MIT", "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": { "@node-rs/argon2": "^1.8.3", diff --git a/src/app.ts b/src/app.ts index 19c9b17..cfd298d 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,21 +1,22 @@ -import express, { type Express } from 'express'; -import cors from 'cors'; -import compression from 'compression'; -import {Logger} from "tslog"; -import helmet from "helmet"; +import * as process from "node:process"; import AuthRouter from "@routes/auth/authRouter"; import CatalogRouter from "@routes/catalog/catalogRouter"; import RentRouter from "@routes/rent/rentRouter"; -import * as process from "node:process"; +import compression from "compression"; +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(); // enable cors app.use(cors()); -app.options('*', cors()); +app.options("*", cors()); // enable xss sanitizer app.use( @@ -23,31 +24,35 @@ app.use( xXssProtection: true, }), ); -app.use(helmet.xXssProtection()) +app.use(helmet.xXssProtection()); // parse json request body app.use(express.json()); // parse urlencoded request body -app.use(express.urlencoded({ extended: true })); +app.use( + express.urlencoded({ + extended: true, + }), +); // gzip compression -app.use(compression()) +app.use(compression()); try { - app.use('/auth', AuthRouter) - app.use('/catalog', CatalogRouter) - app.use('/rent', RentRouter) - logger.info('Routers loaded !') + app.use("/auth", AuthRouter); + app.use("/catalog", CatalogRouter); + app.use("/rent", RentRouter); + logger.info("Routers loaded !"); } catch (err) { - logger.error(err) + logger.error(err); throw null; } try { - app.listen(process.env["APP_PORT"]) - logger.info('Server is running !') + app.listen(process.env["APP_PORT"]); + logger.info("Server is running !"); } catch (error) { logger.error(`Server failed to start: ${error}`); - process.exit(1); -} \ No newline at end of file + process.exit(1); +} diff --git a/src/controllers/auth.controller.ts b/src/controllers/auth.controller.ts index 66f5c80..00854bd 100644 --- a/src/controllers/auth.controller.ts +++ b/src/controllers/auth.controller.ts @@ -1,13 +1,13 @@ import JwtService from "@services/jwt.service"; - -import type {IReqEditUserData} from "@interfaces/IReqEditUserData"; +import type { IReqEditUserData } from "@interfaces/IReqEditUserData"; import UserService from "@services/user.service"; -import type {Request, Response} from "express"; -import {Logger} from "tslog"; +import type { Request, Response } from "express"; +import { Logger } from "tslog"; - -const logger = new Logger({ name: "AuthController" }); +const logger = new Logger({ + name: "AuthController", +}); //FIX Better return object interface /** @@ -22,60 +22,65 @@ const logger = new Logger({ name: "AuthController" }); * - error: "exist" if the user already exists * - Otherwise, the registered user data */ -async function registerUser(req: Request, res: Response): Promise { +async function registerUser( + req: Request, + res: Response, +): Promise { const body = req.body; if (!body) { logger.warn(`Invalid input data (${req.ip})`); - return res - .type('application/json') - .status(400) - .json({ error: 'Invalid input data' }); + return res.type("application/json").status(400).json({ + error: "Invalid input data", + }); } - if (!body.password || !body.username || !body.firstName || !body.lastName || !body.displayName) { + if ( + !body.password || + !body.username || + !body.firstName || + !body.lastName || + !body.displayName + ) { logger.warn(`Field(s) missing (${req.ip})`); - return res - .type('application/json') - .status(400) - .json({ error: 'Field(s) missing' }); + return res.type("application/json").status(400).json({ + error: "Field(s) missing", + }); } - let gdpr = false - if (body.gdpr === true) {gdpr = true} - const sanitizeData= { - username: `${body.username}`, - displayName: `${body.displayName}`, - gdpr: gdpr, - password: `${body.password}`, - firstName: `${body.firstName}`, - lastName: `${body.lastName}`, + let gdpr = false; + if (body.gdpr === true) { + gdpr = true; + } + const sanitizeData = { + username: `${body.username}`, + displayName: `${body.displayName}`, + gdpr: gdpr, + password: `${body.password}`, + firstName: `${body.firstName}`, + lastName: `${body.lastName}`, }; - const RegisterServiceResult = await UserService.register(sanitizeData) + const RegisterServiceResult = + await UserService.register(sanitizeData); if (RegisterServiceResult.error === "gdprNotApproved") { logger.warn(`GDPR not approved (${req.ip})`); - return res - .status(400) - .json({ - error: RegisterServiceResult.error, - message: "GDPR not accepted." - }); + return res.status(400).json({ + error: RegisterServiceResult.error, + message: "GDPR not accepted.", + }); } if (RegisterServiceResult.error === "exist") { logger.warn(`The user already exists (${req.ip})`); - return res - .type('application/json') - .status(400) - .json({ - error: RegisterServiceResult.error, - message: "The user already exists." - }); + return res.type("application/json").status(400).json({ + error: RegisterServiceResult.error, + message: "The user already exists.", + }); } // SUCCESS logger.info(`User registered successfully (${req.ip})`); return res - .type('application/json') + .type("application/json") .status(201) .json(RegisterServiceResult); } @@ -88,378 +93,352 @@ async function registerUser(req: Request, res: Response): Promise { * * @return {Promise} A promise that resolves when the user is logged in or rejects with an error. */ -async function loginUser(req: Request, res: Response): Promise { - +async function loginUser( + req: Request, + res: Response, +): Promise { const body = req.body; if (!body) { - res - .type('application/json') - .status(400) - .json({ error: 'Invalid input data' }); + res.type("application/json").status(400).json({ + error: "Invalid input data", + }); } if (!body.password || !body.username) { logger.warn(`Field(s) missing (${req.ip})`); - res - .type('application/json') - .status(400) - .json({ error: 'Field(s) missing' }); + res.type("application/json").status(400).json({ + error: "Field(s) missing", + }); } const loginData = { username: `${body.username}`, - password: `${body.password}` + password: `${body.password}`, }; - console.log(body) + console.log(body); const LoginServiceResult = await UserService.login(loginData); - console.log(LoginServiceResult) + console.log(LoginServiceResult); if (LoginServiceResult.error === "userNotFound") { - console.log('POOL') - res - .type('application/json') - .status(404) - .json({ - error: LoginServiceResult.error, - message: "User not found." - }); + console.log("POOL"); + res.type("application/json").status(404).json({ + error: LoginServiceResult.error, + message: "User not found.", + }); } if (LoginServiceResult.error === "invalidPassword") { - res - .type('application/json') - .status(401) - .json({ - error: LoginServiceResult.error, - message: "Invalid password." - }); + res.type("application/json").status(401).json({ + error: LoginServiceResult.error, + message: "Invalid password.", + }); } res - .type('application/json') + .type("application/json") .status(200) .json(LoginServiceResult); } async function getAllUsers(req: Request, res: Response) { const authHeader = req.headers.authorization; - const bearerToken = authHeader?.split(' ')[1]; + const bearerToken = authHeader?.split(" ")[1]; if (!bearerToken) { logger.warn(`Bearer token not provided (${req.ip})`); - return res - .type('application/json') - .status(401) - .json({ error: 'Unauthorized' }); + return res.type("application/json").status(401).json({ + error: "Unauthorized", + }); } const payload = await JwtService.verify(bearerToken); if (!payload) { logger.warn(`Unauthorized access attempt (${req.ip})`); - return res - .type('application/json') - .status(401) - .json({ error: 'Unauthorized' }); + return res.type("application/json").status(401).json({ + error: "Unauthorized", + }); } - const sourceUser = await UserService.getFromId(payload.sub) + const sourceUser = await UserService.getFromId(payload.sub); if (!sourceUser) { - return res - .type('application/json') - .status(404) - .json({ error: 'You dont exist anymore' }); + return res.type("application/json").status(404).json({ + error: "You dont exist anymore", + }); } if (!sourceUser.is_admin) { - return res - .type('application/json') - .status(403) - .json({ error: 'Unauthorized' }); + return res.type("application/json").status(403).json({ + error: "Unauthorized", + }); } - const AllUserResponse = await UserService.getAll() + const AllUserResponse = await UserService.getAll(); if (!AllUserResponse.users) { - return res - .type('application/json') - .status(500) - .json({ error: 'Internal server error' }); + return res.type("application/json").status(500).json({ + error: "Internal server error", + }); } return res - .type('application/json') + .type("application/json") .status(200) .json(AllUserResponse); } async function getUser(req: Request, res: Response) { const authHeader = req.headers.authorization; - const bearerToken = authHeader?.split(' ')[1]; + const bearerToken = authHeader?.split(" ")[1]; if (!bearerToken) { logger.warn(`Bearer token not provided (${req.ip})`); - return res - .type('application/json') - .status(401) - .json({ error: 'Unauthorized' }); + return res.type("application/json").status(401).json({ + error: "Unauthorized", + }); } const payload = await JwtService.verify(bearerToken); if (!payload) { logger.warn(`Unauthorized access attempt (${req.ip})`); - return res - .type('application/json') - .status(401) - .json({ error: 'Unauthorized' }); + return res.type("application/json").status(401).json({ + error: "Unauthorized", + }); } - const sourceUser = await UserService.getFromId(payload.sub) + const sourceUser = await UserService.getFromId(payload.sub); if (!sourceUser) { - return res - .type('application/json') - .status(404) - .json({ error: 'You dont exist anymore' }); + return res.type("application/json").status(404).json({ + error: "You dont exist anymore", + }); } if (!sourceUser.is_admin) { - return res - .type('application/json') - .status(403) - .json({ error: 'Unauthorized' }); + return res.type("application/json").status(403).json({ + error: "Unauthorized", + }); } const userId = req.params["id"]; const dbUser = await UserService.getFromId(userId); if (!dbUser) { logger.warn(`User not found (${req.ip})`); - return res - .type('application/json') - .status(404) - .json({ error: 'User not found' }); + return res.type("application/json").status(404).json({ + error: "User not found", + }); } // @ts-ignore - delete dbUser.passwordHash + delete dbUser.passwordHash; // @ts-ignore - delete dbUser._id - return res - .type('application/json') - .status(200) - .json(dbUser); + delete dbUser._id; + return res.type("application/json").status(200).json(dbUser); } //FEAT - Implement re-auth by current password in case of password change async function editUser(req: Request, res: Response) { const body: IReqEditUserData | null = req.body; if (!body) { - return res - .type('application/json') - .status(400) - .json({ error: 'Field(s) missing' }); + return res.type("application/json").status(400).json({ + error: "Field(s) missing", + }); } const authHeader = req.headers.authorization; - const bearerToken = authHeader?.split(' ')[1]; + const bearerToken = authHeader?.split(" ")[1]; if (!bearerToken) { logger.warn(`Bearer token not provided (${req.ip})`); - return res - .type('application/json') - .status(401) - .json({ error: 'Unauthorized' }); + return res.type("application/json").status(401).json({ + error: "Unauthorized", + }); } const payload = await JwtService.verify(bearerToken); if (!payload) { logger.warn(`Unauthorized access attempt (${req.ip})`); - return res - .type('application/json') - .status(401) - .json({ error: 'Unauthorized' }); + return res.type("application/json").status(401).json({ + error: "Unauthorized", + }); } - const sourceUser = await UserService.getFromId(payload.sub) + const sourceUser = await UserService.getFromId(payload.sub); //@ts-ignore - const targetUserId = req.params.id || payload.sub - console.log(targetUserId) + const targetUserId = req.params.id || payload.sub; + console.log(targetUserId); if (!sourceUser) { logger.warn(`Unauthorized access attempt (${req.ip})`); - return res - .type('application/json') - .status(404) - .json({ error: 'You dont exist anymore' }); + return res.type("application/json").status(404).json({ + error: "You dont exist anymore", + }); } if (sourceUser.is_admin || sourceUser.id === payload.sub) { if (sourceUser.is_admin) { - logger.info(`EDIT :> Source user is an admin (${sourceUser.firstname} ${sourceUser.lastname})`) + logger.info( + `EDIT :> Source user is an admin (${sourceUser.firstname} ${sourceUser.lastname})`, + ); } else { - logger.info(`EDIT :> Source user modify itself (${sourceUser.firstname} ${sourceUser.lastname})`) + logger.info( + `EDIT :> Source user modify itself (${sourceUser.firstname} ${sourceUser.lastname})`, + ); } //TODO Interface - const modifiedData = { - } + const modifiedData = {}; //@ts-ignore - if (body.firstName) modifiedData.firstName = `${body.firstName}`; + if (body.firstName) + modifiedData.firstName = `${body.firstName}`; //@ts-ignore - if (body.lastName) modifiedData.lastName = `${body.lastName}`; + if (body.lastName) + modifiedData.lastName = `${body.lastName}`; //@ts-ignore - if (body.displayName) modifiedData.displayName = `${body.displayName}`; + if (body.displayName) + modifiedData.displayName = `${body.displayName}`; //TODO Case handled with hashing by the service. //if (body.password) modifiedData.password = `${body.password}`; //Call service - const EditUserServiceResult = await UserService.edit(`${targetUserId}`, modifiedData); - if (EditUserServiceResult.error === 'userNotFound') { + const EditUserServiceResult = await UserService.edit( + `${targetUserId}`, + modifiedData, + ); + if (EditUserServiceResult.error === "userNotFound") { logger.warn(`User not found (${req.ip})`); - return res - .type('application/json') - .status(404) - .json({ error: 'User not found' }); + return res.type("application/json").status(404).json({ + error: "User not found", + }); } - if (EditUserServiceResult.error !== 'none') { - logger.error(`Error occurred during user edit (${req.ip})`); - return res - .type('application/json') - .status(500) - .json({ error: 'Internal server error' }); + if (EditUserServiceResult.error !== "none") { + logger.error( + `Error occurred during user edit (${req.ip})`, + ); + return res.type("application/json").status(500).json({ + error: "Internal server error", + }); } return res - .type('application/json') + .type("application/json") .status(200) .json(EditUserServiceResult); } //Not itself or - logger.warn(`Unauthorized access attempt, not self or admin (${req.ip})`); - return res - .type('application/json') - .status(403) - .json({ error: 'Unauthorized' }); - - + logger.warn( + `Unauthorized access attempt, not self or admin (${req.ip})`, + ); + return res.type("application/json").status(403).json({ + error: "Unauthorized", + }); } -async function deleteUser(req: Request, res: Response): Promise { +async function deleteUser( + req: Request, + res: Response, +): Promise { const authHeader = req.headers.authorization; - const bearerToken = authHeader?.split(' ')[1]; + const bearerToken = authHeader?.split(" ")[1]; if (!bearerToken) { logger.warn(`Bearer token not provided (${req.ip})`); - return res - .type('application/json') - .status(401) - .json({ error: 'Unauthorized' }); + return res.type("application/json").status(401).json({ + error: "Unauthorized", + }); } const payload = await JwtService.verify(bearerToken); if (!payload) { logger.warn(`Invalid token (${req.ip})`); - return res - .type('application/json') - .status(401) - .json({ error: 'Invalid token' }); + return res.type("application/json").status(401).json({ + error: "Invalid token", + }); } - const sourceUser = await UserService.getFromId(payload?.sub) - const targetUserId = req.params["id"] + const sourceUser = await UserService.getFromId(payload?.sub); + const targetUserId = req.params["id"]; if (!sourceUser) { logger.warn(`Unauthorized access attempt (${req.ip})`); - return res - .type('application/json') - .status(404) - .json({ error: 'You dont exist anymore' }); + return res.type("application/json").status(404).json({ + error: "You dont exist anymore", + }); } if (sourceUser.is_admin || sourceUser.id === payload.sub) { - const deleteUserServiceResult = await UserService.delete(`${targetUserId}`); + const deleteUserServiceResult = await UserService.delete( + `${targetUserId}`, + ); if (!deleteUserServiceResult) { - logger.error(`Error occurred during user delete (${req.ip})`); - return res - .type('application/json') - .status(500) - .json({ error: 'Internal server error' }); + logger.error( + `Error occurred during user delete (${req.ip})`, + ); + return res.type("application/json").status(500).json({ + error: "Internal server error", + }); } - return res - .type('application/json') - .status(200) - .json({ message: 'User deleted successfully' }); + return res.type("application/json").status(200).json({ + message: "User deleted successfully", + }); } - return res - .type('application/json') - .status(403) - .json({ error: 'Unauthorized' }); + return res.type("application/json").status(403).json({ + error: "Unauthorized", + }); } async function deleteSelf(req: Request, res: Response) { const authHeader = req.headers.authorization; - const bearerToken = authHeader?.split(' ')[1]; - if (!bearerToken) { - logger.warn(`Bearer token not provided (${req.ip})`); - return res - .type('application/json') - .status(401) - .json({ error: 'Unauthorized' }); - } - const payload = await JwtService.verify(bearerToken); - if (!payload) { - logger.warn(`Unauthorized access attempt (${req.ip})`); - return res - .type('application/json') - .status(401) - .json({ error: 'Unauthorized' }); - } - const sourceUser = await UserService.getFromId(payload.sub) - if (!sourceUser) { - return res - .type('application/json') - .status(404) - .json({ error: 'You dont exist anymore' }); - } - if (sourceUser.id !== req.params["id"]) { - return res - .type('application/json') - .status(403) - .json({ error: 'Unauthorized' }); - } - const deleteResult = await UserService.delete(sourceUser.id); + const bearerToken = authHeader?.split(" ")[1]; + if (!bearerToken) { + logger.warn(`Bearer token not provided (${req.ip})`); + return res.type("application/json").status(401).json({ + error: "Unauthorized", + }); + } + const payload = await JwtService.verify(bearerToken); + if (!payload) { + logger.warn(`Unauthorized access attempt (${req.ip})`); + return res.type("application/json").status(401).json({ + error: "Unauthorized", + }); + } + const sourceUser = await UserService.getFromId(payload.sub); + if (!sourceUser) { + return res.type("application/json").status(404).json({ + error: "You dont exist anymore", + }); + } + if (sourceUser.id !== req.params["id"]) { + return res.type("application/json").status(403).json({ + error: "Unauthorized", + }); + } + const deleteResult = await UserService.delete(sourceUser.id); if (!deleteResult) { logger.error(`Failed to delete user (${req.ip})`); - return res - .type('application/json') - .status(500) - .json({ error: 'Failed to delete user' }); + return res.type("application/json").status(500).json({ + error: "Failed to delete user", + }); } - return res - .type('application/json') - .status(200) - .json({ message: 'User deleted successfully' }); + return res.type("application/json").status(200).json({ + message: "User deleted successfully", + }); } async function getSelf(req: Request, res: Response) { const authHeader = req.headers.authorization; - const bearerToken = authHeader?.split(' ')[1]; + const bearerToken = authHeader?.split(" ")[1]; if (!bearerToken) { - return res - .type('application/json') - .status(401) - .json({ error: 'Unauthorized' }); + return res.type("application/json").status(401).json({ + error: "Unauthorized", + }); } const payload = await JwtService.verify(bearerToken); if (!payload) { - logger.warn(`Unauthorized access attempt (${req.ip})`); - return res - .type('application/json') - .status(401) - .json({ error: 'Unauthorized' }); - } - const dbUser = await UserService.getFromId(payload.sub) - if (!dbUser) { - return res - .type('application/json') - .status(404) - .json({ error: 'User not found' }); - } - return res - .type('application/json') - .status(200) - .json({ - id: dbUser.id, - username: dbUser.username, - firstName: dbUser.firstname, - lastName: dbUser.firstname, - isAdmin: dbUser.firstname + logger.warn(`Unauthorized access attempt (${req.ip})`); + return res.type("application/json").status(401).json({ + error: "Unauthorized", }); + } + const dbUser = await UserService.getFromId(payload.sub); + if (!dbUser) { + return res.type("application/json").status(404).json({ + error: "User not found", + }); + } + return res.type("application/json").status(200).json({ + id: dbUser.id, + username: dbUser.username, + firstName: dbUser.firstname, + lastName: dbUser.firstname, + isAdmin: dbUser.firstname, + }); } const AuthController = { register: registerUser, - login: loginUser, - getAllUsers, - getUser, - editUser, - deleteUser, + login: loginUser, + getAllUsers, + getUser, + editUser, + deleteUser, deleteSelf, - getSelf -} + getSelf, +}; -export default AuthController; \ No newline at end of file +export default AuthController; diff --git a/src/controllers/brand.controller.ts b/src/controllers/brand.controller.ts index 9ae4c74..4199401 100644 --- a/src/controllers/brand.controller.ts +++ b/src/controllers/brand.controller.ts @@ -1,13 +1,13 @@ -import type {Request, Response} from "express"; -import {Logger} from "tslog"; - +import type { Request, Response } from "express"; +import { Logger } from "tslog"; import type IDbBrand from "@interfaces/database/IDbBrand"; import BrandService from "@services/brand.service"; //import {body} from "express-validator"; - -const logger = new Logger({ name: "BrandController" }); +const logger = new Logger({ + name: "BrandController", +}); /** * Creates a new brand. @@ -17,24 +17,37 @@ const logger = new Logger({ name: "BrandController" }); * * @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(req: Request, res: Response): Promise { - const body: IDbBrand = req.body - const doesExist = await BrandService.getBySlug(`${body.slug_name}`) +async function createBrand( + req: Request, + res: Response, +): Promise { + const body: IDbBrand = req.body; + const doesExist = await BrandService.getBySlug( + `${body.slug_name}`, + ); if (doesExist) { logger.error("Brand already exists"); - return res.status(400).json({ error: "Brand already exists" }); + return res.status(400).json({ + error: "Brand already exists", + }); } const createResult = await BrandService.create({ slug_name: `${body.slug_name}`, display_name: `${body.display_name}`, - image_blob: `${body.image_blob}` - }) + image_blob: `${body.image_blob}`, + }); if (!createResult) { logger.error("Failed to create brand"); - return res.status(500).json({ error: "Failed to create brand" }); + return res.status(500).json({ + error: "Failed to create brand", + }); } - logger.info(`Brand created successfully ! (${body.slug_name})`) - return res.status(201).json({ message: "Brand created successfully" }); + logger.info( + `Brand created successfully ! (${body.slug_name})`, + ); + return res.status(201).json({ + message: "Brand created successfully", + }); } /** @@ -44,29 +57,40 @@ async function createBrand(req: Request, res: Response): Promise { * @param {Response} res - The HTTP response object. * @return {Promise} A promise that resolves with the HTTP response. */ -async function updateBrand(req: Request, res: Response): Promise { +async function updateBrand( + req: Request, + res: Response, +): Promise { const body: IDbBrand = req.body; - const brandSlug = req.params["brandSlug"]; + const brandSlug = req.params["brandSlug"]; if (!brandSlug) { logger.error("Brand slug is missing"); - return res.status(400).json({ error: "Brand slug is missing" }); + return res.status(400).json({ + error: "Brand slug is missing", + }); } - const doesExist = await BrandService.getBySlug(brandSlug); - if (!doesExist) { - logger.error("Brand not found"); - return res.status(404).json({ error: "Brand not found" }); - } - const updateResult = await BrandService.update({ - slug_name: `${body.slug_name}`, - display_name: `${body.display_name}`, - image_blob: `${body.image_blob}` - }); - if (!updateResult) { - logger.error("Failed to update brand"); - return res.status(500).json({ error: "Failed to update brand" }); - } - logger.info(`Brand updated successfully ! (${brandSlug})`); - return res.status(200).json({ message: "Brand updated successfully" }); + const doesExist = await BrandService.getBySlug(brandSlug); + if (!doesExist) { + logger.error("Brand not found"); + return res.status(404).json({ + error: "Brand not found", + }); + } + const updateResult = await BrandService.update({ + slug_name: `${body.slug_name}`, + display_name: `${body.display_name}`, + image_blob: `${body.image_blob}`, + }); + if (!updateResult) { + logger.error("Failed to update brand"); + return res.status(500).json({ + error: "Failed to update brand", + }); + } + logger.info(`Brand updated successfully ! (${brandSlug})`); + return res.status(200).json({ + message: "Brand updated successfully", + }); } /** @@ -76,19 +100,26 @@ async function updateBrand(req: Request, res: Response): Promise { * @param {Response} res - The response object to send the result. * @returns {Promise} - A promise that resolves to the response with the retrieved brand. */ -async function getBySlugBrand(req: Request, res: Response): Promise { +async function getBySlugBrand( + req: Request, + res: Response, +): Promise { const brandSlug = req.params["brandSlug"]; - if (!brandSlug) { - logger.error("Brand slug is missing"); - return res.status(400).json({ error: "Brand slug is missing" }); - } - const brand = await BrandService.getBySlug(brandSlug); - if (!brand) { - logger.error("Brand not found"); - return res.status(404).json({ error: "Brand not found" }); - } - logger.info(`Brand retrieved successfully ! (${brandSlug})`); - return res.status(200).json(brand); + if (!brandSlug) { + logger.error("Brand slug is missing"); + return res.status(400).json({ + error: "Brand slug is missing", + }); + } + const brand = await BrandService.getBySlug(brandSlug); + if (!brand) { + logger.error("Brand not found"); + return res.status(404).json({ + error: "Brand not found", + }); + } + logger.info(`Brand retrieved successfully ! (${brandSlug})`); + return res.status(200).json(brand); } /** @@ -98,17 +129,22 @@ async function getBySlugBrand(req: Request, res: Response): Promise { * @param {Response} res - The response object. * @returns {Promise} - A promise with the response object. */ -async function getAllBrand(_req: Request, res: Response): Promise { +async function getAllBrand( + _req: Request, + res: Response, +): Promise { const brands = await BrandService.getAll(); - if (!brands) { - logger.error("Failed to retrieve brands"); - return res.status(500).json({ error: "Failed to retrieve brands" }); - } - logger.info("Brands retrieved successfully !"); - return res.status(200).json({ + if (!brands) { + logger.error("Failed to retrieve brands"); + return res.status(500).json({ + error: "Failed to retrieve brands", + }); + } + logger.info("Brands retrieved successfully !"); + return res.status(200).json({ uat: Date.now(), brands: brands, - total: brands.length + total: brands.length, }); } @@ -120,25 +156,36 @@ async function getAllBrand(_req: Request, res: Response): Promise { * @param {Response} res - The response object. * @returns {Promise} - The response object indicating the success or failure of the delete operation. */ -async function deleteBrand(req: Request, res: Response): Promise { +async function deleteBrand( + req: Request, + res: Response, +): Promise { const brandSlug = req.params["brandSlug"]; - if (!brandSlug) { - logger.error("Brand slug is missing"); - return res.status(400).json({ error: "Brand slug is missing" }); - } + if (!brandSlug) { + logger.error("Brand slug is missing"); + return res.status(400).json({ + error: "Brand slug is missing", + }); + } //TODO verify if models linked to brand - const doesExist = await BrandService.getBySlug(brandSlug); - if (!doesExist) { - logger.error("Brand not found"); - return res.status(404).json({ error: "Brand not found" }); - } - const deleteResult = await BrandService.delete(brandSlug); - if (!deleteResult) { - logger.error("Failed to delete brand"); - return res.status(500).json({ error: "Failed to delete brand" }); - } - logger.info(`Brand deleted successfully ! (${brandSlug})`); - return res.status(200).json({ message: "Brand deleted successfully" }); + const doesExist = await BrandService.getBySlug(brandSlug); + if (!doesExist) { + logger.error("Brand not found"); + return res.status(404).json({ + error: "Brand not found", + }); + } + const deleteResult = await BrandService.delete(brandSlug); + if (!deleteResult) { + logger.error("Failed to delete brand"); + return res.status(500).json({ + error: "Failed to delete brand", + }); + } + logger.info(`Brand deleted successfully ! (${brandSlug})`); + return res.status(200).json({ + message: "Brand deleted successfully", + }); } //TODO get models of the brand @@ -149,6 +196,6 @@ const BrandController = { getBySlug: getBySlugBrand, getAll: getAllBrand, delete: deleteBrand, -} +}; -export default BrandController; \ No newline at end of file +export default BrandController; diff --git a/src/controllers/category.controller.ts b/src/controllers/category.controller.ts index 0c3d93c..159428d 100644 --- a/src/controllers/category.controller.ts +++ b/src/controllers/category.controller.ts @@ -1,12 +1,12 @@ -import type {Request, Response} from "express"; -import {Logger} from "tslog"; import type IDbCategory from "@interfaces/database/IDbCategory"; import CategoryService from "@services/category.service"; +import type { Request, Response } from "express"; +import { Logger } from "tslog"; //import {validationResult} from "express-validator"; - -const logger = new Logger({ name: "CategoryController" }); - +const logger = new Logger({ + name: "CategoryController", +}); /** * Creates a new category. @@ -15,23 +15,36 @@ const logger = new Logger({ name: "CategoryController" }); * @param {Response} res - The response object to send back to the client. * @returns {Promise} The response object indicating the outcome of the category creation. */ -async function createCategory(req: Request, res: Response): Promise { - const body: IDbCategory = req.body - const doesExist = await CategoryService.getBySlug(`${body.slug_name}`) +async function createCategory( + req: Request, + res: Response, +): Promise { + const body: IDbCategory = req.body; + const doesExist = await CategoryService.getBySlug( + `${body.slug_name}`, + ); if (doesExist) { - logger.error("Category already exists"); - return res.status(400).json({ error: "Category already exists" }); - } + logger.error("Category already exists"); + return res.status(400).json({ + error: "Category already exists", + }); + } const createResult = await CategoryService.create({ display_name: `${body.display_name}`, - slug_name: `${body.slug_name}` - }) + slug_name: `${body.slug_name}`, + }); if (!createResult) { logger.error("Failed to create category"); - return res.status(500).json({ error: "Failed to create category" }); + return res.status(500).json({ + error: "Failed to create category", + }); } - logger.info(`Category created successfully ! (${body.slug_name})`) - return res.status(201).json({ message: "Category created successfully" }); + logger.info( + `Category created successfully ! (${body.slug_name})`, + ); + return res.status(201).json({ + message: "Category created successfully", + }); } /** @@ -42,29 +55,42 @@ async function createCategory(req: Request, res: Response): Promise { * * @return {Promise} - A promise that will be resolved with the result of the update operation. */ -async function updateCategory(req: Request, res:Response): Promise { +async function updateCategory( + req: Request, + res: Response, +): Promise { const body: IDbCategory = req.body; - const categoryId = req.params["categorySlug"]; + const categoryId = req.params["categorySlug"]; if (!categoryId) { logger.error("Category slug is missing"); - return res.status(400).json({ error: "Category slug is missing" }); + return res.status(400).json({ + error: "Category slug is missing", + }); } - const doesExist = await CategoryService.getById(`${categoryId}`) - if (!doesExist || !doesExist.id) { - logger.error("Category not found"); - return res.status(404).json({ error: "Category not found" }); - } - const updateResult = await CategoryService.update({ + const doesExist = await CategoryService.getById( + `${categoryId}`, + ); + if (!doesExist || !doesExist.id) { + logger.error("Category not found"); + return res.status(404).json({ + error: "Category not found", + }); + } + const updateResult = await CategoryService.update({ id: doesExist.id, slug_name: `${body.slug_name}`, - display_name: `${body.display_name}` - }) - if (!updateResult) { - logger.error("Failed to update category"); - return res.status(500).json({ error: "Failed to update category" }); - } - logger.info(`Category updated successfully! (${categoryId})`); - return res.status(200).json({ message: "Category updated successfully" }); + display_name: `${body.display_name}`, + }); + if (!updateResult) { + logger.error("Failed to update category"); + return res.status(500).json({ + error: "Failed to update category", + }); + } + logger.info(`Category updated successfully! (${categoryId})`); + return res.status(200).json({ + message: "Category updated successfully", + }); } /** @@ -74,24 +100,41 @@ async function updateCategory(req: Request, res:Response): Promise { * @param {Response} res - The response object to send the result. * @returns {Promise} A Promise that resolves to the response object. */ -async function deleteCategory(req: Request, res: Response): Promise { +async function deleteCategory( + req: Request, + res: Response, +): Promise { const categorySlug = req.params["categorySlug"]; - if (!categorySlug) { - logger.error("Category slug is missing"); - return res.status(400).json({ error: "Category slug is missing" }); - } - const doesExist = await CategoryService.getBySlug(`${categorySlug}`); - if (!doesExist || !doesExist.id) { - logger.error("Category not found"); - return res.status(404).json({ error: "Category not found" }); - } - const deleteResult = await CategoryService.delete(`${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" }); + if (!categorySlug) { + logger.error("Category slug is missing"); + return res.status(400).json({ + error: "Category slug is missing", + }); + } + const doesExist = await CategoryService.getBySlug( + `${categorySlug}`, + ); + if (!doesExist || !doesExist.id) { + logger.error("Category not found"); + return res.status(404).json({ + error: "Category not found", + }); + } + const deleteResult = await CategoryService.delete( + `${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", + }); } /** @@ -101,23 +144,26 @@ async function deleteCategory(req: Request, res: Response): Promise { * @param {Response} res - The response object. * @return {Promise} - A promise that resolves to the response object. */ -async function getAllCategory(_req: Request, res: Response): Promise { +async function getAllCategory( + _req: Request, + res: Response, +): Promise { const categories = await CategoryService.getAll(); - if (!categories) { - logger.error("Failed to get categories"); - return res.status(500).json({ error: "Failed to get categories" }); - } - logger.info("Categories retrieved successfully"); - return res - .status(200) - .json({ + if (!categories) { + logger.error("Failed to get categories"); + return res.status(500).json({ + error: "Failed to get categories", + }); + } + logger.info("Categories retrieved successfully"); + return res.status(200).json({ iat: Date.now(), categories: categories.map((category: IDbCategory) => ({ - id: category.id, - display_name: category.display_name, - slug_name: category.slug_name - })), - total: categories.length + id: category.id, + display_name: category.display_name, + slug_name: category.slug_name, + })), + total: categories.length, }); } @@ -129,23 +175,34 @@ async function getAllCategory(_req: Request, res: Response): Promise { * * @return {Promise} - The response with category data or error message */ -async function getBySlugCategory(req: Request, res:Response): Promise { +async function getBySlugCategory( + req: Request, + res: Response, +): Promise { const categorySlug = req.params["categorySlug"]; - if (!categorySlug) { - logger.error("Category slug is missing"); - return res.status(400).json({ error: "Category slug is missing" }); - } - const category = await CategoryService.getBySlug(`${categorySlug}`); - if (!category || !category.id) { - logger.error("Category not found"); - return res.status(404).json({ error: "Category not found" }); - } - logger.info(`Category retrieved successfully! (${categorySlug})`); - return res.status(200).json({ - id: category.id, - display_name: category.display_name, - slug_name: category.slug_name - }); + if (!categorySlug) { + logger.error("Category slug is missing"); + return res.status(400).json({ + error: "Category slug is missing", + }); + } + const category = await CategoryService.getBySlug( + `${categorySlug}`, + ); + if (!category || !category.id) { + logger.error("Category not found"); + return res.status(404).json({ + error: "Category not found", + }); + } + 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 = { @@ -153,7 +210,7 @@ const CategoryController = { update: updateCategory, delete: deleteCategory, getAll: getAllCategory, - getBySlug: getBySlugCategory -} + getBySlug: getBySlugCategory, +}; -export default CategoryController; \ No newline at end of file +export default CategoryController; diff --git a/src/controllers/model.controller.ts b/src/controllers/model.controller.ts index 55cb6df..1d6e7ba 100644 --- a/src/controllers/model.controller.ts +++ b/src/controllers/model.controller.ts @@ -1,20 +1,27 @@ -import type {Request, Response} from "express"; -import {Logger} from "tslog"; -import CategoryService from "@services/category.service"; import type IDbModel from "@interfaces/database/IDbModel"; +import CategoryService from "@services/category.service"; import ModelService from "@services/model.service"; +import type { Request, Response } from "express"; +import { Logger } from "tslog"; //import {validationResult} from "express-validator"; +const logger = new Logger({ + name: "ModelController", +}); -const logger = new Logger({ name: "ModelController" }); - - -async function createModel(req: Request, res: Response): Promise { - const body: IDbModel = req.body - const doesExist = await CategoryService.getBySlug(`${body.slug_name}`) +async function createModel( + req: Request, + res: Response, +): Promise { + const body: IDbModel = req.body; + const doesExist = await CategoryService.getBySlug( + `${body.slug_name}`, + ); if (doesExist) { logger.error("Category already exists"); - return res.status(400).json({ error: "Category already exists" }); + return res.status(400).json({ + error: "Category already exists", + }); } const createResult = await ModelService.create({ display_name: `${body.display_name}`, @@ -23,82 +30,123 @@ async function createModel(req: Request, res: Response): Promise { base_price: Number.parseFloat(`${body.base_price}`), brand_id: `${body.brand_id}`, image_blob: `${body.image_blob}`, - is_trending: !!body.is_trending - }) + is_trending: !!body.is_trending, + }); if (!createResult) { logger.error("Failed to create category"); - return res.status(500).json({ error: "Failed to create category" }); + return res.status(500).json({ + error: "Failed to create category", + }); } - logger.info(`Category created successfully ! (${body.slug_name})`) - return res.status(201).json({ message: "Category created successfully" }); + logger.info( + `Category created successfully ! (${body.slug_name})`, + ); + return res.status(201).json({ + message: "Category created successfully", + }); } -async function updateModel(req: Request, res: Response): Promise { +async function updateModel( + req: Request, + res: Response, +): Promise { const body: IDbModel = req.body; - const doesExist = await ModelService.getBySlug(`${body.slug_name}`); - if (!doesExist) { + const doesExist = await ModelService.getBySlug( + `${body.slug_name}`, + ); + if (!doesExist) { logger.error("Model does not exist"); - return res.status(404).json({ error: "Model does not exist" }); + return res.status(404).json({ + error: "Model does not exist", + }); } - const updateResult = await ModelService.update({ - id: `${body.id}`, - display_name: `${body.display_name}`, - slug_name: `${body.slug_name}`, - category_id: `${body.category_id}`, - base_price: Number.parseFloat(`${body.base_price}`), - brand_id: `${body.brand_id}`, - image_blob: `${body.image_blob}`, - is_trending: !!body.is_trending - }); - if (!updateResult) { - logger.error("Failed to update model"); - return res.status(500).json({ error: "Failed to update model" }); - } - logger.info(`Model updated successfully! (${body.slug_name})`); - return res.status(200).json({ message: "Model updated successfully" }); + const updateResult = await ModelService.update({ + id: `${body.id}`, + display_name: `${body.display_name}`, + slug_name: `${body.slug_name}`, + category_id: `${body.category_id}`, + base_price: Number.parseFloat(`${body.base_price}`), + brand_id: `${body.brand_id}`, + image_blob: `${body.image_blob}`, + is_trending: !!body.is_trending, + }); + if (!updateResult) { + logger.error("Failed to update model"); + return res.status(500).json({ + error: "Failed to update model", + }); + } + logger.info( + `Model updated successfully! (${body.slug_name})`, + ); + return res.status(200).json({ + message: "Model updated successfully", + }); } async function getAllModel(res: Response): Promise { const models = await ModelService.getAll(); - if (!models) { - logger.error("Failed to get all models"); - return res.status(500).json({ error: "Failed to get all models" }); - } - return res.status(200).json({ + if (!models) { + logger.error("Failed to get all models"); + return res.status(500).json({ + error: "Failed to get all models", + }); + } + return res.status(200).json({ uat: Date.now(), models: models, - total: models.length + total: models.length, }); } -async function getModelBySlug(req: Request, res: Response): Promise { +async function getModelBySlug( + req: Request, + res: Response, +): Promise { const slug = req.params["modelSlug"]; if (!slug) { logger.error("Invalid slug"); - return res.status(400).json({ error: "Invalid slug" }); + return res.status(400).json({ + error: "Invalid slug", + }); } - const model = await ModelService.getBySlug(slug); - if (!model) { - logger.error("Model not found"); - return res.status(404).json({ error: "Model not found" }); - } - return res.status(200).json({ model }); + const model = await ModelService.getBySlug(slug); + if (!model) { + logger.error("Model not found"); + return res.status(404).json({ + error: "Model not found", + }); + } + return res.status(200).json({ + model, + }); } -async function deleteModel(req: Request, res: Response): Promise { +async function deleteModel( + req: Request, + res: Response, +): Promise { const modelSlug = req.params["modelSlug"]; - if (!modelSlug) { - logger.error("Invalid model slug"); - return res.status(400).json({ error: "Invalid model slug" }); - } + if (!modelSlug) { + logger.error("Invalid model slug"); + return res.status(400).json({ + error: "Invalid model slug", + }); + } //TODO Check if vehicle related to model - const deleteResult = await ModelService.delete(modelSlug); - if (!deleteResult) { - logger.error("Failed to delete model"); - return res.status(500).json({ error: "Failed to delete model" }); - } - logger.info(`Model deleted successfully! (SLUG: ${modelSlug})`); - return res.status(200).json({ message: "Model deleted successfully" }); + const deleteResult = await ModelService.delete(modelSlug); + if (!deleteResult) { + logger.error("Failed to delete model"); + return res.status(500).json({ + error: "Failed to delete model", + }); + } + 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 @@ -108,9 +156,9 @@ async function deleteModel(req: Request, res: Response): Promise { const ModelController = { create: createModel, update: updateModel, - getAll: getAllModel, - getBySlug: getModelBySlug, - delete: deleteModel, -} + getAll: getAllModel, + getBySlug: getModelBySlug, + delete: deleteModel, +}; -export default ModelController; \ No newline at end of file +export default ModelController; diff --git a/src/interfaces/IReqEditUserData.ts b/src/interfaces/IReqEditUserData.ts index 542da13..cdab8e9 100644 --- a/src/interfaces/IReqEditUserData.ts +++ b/src/interfaces/IReqEditUserData.ts @@ -3,4 +3,4 @@ export interface IReqEditUserData { lastName?: string; displayName?: string; password?: string; -} \ No newline at end of file +} diff --git a/src/interfaces/UserData.ts b/src/interfaces/UserData.ts index e23a55f..28ff021 100644 --- a/src/interfaces/UserData.ts +++ b/src/interfaces/UserData.ts @@ -12,7 +12,7 @@ interface DbUserData { isDisabled: boolean; resetPasswordToken?: string; - resetPasswordExpires?: Date; + resetPasswordExpires?: Date; dob: Date; gdpr: Date; @@ -20,4 +20,4 @@ interface DbUserData { uat: Date; } -export default DbUserData \ No newline at end of file +export default DbUserData; diff --git a/src/interfaces/database/IDbBrand.ts b/src/interfaces/database/IDbBrand.ts index bae7123..53c31c5 100644 --- a/src/interfaces/database/IDbBrand.ts +++ b/src/interfaces/database/IDbBrand.ts @@ -1,8 +1,8 @@ export interface IDbBrand { - id?: string; - slug_name: string; - display_name: string; - image_blob: BinaryType; + id?: string; + slug_name: string; + display_name: string; + image_blob: BinaryType; } -export default IDbBrand; \ No newline at end of file +export default IDbBrand; diff --git a/src/interfaces/database/IDbCategory.ts b/src/interfaces/database/IDbCategory.ts index 015b538..7acec3b 100644 --- a/src/interfaces/database/IDbCategory.ts +++ b/src/interfaces/database/IDbCategory.ts @@ -1,7 +1,7 @@ export interface IDbCategory { - id?: string; - slug_name: string; - display_name: string + id?: string; + slug_name: string; + display_name: string; } -export default IDbCategory; \ No newline at end of file +export default IDbCategory; diff --git a/src/interfaces/database/IDbModel.ts b/src/interfaces/database/IDbModel.ts index 581d619..b344c25 100644 --- a/src/interfaces/database/IDbModel.ts +++ b/src/interfaces/database/IDbModel.ts @@ -1,12 +1,12 @@ export interface IDbModel { - id?: string; - slug_name: string; - display_name: string; - brand_id: string; - category_id: string; - image_blob: BinaryType; - is_trending: boolean; - base_price: number; + id?: string; + slug_name: string; + display_name: string; + brand_id: string; + category_id: string; + image_blob: BinaryType; + is_trending: boolean; + base_price: number; } -export default IDbModel; \ No newline at end of file +export default IDbModel; diff --git a/src/interfaces/database/IDbRent.ts b/src/interfaces/database/IDbRent.ts index 5c60e0e..5ceb664 100644 --- a/src/interfaces/database/IDbRent.ts +++ b/src/interfaces/database/IDbRent.ts @@ -1,11 +1,11 @@ export interface IDbRent { - vehicle_id: string; - user_id: string; - active: boolean; - iat: Date; - eat: Date; - need_survey: boolean; - km_at_start: number + vehicle_id: string; + user_id: string; + active: boolean; + iat: Date; + eat: Date; + need_survey: boolean; + km_at_start: number; } -export default IDbRent; \ No newline at end of file +export default IDbRent; diff --git a/src/interfaces/database/IDbStatusResult.ts b/src/interfaces/database/IDbStatusResult.ts index c1af692..e51b1e6 100644 --- a/src/interfaces/database/IDbStatusResult.ts +++ b/src/interfaces/database/IDbStatusResult.ts @@ -6,4 +6,4 @@ export interface IDbStatusResult { serverStatus: number; warningStatus: number; changedRows: number; -} \ No newline at end of file +} diff --git a/src/interfaces/database/IDbUser.ts b/src/interfaces/database/IDbUser.ts index 2018d14..4186f38 100644 --- a/src/interfaces/database/IDbUser.ts +++ b/src/interfaces/database/IDbUser.ts @@ -1,12 +1,12 @@ export interface IDbUser { - id?: string; - username: string; - firstname: string; - lastname: string; - dob: Date; - email: string; - is_mail_verified: boolean; - is_admin: boolean; - gdpr: Date; - hash: string -} \ No newline at end of file + id?: string; + username: string; + firstname: string; + lastname: string; + dob: Date; + email: string; + is_mail_verified: boolean; + is_admin: boolean; + gdpr: Date; + hash: string; +} diff --git a/src/interfaces/database/IDbVehicle.ts b/src/interfaces/database/IDbVehicle.ts index bcab883..313b7ec 100644 --- a/src/interfaces/database/IDbVehicle.ts +++ b/src/interfaces/database/IDbVehicle.ts @@ -4,4 +4,4 @@ export interface IDbVehicle { model_id: string; odometer: number; health_state: number; -} \ No newline at end of file +} diff --git a/src/interfaces/index.ts b/src/interfaces/index.ts index cd28ab2..66f3692 100644 --- a/src/interfaces/index.ts +++ b/src/interfaces/index.ts @@ -1 +1 @@ -export * from './UserData' \ No newline at end of file +export * from "./UserData"; diff --git a/src/interfaces/requests/IReqLogin.ts b/src/interfaces/requests/IReqLogin.ts index 4649dfa..4d42362 100644 --- a/src/interfaces/requests/IReqLogin.ts +++ b/src/interfaces/requests/IReqLogin.ts @@ -1,4 +1,4 @@ export interface IReqLogin { username: string; password: string; -} \ No newline at end of file +} diff --git a/src/interfaces/requests/IReqRegister.ts b/src/interfaces/requests/IReqRegister.ts index 575f2d5..3ee474b 100644 --- a/src/interfaces/requests/IReqRegister.ts +++ b/src/interfaces/requests/IReqRegister.ts @@ -5,4 +5,4 @@ export interface IReqRegister { lastName: string; password: string; gdpr?: boolean; -} \ No newline at end of file +} diff --git a/src/routes/auth/authRouter.ts b/src/routes/auth/authRouter.ts index e870cea..65d6480 100644 --- a/src/routes/auth/authRouter.ts +++ b/src/routes/auth/authRouter.ts @@ -1,38 +1,39 @@ -import express, {type Router} from "express"; -import UserGuard from "@validators/UserGuard"; -import AdminGuard from "@validators/AdminGuard"; import AuthController from "@controllers/auth.controller"; - +import AdminGuard from "@validators/AdminGuard"; +import UserGuard from "@validators/UserGuard"; +import express, { type Router } from "express"; const AuthRouter: Router = express.Router(); -AuthRouter.route('/login').post(AuthController.login) -AuthRouter.route('/register').post(AuthController.register) +AuthRouter.route("/login").post(AuthController.login); +AuthRouter.route("/register").post(AuthController.register); // PATCH //TODO - To test -AuthRouter.route('/me') - .patch(UserGuard, AuthController.editUser) +AuthRouter.route("/me").patch( + UserGuard, + AuthController.editUser, +); // GET -AuthRouter.route('/me') - .get(UserGuard, AuthController.getSelf) +AuthRouter.route("/me").get(UserGuard, AuthController.getSelf); // DELETE -AuthRouter.route('/me') - .delete(UserGuard, AuthController.deleteSelf) - +AuthRouter.route("/me").delete( + UserGuard, + AuthController.deleteSelf, +); // GET -AuthRouter.route('/all') - .get(AdminGuard, AuthController.getAllUsers) - +AuthRouter.route("/all").get( + AdminGuard, + AuthController.getAllUsers, +); // GET -AuthRouter.route('/user/:targetId') +AuthRouter.route("/user/:targetId") .get(AdminGuard, AuthController.getUser) .patch(AdminGuard, AuthController.editUser) - .delete(AdminGuard, AuthController.deleteUser) + .delete(AdminGuard, AuthController.deleteUser); - -export default AuthRouter \ No newline at end of file +export default AuthRouter; diff --git a/src/routes/catalog/catalogRouter.ts b/src/routes/catalog/catalogRouter.ts index 146946d..accbd83 100644 --- a/src/routes/catalog/catalogRouter.ts +++ b/src/routes/catalog/catalogRouter.ts @@ -1,44 +1,52 @@ -import express, {type Router} from "express"; -import AdminGuard from "@validators/AdminGuard"; -import UserGuard from "@validators/UserGuard"; +import BrandController from "@controllers/brand.controller"; import CategoryController from "@controllers/category.controller"; import ModelController from "@controllers/model.controller"; -import BrandController from "@controllers/brand.controller"; - +import AdminGuard from "@validators/AdminGuard"; +import UserGuard from "@validators/UserGuard"; +import express, { type Router } from "express"; const CatalogRouter: Router = express.Router(); //-- MODELS >> -CatalogRouter.route('/model/new').get(AdminGuard, ModelController.create) +CatalogRouter.route("/model/new").get( + 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) .patch(AdminGuard, ModelController.update) - .delete(AdminGuard, ModelController.delete) - + .delete(AdminGuard, ModelController.delete); //-- CATEGORY >> -CatalogRouter.route('/category/new').get(AdminGuard, CategoryController.create) +CatalogRouter.route("/category/new").get( + AdminGuard, + CategoryController.create, +); -CatalogRouter.route('/category/all').get(CategoryController.getAll) +CatalogRouter.route("/category/all").get( + CategoryController.getAll, +); -CatalogRouter.route('/category/:categorySlug') +CatalogRouter.route("/category/:categorySlug") .get(UserGuard, CategoryController.getBySlug) .patch(AdminGuard, CategoryController.update) - .delete(AdminGuard, CategoryController.delete) - + .delete(AdminGuard, CategoryController.delete); //-- BRAND >> -CatalogRouter.route('/brand/new').post(AdminGuard, BrandController.create) -CatalogRouter.route('/brand/all').get(BrandController.getAll) -CatalogRouter.route('/brand/:brandSlug') +CatalogRouter.route("/brand/new").post( + AdminGuard, + BrandController.create, +); +CatalogRouter.route("/brand/all").get(BrandController.getAll); +CatalogRouter.route("/brand/:brandSlug") .get(UserGuard, BrandController.getBySlug) .patch(AdminGuard, BrandController.update) - .delete(AdminGuard, BrandController.delete) + .delete(AdminGuard, BrandController.delete); -export default CatalogRouter; \ No newline at end of file +export default CatalogRouter; diff --git a/src/routes/index.ts b/src/routes/index.ts index 5339fa4..43d347e 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -1,3 +1,3 @@ -export * from 'src/routes/auth/authRouter' -export * from 'src/routes/catalog/catalogRouter' -export * from 'src/routes/rent/rentRouter' \ No newline at end of file +export * from "src/routes/auth/authRouter"; +export * from "src/routes/catalog/catalogRouter"; +export * from "src/routes/rent/rentRouter"; diff --git a/src/routes/rent/rentRouter.ts b/src/routes/rent/rentRouter.ts index d7ecb01..f3bd302 100644 --- a/src/routes/rent/rentRouter.ts +++ b/src/routes/rent/rentRouter.ts @@ -1,34 +1,27 @@ -import express, {type Router} from "express"; import AdminGuard from "@validators/AdminGuard"; import UserGuard from "@validators/UserGuard"; - +import express, { type Router } from "express"; const RentRouter: Router = express.Router(); // Get rent affected to the user -RentRouter.route('/affected') - .get(UserGuard) +RentRouter.route("/affected").get(UserGuard); // 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) -RentRouter.route('/veh/new') - .post(AdminGuard) +RentRouter.route("/veh/new").post(AdminGuard); // Get all vehicles -RentRouter.route('/veh/all') - .get() +RentRouter.route("/veh/all").get(); // 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) .patch(AdminGuard) - .delete(AdminGuard) + .delete(AdminGuard); -export default RentRouter; \ No newline at end of file +export default RentRouter; diff --git a/src/services/brand.service.ts b/src/services/brand.service.ts index 95f6802..49c9ee9 100644 --- a/src/services/brand.service.ts +++ b/src/services/brand.service.ts @@ -1,10 +1,12 @@ import type IDbBrand from "@interfaces/database/IDbBrand"; import MysqlService from "@services/mysql.service"; -import {Logger} from "tslog"; -import { v4 as uuidv4 } from 'uuid'; +import { Logger } from "tslog"; +import { v4 as uuidv4 } from "uuid"; -const DbHandler = new MysqlService.Handler('BrandService') -const logger = new Logger({name: 'BrandService'}) +const DbHandler = new MysqlService.Handler("BrandService"); +const logger = new Logger({ + name: "BrandService", +}); //SEC todo Blob validation /** @@ -14,24 +16,39 @@ const logger = new Logger({name: 'BrandService'}) * @return {Promise} A promise that resolves to the result of the operation. */ async function createBrand(data: IDbBrand): Promise { - const doesExist = await MysqlService.Brand.getBySlug(DbHandler, data.slug_name); + const doesExist = await MysqlService.Brand.getBySlug( + DbHandler, + data.slug_name, + ); if (doesExist) { - logger.error(`Brand already exists (${data.slug_name})`) - return {error: 'exist'} + logger.error(`Brand already exists (${data.slug_name})`); + return { + error: "exist", + }; } const brandId = uuidv4(); - const createdBrand = await MysqlService.Brand.insert(DbHandler, { - id: brandId, - slug_name: `${data.slug_name}`, - 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 }; - } - logger.error(`Failed to create brand (${data.slug_name})`); - return { error: 'failed' }; + const createdBrand = await MysqlService.Brand.insert( + DbHandler, + { + id: brandId, + slug_name: `${data.slug_name}`, + 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, + }; + } + logger.error(`Failed to create brand (${data.slug_name})`); + return { + error: "failed", + }; } //SEC todo Blob validation @@ -44,38 +61,48 @@ async function createBrand(data: IDbBrand): Promise { async function updateBrand(data: IDbBrand): Promise { if (!data.id) { logger.error("Brand ID is missing"); - return false; + return false; } - const doesExist = await MysqlService.Brand.getBySlug(DbHandler, data.slug_name); - if (doesExist && doesExist.id !== data.id) { - logger.error(`Brand already exists (${data.slug_name})`); - return false; - } - const updatedBrand = await MysqlService.Brand.update(DbHandler, { - id: data.id, - slug_name: `${data.slug_name}`, - display_name: `${data.display_name}`, - image_blob: data.image_blob - }); - if (updatedBrand) { - logger.info(`Brand updated successfully (${data.slug_name})`); - return true; - } - logger.error(`Failed to update brand (${data.slug_name})`); - return false; + const doesExist = await MysqlService.Brand.getBySlug( + DbHandler, + data.slug_name, + ); + if (doesExist && doesExist.id !== data.id) { + logger.error(`Brand already exists (${data.slug_name})`); + return false; + } + const updatedBrand = await MysqlService.Brand.update( + DbHandler, + { + id: data.id, + slug_name: `${data.slug_name}`, + display_name: `${data.display_name}`, + image_blob: data.image_blob, + }, + ); + 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. * @returns {Promise|false>} - An array of IDbBrand objects if successful, false otherwise. */ -async function getAllBrand(): Promise| false> { +async function getAllBrand(): Promise | false> { const brands = await MysqlService.Brand.getAll(DbHandler); if (!brands) { logger.error("Failed to retrieve brands"); return false; - } - logger.info(`Retrieved all brands successfully (${brands.length})`); + } + logger.info( + `Retrieved all brands successfully (${brands.length})`, + ); return brands; } @@ -85,18 +112,25 @@ async function getAllBrand(): Promise| false> { * @param {string} brandSlug - The slug of the brand. * @returns {Promise} - A promise that resolves to the retrieved brand object or false if the brand is not found. */ -async function getBySlugBrand(brandSlug: string): Promise { +async function getBySlugBrand( + brandSlug: string, +): Promise { if (!brandSlug) { - logger.error("Brand slug is missing"); - return false; - } - const brand = await MysqlService.Brand.getBySlug(DbHandler, brandSlug); - if (!brand) { - logger.error(`Brand not found (${brandSlug})`); - return false; - } - logger.info(`Retrieved brand by slug successfully (${brandSlug})`); - return brand; + logger.error("Brand slug is missing"); + return false; + } + const brand = await MysqlService.Brand.getBySlug( + DbHandler, + brandSlug, + ); + if (!brand) { + logger.error(`Brand not found (${brandSlug})`); + return false; + } + logger.info( + `Retrieved brand by slug successfully (${brandSlug})`, + ); + return brand; } /** @@ -106,7 +140,9 @@ async function getBySlugBrand(brandSlug: string): Promise { * * @returns {Promise} 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(brandId: string): Promise { +async function getByIdBrand( + brandId: string, +): Promise { if (!brandId) { logger.error("Brand ID is missing"); return false; @@ -115,12 +151,17 @@ async function getByIdBrand(brandId: string): Promise { logger.error("Invalid brand ID"); return false; } - const brand = await MysqlService.Brand.getById(DbHandler, brandId); + const brand = await MysqlService.Brand.getById( + DbHandler, + brandId, + ); if (!brand) { logger.error(`Brand not found (${brandId})`); return false; } - logger.info(`Retrieved brand by ID successfully (${brandId})`); + logger.info( + `Retrieved brand by ID successfully (${brandId})`, + ); return brand; } @@ -144,11 +185,14 @@ async function deleteBrand(brandId: string): Promise { return false; } //TODO verify if as models linked - const deletedBrand = await MysqlService.Brand.delete(DbHandler, brandId); - if (!deletedBrand) { + const deletedBrand = await MysqlService.Brand.delete( + DbHandler, + brandId, + ); + if (!deletedBrand) { logger.error(`Failed to delete brand (${brandId})`); return false; - } + } logger.info(`Brand deleted successfully (${brandId})`); return true; } @@ -160,6 +204,6 @@ const BrandService = { getBySlug: getBySlugBrand, getById: getByIdBrand, delete: deleteBrand, -} +}; -export default BrandService; \ No newline at end of file +export default BrandService; diff --git a/src/services/category.service.ts b/src/services/category.service.ts index 9bc9f1c..48b4af6 100644 --- a/src/services/category.service.ts +++ b/src/services/category.service.ts @@ -1,12 +1,12 @@ import type { IDbCategory } from "@interfaces/database/IDbCategory"; import MysqlService from "@services/mysql.service"; -import {Logger} from "tslog"; -import { v4 as uuidv4 } from 'uuid'; - -const DbHandler = new MysqlService.Handler('CategoryService') -const logger = new Logger({name: 'CategoryService'}) - +import { Logger } from "tslog"; +import { v4 as uuidv4 } from "uuid"; +const DbHandler = new MysqlService.Handler("CategoryService"); +const logger = new Logger({ + name: "CategoryService", +}); /** * Creates a new category with the given data. @@ -15,19 +15,23 @@ const logger = new Logger({name: 'CategoryService'}) * @returns {Promise} A promise that resolves with the created category. * If an error occurs, the promise will reject with the error. */ -async function createCategory(data: IDbCategory): Promise { - logger.info(`Creating a new category... (${data.display_name})`) +async function createCategory( + data: IDbCategory, +): Promise { + logger.info( + `Creating a new category... (${data.display_name})`, + ); try { await MysqlService.Category.insert(DbHandler, { id: uuidv4(), display_name: data.display_name, - slug_name: data.slug_name - }) + slug_name: data.slug_name, + }); //TODO Return the new id return true; } catch (error) { logger.error(`Error creating category: ${error}`); - return false; + return false; } } @@ -43,19 +47,19 @@ async function createCategory(data: IDbCategory): Promise { */ async function updateCategory(data: IDbCategory) { if (!data.id) { - logger.error("Category id is missing.") - return false + logger.error("Category id is missing."); + return false; } try { await MysqlService.Category.update(DbHandler, { id: data.id, slug_name: data.slug_name, - display_name: data.display_name + display_name: data.display_name, }); //TODO Return id return true; } catch (err) { - logger.error(err) + logger.error(err); return false; } } @@ -65,31 +69,37 @@ async function updateCategory(data: IDbCategory) { * * @returns {Promise> | null} Promise that resolves to an array of IDbCategory objects or null if an error occurred. */ -async function getAll(): Promise> | null> { +async function getAll(): Promise +> | null> { try { - logger.info("Getting all categories..."); - return await MysqlService.Category.getAll(DbHandler); - } catch (error) { - logger.error(`Error getting all categories: ${error}`); - return null; - } + logger.info("Getting all categories..."); + return await MysqlService.Category.getAll(DbHandler); + } catch (error) { + logger.error(`Error getting all categories: ${error}`); + return null; + } } - /** * Gets a category by its slug * * @param {string} slug - The slug of the category * @return {Promise} - A promise that resolves to the category object or null if not found */ -async function getBySlug(slug: string): Promise { +async function getBySlug( + slug: string, +): Promise { try { - logger.info(`Getting category by slug... (${slug})`); - return await MysqlService.Category.getBySlug(DbHandler, slug); - } catch (error) { - logger.error(`Error getting category by slug: ${error}`); - return null; - } + logger.info(`Getting category by slug... (${slug})`); + return await MysqlService.Category.getBySlug( + DbHandler, + slug, + ); + } catch (error) { + logger.error(`Error getting category by slug: ${error}`); + return null; + } } /** @@ -98,35 +108,36 @@ async function getBySlug(slug: string): Promise { * @param {string} id - The id of the category to retrieve. * @returns {Promise} - A Promise that resolves with the retrieved category object or null if not found. */ -async function getById(id: string):Promise { +async function getById( + id: string, +): Promise { try { - logger.info(`Getting category by id... (${id})`); - return await MysqlService.Category.getById(DbHandler, id); - } catch (error) { - logger.error(`Error getting category by id: ${error}`); - return null; - } + logger.info(`Getting category by id... (${id})`); + return await MysqlService.Category.getById(DbHandler, id); + } catch (error) { + logger.error(`Error getting category by id: ${error}`); + return null; + } } //FEAT Get all models in category (slug) - /** * Deletes a category with the given ID from the database. * * @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. */ -async function deleteCategory(id:string): Promise { +async function deleteCategory(id: string): Promise { //TODO Verify if exist //TODO Verify if element linked to category try { - logger.info(`Deleting category... (${id})`); - return await MysqlService.Category.delete(DbHandler, id); - } catch (error) { - logger.error(`Error deleting category: ${error}`); - return null; - } + logger.info(`Deleting category... (${id})`); + return await MysqlService.Category.delete(DbHandler, id); + } catch (error) { + logger.error(`Error deleting category: ${error}`); + return null; + } } const CategoryService = { @@ -135,7 +146,7 @@ const CategoryService = { update: updateCategory, getAll, getBySlug, - getById -} + getById, +}; -export default CategoryService; \ No newline at end of file +export default CategoryService; diff --git a/src/services/credential.service.ts b/src/services/credential.service.ts index e0266c6..cf678a9 100644 --- a/src/services/credential.service.ts +++ b/src/services/credential.service.ts @@ -2,23 +2,26 @@ import Argon2id from "@node-rs/argon2"; //ToTest export async function getHashFromPassword(password: string) { - return await Argon2id.hash(password,{ + return await Argon2id.hash(password, { secret: Buffer.from(`${process.env["HASH_SECRET"]}`), - algorithm: 2 - }) + algorithm: 2, + }); } //ToTest -export async function comparePassword(password: string, hash: string) { +export async function comparePassword( + password: string, + hash: string, +) { return await Argon2id.verify(hash, password, { secret: Buffer.from(`${process.env["HASH_SECRET"]}`), - algorithm: 2 + algorithm: 2, }); } const CredentialService = { compare: comparePassword, hash: getHashFromPassword, -} +}; -export default CredentialService; \ No newline at end of file +export default CredentialService; diff --git a/src/services/index.ts b/src/services/index.ts index c52d12e..bee4647 100644 --- a/src/services/index.ts +++ b/src/services/index.ts @@ -1,2 +1,2 @@ -export * from './jwt.service'; -export * as MySqlService from './mysql.service' \ No newline at end of file +export * from "./jwt.service"; +export * as MySqlService from "./mysql.service"; diff --git a/src/services/jwt.service.ts b/src/services/jwt.service.ts index 1513125..91a0f0d 100644 --- a/src/services/jwt.service.ts +++ b/src/services/jwt.service.ts @@ -1,7 +1,14 @@ -import {type JWTHeaderParameters, type JWTPayload, jwtVerify, SignJWT} from "jose"; -import {Logger} from "tslog"; +import { + type JWTHeaderParameters, + type JWTPayload, + SignJWT, + jwtVerify, +} from "jose"; +import { Logger } from "tslog"; -const logger = new Logger({ name: "JwtService" }); +const logger = new Logger({ + name: "JwtService", +}); /** * Verify a JWT token. @@ -11,22 +18,22 @@ const logger = new Logger({ name: "JwtService" }); * @returns {Promise} * - The payload of the verified JWT token or null if verification fails. */ -async function JwtVerifyService(jwt: string | Uint8Array): Promise { - try { - const result = await jwtVerify( - jwt, - new TextEncoder() - .encode(`${process.env["JWT_SECRET"]}`), - { - }) - return result.payload; - } catch (error) { - logger.error(error) - return null - } +async function JwtVerifyService( + jwt: string | Uint8Array, +): Promise { + try { + const result = await jwtVerify( + jwt, + new TextEncoder().encode(`${process.env["JWT_SECRET"]}`), + {}, + ); + return result.payload; + } catch (error) { + logger.error(error); + return null; + } } - /** * Asynchronously signs a JWT token using the provided payload, header, expiration time, and audience. * @@ -42,19 +49,26 @@ async function JwtVerifyService(jwt: string | Uint8Array): Promise} * - A promise that resolves with the signed JWT token. */ -async function JwtSignService(payload: JWTPayload, pHeader: JWTHeaderParameters, expTime: string | number | Date, audience: string | string[]): Promise { - return await new SignJWT(payload) - .setProtectedHeader(pHeader) - .setIssuedAt(new Date()) - .setIssuer(`${process.env["JWT_SECRET"]} - Mathis HERRIOT`) - .setAudience(audience) - .setExpirationTime(expTime) - .sign(new TextEncoder().encode(`${process.env["JWT_SECRET"]}`)) +async function JwtSignService( + payload: JWTPayload, + pHeader: JWTHeaderParameters, + expTime: string | number | Date, + audience: string | string[], +): Promise { + return await new SignJWT(payload) + .setProtectedHeader(pHeader) + .setIssuedAt(new Date()) + .setIssuer(`${process.env["JWT_SECRET"]} - Mathis HERRIOT`) + .setAudience(audience) + .setExpirationTime(expTime) + .sign( + new TextEncoder().encode(`${process.env["JWT_SECRET"]}`), + ); } const JwtService = { - verify: JwtVerifyService, - sign: JwtSignService -} + verify: JwtVerifyService, + sign: JwtSignService, +}; -export default JwtService \ No newline at end of file +export default JwtService; diff --git a/src/services/model.service.ts b/src/services/model.service.ts index ccae97d..e643b9d 100644 --- a/src/services/model.service.ts +++ b/src/services/model.service.ts @@ -1,10 +1,12 @@ import type IDbModel from "@interfaces/database/IDbModel"; import MysqlService from "@services/mysql.service"; -import {Logger} from "tslog"; -import { v4 as uuidv4 } from 'uuid'; +import { Logger } from "tslog"; +import { v4 as uuidv4 } from "uuid"; -const DbHandler = new MysqlService.Handler('ModelService') -const logger = new Logger({name: 'ModelService'}) +const DbHandler = new MysqlService.Handler("ModelService"); +const logger = new Logger({ + name: "ModelService", +}); //SEC TODO validate blob /** @@ -15,7 +17,7 @@ const logger = new Logger({name: 'ModelService'}) * @return {Promise} - Indicates whether the model was created successfully. */ async function createModel(data: IDbModel): Promise { - logger.info(`Creating a new model... (${data.display_name})`) + logger.info(`Creating a new model... (${data.display_name})`); //TODO Validate IDbModel data try { await MysqlService.Model.insert(DbHandler, { @@ -26,10 +28,10 @@ async function createModel(data: IDbModel): Promise { brand_id: data.brand_id, category_id: data.category_id, base_price: data.base_price, - is_trending: data.is_trending - }) + is_trending: data.is_trending, + }); //TODO Return the new id - logger.info('Success !') + logger.info("Success !"); return true; } catch (error) { logger.error(`Error creating category: ${error}`); @@ -70,17 +72,22 @@ async function updateModel(data: IDbModel): Promise { * @param {string} modelSlug - The slug of the model to be deleted. * @return {Promise} - A promise that resolves to true if the deletion is successful, else false. */ -async function deleteModel(modelSlug: string): Promise { +async function deleteModel( + modelSlug: string, +): Promise { if (!modelSlug) { logger.error("Model slug is missing"); - return false + return false; } logger.info(`Deleting model with ID: ${modelSlug}`); - const doesExist = await MysqlService.Model.getBySlug(DbHandler, modelSlug); + const doesExist = await MysqlService.Model.getBySlug( + DbHandler, + modelSlug, + ); if (!doesExist || !doesExist.id) { - logger.warn(`Model with slug ${modelSlug} not found`); - return false; - } + logger.warn(`Model with slug ${modelSlug} not found`); + return false; + } try { await MysqlService.Model.delete(DbHandler, doesExist.id); logger.info("Deletion Successful !"); @@ -91,17 +98,21 @@ async function deleteModel(modelSlug: string): Promise { } } - /** * Fetches a model by slug from the database. * * @param {string} modelSlug - The slug of the model to be fetched. * @return {Promise} - A promise that resolves to the model if found, else null. */ -async function getBySlugModel(modelSlug: string): Promise { +async function getBySlugModel( + modelSlug: string, +): Promise { logger.info(`Fetching model with slug: ${modelSlug}`); try { - const model = await MysqlService.Model.getBySlug(DbHandler, modelSlug); + const model = await MysqlService.Model.getBySlug( + DbHandler, + modelSlug, + ); if (!model) { logger.warn(`Model with slug ${modelSlug} not found`); return null; @@ -113,7 +124,6 @@ async function getBySlugModel(modelSlug: string): Promise { } } - /** * Fetches all models from the database. * @@ -127,7 +137,7 @@ async function getAllModels(): Promise { logger.warn("No models found on the database"); return null; } - logger.info(`Found ${models.length} model(s)`) + logger.info(`Found ${models.length} model(s)`); return models; } catch (error) { logger.error(`Error fetching all models: ${error}`); @@ -135,8 +145,6 @@ async function getAllModels(): Promise { } } - - /** * ModelService is responsible for managing models. * @namespace @@ -149,6 +157,6 @@ const ModelService = { getAll: getAllModels, //getByCategory: getByCategoryModel, //getByBrand: getModelsByBrand, -} +}; export default ModelService; diff --git a/src/services/mysql.service.ts b/src/services/mysql.service.ts index 052e897..85a5e1f 100644 --- a/src/services/mysql.service.ts +++ b/src/services/mysql.service.ts @@ -1,68 +1,83 @@ -import type {IDbCategory} from "@interfaces/database/IDbCategory"; -import type {IDbModel} from "@interfaces/database/IDbModel"; -import type {IDbUser} from "@interfaces/database/IDbUser"; -import type {IDbBrand} from "@interfaces/database/IDbBrand"; -import type {IDbStatusResult} from "@interfaces/database/IDbStatusResult"; -import type {IDbVehicle} from "@interfaces/database/IDbVehicle"; -import mysql, {type Connection, type ConnectionOptions} from 'mysql2'; -import {Logger} from "tslog"; import process from "node:process"; - +import type { IDbBrand } from "@interfaces/database/IDbBrand"; +import type { IDbCategory } from "@interfaces/database/IDbCategory"; +import type { IDbModel } from "@interfaces/database/IDbModel"; +import type { IDbStatusResult } from "@interfaces/database/IDbStatusResult"; +import type { IDbUser } from "@interfaces/database/IDbUser"; +import type { IDbVehicle } from "@interfaces/database/IDbVehicle"; +import mysql, { + type Connection, + type ConnectionOptions, +} from "mysql2"; +import { Logger } from "tslog"; const access: ConnectionOptions = { host: `${process.env["MYSQL_HOST"]}`, port: Number.parseInt(`${process.env["MYSQL_PORT"]}`), user: `${process.env["MYSQL_USER"]}`, database: `${process.env["MYSQL_DATABASE"]}`, - password: `${process.env["MYSQL_PASS"]}` + password: `${process.env["MYSQL_PASS"]}`, }; - class MysqlHandler { private readonly handlerName: string; - private Logger: Logger + private Logger: Logger; private Connection: Connection; constructor(handlerName?: string) { - this.handlerName = handlerName || 'Unknown'; - this.Logger = new Logger({ name: `DB>> ${this.handlerName}` }); + this.handlerName = handlerName || "Unknown"; + this.Logger = new Logger({ + name: `DB>> ${this.handlerName}`, + }); this.Connection = mysql.createConnection(access); this.Connection.connect((err) => { - if (err) { - this.Logger.error(`Error connecting to MySQL: ${err}`); + if (err) { + this.Logger.error(`Error connecting to MySQL: ${err}`); process.exit(1); - } - this.Logger.info(`Connected to MySQL database (${access.database})`); - }); + } + this.Logger.info( + `Connected to MySQL database (${access.database})`, + ); + }); } closeConnection() { this.Connection.end(); - }; + } query(queryString: string) { return new Promise((resolve, reject) => { - this.Connection.query(queryString, (err, results) => { - if (err) { - this.Logger.error(`Error executing query: ${err}`); - reject(err); - } else { - resolve(results); - } - }); - }); + this.Connection.query(queryString, (err, results) => { + if (err) { + this.Logger.error(`Error executing query: ${err}`); + reject(err); + } else { + resolve(results); + } + }); + }); } - execute(queryString: string, values: Array): Promise { + execute( + queryString: string, + values: Array, + ): Promise { return new Promise((resolve, reject) => { - this.Connection.execute(queryString, values, (err: mysql.QueryError | null, results: mysql.QueryResult) => { - if (err) { - this.Logger.error(`Error executing query: ${err}`); - reject(err); - } else { - resolve(results); - } - }); - }); + this.Connection.execute( + queryString, + values, + ( + err: mysql.QueryError | null, + results: mysql.QueryResult, + ) => { + if (err) { + this.Logger.error(`Error executing query: ${err}`); + reject(err); + } else { + resolve(results); + } + }, + ); + }); } /** @@ -76,21 +91,20 @@ class MysqlHandler { */ unprepare(queryString: string): Promise { return new Promise((resolve, reject) => { - try { + try { resolve(this.Connection.unprepare(queryString)); } catch (err) { - reject(err) + reject(err); } - }); + }); } } const MySqlService = { - Handler : MysqlHandler, + Handler: MysqlHandler, //ToTest all User: { - /** * Inserts a new user into the database. * @@ -100,12 +114,16 @@ const MySqlService = { * @throws {Error} If an error occurs during the execution. * @throws {string} If the `id` field is undefined or invalid. */ - insert(handler: MysqlHandler, data: IDbUser): Promise { + insert( + handler: MysqlHandler, + data: IDbUser, + ): Promise { return new Promise((resolve, reject) => { - if (!data.id) return reject('Id is undefined'); - if (data.id.length !== 36) return reject('Id invalid'); + if (!data.id) return reject("Id is undefined"); + if (data.id.length !== 36) return reject("Id invalid"); - const _sql = "INSERT INTO `users`(`id`,`username`, `firstname`, `lastname`, `dob`, `email`, `is_mail_verified`, `is_admin`, `gdpr`, `hash`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)" + const _sql = + "INSERT INTO `users`(`id`,`username`, `firstname`, `lastname`, `dob`, `email`, `is_mail_verified`, `is_admin`, `gdpr`, `hash`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; const _values = [ data.id, data.username, @@ -116,41 +134,43 @@ const MySqlService = { data.is_mail_verified, data.is_admin, data.gdpr, - data.hash - ] + data.hash, + ]; try { - resolve(handler.execute(_sql, _values) as unknown as IDbStatusResult) + handler.execute(_sql, _values).then((result) => { + return resolve( + result as unknown as IDbStatusResult, + ); + }); } catch (err: unknown) { reject(err as Error); } - }) + }); }, - - /** - * Updates a user in the database. - * - * @param {MysqlHandler} handler - The MySQL database handler. - * @param {IDbUser} data - The data of the user to update. - * @returns {Promise} - A promise that resolves with the status result of the update. - * @throws {Error} - If an error occurs during the update. - */ - update(handler: MysqlHandler, data: IDbUser): Promise { + update( + handler: MysqlHandler, + data: IDbUser, + ): Promise { return new Promise((resolve, reject) => { - if (!data.id) return reject('Id is undefined'); - if (data.id.length !== 36) return reject('Id invalid'); + if (!data.id) return reject("Id is undefined"); + if (data.id.length !== 36) return reject("Id invalid"); - try { + try { const _template = ` - ${data.username ? "`username` = ?," : null} - ${data.firstname ? "`firstname` = ?," : null} - ${data.lastname ? "`lastname` = ?," : null} - ${data.dob ? "`dob` = ?," : null} - ${data.email ? "`email` = ?," : null} - ${data.is_mail_verified ? "`is_mail_verified` = ?," : null} - ${data.is_admin ? "`is_admin` = ?," : null} - ${data.gdpr ? "`gdpr` = ?," : null} - ${data.hash ? "`hash` = ?" : null}` + ${data.username ? "`username` = ?," : null} + ${data.firstname ? "`firstname` = ?," : null} + ${data.lastname ? "`lastname` = ?," : null} + ${data.dob ? "`dob` = ?," : null} + ${data.email ? "`email` = ?," : null} + ${ + data.is_mail_verified + ? "`is_mail_verified` = ?," + : null + } + ${data.is_admin ? "`is_admin` = ?," : null} + ${data.gdpr ? "`gdpr` = ?," : null} + ${data.hash ? "`hash` = ?" : null}`; const _values = [ data.username, data.firstname, @@ -161,39 +181,38 @@ const MySqlService = { data.is_admin, data.gdpr, data.hash, - data.id - ] + data.id, + ]; const _sql = `UPDATE "users" SET ${_template} WHERE 'id' = ?`; - return resolve(handler.execute(_sql, _values) as unknown as IDbStatusResult); - - } catch (err: unknown) { - reject(err as Error); - } - }); + handler.execute(_sql, _values).then((result) => { + return resolve( + result as unknown as IDbStatusResult, + ); + }); + } catch (err: unknown) { + reject(err as Error); + } + }); }, - /** - * Retrieves a user from the database based on their ID. - * - * @param {MysqlHandler} handler - The MySQL handler object used to execute the query. - * @param {string} userId - The ID of the user to retrieve from the database. - * - * @return {Promise} - A promise that resolves with the retrieved user object (of type IDbUser). - * - Rejects with an error if the ID is invalid or if an error occurs during the database operation. - */ - getById(handler: MysqlHandler, userId: string): Promise { - return new Promise((resolve, reject) => { - if (userId.length !== 36) return reject('Id invalid'); - const _sql = "SELECT * FROM `users` WHERE `id` = ?"; - const _values = [userId]; - try { - resolve(handler.execute(_sql, _values) as unknown as IDbUser); - } catch (err: unknown) { - reject(err as Error); - } - }); - }, + getById( + handler: MysqlHandler, + userId: string, + ): Promise { + return new Promise((resolve, reject) => { + if (userId.length !== 36) return reject("Id invalid"); + const _sql = "SELECT * FROM `users` WHERE `id` = ?"; + const _values = [userId]; + try { + handler.execute(_sql, _values).then((result) => { + return resolve(result as unknown as IDbUser); + }); + } catch (err: unknown) { + reject(err as Error); + } + }); + }, /** * Retrieves all users from the database. @@ -204,13 +223,15 @@ const MySqlService = { */ getAll(handler: MysqlHandler): Promise> { return new Promise((resolve, reject) => { - const _sql = "SELECT * FROM `users`"; - try { - resolve(handler.query(_sql) as unknown as Array); - } catch (err: unknown) { - reject(err as Error); - } - }); + const _sql = "SELECT * FROM `users`"; + try { + handler.query(_sql).then((result) => { + return resolve(result as unknown as Array); + }); + } catch (err: unknown) { + reject(err as Error); + } + }); }, /** @@ -221,18 +242,23 @@ const MySqlService = { * @return {Promise} - A promise that resolves to the retrieved user object. * @throws {Error} - If an error occurs while retrieving the user. */ - getByEmail(handler: MysqlHandler, email: string): Promise { - return new Promise((resolve, reject) => { - if (!email) return reject('email is undefined') - const _sql = "SELECT * FROM `users` WHERE `email` = ?"; - const _values = [email]; - try { - resolve(handler.execute(_sql, _values) as unknown as IDbUser); - } catch (err: unknown) { - reject(err as Error); - } - }); - }, + getByEmail( + handler: MysqlHandler, + email: string, + ): Promise { + return new Promise((resolve, reject) => { + if (!email) return reject("email is undefined"); + const _sql = "SELECT * FROM `users` WHERE `email` = ?"; + const _values = [email]; + try { + handler.execute(_sql, _values).then((result) => { + return resolve(result as unknown as IDbUser); + }); + } catch (err: unknown) { + reject(err as Error); + } + }); + }, /** * Retrieves the admin state for a given user ID. @@ -242,20 +268,27 @@ const MySqlService = { * @return {Promise} A Promise that resolves to a boolean value indicating whether the user is an admin or not. * @throws {Error} if an error occurs during the execution of the query. */ - getAdminStateForId(handler: MysqlHandler, userId: string) : Promise { + getAdminStateForId( + handler: MysqlHandler, + userId: string, + ): Promise { return new Promise((resolve, reject) => { - const _sql = "SELECT `is_admin` FROM `users` WHERE `id` = ?"; - const _values = [userId]; - try { - const isAdmin = handler.execute(_sql, _values) - isAdmin.then((result) => { - if (result !== true) return resolve(false); - return resolve(true) - }); - } catch (err: unknown) { - reject(err as Error); - } - }); + const _sql = + "SELECT `is_admin` FROM `users` WHERE `id` = ?"; + const _values = [userId]; + try { + const isAdmin = handler.execute( + _sql, + _values, + ) as unknown as Promise; + isAdmin.then((result: boolean) => { + if (!result) return resolve(false); + return resolve(true); + }); + } catch (err: unknown) { + reject(err as Error); + } + }); }, /** @@ -264,22 +297,24 @@ const MySqlService = { * @param {string} userId - The ID of the user to delete. * @return {Promise} - A Promise that resolves when the deletion is successful, or rejects with an error. */ - delete(handler: MysqlHandler, userId: string): Promise { + delete( + handler: MysqlHandler, + userId: string, + ): Promise { return new Promise((resolve, reject) => { - if (!userId) return reject('Id is undefined'); - if (userId.length !== 36) return reject('Id invalid'); - const _sql = "DELETE FROM `users` WHERE `id` = ?"; - const _values = [userId]; - try { - resolve(handler.execute(_sql, _values)); - } catch (err: unknown) { - reject(err as Error); - } - }); - } + if (!userId) return reject("Id is undefined"); + if (userId.length !== 36) return reject("Id invalid"); + const _sql = "DELETE FROM `users` WHERE `id` = ?"; + const _values = [userId]; + try { + resolve(handler.execute(_sql, _values)); + } catch (err: unknown) { + reject(err as Error); + } + }); + }, }, Brand: { - /** * Inserts a new record into the `brands` table. * @@ -288,27 +323,35 @@ const MySqlService = { * @returns {Promise} - A Promise that resolves to the status result of the insert operation. * @throws {Error} - If an error occurs during the execution of the SQL query. */ - insert(handler: MysqlHandler, data: IDbBrand): Promise { + insert( + handler: MysqlHandler, + data: IDbBrand, + ): Promise { return new Promise((resolve, reject) => { - if (!data.id) return reject('Id is undefined'); - if (data.id.length !== 36) return reject('Id invalid'); + if (!data.id) return reject("Id is undefined"); + if (data.id.length !== 36) return reject("Id invalid"); - const _sql = "INSERT INTO `brands`(`id`,`display_name`, `slug_name`, `image_blob`) VALUES (?, ?, ?, ?)" + const _sql = + "INSERT INTO `brands`(`id`,`display_name`, `slug_name`, `image_blob`) VALUES (?, ?, ?, ?)"; const _values = [ data.id, data.display_name, data.slug_name, - data.image_blob - ] + data.image_blob, + ]; try { - resolve(handler.execute(_sql, _values) as unknown as IDbStatusResult) + resolve( + handler.execute( + _sql, + _values, + ) as unknown as IDbStatusResult, + ); } catch (err: unknown) { reject(err as Error); } - }) + }); }, - /** * Update the brand information in the database. * @@ -317,30 +360,37 @@ const MySqlService = { * @returns {Promise} - A promise that resolves to the status result of the update operation. * @throws {Error} - If any error occurs during the process. */ - update(handler: MysqlHandler, data: IDbBrand): Promise { + update( + handler: MysqlHandler, + data: IDbBrand, + ): Promise { return new Promise((resolve, reject) => { - if (!data.id) return reject('Id is undefined'); - if (data.id.length !== 36) return reject('Id invalid'); + if (!data.id) return reject("Id is undefined"); + if (data.id.length !== 36) return reject("Id invalid"); try { const _template = ` - ${data.slug_name ? "`slug_name` = ?," : null} - ${data.display_name ? "`display_name` = ?," : null} - ${data.image_blob ? "`slug_name` = ?," : null}` + ${data.slug_name ? "`slug_name` = ?," : null} + ${data.display_name ? "`display_name` = ?," : null} + ${data.image_blob ? "`slug_name` = ?," : null}`; const _values = [ data.slug_name, data.display_name, data.image_blob, - data.id - ] + data.id, + ]; const _sql = `UPDATE "brands" SET ${_template} WHERE 'id' = ?`; - return resolve(handler.execute(_sql, _values) as unknown as IDbStatusResult); - + return resolve( + handler.execute( + _sql, + _values, + ) as unknown as IDbStatusResult, + ); } catch (err: unknown) { reject(err as Error); } - }) + }); }, /** @@ -354,11 +404,13 @@ const MySqlService = { return new Promise((resolve, reject) => { const _sql = "SELECT * FROM `brands`"; try { - resolve(handler.query(_sql) as unknown as Array); + resolve( + handler.query(_sql) as unknown as Array, + ); } catch (err: unknown) { reject(err as Error); } - }) + }); }, /** @@ -370,19 +422,27 @@ const MySqlService = { * @throws {Error} - If an error occurs during execution * @throws {string} - If brandId is undefined or invalid */ - getById(handler: MysqlHandler, brandId: string): Promise { + getById( + handler: MysqlHandler, + brandId: string, + ): Promise { return new Promise((resolve, reject) => { - if (!brandId) return reject('Id is undefined') - if (brandId.length !== 36) return reject('Id invalid'); + if (!brandId) return reject("Id is undefined"); + if (brandId.length !== 36) return reject("Id invalid"); const _sql = "SELECT * FROM `brands` WHERE `id` = ?"; const _values = [brandId]; try { - resolve(handler.execute(_sql, _values) as unknown as IDbBrand); + resolve( + handler.execute( + _sql, + _values, + ) as unknown as IDbBrand, + ); } catch (err: unknown) { //TODO Reject with null and logger error reject(err as Error); } - }) + }); }, /** @@ -392,17 +452,26 @@ const MySqlService = { * @param {string} brandSlug - The slug of the brand to retrieve. * @returns {Promise} - A promise that resolves with the brand object if found, or rejects with an error message. */ - getBySlug(handler: MysqlHandler, brandSlug: string): Promise { + getBySlug( + handler: MysqlHandler, + brandSlug: string, + ): Promise { return new Promise((resolve, reject) => { - if (!brandSlug) return reject('slug is undefined') - const _sql = "SELECT * FROM `brands` WHERE `slug_name` = ?"; + if (!brandSlug) return reject("slug is undefined"); + const _sql = + "SELECT * FROM `brands` WHERE `slug_name` = ?"; const _values = [brandSlug]; try { - resolve(handler.execute(_sql, _values) as unknown as IDbBrand); + resolve( + handler.execute( + _sql, + _values, + ) as unknown as IDbBrand, + ); } catch (err: unknown) { reject(err as Error); } - }) + }); }, /** @@ -413,25 +482,32 @@ const MySqlService = { * @returns {Promise} A promise that resolves to the database status result. * @throws {Error} If an error occurs while deleting the brand. */ - delete(handler: MysqlHandler, brandId: string): Promise { + delete( + handler: MysqlHandler, + brandId: string, + ): Promise { //TODO check if has models linked before actions return new Promise((resolve, reject) => { - if (!brandId) return reject('Id is undefined'); - if (brandId.length !== 36) return reject('Id invalid'); + if (!brandId) return reject("Id is undefined"); + if (brandId.length !== 36) return reject("Id invalid"); const _sql = "DELETE FROM `brands` WHERE `id` = ?"; const _values = [brandId]; try { - resolve(handler.execute(_sql, _values) as unknown as IDbStatusResult); + resolve( + handler.execute( + _sql, + _values, + ) as unknown as IDbStatusResult, + ); } catch (err: unknown) { reject(err as Error); } - }) - } + }); + }, //TODO Get models of the brand }, Model: { - /** * Retrieves all records from the 'models' table. * @@ -443,7 +519,9 @@ const MySqlService = { return new Promise((resolve, reject) => { const _sql = "SELECT * FROM `models`"; try { - resolve(handler.query(_sql) as unknown as Array); + resolve( + handler.query(_sql) as unknown as Array, + ); } catch (err: unknown) { reject(err as Error); } @@ -458,12 +536,21 @@ const MySqlService = { * @return {Promise} A promise that resolves with the retrieved model. * @throws {Error} If there was an error executing the query. */ - getBySlug(handler: MysqlHandler, modelSlug: string): Promise { + getBySlug( + handler: MysqlHandler, + modelSlug: string, + ): Promise { return new Promise((resolve, reject) => { - const _sql = "SELECT * FROM `models` WHERE `slug_name` = ?"; + const _sql = + "SELECT * FROM `models` WHERE `slug_name` = ?"; const _values = [modelSlug]; try { - resolve(handler.execute(_sql, _values) as unknown as IDbModel); + resolve( + handler.execute( + _sql, + _values, + ) as unknown as IDbModel, + ); } catch (err: unknown) { reject(err as Error); } @@ -477,12 +564,20 @@ const MySqlService = { * @param {string} modelId - The ID of the model to retrieve. * @return {Promise} - A promise that resolves with the retrieved model, or rejects with an error. */ - getById(handler: MysqlHandler, modelId: string): Promise { + getById( + handler: MysqlHandler, + modelId: string, + ): Promise { return new Promise((resolve, reject) => { const _sql = "SELECT * FROM `models` WHERE `id` = ?"; const _values = [modelId]; try { - resolve(handler.execute(_sql, _values) as unknown as IDbModel); + resolve( + handler.execute( + _sql, + _values, + ) as unknown as IDbModel, + ); } catch (err: unknown) { reject(err as Error); } @@ -497,12 +592,16 @@ const MySqlService = { * @throws {string} - Throws an error message if the id is undefined or invalid. * @returns {Promise} - A promise that resolves to the status result of the insert operation. */ - insert(handler: MysqlHandler, data: IDbModel): Promise { + insert( + handler: MysqlHandler, + data: IDbModel, + ): Promise { return new Promise((resolve, reject) => { - if (!data.id) return reject('Id is undefined'); - if (data.id.length !== 36) return reject('Id invalid'); + if (!data.id) return reject("Id is undefined"); + if (data.id.length !== 36) return reject("Id invalid"); - const _sql = "INSERT INTO `models`(`slug_name`,`display_name`, `brand_id`, `category_id`, `image_blob`, `is_trending`, `base_price`, `id`) VALUES (?, ?, ?, ?, ?, ?, ?, ?)" + const _sql = + "INSERT INTO `models`(`slug_name`,`display_name`, `brand_id`, `category_id`, `image_blob`, `is_trending`, `base_price`, `id`) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; const _values = [ data.slug_name, data.display_name, @@ -511,14 +610,19 @@ const MySqlService = { data.image_blob, data.is_trending, data.base_price, - data.id - ] + data.id, + ]; try { - resolve(handler.execute(_sql, _values) as unknown as IDbStatusResult) + resolve( + handler.execute( + _sql, + _values, + ) as unknown as IDbStatusResult, + ); } catch (err: unknown) { reject(err as Error); } - }) + }); }, //TODO get linked vehicles @@ -531,20 +635,23 @@ const MySqlService = { * @return {Promise} - A promise that resolves to the status result of the update operation. * @throws {Error} - If an error occurs during the update process. */ - update(handler: MysqlHandler, data: IDbModel): Promise { + update( + handler: MysqlHandler, + data: IDbModel, + ): Promise { return new Promise((resolve, reject) => { - if (!data.id) return reject('Id is undefined'); - if (data.id.length !== 36) return reject('Id invalid'); + if (!data.id) return reject("Id is undefined"); + if (data.id.length !== 36) return reject("Id invalid"); try { const _template = ` - ${data.slug_name ? "`slug_name` = ?," : null} - ${data.display_name ? "`display_name` = ?," : null} - ${data.brand_id ? "`brand_id` = ?," : null} - ${data.category_id ? "`category_id` = ?," : null} - ${data.image_blob ? "`image_blob` = ?," : null} - ${data.is_trending ? "`is_trending` = ?," : null} - ${data.base_price ? "`base_price` = ?," : null}` + ${data.slug_name ? "`slug_name` = ?," : null} + ${data.display_name ? "`display_name` = ?," : null} + ${data.brand_id ? "`brand_id` = ?," : null} + ${data.category_id ? "`category_id` = ?," : null} + ${data.image_blob ? "`image_blob` = ?," : null} + ${data.is_trending ? "`is_trending` = ?," : null} + ${data.base_price ? "`base_price` = ?," : null}`; const _values = [ data.slug_name, @@ -554,14 +661,19 @@ const MySqlService = { data.image_blob, data.is_trending, data.base_price, - data.id - ] + data.id, + ]; const _sql = `UPDATE "models" SET ${_template} WHERE 'id' = ?`; - return resolve(handler.execute(_sql, _values) as unknown as IDbStatusResult); + return resolve( + handler.execute( + _sql, + _values, + ) as unknown as IDbStatusResult, + ); } catch (err: unknown) { reject(err as Error); } - }) + }); }, /** @@ -572,20 +684,28 @@ const MySqlService = { * @returns {Promise} A promise that resolves to the result of the delete operation. * @throws {Error} If an error occurs during the delete operation. */ - delete(handler: MysqlHandler, modelId: string): Promise { + delete( + handler: MysqlHandler, + modelId: string, + ): Promise { //TODO check if has models linked before actions return new Promise((resolve, reject) => { - if (!modelId) return reject('Id is undefined'); - if (modelId.length !== 36) return reject('Id invalid'); + if (!modelId) return reject("Id is undefined"); + if (modelId.length !== 36) return reject("Id invalid"); const _sql = "DELETE FROM `models` WHERE `id` = ?"; const _values = [modelId]; try { - resolve(handler.execute(_sql, _values) as unknown as IDbStatusResult); + resolve( + handler.execute( + _sql, + _values, + ) as unknown as IDbStatusResult, + ); } catch (err: unknown) { reject(err as Error); } - }) - } + }); + }, }, Vehicle: { /** @@ -595,25 +715,34 @@ const MySqlService = { * @throws Throws an error if the provided `data` object does not contain the `id` property or if the `id` is not a valid UUID. * @returns {Promise} A promise that resolves to the result of the insert operation. */ - insert(handler: MysqlHandler, data: IDbVehicle): Promise { + insert( + handler: MysqlHandler, + data: IDbVehicle, + ): Promise { return new Promise((resolve, reject) => { - if (!data.id) return reject('Id is undefined'); - if (data.id.length !== 36) return reject('Id invalid'); + if (!data.id) return reject("Id is undefined"); + if (data.id.length !== 36) return reject("Id invalid"); - const _sql = "INSERT INTO `vehicles`(`model_id`, `plate_number`, `odometer`, `health_state`, `id`) VALUES (?, ?, ?, ?, ?)" + const _sql = + "INSERT INTO `vehicles`(`model_id`, `plate_number`, `odometer`, `health_state`, `id`) VALUES (?, ?, ?, ?, ?)"; const _values = [ data.model_id, data.plate_number, data.odometer, data.health_state, - data.id - ] + data.id, + ]; try { - resolve(handler.execute(_sql, _values) as unknown as IDbStatusResult) + resolve( + handler.execute( + _sql, + _values, + ) as unknown as IDbStatusResult, + ); } catch (err: unknown) { reject(err as Error); } - }) + }); }, /** @@ -624,31 +753,41 @@ const MySqlService = { * @throws {string} Throws an error if the id is undefined or invalid. * @returns {Promise} Returns a Promise that resolves to the status result of the update operation. */ - update(handler: MysqlHandler, data: IDbVehicle): Promise { + update( + handler: MysqlHandler, + data: IDbVehicle, + ): Promise { return new Promise((resolve, reject) => { - if (!data.id) return reject('Id is undefined'); - if (data.id.length !== 36) return reject('Id invalid'); + if (!data.id) return reject("Id is undefined"); + if (data.id.length !== 36) return reject("Id invalid"); try { const _template = ` - ${data.model_id ? "`model_id` = ?," : null} - ${data.plate_number ? "`plate_number` = ?," : null} - ${data.odometer ? "`odometer` = ?," : null} - ${data.health_state ? "`health_state` = ?," : null}` + ${data.model_id ? "`model_id` = ?," : null} + ${data.plate_number ? "`plate_number` = ?," : null} + ${data.odometer ? "`odometer` = ?," : null} + ${ + data.health_state ? "`health_state` = ?," : null + }`; const _values = [ data.model_id, data.plate_number, data.odometer, data.health_state, - data.id - ] + data.id, + ]; const _sql = `UPDATE "vehicles" SET ${_template} WHERE 'id' = ?`; - return resolve(handler.execute(_sql, _values) as unknown as IDbStatusResult); + return resolve( + handler.execute( + _sql, + _values, + ) as unknown as IDbStatusResult, + ); } catch (err: unknown) { reject(err as Error); } - }) + }); }, /** @@ -659,14 +798,23 @@ const MySqlService = { * @returns {Promise} - A promise that resolves to the retrieved vehicle. * @throws {Error} - If an error occurs while retrieving the vehicle. */ - getById(handler: MysqlHandler, vehicleId: string): Promise { + getById( + handler: MysqlHandler, + vehicleId: string, + ): Promise { return new Promise((resolve, reject) => { - if (!vehicleId) return reject('Id is undefined'); - if (vehicleId.length !== 36) return reject('Id invalid'); + if (!vehicleId) return reject("Id is undefined"); + if (vehicleId.length !== 36) + return reject("Id invalid"); const _sql = "SELECT * FROM `vehicles` WHERE `id` = ?"; const _values = [vehicleId]; try { - resolve(handler.execute(_sql, _values) as unknown as IDbVehicle); + resolve( + handler.execute( + _sql, + _values, + ) as unknown as IDbVehicle, + ); } catch (err: unknown) { reject(err as Error); } @@ -684,7 +832,9 @@ const MySqlService = { return new Promise((resolve, reject) => { const _sql = "SELECT * FROM `models`"; try { - resolve(handler.query(_sql) as unknown as Array); + resolve( + handler.query(_sql) as unknown as Array, + ); } catch (err: unknown) { reject(err as Error); } @@ -698,16 +848,21 @@ const MySqlService = { * @returns {Promise>} A promise that resolves to an array of available vehicles. * @throws {Error} If an error occurs while executing the query. */ - getAvailable(handler: MysqlHandler): Promise> { + getAvailable( + handler: MysqlHandler, + ): Promise> { return new Promise((resolve, reject) => { - const _sql = "SELECT * FROM `vehicles` WERE `isAvailable` = 1"; + const _sql = + "SELECT * FROM `vehicles` WERE `isAvailable` = 1"; try { - resolve(handler.query(_sql) as unknown as Array); + resolve( + handler.query(_sql) as unknown as Array, + ); } catch (err: unknown) { reject(err as Error); } - }) - } + }); + }, }, Category: { /** @@ -717,23 +872,27 @@ const MySqlService = { * @param {IDbCategory} data - The category data to be inserted. * @return {Promise} - A promise that resolves if the insertion is successful, and rejects with an error if it fails. */ - insert(handler: MysqlHandler, data: IDbCategory): Promise { + insert( + handler: MysqlHandler, + data: IDbCategory, + ): Promise { return new Promise((resolve, reject) => { - if (!data.id) return reject('Id is undefined'); - if (data.id.length !== 36) return reject('Id invalid'); + if (!data.id) return reject("Id is undefined"); + if (data.id.length !== 36) return reject("Id invalid"); - const _sql = "INSERT INTO `categories`(`id`,`slug_name`, `display_name`) VALUES (?, ?, ?)" + const _sql = + "INSERT INTO `categories`(`id`,`slug_name`, `display_name`) VALUES (?, ?, ?)"; const _values = [ data.id, data.slug_name, - data.display_name - ] + data.display_name, + ]; try { - resolve(handler.execute(_sql, _values)) + resolve(handler.execute(_sql, _values)); } catch (err: unknown) { reject(err as Error); } - }) + }); }, /** @@ -744,28 +903,34 @@ const MySqlService = { * @returns {Promise} - A promise that resolves with the number of affected rows in the database. * @throws {Error} - If an error occurs during execution. */ - update(handler: MysqlHandler, data: IDbCategory): Promise { + update( + handler: MysqlHandler, + data: IDbCategory, + ): Promise { return new Promise((resolve, reject) => { - if (!data.id) return reject('Id is undefined'); - if (data.id.length !== 36) return reject('Id invalid'); + if (!data.id) return reject("Id is undefined"); + if (data.id.length !== 36) return reject("Id invalid"); try { const _template = ` - ${data.slug_name ? "`slug_name` = ?," : null} - ${data.display_name ? "`display_name` = ?," : null}` + ${data.slug_name ? "`slug_name` = ?," : null} + ${ + data.display_name ? "`display_name` = ?," : null + }`; const _values = [ data.slug_name, data.display_name, - data.id - ] + data.id, + ]; const _sql = `UPDATE "categories" SET ${_template} WHERE 'id' = ?`; - return resolve(handler.execute(_sql, _values) as unknown as number); - + return resolve( + handler.execute(_sql, _values) as unknown as number, + ); } catch (err: unknown) { reject(err as Error); } - }) + }); }, /** * Retrieves all categories from the database. @@ -780,7 +945,11 @@ const MySqlService = { return new Promise((resolve, reject) => { const _sql = "SELECT * FROM `categories`"; try { - resolve(handler.query(_sql) as unknown as Array); + resolve( + handler.query( + _sql, + ) as unknown as Array, + ); } catch (err: unknown) { reject(err as Error); } @@ -794,17 +963,26 @@ const MySqlService = { * @returns {Promise} - A promise that resolves with the retrieved category object. * @throws {Error} - If an error occurs while executing the query. */ - getBySlug(handler: MysqlHandler, categorySlug: string): Promise { + getBySlug( + handler: MysqlHandler, + categorySlug: string, + ): Promise { return new Promise((resolve, reject) => { - if (!categorySlug) return reject('slug is undefined') - const _sql = "SELECT * FROM `categories` WHERE `slug_name` = ?"; + if (!categorySlug) return reject("slug is undefined"); + const _sql = + "SELECT * FROM `categories` WHERE `slug_name` = ?"; const _values = [categorySlug]; try { - resolve(handler.execute(_sql, _values) as unknown as IDbCategory); + resolve( + handler.execute( + _sql, + _values, + ) as unknown as IDbCategory, + ); } catch (err: unknown) { reject(err as Error); } - }) + }); }, /** * Retrieves a category from the database by its ID. @@ -814,14 +992,24 @@ const MySqlService = { * @returns {Promise} - A Promise that resolves with the category object. * @throws {Error} - If an error occurs during execution. */ - getById(handler: MysqlHandler, categoryId: string): Promise { + getById( + handler: MysqlHandler, + categoryId: string, + ): Promise { return new Promise((resolve, reject) => { - if (!categoryId) return reject('slug is undefined') - if (categoryId.length !== 36) return reject('Id invalid'); - const _sql = "SELECT * FROM `categories` WHERE `id` = ?"; + if (!categoryId) return reject("slug is undefined"); + if (categoryId.length !== 36) + return reject("Id invalid"); + const _sql = + "SELECT * FROM `categories` WHERE `id` = ?"; const _values = [categoryId]; try { - resolve(handler.execute(_sql, _values) as unknown as IDbCategory); + resolve( + handler.execute( + _sql, + _values, + ) as unknown as IDbCategory, + ); } catch (err: unknown) { reject(err as Error); } @@ -829,8 +1017,9 @@ const MySqlService = { }, delete(handler: MysqlHandler, categoryId: string) { return new Promise((resolve, reject) => { - if (!categoryId) return reject('Id is undefined'); - if (categoryId.length !== 36) return reject('Id invalid'); + if (!categoryId) return reject("Id is undefined"); + if (categoryId.length !== 36) + return reject("Id invalid"); const _sql = "DELETE FROM `categories` WHERE `id` = ?"; const _values = [categoryId]; try { @@ -838,10 +1027,10 @@ const MySqlService = { } catch (err: unknown) { reject(err as Error); } - }) - } + }); + }, //TODO Get models in category - } -} + }, +}; -export default MySqlService \ No newline at end of file +export default MySqlService; diff --git a/src/services/user.service.ts b/src/services/user.service.ts index 2c1e564..9fa8fae 100644 --- a/src/services/user.service.ts +++ b/src/services/user.service.ts @@ -1,15 +1,16 @@ -import {Logger} from "tslog"; -import MySqlService from "@services/mysql.service"; +import type { IReqLogin } from "@interfaces/requests/IReqLogin"; +import type { IReqRegister } from "@interfaces/requests/IReqRegister"; import CredentialService from "@services/credential.service"; import JwtService from "@services/jwt.service"; +import MySqlService from "@services/mysql.service"; import MysqlService from "@services/mysql.service"; -import type {IReqRegister} from "@interfaces/requests/IReqRegister"; -import {IReqLogin} from "@interfaces/requests/IReqLogin"; +import { Logger } from "tslog"; +const logger = new Logger({ + name: "UserService", +}); -const logger = new Logger({ name: "UserService" }); - -const DbHandler = new MySqlService.Handler('UserService') +const DbHandler = new MySqlService.Handler("UserService"); /** * Retrieves a user object from the database based on the given username. @@ -17,55 +18,84 @@ const DbHandler = new MySqlService.Handler('UserService') * @param {string} username - The username of the user to retrieve. * @returns {Promise} - The user object if found, or null if not found. */ -async function getUserFromUsername(username: string): Promise { - const dbUser = await MySqlService.User.getByUsername(DbHandler, username) +async function getUserFromUsername( + username: string, +): Promise { + const dbUser = await MySqlService.User.getByUsername( + DbHandler, + username, + ); if (dbUser === undefined) return null; return dbUser; } async function getUserFromIdService(id: string | undefined) { const dbUser = await MySqlService.User.getById(DbHandler, id); - if (dbUser === undefined) return null; - return dbUser; + if (dbUser === undefined) return null; + return dbUser; } async function register(ReqData: IReqRegister) { if (ReqData.password.length < 6) { - logger.info(`REGISTER :> Invalid password (${ReqData.username})`) - return { error: "invalidPassword" }; + logger.info( + `REGISTER :> Invalid password (${ReqData.username})`, + ); + return { + error: "invalidPassword", + }; } - const passwordHash = await CredentialService.hash(ReqData.password) + const passwordHash = await CredentialService.hash( + ReqData.password, + ); // Does the new user has accepted GDPR ? if (ReqData.gdpr !== true) { - logger.info(`REGISTER :> GDPR not validated (${ReqData.username})`) - return { error: "gdprNotApproved" } + logger.info( + `REGISTER :> GDPR not validated (${ReqData.username})`, + ); + return { + error: "gdprNotApproved", + }; } // Check if exist and return - const dbUserIfExist = await getUserFromUsername(ReqData.username) + const dbUserIfExist = await getUserFromUsername( + ReqData.username, + ); if (dbUserIfExist) { - logger.info(`REGISTER :> User exist (${dbUserIfExist.username})\n ID:${dbUserIfExist.id}`) - return { error: "exist" } + logger.info( + `REGISTER :> User exist (${dbUserIfExist.username})\n ID:${dbUserIfExist.id}`, + ); + return { + error: "exist", + }; } const currentDate = new Date(); // New UserService (class) - const NewUser = new User(ReqData.username, ReqData.displayName, passwordHash, currentDate); + const NewUser = new User( + ReqData.username, + ReqData.displayName, + passwordHash, + currentDate, + ); NewUser.setFirstName(ReqData.firstName); NewUser.setLastName(ReqData.lastName); // JWT - const alg = 'HS512' - const token = await JwtService.sign({ - sub: NewUser.id - }, alg, - '1d', - 'user') + const alg = "HS512"; + const token = await JwtService.sign( + { + sub: NewUser.id, + }, + alg, + "1d", + "user", + ); const userData = { error: "none", @@ -75,45 +105,74 @@ async function register(ReqData: IReqRegister) { username: NewUser.username, displayName: NewUser.displayName, firstName: NewUser.firstName, - lastName: NewUser.lastName - }}; - logger.info(userData) + lastName: NewUser.lastName, + }, + }; + logger.info(userData); await Db.collection("users").insertOne(NewUser); - logger.info(`REGISTER :> Inserted new user (${NewUser.username})`) - return userData + logger.info( + `REGISTER :> Inserted new user (${NewUser.username})`, + ); + return userData; } async function login(ReqData: IReqLogin) { //const passwordHash = await getHashFromPassword(sanitizedData.password); - const dbUser = await MysqlService.User.getByUsername(DbHandler, ReqData.username); + const dbUser = await MysqlService.User.getByUsername( + DbHandler, + ReqData.username, + ); if (!dbUser) { - console.log(`LoginService :> User does not exist (${ReqData.username})`); - return { error: "userNotFound" }; + console.log( + `LoginService :> User does not exist (${ReqData.username})`, + ); + return { + error: "userNotFound", + }; } if (ReqData.password.length < 6) { - console.log('X') - console.log(`LoginService :> Invalid password (${ReqData.username})`); - return { error: "invalidPassword" }; + console.log("X"); + console.log( + `LoginService :> Invalid password (${ReqData.username})`, + ); + return { + error: "invalidPassword", + }; } - const isPasswordValid = await CredentialService.compare(ReqData.password, dbUser.hash) + const isPasswordValid = await CredentialService.compare( + ReqData.password, + dbUser.hash, + ); if (!isPasswordValid) { - console.log(isPasswordValid) - console.log(`LoginService :> Invalid password (${ReqData.username})`); - return { error: "invalidPassword" }; + console.log(isPasswordValid); + console.log( + `LoginService :> Invalid password (${ReqData.username})`, + ); + return { + error: "invalidPassword", + }; } // biome-ignore lint/style/useConst: let userData = { error: "none", - jwt: '', + jwt: "", user: { id: dbUser.id, username: dbUser.username, displayName: dbUser.displayName, - } + }, }; - userData.jwt = await JwtService.sign({sub: dbUser.id}, {alg: 'HS512'}, '7d', 'user') - + userData.jwt = await JwtService.sign( + { + sub: dbUser.id, + }, + { + alg: "HS512", + }, + "7d", + "user", + ); console.log("USERDATA :>"); console.log(userData); @@ -130,17 +189,17 @@ async function login(ReqData: IReqLogin) { async function getAllUsersService() { const users = await Db.collection("users").find().toArray(); // biome-ignore lint/complexity/noForEach: - users.forEach(user => { - delete user.passwordHash - delete user._id - delete user.gdpr + users.forEach((user) => { + delete user.passwordHash; + delete user._id; + delete user.gdpr; }); - logger.info(`Query ${users.length} user(s)`) + logger.info(`Query ${users.length} user(s)`); return { iat: Date.now(), users: users, - length: users.length - } + length: users.length, + }; } /** @@ -154,19 +213,34 @@ async function getAllUsersService() { */ async function editUserService(targetId, sanitizedData) { if (sanitizedData.password) { - const passwordHash = await getHashFromPassword(sanitizedData.password) - delete sanitizedData.password - logger.info(`Changing password for user "${targetId}"`) - sanitizedData.passwordHash = passwordHash + const passwordHash = await getHashFromPassword( + sanitizedData.password, + ); + delete sanitizedData.password; + logger.info(`Changing password for user "${targetId}"`); + sanitizedData.passwordHash = passwordHash; } - const updatedUserResult = await Db.collection("users").updateOne({id: targetId}, {$set: sanitizedData}); + const updatedUserResult = await Db.collection( + "users", + ).updateOne( + { + id: targetId, + }, + { + $set: sanitizedData, + }, + ); if (updatedUserResult.modifiedCount === 0) { logger.info(`EDIT :> User not found (${targetId})`); - return { error: "userNotFound" }; + return { + error: "userNotFound", + }; } logger.info(`EDIT :> User updated (${targetId})`); - return { error: "none" }; + return { + error: "none", + }; } /** @@ -176,13 +250,15 @@ async function editUserService(targetId, sanitizedData) { * @return {Promise} - A promise that resolves to true if the user is successfully deleted, or false if an error occurs. */ async function deleteUserService(targetId) { - logger.info(`Deleting user ${targetId}`) + logger.info(`Deleting user ${targetId}`); try { - await Db.collection("users").deleteOne({id: targetId}); - return true + await Db.collection("users").deleteOne({ + id: targetId, + }); + return true; } catch (e) { - logger.warn(e) - return false + logger.warn(e); + return false; } } @@ -192,7 +268,7 @@ const UserService = { getAll: getAllUsersService, getFromId: getUserFromIdService, edit: editUserService, - delete: deleteUserService -} + delete: deleteUserService, +}; -export default UserService; \ No newline at end of file +export default UserService; diff --git a/src/validators/AdminGuard.ts b/src/validators/AdminGuard.ts index 5e498f3..1a88c60 100644 --- a/src/validators/AdminGuard.ts +++ b/src/validators/AdminGuard.ts @@ -1,39 +1,58 @@ 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 {Logger} from "tslog"; +import type { NextFunction, Request, Response } from "express"; +import { Logger } from "tslog"; -const DbHandler = new MySqlService.Handler('AdminGuard') -const logger = new Logger({name: 'AdminGuard'}) +const DbHandler = new MySqlService.Handler("AdminGuard"); +const logger = new Logger({ + name: "AdminGuard", +}); const UNAUTHORIZED = 401; const FORBIDDEN = 403; -const UNAUTH_MESSAGE = 'Missing Authorization Header'; -const INVALID_TOKEN_MESSAGE = 'Invalid or expired token.'; -const PERMISSON_NOT_VALID = 'You are missing the required permission.' +const UNAUTH_MESSAGE = "Missing Authorization Header"; +const INVALID_TOKEN_MESSAGE = "Invalid or expired token."; +const PERMISSON_NOT_VALID = + "You are missing the required permission."; -async function AdminGuard(req: Request, res: Response, next: NextFunction) { +async function AdminGuard( + req: Request, + res: Response, + next: NextFunction, +) { const authHeader = req.headers.authorization; if (!authHeader) { - logger.warn(`Invalid header (${req.ip})`) - return res.status(UNAUTHORIZED).json({message: UNAUTH_MESSAGE}); + logger.warn(`Invalid header (${req.ip})`); + return res.status(UNAUTHORIZED).json({ + message: UNAUTH_MESSAGE, + }); } - const bearerToken = authHeader.split(' ')[1]; + const bearerToken = authHeader.split(" ")[1]; - if (!bearerToken) return res.status(FORBIDDEN).json({message: INVALID_TOKEN_MESSAGE}); + if (!bearerToken) + return res.status(FORBIDDEN).json({ + message: INVALID_TOKEN_MESSAGE, + }); const token = await JwtService.verify(bearerToken); if (token) { // @ts-ignore - const isSourceAdmin = await MysqlService.User.getAdminStateForId(DbHandler, token.sub) + const isSourceAdmin = + await MysqlService.User.getAdminStateForId( + DbHandler, + token.sub, + ); if (isSourceAdmin === true) next(); - return res.status(FORBIDDEN).json({message: PERMISSON_NOT_VALID}); - + return res.status(FORBIDDEN).json({ + message: PERMISSON_NOT_VALID, + }); } - return res.status(FORBIDDEN).json({message: INVALID_TOKEN_MESSAGE}); + return res.status(FORBIDDEN).json({ + message: INVALID_TOKEN_MESSAGE, + }); } -export default AdminGuard \ No newline at end of file +export default AdminGuard; diff --git a/src/validators/UserGuard.ts b/src/validators/UserGuard.ts index 7d87ca3..e7312ac 100644 --- a/src/validators/UserGuard.ts +++ b/src/validators/UserGuard.ts @@ -1,26 +1,37 @@ import JwtService from "@services/jwt.service"; -import type {NextFunction, Request, Response} from "express"; import MySqlService from "@services/mysql.service"; -import {Logger} from "tslog"; +import type { NextFunction, Request, Response } from "express"; +import { Logger } from "tslog"; -const DbHandler = new MySqlService.Handler('UserGuard') -const logger = new Logger({name: 'UserGuard'}) +const DbHandler = new MySqlService.Handler("UserGuard"); +const logger = new Logger({ + name: "UserGuard", +}); const UNAUTHORIZED = 401; const FORBIDDEN = 403; -const UNAUTH_MESSAGE = 'Missing Authorization Header'; -const INVALID_TOKEN_MESSAGE = 'Invalid or expired token.'; -const USER_NOT_EXIST = 'You dont exist anymore' +const UNAUTH_MESSAGE = "Missing Authorization Header"; +const INVALID_TOKEN_MESSAGE = "Invalid or expired token."; +const USER_NOT_EXIST = "You dont exist anymore"; -async function UserGuard(req: Request, res: Response, next: NextFunction) { +async function UserGuard( + req: Request, + res: Response, + next: NextFunction, +) { const authHeader = req.headers.authorization; if (!authHeader) { - return res.status(UNAUTHORIZED).json({message: UNAUTH_MESSAGE}); + return res.status(UNAUTHORIZED).json({ + message: UNAUTH_MESSAGE, + }); } - const bearerToken = authHeader.split(' ')[1]; + const bearerToken = authHeader.split(" ")[1]; - if (!bearerToken) return res.status(FORBIDDEN).json({message: INVALID_TOKEN_MESSAGE}); + if (!bearerToken) + return res.status(FORBIDDEN).json({ + message: INVALID_TOKEN_MESSAGE, + }); const token = await JwtService.verify(bearerToken); @@ -29,16 +40,25 @@ async function UserGuard(req: Request, res: Response, next: NextFunction) { const userId = token.sub; if (!userId) { logger.error(USER_NOT_EXIST); - return res.status(UNAUTHORIZED).json({message: USER_NOT_EXIST}); + return res.status(UNAUTHORIZED).json({ + message: USER_NOT_EXIST, + }); } - const user= await MySqlService.User.getById(DbHandler, userId); - if (user) { - logger.info(`An user do a request. (${user?.username})`) - next() + const user = await MySqlService.User.getById( + DbHandler, + userId, + ); + if (user) { + logger.info(`An user do a request. (${user?.username})`); + next(); } - return res.status(UNAUTHORIZED).json({message: USER_NOT_EXIST}); + return res.status(UNAUTHORIZED).json({ + message: USER_NOT_EXIST, + }); } - return res.status(FORBIDDEN).json({message: INVALID_TOKEN_MESSAGE}); + return res.status(FORBIDDEN).json({ + message: INVALID_TOKEN_MESSAGE, + }); } -export default UserGuard \ No newline at end of file +export default UserGuard;