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