05.1 ปรบปรง backend ทงหมด และ frontend/login

This commit is contained in:
admin
2025-10-01 11:14:11 +07:00
parent 5be0f5407b
commit 905afb56f5
43 changed files with 2285 additions and 2834 deletions

View File

@@ -1,62 +1,47 @@
// FILE: src/routes/rbac_admin.js
// RBAC Admin routes
// - Manage roles, permissions, user-role assignments
// - Requires appropriate permissions via requirePerm middleware
// - Uses global scope for all permissions
// - rbac_admin.read, rbac_admin.assign_role, rbac_admin.grant_perm
// FILE: backend/src/routes/rbac_admin.js
// RBAC admin — ใช้ settings.manage ทั้งหมด
import { Router } from "express";
import sql from "../db/index.js";
import { requirePerm } from "../middleware/requirePerm.js";
import PERM from "../config/permissions.js";
const r = Router();
/** LIST: roles */
r.get(
"/roles",
requirePerm(PERM.rbac_admin.read, { scope: "global" }),
async (req, res) => {
const [rows] = await sql.query(
"SELECT role_id, role_code, role_name, description FROM roles ORDER BY role_code"
);
res.json(rows);
}
);
// ROLES
r.get("/roles", requirePerm("settings.manage"), async (_req, res) => {
const [rows] = await sql.query(
"SELECT role_id, role_code, role_name, description FROM roles ORDER BY role_code"
);
res.json(rows);
});
/** LIST: permissions */
r.get(
"/permissions",
requirePerm(PERM.rbac_admin.read, { scope: "global" }),
async (req, res) => {
const [rows] = await sql.query(
"SELECT permission_id, permission_code, description FROM permissions ORDER BY permission_code"
);
res.json(rows);
}
);
// PERMISSIONS
r.get("/permissions", requirePerm("settings.manage"), async (_req, res) => {
const [rows] = await sql.query(
"SELECT permission_id, perm_code AS permission_code, scope_level, description FROM permissions ORDER BY perm_code"
);
res.json(rows);
});
/** LIST: rolepermissions */
// role -> permissions
r.get(
"/roles/:role_id/permissions",
requirePerm(PERM.rbac_admin.read, { scope: "global" }),
requirePerm("settings.manage"),
async (req, res) => {
const role_id = Number(req.params.role_id);
const [rows] = await sql.query(
`SELECT p.permission_id, p.permission_code, p.description
FROM role_permissions rp
JOIN permissions p ON p.permission_id = rp.permission_id
WHERE rp.role_id=? ORDER BY p.permission_code`,
`SELECT p.permission_id, p.perm_code AS permission_code, p.description
FROM role_permissions rp
JOIN permissions p ON p.permission_id = rp.permission_id
WHERE rp.role_id=? ORDER BY p.perm_code`,
[role_id]
);
res.json(rows);
}
);
/** MAP: role↔permission (grant/revoke) */
r.post(
"/roles/:role_id/permissions",
requirePerm(PERM.rbac_admin.grant_perm, { scope: "global" }),
requirePerm("settings.manage"),
async (req, res) => {
const role_id = Number(req.params.role_id);
const { permission_id } = req.body || {};
@@ -70,7 +55,7 @@ r.post(
r.delete(
"/roles/:role_id/permissions/:permission_id",
requirePerm(PERM.rbac_admin.grant_perm, { scope: "global" }),
requirePerm("settings.manage"),
async (req, res) => {
const role_id = Number(req.params.role_id);
const permission_id = Number(req.params.permission_id);
@@ -82,26 +67,25 @@ r.delete(
}
);
/** LIST: userroles(+scope) */
// user -> roles (global/org/project scope columns มีในตาราง user_roles ตามสคีมา)
r.get(
"/users/:user_id/roles",
requirePerm(PERM.rbac_admin.read, { scope: "global" }),
requirePerm("settings.manage"),
async (req, res) => {
const user_id = Number(req.params.user_id);
const [rows] = await sql.query(
`SELECT ur.user_id, ur.role_id, r.role_code, r.role_name, ur.org_id, ur.project_id
FROM user_roles ur JOIN roles r ON r.role_id = ur.role_id
WHERE ur.user_id=? ORDER BY r.role_code`,
FROM user_roles ur JOIN roles r ON r.role_id = ur.role_id
WHERE ur.user_id=? ORDER BY r.role_code`,
[user_id]
);
res.json(rows);
}
);
/** MAP: user↔role(+scope) (assign / revoke) */
r.post(
"/users/:user_id/roles",
requirePerm(PERM.rbac_admin.assign_role, { scope: "global" }),
requirePerm("settings.manage"),
async (req, res) => {
const user_id = Number(req.params.user_id);
const { role_id, org_id = null, project_id = null } = req.body || {};
@@ -120,18 +104,20 @@ r.post(
r.delete(
"/users/:user_id/roles",
requirePerm(PERM.rbac_admin.assign_role, { scope: "global" }),
requirePerm("settings.manage"),
async (req, res) => {
const user_id = Number(req.params.user_id);
const { role_id, org_id = null, project_id = null } = req.body || {};
// สร้างเงื่อนไขแบบ dynamic สำหรับ NULL-safe compare
const whereOrg = org_id === null ? "ur.org_id IS NULL" : "ur.org_id = ?";
const wherePrj =
project_id === null ? "ur.project_id IS NULL" : "ur.project_id = ?";
const params = [user_id, Number(role_id)];
if (org_id !== null) params.push(Number(org_id));
if (project_id !== null) params.push(Number(project_id));
await sql.query(
"DELETE FROM user_roles WHERE user_id=? AND role_id=? AND <=> org_id ? AND <=> project_id ?"
.replace("<=> org_id ?", org_id === null ? "org_id IS ?" : "org_id=?")
.replace(
"<=> project_id ?",
project_id === null ? "project_id IS ?" : "project_id=?"
),
[user_id, Number(role_id), org_id, project_id]
`DELETE FROM user_roles ur WHERE ur.user_id=? AND ur.role_id=? AND ${whereOrg} AND ${wherePrj}`,
params
);
res.json({ ok: 1 });
}