Compare commits
4 Commits
355cb0ec90
...
3232e5fac1
Author | SHA1 | Date | |
---|---|---|---|
3232e5fac1 | |||
9225337e95 | |||
f1272ca2c8 | |||
4fd6c11326 |
@ -1,8 +1,9 @@
|
||||
export interface IReqRegister {
|
||||
username: string;
|
||||
displayName: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
password: string;
|
||||
dob: Date;
|
||||
email: string;
|
||||
gdpr?: boolean;
|
||||
password: string;
|
||||
}
|
||||
|
25
src/interfaces/services/ISError.ts
Normal file
25
src/interfaces/services/ISError.ts
Normal file
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Represents an error object.
|
||||
*
|
||||
* @interface ISError
|
||||
*/
|
||||
export interface ISError {
|
||||
error: ErrorType;
|
||||
message: string;
|
||||
result?: unknown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the types of errors that can occur in the application.
|
||||
*
|
||||
* @enum {number}
|
||||
*/
|
||||
export enum ErrorType {
|
||||
InvalidData = 0,
|
||||
DatabaseError = 1,
|
||||
ServiceError = 2,
|
||||
NotFound = 3,
|
||||
PasswordInvalid = 4,
|
||||
UnAuthorized = 5,
|
||||
UnexpectedError = 6,
|
||||
}
|
@ -1,10 +1,14 @@
|
||||
import type { IReqLogin } from "@interfaces/requests/IReqLogin";
|
||||
import type { IReqRegister } from "@interfaces/requests/IReqRegister";
|
||||
import type {IDbUser} from "@interfaces/database/IDbUser";
|
||||
import type {IReqLogin} from "@interfaces/requests/IReqLogin";
|
||||
import type {IReqRegister} from "@interfaces/requests/IReqRegister";
|
||||
import {ErrorType, type ISError} from "@interfaces/services/ISError";
|
||||
import CredentialService from "@services/credential.service";
|
||||
import JwtService from "@services/jwt.service";
|
||||
import MySqlService from "@services/mysql.service";
|
||||
import MysqlService from "@services/mysql.service";
|
||||
import { Logger } from "tslog";
|
||||
import {Logger} from "tslog";
|
||||
import {v4} from "uuid";
|
||||
|
||||
|
||||
const logger = new Logger({
|
||||
name: "UserService",
|
||||
@ -13,92 +17,124 @@ const logger = new Logger({
|
||||
const DbHandler = new MySqlService.Handler("UserService");
|
||||
|
||||
/**
|
||||
* Retrieves a user object from the database based on the given username.
|
||||
* Retrieves a user from the database by the given email address.
|
||||
*
|
||||
* @param {string} username - The username of the user to retrieve.
|
||||
* @returns {Promise<Object | null>} - The user object if found, or null if not found.
|
||||
* @param {string} targetEmail - The email address of the user to retrieve.
|
||||
* @returns {Promise<IDbUser | ISError>}
|
||||
* - A promise that resolves with the user.
|
||||
* - If the user is not found, an error object is returned.
|
||||
* - If an error occurs during the database operation, an error object is returned.
|
||||
*/
|
||||
async function getUserFromUsername(username: string): Promise<object | null> {
|
||||
const dbUser = await MySqlService.User.getByUsername(DbHandler, username);
|
||||
if (dbUser === undefined) return null;
|
||||
return dbUser;
|
||||
}
|
||||
|
||||
async function getUserFromIdService(id: string | undefined) {
|
||||
const dbUser = await MySqlService.User.getById(DbHandler, id);
|
||||
if (dbUser === undefined) return null;
|
||||
return dbUser;
|
||||
}
|
||||
|
||||
async function register(ReqData: IReqRegister) {
|
||||
if (ReqData.password.length < 6) {
|
||||
logger.info(`REGISTER :> Invalid password (${ReqData.username})`);
|
||||
async function getUserByEmail(targetEmail: string): Promise<IDbUser | ISError> {
|
||||
try {
|
||||
const dbUser = await MySqlService.User.getByEmail(DbHandler, targetEmail);
|
||||
if (dbUser === undefined) {
|
||||
logger.info(`User not found (${targetEmail})`);
|
||||
return {
|
||||
error: ErrorType.NotFound,
|
||||
message: "The user was not fund.",
|
||||
};
|
||||
}
|
||||
return dbUser;
|
||||
} catch (err) {
|
||||
logger.error(err);
|
||||
return {
|
||||
error: "invalidPassword",
|
||||
error: ErrorType.DatabaseError,
|
||||
message: "An unknown error occurred.",
|
||||
};
|
||||
}
|
||||
const passwordHash = await CredentialService.hash(ReqData.password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a user from the database based on the provided ID.
|
||||
*
|
||||
* @param {string} id - The ID of the user to retrieve.
|
||||
* @returns {Promise<IDbUser | ISError>} - A promise that resolves with the user object if found, or an error object if not.
|
||||
*/
|
||||
async function getUserFromIdService(id: string): Promise<IDbUser | ISError> {
|
||||
try {
|
||||
if (!id || id.length !== 36) {
|
||||
logger.info(`Invalid ID (${id})`);
|
||||
return {
|
||||
error: ErrorType.InvalidData,
|
||||
message: "Invalid ID length.",
|
||||
};
|
||||
}
|
||||
const dbUser = await MySqlService.User.getById(DbHandler, id);
|
||||
if (dbUser === undefined) {
|
||||
logger.info(`User not found (${id})`);
|
||||
return {
|
||||
error: ErrorType.NotFound,
|
||||
message: "The user was not found.",
|
||||
};
|
||||
}
|
||||
return dbUser;
|
||||
} catch (err) {
|
||||
return {
|
||||
error: ErrorType.DatabaseError,
|
||||
message: "An unknown error occurred.",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async function register(ReqData: IReqRegister): Promise<ISError | string> {
|
||||
if (ReqData.password.length < 6) {
|
||||
return {
|
||||
error: ErrorType.InvalidData,
|
||||
message: "Password must be at least 6 characters long.",
|
||||
};
|
||||
}
|
||||
const passwordHash = await CredentialService.hash(`${ReqData.password}`);
|
||||
|
||||
// Does the new user has accepted GDPR ?
|
||||
if (ReqData.gdpr !== true) {
|
||||
logger.info(`REGISTER :> GDPR not validated (${ReqData.username})`);
|
||||
return {
|
||||
error: "gdprNotApproved",
|
||||
error: ErrorType.InvalidData,
|
||||
message: "GDPR acceptance is required.",
|
||||
};
|
||||
}
|
||||
|
||||
// Check if exist and return
|
||||
|
||||
const dbUserIfExist = await getUserFromUsername(ReqData.username);
|
||||
if (dbUserIfExist) {
|
||||
logger.info(
|
||||
`REGISTER :> User exist (${dbUserIfExist.username})\n ID:${dbUserIfExist.id}`,
|
||||
);
|
||||
return {
|
||||
error: "exist",
|
||||
};
|
||||
}
|
||||
|
||||
const currentDate = new Date();
|
||||
|
||||
// New UserService (class)
|
||||
// Check if exist and return
|
||||
const dbUserIfExist: IDbUser | ISError = await getUserByEmail(ReqData.email);
|
||||
if ("error" in dbUserIfExist) {
|
||||
return {
|
||||
error: dbUserIfExist.error,
|
||||
message: dbUserIfExist.message,
|
||||
};
|
||||
}
|
||||
|
||||
const NewUser = new User(
|
||||
ReqData.username,
|
||||
ReqData.displayName,
|
||||
passwordHash,
|
||||
currentDate,
|
||||
);
|
||||
NewUser.setFirstName(ReqData.firstName);
|
||||
NewUser.setLastName(ReqData.lastName);
|
||||
const NewUser = await MySqlService.User.insert(DbHandler, {
|
||||
id: v4(),
|
||||
email: ReqData.email,
|
||||
username: ReqData.username,
|
||||
firstname: ReqData.firstName,
|
||||
lastname: ReqData.lastName,
|
||||
dob: ReqData.dob,
|
||||
hash: passwordHash,
|
||||
gdpr: currentDate,
|
||||
is_admin: false,
|
||||
is_mail_verified: false,
|
||||
});
|
||||
if ("error" in NewUser || !NewUser.id) {
|
||||
return {
|
||||
error: ErrorType.DatabaseError,
|
||||
message: 'Error when inserting user in database.'
|
||||
};
|
||||
}
|
||||
|
||||
// JWT
|
||||
|
||||
const alg = "HS512";
|
||||
const token = await JwtService.sign(
|
||||
{
|
||||
sub: NewUser.id,
|
||||
},
|
||||
alg,
|
||||
{
|
||||
alg: "HS512",
|
||||
},
|
||||
"1d",
|
||||
"user",
|
||||
);
|
||||
|
||||
const userData = {
|
||||
error: "none",
|
||||
jwt: token,
|
||||
user: {
|
||||
id: NewUser.id,
|
||||
username: NewUser.username,
|
||||
displayName: NewUser.displayName,
|
||||
firstName: NewUser.firstName,
|
||||
lastName: NewUser.lastName,
|
||||
},
|
||||
};
|
||||
logger.info(userData);
|
||||
await Db.collection("users").insertOne(NewUser);
|
||||
logger.info(`REGISTER :> Inserted new user (${NewUser.username})`);
|
||||
return userData;
|
||||
return token;
|
||||
}
|
||||
|
||||
async function login(ReqData: IReqLogin) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user