Compare commits
11 Commits
5163d79056
...
1723a8588a
| Author | SHA1 | Date | |
|---|---|---|---|
| 1723a8588a | |||
| 3fe6453b0c | |||
| 98477c5f27 | |||
| 3472c59ac2 | |||
| 3b6726113d | |||
| d78b0aec4c | |||
| ae6b25fbd6 | |||
| d7f9cb0b37 | |||
| cb1c2ee87c | |||
| 23ce32cb6f | |||
| f6d18fc58d |
@ -1,7 +1,9 @@
|
|||||||
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 type { IReqRegister } from "@interfaces/requests/IReqRegister";
|
||||||
import UserService from "@services/user.service";
|
import UserService from "@services/user.service";
|
||||||
|
import { isEmail } from "@utils/validators/email";
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { Logger } from "tslog";
|
import { Logger } from "tslog";
|
||||||
|
|
||||||
@ -9,21 +11,8 @@ const logger = new Logger({
|
|||||||
name: "AuthController",
|
name: "AuthController",
|
||||||
});
|
});
|
||||||
|
|
||||||
//FIX Better return object interface
|
|
||||||
/**
|
|
||||||
* Registers a user with the given request data.
|
|
||||||
*
|
|
||||||
* @param {Request} req - The request object containing user data.
|
|
||||||
* @param {Response} res - The response object to send the registration result.
|
|
||||||
*
|
|
||||||
* @return {Promise} A promise that resolves to the registration result.
|
|
||||||
* It can have the following properties:
|
|
||||||
* - error: "gdprNotApproved" if GDPR is not approved
|
|
||||||
* - error: "exist" if the user already exists
|
|
||||||
* - 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: IReqRegister = req.body;
|
||||||
if (!body) {
|
if (!body) {
|
||||||
logger.warn(`Invalid input data (${req.ip})`);
|
logger.warn(`Invalid input data (${req.ip})`);
|
||||||
return res.type("application/json").status(400).json({
|
return res.type("application/json").status(400).json({
|
||||||
@ -35,7 +24,7 @@ async function registerUser(req: Request, res: Response): Promise<unknown> {
|
|||||||
!body.username ||
|
!body.username ||
|
||||||
!body.firstName ||
|
!body.firstName ||
|
||||||
!body.lastName ||
|
!body.lastName ||
|
||||||
!body.displayName
|
!body.email
|
||||||
) {
|
) {
|
||||||
logger.warn(`Field(s) missing (${req.ip})`);
|
logger.warn(`Field(s) missing (${req.ip})`);
|
||||||
return res.type("application/json").status(400).json({
|
return res.type("application/json").status(400).json({
|
||||||
@ -43,13 +32,20 @@ async function registerUser(req: Request, res: Response): Promise<unknown> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isEmail(body.email)) {
|
||||||
|
logger.warn(`Invalid email format (${req.ip})`);
|
||||||
|
return res.type("application/json").status(400).json({
|
||||||
|
error: "Invalid email format",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let gdpr = false;
|
let gdpr = false;
|
||||||
if (body.gdpr === true) {
|
if (body.gdpr === true) {
|
||||||
gdpr = true;
|
gdpr = true;
|
||||||
}
|
}
|
||||||
const sanitizeData = {
|
const sanitizeData: IReqRegister = {
|
||||||
username: `${body.username}`,
|
username: `${body.username}`,
|
||||||
displayName: `${body.displayName}`,
|
email: `${body.email.toLowerCase()}`,
|
||||||
gdpr: gdpr,
|
gdpr: gdpr,
|
||||||
password: `${body.password}`,
|
password: `${body.password}`,
|
||||||
firstName: `${body.firstName}`,
|
firstName: `${body.firstName}`,
|
||||||
@ -74,7 +70,7 @@ async function registerUser(req: Request, res: Response): Promise<unknown> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SUCCESS
|
// SUCCESS
|
||||||
logger.info(`User registered successfully (${req.ip})`);
|
logger.info(`User registered successfully (${sanitizeData.username})`);
|
||||||
return res.type("application/json").status(201).json(RegisterServiceResult);
|
return res.type("application/json").status(201).json(RegisterServiceResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,6 +14,12 @@ export interface IDbFactorizeOutput {
|
|||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
_keysTemplate: string;
|
_keysTemplate: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of ? for the "VALUE" section
|
||||||
|
*/
|
||||||
|
_questionMarksFields: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The total number of fields.
|
* The total number of fields.
|
||||||
*
|
*
|
||||||
@ -45,4 +51,4 @@ export interface IDbFactorizeInput {
|
|||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
throwOnError?: true;
|
throwOnError?: true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ export interface IDbUser {
|
|||||||
lastname: string;
|
lastname: string;
|
||||||
dob: Date;
|
dob: Date;
|
||||||
email: string;
|
email: string;
|
||||||
is_mail_verified: boolean;
|
is_email_verified: boolean;
|
||||||
is_admin: boolean;
|
is_admin: boolean;
|
||||||
gdpr: Date;
|
gdpr: Date;
|
||||||
hash: string;
|
hash: string;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
export interface IReqLogin {
|
export interface IReqLogin {
|
||||||
username: string;
|
email: string;
|
||||||
password: string;
|
password: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@ export interface IReqRegister {
|
|||||||
username: string;
|
username: string;
|
||||||
firstName: string;
|
firstName: string;
|
||||||
lastName: string;
|
lastName: string;
|
||||||
dob: Date;
|
/*dob: Date;*/
|
||||||
email: string;
|
email: string;
|
||||||
gdpr?: boolean;
|
gdpr?: boolean;
|
||||||
password: string;
|
password: string;
|
||||||
|
|||||||
@ -1,14 +1,18 @@
|
|||||||
import process from "node:process";
|
import process from "node:process";
|
||||||
import type { IDbBrand } from "@interfaces/database/IDbBrand";
|
import type { IDbBrand } from "@interfaces/database/IDbBrand";
|
||||||
import type { IDbCategory } from "@interfaces/database/IDbCategory";
|
import type { IDbCategory } from "@interfaces/database/IDbCategory";
|
||||||
|
import type {
|
||||||
|
IDbFactorizeInput,
|
||||||
|
IDbFactorizeOutput,
|
||||||
|
} from "@interfaces/database/IDbFactorize";
|
||||||
import type { IDbModel } from "@interfaces/database/IDbModel";
|
import type { IDbModel } from "@interfaces/database/IDbModel";
|
||||||
import type { IDbStatusResult } from "@interfaces/database/IDbStatusResult";
|
import type { IDbStatusResult } from "@interfaces/database/IDbStatusResult";
|
||||||
import type { IDbUser } from "@interfaces/database/IDbUser";
|
import type { IDbUser } from "@interfaces/database/IDbUser";
|
||||||
import type { IDbVehicle } from "@interfaces/database/IDbVehicle";
|
import type { IDbVehicle } from "@interfaces/database/IDbVehicle";
|
||||||
|
import type { IUserUpdate } from "@interfaces/services/IUserUpdate";
|
||||||
import mysql, { type Connection, type ConnectionOptions } from "mysql2";
|
import mysql, { type Connection, type ConnectionOptions } from "mysql2";
|
||||||
import { Logger } from "tslog";
|
import { Logger } from "tslog";
|
||||||
import {IUserUpdate} from "@interfaces/services/IUserUpdate";
|
import { v4 } from "uuid";
|
||||||
import {IDbFactorizeInput, IDbFactorizeOutput} from "@interfaces/database/IDbFactorize";
|
|
||||||
|
|
||||||
const access: ConnectionOptions = {
|
const access: ConnectionOptions = {
|
||||||
host: `${process.env["MYSQL_HOST"]}`,
|
host: `${process.env["MYSQL_HOST"]}`,
|
||||||
@ -20,7 +24,7 @@ const access: ConnectionOptions = {
|
|||||||
|
|
||||||
class MysqlHandler {
|
class MysqlHandler {
|
||||||
private readonly handlerName: string;
|
private readonly handlerName: string;
|
||||||
private Logger: Logger<unknown>;
|
Logger: Logger<unknown>;
|
||||||
private Connection: Connection;
|
private Connection: Connection;
|
||||||
|
|
||||||
constructor(handlerName?: string) {
|
constructor(handlerName?: string) {
|
||||||
@ -34,7 +38,9 @@ class MysqlHandler {
|
|||||||
this.Logger.error(`Error connecting to MySQL: ${err}`);
|
this.Logger.error(`Error connecting to MySQL: ${err}`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
this.Logger.info(`\n\n> Connected to MySQL database (${access.database})\n`);
|
this.Logger.info(
|
||||||
|
`\n\n> Connected to MySQL database (${access.database})\n`,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
closeConnection() {
|
closeConnection() {
|
||||||
@ -62,32 +68,47 @@ class MysqlHandler {
|
|||||||
* @return {Promise<IDbFactorizeOutput>} - A promise resolving to the factorized output.
|
* @return {Promise<IDbFactorizeOutput>} - A promise resolving to the factorized output.
|
||||||
*/
|
*/
|
||||||
factorize(data: IDbFactorizeInput): Promise<IDbFactorizeOutput> {
|
factorize(data: IDbFactorizeInput): Promise<IDbFactorizeOutput> {
|
||||||
return new Promise((resolve, reject)=>{
|
return new Promise((resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
|
let _id = "";
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
data.values.id ? delete data.values.id : null;
|
if (data.values.id) {
|
||||||
const _sqlQueryKeys = Object.keys(data.values).map((key: string) => {
|
// @ts-ignore
|
||||||
if (key !== 'id') {
|
_id = data.values.id;
|
||||||
return `\'${key}\' = ?`
|
// @ts-ignore
|
||||||
}
|
delete data.values.id;
|
||||||
return '';
|
}
|
||||||
})
|
const _sqlQueryKeys = Object.keys(data.values).map(
|
||||||
const values = Object.values(data.values).map((val)=>val)
|
(key: string) => `${key}`,
|
||||||
this.Logger.debug(`\n\n>-> Factorized ${_sqlQueryKeys.length} keys for a prepare Query.\n>-> Action: ${data.actionName}\n`)
|
);
|
||||||
const sqlQueryKeys = _sqlQueryKeys.join(', ')
|
const values = Object.values(data.values).map((val) => val);
|
||||||
|
this.Logger.debug(
|
||||||
|
`\n\n>-> Factorized ${_sqlQueryKeys.length} keys for a prepare Query.\n>-> Action: ${data.actionName}\n`,
|
||||||
|
);
|
||||||
|
const sqlQueryKeys = _sqlQueryKeys.join(", ");
|
||||||
|
if (_id && _id.length > 2) {
|
||||||
|
this.Logger.trace(`Id post-pushed in factorized data`);
|
||||||
|
values.push(_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
const questionMarksFields = Array(values.length)
|
||||||
|
.fill("?")
|
||||||
|
.join(", ")
|
||||||
|
.toString();
|
||||||
|
|
||||||
const factorizedOutput: IDbFactorizeOutput = {
|
const factorizedOutput: IDbFactorizeOutput = {
|
||||||
_keysTemplate: sqlQueryKeys,
|
_keysTemplate: sqlQueryKeys,
|
||||||
|
_questionMarksFields: questionMarksFields,
|
||||||
totalFields: _sqlQueryKeys.length,
|
totalFields: _sqlQueryKeys.length,
|
||||||
_valuesArray: values
|
_valuesArray: values,
|
||||||
}
|
};
|
||||||
resolve(factorizedOutput);
|
resolve(factorizedOutput);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (data.throwOnError) throw new Error(`${err}`)
|
if (data.throwOnError) throw new Error(`${err}`);
|
||||||
this.Logger.error(`\n|\n${err}\n|`)
|
this.Logger.error(`\n|\n${err}\n|`);
|
||||||
reject(`${err}`)
|
reject(`${err}`);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -155,27 +176,41 @@ const MySqlService = {
|
|||||||
if (!data.id) return reject("Id is undefined");
|
if (!data.id) return reject("Id is undefined");
|
||||||
if (data.id.length !== 36) return reject("Id invalid");
|
if (data.id.length !== 36) return reject("Id invalid");
|
||||||
|
|
||||||
const _sql =
|
// const _values = [
|
||||||
"INSERT INTO `users`(`id`,`username`, `firstname`, `lastname`, `dob`, `email`, `is_mail_verified`, `is_admin`, `gdpr`, `hash`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
// data.id,
|
||||||
const _values = [
|
// data.username,
|
||||||
data.id,
|
// data.firstname,
|
||||||
data.username,
|
// data.lastname,
|
||||||
data.firstname,
|
// data.dob,
|
||||||
data.lastname,
|
// data.email,
|
||||||
data.dob,
|
// data.is_mail_verified,
|
||||||
data.email,
|
// data.is_admin,
|
||||||
data.is_mail_verified,
|
// data.gdpr,
|
||||||
data.is_admin,
|
// data.hash,
|
||||||
data.gdpr,
|
// ];
|
||||||
data.hash,
|
|
||||||
];
|
handler
|
||||||
try {
|
.factorize({
|
||||||
handler.execute(_sql, _values).then((result) => {
|
values: data,
|
||||||
return resolve(result as unknown as IDbStatusResult);
|
actionName: "Inserting new user",
|
||||||
|
})
|
||||||
|
.then((result) => {
|
||||||
|
const valuesArray = result._valuesArray;
|
||||||
|
const template = result._keysTemplate;
|
||||||
|
const _sql = `INSERT INTO users (${template + `, id`}) VALUES(${
|
||||||
|
result._questionMarksFields
|
||||||
|
})`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
handler.Logger.trace(_sql);
|
||||||
|
handler.Logger.trace(valuesArray);
|
||||||
|
handler.execute(_sql, valuesArray).then((result) => {
|
||||||
|
return resolve(result as unknown as IDbStatusResult);
|
||||||
|
});
|
||||||
|
} catch (err: unknown) {
|
||||||
|
reject(err as Error);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} catch (err: unknown) {
|
|
||||||
reject(err as Error);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -188,38 +223,37 @@ const MySqlService = {
|
|||||||
*/
|
*/
|
||||||
update(handler: MysqlHandler, data: IUserUpdate): Promise<IDbStatusResult> {
|
update(handler: MysqlHandler, data: IUserUpdate): Promise<IDbStatusResult> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
if (data.gdpr && typeof data.gdpr !== typeof Date) {
|
||||||
|
return reject("Invalid gdpr date.");
|
||||||
|
}
|
||||||
if (!data.id) return reject("Id is undefined");
|
if (!data.id) return reject("Id is undefined");
|
||||||
if (data.id.length !== 36) return reject("Id invalid");
|
if (data.id.length !== 36) return reject("Id invalid");
|
||||||
if (data.gdpr && typeof data.gdpr !== typeof Date) {
|
|
||||||
return reject("Invalid gdpr date.")
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
const _values = [];
|
handler
|
||||||
const _template = `
|
.factorize({
|
||||||
${data.username ? "`username` = ?," && _values.push(data.username) as unknown as void : null}
|
values: data,
|
||||||
${data.firstname ? "`firstname` = ?," : null}
|
actionName: `Update user ID::${data.id}`,
|
||||||
${data.lastname ? "`lastname` = ?," : null}
|
})
|
||||||
${data.dob ? "`dob` = ?," : null}
|
.then((result) => {
|
||||||
${data.gdpr ? "`gdpr` = ?," : null}`
|
const _sql = `UPDATE "users" SET ${result._keysTemplate} WHERE 'id' = '${data.id}'`;
|
||||||
|
handler.execute(_sql, result._valuesArray).then((result) => {
|
||||||
const _sql = `UPDATE "users" SET ${_template} WHERE 'id' = ?`;
|
return resolve(result as unknown as IDbStatusResult);
|
||||||
handler.execute(_sql, _values).then((result) => {
|
});
|
||||||
return resolve(result as unknown as IDbStatusResult);
|
});
|
||||||
});
|
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
reject(err as Error);
|
reject(err as Error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
getById(handler: MysqlHandler, userId: string): Promise<IDbUser> {
|
getById(handler: MysqlHandler, userId: string): Promise<Array<IDbUser>> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (userId.length !== 36) return reject("Id invalid");
|
if (userId.length !== 36) return reject("Id invalid");
|
||||||
const _sql = "SELECT * FROM `users` WHERE `id` = ?";
|
const _sql = "SELECT * FROM `users` WHERE `id` = ?";
|
||||||
const _values = [userId];
|
const _values = [userId];
|
||||||
try {
|
try {
|
||||||
handler.execute(_sql, _values).then((result) => {
|
handler.execute(_sql, _values).then((result) => {
|
||||||
return resolve(result as unknown as IDbUser);
|
return resolve(result as unknown as Array<IDbUser>);
|
||||||
});
|
});
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
reject(err as Error);
|
reject(err as Error);
|
||||||
@ -252,17 +286,17 @@ const MySqlService = {
|
|||||||
*
|
*
|
||||||
* @param {MysqlHandler} handler - The MySQL database handler instance.
|
* @param {MysqlHandler} handler - The MySQL database handler instance.
|
||||||
* @param {string} email - The email of the user to retrieve.
|
* @param {string} email - The email of the user to retrieve.
|
||||||
* @return {Promise<IDbUser>} - A promise that resolves to the retrieved user object.
|
* @return {Promise<Array<IDbUser>>} - A promise that resolves to the retrieved user object.
|
||||||
* @throws {Error} - If an error occurs while retrieving the user.
|
* @throws {Error} - If an error occurs while retrieving the user.
|
||||||
*/
|
*/
|
||||||
getByEmail(handler: MysqlHandler, email: string): Promise<IDbUser> {
|
getByEmail(handler: MysqlHandler, email: string): Promise<Array<IDbUser>> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!email) return reject("email is undefined");
|
if (!email) return reject("email is undefined");
|
||||||
const _sql = "SELECT * FROM `users` WHERE `email` = ?";
|
const _sql = "SELECT * FROM `users` WHERE `email` = ?";
|
||||||
const _values = [email];
|
const _values = [email];
|
||||||
try {
|
try {
|
||||||
handler.execute(_sql, _values).then((result) => {
|
handler.execute(_sql, _values).then((result) => {
|
||||||
return resolve(result as unknown as IDbUser);
|
return resolve(result as unknown as Array<IDbUser>);
|
||||||
});
|
});
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
reject(err as Error);
|
reject(err as Error);
|
||||||
@ -364,16 +398,18 @@ const MySqlService = {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!data.id) return reject("Id is undefined");
|
if (!data.id) return reject("Id is undefined");
|
||||||
if (data.id.length !== 36) return reject("Id invalid");
|
if (data.id.length !== 36) return reject("Id invalid");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
handler.factorize({
|
handler
|
||||||
values: data,
|
.factorize({
|
||||||
actionName: `Update user ID::${data.id}`
|
values: data,
|
||||||
})
|
actionName: `Update brand ID::${data.id}`,
|
||||||
const _sql = `UPDATE "brands" SET ${_template} WHERE 'id' = ?`;
|
})
|
||||||
handler.execute(_sql, _values).then((result) => {
|
.then((result) => {
|
||||||
return resolve(result as unknown as IDbStatusResult);
|
const _sql = `UPDATE "brands" SET ${result._keysTemplate} WHERE 'id' = '${data.id}'`;
|
||||||
});
|
handler.execute(_sql, result._valuesArray).then((result) => {
|
||||||
|
return resolve(result as unknown as IDbStatusResult);
|
||||||
|
});
|
||||||
|
});
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
reject(err as Error);
|
reject(err as Error);
|
||||||
}
|
}
|
||||||
@ -586,31 +622,18 @@ const MySqlService = {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!data.id) return reject("Id is undefined");
|
if (!data.id) return reject("Id is undefined");
|
||||||
if (data.id.length !== 36) return reject("Id invalid");
|
if (data.id.length !== 36) return reject("Id invalid");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const _template = `
|
handler
|
||||||
${data.slug_name ? "`slug_name` = ?," : null}
|
.factorize({
|
||||||
${data.display_name ? "`display_name` = ?," : null}
|
values: data,
|
||||||
${data.brand_id ? "`brand_id` = ?," : null}
|
actionName: `Update users ID::${data.id}`,
|
||||||
${data.category_id ? "`category_id` = ?," : null}
|
})
|
||||||
${data.image_blob ? "`image_blob` = ?," : null}
|
.then((result) => {
|
||||||
${data.is_trending ? "`is_trending` = ?," : null}
|
const _sql = `UPDATE "users" SET ${result._keysTemplate} WHERE 'id' = '${data.id}'`;
|
||||||
${data.base_price ? "`base_price` = ?," : null}`;
|
handler.execute(_sql, result._valuesArray).then((result) => {
|
||||||
|
return resolve(result as unknown as IDbStatusResult);
|
||||||
const _values = [
|
});
|
||||||
data.slug_name,
|
});
|
||||||
data.display_name,
|
|
||||||
data.brand_id,
|
|
||||||
data.category_id,
|
|
||||||
data.image_blob,
|
|
||||||
data.is_trending,
|
|
||||||
data.base_price,
|
|
||||||
data.id,
|
|
||||||
];
|
|
||||||
const _sql = `UPDATE "models" SET ${_template} WHERE 'id' = ?`;
|
|
||||||
handler.execute(_sql, _values).then((result) => {
|
|
||||||
return resolve(result as unknown as IDbStatusResult);
|
|
||||||
});
|
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
reject(err as Error);
|
reject(err as Error);
|
||||||
}
|
}
|
||||||
@ -686,25 +709,18 @@ const MySqlService = {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!data.id) return reject("Id is undefined");
|
if (!data.id) return reject("Id is undefined");
|
||||||
if (data.id.length !== 36) return reject("Id invalid");
|
if (data.id.length !== 36) return reject("Id invalid");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const _template = `
|
handler
|
||||||
${data.model_id ? "`model_id` = ?," : null}
|
.factorize({
|
||||||
${data.plate_number ? "`plate_number` = ?," : null}
|
values: data,
|
||||||
${data.odometer ? "`odometer` = ?," : null}
|
actionName: `Update vehicle ID::${data.id}`,
|
||||||
${data.health_state ? "`health_state` = ?," : null}`;
|
})
|
||||||
|
.then((result) => {
|
||||||
const _values = [
|
const _sql = `UPDATE "vehicles" SET ${result._keysTemplate} WHERE 'id' = '${data.id}'`;
|
||||||
data.model_id,
|
handler.execute(_sql, result._valuesArray).then((result) => {
|
||||||
data.plate_number,
|
return resolve(result as unknown as IDbStatusResult);
|
||||||
data.odometer,
|
});
|
||||||
data.health_state,
|
});
|
||||||
data.id,
|
|
||||||
];
|
|
||||||
const _sql = `UPDATE "vehicles" SET ${_template} WHERE 'id' = ?`;
|
|
||||||
handler.execute(_sql, _values).then((result) => {
|
|
||||||
return resolve(result as unknown as IDbStatusResult);
|
|
||||||
});
|
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
reject(err as Error);
|
reject(err as Error);
|
||||||
}
|
}
|
||||||
@ -813,17 +829,18 @@ const MySqlService = {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!data.id) return reject("Id is undefined");
|
if (!data.id) return reject("Id is undefined");
|
||||||
if (data.id.length !== 36) return reject("Id invalid");
|
if (data.id.length !== 36) return reject("Id invalid");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const _template = `
|
handler
|
||||||
${data.slug_name ? "`slug_name` = ?," : null}
|
.factorize({
|
||||||
${data.display_name ? "`display_name` = ?," : null}`;
|
values: data,
|
||||||
|
actionName: `Update category ID::${data.id}`,
|
||||||
const _values = [data.slug_name, data.display_name, data.id];
|
})
|
||||||
const _sql = `UPDATE "categories" SET ${_template} WHERE 'id' = ?`;
|
.then((result) => {
|
||||||
handler.execute(_sql, _values).then((result) => {
|
const _sql = `UPDATE "categories" SET ${result._keysTemplate} WHERE 'id' = '${data.id}'`;
|
||||||
return resolve(result as unknown as IDbStatusResult);
|
handler.execute(_sql, result._valuesArray).then((result) => {
|
||||||
});
|
return resolve(result as unknown as IDbStatusResult);
|
||||||
|
});
|
||||||
|
});
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
reject(err as Error);
|
reject(err as Error);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,14 +26,18 @@ const DbHandler = new MySqlService.Handler("UserService");
|
|||||||
async function getUserByEmail(targetEmail: string): Promise<IDbUser | ISError> {
|
async function getUserByEmail(targetEmail: string): Promise<IDbUser | ISError> {
|
||||||
try {
|
try {
|
||||||
const dbUser = await MySqlService.User.getByEmail(DbHandler, targetEmail);
|
const dbUser = await MySqlService.User.getByEmail(DbHandler, targetEmail);
|
||||||
if (dbUser === undefined) {
|
if (dbUser.length === 0) {
|
||||||
logger.info(`\n\n> User not found (${targetEmail})\n`);
|
logger.info(`\n\n> User not found (${targetEmail})\n`);
|
||||||
return {
|
return {
|
||||||
error: ErrorType.NotFound,
|
error: ErrorType.NotFound,
|
||||||
message: "The user was not fund.",
|
message: "The user was not fund.",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return dbUser;
|
if (dbUser.length === 1 && dbUser[0]) return dbUser[0];
|
||||||
|
return {
|
||||||
|
error: ErrorType.ServiceError,
|
||||||
|
message: "To many user found, suspicious.",
|
||||||
|
};
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(err);
|
logger.error(err);
|
||||||
return {
|
return {
|
||||||
@ -135,17 +139,18 @@ async function register(inputData: IReqRegister): Promise<ISError | string> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
const currentId = v4();
|
const currentId = v4();
|
||||||
|
logger.info(`\n\n> Trying to insert a new user... (${currentId})\n`);
|
||||||
const NewUser = await MySqlService.User.insert(DbHandler, {
|
const NewUser = await MySqlService.User.insert(DbHandler, {
|
||||||
id: currentId,
|
id: currentId,
|
||||||
email: inputData.email,
|
email: inputData.email,
|
||||||
username: inputData.username,
|
username: inputData.username,
|
||||||
firstname: inputData.firstName,
|
firstname: inputData.firstName,
|
||||||
lastname: inputData.lastName,
|
lastname: inputData.lastName,
|
||||||
dob: inputData.dob,
|
dob: new Date(),
|
||||||
hash: passwordHash,
|
hash: passwordHash,
|
||||||
gdpr: currentDate,
|
gdpr: currentDate,
|
||||||
is_admin: false,
|
is_admin: false,
|
||||||
is_mail_verified: false,
|
is_email_verified: false,
|
||||||
});
|
});
|
||||||
if ("error" in NewUser || NewUser.affectedRows === 0) {
|
if ("error" in NewUser || NewUser.affectedRows === 0) {
|
||||||
return {
|
return {
|
||||||
@ -153,7 +158,9 @@ async function register(inputData: IReqRegister): Promise<ISError | string> {
|
|||||||
message: "Error when inserting user in database.",
|
message: "Error when inserting user in database.",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
logger.info(`\n\n> New user created ! (${inputData.username}::${currentId})\n`);
|
logger.info(
|
||||||
|
`\n\n> New user created ! (${inputData.username}::${currentId})\n`,
|
||||||
|
);
|
||||||
|
|
||||||
// JWT
|
// JWT
|
||||||
const token = await JwtService.sign(
|
const token = await JwtService.sign(
|
||||||
@ -204,7 +211,7 @@ async function login(inputData: IReqLogin): Promise<ISError | string> {
|
|||||||
}
|
}
|
||||||
const isPasswordValid = await CredentialService.compare(
|
const isPasswordValid = await CredentialService.compare(
|
||||||
inputData.password,
|
inputData.password,
|
||||||
dbUser.hash
|
dbUser.hash,
|
||||||
);
|
);
|
||||||
if (!isPasswordValid) {
|
if (!isPasswordValid) {
|
||||||
return {
|
return {
|
||||||
@ -215,16 +222,18 @@ async function login(inputData: IReqLogin): Promise<ISError | string> {
|
|||||||
const token = await JwtService.sign(
|
const token = await JwtService.sign(
|
||||||
{
|
{
|
||||||
sub: dbUser.id,
|
sub: dbUser.id,
|
||||||
p: [{
|
p: [
|
||||||
isAdmin: dbUser.is_admin,
|
{
|
||||||
gdpr: dbUser.gdpr
|
isAdmin: dbUser.is_admin,
|
||||||
}]
|
gdpr: dbUser.gdpr,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
alg: "HS512",
|
alg: "HS512",
|
||||||
},
|
},
|
||||||
"1d",
|
"1d",
|
||||||
"user"
|
"user",
|
||||||
);
|
);
|
||||||
return token;
|
return token;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -236,6 +245,16 @@ async function login(inputData: IReqLogin): Promise<ISError | string> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getByEmailService(email: string): Promise<IDbUser | false> {
|
||||||
|
const dbUser = await MySqlService.User.getByEmail(DbHandler, email);
|
||||||
|
if (dbUser === undefined) {
|
||||||
|
logger.trace(`\n\n> User not found in DB (${email})\n`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
logger.trace(dbUser);
|
||||||
|
return dbUser;
|
||||||
|
}
|
||||||
|
|
||||||
//TOTest
|
//TOTest
|
||||||
/**
|
/**
|
||||||
* Retrieves all users from the database.
|
* Retrieves all users from the database.
|
||||||
@ -255,34 +274,37 @@ async function getAllUsersService(): Promise<Array<IDbUser> | ISError> {
|
|||||||
return allUsers;
|
return allUsers;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(`\n\n${err}\n`);
|
logger.error(`\n\n${err}\n`);
|
||||||
return {
|
return {
|
||||||
error: ErrorType.DatabaseError,
|
error: ErrorType.DatabaseError,
|
||||||
message: "An unknown error occurred.",
|
message: "An unknown error occurred.",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function editUserService(targetId, inputData: IDbUser): Promise<ISError | boolean> {
|
async function editUserService(
|
||||||
|
targetId,
|
||||||
|
inputData: IDbUser,
|
||||||
|
): Promise<ISError | boolean> {
|
||||||
if (!targetId || targetId.length !== 36) {
|
if (!targetId || targetId.length !== 36) {
|
||||||
logger.info(`\n\n> Invalid ID (${targetId})\n`);
|
logger.info(`\n\n> Invalid ID (${targetId})\n`);
|
||||||
return {
|
return {
|
||||||
error: ErrorType.InvalidData,
|
error: ErrorType.InvalidData,
|
||||||
message: "Invalid ID length.",
|
message: "Invalid ID length.",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const dbUser = await MySqlService.User.getById(DbHandler, targetId)
|
const dbUser = await MySqlService.User.getById(DbHandler, targetId);
|
||||||
if (!dbUser.id) {
|
if (!dbUser.id) {
|
||||||
return {
|
return {
|
||||||
error: ErrorType.NotFound,
|
error: ErrorType.NotFound,
|
||||||
message: "User not found.",
|
message: "User not found.",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const result = await MySqlService.User.update(DbHandler, {
|
const result = await MySqlService.User.update(DbHandler, {
|
||||||
username: inputData.username,
|
username: inputData.username,
|
||||||
firstname: inputData.firstname,
|
firstname: inputData.firstname,
|
||||||
lastname: inputData.lastname,
|
lastname: inputData.lastname,
|
||||||
dob: inputData.dob,
|
dob: inputData.dob,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -311,6 +333,7 @@ const UserService = {
|
|||||||
login: login,
|
login: login,
|
||||||
getAll: getAllUsersService,
|
getAll: getAllUsersService,
|
||||||
getFromId: getUserFromIdService,
|
getFromId: getUserFromIdService,
|
||||||
|
getByEmail: getByEmailService,
|
||||||
edit: editUserService,
|
edit: editUserService,
|
||||||
delete: deleteUserService,
|
delete: deleteUserService,
|
||||||
};
|
};
|
||||||
|
|||||||
5
src/utils/validators/email.ts
Normal file
5
src/utils/validators/email.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export function isEmail(email: string) {
|
||||||
|
const re =
|
||||||
|
/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||||
|
return re.test(String(email).toLowerCase());
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user