feat: RBAC controlling

This commit is contained in:
2026-03-10 17:59:44 +08:00
parent f803a447b5
commit b9c0f3025c
11 changed files with 716 additions and 380 deletions

View File

@@ -4,10 +4,11 @@ import { useDrizzle } from "@/lib/db.js";
import { transaction, chargePoint, connector, idTag } from "@/db/schema.js";
import { ocppConnections } from "@/ocpp/handler.js";
import { OCPP_MESSAGE_TYPE } from "@/ocpp/types.js";
import type { HonoEnv } from "@/types/hono.ts";
const app = new Hono();
const app = new Hono<HonoEnv>();
/** GET /api/transactions?page=1&limit=20&status=active|completed */
/** GET /api/transactions?page=1&limit=20&status=active|completed&chargePointId=... */
app.get("/", async (c) => {
const page = Math.max(1, Number(c.req.query("page") ?? 1));
const limit = Math.min(100, Math.max(1, Number(c.req.query("limit") ?? 20)));
@@ -16,6 +17,8 @@ app.get("/", async (c) => {
const offset = (page - 1) * limit;
const db = useDrizzle();
const currentUser = c.get("user");
const isAdmin = currentUser?.role === "admin";
const statusCondition =
status === "active"
@@ -24,11 +27,15 @@ app.get("/", async (c) => {
? isNotNull(transaction.stopTimestamp)
: undefined;
const whereClause = chargePointId
? statusCondition
? and(statusCondition, eq(transaction.chargePointId, chargePointId))
: eq(transaction.chargePointId, chargePointId)
: statusCondition;
// For non-admin users, restrict to transactions matching their id-tags
const userCondition =
!isAdmin && currentUser
? sql`${transaction.idTag} in (select id_tag from id_tag where user_id = ${currentUser.id})`
: undefined;
const cpCondition = chargePointId ? eq(transaction.chargePointId, chargePointId) : undefined;
const whereClause = and(statusCondition, userCondition, cpCondition);
const [{ total }] = await db
.select({ total: sql<number>`count(*)::int` })
@@ -174,6 +181,7 @@ app.post("/:id/stop", async (c) => {
/** DELETE /api/transactions/:id — delete a transaction record */
app.delete("/:id", async (c) => {
if (c.get("user")?.role !== "admin") return c.json({ error: "Forbidden" }, 403);
const db = useDrizzle();
const id = Number(c.req.param("id"));