update
This commit is contained in:
@@ -1,4 +1,149 @@
|
||||
export const JWT_SECRET = process.env.JWT_SECRET || "secret";
|
||||
export const TOKEN_NAME = 'userToken'
|
||||
export const TOKEN_NAME = "userToken";
|
||||
|
||||
export const requestType = ['software','hardware','his','rahkaran','taradod','general']
|
||||
export const requestType = [
|
||||
"software",
|
||||
"hardware",
|
||||
"his",
|
||||
"rahkaran",
|
||||
"taradod",
|
||||
"general",
|
||||
];
|
||||
|
||||
export const permissions = [
|
||||
"filter.view",
|
||||
/* ================================
|
||||
✅ TICKETS
|
||||
================================= */
|
||||
"ticket.create",
|
||||
"ticket.view",
|
||||
"ticket.view_all",
|
||||
"ticket.update",
|
||||
"ticket.delete",
|
||||
"ticket.assign",
|
||||
"ticket.change_status",
|
||||
"ticket.close",
|
||||
"ticket.reopen",
|
||||
"ticket.comment",
|
||||
"ticket.internal_note",
|
||||
"ticket.upload_file",
|
||||
"ticket.merge",
|
||||
"ticket.export",
|
||||
|
||||
/* ================================
|
||||
✅ USERS
|
||||
================================= */
|
||||
"user.view",
|
||||
"user.view_all",
|
||||
"user.create",
|
||||
"user.update",
|
||||
"user.delete",
|
||||
"user.activate",
|
||||
"user.deactivate",
|
||||
"user.assign_role",
|
||||
|
||||
/* ================================
|
||||
✅ ROLES
|
||||
================================= */
|
||||
"role.view",
|
||||
"role.create",
|
||||
"role.update",
|
||||
"role.delete",
|
||||
|
||||
/* ================================
|
||||
✅ PERMISSIONS
|
||||
================================= */
|
||||
"permission.view",
|
||||
"permission.assign_to_role",
|
||||
"permission.assign_to_user",
|
||||
|
||||
/* ================================
|
||||
✅ DEPARTMENTS
|
||||
================================= */
|
||||
"department.view",
|
||||
"department.create",
|
||||
"department.update",
|
||||
"department.delete",
|
||||
|
||||
/* ================================
|
||||
✅ REPORTS - SYSTEM LEVEL
|
||||
================================= */
|
||||
"report.system.view",
|
||||
"report.system.export",
|
||||
|
||||
"report.department.view",
|
||||
"report.department.export",
|
||||
|
||||
"report.operator.view",
|
||||
"report.operator.export",
|
||||
|
||||
"report.sla.view",
|
||||
"report.sla.export",
|
||||
|
||||
"report.kpi.view",
|
||||
"report.kpi.export",
|
||||
|
||||
"report.trend.view",
|
||||
"report.closure_rate.view",
|
||||
"report.critical.view",
|
||||
"report.avg_resolution.view",
|
||||
"report.aging.view",
|
||||
"report.agent_efficiency.view",
|
||||
"report.department_load.view",
|
||||
"report.prediction.view",
|
||||
"report.export_excel",
|
||||
|
||||
/* ================================
|
||||
✅ DASHBOARD
|
||||
================================= */
|
||||
"dashboard.view",
|
||||
"dashboard.view_advanced",
|
||||
|
||||
/* ================================
|
||||
✅ SLA MANAGEMENT
|
||||
================================= */
|
||||
"sla.view",
|
||||
"sla.create",
|
||||
"sla.update",
|
||||
"sla.delete",
|
||||
|
||||
/* ================================
|
||||
✅ REQUEST TYPES
|
||||
================================= */
|
||||
"request_type.view",
|
||||
"request_type.create",
|
||||
"request_type.update",
|
||||
"request_type.delete",
|
||||
|
||||
/* ================================
|
||||
✅ TAGS
|
||||
================================= */
|
||||
"tag.view",
|
||||
"tag.create",
|
||||
"tag.update",
|
||||
"tag.delete",
|
||||
|
||||
/* ================================
|
||||
✅ SETTINGS
|
||||
================================= */
|
||||
"settings.view",
|
||||
"settings.update",
|
||||
|
||||
/* ================================
|
||||
✅ LOGS
|
||||
================================= */
|
||||
"log.view",
|
||||
"audit.view",
|
||||
|
||||
/* ================================
|
||||
✅ OPERATOR / PERFORMANCE
|
||||
================================= */
|
||||
"operator.view",
|
||||
"operator.performance.view",
|
||||
"operator.performance.export",
|
||||
|
||||
"permission.view_all",
|
||||
"permission.create",
|
||||
"permission.update",
|
||||
"permission.delete",
|
||||
] as const;
|
||||
|
||||
@@ -2,28 +2,66 @@ import { NextFunction } from "express";
|
||||
import { ServerResponse } from "../types";
|
||||
import { JWT_SECRET, TOKEN_NAME } from "../constants";
|
||||
import createHttpError from "http-errors";
|
||||
import User from "../../models/User";
|
||||
import Permission from "../../models/Permission";
|
||||
import Role from "../../models/Role";
|
||||
|
||||
const jwt = require("jsonwebtoken");
|
||||
|
||||
const authMiddleware = (req:any, res:ServerResponse, next:NextFunction) => {
|
||||
// ۱. خواندن توکن از کوکیها
|
||||
const token = req.cookies[TOKEN_NAME]; // TOKEN_NAME همان متغیری است که در زمان ست کردن کوکی داشتید
|
||||
const authMiddleware = async (
|
||||
req: any,
|
||||
res: ServerResponse,
|
||||
next: NextFunction,
|
||||
) => {
|
||||
const token = req.cookies[TOKEN_NAME];
|
||||
|
||||
if (!token) {
|
||||
throw new createHttpError.Unauthorized("لطفا وارد حساب كاربري خود شويد")
|
||||
return next(
|
||||
new createHttpError.Unauthorized("لطفا وارد حساب كاربري خود شويد"),
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
// ۲. اعتبارسنجی توکن با استفاده از همان SECRET
|
||||
const decoded = jwt.verify(token, JWT_SECRET);
|
||||
const decoded = jwt.verify(token, JWT_SECRET) as {
|
||||
id: number;
|
||||
roleId: number;
|
||||
};
|
||||
|
||||
// ۳. قرار دادن اطلاعات کاربر در آبجکت درخواست برای استفاده در مسیرهای بعدی
|
||||
req.user = decoded;
|
||||
const user = await User.findByPk(decoded.id, {
|
||||
attributes: ["id", "roleId"],
|
||||
include: [
|
||||
{
|
||||
model: Role,
|
||||
as: "role",
|
||||
attributes: ["id", "name"],
|
||||
include: [
|
||||
{
|
||||
model: Permission,
|
||||
as: "permissions",
|
||||
attributes: ["name"],
|
||||
through: { attributes: [] },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
next(); // ادامه به مسیر اصلی
|
||||
} catch (error) {
|
||||
throw new createHttpError.Forbidden("حساب كاربري شما نامعتبر است")
|
||||
if (!user) {
|
||||
return next(new createHttpError.Unauthorized("کاربر یافت نشد"));
|
||||
}
|
||||
|
||||
const permissions = user?.role?.permissions?.map((p: any) => p.name) || [];
|
||||
|
||||
req.user = {
|
||||
id: user.id,
|
||||
roleId: user.roleId,
|
||||
permissions,
|
||||
};
|
||||
|
||||
next();
|
||||
} catch (err) {
|
||||
return next(new createHttpError.Forbidden("حساب كاربري شما نامعتبر است"));
|
||||
}
|
||||
};
|
||||
|
||||
export default authMiddleware
|
||||
export default authMiddleware;
|
||||
|
||||
@@ -1,46 +1,65 @@
|
||||
import Permission from "../../models/Permission";
|
||||
import RolePermission from "../../models/RolePermission";
|
||||
import UserPermission from "../../models/UserPermission";
|
||||
import { NextFunction } from "express";
|
||||
import { PermissionType } from "../types";
|
||||
import createHttpError from "http-errors";
|
||||
|
||||
// export function checkPermission(permissionName: string) {
|
||||
// return async (req: any, res: any, next: any) => {
|
||||
// const user = req.user;
|
||||
|
||||
export function checkPermission(permissionName: string) {
|
||||
return async (req: any, res: any, next: any) => {
|
||||
// const permission = await Permission.findOne({
|
||||
// where: { name: permissionName },
|
||||
// });
|
||||
|
||||
// if (!permission) {
|
||||
// return res.status(403).json({ message: "Permission not found" });
|
||||
// }
|
||||
|
||||
// // ✅ 1- چک سطح کاربر
|
||||
// const userPermission = await UserPermission.findOne({
|
||||
// where: {
|
||||
// userId: user.id,
|
||||
// permissionId: permission.id,
|
||||
// },
|
||||
// });
|
||||
|
||||
// if (userPermission) {
|
||||
// return next();
|
||||
// }
|
||||
|
||||
// // ✅ 2- چک سطح رول
|
||||
// const rolePermission = await RolePermission.findOne({
|
||||
// where: {
|
||||
// roleId: user.roleId,
|
||||
// permissionId: permission.id,
|
||||
// },
|
||||
// });
|
||||
|
||||
// if (rolePermission) {
|
||||
// return next();
|
||||
// }
|
||||
|
||||
// return res.status(403).json({
|
||||
// message: "Access Denied",
|
||||
// });
|
||||
// };
|
||||
// }
|
||||
|
||||
export function requirePermission(permission: PermissionType[]) {
|
||||
return (req: any, res: any, next: NextFunction) => {
|
||||
const user = req.user;
|
||||
|
||||
const permission = await Permission.findOne({
|
||||
where: { name: permissionName },
|
||||
});
|
||||
|
||||
if (!permission) {
|
||||
return res.status(403).json({ message: "Permission not found" });
|
||||
if (!user) {
|
||||
throw new createHttpError.Unauthorized("وارد حساب كاربري خود شويد");
|
||||
}
|
||||
|
||||
// ✅ 1- چک سطح کاربر
|
||||
const userPermission = await UserPermission.findOne({
|
||||
where: {
|
||||
userId: user.id,
|
||||
permissionId: permission.id,
|
||||
},
|
||||
});
|
||||
const userPermissions: PermissionType[] = user.permissions || [];
|
||||
|
||||
if (userPermission) {
|
||||
return next();
|
||||
const hasPermission = permission.some((p) => userPermissions.includes(p));
|
||||
|
||||
if (!hasPermission) {
|
||||
throw new createHttpError.Forbidden("به اين قسمت دسترسي نداريد");
|
||||
}
|
||||
|
||||
// ✅ 2- چک سطح رول
|
||||
const rolePermission = await RolePermission.findOne({
|
||||
where: {
|
||||
roleId: user.roleId,
|
||||
permissionId: permission.id,
|
||||
},
|
||||
});
|
||||
|
||||
if (rolePermission) {
|
||||
return next();
|
||||
}
|
||||
|
||||
return res.status(403).json({
|
||||
message: "Access Denied",
|
||||
});
|
||||
next();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Response } from "express";
|
||||
import { permissions } from "../constants";
|
||||
|
||||
export interface ServerResponseObject {
|
||||
status: number;
|
||||
@@ -69,30 +70,29 @@ export interface ticketRequestTypeDataType {
|
||||
updatedAt?: Date;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// reports
|
||||
|
||||
export interface TicketStats {
|
||||
total: number
|
||||
open: number
|
||||
inProgress: number
|
||||
resolved: number
|
||||
closed: number
|
||||
total: number;
|
||||
open: number;
|
||||
inProgress: number;
|
||||
resolved: number;
|
||||
closed: number;
|
||||
}
|
||||
|
||||
export interface DepartmentReport {
|
||||
departmentId: string
|
||||
departmentName: string
|
||||
totalTickets: number
|
||||
openTickets: number
|
||||
resolvedTickets: number
|
||||
departmentId: string;
|
||||
departmentName: string;
|
||||
totalTickets: number;
|
||||
openTickets: number;
|
||||
resolvedTickets: number;
|
||||
}
|
||||
|
||||
export interface AgentReport {
|
||||
userId: string
|
||||
fullname: string
|
||||
totalAssigned: number
|
||||
resolved: number
|
||||
open: number
|
||||
userId: string;
|
||||
fullname: string;
|
||||
totalAssigned: number;
|
||||
resolved: number;
|
||||
open: number;
|
||||
}
|
||||
export type PermissionType = (typeof permissions)[number];
|
||||
|
||||
@@ -1,92 +1,97 @@
|
||||
import {
|
||||
Model,
|
||||
DataTypes,
|
||||
Optional,
|
||||
Sequelize,
|
||||
BelongsToManySetAssociationsMixin,
|
||||
BelongsToManyAddAssociationsMixin,
|
||||
BelongsToManyRemoveAssociationsMixin,
|
||||
BelongsToManyGetAssociationsMixin,
|
||||
HasManyGetAssociationsMixin
|
||||
} from "sequelize";
|
||||
import User from "./User";
|
||||
import Permission from "./Permission";
|
||||
import {
|
||||
Model,
|
||||
DataTypes,
|
||||
Optional,
|
||||
Sequelize,
|
||||
BelongsToManySetAssociationsMixin,
|
||||
BelongsToManyAddAssociationsMixin,
|
||||
BelongsToManyRemoveAssociationsMixin,
|
||||
BelongsToManyGetAssociationsMixin,
|
||||
HasManyGetAssociationsMixin,
|
||||
} from "sequelize";
|
||||
import User from "./User";
|
||||
import Permission from "./Permission";
|
||||
|
||||
interface RoleAttributes {
|
||||
id: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
createdAt?: Date;
|
||||
updatedAt?: Date;
|
||||
}
|
||||
|
||||
interface RoleAttributes {
|
||||
id: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
createdAt?: Date;
|
||||
updatedAt?: Date;
|
||||
}
|
||||
interface RoleCreationAttributes extends Optional<
|
||||
RoleAttributes,
|
||||
"id" | "description"
|
||||
> {}
|
||||
|
||||
interface RoleCreationAttributes
|
||||
extends Optional<RoleAttributes, "id" | "description"> {}
|
||||
class Role
|
||||
extends Model<RoleAttributes, RoleCreationAttributes>
|
||||
implements RoleAttributes
|
||||
{
|
||||
public id!: string;
|
||||
public name!: string;
|
||||
public description?: string;
|
||||
public permissions?: Permission[];
|
||||
|
||||
class Role
|
||||
extends Model<RoleAttributes, RoleCreationAttributes>
|
||||
implements RoleAttributes
|
||||
{
|
||||
public id!: string;
|
||||
public name!: string;
|
||||
public description?: string;
|
||||
public readonly createdAt!: Date;
|
||||
public readonly updatedAt!: Date;
|
||||
|
||||
public readonly createdAt!: Date;
|
||||
public readonly updatedAt!: Date;
|
||||
// Users relation
|
||||
public getUsers!: HasManyGetAssociationsMixin<User>;
|
||||
|
||||
// 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
|
||||
>;
|
||||
|
||||
// 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 {
|
||||
Role.init(
|
||||
{
|
||||
id: {
|
||||
type: DataTypes.UUID,
|
||||
primaryKey: true,
|
||||
defaultValue: DataTypes.UUIDV4,
|
||||
},
|
||||
|
||||
name: {
|
||||
type: DataTypes.STRING,
|
||||
unique: true,
|
||||
allowNull: false,
|
||||
},
|
||||
|
||||
description: {
|
||||
type: DataTypes.STRING,
|
||||
},
|
||||
static initModel(sequelize: Sequelize): typeof Role {
|
||||
Role.init(
|
||||
{
|
||||
id: {
|
||||
type: DataTypes.UUID,
|
||||
primaryKey: true,
|
||||
defaultValue: DataTypes.UUIDV4,
|
||||
},
|
||||
{
|
||||
sequelize,
|
||||
modelName: "Role",
|
||||
tableName: "roles",
|
||||
timestamps: true,
|
||||
}
|
||||
);
|
||||
|
||||
return Role;
|
||||
}
|
||||
name: {
|
||||
type: DataTypes.STRING,
|
||||
unique: true,
|
||||
allowNull: false,
|
||||
},
|
||||
|
||||
static associate(models: any) {
|
||||
Role.hasMany(models.User, {
|
||||
foreignKey: "roleId",
|
||||
as: "users",
|
||||
});
|
||||
description: {
|
||||
type: DataTypes.STRING,
|
||||
},
|
||||
},
|
||||
{
|
||||
sequelize,
|
||||
modelName: "Role",
|
||||
tableName: "roles",
|
||||
timestamps: true,
|
||||
},
|
||||
);
|
||||
|
||||
Role.belongsToMany(models.Permission, {
|
||||
through: models.RolePermission,
|
||||
foreignKey: "roleId",
|
||||
otherKey: "permissionId",
|
||||
as: "permissions",
|
||||
});
|
||||
}
|
||||
return Role;
|
||||
}
|
||||
|
||||
export default Role;
|
||||
static associate(models: any) {
|
||||
Role.hasMany(models.User, {
|
||||
foreignKey: "roleId",
|
||||
as: "users",
|
||||
});
|
||||
|
||||
Role.belongsToMany(models.Permission, {
|
||||
through: models.RolePermission,
|
||||
foreignKey: "roleId",
|
||||
otherKey: "permissionId",
|
||||
as: "permissions",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default Role;
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import {
|
||||
Model,
|
||||
DataTypes,
|
||||
Optional,
|
||||
Sequelize
|
||||
} from "sequelize";
|
||||
import { Model, DataTypes, Optional, Sequelize } from "sequelize";
|
||||
import Role from "./Role";
|
||||
|
||||
interface UserAttributes {
|
||||
id: string;
|
||||
@@ -15,8 +11,7 @@ interface UserAttributes {
|
||||
updatedAt?: Date;
|
||||
}
|
||||
|
||||
interface UserCreationAttributes
|
||||
extends Optional<UserAttributes, "id"> {}
|
||||
interface UserCreationAttributes extends Optional<UserAttributes, "id"> {}
|
||||
|
||||
class User
|
||||
extends Model<UserAttributes, UserCreationAttributes>
|
||||
@@ -27,6 +22,7 @@ class User
|
||||
public nationalCode!: string;
|
||||
public mobile!: string;
|
||||
public roleId!: string;
|
||||
public role?: Role;
|
||||
|
||||
public readonly createdAt!: Date;
|
||||
public readonly updatedAt!: Date;
|
||||
@@ -69,26 +65,22 @@ class User
|
||||
modelName: "User",
|
||||
tableName: "users",
|
||||
timestamps: true,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return User;
|
||||
}
|
||||
|
||||
static associate(models: any) {
|
||||
|
||||
User.belongsTo(models.Role, {
|
||||
foreignKey: "roleId",
|
||||
as: "role",
|
||||
});
|
||||
|
||||
|
||||
|
||||
User.hasMany(models.Ticket, {
|
||||
foreignKey: "assignedTo",
|
||||
as: "assignedTickets",
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import { TOKEN_NAME } from "../../../core/constants";
|
||||
import { GlobalMessages } from "../../../core/messages";
|
||||
import { Controller } from "../../../core/controller/main.controller";
|
||||
|
||||
|
||||
class AuthControllerClass extends Controller {
|
||||
#service;
|
||||
|
||||
@@ -16,6 +15,19 @@ class AuthControllerClass extends Controller {
|
||||
this.#service = AuthService;
|
||||
}
|
||||
|
||||
async Me(req: any, res: ServerResponse, next: NextFunction) {
|
||||
try {
|
||||
const data = await this.#service.Me(req);
|
||||
|
||||
return res.status(200).json({
|
||||
data,
|
||||
status: 200,
|
||||
message: "Ok",
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
async login(req: any, res: ServerResponse, next: NextFunction) {
|
||||
try {
|
||||
await AuthValidationSchema.validateAsync(req.body || {});
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import express from 'express'
|
||||
import AuthController from '../controller/auth.controller';
|
||||
import express from "express";
|
||||
import AuthController from "../controller/auth.controller";
|
||||
import authMiddleware from "../../../core/middleware/auth.middleware";
|
||||
|
||||
const authRouter = express.Router();
|
||||
const authRouter = express.Router();
|
||||
|
||||
|
||||
authRouter.post('/login',AuthController.login)
|
||||
authRouter.post('/logout',AuthController.logout)
|
||||
authRouter.get("/me", authMiddleware, AuthController.Me);
|
||||
authRouter.post("/login", AuthController.login);
|
||||
authRouter.post("/logout", AuthController.logout);
|
||||
|
||||
export default authRouter;
|
||||
@@ -4,6 +4,8 @@ import jwt from "jsonwebtoken";
|
||||
import dotenv from "dotenv";
|
||||
import User from "../../../models/User";
|
||||
import { JWT_SECRET } from "../../../core/constants";
|
||||
import Role from "../../../models/Role";
|
||||
import Permission from "../../../models/Permission";
|
||||
dotenv.config();
|
||||
|
||||
class AuthServiceClass {
|
||||
@@ -39,6 +41,46 @@ class AuthServiceClass {
|
||||
);
|
||||
}
|
||||
}
|
||||
async Me(req:any) {
|
||||
const userId = req.user?.id;
|
||||
|
||||
if (!userId) {
|
||||
throw new createHttpError.Unauthorized("کاربر احراز هویت نشده است");
|
||||
}
|
||||
|
||||
const user = await User.findByPk(userId, {
|
||||
attributes: ["id", "fullname", "mobile", "roleId"],
|
||||
include: [
|
||||
{
|
||||
model: Role,
|
||||
as: "role",
|
||||
attributes: ["id", "name"],
|
||||
include: [
|
||||
{
|
||||
model: Permission,
|
||||
as: "permissions",
|
||||
attributes: ["name"],
|
||||
through: { attributes: [] },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
throw new createHttpError.NotFound("کاربر پیدا نشد");
|
||||
}
|
||||
|
||||
const permissions = user.role?.permissions?.map((p: any) => p.name) || [];
|
||||
|
||||
return {
|
||||
id: user.id,
|
||||
fullname: user.fullname,
|
||||
mobile: user.mobile,
|
||||
role: user.role?.name,
|
||||
permissions,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const AuthService = new AuthServiceClass();
|
||||
|
||||
@@ -1,13 +1,48 @@
|
||||
import router from "express";
|
||||
import DepartmentController from "../controller/department.controller";
|
||||
import authMiddleware from "../../../core/middleware/auth.middleware";
|
||||
import { requirePermission } from "../../../core/middleware/check-permission";
|
||||
|
||||
const departmentRouter = router.Router();
|
||||
departmentRouter.get(
|
||||
"/all",
|
||||
authMiddleware,
|
||||
requirePermission(["department.view"]),
|
||||
DepartmentController.getAll,
|
||||
);
|
||||
|
||||
departmentRouter.get("/all", DepartmentController.getAll);
|
||||
departmentRouter.get("/list", DepartmentController.getAllList);
|
||||
departmentRouter.get("/get/:id", DepartmentController.getById);
|
||||
departmentRouter.post("/create", DepartmentController.create);
|
||||
departmentRouter.delete("/delete/:id", DepartmentController.delete);
|
||||
departmentRouter.put("/update/:id", DepartmentController.update);
|
||||
departmentRouter.get(
|
||||
"/list",
|
||||
authMiddleware,
|
||||
DepartmentController.getAllList,
|
||||
);
|
||||
|
||||
departmentRouter.get(
|
||||
"/get/:id",
|
||||
authMiddleware,
|
||||
requirePermission(["department.view"]),
|
||||
DepartmentController.getById,
|
||||
);
|
||||
|
||||
departmentRouter.post(
|
||||
"/create",
|
||||
authMiddleware,
|
||||
requirePermission(["department.create"]),
|
||||
DepartmentController.create,
|
||||
);
|
||||
|
||||
departmentRouter.delete(
|
||||
"/delete/:id",
|
||||
authMiddleware,
|
||||
requirePermission(["department.delete"]),
|
||||
DepartmentController.delete,
|
||||
);
|
||||
|
||||
departmentRouter.put(
|
||||
"/update/:id",
|
||||
authMiddleware,
|
||||
requirePermission(["department.update"]),
|
||||
DepartmentController.update,
|
||||
);
|
||||
|
||||
export default departmentRouter;
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
import { Router } from "express";
|
||||
import PermissionController from "./permission.controller";
|
||||
import { requirePermission } from "../../core/middleware/check-permission";
|
||||
import authMiddleware from "../../core/middleware/auth.middleware";
|
||||
|
||||
const PermissionRouter = Router();
|
||||
|
||||
PermissionRouter.post("/create", PermissionController.create);
|
||||
PermissionRouter.post("/create",authMiddleware,requirePermission(["permission.create"]),PermissionController.create);
|
||||
|
||||
|
||||
PermissionRouter.get("/all", PermissionController.getAll);
|
||||
PermissionRouter.get("/list", PermissionController.getList);
|
||||
PermissionRouter.get("/all", authMiddleware,requirePermission(["permission.view_all"]),PermissionController.getAll);
|
||||
PermissionRouter.get("/list", authMiddleware,PermissionController.getList);
|
||||
|
||||
PermissionRouter.get("/get/:id", PermissionController.getById);
|
||||
PermissionRouter.get("/get/:id", authMiddleware,requirePermission(["permission.view"]),PermissionController.getById);
|
||||
|
||||
|
||||
PermissionRouter.put("/update/:id", PermissionController.update);
|
||||
PermissionRouter.put("/update/:id", authMiddleware,requirePermission(["permission.update"]),PermissionController.update);
|
||||
|
||||
PermissionRouter.delete("/remove/:id", PermissionController.delete);
|
||||
PermissionRouter.delete("/remove/:id", authMiddleware,requirePermission(["permission.delete"]),PermissionController.delete);
|
||||
|
||||
export default PermissionRouter;
|
||||
|
||||
@@ -1,60 +1,62 @@
|
||||
import { Router } from "express";
|
||||
import ReportController from "../controller/report.controller";
|
||||
import authMiddleware from "../../../core/middleware/auth.middleware";
|
||||
import { requirePermission } from "../../../core/middleware/check-permission";
|
||||
|
||||
const reportRouter = Router();
|
||||
|
||||
reportRouter.get(
|
||||
"/stats",
|
||||
"/stats",authMiddleware,requirePermission(["report.system.view"]),
|
||||
// requireAuth,
|
||||
// requirePermission("VIEW_REPORTS"),
|
||||
ReportController.ticketStats,
|
||||
);
|
||||
|
||||
reportRouter.get(
|
||||
"/departments",
|
||||
"/departments",authMiddleware,requirePermission(["report.department.view"]),
|
||||
// requireAuth,
|
||||
// requirePermission("VIEW_REPORTS"),
|
||||
ReportController.departmentReport,
|
||||
);
|
||||
|
||||
reportRouter.get(
|
||||
"/agents",
|
||||
"/agents",authMiddleware,requirePermission(["report.operator.view"]),
|
||||
// requireAuth,
|
||||
// requirePermission("VIEW_REPORTS"),
|
||||
ReportController.agentPerformance,
|
||||
);
|
||||
|
||||
reportRouter.get(
|
||||
"/avg-resolution",
|
||||
"/avg-resolution",authMiddleware,requirePermission(["report.avg_resolution.view"]),
|
||||
// requireAuth,
|
||||
// requirePermission("VIEW_REPORTS"),
|
||||
ReportController.avgResolution,
|
||||
);
|
||||
|
||||
reportRouter.get(
|
||||
"/critical",
|
||||
"/critical",authMiddleware,requirePermission(["report.critical.view"]),
|
||||
// requireAuth,
|
||||
// requirePermission("VIEW_REPORTS"),
|
||||
ReportController.criticalTickets,
|
||||
);
|
||||
|
||||
reportRouter.get("/trend", ReportController.ticketsPerDay)
|
||||
reportRouter.get("/trend",authMiddleware,requirePermission(["report.trend.view"]), ReportController.ticketsPerDay)
|
||||
|
||||
reportRouter.get("/closure-rate", ReportController.closureRate)
|
||||
reportRouter.get("/closure-rate",authMiddleware,requirePermission(["report.closure_rate.view"]), ReportController.closureRate)
|
||||
|
||||
reportRouter.get("/sla", ReportController.slaBreach)
|
||||
reportRouter.get("/sla",authMiddleware,requirePermission(["report.sla.view"]), ReportController.slaBreach)
|
||||
|
||||
reportRouter.get("/aging", ReportController.aging)
|
||||
reportRouter.get("/aging",authMiddleware,requirePermission(["report.aging.view"]), ReportController.aging)
|
||||
|
||||
reportRouter.get("/agent-efficiency", ReportController.agentEfficiency)
|
||||
reportRouter.get("/agent-efficiency",authMiddleware,requirePermission(["report.agent_efficiency.view"]), ReportController.agentEfficiency)
|
||||
|
||||
reportRouter.get("/department-load", ReportController.departmentLoad)
|
||||
reportRouter.get("/department-load",authMiddleware,requirePermission(["report.department_load.view"]), ReportController.departmentLoad)
|
||||
|
||||
reportRouter.get("/kpi", ReportController.kpi)
|
||||
reportRouter.get("/kpi",authMiddleware,requirePermission(["report.kpi.view"]), ReportController.kpi)
|
||||
|
||||
reportRouter.get("/prediction", ReportController.prediction)
|
||||
reportRouter.get("/prediction",authMiddleware,requirePermission(["report.prediction.view"]), ReportController.prediction)
|
||||
|
||||
reportRouter.get("/export-excel", ReportController.exportExcel)
|
||||
reportRouter.get("/export-excel",authMiddleware,requirePermission(["report.export_excel"]), ReportController.exportExcel)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import { Router } from "express";
|
||||
import RoleController from "./role.controller";
|
||||
import authMiddleware from "../../core/middleware/auth.middleware";
|
||||
import { requirePermission } from "../../core/middleware/check-permission";
|
||||
|
||||
const RoleRouter = Router();
|
||||
RoleRouter.post("/create", RoleController.create);
|
||||
RoleRouter.get("/list", RoleController.findList);
|
||||
RoleRouter.get("/all", RoleController.findAll);
|
||||
RoleRouter.get("/:id", RoleController.findById);
|
||||
RoleRouter.put("/update/:id", RoleController.update);
|
||||
RoleRouter.delete("/remove/:id", RoleController.delete);
|
||||
RoleRouter.post("/create", authMiddleware,requirePermission(["role.create"]),RoleController.create);
|
||||
RoleRouter.get("/list", authMiddleware,RoleController.findList);
|
||||
RoleRouter.get("/all", authMiddleware,requirePermission(["role.view"]),RoleController.findAll);
|
||||
RoleRouter.get("/:id", authMiddleware,requirePermission(["role.view"]),RoleController.findById);
|
||||
RoleRouter.put("/update/:id", authMiddleware,requirePermission(["role.update"]),RoleController.update);
|
||||
RoleRouter.delete("/remove/:id", authMiddleware,requirePermission(["role.delete"]),RoleController.delete);
|
||||
|
||||
RoleRouter.post("/:id/permissions/assign", RoleController.assignPermissions);
|
||||
RoleRouter.post("/:id/permissions/add", RoleController.addPermissions);
|
||||
RoleRouter.post("/:id/permissions/remove", RoleController.removePermissions);
|
||||
RoleRouter.post("/:id/permissions/assign", authMiddleware,requirePermission(["permission.assign_to_role"]),RoleController.assignPermissions);
|
||||
RoleRouter.post("/:id/permissions/add", authMiddleware,RoleController.addPermissions);
|
||||
RoleRouter.post("/:id/permissions/remove", authMiddleware,RoleController.removePermissions);
|
||||
|
||||
export default RoleRouter;
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
import express from "express";
|
||||
import TicketController from "../controller/ticket.controller";
|
||||
import authMiddleware from "../../../core/middleware/auth.middleware";
|
||||
import { requirePermission } from "../../../core/middleware/check-permission";
|
||||
|
||||
const ticketRouter = express.Router();
|
||||
|
||||
ticketRouter.post("/create", TicketController.create);
|
||||
ticketRouter.get("/all", TicketController.getAll);
|
||||
ticketRouter.get("/all/export", TicketController.getAllExport);
|
||||
ticketRouter.get("/all/report", TicketController.getAllReport);
|
||||
ticketRouter.get("/get/:id", TicketController.getById);
|
||||
ticketRouter.put("/update/:id", TicketController.update);
|
||||
ticketRouter.delete("/remove/:id", TicketController.remove);
|
||||
ticketRouter.post("/create", authMiddleware,requirePermission(["ticket.create"]),TicketController.create);
|
||||
ticketRouter.get("/all", authMiddleware,requirePermission(["ticket.view_all"]),TicketController.getAll);
|
||||
ticketRouter.get("/all/export", authMiddleware,requirePermission(["ticket.export"]),TicketController.getAllExport);
|
||||
ticketRouter.get("/all/report", authMiddleware,TicketController.getAllReport);
|
||||
ticketRouter.get("/get/:id",authMiddleware,requirePermission(["ticket.view"]), TicketController.getById);
|
||||
ticketRouter.put("/update/:id", authMiddleware,requirePermission(["ticket.update"]),TicketController.update);
|
||||
ticketRouter.delete("/remove/:id",authMiddleware,requirePermission(["ticket.delete"]), TicketController.remove);
|
||||
|
||||
export default ticketRouter;
|
||||
|
||||
@@ -1,13 +1,44 @@
|
||||
import router from "express";
|
||||
import UserController from "../controller/user.controller";
|
||||
import { requirePermission } from "../../../core/middleware/check-permission";
|
||||
import authMiddleware from "../../../core/middleware/auth.middleware";
|
||||
|
||||
const userRouter = router.Router();
|
||||
|
||||
userRouter.get("/all", UserController.getAll);
|
||||
userRouter.get("/list", UserController.getList);
|
||||
userRouter.get("/get/:id", UserController.getById);
|
||||
userRouter.post("/create", UserController.create);
|
||||
userRouter.put("/update/:id", UserController.update);
|
||||
userRouter.delete("/delete/:id", UserController.delete);
|
||||
userRouter.get(
|
||||
"/all",
|
||||
authMiddleware,
|
||||
requirePermission(["user.view_all"]),
|
||||
UserController.getAll,
|
||||
);
|
||||
userRouter.get(
|
||||
"/list",
|
||||
authMiddleware,
|
||||
UserController.getList,
|
||||
);
|
||||
userRouter.get(
|
||||
"/get/:id",
|
||||
authMiddleware,
|
||||
requirePermission(["user.view"]),
|
||||
UserController.getById,
|
||||
);
|
||||
userRouter.post(
|
||||
"/create",
|
||||
authMiddleware,
|
||||
requirePermission(["user.create"]),
|
||||
UserController.create,
|
||||
);
|
||||
userRouter.put(
|
||||
"/update/:id",
|
||||
authMiddleware,
|
||||
requirePermission(["user.update"]),
|
||||
UserController.update,
|
||||
);
|
||||
userRouter.delete(
|
||||
"/delete/:id",
|
||||
authMiddleware,
|
||||
requirePermission(["user.delete"]),
|
||||
UserController.delete,
|
||||
);
|
||||
|
||||
export default userRouter;
|
||||
|
||||
@@ -1,128 +1,7 @@
|
||||
import { permissions } from "../core/constants";
|
||||
import Permission from "../models/Permission";
|
||||
|
||||
export async function seedPermissions() {
|
||||
const permissions = [
|
||||
"filter.view",
|
||||
/* ================================
|
||||
✅ TICKETS
|
||||
================================= */
|
||||
"ticket.create",
|
||||
"ticket.view",
|
||||
"ticket.view_all",
|
||||
"ticket.update",
|
||||
"ticket.delete",
|
||||
"ticket.assign",
|
||||
"ticket.change_status",
|
||||
"ticket.close",
|
||||
"ticket.reopen",
|
||||
"ticket.comment",
|
||||
"ticket.internal_note",
|
||||
"ticket.upload_file",
|
||||
"ticket.merge",
|
||||
"ticket.export",
|
||||
|
||||
/* ================================
|
||||
✅ USERS
|
||||
================================= */
|
||||
"user.view",
|
||||
"user.view_all",
|
||||
"user.create",
|
||||
"user.update",
|
||||
"user.delete",
|
||||
"user.activate",
|
||||
"user.deactivate",
|
||||
"user.assign_role",
|
||||
|
||||
/* ================================
|
||||
✅ ROLES
|
||||
================================= */
|
||||
"role.view",
|
||||
"role.create",
|
||||
"role.update",
|
||||
"role.delete",
|
||||
|
||||
/* ================================
|
||||
✅ PERMISSIONS
|
||||
================================= */
|
||||
"permission.view",
|
||||
"permission.assign_to_role",
|
||||
"permission.assign_to_user",
|
||||
|
||||
/* ================================
|
||||
✅ DEPARTMENTS
|
||||
================================= */
|
||||
"department.view",
|
||||
"department.create",
|
||||
"department.update",
|
||||
"department.delete",
|
||||
|
||||
/* ================================
|
||||
✅ REPORTS - SYSTEM LEVEL
|
||||
================================= */
|
||||
"report.system.view",
|
||||
"report.system.export",
|
||||
|
||||
"report.department.view",
|
||||
"report.department.export",
|
||||
|
||||
"report.operator.view",
|
||||
"report.operator.export",
|
||||
|
||||
"report.sla.view",
|
||||
"report.sla.export",
|
||||
|
||||
"report.kpi.view",
|
||||
"report.kpi.export",
|
||||
|
||||
/* ================================
|
||||
✅ DASHBOARD
|
||||
================================= */
|
||||
"dashboard.view",
|
||||
"dashboard.view_advanced",
|
||||
|
||||
/* ================================
|
||||
✅ SLA MANAGEMENT
|
||||
================================= */
|
||||
"sla.view",
|
||||
"sla.create",
|
||||
"sla.update",
|
||||
"sla.delete",
|
||||
|
||||
/* ================================
|
||||
✅ REQUEST TYPES
|
||||
================================= */
|
||||
"request_type.view",
|
||||
"request_type.create",
|
||||
"request_type.update",
|
||||
"request_type.delete",
|
||||
|
||||
/* ================================
|
||||
✅ TAGS
|
||||
================================= */
|
||||
"tag.view",
|
||||
"tag.create",
|
||||
"tag.update",
|
||||
"tag.delete",
|
||||
|
||||
/* ================================
|
||||
✅ SETTINGS
|
||||
================================= */
|
||||
"settings.view",
|
||||
"settings.update",
|
||||
|
||||
/* ================================
|
||||
✅ LOGS
|
||||
================================= */
|
||||
"log.view",
|
||||
"audit.view",
|
||||
|
||||
/* ================================
|
||||
✅ OPERATOR / PERFORMANCE
|
||||
================================= */
|
||||
"operator.view",
|
||||
"operator.performance.view",
|
||||
"operator.performance.export",
|
||||
];
|
||||
|
||||
let createdCount = 0;
|
||||
|
||||
|
||||
@@ -39,83 +39,144 @@ export async function seedRolePermissions() {
|
||||
/* =========================================
|
||||
✅ MANAGER (دسترسی بالا)
|
||||
========================================== */
|
||||
/* =========================================
|
||||
✅ MANAGER
|
||||
========================================= */
|
||||
/* =========================================
|
||||
✅ MANAGER
|
||||
========================================= */
|
||||
await assignPermissions("manager", [
|
||||
// tickets
|
||||
/* ---------- Tickets ---------- */
|
||||
"ticket.view_all",
|
||||
"ticket.assign",
|
||||
"ticket.change_status",
|
||||
"ticket.close",
|
||||
"ticket.reopen",
|
||||
"ticket.merge",
|
||||
"ticket.export",
|
||||
"ticket.create",
|
||||
|
||||
// users
|
||||
/* ---------- Users ---------- */
|
||||
"user.view",
|
||||
"user.view_all",
|
||||
"user.create",
|
||||
"user.update",
|
||||
"user.activate",
|
||||
"user.deactivate",
|
||||
"user.assign_role",
|
||||
|
||||
// reports
|
||||
/* ---------- Roles ---------- */
|
||||
"role.view",
|
||||
|
||||
/* ---------- Permissions ---------- */
|
||||
"permission.view",
|
||||
"permission.view_all",
|
||||
"permission.assign_to_role",
|
||||
"permission.assign_to_user",
|
||||
|
||||
/* ---------- Departments ---------- */
|
||||
"department.view",
|
||||
"department.create",
|
||||
"department.update",
|
||||
|
||||
/* ---------- Reports ---------- */
|
||||
"report.system.view",
|
||||
"report.system.export",
|
||||
"report.department.view",
|
||||
"report.department.export",
|
||||
"report.operator.view",
|
||||
"report.operator.export",
|
||||
"report.sla.view",
|
||||
"report.kpi.view",
|
||||
"report.trend.view",
|
||||
"report.closure_rate.view",
|
||||
"report.critical.view",
|
||||
"report.avg_resolution.view",
|
||||
"report.aging.view",
|
||||
"report.agent_efficiency.view",
|
||||
"report.department_load.view",
|
||||
"report.prediction.view",
|
||||
"report.export_excel",
|
||||
|
||||
"report.system.export",
|
||||
"report.department.export",
|
||||
|
||||
// dashboard
|
||||
/* ---------- Dashboard ---------- */
|
||||
"dashboard.view_advanced",
|
||||
|
||||
// operator
|
||||
/* ---------- Operator ---------- */
|
||||
"operator.view",
|
||||
"operator.performance.view",
|
||||
]);
|
||||
"operator.performance.export",
|
||||
|
||||
/* ---------- Logs ---------- */
|
||||
"log.view",
|
||||
"audit.view",
|
||||
]);
|
||||
/* =========================================
|
||||
✅ SUPERVISOR
|
||||
========================================== */
|
||||
✅ SUPERVISOR
|
||||
========================================= */
|
||||
await assignPermissions("supervisor", [
|
||||
/* Tickets */
|
||||
"ticket.view_all",
|
||||
"ticket.assign",
|
||||
"ticket.change_status",
|
||||
"ticket.comment",
|
||||
"ticket.internal_note",
|
||||
"ticket.close",
|
||||
"ticket.reopen",
|
||||
|
||||
/* Reports */
|
||||
"report.department.view",
|
||||
"report.operator.view",
|
||||
"report.trend.view",
|
||||
"report.closure_rate.view",
|
||||
"report.aging.view",
|
||||
|
||||
/* Dashboard */
|
||||
"dashboard.view",
|
||||
|
||||
/* Operator */
|
||||
"operator.view",
|
||||
"operator.performance.view",
|
||||
]);
|
||||
|
||||
/* =========================================
|
||||
✅ SENIOR EXPERT
|
||||
========================================== */
|
||||
✅ SENIOR EXPERT
|
||||
========================================= */
|
||||
await assignPermissions("senior_expert", [
|
||||
"ticket.view",
|
||||
"ticket.change_status",
|
||||
"ticket.comment",
|
||||
"ticket.internal_note",
|
||||
"ticket.upload_file",
|
||||
|
||||
"dashboard.view",
|
||||
]);
|
||||
|
||||
/* =========================================
|
||||
✅ EXPERT
|
||||
========================================== */
|
||||
✅ EXPERT
|
||||
========================================= */
|
||||
await assignPermissions("expert", [
|
||||
"ticket.view",
|
||||
"ticket.change_status",
|
||||
"ticket.comment",
|
||||
"ticket.upload_file",
|
||||
]);
|
||||
|
||||
/* =========================================
|
||||
✅ TECHNICIAN
|
||||
========================================== */
|
||||
await assignPermissions("technician", ["ticket.view", "ticket.comment"]);
|
||||
|
||||
✅ TECHNICIAN
|
||||
========================================= */
|
||||
await assignPermissions("technician", [
|
||||
"ticket.view",
|
||||
"ticket.comment",
|
||||
"ticket.upload_file",
|
||||
]);
|
||||
/* =========================================
|
||||
✅ NORMAL USER
|
||||
========================================== */
|
||||
✅ NORMAL USER
|
||||
========================================= */
|
||||
await assignPermissions("user", [
|
||||
"ticket.create",
|
||||
"ticket.view",
|
||||
"ticket.comment",
|
||||
"ticket.upload_file",
|
||||
]);
|
||||
|
||||
console.log("✅ RolePermissions seeded successfully");
|
||||
|
||||
Reference in New Issue
Block a user