diff --git a/package.json b/package.json index 93f000a..ca489f9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sikka/hajar", - "version": "1.0.81", + "version": "1.0.82", "description": "Toolkit to create SaaS applications", "author": "Sikka Software (http://sikka.io)", "license": "MIT", diff --git a/src/core/authentication/index.js b/src/core/authentication/index.js index 798c6ce..3097c7b 100644 --- a/src/core/authentication/index.js +++ b/src/core/authentication/index.js @@ -1,3 +1,5 @@ +const { default: CustomError } = require("../../utils/customError"); + class HajarAuth { constructor(options) { this.jwt = options.jwt; @@ -13,7 +15,11 @@ class HajarAuth { // modified const userExists = await this.User.findOne({ email }); if (userExists) { - throw new Error("User with this email already exists"); + throw new CustomError( + "User with this email already exists", + "user-already-exist", + { email: email } + ); } const role = await this.Role.find({ name: "Admin" }); const RoleId = role._id; @@ -36,7 +42,10 @@ class HajarAuth { async createRole(roleName, permissionIds) { const existingRole = await this.Role.findOne({ name: roleName }); if (existingRole) { - throw new Error(`Role ${roleName} already exists`); + // throw new Error(`Role ${roleName} already exists`); + throw new CustomError("Role already exists", "role-already-exist", { + role: roleName, + }); } let idPermissions = []; for (let i = 0; i < permissionIds.length; i++) { @@ -65,7 +74,11 @@ class HajarAuth { async signin(email, password, res) { const user = await this.User.findOne({ email }); if (!user) { - throw new Error("Invalid email or password"); + // throw new Error("Invalid email or password"); + throw new CustomError( + "Invalid email or password", + "invalid-email-password" + ); } const isPasswordCorrect = await this.bcrypt.compare( @@ -73,7 +86,11 @@ class HajarAuth { user.password ); if (!isPasswordCorrect) { - throw new Error("Invalid email or password"); + // throw new Error("Invalid email or password"); + throw new CustomError( + "Invalid email or password", + "invalid-email-password" + ); } const token = this.jwt.sign({ userId: user._id }, this.secret); @@ -98,12 +115,14 @@ class HajarAuth { const user = await this.User.findById(decodedToken.userId); if (!user) { console.error(`User not found for ID ${decodedToken.userId}`); - return { error: "User not found" }; + // return { error: "User not found" }; + return new CustomError("User not found", "user-not-found"); } return user; } catch (err) { console.error("JWT verification error:", err); - return { error: "Invalid token" }; + // return { error: "Invalid token" }; + return new CustomError("Invalid user token", "invalid-user-token"); } } @@ -116,7 +135,10 @@ class HajarAuth { }, }); if (!user) { - throw new Error(`User with email ${email} not found`); + // throw new Error(`User with email ${email} not found`); + throw new CustomError("User not found", "user-not-found", { + email: email, + }); } return user; @@ -130,7 +152,10 @@ class HajarAuth { }, }); if (!user) { - throw new Error(`User with ID ${userId} not found`); + // throw new Error(`User with ID ${userId} not found`); + throw new CustomError("User not found", "user-not-found", { + userID: userId, + }); } return user; @@ -138,16 +163,25 @@ class HajarAuth { async getRoleById(middelware, roleId) { if (!middelware.Types.ObjectId.isValid(roleId)) { - throw new Error("Invalid roleId"); + // throw new Error("Invalid roleId"); + throw new CustomError("Invalid Role ID", "invalid-role", { + roleID: roleId, + }); } try { const role = await this.Role.findOne({ _id: roleId }); if (!role) { - throw new Error("Role not found"); + // throw new Error("Role not found"); + throw new CustomError("Role not found", "role-not-found", { + roleID: roleId, + }); } return role; } catch (error) { - throw new Error(`Unable to fetch role: ${error.message}`); + // throw new Error(`Unable to fetch role: ${error.message}`); + throw new CustomError(error.message, "fetch-role-error", { + roleID: roleId, + }); } } // Fetch all roles from the database @@ -156,7 +190,8 @@ class HajarAuth { const roles = await this.Role.find(); return roles; } catch (error) { - throw new Error(`Unable to fetch roles: ${error.message}`); + // throw new Error(`Unable to fetch roles: ${error.message}`); + throw new CustomError(error.message, "fetch-role-error"); } } @@ -165,17 +200,24 @@ class HajarAuth { try { const role = await this.Role.findByIdAndRemove(roleId); if (!role) { - throw new Error("Role not found"); + // throw new Error("Role not found"); + throw new CustomError("Role not found", "role-not-found", { + roleID: roleId, + }); } } catch (error) { - throw new Error(`Unable to delete role: ${error.message}`); + // throw new Error(`Unable to delete role: ${error.message}`); + throw new CustomError(error.message, "delete-role-error"); } } async updateRole(roleId, name, permissionIds) { const role = await this.Role.findById(roleId); if (!role) { - throw new Error("Role not found"); + // throw new Error("Role not found"); + throw new CustomError("Role not found", "role-not-found", { + roleID: roleId, + }); } role.name = name; let idPermissions = []; @@ -203,7 +245,8 @@ class HajarAuth { const grants = await this.Permission.find().distinct("grant"); return [...grants]; } catch (error) { - throw new Error(`Unable to fetch permissions: ${error.message}`); + // throw new Error(`Unable to fetch permissions: ${error.message}`); + throw new CustomError(error.message, "fetch-permission-error"); } } } diff --git a/src/utils/customError.js b/src/utils/customError.js new file mode 100644 index 0000000..86d3eb4 --- /dev/null +++ b/src/utils/customError.js @@ -0,0 +1,9 @@ +class CustomError extends Error { + constructor(message, slug, customProperties) { + super(message); // Pass the message parameter to the Error constructor + this.slug = slug; // Assign the code parameter to a property on the error object + Object.assign(this, customProperties); // Assign any additional properties to the error object + } +} + +export default CustomError;