update
This commit is contained in:
@@ -5,6 +5,7 @@ import ticketRouter from "../../modules/ticket/routes/ticket.routes";
|
|||||||
import userRouter from "../../modules/user/routes/user.router";
|
import userRouter from "../../modules/user/routes/user.router";
|
||||||
import reportRouter from "../../modules/report/routes/report.router";
|
import reportRouter from "../../modules/report/routes/report.router";
|
||||||
import authMiddleware from "../middleware/auth.middleware";
|
import authMiddleware from "../middleware/auth.middleware";
|
||||||
|
import RoleRouter from "../../modules/roles/role.routes";
|
||||||
|
|
||||||
const mainRouter = router.Router();
|
const mainRouter = router.Router();
|
||||||
|
|
||||||
@@ -13,5 +14,6 @@ mainRouter.use("/department", authMiddleware, departmentRouter);
|
|||||||
mainRouter.use("/ticket", authMiddleware, ticketRouter);
|
mainRouter.use("/ticket", authMiddleware, ticketRouter);
|
||||||
mainRouter.use("/user", authMiddleware, userRouter);
|
mainRouter.use("/user", authMiddleware, userRouter);
|
||||||
mainRouter.use("/report", authMiddleware, reportRouter);
|
mainRouter.use("/report", authMiddleware, reportRouter);
|
||||||
|
mainRouter.use("/role", authMiddleware, RoleRouter);
|
||||||
|
|
||||||
export default mainRouter;
|
export default mainRouter;
|
||||||
|
|||||||
@@ -2,8 +2,16 @@ import {
|
|||||||
Model,
|
Model,
|
||||||
DataTypes,
|
DataTypes,
|
||||||
Optional,
|
Optional,
|
||||||
Sequelize
|
Sequelize,
|
||||||
|
BelongsToManySetAssociationsMixin,
|
||||||
|
BelongsToManyAddAssociationsMixin,
|
||||||
|
BelongsToManyRemoveAssociationsMixin,
|
||||||
|
BelongsToManyGetAssociationsMixin,
|
||||||
|
HasManyGetAssociationsMixin
|
||||||
} from "sequelize";
|
} from "sequelize";
|
||||||
|
import User from "./User";
|
||||||
|
import Permission from "./Permission";
|
||||||
|
|
||||||
|
|
||||||
interface RoleAttributes {
|
interface RoleAttributes {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -27,6 +35,15 @@ class Role
|
|||||||
public readonly createdAt!: Date;
|
public readonly createdAt!: Date;
|
||||||
public readonly updatedAt!: Date;
|
public readonly updatedAt!: Date;
|
||||||
|
|
||||||
|
// Users relation
|
||||||
|
public getUsers!: HasManyGetAssociationsMixin<User>;
|
||||||
|
|
||||||
|
// Permissions relation
|
||||||
|
public getPermissions!: BelongsToManyGetAssociationsMixin<Permission>;
|
||||||
|
public setPermissions!: BelongsToManySetAssociationsMixin<Permission, string>;
|
||||||
|
public addPermissions!: BelongsToManyAddAssociationsMixin<Permission, string>;
|
||||||
|
public removePermissions!: BelongsToManyRemoveAssociationsMixin<Permission, string>;
|
||||||
|
|
||||||
static initModel(sequelize: Sequelize): typeof Role {
|
static initModel(sequelize: Sequelize): typeof Role {
|
||||||
Role.init(
|
Role.init(
|
||||||
{
|
{
|
||||||
@@ -58,21 +75,17 @@ class Role
|
|||||||
}
|
}
|
||||||
|
|
||||||
static associate(models: any) {
|
static associate(models: any) {
|
||||||
|
|
||||||
// Role -> Users
|
|
||||||
Role.hasMany(models.User, {
|
Role.hasMany(models.User, {
|
||||||
foreignKey: "roleId",
|
foreignKey: "roleId",
|
||||||
as: "users",
|
as: "users",
|
||||||
});
|
});
|
||||||
|
|
||||||
// Role <-> Permission
|
|
||||||
Role.belongsToMany(models.Permission, {
|
Role.belongsToMany(models.Permission, {
|
||||||
through: models.RolePermission,
|
through: models.RolePermission,
|
||||||
foreignKey: "roleId",
|
foreignKey: "roleId",
|
||||||
otherKey: "permissionId",
|
otherKey: "permissionId",
|
||||||
as: "permissions",
|
as: "permissions",
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
151
src/modules/roles/role.controller.ts
Normal file
151
src/modules/roles/role.controller.ts
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
import { NextFunction } from "express";
|
||||||
|
import { Controller } from "../../core/controller/main.controller";
|
||||||
|
import RoleService from "./role.service";
|
||||||
|
import { ServerResponse } from "../../core/types";
|
||||||
|
|
||||||
|
class RoleControllerClass extends Controller {
|
||||||
|
#serivce;
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.#serivce = RoleService;
|
||||||
|
}
|
||||||
|
async create(req: any, res: ServerResponse, next: NextFunction) {
|
||||||
|
try {
|
||||||
|
const role = await this.#serivce.create(req.body);
|
||||||
|
|
||||||
|
return res.status(201).json({
|
||||||
|
status: 200,
|
||||||
|
message: "Role created successfully",
|
||||||
|
data: role,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async findAll(_req: any, res: ServerResponse, next: NextFunction) {
|
||||||
|
try {
|
||||||
|
const roles = await this.#serivce.findAll();
|
||||||
|
|
||||||
|
return res.status(200).json({
|
||||||
|
status: 200,
|
||||||
|
data: roles,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
findById = async (req: any, res: ServerResponse, next: NextFunction) => {
|
||||||
|
try {
|
||||||
|
const role = await this.#serivce.findById(req.params.id);
|
||||||
|
|
||||||
|
return res.status(200).json({
|
||||||
|
status: 200,
|
||||||
|
data: role,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
update = async (req: any, res: ServerResponse, next: NextFunction) => {
|
||||||
|
try {
|
||||||
|
const updatedRole = await this.#serivce.update(req.params.id, req.body);
|
||||||
|
|
||||||
|
return res.status(200).json({
|
||||||
|
status: 200,
|
||||||
|
message: "Role updated statusfully",
|
||||||
|
data: updatedRole,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
delete = async (req: any, res: ServerResponse, next: NextFunction) => {
|
||||||
|
try {
|
||||||
|
const result = await this.#serivce.delete(req.params.id);
|
||||||
|
|
||||||
|
return res.status(200).json({
|
||||||
|
status: 200,
|
||||||
|
data: { ...result },
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assignPermissions = async (
|
||||||
|
req: any,
|
||||||
|
res: ServerResponse,
|
||||||
|
next: NextFunction,
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const { permissionIds } = req.body;
|
||||||
|
|
||||||
|
const role = await this.#serivce.assignPermissions(
|
||||||
|
req.params.id,
|
||||||
|
permissionIds,
|
||||||
|
);
|
||||||
|
|
||||||
|
return res.status(200).json({
|
||||||
|
status: 200,
|
||||||
|
message: "Permissions assigned statusfully",
|
||||||
|
data: role,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
addPermissions = async (
|
||||||
|
req: any,
|
||||||
|
res: ServerResponse,
|
||||||
|
next: NextFunction,
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const { permissionIds } = req.body;
|
||||||
|
|
||||||
|
const role = await this.#serivce.addPermissions(
|
||||||
|
req.params.id,
|
||||||
|
permissionIds,
|
||||||
|
);
|
||||||
|
|
||||||
|
return res.status(200).json({
|
||||||
|
status: 200,
|
||||||
|
message: "Permissions added statusfully",
|
||||||
|
data: role,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
removePermissions = async (
|
||||||
|
req: any,
|
||||||
|
res: ServerResponse,
|
||||||
|
next: NextFunction,
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const { permissionIds } = req.body;
|
||||||
|
|
||||||
|
const role = await this.#serivce.removePermissions(
|
||||||
|
req.params.id,
|
||||||
|
permissionIds,
|
||||||
|
);
|
||||||
|
|
||||||
|
return res.status(200).json({
|
||||||
|
status: 200,
|
||||||
|
message: "Permissions removed statusfully",
|
||||||
|
data: role,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const RoleController = new RoleControllerClass();
|
||||||
|
|
||||||
|
export default RoleController;
|
||||||
15
src/modules/roles/role.routes.ts
Normal file
15
src/modules/roles/role.routes.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { Router } from "express";
|
||||||
|
import RoleController from "./role.controller";
|
||||||
|
|
||||||
|
const RoleRouter = Router();
|
||||||
|
RoleRouter.post("/create", RoleController.create);
|
||||||
|
RoleRouter.get("/list", RoleController.findAll);
|
||||||
|
RoleRouter.get("/:id", RoleController.findById);
|
||||||
|
RoleRouter.put("/update/:id", RoleController.update);
|
||||||
|
RoleRouter.delete("/remove/:id", RoleController.delete);
|
||||||
|
|
||||||
|
RoleRouter.post("/:id/permissions/assign", RoleController.assignPermissions);
|
||||||
|
RoleRouter.post("/:id/permissions/add", RoleController.addPermissions);
|
||||||
|
RoleRouter.post("/:id/permissions/remove", RoleController.removePermissions);
|
||||||
|
|
||||||
|
export default RoleRouter;
|
||||||
168
src/modules/roles/role.service.ts
Normal file
168
src/modules/roles/role.service.ts
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
import Permission from "../../models/Permission";
|
||||||
|
import Role from "../../models/Role";
|
||||||
|
import User from "../../models/User";
|
||||||
|
|
||||||
|
class RoleServiceClass {
|
||||||
|
async create(data: { name: string; description?: string }) {
|
||||||
|
const existingRole = await Role.findOne({
|
||||||
|
where: { name: data.name },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existingRole) {
|
||||||
|
throw new Error("Role already exists");
|
||||||
|
}
|
||||||
|
|
||||||
|
const role = await Role.create({
|
||||||
|
name: data.name,
|
||||||
|
description: data.description,
|
||||||
|
});
|
||||||
|
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
async findAll() {
|
||||||
|
return await Role.findAll({
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: Permission,
|
||||||
|
as: "permissions",
|
||||||
|
through: { attributes: [] },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
model: User,
|
||||||
|
as: "users",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
order: [["createdAt", "DESC"]],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async findById(id: string) {
|
||||||
|
const role = await Role.findByPk(id, {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: Permission,
|
||||||
|
as: "permissions",
|
||||||
|
through: { attributes: [] },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
model: User,
|
||||||
|
as: "users",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!role) {
|
||||||
|
throw new Error("Role not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
async update(id: string, data: { name?: string; description?: string }) {
|
||||||
|
const role = await Role.findByPk(id);
|
||||||
|
|
||||||
|
if (!role) {
|
||||||
|
throw new Error("Role not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.name) {
|
||||||
|
const existingRole = await Role.findOne({
|
||||||
|
where: { name: data.name },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existingRole && existingRole.id !== id) {
|
||||||
|
throw new Error("Another role with this name already exists");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await role.update({
|
||||||
|
name: data.name ?? role.name,
|
||||||
|
description: data.description ?? role.description,
|
||||||
|
});
|
||||||
|
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
async delete(id: string) {
|
||||||
|
const role = await Role.findByPk(id);
|
||||||
|
|
||||||
|
if (!role) {
|
||||||
|
throw new Error("Role not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
await role.destroy();
|
||||||
|
|
||||||
|
return { message: "Role deleted successfully" };
|
||||||
|
}
|
||||||
|
|
||||||
|
async assignPermissions(roleId: string, permissionIds: string[]) {
|
||||||
|
const role = await Role.findByPk(roleId);
|
||||||
|
|
||||||
|
if (!role) {
|
||||||
|
throw new Error("Role not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
await role.setPermissions(permissionIds);
|
||||||
|
|
||||||
|
const updatedRole = await Role.findByPk(roleId, {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: Permission,
|
||||||
|
as: "permissions",
|
||||||
|
through: { attributes: [] },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
return updatedRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
async addPermissions(roleId: string, permissionIds: string[]) {
|
||||||
|
const role = await Role.findByPk(roleId);
|
||||||
|
|
||||||
|
if (!role) {
|
||||||
|
throw new Error("Role not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
await role.addPermissions(permissionIds);
|
||||||
|
|
||||||
|
const updatedRole = await Role.findByPk(roleId, {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: Permission,
|
||||||
|
as: "permissions",
|
||||||
|
through: { attributes: [] },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
return updatedRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
async removePermissions(roleId: string, permissionIds: string[]) {
|
||||||
|
const role = await Role.findByPk(roleId);
|
||||||
|
|
||||||
|
if (!role) {
|
||||||
|
throw new Error("Role not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
await role.removePermissions(permissionIds);
|
||||||
|
|
||||||
|
const updatedRole = await Role.findByPk(roleId, {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: Permission,
|
||||||
|
as: "permissions",
|
||||||
|
through: { attributes: [] },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
return updatedRole;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const RoleService = new RoleServiceClass();
|
||||||
|
|
||||||
|
export default RoleService;
|
||||||
Reference in New Issue
Block a user