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];
|
||||
|
||||
Reference in New Issue
Block a user