88 lines
3.9 KiB
JavaScript
Executable File
88 lines
3.9 KiB
JavaScript
Executable File
// FILE: backend/src/routes/rbac_admin.js
|
|
import { Router } from "express";
|
|
import { Role, Permission, UserProjectRole, Project } from "../db/sequelize.js";
|
|
import { authJwt } from "../middleware/authJwt.js";
|
|
import { loadPrincipalMw } from "../middleware/loadPrincipal.js"; // แก้ไข: import ให้ถูกต้อง
|
|
import { requirePerm } from "../middleware/requirePerm.js";
|
|
|
|
const router = Router();
|
|
|
|
// Middleware Chain ที่ถูกต้อง 100% ตามสถาปัตยกรรมของคุณ
|
|
router.use(authJwt(), loadPrincipalMw());
|
|
|
|
// == ROLES Management ==
|
|
router.get("/roles", requirePerm("roles.manage"), async (req, res, next) => {
|
|
try {
|
|
const roles = await Role.findAll({
|
|
include: [{ model: Permission, attributes: ["id", "name"], through: { attributes: [] } }],
|
|
order: [["name", "ASC"]],
|
|
});
|
|
res.json(roles);
|
|
} catch (error) { next(error); }
|
|
});
|
|
|
|
router.post("/roles", requirePerm("roles.manage"), async (req, res, next) => {
|
|
const { name, description } = req.body;
|
|
if (!name) return res.status(400).json({ message: "Role name is required." });
|
|
try {
|
|
const newRole = await Role.create({ name, description });
|
|
res.status(201).json(newRole);
|
|
} catch (error) {
|
|
if (error.name === "SequelizeUniqueConstraintError") {
|
|
return res.status(409).json({ message: `Role '${name}' already exists.` });
|
|
}
|
|
next(error);
|
|
}
|
|
});
|
|
|
|
router.put("/roles/:id/permissions", requirePerm("roles.manage"), async (req, res, next) => {
|
|
const { permissionIds } = req.body;
|
|
if (!Array.isArray(permissionIds)) return res.status(400).json({ message: "permissionIds must be an array." });
|
|
try {
|
|
const role = await Role.findByPk(req.params.id);
|
|
if (!role) return res.status(404).json({ message: "Role not found." });
|
|
await role.setPermissions(permissionIds);
|
|
const updatedRole = await Role.findByPk(req.params.id, {
|
|
include: [{ model: Permission, attributes: ['id', 'name'], through: { attributes: [] } }]
|
|
});
|
|
res.json(updatedRole);
|
|
} catch (error) { next(error); }
|
|
});
|
|
|
|
// == USER-PROJECT-ROLES Management ==
|
|
router.get("/user-project-roles", requirePerm("users.manage"), async (req, res, next) => {
|
|
const { userId } = req.query;
|
|
if (!userId) return res.status(400).json({ message: "userId query parameter is required." });
|
|
try {
|
|
const assignments = await UserProjectRole.findAll({
|
|
where: { user_id: userId },
|
|
include: [ { model: Project, attributes: ["id", "name"] }, { model: Role, attributes: ["id", "name"] } ],
|
|
});
|
|
res.json(assignments);
|
|
} catch (error) { next(error); }
|
|
});
|
|
|
|
router.post("/user-project-roles", requirePerm("users.manage"), async (req, res, next) => {
|
|
const { userId, projectId, roleId } = req.body;
|
|
if (!userId || !projectId || !roleId) return res.status(400).json({ message: "userId, projectId, and roleId are required." });
|
|
try {
|
|
const [assignment, created] = await UserProjectRole.findOrCreate({
|
|
where: { user_id: userId, project_id: projectId, role_id: roleId },
|
|
defaults: { user_id: userId, project_id: projectId, role_id: roleId },
|
|
});
|
|
if (!created) return res.status(409).json({ message: "This assignment already exists." });
|
|
res.status(201).json(assignment);
|
|
} catch (error) { next(error); }
|
|
});
|
|
|
|
router.delete("/user-project-roles", requirePerm("users.manage"), async (req, res, next) => {
|
|
const { userId, projectId, roleId } = req.body;
|
|
if (!userId || !projectId || !roleId) return res.status(400).json({ message: "userId, projectId, and roleId are required." });
|
|
try {
|
|
const deletedCount = await UserProjectRole.destroy({ where: { user_id: userId, project_id: projectId, role_id: roleId } });
|
|
if (deletedCount === 0) return res.status(404).json({ message: 'Assignment not found.' });
|
|
res.status(204).send();
|
|
} catch (error) { next(error); }
|
|
});
|
|
|
|
export default router; |