type: style
scope: services, interfaces subject: Apply code formatting - Correct indentation and formatting to match code style standards in multiple 'interfaces' and 'services' files. - Also ensure lines at the end of the files. Signed-off-by: Mathis <yidhra@tuta.io>
This commit is contained in:
parent
cda313866f
commit
56bfd8cd0d
13
biome.json
13
biome.json
@ -3,6 +3,15 @@
|
|||||||
"organizeImports": {
|
"organizeImports": {
|
||||||
"enabled": true
|
"enabled": true
|
||||||
},
|
},
|
||||||
|
"files": {
|
||||||
|
"include": [
|
||||||
|
"./src/**/*.ts"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"vcs": {
|
||||||
|
"enabled": true,
|
||||||
|
"clientKind": "git"
|
||||||
|
},
|
||||||
"linter": {
|
"linter": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"rules": {
|
"rules": {
|
||||||
@ -17,8 +26,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"formatter": {
|
"formatter": {
|
||||||
"indentStyle": "space",
|
"indentStyle": "tab",
|
||||||
"indentWidth": 2,
|
"indentWidth": 2,
|
||||||
"lineWidth": 15
|
"lineWidth": 64
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
"author": "Mathis HERRIOT",
|
"author": "Mathis HERRIOT",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"bun:dev": "bun run --watch src/app.ts"
|
"bun:dev": "bun run --watch src/app.ts",
|
||||||
|
"bun:check": "bunx biome check --skip-errors --apply src"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@node-rs/argon2": "^1.8.3",
|
"@node-rs/argon2": "^1.8.3",
|
||||||
|
43
src/app.ts
43
src/app.ts
@ -1,21 +1,22 @@
|
|||||||
import express, { type Express } from 'express';
|
import * as process from "node:process";
|
||||||
import cors from 'cors';
|
|
||||||
import compression from 'compression';
|
|
||||||
import {Logger} from "tslog";
|
|
||||||
import helmet from "helmet";
|
|
||||||
import AuthRouter from "@routes/auth/authRouter";
|
import AuthRouter from "@routes/auth/authRouter";
|
||||||
import CatalogRouter from "@routes/catalog/catalogRouter";
|
import CatalogRouter from "@routes/catalog/catalogRouter";
|
||||||
import RentRouter from "@routes/rent/rentRouter";
|
import RentRouter from "@routes/rent/rentRouter";
|
||||||
import * 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({
|
||||||
const logger = new Logger({ name: "App" });
|
name: "App",
|
||||||
|
});
|
||||||
|
|
||||||
const app: Express = express();
|
const app: Express = express();
|
||||||
|
|
||||||
// enable cors
|
// enable cors
|
||||||
app.use(cors());
|
app.use(cors());
|
||||||
app.options('*', cors());
|
app.options("*", cors());
|
||||||
|
|
||||||
// enable xss sanitizer
|
// enable xss sanitizer
|
||||||
app.use(
|
app.use(
|
||||||
@ -23,30 +24,34 @@ app.use(
|
|||||||
xXssProtection: true,
|
xXssProtection: true,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
app.use(helmet.xXssProtection())
|
app.use(helmet.xXssProtection());
|
||||||
|
|
||||||
// parse json request body
|
// parse json request body
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
|
||||||
// parse urlencoded request body
|
// parse urlencoded request body
|
||||||
app.use(express.urlencoded({ extended: true }));
|
app.use(
|
||||||
|
express.urlencoded({
|
||||||
|
extended: true,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
// gzip compression
|
// gzip compression
|
||||||
app.use(compression())
|
app.use(compression());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
app.use('/auth', AuthRouter)
|
app.use("/auth", AuthRouter);
|
||||||
app.use('/catalog', CatalogRouter)
|
app.use("/catalog", CatalogRouter);
|
||||||
app.use('/rent', RentRouter)
|
app.use("/rent", RentRouter);
|
||||||
logger.info('Routers loaded !')
|
logger.info("Routers loaded !");
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(err)
|
logger.error(err);
|
||||||
throw null;
|
throw null;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
app.listen(process.env["APP_PORT"])
|
app.listen(process.env["APP_PORT"]);
|
||||||
logger.info('Server is running !')
|
logger.info("Server is running !");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`Server failed to start: ${error}`);
|
logger.error(`Server failed to start: ${error}`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import JwtService from "@services/jwt.service";
|
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 UserService from "@services/user.service";
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { Logger } from "tslog";
|
import { Logger } from "tslog";
|
||||||
|
|
||||||
|
const logger = new Logger({
|
||||||
const logger = new Logger({ name: "AuthController" });
|
name: "AuthController",
|
||||||
|
});
|
||||||
|
|
||||||
//FIX Better return object interface
|
//FIX Better return object interface
|
||||||
/**
|
/**
|
||||||
@ -22,25 +22,34 @@ const logger = new Logger({ name: "AuthController" });
|
|||||||
* - error: "exist" if the user already exists
|
* - error: "exist" if the user already exists
|
||||||
* - Otherwise, the registered user data
|
* - Otherwise, the registered user data
|
||||||
*/
|
*/
|
||||||
async function registerUser(req: Request, res: Response): Promise<unknown> {
|
async function registerUser(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
): Promise<unknown> {
|
||||||
const body = req.body;
|
const body = req.body;
|
||||||
if (!body) {
|
if (!body) {
|
||||||
logger.warn(`Invalid input data (${req.ip})`);
|
logger.warn(`Invalid input data (${req.ip})`);
|
||||||
return res
|
return res.type("application/json").status(400).json({
|
||||||
.type('application/json')
|
error: "Invalid input data",
|
||||||
.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})`);
|
logger.warn(`Field(s) missing (${req.ip})`);
|
||||||
return res
|
return res.type("application/json").status(400).json({
|
||||||
.type('application/json')
|
error: "Field(s) missing",
|
||||||
.status(400)
|
});
|
||||||
.json({ error: 'Field(s) missing' });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let gdpr = false
|
let gdpr = false;
|
||||||
if (body.gdpr === true) {gdpr = true}
|
if (body.gdpr === true) {
|
||||||
|
gdpr = true;
|
||||||
|
}
|
||||||
const sanitizeData = {
|
const sanitizeData = {
|
||||||
username: `${body.username}`,
|
username: `${body.username}`,
|
||||||
displayName: `${body.displayName}`,
|
displayName: `${body.displayName}`,
|
||||||
@ -50,32 +59,28 @@ async function registerUser(req: Request, res: Response): Promise<unknown> {
|
|||||||
lastName: `${body.lastName}`,
|
lastName: `${body.lastName}`,
|
||||||
};
|
};
|
||||||
|
|
||||||
const RegisterServiceResult = await UserService.register(sanitizeData)
|
const RegisterServiceResult =
|
||||||
|
await UserService.register(sanitizeData);
|
||||||
|
|
||||||
if (RegisterServiceResult.error === "gdprNotApproved") {
|
if (RegisterServiceResult.error === "gdprNotApproved") {
|
||||||
logger.warn(`GDPR not approved (${req.ip})`);
|
logger.warn(`GDPR not approved (${req.ip})`);
|
||||||
return res
|
return res.status(400).json({
|
||||||
.status(400)
|
|
||||||
.json({
|
|
||||||
error: RegisterServiceResult.error,
|
error: RegisterServiceResult.error,
|
||||||
message: "GDPR not accepted."
|
message: "GDPR not accepted.",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (RegisterServiceResult.error === "exist") {
|
if (RegisterServiceResult.error === "exist") {
|
||||||
logger.warn(`The user already exists (${req.ip})`);
|
logger.warn(`The user already exists (${req.ip})`);
|
||||||
return res
|
return res.type("application/json").status(400).json({
|
||||||
.type('application/json')
|
|
||||||
.status(400)
|
|
||||||
.json({
|
|
||||||
error: RegisterServiceResult.error,
|
error: RegisterServiceResult.error,
|
||||||
message: "The user already exists."
|
message: "The user already exists.",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// SUCCESS
|
// SUCCESS
|
||||||
logger.info(`User registered successfully (${req.ip})`);
|
logger.info(`User registered successfully (${req.ip})`);
|
||||||
return res
|
return res
|
||||||
.type('application/json')
|
.type("application/json")
|
||||||
.status(201)
|
.status(201)
|
||||||
.json(RegisterServiceResult);
|
.json(RegisterServiceResult);
|
||||||
}
|
}
|
||||||
@ -88,366 +93,340 @@ async function registerUser(req: Request, res: Response): Promise<unknown> {
|
|||||||
*
|
*
|
||||||
* @return {Promise<void>} A promise that resolves when the user is logged in or rejects with an error.
|
* @return {Promise<void>} A promise that resolves when the user is logged in or rejects with an error.
|
||||||
*/
|
*/
|
||||||
async function loginUser(req: Request, res: Response): Promise<void> {
|
async function loginUser(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
): Promise<void> {
|
||||||
const body = req.body;
|
const body = req.body;
|
||||||
if (!body) {
|
if (!body) {
|
||||||
res
|
res.type("application/json").status(400).json({
|
||||||
.type('application/json')
|
error: "Invalid input data",
|
||||||
.status(400)
|
});
|
||||||
.json({ error: 'Invalid input data' });
|
|
||||||
}
|
}
|
||||||
if (!body.password || !body.username) {
|
if (!body.password || !body.username) {
|
||||||
logger.warn(`Field(s) missing (${req.ip})`);
|
logger.warn(`Field(s) missing (${req.ip})`);
|
||||||
res
|
res.type("application/json").status(400).json({
|
||||||
.type('application/json')
|
error: "Field(s) missing",
|
||||||
.status(400)
|
});
|
||||||
.json({ error: 'Field(s) missing' });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const loginData = {
|
const loginData = {
|
||||||
username: `${body.username}`,
|
username: `${body.username}`,
|
||||||
password: `${body.password}`
|
password: `${body.password}`,
|
||||||
};
|
};
|
||||||
console.log(body)
|
console.log(body);
|
||||||
const LoginServiceResult = await UserService.login(loginData);
|
const LoginServiceResult = await UserService.login(loginData);
|
||||||
console.log(LoginServiceResult)
|
console.log(LoginServiceResult);
|
||||||
|
|
||||||
if (LoginServiceResult.error === "userNotFound") {
|
if (LoginServiceResult.error === "userNotFound") {
|
||||||
console.log('POOL')
|
console.log("POOL");
|
||||||
res
|
res.type("application/json").status(404).json({
|
||||||
.type('application/json')
|
|
||||||
.status(404)
|
|
||||||
.json({
|
|
||||||
error: LoginServiceResult.error,
|
error: LoginServiceResult.error,
|
||||||
message: "User not found."
|
message: "User not found.",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (LoginServiceResult.error === "invalidPassword") {
|
if (LoginServiceResult.error === "invalidPassword") {
|
||||||
res
|
res.type("application/json").status(401).json({
|
||||||
.type('application/json')
|
|
||||||
.status(401)
|
|
||||||
.json({
|
|
||||||
error: LoginServiceResult.error,
|
error: LoginServiceResult.error,
|
||||||
message: "Invalid password."
|
message: "Invalid password.",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
.type('application/json')
|
.type("application/json")
|
||||||
.status(200)
|
.status(200)
|
||||||
.json(LoginServiceResult);
|
.json(LoginServiceResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getAllUsers(req: Request, res: Response) {
|
async function getAllUsers(req: Request, res: Response) {
|
||||||
const authHeader = req.headers.authorization;
|
const authHeader = req.headers.authorization;
|
||||||
const bearerToken = authHeader?.split(' ')[1];
|
const bearerToken = authHeader?.split(" ")[1];
|
||||||
if (!bearerToken) {
|
if (!bearerToken) {
|
||||||
logger.warn(`Bearer token not provided (${req.ip})`);
|
logger.warn(`Bearer token not provided (${req.ip})`);
|
||||||
return res
|
return res.type("application/json").status(401).json({
|
||||||
.type('application/json')
|
error: "Unauthorized",
|
||||||
.status(401)
|
});
|
||||||
.json({ error: 'Unauthorized' });
|
|
||||||
}
|
}
|
||||||
const payload = await JwtService.verify(bearerToken);
|
const payload = await JwtService.verify(bearerToken);
|
||||||
if (!payload) {
|
if (!payload) {
|
||||||
logger.warn(`Unauthorized access attempt (${req.ip})`);
|
logger.warn(`Unauthorized access attempt (${req.ip})`);
|
||||||
return res
|
return res.type("application/json").status(401).json({
|
||||||
.type('application/json')
|
error: "Unauthorized",
|
||||||
.status(401)
|
});
|
||||||
.json({ error: 'Unauthorized' });
|
|
||||||
}
|
}
|
||||||
const sourceUser = await UserService.getFromId(payload.sub)
|
const sourceUser = await UserService.getFromId(payload.sub);
|
||||||
if (!sourceUser) {
|
if (!sourceUser) {
|
||||||
return res
|
return res.type("application/json").status(404).json({
|
||||||
.type('application/json')
|
error: "You dont exist anymore",
|
||||||
.status(404)
|
});
|
||||||
.json({ error: 'You dont exist anymore' });
|
|
||||||
}
|
}
|
||||||
if (!sourceUser.is_admin) {
|
if (!sourceUser.is_admin) {
|
||||||
return res
|
return res.type("application/json").status(403).json({
|
||||||
.type('application/json')
|
error: "Unauthorized",
|
||||||
.status(403)
|
});
|
||||||
.json({ error: 'Unauthorized' });
|
|
||||||
}
|
}
|
||||||
const AllUserResponse = await UserService.getAll()
|
const AllUserResponse = await UserService.getAll();
|
||||||
if (!AllUserResponse.users) {
|
if (!AllUserResponse.users) {
|
||||||
return res
|
return res.type("application/json").status(500).json({
|
||||||
.type('application/json')
|
error: "Internal server error",
|
||||||
.status(500)
|
});
|
||||||
.json({ error: 'Internal server error' });
|
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
.type('application/json')
|
.type("application/json")
|
||||||
.status(200)
|
.status(200)
|
||||||
.json(AllUserResponse);
|
.json(AllUserResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getUser(req: Request, res: Response) {
|
async function getUser(req: Request, res: Response) {
|
||||||
const authHeader = req.headers.authorization;
|
const authHeader = req.headers.authorization;
|
||||||
const bearerToken = authHeader?.split(' ')[1];
|
const bearerToken = authHeader?.split(" ")[1];
|
||||||
if (!bearerToken) {
|
if (!bearerToken) {
|
||||||
logger.warn(`Bearer token not provided (${req.ip})`);
|
logger.warn(`Bearer token not provided (${req.ip})`);
|
||||||
return res
|
return res.type("application/json").status(401).json({
|
||||||
.type('application/json')
|
error: "Unauthorized",
|
||||||
.status(401)
|
});
|
||||||
.json({ error: 'Unauthorized' });
|
|
||||||
}
|
}
|
||||||
const payload = await JwtService.verify(bearerToken);
|
const payload = await JwtService.verify(bearerToken);
|
||||||
if (!payload) {
|
if (!payload) {
|
||||||
logger.warn(`Unauthorized access attempt (${req.ip})`);
|
logger.warn(`Unauthorized access attempt (${req.ip})`);
|
||||||
return res
|
return res.type("application/json").status(401).json({
|
||||||
.type('application/json')
|
error: "Unauthorized",
|
||||||
.status(401)
|
});
|
||||||
.json({ error: 'Unauthorized' });
|
|
||||||
}
|
}
|
||||||
const sourceUser = await UserService.getFromId(payload.sub)
|
const sourceUser = await UserService.getFromId(payload.sub);
|
||||||
if (!sourceUser) {
|
if (!sourceUser) {
|
||||||
return res
|
return res.type("application/json").status(404).json({
|
||||||
.type('application/json')
|
error: "You dont exist anymore",
|
||||||
.status(404)
|
});
|
||||||
.json({ error: 'You dont exist anymore' });
|
|
||||||
}
|
}
|
||||||
if (!sourceUser.is_admin) {
|
if (!sourceUser.is_admin) {
|
||||||
return res
|
return res.type("application/json").status(403).json({
|
||||||
.type('application/json')
|
error: "Unauthorized",
|
||||||
.status(403)
|
});
|
||||||
.json({ error: 'Unauthorized' });
|
|
||||||
}
|
}
|
||||||
const userId = req.params["id"];
|
const userId = req.params["id"];
|
||||||
const dbUser = await UserService.getFromId(userId);
|
const dbUser = await UserService.getFromId(userId);
|
||||||
if (!dbUser) {
|
if (!dbUser) {
|
||||||
logger.warn(`User not found (${req.ip})`);
|
logger.warn(`User not found (${req.ip})`);
|
||||||
return res
|
return res.type("application/json").status(404).json({
|
||||||
.type('application/json')
|
error: "User not found",
|
||||||
.status(404)
|
});
|
||||||
.json({ error: 'User not found' });
|
|
||||||
}
|
}
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
delete dbUser.passwordHash
|
delete dbUser.passwordHash;
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
delete dbUser._id
|
delete dbUser._id;
|
||||||
return res
|
return res.type("application/json").status(200).json(dbUser);
|
||||||
.type('application/json')
|
|
||||||
.status(200)
|
|
||||||
.json(dbUser);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//FEAT - Implement re-auth by current password in case of password change
|
//FEAT - Implement re-auth by current password in case of password change
|
||||||
async function editUser(req: Request, res: Response) {
|
async function editUser(req: Request, res: Response) {
|
||||||
const body: IReqEditUserData | null = req.body;
|
const body: IReqEditUserData | null = req.body;
|
||||||
if (!body) {
|
if (!body) {
|
||||||
return res
|
return res.type("application/json").status(400).json({
|
||||||
.type('application/json')
|
error: "Field(s) missing",
|
||||||
.status(400)
|
});
|
||||||
.json({ error: 'Field(s) missing' });
|
|
||||||
}
|
}
|
||||||
const authHeader = req.headers.authorization;
|
const authHeader = req.headers.authorization;
|
||||||
const bearerToken = authHeader?.split(' ')[1];
|
const bearerToken = authHeader?.split(" ")[1];
|
||||||
if (!bearerToken) {
|
if (!bearerToken) {
|
||||||
logger.warn(`Bearer token not provided (${req.ip})`);
|
logger.warn(`Bearer token not provided (${req.ip})`);
|
||||||
return res
|
return res.type("application/json").status(401).json({
|
||||||
.type('application/json')
|
error: "Unauthorized",
|
||||||
.status(401)
|
});
|
||||||
.json({ error: 'Unauthorized' });
|
|
||||||
}
|
}
|
||||||
const payload = await JwtService.verify(bearerToken);
|
const payload = await JwtService.verify(bearerToken);
|
||||||
if (!payload) {
|
if (!payload) {
|
||||||
logger.warn(`Unauthorized access attempt (${req.ip})`);
|
logger.warn(`Unauthorized access attempt (${req.ip})`);
|
||||||
return res
|
return res.type("application/json").status(401).json({
|
||||||
.type('application/json')
|
error: "Unauthorized",
|
||||||
.status(401)
|
});
|
||||||
.json({ error: 'Unauthorized' });
|
|
||||||
}
|
}
|
||||||
const sourceUser = await UserService.getFromId(payload.sub)
|
const sourceUser = await UserService.getFromId(payload.sub);
|
||||||
|
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
const targetUserId = req.params.id || payload.sub
|
const targetUserId = req.params.id || payload.sub;
|
||||||
console.log(targetUserId)
|
console.log(targetUserId);
|
||||||
|
|
||||||
if (!sourceUser) {
|
if (!sourceUser) {
|
||||||
logger.warn(`Unauthorized access attempt (${req.ip})`);
|
logger.warn(`Unauthorized access attempt (${req.ip})`);
|
||||||
return res
|
return res.type("application/json").status(404).json({
|
||||||
.type('application/json')
|
error: "You dont exist anymore",
|
||||||
.status(404)
|
});
|
||||||
.json({ error: 'You dont exist anymore' });
|
|
||||||
}
|
}
|
||||||
if (sourceUser.is_admin || sourceUser.id === payload.sub) {
|
if (sourceUser.is_admin || sourceUser.id === payload.sub) {
|
||||||
if (sourceUser.is_admin) {
|
if (sourceUser.is_admin) {
|
||||||
logger.info(`EDIT :> Source user is an admin (${sourceUser.firstname} ${sourceUser.lastname})`)
|
logger.info(
|
||||||
|
`EDIT :> Source user is an admin (${sourceUser.firstname} ${sourceUser.lastname})`,
|
||||||
|
);
|
||||||
} else {
|
} 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
|
//TODO Interface
|
||||||
const modifiedData = {
|
const modifiedData = {};
|
||||||
}
|
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
if (body.firstName) modifiedData.firstName = `${body.firstName}`;
|
if (body.firstName)
|
||||||
|
modifiedData.firstName = `${body.firstName}`;
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
if (body.lastName) modifiedData.lastName = `${body.lastName}`;
|
if (body.lastName)
|
||||||
|
modifiedData.lastName = `${body.lastName}`;
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
if (body.displayName) modifiedData.displayName = `${body.displayName}`;
|
if (body.displayName)
|
||||||
|
modifiedData.displayName = `${body.displayName}`;
|
||||||
//TODO Case handled with hashing by the service.
|
//TODO Case handled with hashing by the service.
|
||||||
//if (body.password) modifiedData.password = `${body.password}`;
|
//if (body.password) modifiedData.password = `${body.password}`;
|
||||||
|
|
||||||
//Call service
|
//Call service
|
||||||
const EditUserServiceResult = await UserService.edit(`${targetUserId}`, modifiedData);
|
const EditUserServiceResult = await UserService.edit(
|
||||||
if (EditUserServiceResult.error === 'userNotFound') {
|
`${targetUserId}`,
|
||||||
|
modifiedData,
|
||||||
|
);
|
||||||
|
if (EditUserServiceResult.error === "userNotFound") {
|
||||||
logger.warn(`User not found (${req.ip})`);
|
logger.warn(`User not found (${req.ip})`);
|
||||||
return res
|
return res.type("application/json").status(404).json({
|
||||||
.type('application/json')
|
error: "User not found",
|
||||||
.status(404)
|
});
|
||||||
.json({ error: 'User not found' });
|
|
||||||
}
|
}
|
||||||
if (EditUserServiceResult.error !== 'none') {
|
if (EditUserServiceResult.error !== "none") {
|
||||||
logger.error(`Error occurred during user edit (${req.ip})`);
|
logger.error(
|
||||||
return res
|
`Error occurred during user edit (${req.ip})`,
|
||||||
.type('application/json')
|
);
|
||||||
.status(500)
|
return res.type("application/json").status(500).json({
|
||||||
.json({ error: 'Internal server error' });
|
error: "Internal server error",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
.type('application/json')
|
.type("application/json")
|
||||||
.status(200)
|
.status(200)
|
||||||
.json(EditUserServiceResult);
|
.json(EditUserServiceResult);
|
||||||
}
|
}
|
||||||
//Not itself or
|
//Not itself or
|
||||||
logger.warn(`Unauthorized access attempt, not self or admin (${req.ip})`);
|
logger.warn(
|
||||||
return res
|
`Unauthorized access attempt, not self or admin (${req.ip})`,
|
||||||
.type('application/json')
|
);
|
||||||
.status(403)
|
return res.type("application/json").status(403).json({
|
||||||
.json({ error: 'Unauthorized' });
|
error: "Unauthorized",
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteUser(req: Request, res: Response): Promise<Response> {
|
async function deleteUser(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
): Promise<Response> {
|
||||||
const authHeader = req.headers.authorization;
|
const authHeader = req.headers.authorization;
|
||||||
const bearerToken = authHeader?.split(' ')[1];
|
const bearerToken = authHeader?.split(" ")[1];
|
||||||
if (!bearerToken) {
|
if (!bearerToken) {
|
||||||
logger.warn(`Bearer token not provided (${req.ip})`);
|
logger.warn(`Bearer token not provided (${req.ip})`);
|
||||||
return res
|
return res.type("application/json").status(401).json({
|
||||||
.type('application/json')
|
error: "Unauthorized",
|
||||||
.status(401)
|
});
|
||||||
.json({ error: 'Unauthorized' });
|
|
||||||
}
|
}
|
||||||
const payload = await JwtService.verify(bearerToken);
|
const payload = await JwtService.verify(bearerToken);
|
||||||
|
|
||||||
if (!payload) {
|
if (!payload) {
|
||||||
logger.warn(`Invalid token (${req.ip})`);
|
logger.warn(`Invalid token (${req.ip})`);
|
||||||
return res
|
return res.type("application/json").status(401).json({
|
||||||
.type('application/json')
|
error: "Invalid token",
|
||||||
.status(401)
|
});
|
||||||
.json({ error: 'Invalid token' });
|
|
||||||
}
|
}
|
||||||
const sourceUser = await UserService.getFromId(payload?.sub)
|
const sourceUser = await UserService.getFromId(payload?.sub);
|
||||||
const targetUserId = req.params["id"]
|
const targetUserId = req.params["id"];
|
||||||
if (!sourceUser) {
|
if (!sourceUser) {
|
||||||
logger.warn(`Unauthorized access attempt (${req.ip})`);
|
logger.warn(`Unauthorized access attempt (${req.ip})`);
|
||||||
return res
|
return res.type("application/json").status(404).json({
|
||||||
.type('application/json')
|
error: "You dont exist anymore",
|
||||||
.status(404)
|
});
|
||||||
.json({ error: 'You dont exist anymore' });
|
|
||||||
}
|
}
|
||||||
if (sourceUser.is_admin || sourceUser.id === payload.sub) {
|
if (sourceUser.is_admin || sourceUser.id === payload.sub) {
|
||||||
const deleteUserServiceResult = await UserService.delete(`${targetUserId}`);
|
const deleteUserServiceResult = await UserService.delete(
|
||||||
|
`${targetUserId}`,
|
||||||
|
);
|
||||||
if (!deleteUserServiceResult) {
|
if (!deleteUserServiceResult) {
|
||||||
logger.error(`Error occurred during user delete (${req.ip})`);
|
logger.error(
|
||||||
return res
|
`Error occurred during user delete (${req.ip})`,
|
||||||
.type('application/json')
|
);
|
||||||
.status(500)
|
return res.type("application/json").status(500).json({
|
||||||
.json({ error: 'Internal server error' });
|
error: "Internal server error",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return res.type("application/json").status(200).json({
|
||||||
.type('application/json')
|
message: "User deleted successfully",
|
||||||
.status(200)
|
});
|
||||||
.json({ message: 'User deleted successfully' });
|
|
||||||
}
|
}
|
||||||
return res
|
return res.type("application/json").status(403).json({
|
||||||
.type('application/json')
|
error: "Unauthorized",
|
||||||
.status(403)
|
});
|
||||||
.json({ error: 'Unauthorized' });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteSelf(req: Request, res: Response) {
|
async function deleteSelf(req: Request, res: Response) {
|
||||||
const authHeader = req.headers.authorization;
|
const authHeader = req.headers.authorization;
|
||||||
const bearerToken = authHeader?.split(' ')[1];
|
const bearerToken = authHeader?.split(" ")[1];
|
||||||
if (!bearerToken) {
|
if (!bearerToken) {
|
||||||
logger.warn(`Bearer token not provided (${req.ip})`);
|
logger.warn(`Bearer token not provided (${req.ip})`);
|
||||||
return res
|
return res.type("application/json").status(401).json({
|
||||||
.type('application/json')
|
error: "Unauthorized",
|
||||||
.status(401)
|
});
|
||||||
.json({ error: 'Unauthorized' });
|
|
||||||
}
|
}
|
||||||
const payload = await JwtService.verify(bearerToken);
|
const payload = await JwtService.verify(bearerToken);
|
||||||
if (!payload) {
|
if (!payload) {
|
||||||
logger.warn(`Unauthorized access attempt (${req.ip})`);
|
logger.warn(`Unauthorized access attempt (${req.ip})`);
|
||||||
return res
|
return res.type("application/json").status(401).json({
|
||||||
.type('application/json')
|
error: "Unauthorized",
|
||||||
.status(401)
|
});
|
||||||
.json({ error: 'Unauthorized' });
|
|
||||||
}
|
}
|
||||||
const sourceUser = await UserService.getFromId(payload.sub)
|
const sourceUser = await UserService.getFromId(payload.sub);
|
||||||
if (!sourceUser) {
|
if (!sourceUser) {
|
||||||
return res
|
return res.type("application/json").status(404).json({
|
||||||
.type('application/json')
|
error: "You dont exist anymore",
|
||||||
.status(404)
|
});
|
||||||
.json({ error: 'You dont exist anymore' });
|
|
||||||
}
|
}
|
||||||
if (sourceUser.id !== req.params["id"]) {
|
if (sourceUser.id !== req.params["id"]) {
|
||||||
return res
|
return res.type("application/json").status(403).json({
|
||||||
.type('application/json')
|
error: "Unauthorized",
|
||||||
.status(403)
|
});
|
||||||
.json({ error: 'Unauthorized' });
|
|
||||||
}
|
}
|
||||||
const deleteResult = await UserService.delete(sourceUser.id);
|
const deleteResult = await UserService.delete(sourceUser.id);
|
||||||
if (!deleteResult) {
|
if (!deleteResult) {
|
||||||
logger.error(`Failed to delete user (${req.ip})`);
|
logger.error(`Failed to delete user (${req.ip})`);
|
||||||
return res
|
return res.type("application/json").status(500).json({
|
||||||
.type('application/json')
|
error: "Failed to delete user",
|
||||||
.status(500)
|
});
|
||||||
.json({ error: 'Failed to delete user' });
|
|
||||||
}
|
}
|
||||||
return res
|
return res.type("application/json").status(200).json({
|
||||||
.type('application/json')
|
message: "User deleted successfully",
|
||||||
.status(200)
|
});
|
||||||
.json({ message: 'User deleted successfully' });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getSelf(req: Request, res: Response) {
|
async function getSelf(req: Request, res: Response) {
|
||||||
const authHeader = req.headers.authorization;
|
const authHeader = req.headers.authorization;
|
||||||
const bearerToken = authHeader?.split(' ')[1];
|
const bearerToken = authHeader?.split(" ")[1];
|
||||||
if (!bearerToken) {
|
if (!bearerToken) {
|
||||||
return res
|
return res.type("application/json").status(401).json({
|
||||||
.type('application/json')
|
error: "Unauthorized",
|
||||||
.status(401)
|
});
|
||||||
.json({ error: 'Unauthorized' });
|
|
||||||
}
|
}
|
||||||
const payload = await JwtService.verify(bearerToken);
|
const payload = await JwtService.verify(bearerToken);
|
||||||
if (!payload) {
|
if (!payload) {
|
||||||
logger.warn(`Unauthorized access attempt (${req.ip})`);
|
logger.warn(`Unauthorized access attempt (${req.ip})`);
|
||||||
return res
|
return res.type("application/json").status(401).json({
|
||||||
.type('application/json')
|
error: "Unauthorized",
|
||||||
.status(401)
|
});
|
||||||
.json({ error: 'Unauthorized' });
|
|
||||||
}
|
}
|
||||||
const dbUser = await UserService.getFromId(payload.sub)
|
const dbUser = await UserService.getFromId(payload.sub);
|
||||||
if (!dbUser) {
|
if (!dbUser) {
|
||||||
return res
|
return res.type("application/json").status(404).json({
|
||||||
.type('application/json')
|
error: "User not found",
|
||||||
.status(404)
|
});
|
||||||
.json({ error: 'User not found' });
|
|
||||||
}
|
}
|
||||||
return res
|
return res.type("application/json").status(200).json({
|
||||||
.type('application/json')
|
|
||||||
.status(200)
|
|
||||||
.json({
|
|
||||||
id: dbUser.id,
|
id: dbUser.id,
|
||||||
username: dbUser.username,
|
username: dbUser.username,
|
||||||
firstName: dbUser.firstname,
|
firstName: dbUser.firstname,
|
||||||
lastName: dbUser.firstname,
|
lastName: dbUser.firstname,
|
||||||
isAdmin: dbUser.firstname
|
isAdmin: dbUser.firstname,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -459,7 +438,7 @@ const AuthController = {
|
|||||||
editUser,
|
editUser,
|
||||||
deleteUser,
|
deleteUser,
|
||||||
deleteSelf,
|
deleteSelf,
|
||||||
getSelf
|
getSelf,
|
||||||
}
|
};
|
||||||
|
|
||||||
export default AuthController;
|
export default AuthController;
|
@ -1,13 +1,13 @@
|
|||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { Logger } from "tslog";
|
import { Logger } from "tslog";
|
||||||
|
|
||||||
|
|
||||||
import type IDbBrand from "@interfaces/database/IDbBrand";
|
import type IDbBrand from "@interfaces/database/IDbBrand";
|
||||||
import BrandService from "@services/brand.service";
|
import BrandService from "@services/brand.service";
|
||||||
//import {body} from "express-validator";
|
//import {body} from "express-validator";
|
||||||
|
|
||||||
|
const logger = new Logger({
|
||||||
const logger = new Logger({ name: "BrandController" });
|
name: "BrandController",
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new brand.
|
* 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.
|
* @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<Response> {
|
async function createBrand(
|
||||||
const body: IDbBrand = req.body
|
req: Request,
|
||||||
const doesExist = await BrandService.getBySlug(`${body.slug_name}`)
|
res: Response,
|
||||||
|
): Promise<Response> {
|
||||||
|
const body: IDbBrand = req.body;
|
||||||
|
const doesExist = await BrandService.getBySlug(
|
||||||
|
`${body.slug_name}`,
|
||||||
|
);
|
||||||
if (doesExist) {
|
if (doesExist) {
|
||||||
logger.error("Brand already exists");
|
logger.error("Brand already exists");
|
||||||
return res.status(400).json({ error: "Brand already exists" });
|
return res.status(400).json({
|
||||||
|
error: "Brand already exists",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const createResult = await BrandService.create({
|
const createResult = await BrandService.create({
|
||||||
slug_name: `${body.slug_name}`,
|
slug_name: `${body.slug_name}`,
|
||||||
display_name: `${body.display_name}`,
|
display_name: `${body.display_name}`,
|
||||||
image_blob: `${body.image_blob}`
|
image_blob: `${body.image_blob}`,
|
||||||
})
|
});
|
||||||
if (!createResult) {
|
if (!createResult) {
|
||||||
logger.error("Failed to create brand");
|
logger.error("Failed to create brand");
|
||||||
return res.status(500).json({ error: "Failed to create brand" });
|
return res.status(500).json({
|
||||||
|
error: "Failed to create brand",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
logger.info(`Brand created successfully ! (${body.slug_name})`)
|
logger.info(
|
||||||
return res.status(201).json({ message: "Brand created successfully" });
|
`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<Response> {
|
|||||||
* @param {Response} res - The HTTP response object.
|
* @param {Response} res - The HTTP response object.
|
||||||
* @return {Promise<Response>} A promise that resolves with the HTTP response.
|
* @return {Promise<Response>} A promise that resolves with the HTTP response.
|
||||||
*/
|
*/
|
||||||
async function updateBrand(req: Request, res: Response): Promise<Response> {
|
async function updateBrand(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
): Promise<Response> {
|
||||||
const body: IDbBrand = req.body;
|
const body: IDbBrand = req.body;
|
||||||
const brandSlug = req.params["brandSlug"];
|
const brandSlug = req.params["brandSlug"];
|
||||||
if (!brandSlug) {
|
if (!brandSlug) {
|
||||||
logger.error("Brand slug is missing");
|
logger.error("Brand slug is missing");
|
||||||
return res.status(400).json({ error: "Brand slug is missing" });
|
return res.status(400).json({
|
||||||
|
error: "Brand slug is missing",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const doesExist = await BrandService.getBySlug(brandSlug);
|
const doesExist = await BrandService.getBySlug(brandSlug);
|
||||||
if (!doesExist) {
|
if (!doesExist) {
|
||||||
logger.error("Brand not found");
|
logger.error("Brand not found");
|
||||||
return res.status(404).json({ error: "Brand not found" });
|
return res.status(404).json({
|
||||||
|
error: "Brand not found",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const updateResult = await BrandService.update({
|
const updateResult = await BrandService.update({
|
||||||
slug_name: `${body.slug_name}`,
|
slug_name: `${body.slug_name}`,
|
||||||
display_name: `${body.display_name}`,
|
display_name: `${body.display_name}`,
|
||||||
image_blob: `${body.image_blob}`
|
image_blob: `${body.image_blob}`,
|
||||||
});
|
});
|
||||||
if (!updateResult) {
|
if (!updateResult) {
|
||||||
logger.error("Failed to update brand");
|
logger.error("Failed to update brand");
|
||||||
return res.status(500).json({ error: "Failed to update brand" });
|
return res.status(500).json({
|
||||||
|
error: "Failed to update brand",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
logger.info(`Brand updated successfully ! (${brandSlug})`);
|
logger.info(`Brand updated successfully ! (${brandSlug})`);
|
||||||
return res.status(200).json({ message: "Brand updated successfully" });
|
return res.status(200).json({
|
||||||
|
message: "Brand updated successfully",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,16 +100,23 @@ async function updateBrand(req: Request, res: Response): Promise<Response> {
|
|||||||
* @param {Response} res - The response object to send the result.
|
* @param {Response} res - The response object to send the result.
|
||||||
* @returns {Promise<Response>} - A promise that resolves to the response with the retrieved brand.
|
* @returns {Promise<Response>} - A promise that resolves to the response with the retrieved brand.
|
||||||
*/
|
*/
|
||||||
async function getBySlugBrand(req: Request, res: Response): Promise<Response> {
|
async function getBySlugBrand(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
): Promise<Response> {
|
||||||
const brandSlug = req.params["brandSlug"];
|
const brandSlug = req.params["brandSlug"];
|
||||||
if (!brandSlug) {
|
if (!brandSlug) {
|
||||||
logger.error("Brand slug is missing");
|
logger.error("Brand slug is missing");
|
||||||
return res.status(400).json({ error: "Brand slug is missing" });
|
return res.status(400).json({
|
||||||
|
error: "Brand slug is missing",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const brand = await BrandService.getBySlug(brandSlug);
|
const brand = await BrandService.getBySlug(brandSlug);
|
||||||
if (!brand) {
|
if (!brand) {
|
||||||
logger.error("Brand not found");
|
logger.error("Brand not found");
|
||||||
return res.status(404).json({ error: "Brand not found" });
|
return res.status(404).json({
|
||||||
|
error: "Brand not found",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
logger.info(`Brand retrieved successfully ! (${brandSlug})`);
|
logger.info(`Brand retrieved successfully ! (${brandSlug})`);
|
||||||
return res.status(200).json(brand);
|
return res.status(200).json(brand);
|
||||||
@ -98,17 +129,22 @@ async function getBySlugBrand(req: Request, res: Response): Promise<Response> {
|
|||||||
* @param {Response} res - The response object.
|
* @param {Response} res - The response object.
|
||||||
* @returns {Promise<Response>} - A promise with the response object.
|
* @returns {Promise<Response>} - A promise with the response object.
|
||||||
*/
|
*/
|
||||||
async function getAllBrand(_req: Request, res: Response): Promise<Response> {
|
async function getAllBrand(
|
||||||
|
_req: Request,
|
||||||
|
res: Response,
|
||||||
|
): Promise<Response> {
|
||||||
const brands = await BrandService.getAll();
|
const brands = await BrandService.getAll();
|
||||||
if (!brands) {
|
if (!brands) {
|
||||||
logger.error("Failed to retrieve brands");
|
logger.error("Failed to retrieve brands");
|
||||||
return res.status(500).json({ error: "Failed to retrieve brands" });
|
return res.status(500).json({
|
||||||
|
error: "Failed to retrieve brands",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
logger.info("Brands retrieved successfully !");
|
logger.info("Brands retrieved successfully !");
|
||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
uat: Date.now(),
|
uat: Date.now(),
|
||||||
brands: brands,
|
brands: brands,
|
||||||
total: brands.length
|
total: brands.length,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,25 +156,36 @@ async function getAllBrand(_req: Request, res: Response): Promise<Response> {
|
|||||||
* @param {Response} res - The response object.
|
* @param {Response} res - The response object.
|
||||||
* @returns {Promise<Response>} - The response object indicating the success or failure of the delete operation.
|
* @returns {Promise<Response>} - The response object indicating the success or failure of the delete operation.
|
||||||
*/
|
*/
|
||||||
async function deleteBrand(req: Request, res: Response): Promise<Response> {
|
async function deleteBrand(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
): Promise<Response> {
|
||||||
const brandSlug = req.params["brandSlug"];
|
const brandSlug = req.params["brandSlug"];
|
||||||
if (!brandSlug) {
|
if (!brandSlug) {
|
||||||
logger.error("Brand slug is missing");
|
logger.error("Brand slug is missing");
|
||||||
return res.status(400).json({ error: "Brand slug is missing" });
|
return res.status(400).json({
|
||||||
|
error: "Brand slug is missing",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
//TODO verify if models linked to brand
|
//TODO verify if models linked to brand
|
||||||
const doesExist = await BrandService.getBySlug(brandSlug);
|
const doesExist = await BrandService.getBySlug(brandSlug);
|
||||||
if (!doesExist) {
|
if (!doesExist) {
|
||||||
logger.error("Brand not found");
|
logger.error("Brand not found");
|
||||||
return res.status(404).json({ error: "Brand not found" });
|
return res.status(404).json({
|
||||||
|
error: "Brand not found",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const deleteResult = await BrandService.delete(brandSlug);
|
const deleteResult = await BrandService.delete(brandSlug);
|
||||||
if (!deleteResult) {
|
if (!deleteResult) {
|
||||||
logger.error("Failed to delete brand");
|
logger.error("Failed to delete brand");
|
||||||
return res.status(500).json({ error: "Failed to delete brand" });
|
return res.status(500).json({
|
||||||
|
error: "Failed to delete brand",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
logger.info(`Brand deleted successfully ! (${brandSlug})`);
|
logger.info(`Brand deleted successfully ! (${brandSlug})`);
|
||||||
return res.status(200).json({ message: "Brand deleted successfully" });
|
return res.status(200).json({
|
||||||
|
message: "Brand deleted successfully",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO get models of the brand
|
//TODO get models of the brand
|
||||||
@ -149,6 +196,6 @@ const BrandController = {
|
|||||||
getBySlug: getBySlugBrand,
|
getBySlug: getBySlugBrand,
|
||||||
getAll: getAllBrand,
|
getAll: getAllBrand,
|
||||||
delete: deleteBrand,
|
delete: deleteBrand,
|
||||||
}
|
};
|
||||||
|
|
||||||
export default BrandController;
|
export default BrandController;
|
@ -1,12 +1,12 @@
|
|||||||
import type {Request, Response} from "express";
|
|
||||||
import {Logger} from "tslog";
|
|
||||||
import type IDbCategory from "@interfaces/database/IDbCategory";
|
import type IDbCategory from "@interfaces/database/IDbCategory";
|
||||||
import CategoryService from "@services/category.service";
|
import CategoryService from "@services/category.service";
|
||||||
|
import type { Request, Response } from "express";
|
||||||
|
import { Logger } from "tslog";
|
||||||
//import {validationResult} from "express-validator";
|
//import {validationResult} from "express-validator";
|
||||||
|
|
||||||
|
const logger = new Logger({
|
||||||
const logger = new Logger({ name: "CategoryController" });
|
name: "CategoryController",
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new category.
|
* 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.
|
* @param {Response} res - The response object to send back to the client.
|
||||||
* @returns {Promise<Response>} The response object indicating the outcome of the category creation.
|
* @returns {Promise<Response>} The response object indicating the outcome of the category creation.
|
||||||
*/
|
*/
|
||||||
async function createCategory(req: Request, res: Response): Promise<Response> {
|
async function createCategory(
|
||||||
const body: IDbCategory = req.body
|
req: Request,
|
||||||
const doesExist = await CategoryService.getBySlug(`${body.slug_name}`)
|
res: Response,
|
||||||
|
): Promise<Response> {
|
||||||
|
const body: IDbCategory = req.body;
|
||||||
|
const doesExist = await CategoryService.getBySlug(
|
||||||
|
`${body.slug_name}`,
|
||||||
|
);
|
||||||
if (doesExist) {
|
if (doesExist) {
|
||||||
logger.error("Category already exists");
|
logger.error("Category already exists");
|
||||||
return res.status(400).json({ error: "Category already exists" });
|
return res.status(400).json({
|
||||||
|
error: "Category already exists",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const createResult = await CategoryService.create({
|
const createResult = await CategoryService.create({
|
||||||
display_name: `${body.display_name}`,
|
display_name: `${body.display_name}`,
|
||||||
slug_name: `${body.slug_name}`
|
slug_name: `${body.slug_name}`,
|
||||||
})
|
});
|
||||||
if (!createResult) {
|
if (!createResult) {
|
||||||
logger.error("Failed to create category");
|
logger.error("Failed to create category");
|
||||||
return res.status(500).json({ error: "Failed to create category" });
|
return res.status(500).json({
|
||||||
|
error: "Failed to create category",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
logger.info(`Category created successfully ! (${body.slug_name})`)
|
logger.info(
|
||||||
return res.status(201).json({ message: "Category created successfully" });
|
`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<Response> {
|
|||||||
*
|
*
|
||||||
* @return {Promise<Response>} - A promise that will be resolved with the result of the update operation.
|
* @return {Promise<Response>} - A promise that will be resolved with the result of the update operation.
|
||||||
*/
|
*/
|
||||||
async function updateCategory(req: Request, res:Response): Promise<Response> {
|
async function updateCategory(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
): Promise<Response> {
|
||||||
const body: IDbCategory = req.body;
|
const body: IDbCategory = req.body;
|
||||||
const categoryId = req.params["categorySlug"];
|
const categoryId = req.params["categorySlug"];
|
||||||
if (!categoryId) {
|
if (!categoryId) {
|
||||||
logger.error("Category slug is missing");
|
logger.error("Category slug is missing");
|
||||||
return res.status(400).json({ error: "Category slug is missing" });
|
return res.status(400).json({
|
||||||
|
error: "Category slug is missing",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const doesExist = await CategoryService.getById(`${categoryId}`)
|
const doesExist = await CategoryService.getById(
|
||||||
|
`${categoryId}`,
|
||||||
|
);
|
||||||
if (!doesExist || !doesExist.id) {
|
if (!doesExist || !doesExist.id) {
|
||||||
logger.error("Category not found");
|
logger.error("Category not found");
|
||||||
return res.status(404).json({ error: "Category not found" });
|
return res.status(404).json({
|
||||||
|
error: "Category not found",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const updateResult = await CategoryService.update({
|
const updateResult = await CategoryService.update({
|
||||||
id: doesExist.id,
|
id: doesExist.id,
|
||||||
slug_name: `${body.slug_name}`,
|
slug_name: `${body.slug_name}`,
|
||||||
display_name: `${body.display_name}`
|
display_name: `${body.display_name}`,
|
||||||
})
|
});
|
||||||
if (!updateResult) {
|
if (!updateResult) {
|
||||||
logger.error("Failed to update category");
|
logger.error("Failed to update category");
|
||||||
return res.status(500).json({ error: "Failed to update category" });
|
return res.status(500).json({
|
||||||
|
error: "Failed to update category",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
logger.info(`Category updated successfully! (${categoryId})`);
|
logger.info(`Category updated successfully! (${categoryId})`);
|
||||||
return res.status(200).json({ message: "Category updated successfully" });
|
return res.status(200).json({
|
||||||
|
message: "Category updated successfully",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -74,24 +100,41 @@ async function updateCategory(req: Request, res:Response): Promise<Response> {
|
|||||||
* @param {Response} res - The response object to send the result.
|
* @param {Response} res - The response object to send the result.
|
||||||
* @returns {Promise<Response>} A Promise that resolves to the response object.
|
* @returns {Promise<Response>} A Promise that resolves to the response object.
|
||||||
*/
|
*/
|
||||||
async function deleteCategory(req: Request, res: Response): Promise<Response> {
|
async function deleteCategory(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
): Promise<Response> {
|
||||||
const categorySlug = req.params["categorySlug"];
|
const categorySlug = req.params["categorySlug"];
|
||||||
if (!categorySlug) {
|
if (!categorySlug) {
|
||||||
logger.error("Category slug is missing");
|
logger.error("Category slug is missing");
|
||||||
return res.status(400).json({ error: "Category slug is missing" });
|
return res.status(400).json({
|
||||||
|
error: "Category slug is missing",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const doesExist = await CategoryService.getBySlug(`${categorySlug}`);
|
const doesExist = await CategoryService.getBySlug(
|
||||||
|
`${categorySlug}`,
|
||||||
|
);
|
||||||
if (!doesExist || !doesExist.id) {
|
if (!doesExist || !doesExist.id) {
|
||||||
logger.error("Category not found");
|
logger.error("Category not found");
|
||||||
return res.status(404).json({ error: "Category not found" });
|
return res.status(404).json({
|
||||||
|
error: "Category not found",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const deleteResult = await CategoryService.delete(`${doesExist.id}`);
|
const deleteResult = await CategoryService.delete(
|
||||||
|
`${doesExist.id}`,
|
||||||
|
);
|
||||||
if (!deleteResult) {
|
if (!deleteResult) {
|
||||||
logger.error("Failed to delete category");
|
logger.error("Failed to delete category");
|
||||||
return res.status(500).json({ error: "Failed to delete category" });
|
return res.status(500).json({
|
||||||
|
error: "Failed to delete category",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
logger.info(`Category deleted successfully! (${categorySlug})`);
|
logger.info(
|
||||||
return res.status(200).json({ message: "Category deleted successfully" });
|
`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<Response> {
|
|||||||
* @param {Response} res - The response object.
|
* @param {Response} res - The response object.
|
||||||
* @return {Promise<Response>} - A promise that resolves to the response object.
|
* @return {Promise<Response>} - A promise that resolves to the response object.
|
||||||
*/
|
*/
|
||||||
async function getAllCategory(_req: Request, res: Response): Promise<Response> {
|
async function getAllCategory(
|
||||||
|
_req: Request,
|
||||||
|
res: Response,
|
||||||
|
): Promise<Response> {
|
||||||
const categories = await CategoryService.getAll();
|
const categories = await CategoryService.getAll();
|
||||||
if (!categories) {
|
if (!categories) {
|
||||||
logger.error("Failed to get categories");
|
logger.error("Failed to get categories");
|
||||||
return res.status(500).json({ error: "Failed to get categories" });
|
return res.status(500).json({
|
||||||
|
error: "Failed to get categories",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
logger.info("Categories retrieved successfully");
|
logger.info("Categories retrieved successfully");
|
||||||
return res
|
return res.status(200).json({
|
||||||
.status(200)
|
|
||||||
.json({
|
|
||||||
iat: Date.now(),
|
iat: Date.now(),
|
||||||
categories: categories.map((category: IDbCategory) => ({
|
categories: categories.map((category: IDbCategory) => ({
|
||||||
id: category.id,
|
id: category.id,
|
||||||
display_name: category.display_name,
|
display_name: category.display_name,
|
||||||
slug_name: category.slug_name
|
slug_name: category.slug_name,
|
||||||
})),
|
})),
|
||||||
total: categories.length
|
total: categories.length,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,22 +175,33 @@ async function getAllCategory(_req: Request, res: Response): Promise<Response> {
|
|||||||
*
|
*
|
||||||
* @return {Promise<Response>} - The response with category data or error message
|
* @return {Promise<Response>} - The response with category data or error message
|
||||||
*/
|
*/
|
||||||
async function getBySlugCategory(req: Request, res:Response): Promise<Response> {
|
async function getBySlugCategory(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
): Promise<Response> {
|
||||||
const categorySlug = req.params["categorySlug"];
|
const categorySlug = req.params["categorySlug"];
|
||||||
if (!categorySlug) {
|
if (!categorySlug) {
|
||||||
logger.error("Category slug is missing");
|
logger.error("Category slug is missing");
|
||||||
return res.status(400).json({ error: "Category slug is missing" });
|
return res.status(400).json({
|
||||||
|
error: "Category slug is missing",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const category = await CategoryService.getBySlug(`${categorySlug}`);
|
const category = await CategoryService.getBySlug(
|
||||||
|
`${categorySlug}`,
|
||||||
|
);
|
||||||
if (!category || !category.id) {
|
if (!category || !category.id) {
|
||||||
logger.error("Category not found");
|
logger.error("Category not found");
|
||||||
return res.status(404).json({ error: "Category not found" });
|
return res.status(404).json({
|
||||||
|
error: "Category not found",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
logger.info(`Category retrieved successfully! (${categorySlug})`);
|
logger.info(
|
||||||
|
`Category retrieved successfully! (${categorySlug})`,
|
||||||
|
);
|
||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
id: category.id,
|
id: category.id,
|
||||||
display_name: category.display_name,
|
display_name: category.display_name,
|
||||||
slug_name: category.slug_name
|
slug_name: category.slug_name,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +210,7 @@ const CategoryController = {
|
|||||||
update: updateCategory,
|
update: updateCategory,
|
||||||
delete: deleteCategory,
|
delete: deleteCategory,
|
||||||
getAll: getAllCategory,
|
getAll: getAllCategory,
|
||||||
getBySlug: getBySlugCategory
|
getBySlug: getBySlugCategory,
|
||||||
}
|
};
|
||||||
|
|
||||||
export default CategoryController;
|
export default CategoryController;
|
@ -1,20 +1,27 @@
|
|||||||
|
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 type { Request, Response } from "express";
|
||||||
import { Logger } from "tslog";
|
import { Logger } from "tslog";
|
||||||
import CategoryService from "@services/category.service";
|
|
||||||
import type IDbModel from "@interfaces/database/IDbModel";
|
|
||||||
import ModelService from "@services/model.service";
|
|
||||||
//import {validationResult} from "express-validator";
|
//import {validationResult} from "express-validator";
|
||||||
|
|
||||||
|
const logger = new Logger({
|
||||||
|
name: "ModelController",
|
||||||
|
});
|
||||||
|
|
||||||
const logger = new Logger({ name: "ModelController" });
|
async function createModel(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
async function createModel(req: Request, res: Response): Promise<Response> {
|
): Promise<Response> {
|
||||||
const body: IDbModel = req.body
|
const body: IDbModel = req.body;
|
||||||
const doesExist = await CategoryService.getBySlug(`${body.slug_name}`)
|
const doesExist = await CategoryService.getBySlug(
|
||||||
|
`${body.slug_name}`,
|
||||||
|
);
|
||||||
if (doesExist) {
|
if (doesExist) {
|
||||||
logger.error("Category already exists");
|
logger.error("Category already exists");
|
||||||
return res.status(400).json({ error: "Category already exists" });
|
return res.status(400).json({
|
||||||
|
error: "Category already exists",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const createResult = await ModelService.create({
|
const createResult = await ModelService.create({
|
||||||
display_name: `${body.display_name}`,
|
display_name: `${body.display_name}`,
|
||||||
@ -23,22 +30,35 @@ async function createModel(req: Request, res: Response): Promise<Response> {
|
|||||||
base_price: Number.parseFloat(`${body.base_price}`),
|
base_price: Number.parseFloat(`${body.base_price}`),
|
||||||
brand_id: `${body.brand_id}`,
|
brand_id: `${body.brand_id}`,
|
||||||
image_blob: `${body.image_blob}`,
|
image_blob: `${body.image_blob}`,
|
||||||
is_trending: !!body.is_trending
|
is_trending: !!body.is_trending,
|
||||||
})
|
});
|
||||||
if (!createResult) {
|
if (!createResult) {
|
||||||
logger.error("Failed to create category");
|
logger.error("Failed to create category");
|
||||||
return res.status(500).json({ error: "Failed to create category" });
|
return res.status(500).json({
|
||||||
|
error: "Failed to create category",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
logger.info(`Category created successfully ! (${body.slug_name})`)
|
logger.info(
|
||||||
return res.status(201).json({ message: "Category created successfully" });
|
`Category created successfully ! (${body.slug_name})`,
|
||||||
|
);
|
||||||
|
return res.status(201).json({
|
||||||
|
message: "Category created successfully",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateModel(req: Request, res: Response): Promise<Response> {
|
async function updateModel(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
): Promise<Response> {
|
||||||
const body: IDbModel = req.body;
|
const body: IDbModel = req.body;
|
||||||
const doesExist = await ModelService.getBySlug(`${body.slug_name}`);
|
const doesExist = await ModelService.getBySlug(
|
||||||
|
`${body.slug_name}`,
|
||||||
|
);
|
||||||
if (!doesExist) {
|
if (!doesExist) {
|
||||||
logger.error("Model does not exist");
|
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({
|
const updateResult = await ModelService.update({
|
||||||
id: `${body.id}`,
|
id: `${body.id}`,
|
||||||
@ -48,57 +68,85 @@ async function updateModel(req: Request, res: Response): Promise<Response> {
|
|||||||
base_price: Number.parseFloat(`${body.base_price}`),
|
base_price: Number.parseFloat(`${body.base_price}`),
|
||||||
brand_id: `${body.brand_id}`,
|
brand_id: `${body.brand_id}`,
|
||||||
image_blob: `${body.image_blob}`,
|
image_blob: `${body.image_blob}`,
|
||||||
is_trending: !!body.is_trending
|
is_trending: !!body.is_trending,
|
||||||
});
|
});
|
||||||
if (!updateResult) {
|
if (!updateResult) {
|
||||||
logger.error("Failed to update model");
|
logger.error("Failed to update model");
|
||||||
return res.status(500).json({ error: "Failed to update model" });
|
return res.status(500).json({
|
||||||
|
error: "Failed to update model",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
logger.info(`Model updated successfully! (${body.slug_name})`);
|
logger.info(
|
||||||
return res.status(200).json({ message: "Model updated successfully" });
|
`Model updated successfully! (${body.slug_name})`,
|
||||||
|
);
|
||||||
|
return res.status(200).json({
|
||||||
|
message: "Model updated successfully",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getAllModel(res: Response): Promise<Response> {
|
async function getAllModel(res: Response): Promise<Response> {
|
||||||
const models = await ModelService.getAll();
|
const models = await ModelService.getAll();
|
||||||
if (!models) {
|
if (!models) {
|
||||||
logger.error("Failed to get all models");
|
logger.error("Failed to get all models");
|
||||||
return res.status(500).json({ error: "Failed to get all models" });
|
return res.status(500).json({
|
||||||
|
error: "Failed to get all models",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
uat: Date.now(),
|
uat: Date.now(),
|
||||||
models: models,
|
models: models,
|
||||||
total: models.length
|
total: models.length,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getModelBySlug(req: Request, res: Response): Promise<Response> {
|
async function getModelBySlug(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
): Promise<Response> {
|
||||||
const slug = req.params["modelSlug"];
|
const slug = req.params["modelSlug"];
|
||||||
if (!slug) {
|
if (!slug) {
|
||||||
logger.error("Invalid slug");
|
logger.error("Invalid slug");
|
||||||
return res.status(400).json({ error: "Invalid slug" });
|
return res.status(400).json({
|
||||||
|
error: "Invalid slug",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const model = await ModelService.getBySlug(slug);
|
const model = await ModelService.getBySlug(slug);
|
||||||
if (!model) {
|
if (!model) {
|
||||||
logger.error("Model not found");
|
logger.error("Model not found");
|
||||||
return res.status(404).json({ error: "Model not found" });
|
return res.status(404).json({
|
||||||
|
error: "Model not found",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return res.status(200).json({ model });
|
return res.status(200).json({
|
||||||
|
model,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteModel(req: Request, res: Response): Promise<Response> {
|
async function deleteModel(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
): Promise<Response> {
|
||||||
const modelSlug = req.params["modelSlug"];
|
const modelSlug = req.params["modelSlug"];
|
||||||
if (!modelSlug) {
|
if (!modelSlug) {
|
||||||
logger.error("Invalid model slug");
|
logger.error("Invalid model slug");
|
||||||
return res.status(400).json({ error: "Invalid model slug" });
|
return res.status(400).json({
|
||||||
|
error: "Invalid model slug",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
//TODO Check if vehicle related to model
|
//TODO Check if vehicle related to model
|
||||||
const deleteResult = await ModelService.delete(modelSlug);
|
const deleteResult = await ModelService.delete(modelSlug);
|
||||||
if (!deleteResult) {
|
if (!deleteResult) {
|
||||||
logger.error("Failed to delete model");
|
logger.error("Failed to delete model");
|
||||||
return res.status(500).json({ error: "Failed to delete model" });
|
return res.status(500).json({
|
||||||
|
error: "Failed to delete model",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
logger.info(`Model deleted successfully! (SLUG: ${modelSlug})`);
|
logger.info(
|
||||||
return res.status(200).json({ message: "Model deleted successfully" });
|
`Model deleted successfully! (SLUG: ${modelSlug})`,
|
||||||
|
);
|
||||||
|
return res.status(200).json({
|
||||||
|
message: "Model deleted successfully",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO get all vehicles of an model by slug
|
//TODO get all vehicles of an model by slug
|
||||||
@ -111,6 +159,6 @@ const ModelController = {
|
|||||||
getAll: getAllModel,
|
getAll: getAllModel,
|
||||||
getBySlug: getModelBySlug,
|
getBySlug: getModelBySlug,
|
||||||
delete: deleteModel,
|
delete: deleteModel,
|
||||||
}
|
};
|
||||||
|
|
||||||
export default ModelController;
|
export default ModelController;
|
@ -20,4 +20,4 @@ interface DbUserData {
|
|||||||
uat: Date;
|
uat: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default DbUserData
|
export default DbUserData;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
export interface IDbCategory {
|
export interface IDbCategory {
|
||||||
id?: string;
|
id?: string;
|
||||||
slug_name: string;
|
slug_name: string;
|
||||||
display_name: string
|
display_name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default IDbCategory;
|
export default IDbCategory;
|
@ -5,7 +5,7 @@ export interface IDbRent {
|
|||||||
iat: Date;
|
iat: Date;
|
||||||
eat: Date;
|
eat: Date;
|
||||||
need_survey: boolean;
|
need_survey: boolean;
|
||||||
km_at_start: number
|
km_at_start: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default IDbRent;
|
export default IDbRent;
|
@ -8,5 +8,5 @@ export interface IDbUser {
|
|||||||
is_mail_verified: boolean;
|
is_mail_verified: boolean;
|
||||||
is_admin: boolean;
|
is_admin: boolean;
|
||||||
gdpr: Date;
|
gdpr: Date;
|
||||||
hash: string
|
hash: string;
|
||||||
}
|
}
|
@ -1 +1 @@
|
|||||||
export * from './UserData'
|
export * from "./UserData";
|
||||||
|
@ -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 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();
|
const AuthRouter: Router = express.Router();
|
||||||
|
|
||||||
AuthRouter.route('/login').post(AuthController.login)
|
AuthRouter.route("/login").post(AuthController.login);
|
||||||
AuthRouter.route('/register').post(AuthController.register)
|
AuthRouter.route("/register").post(AuthController.register);
|
||||||
|
|
||||||
// PATCH
|
// PATCH
|
||||||
//TODO - To test
|
//TODO - To test
|
||||||
AuthRouter.route('/me')
|
AuthRouter.route("/me").patch(
|
||||||
.patch(UserGuard, AuthController.editUser)
|
UserGuard,
|
||||||
|
AuthController.editUser,
|
||||||
|
);
|
||||||
|
|
||||||
// GET
|
// GET
|
||||||
AuthRouter.route('/me')
|
AuthRouter.route("/me").get(UserGuard, AuthController.getSelf);
|
||||||
.get(UserGuard, AuthController.getSelf)
|
|
||||||
|
|
||||||
// DELETE
|
// DELETE
|
||||||
AuthRouter.route('/me')
|
AuthRouter.route("/me").delete(
|
||||||
.delete(UserGuard, AuthController.deleteSelf)
|
UserGuard,
|
||||||
|
AuthController.deleteSelf,
|
||||||
|
);
|
||||||
|
|
||||||
// GET
|
// GET
|
||||||
AuthRouter.route('/all')
|
AuthRouter.route("/all").get(
|
||||||
.get(AdminGuard, AuthController.getAllUsers)
|
AdminGuard,
|
||||||
|
AuthController.getAllUsers,
|
||||||
|
);
|
||||||
|
|
||||||
// GET
|
// GET
|
||||||
AuthRouter.route('/user/:targetId')
|
AuthRouter.route("/user/:targetId")
|
||||||
.get(AdminGuard, AuthController.getUser)
|
.get(AdminGuard, AuthController.getUser)
|
||||||
.patch(AdminGuard, AuthController.editUser)
|
.patch(AdminGuard, AuthController.editUser)
|
||||||
.delete(AdminGuard, AuthController.deleteUser)
|
.delete(AdminGuard, AuthController.deleteUser);
|
||||||
|
|
||||||
|
export default AuthRouter;
|
||||||
export default AuthRouter
|
|
||||||
|
@ -1,44 +1,52 @@
|
|||||||
import express, {type Router} from "express";
|
import BrandController from "@controllers/brand.controller";
|
||||||
import AdminGuard from "@validators/AdminGuard";
|
|
||||||
import UserGuard from "@validators/UserGuard";
|
|
||||||
import CategoryController from "@controllers/category.controller";
|
import CategoryController from "@controllers/category.controller";
|
||||||
import ModelController from "@controllers/model.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();
|
const CatalogRouter: Router = express.Router();
|
||||||
|
|
||||||
//-- MODELS >>
|
//-- 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)
|
.get(UserGuard, ModelController.getBySlug)
|
||||||
.patch(AdminGuard, ModelController.update)
|
.patch(AdminGuard, ModelController.update)
|
||||||
.delete(AdminGuard, ModelController.delete)
|
.delete(AdminGuard, ModelController.delete);
|
||||||
|
|
||||||
|
|
||||||
//-- CATEGORY >>
|
//-- CATEGORY >>
|
||||||
|
|
||||||
CatalogRouter.route('/category/new').get(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)
|
.get(UserGuard, CategoryController.getBySlug)
|
||||||
.patch(AdminGuard, CategoryController.update)
|
.patch(AdminGuard, CategoryController.update)
|
||||||
.delete(AdminGuard, CategoryController.delete)
|
.delete(AdminGuard, CategoryController.delete);
|
||||||
|
|
||||||
|
|
||||||
//-- BRAND >>
|
//-- BRAND >>
|
||||||
|
|
||||||
CatalogRouter.route('/brand/new').post(AdminGuard, BrandController.create)
|
CatalogRouter.route("/brand/new").post(
|
||||||
CatalogRouter.route('/brand/all').get(BrandController.getAll)
|
AdminGuard,
|
||||||
CatalogRouter.route('/brand/:brandSlug')
|
BrandController.create,
|
||||||
|
);
|
||||||
|
CatalogRouter.route("/brand/all").get(BrandController.getAll);
|
||||||
|
CatalogRouter.route("/brand/:brandSlug")
|
||||||
.get(UserGuard, BrandController.getBySlug)
|
.get(UserGuard, BrandController.getBySlug)
|
||||||
.patch(AdminGuard, BrandController.update)
|
.patch(AdminGuard, BrandController.update)
|
||||||
.delete(AdminGuard, BrandController.delete)
|
.delete(AdminGuard, BrandController.delete);
|
||||||
|
|
||||||
export default CatalogRouter;
|
export default CatalogRouter;
|
@ -1,3 +1,3 @@
|
|||||||
export * from 'src/routes/auth/authRouter'
|
export * from "src/routes/auth/authRouter";
|
||||||
export * from 'src/routes/catalog/catalogRouter'
|
export * from "src/routes/catalog/catalogRouter";
|
||||||
export * from 'src/routes/rent/rentRouter'
|
export * from "src/routes/rent/rentRouter";
|
||||||
|
@ -1,34 +1,27 @@
|
|||||||
import express, {type Router} from "express";
|
|
||||||
import AdminGuard from "@validators/AdminGuard";
|
import AdminGuard from "@validators/AdminGuard";
|
||||||
import UserGuard from "@validators/UserGuard";
|
import UserGuard from "@validators/UserGuard";
|
||||||
|
import express, { type Router } from "express";
|
||||||
|
|
||||||
const RentRouter: Router = express.Router();
|
const RentRouter: Router = express.Router();
|
||||||
|
|
||||||
// Get rent affected to the user
|
// Get rent affected to the user
|
||||||
RentRouter.route('/affected')
|
RentRouter.route("/affected").get(UserGuard);
|
||||||
.get(UserGuard)
|
|
||||||
|
|
||||||
// Get all vehicle in rent (admin only)
|
// Get all vehicle in rent (admin only)
|
||||||
RentRouter.route('/affected/all')
|
RentRouter.route("/affected/all").get(AdminGuard);
|
||||||
.get(AdminGuard)
|
|
||||||
|
|
||||||
// Add a new vehicle (admin only)
|
// Add a new vehicle (admin only)
|
||||||
RentRouter.route('/veh/new')
|
RentRouter.route("/veh/new").post(AdminGuard);
|
||||||
.post(AdminGuard)
|
|
||||||
|
|
||||||
// Get all vehicles
|
// Get all vehicles
|
||||||
RentRouter.route('/veh/all')
|
RentRouter.route("/veh/all").get();
|
||||||
.get()
|
|
||||||
|
|
||||||
// Rent a specific vehicle
|
// Rent a specific vehicle
|
||||||
RentRouter.route('/veh/rent/:vehicleId')
|
RentRouter.route("/veh/rent/:vehicleId").post(UserGuard);
|
||||||
.post(UserGuard)
|
|
||||||
|
|
||||||
|
RentRouter.route("/veh/:vehicleId")
|
||||||
RentRouter.route('/veh/:vehicleId')
|
|
||||||
.get(UserGuard)
|
.get(UserGuard)
|
||||||
.patch(AdminGuard)
|
.patch(AdminGuard)
|
||||||
.delete(AdminGuard)
|
.delete(AdminGuard);
|
||||||
|
|
||||||
export default RentRouter;
|
export default RentRouter;
|
@ -1,10 +1,12 @@
|
|||||||
import type IDbBrand from "@interfaces/database/IDbBrand";
|
import type IDbBrand from "@interfaces/database/IDbBrand";
|
||||||
import MysqlService from "@services/mysql.service";
|
import MysqlService from "@services/mysql.service";
|
||||||
import { Logger } from "tslog";
|
import { Logger } from "tslog";
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
|
||||||
const DbHandler = new MysqlService.Handler('BrandService')
|
const DbHandler = new MysqlService.Handler("BrandService");
|
||||||
const logger = new Logger({name: 'BrandService'})
|
const logger = new Logger({
|
||||||
|
name: "BrandService",
|
||||||
|
});
|
||||||
|
|
||||||
//SEC todo Blob validation
|
//SEC todo Blob validation
|
||||||
/**
|
/**
|
||||||
@ -14,24 +16,39 @@ const logger = new Logger({name: 'BrandService'})
|
|||||||
* @return {Promise<unknown>} A promise that resolves to the result of the operation.
|
* @return {Promise<unknown>} A promise that resolves to the result of the operation.
|
||||||
*/
|
*/
|
||||||
async function createBrand(data: IDbBrand): Promise<unknown> {
|
async function createBrand(data: IDbBrand): Promise<unknown> {
|
||||||
const doesExist = await MysqlService.Brand.getBySlug(DbHandler, data.slug_name);
|
const doesExist = await MysqlService.Brand.getBySlug(
|
||||||
|
DbHandler,
|
||||||
|
data.slug_name,
|
||||||
|
);
|
||||||
if (doesExist) {
|
if (doesExist) {
|
||||||
logger.error(`Brand already exists (${data.slug_name})`)
|
logger.error(`Brand already exists (${data.slug_name})`);
|
||||||
return {error: 'exist'}
|
return {
|
||||||
|
error: "exist",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
const brandId = uuidv4();
|
const brandId = uuidv4();
|
||||||
const createdBrand = await MysqlService.Brand.insert(DbHandler, {
|
const createdBrand = await MysqlService.Brand.insert(
|
||||||
|
DbHandler,
|
||||||
|
{
|
||||||
id: brandId,
|
id: brandId,
|
||||||
slug_name: `${data.slug_name}`,
|
slug_name: `${data.slug_name}`,
|
||||||
display_name: `${data.display_name}`,
|
display_name: `${data.display_name}`,
|
||||||
image_blob: data.image_blob
|
image_blob: data.image_blob,
|
||||||
});
|
},
|
||||||
|
);
|
||||||
if (createdBrand) {
|
if (createdBrand) {
|
||||||
logger.info(`Brand created successfully (${data.slug_name})`);
|
logger.info(
|
||||||
return { success: true, brand: createdBrand };
|
`Brand created successfully (${data.slug_name})`,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
brand: createdBrand,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
logger.error(`Failed to create brand (${data.slug_name})`);
|
logger.error(`Failed to create brand (${data.slug_name})`);
|
||||||
return { error: 'failed' };
|
return {
|
||||||
|
error: "failed",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
//SEC todo Blob validation
|
//SEC todo Blob validation
|
||||||
@ -46,19 +63,27 @@ async function updateBrand(data: IDbBrand): Promise<boolean> {
|
|||||||
logger.error("Brand ID is missing");
|
logger.error("Brand ID is missing");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const doesExist = await MysqlService.Brand.getBySlug(DbHandler, data.slug_name);
|
const doesExist = await MysqlService.Brand.getBySlug(
|
||||||
|
DbHandler,
|
||||||
|
data.slug_name,
|
||||||
|
);
|
||||||
if (doesExist && doesExist.id !== data.id) {
|
if (doesExist && doesExist.id !== data.id) {
|
||||||
logger.error(`Brand already exists (${data.slug_name})`);
|
logger.error(`Brand already exists (${data.slug_name})`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const updatedBrand = await MysqlService.Brand.update(DbHandler, {
|
const updatedBrand = await MysqlService.Brand.update(
|
||||||
|
DbHandler,
|
||||||
|
{
|
||||||
id: data.id,
|
id: data.id,
|
||||||
slug_name: `${data.slug_name}`,
|
slug_name: `${data.slug_name}`,
|
||||||
display_name: `${data.display_name}`,
|
display_name: `${data.display_name}`,
|
||||||
image_blob: data.image_blob
|
image_blob: data.image_blob,
|
||||||
});
|
},
|
||||||
|
);
|
||||||
if (updatedBrand) {
|
if (updatedBrand) {
|
||||||
logger.info(`Brand updated successfully (${data.slug_name})`);
|
logger.info(
|
||||||
|
`Brand updated successfully (${data.slug_name})`,
|
||||||
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
logger.error(`Failed to update brand (${data.slug_name})`);
|
logger.error(`Failed to update brand (${data.slug_name})`);
|
||||||
@ -75,7 +100,9 @@ async function getAllBrand(): Promise<Array<IDbBrand>| false> {
|
|||||||
logger.error("Failed to retrieve brands");
|
logger.error("Failed to retrieve brands");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
logger.info(`Retrieved all brands successfully (${brands.length})`);
|
logger.info(
|
||||||
|
`Retrieved all brands successfully (${brands.length})`,
|
||||||
|
);
|
||||||
return brands;
|
return brands;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,17 +112,24 @@ async function getAllBrand(): Promise<Array<IDbBrand>| false> {
|
|||||||
* @param {string} brandSlug - The slug of the brand.
|
* @param {string} brandSlug - The slug of the brand.
|
||||||
* @returns {Promise<IDbBrand|false>} - A promise that resolves to the retrieved brand object or false if the brand is not found.
|
* @returns {Promise<IDbBrand|false>} - A promise that resolves to the retrieved brand object or false if the brand is not found.
|
||||||
*/
|
*/
|
||||||
async function getBySlugBrand(brandSlug: string): Promise<IDbBrand | false> {
|
async function getBySlugBrand(
|
||||||
|
brandSlug: string,
|
||||||
|
): Promise<IDbBrand | false> {
|
||||||
if (!brandSlug) {
|
if (!brandSlug) {
|
||||||
logger.error("Brand slug is missing");
|
logger.error("Brand slug is missing");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const brand = await MysqlService.Brand.getBySlug(DbHandler, brandSlug);
|
const brand = await MysqlService.Brand.getBySlug(
|
||||||
|
DbHandler,
|
||||||
|
brandSlug,
|
||||||
|
);
|
||||||
if (!brand) {
|
if (!brand) {
|
||||||
logger.error(`Brand not found (${brandSlug})`);
|
logger.error(`Brand not found (${brandSlug})`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
logger.info(`Retrieved brand by slug successfully (${brandSlug})`);
|
logger.info(
|
||||||
|
`Retrieved brand by slug successfully (${brandSlug})`,
|
||||||
|
);
|
||||||
return brand;
|
return brand;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +140,9 @@ async function getBySlugBrand(brandSlug: string): Promise<IDbBrand | false> {
|
|||||||
*
|
*
|
||||||
* @returns {Promise<IDbBrand | false>} A promise that resolves to the retrieved brand object, or false if the brand is not found or the ID is invalid.
|
* @returns {Promise<IDbBrand | false>} A promise that resolves to the retrieved brand object, or false if the brand is not found or the ID is invalid.
|
||||||
*/
|
*/
|
||||||
async function getByIdBrand(brandId: string): Promise<IDbBrand | false> {
|
async function getByIdBrand(
|
||||||
|
brandId: string,
|
||||||
|
): Promise<IDbBrand | false> {
|
||||||
if (!brandId) {
|
if (!brandId) {
|
||||||
logger.error("Brand ID is missing");
|
logger.error("Brand ID is missing");
|
||||||
return false;
|
return false;
|
||||||
@ -115,12 +151,17 @@ async function getByIdBrand(brandId: string): Promise<IDbBrand | false> {
|
|||||||
logger.error("Invalid brand ID");
|
logger.error("Invalid brand ID");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const brand = await MysqlService.Brand.getById(DbHandler, brandId);
|
const brand = await MysqlService.Brand.getById(
|
||||||
|
DbHandler,
|
||||||
|
brandId,
|
||||||
|
);
|
||||||
if (!brand) {
|
if (!brand) {
|
||||||
logger.error(`Brand not found (${brandId})`);
|
logger.error(`Brand not found (${brandId})`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
logger.info(`Retrieved brand by ID successfully (${brandId})`);
|
logger.info(
|
||||||
|
`Retrieved brand by ID successfully (${brandId})`,
|
||||||
|
);
|
||||||
return brand;
|
return brand;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +185,10 @@ async function deleteBrand(brandId: string): Promise<boolean> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//TODO verify if as models linked
|
//TODO verify if as models linked
|
||||||
const deletedBrand = await MysqlService.Brand.delete(DbHandler, brandId);
|
const deletedBrand = await MysqlService.Brand.delete(
|
||||||
|
DbHandler,
|
||||||
|
brandId,
|
||||||
|
);
|
||||||
if (!deletedBrand) {
|
if (!deletedBrand) {
|
||||||
logger.error(`Failed to delete brand (${brandId})`);
|
logger.error(`Failed to delete brand (${brandId})`);
|
||||||
return false;
|
return false;
|
||||||
@ -160,6 +204,6 @@ const BrandService = {
|
|||||||
getBySlug: getBySlugBrand,
|
getBySlug: getBySlugBrand,
|
||||||
getById: getByIdBrand,
|
getById: getByIdBrand,
|
||||||
delete: deleteBrand,
|
delete: deleteBrand,
|
||||||
}
|
};
|
||||||
|
|
||||||
export default BrandService;
|
export default BrandService;
|
@ -1,12 +1,12 @@
|
|||||||
import type { IDbCategory } from "@interfaces/database/IDbCategory";
|
import type { IDbCategory } from "@interfaces/database/IDbCategory";
|
||||||
import MysqlService from "@services/mysql.service";
|
import MysqlService from "@services/mysql.service";
|
||||||
import { Logger } from "tslog";
|
import { Logger } from "tslog";
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
|
||||||
const DbHandler = new MysqlService.Handler('CategoryService')
|
|
||||||
const logger = new Logger({name: 'CategoryService'})
|
|
||||||
|
|
||||||
|
|
||||||
|
const DbHandler = new MysqlService.Handler("CategoryService");
|
||||||
|
const logger = new Logger({
|
||||||
|
name: "CategoryService",
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new category with the given data.
|
* Creates a new category with the given data.
|
||||||
@ -15,14 +15,18 @@ const logger = new Logger({name: 'CategoryService'})
|
|||||||
* @returns {Promise<boolean>} A promise that resolves with the created category.
|
* @returns {Promise<boolean>} A promise that resolves with the created category.
|
||||||
* If an error occurs, the promise will reject with the error.
|
* If an error occurs, the promise will reject with the error.
|
||||||
*/
|
*/
|
||||||
async function createCategory(data: IDbCategory): Promise<boolean> {
|
async function createCategory(
|
||||||
logger.info(`Creating a new category... (${data.display_name})`)
|
data: IDbCategory,
|
||||||
|
): Promise<boolean> {
|
||||||
|
logger.info(
|
||||||
|
`Creating a new category... (${data.display_name})`,
|
||||||
|
);
|
||||||
try {
|
try {
|
||||||
await MysqlService.Category.insert(DbHandler, {
|
await MysqlService.Category.insert(DbHandler, {
|
||||||
id: uuidv4(),
|
id: uuidv4(),
|
||||||
display_name: data.display_name,
|
display_name: data.display_name,
|
||||||
slug_name: data.slug_name
|
slug_name: data.slug_name,
|
||||||
})
|
});
|
||||||
//TODO Return the new id
|
//TODO Return the new id
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -43,19 +47,19 @@ async function createCategory(data: IDbCategory): Promise<boolean> {
|
|||||||
*/
|
*/
|
||||||
async function updateCategory(data: IDbCategory) {
|
async function updateCategory(data: IDbCategory) {
|
||||||
if (!data.id) {
|
if (!data.id) {
|
||||||
logger.error("Category id is missing.")
|
logger.error("Category id is missing.");
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await MysqlService.Category.update(DbHandler, {
|
await MysqlService.Category.update(DbHandler, {
|
||||||
id: data.id,
|
id: data.id,
|
||||||
slug_name: data.slug_name,
|
slug_name: data.slug_name,
|
||||||
display_name: data.display_name
|
display_name: data.display_name,
|
||||||
});
|
});
|
||||||
//TODO Return id
|
//TODO Return id
|
||||||
return true;
|
return true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(err)
|
logger.error(err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,7 +69,9 @@ async function updateCategory(data: IDbCategory) {
|
|||||||
*
|
*
|
||||||
* @returns {Promise<Array<IDbCategory>> | null} Promise that resolves to an array of IDbCategory objects or null if an error occurred.
|
* @returns {Promise<Array<IDbCategory>> | null} Promise that resolves to an array of IDbCategory objects or null if an error occurred.
|
||||||
*/
|
*/
|
||||||
async function getAll(): Promise<Promise<Array<IDbCategory>> | null> {
|
async function getAll(): Promise<Promise<
|
||||||
|
Array<IDbCategory>
|
||||||
|
> | null> {
|
||||||
try {
|
try {
|
||||||
logger.info("Getting all categories...");
|
logger.info("Getting all categories...");
|
||||||
return await MysqlService.Category.getAll(DbHandler);
|
return await MysqlService.Category.getAll(DbHandler);
|
||||||
@ -75,17 +81,21 @@ async function getAll(): Promise<Promise<Array<IDbCategory>> | null> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a category by its slug
|
* Gets a category by its slug
|
||||||
*
|
*
|
||||||
* @param {string} slug - The slug of the category
|
* @param {string} slug - The slug of the category
|
||||||
* @return {Promise<IDbCategory|null>} - A promise that resolves to the category object or null if not found
|
* @return {Promise<IDbCategory|null>} - A promise that resolves to the category object or null if not found
|
||||||
*/
|
*/
|
||||||
async function getBySlug(slug: string): Promise<IDbCategory | null> {
|
async function getBySlug(
|
||||||
|
slug: string,
|
||||||
|
): Promise<IDbCategory | null> {
|
||||||
try {
|
try {
|
||||||
logger.info(`Getting category by slug... (${slug})`);
|
logger.info(`Getting category by slug... (${slug})`);
|
||||||
return await MysqlService.Category.getBySlug(DbHandler, slug);
|
return await MysqlService.Category.getBySlug(
|
||||||
|
DbHandler,
|
||||||
|
slug,
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`Error getting category by slug: ${error}`);
|
logger.error(`Error getting category by slug: ${error}`);
|
||||||
return null;
|
return null;
|
||||||
@ -98,7 +108,9 @@ async function getBySlug(slug: string): Promise<IDbCategory | null> {
|
|||||||
* @param {string} id - The id of the category to retrieve.
|
* @param {string} id - The id of the category to retrieve.
|
||||||
* @returns {Promise<IDbCategory | null>} - A Promise that resolves with the retrieved category object or null if not found.
|
* @returns {Promise<IDbCategory | null>} - A Promise that resolves with the retrieved category object or null if not found.
|
||||||
*/
|
*/
|
||||||
async function getById(id: string):Promise<IDbCategory | null> {
|
async function getById(
|
||||||
|
id: string,
|
||||||
|
): Promise<IDbCategory | null> {
|
||||||
try {
|
try {
|
||||||
logger.info(`Getting category by id... (${id})`);
|
logger.info(`Getting category by id... (${id})`);
|
||||||
return await MysqlService.Category.getById(DbHandler, id);
|
return await MysqlService.Category.getById(DbHandler, id);
|
||||||
@ -110,7 +122,6 @@ async function getById(id: string):Promise<IDbCategory | null> {
|
|||||||
|
|
||||||
//FEAT Get all models in category (slug)
|
//FEAT Get all models in category (slug)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes a category with the given ID from the database.
|
* Deletes a category with the given ID from the database.
|
||||||
*
|
*
|
||||||
@ -135,7 +146,7 @@ const CategoryService = {
|
|||||||
update: updateCategory,
|
update: updateCategory,
|
||||||
getAll,
|
getAll,
|
||||||
getBySlug,
|
getBySlug,
|
||||||
getById
|
getById,
|
||||||
}
|
};
|
||||||
|
|
||||||
export default CategoryService;
|
export default CategoryService;
|
@ -4,21 +4,24 @@ import Argon2id from "@node-rs/argon2";
|
|||||||
export async function getHashFromPassword(password: string) {
|
export async function getHashFromPassword(password: string) {
|
||||||
return await Argon2id.hash(password, {
|
return await Argon2id.hash(password, {
|
||||||
secret: Buffer.from(`${process.env["HASH_SECRET"]}`),
|
secret: Buffer.from(`${process.env["HASH_SECRET"]}`),
|
||||||
algorithm: 2
|
algorithm: 2,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//ToTest
|
//ToTest
|
||||||
export async function comparePassword(password: string, hash: string) {
|
export async function comparePassword(
|
||||||
|
password: string,
|
||||||
|
hash: string,
|
||||||
|
) {
|
||||||
return await Argon2id.verify(hash, password, {
|
return await Argon2id.verify(hash, password, {
|
||||||
secret: Buffer.from(`${process.env["HASH_SECRET"]}`),
|
secret: Buffer.from(`${process.env["HASH_SECRET"]}`),
|
||||||
algorithm: 2
|
algorithm: 2,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const CredentialService = {
|
const CredentialService = {
|
||||||
compare: comparePassword,
|
compare: comparePassword,
|
||||||
hash: getHashFromPassword,
|
hash: getHashFromPassword,
|
||||||
}
|
};
|
||||||
|
|
||||||
export default CredentialService;
|
export default CredentialService;
|
@ -1,2 +1,2 @@
|
|||||||
export * from './jwt.service';
|
export * from "./jwt.service";
|
||||||
export * as MySqlService from './mysql.service'
|
export * as MySqlService from "./mysql.service";
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
import {type JWTHeaderParameters, type JWTPayload, jwtVerify, SignJWT} from "jose";
|
import {
|
||||||
|
type JWTHeaderParameters,
|
||||||
|
type JWTPayload,
|
||||||
|
SignJWT,
|
||||||
|
jwtVerify,
|
||||||
|
} from "jose";
|
||||||
import { Logger } from "tslog";
|
import { Logger } from "tslog";
|
||||||
|
|
||||||
const logger = new Logger({ name: "JwtService" });
|
const logger = new Logger({
|
||||||
|
name: "JwtService",
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify a JWT token.
|
* Verify a JWT token.
|
||||||
@ -11,22 +18,22 @@ const logger = new Logger({ name: "JwtService" });
|
|||||||
* @returns {Promise<null | JWTPayload>}
|
* @returns {Promise<null | JWTPayload>}
|
||||||
* - The payload of the verified JWT token or null if verification fails.
|
* - The payload of the verified JWT token or null if verification fails.
|
||||||
*/
|
*/
|
||||||
async function JwtVerifyService(jwt: string | Uint8Array): Promise<null | JWTPayload> {
|
async function JwtVerifyService(
|
||||||
|
jwt: string | Uint8Array,
|
||||||
|
): Promise<null | JWTPayload> {
|
||||||
try {
|
try {
|
||||||
const result = await jwtVerify(
|
const result = await jwtVerify(
|
||||||
jwt,
|
jwt,
|
||||||
new TextEncoder()
|
new TextEncoder().encode(`${process.env["JWT_SECRET"]}`),
|
||||||
.encode(`${process.env["JWT_SECRET"]}`),
|
{},
|
||||||
{
|
);
|
||||||
})
|
|
||||||
return result.payload;
|
return result.payload;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(error)
|
logger.error(error);
|
||||||
return null
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asynchronously signs a JWT token using the provided payload, header, expiration time, and audience.
|
* Asynchronously signs a JWT token using the provided payload, header, expiration time, and audience.
|
||||||
*
|
*
|
||||||
@ -42,19 +49,26 @@ async function JwtVerifyService(jwt: string | Uint8Array): Promise<null | JWTPay
|
|||||||
* @returns {Promise<string>}
|
* @returns {Promise<string>}
|
||||||
* - A promise that resolves with the signed JWT token.
|
* - A promise that resolves with the signed JWT token.
|
||||||
*/
|
*/
|
||||||
async function JwtSignService(payload: JWTPayload, pHeader: JWTHeaderParameters, expTime: string | number | Date, audience: string | string[]): Promise<string> {
|
async function JwtSignService(
|
||||||
|
payload: JWTPayload,
|
||||||
|
pHeader: JWTHeaderParameters,
|
||||||
|
expTime: string | number | Date,
|
||||||
|
audience: string | string[],
|
||||||
|
): Promise<string> {
|
||||||
return await new SignJWT(payload)
|
return await new SignJWT(payload)
|
||||||
.setProtectedHeader(pHeader)
|
.setProtectedHeader(pHeader)
|
||||||
.setIssuedAt(new Date())
|
.setIssuedAt(new Date())
|
||||||
.setIssuer(`${process.env["JWT_SECRET"]} - Mathis HERRIOT`)
|
.setIssuer(`${process.env["JWT_SECRET"]} - Mathis HERRIOT`)
|
||||||
.setAudience(audience)
|
.setAudience(audience)
|
||||||
.setExpirationTime(expTime)
|
.setExpirationTime(expTime)
|
||||||
.sign(new TextEncoder().encode(`${process.env["JWT_SECRET"]}`))
|
.sign(
|
||||||
|
new TextEncoder().encode(`${process.env["JWT_SECRET"]}`),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const JwtService = {
|
const JwtService = {
|
||||||
verify: JwtVerifyService,
|
verify: JwtVerifyService,
|
||||||
sign: JwtSignService
|
sign: JwtSignService,
|
||||||
}
|
};
|
||||||
|
|
||||||
export default JwtService
|
export default JwtService;
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import type IDbModel from "@interfaces/database/IDbModel";
|
import type IDbModel from "@interfaces/database/IDbModel";
|
||||||
import MysqlService from "@services/mysql.service";
|
import MysqlService from "@services/mysql.service";
|
||||||
import { Logger } from "tslog";
|
import { Logger } from "tslog";
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
|
||||||
const DbHandler = new MysqlService.Handler('ModelService')
|
const DbHandler = new MysqlService.Handler("ModelService");
|
||||||
const logger = new Logger({name: 'ModelService'})
|
const logger = new Logger({
|
||||||
|
name: "ModelService",
|
||||||
|
});
|
||||||
|
|
||||||
//SEC TODO validate blob
|
//SEC TODO validate blob
|
||||||
/**
|
/**
|
||||||
@ -15,7 +17,7 @@ const logger = new Logger({name: 'ModelService'})
|
|||||||
* @return {Promise<boolean>} - Indicates whether the model was created successfully.
|
* @return {Promise<boolean>} - Indicates whether the model was created successfully.
|
||||||
*/
|
*/
|
||||||
async function createModel(data: IDbModel): Promise<boolean> {
|
async function createModel(data: IDbModel): Promise<boolean> {
|
||||||
logger.info(`Creating a new model... (${data.display_name})`)
|
logger.info(`Creating a new model... (${data.display_name})`);
|
||||||
//TODO Validate IDbModel data
|
//TODO Validate IDbModel data
|
||||||
try {
|
try {
|
||||||
await MysqlService.Model.insert(DbHandler, {
|
await MysqlService.Model.insert(DbHandler, {
|
||||||
@ -26,10 +28,10 @@ async function createModel(data: IDbModel): Promise<boolean> {
|
|||||||
brand_id: data.brand_id,
|
brand_id: data.brand_id,
|
||||||
category_id: data.category_id,
|
category_id: data.category_id,
|
||||||
base_price: data.base_price,
|
base_price: data.base_price,
|
||||||
is_trending: data.is_trending
|
is_trending: data.is_trending,
|
||||||
})
|
});
|
||||||
//TODO Return the new id
|
//TODO Return the new id
|
||||||
logger.info('Success !')
|
logger.info("Success !");
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`Error creating category: ${error}`);
|
logger.error(`Error creating category: ${error}`);
|
||||||
@ -70,13 +72,18 @@ async function updateModel(data: IDbModel): Promise<boolean> {
|
|||||||
* @param {string} modelSlug - The slug of the model to be deleted.
|
* @param {string} modelSlug - The slug of the model to be deleted.
|
||||||
* @return {Promise<boolean>} - A promise that resolves to true if the deletion is successful, else false.
|
* @return {Promise<boolean>} - A promise that resolves to true if the deletion is successful, else false.
|
||||||
*/
|
*/
|
||||||
async function deleteModel(modelSlug: string): Promise<boolean> {
|
async function deleteModel(
|
||||||
|
modelSlug: string,
|
||||||
|
): Promise<boolean> {
|
||||||
if (!modelSlug) {
|
if (!modelSlug) {
|
||||||
logger.error("Model slug is missing");
|
logger.error("Model slug is missing");
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
logger.info(`Deleting model with ID: ${modelSlug}`);
|
logger.info(`Deleting model with ID: ${modelSlug}`);
|
||||||
const doesExist = await MysqlService.Model.getBySlug(DbHandler, modelSlug);
|
const doesExist = await MysqlService.Model.getBySlug(
|
||||||
|
DbHandler,
|
||||||
|
modelSlug,
|
||||||
|
);
|
||||||
if (!doesExist || !doesExist.id) {
|
if (!doesExist || !doesExist.id) {
|
||||||
logger.warn(`Model with slug ${modelSlug} not found`);
|
logger.warn(`Model with slug ${modelSlug} not found`);
|
||||||
return false;
|
return false;
|
||||||
@ -91,17 +98,21 @@ async function deleteModel(modelSlug: string): Promise<boolean> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches a model by slug from the database.
|
* Fetches a model by slug from the database.
|
||||||
*
|
*
|
||||||
* @param {string} modelSlug - The slug of the model to be fetched.
|
* @param {string} modelSlug - The slug of the model to be fetched.
|
||||||
* @return {Promise<IDbModel | null>} - A promise that resolves to the model if found, else null.
|
* @return {Promise<IDbModel | null>} - A promise that resolves to the model if found, else null.
|
||||||
*/
|
*/
|
||||||
async function getBySlugModel(modelSlug: string): Promise<IDbModel | null> {
|
async function getBySlugModel(
|
||||||
|
modelSlug: string,
|
||||||
|
): Promise<IDbModel | null> {
|
||||||
logger.info(`Fetching model with slug: ${modelSlug}`);
|
logger.info(`Fetching model with slug: ${modelSlug}`);
|
||||||
try {
|
try {
|
||||||
const model = await MysqlService.Model.getBySlug(DbHandler, modelSlug);
|
const model = await MysqlService.Model.getBySlug(
|
||||||
|
DbHandler,
|
||||||
|
modelSlug,
|
||||||
|
);
|
||||||
if (!model) {
|
if (!model) {
|
||||||
logger.warn(`Model with slug ${modelSlug} not found`);
|
logger.warn(`Model with slug ${modelSlug} not found`);
|
||||||
return null;
|
return null;
|
||||||
@ -113,7 +124,6 @@ async function getBySlugModel(modelSlug: string): Promise<IDbModel | null> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches all models from the database.
|
* Fetches all models from the database.
|
||||||
*
|
*
|
||||||
@ -127,7 +137,7 @@ async function getAllModels(): Promise<IDbModel[] | null> {
|
|||||||
logger.warn("No models found on the database");
|
logger.warn("No models found on the database");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
logger.info(`Found ${models.length} model(s)`)
|
logger.info(`Found ${models.length} model(s)`);
|
||||||
return models;
|
return models;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`Error fetching all models: ${error}`);
|
logger.error(`Error fetching all models: ${error}`);
|
||||||
@ -135,8 +145,6 @@ async function getAllModels(): Promise<IDbModel[] | null> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ModelService is responsible for managing models.
|
* ModelService is responsible for managing models.
|
||||||
* @namespace
|
* @namespace
|
||||||
@ -149,6 +157,6 @@ const ModelService = {
|
|||||||
getAll: getAllModels,
|
getAll: getAllModels,
|
||||||
//getByCategory: getByCategoryModel,
|
//getByCategory: getByCategoryModel,
|
||||||
//getByBrand: getModelsByBrand,
|
//getByBrand: getModelsByBrand,
|
||||||
}
|
};
|
||||||
|
|
||||||
export default ModelService;
|
export default ModelService;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,15 +1,16 @@
|
|||||||
import {Logger} from "tslog";
|
import type { IReqLogin } from "@interfaces/requests/IReqLogin";
|
||||||
import MySqlService from "@services/mysql.service";
|
import type { IReqRegister } from "@interfaces/requests/IReqRegister";
|
||||||
import CredentialService from "@services/credential.service";
|
import CredentialService from "@services/credential.service";
|
||||||
import JwtService from "@services/jwt.service";
|
import JwtService from "@services/jwt.service";
|
||||||
|
import MySqlService from "@services/mysql.service";
|
||||||
import MysqlService from "@services/mysql.service";
|
import MysqlService from "@services/mysql.service";
|
||||||
import type {IReqRegister} from "@interfaces/requests/IReqRegister";
|
import { Logger } from "tslog";
|
||||||
import {IReqLogin} from "@interfaces/requests/IReqLogin";
|
|
||||||
|
|
||||||
|
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.
|
* Retrieves a user object from the database based on the given username.
|
||||||
@ -17,8 +18,13 @@ const DbHandler = new MySqlService.Handler('UserService')
|
|||||||
* @param {string} username - The username of the user to retrieve.
|
* @param {string} username - The username of the user to retrieve.
|
||||||
* @returns {Promise<Object | null>} - The user object if found, or null if not found.
|
* @returns {Promise<Object | null>} - The user object if found, or null if not found.
|
||||||
*/
|
*/
|
||||||
async function getUserFromUsername(username: string): Promise<object | null> {
|
async function getUserFromUsername(
|
||||||
const dbUser = await MySqlService.User.getByUsername(DbHandler, username)
|
username: string,
|
||||||
|
): Promise<object | null> {
|
||||||
|
const dbUser = await MySqlService.User.getByUsername(
|
||||||
|
DbHandler,
|
||||||
|
username,
|
||||||
|
);
|
||||||
if (dbUser === undefined) return null;
|
if (dbUser === undefined) return null;
|
||||||
return dbUser;
|
return dbUser;
|
||||||
}
|
}
|
||||||
@ -31,41 +37,65 @@ async function getUserFromIdService(id: string | undefined) {
|
|||||||
|
|
||||||
async function register(ReqData: IReqRegister) {
|
async function register(ReqData: IReqRegister) {
|
||||||
if (ReqData.password.length < 6) {
|
if (ReqData.password.length < 6) {
|
||||||
logger.info(`REGISTER :> Invalid password (${ReqData.username})`)
|
logger.info(
|
||||||
return { error: "invalidPassword" };
|
`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 ?
|
// Does the new user has accepted GDPR ?
|
||||||
if (ReqData.gdpr !== true) {
|
if (ReqData.gdpr !== true) {
|
||||||
logger.info(`REGISTER :> GDPR not validated (${ReqData.username})`)
|
logger.info(
|
||||||
return { error: "gdprNotApproved" }
|
`REGISTER :> GDPR not validated (${ReqData.username})`,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
error: "gdprNotApproved",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if exist and return
|
// Check if exist and return
|
||||||
|
|
||||||
const dbUserIfExist = await getUserFromUsername(ReqData.username)
|
const dbUserIfExist = await getUserFromUsername(
|
||||||
|
ReqData.username,
|
||||||
|
);
|
||||||
if (dbUserIfExist) {
|
if (dbUserIfExist) {
|
||||||
logger.info(`REGISTER :> User exist (${dbUserIfExist.username})\n ID:${dbUserIfExist.id}`)
|
logger.info(
|
||||||
return { error: "exist" }
|
`REGISTER :> User exist (${dbUserIfExist.username})\n ID:${dbUserIfExist.id}`,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
error: "exist",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentDate = new Date();
|
const currentDate = new Date();
|
||||||
|
|
||||||
// New UserService (class)
|
// 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.setFirstName(ReqData.firstName);
|
||||||
NewUser.setLastName(ReqData.lastName);
|
NewUser.setLastName(ReqData.lastName);
|
||||||
|
|
||||||
// JWT
|
// JWT
|
||||||
|
|
||||||
const alg = 'HS512'
|
const alg = "HS512";
|
||||||
const token = await JwtService.sign({
|
const token = await JwtService.sign(
|
||||||
sub: NewUser.id
|
{
|
||||||
}, alg,
|
sub: NewUser.id,
|
||||||
'1d',
|
},
|
||||||
'user')
|
alg,
|
||||||
|
"1d",
|
||||||
|
"user",
|
||||||
|
);
|
||||||
|
|
||||||
const userData = {
|
const userData = {
|
||||||
error: "none",
|
error: "none",
|
||||||
@ -75,45 +105,74 @@ async function register(ReqData: IReqRegister) {
|
|||||||
username: NewUser.username,
|
username: NewUser.username,
|
||||||
displayName: NewUser.displayName,
|
displayName: NewUser.displayName,
|
||||||
firstName: NewUser.firstName,
|
firstName: NewUser.firstName,
|
||||||
lastName: NewUser.lastName
|
lastName: NewUser.lastName,
|
||||||
}};
|
},
|
||||||
logger.info(userData)
|
};
|
||||||
|
logger.info(userData);
|
||||||
await Db.collection("users").insertOne(NewUser);
|
await Db.collection("users").insertOne(NewUser);
|
||||||
logger.info(`REGISTER :> Inserted new user (${NewUser.username})`)
|
logger.info(
|
||||||
return userData
|
`REGISTER :> Inserted new user (${NewUser.username})`,
|
||||||
|
);
|
||||||
|
return userData;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function login(ReqData: IReqLogin) {
|
async function login(ReqData: IReqLogin) {
|
||||||
//const passwordHash = await getHashFromPassword(sanitizedData.password);
|
//const passwordHash = await getHashFromPassword(sanitizedData.password);
|
||||||
const dbUser = await MysqlService.User.getByUsername(DbHandler, ReqData.username);
|
const dbUser = await MysqlService.User.getByUsername(
|
||||||
|
DbHandler,
|
||||||
|
ReqData.username,
|
||||||
|
);
|
||||||
if (!dbUser) {
|
if (!dbUser) {
|
||||||
console.log(`LoginService :> User does not exist (${ReqData.username})`);
|
console.log(
|
||||||
return { error: "userNotFound" };
|
`LoginService :> User does not exist (${ReqData.username})`,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
error: "userNotFound",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
if (ReqData.password.length < 6) {
|
if (ReqData.password.length < 6) {
|
||||||
console.log('X')
|
console.log("X");
|
||||||
console.log(`LoginService :> Invalid password (${ReqData.username})`);
|
console.log(
|
||||||
return { error: "invalidPassword" };
|
`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) {
|
if (!isPasswordValid) {
|
||||||
console.log(isPasswordValid)
|
console.log(isPasswordValid);
|
||||||
console.log(`LoginService :> Invalid password (${ReqData.username})`);
|
console.log(
|
||||||
return { error: "invalidPassword" };
|
`LoginService :> Invalid password (${ReqData.username})`,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
error: "invalidPassword",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
// biome-ignore lint/style/useConst: <explanation>
|
// biome-ignore lint/style/useConst: <explanation>
|
||||||
let userData = {
|
let userData = {
|
||||||
error: "none",
|
error: "none",
|
||||||
jwt: '',
|
jwt: "",
|
||||||
user: {
|
user: {
|
||||||
id: dbUser.id,
|
id: dbUser.id,
|
||||||
username: dbUser.username,
|
username: dbUser.username,
|
||||||
displayName: dbUser.displayName,
|
displayName: dbUser.displayName,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
userData.jwt = await JwtService.sign({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 :>");
|
||||||
console.log(userData);
|
console.log(userData);
|
||||||
@ -130,17 +189,17 @@ async function login(ReqData: IReqLogin) {
|
|||||||
async function getAllUsersService() {
|
async function getAllUsersService() {
|
||||||
const users = await Db.collection("users").find().toArray();
|
const users = await Db.collection("users").find().toArray();
|
||||||
// biome-ignore lint/complexity/noForEach: <explanation>
|
// biome-ignore lint/complexity/noForEach: <explanation>
|
||||||
users.forEach(user => {
|
users.forEach((user) => {
|
||||||
delete user.passwordHash
|
delete user.passwordHash;
|
||||||
delete user._id
|
delete user._id;
|
||||||
delete user.gdpr
|
delete user.gdpr;
|
||||||
});
|
});
|
||||||
logger.info(`Query ${users.length} user(s)`)
|
logger.info(`Query ${users.length} user(s)`);
|
||||||
return {
|
return {
|
||||||
iat: Date.now(),
|
iat: Date.now(),
|
||||||
users: users,
|
users: users,
|
||||||
length: users.length
|
length: users.length,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -154,19 +213,34 @@ async function getAllUsersService() {
|
|||||||
*/
|
*/
|
||||||
async function editUserService(targetId, sanitizedData) {
|
async function editUserService(targetId, sanitizedData) {
|
||||||
if (sanitizedData.password) {
|
if (sanitizedData.password) {
|
||||||
const passwordHash = await getHashFromPassword(sanitizedData.password)
|
const passwordHash = await getHashFromPassword(
|
||||||
delete sanitizedData.password
|
sanitizedData.password,
|
||||||
logger.info(`Changing password for user "${targetId}"`)
|
);
|
||||||
sanitizedData.passwordHash = passwordHash
|
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) {
|
if (updatedUserResult.modifiedCount === 0) {
|
||||||
logger.info(`EDIT :> User not found (${targetId})`);
|
logger.info(`EDIT :> User not found (${targetId})`);
|
||||||
return { error: "userNotFound" };
|
return {
|
||||||
|
error: "userNotFound",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(`EDIT :> User updated (${targetId})`);
|
logger.info(`EDIT :> User updated (${targetId})`);
|
||||||
return { error: "none" };
|
return {
|
||||||
|
error: "none",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -176,13 +250,15 @@ async function editUserService(targetId, sanitizedData) {
|
|||||||
* @return {Promise<boolean>} - A promise that resolves to true if the user is successfully deleted, or false if an error occurs.
|
* @return {Promise<boolean>} - A promise that resolves to true if the user is successfully deleted, or false if an error occurs.
|
||||||
*/
|
*/
|
||||||
async function deleteUserService(targetId) {
|
async function deleteUserService(targetId) {
|
||||||
logger.info(`Deleting user ${targetId}`)
|
logger.info(`Deleting user ${targetId}`);
|
||||||
try {
|
try {
|
||||||
await Db.collection("users").deleteOne({id: targetId});
|
await Db.collection("users").deleteOne({
|
||||||
return true
|
id: targetId,
|
||||||
|
});
|
||||||
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.warn(e)
|
logger.warn(e);
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +268,7 @@ const UserService = {
|
|||||||
getAll: getAllUsersService,
|
getAll: getAllUsersService,
|
||||||
getFromId: getUserFromIdService,
|
getFromId: getUserFromIdService,
|
||||||
edit: editUserService,
|
edit: editUserService,
|
||||||
delete: deleteUserService
|
delete: deleteUserService,
|
||||||
}
|
};
|
||||||
|
|
||||||
export default UserService;
|
export default UserService;
|
@ -1,39 +1,58 @@
|
|||||||
import JwtService from "@services/jwt.service";
|
import JwtService from "@services/jwt.service";
|
||||||
import type {NextFunction, Request, Response} from "express";
|
|
||||||
import MySqlService from "@services/mysql.service";
|
import MySqlService from "@services/mysql.service";
|
||||||
import MysqlService from "@services/mysql.service";
|
import MysqlService from "@services/mysql.service";
|
||||||
|
import type { NextFunction, Request, Response } from "express";
|
||||||
import { Logger } from "tslog";
|
import { Logger } from "tslog";
|
||||||
|
|
||||||
const DbHandler = new MySqlService.Handler('AdminGuard')
|
const DbHandler = new MySqlService.Handler("AdminGuard");
|
||||||
const logger = new Logger({name: 'AdminGuard'})
|
const logger = new Logger({
|
||||||
|
name: "AdminGuard",
|
||||||
|
});
|
||||||
|
|
||||||
const UNAUTHORIZED = 401;
|
const UNAUTHORIZED = 401;
|
||||||
const FORBIDDEN = 403;
|
const FORBIDDEN = 403;
|
||||||
const UNAUTH_MESSAGE = 'Missing Authorization Header';
|
const UNAUTH_MESSAGE = "Missing Authorization Header";
|
||||||
const INVALID_TOKEN_MESSAGE = 'Invalid or expired token.';
|
const INVALID_TOKEN_MESSAGE = "Invalid or expired token.";
|
||||||
const PERMISSON_NOT_VALID = 'You are missing the required permission.'
|
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;
|
const authHeader = req.headers.authorization;
|
||||||
if (!authHeader) {
|
if (!authHeader) {
|
||||||
logger.warn(`Invalid header (${req.ip})`)
|
logger.warn(`Invalid header (${req.ip})`);
|
||||||
return res.status(UNAUTHORIZED).json({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);
|
const token = await JwtService.verify(bearerToken);
|
||||||
|
|
||||||
if (token) {
|
if (token) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const isSourceAdmin = await MysqlService.User.getAdminStateForId(DbHandler, token.sub)
|
const isSourceAdmin =
|
||||||
|
await MysqlService.User.getAdminStateForId(
|
||||||
|
DbHandler,
|
||||||
|
token.sub,
|
||||||
|
);
|
||||||
if (isSourceAdmin === true) next();
|
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
|
export default AdminGuard;
|
||||||
|
@ -1,26 +1,37 @@
|
|||||||
import JwtService from "@services/jwt.service";
|
import JwtService from "@services/jwt.service";
|
||||||
import type {NextFunction, Request, Response} from "express";
|
|
||||||
import MySqlService from "@services/mysql.service";
|
import MySqlService from "@services/mysql.service";
|
||||||
|
import type { NextFunction, Request, Response } from "express";
|
||||||
import { Logger } from "tslog";
|
import { Logger } from "tslog";
|
||||||
|
|
||||||
const DbHandler = new MySqlService.Handler('UserGuard')
|
const DbHandler = new MySqlService.Handler("UserGuard");
|
||||||
const logger = new Logger({name: 'UserGuard'})
|
const logger = new Logger({
|
||||||
|
name: "UserGuard",
|
||||||
|
});
|
||||||
|
|
||||||
const UNAUTHORIZED = 401;
|
const UNAUTHORIZED = 401;
|
||||||
const FORBIDDEN = 403;
|
const FORBIDDEN = 403;
|
||||||
const UNAUTH_MESSAGE = 'Missing Authorization Header';
|
const UNAUTH_MESSAGE = "Missing Authorization Header";
|
||||||
const INVALID_TOKEN_MESSAGE = 'Invalid or expired token.';
|
const INVALID_TOKEN_MESSAGE = "Invalid or expired token.";
|
||||||
const USER_NOT_EXIST = 'You dont exist anymore'
|
const USER_NOT_EXIST = "You dont exist anymore";
|
||||||
|
|
||||||
async function UserGuard(req: Request, res: Response, next: NextFunction) {
|
async function UserGuard(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction,
|
||||||
|
) {
|
||||||
const authHeader = req.headers.authorization;
|
const authHeader = req.headers.authorization;
|
||||||
if (!authHeader) {
|
if (!authHeader) {
|
||||||
return res.status(UNAUTHORIZED).json({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);
|
const token = await JwtService.verify(bearerToken);
|
||||||
|
|
||||||
@ -29,16 +40,25 @@ async function UserGuard(req: Request, res: Response, next: NextFunction) {
|
|||||||
const userId = token.sub;
|
const userId = token.sub;
|
||||||
if (!userId) {
|
if (!userId) {
|
||||||
logger.error(USER_NOT_EXIST);
|
logger.error(USER_NOT_EXIST);
|
||||||
return res.status(UNAUTHORIZED).json({message: USER_NOT_EXIST});
|
return res.status(UNAUTHORIZED).json({
|
||||||
|
message: USER_NOT_EXIST,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const user= await MySqlService.User.getById(DbHandler, userId);
|
const user = await MySqlService.User.getById(
|
||||||
|
DbHandler,
|
||||||
|
userId,
|
||||||
|
);
|
||||||
if (user) {
|
if (user) {
|
||||||
logger.info(`An user do a request. (${user?.username})`)
|
logger.info(`An user do a request. (${user?.username})`);
|
||||||
next()
|
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
|
export default UserGuard;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user