feat(gro-203): add requireSuperUser() middleware + route guards
- Added requireSuperUser() middleware in apps/api/src/middleware/rbac.ts
that checks staff.isSuperUser, returns 403 if false
- Wired into index.ts:
- POST/PATCH/DELETE /api/staff/* → requireSuperUser() after requireRole("manager")
- /api/admin/settings/* → requireSuperUser() after requireRole("manager")
- resolveStaffMiddleware: inject isSuperUser: true for AUTH_DISABLED dev mode
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
committed by
Flea Flicker
parent
a547931f9b
commit
1c82a75a88
@@ -42,7 +42,7 @@ export const resolveStaffMiddleware: MiddlewareHandler<AppEnv> = async (
|
|||||||
if (!manager) {
|
if (!manager) {
|
||||||
return c.json({ error: "Forbidden: no staff records found" }, 403);
|
return c.json({ error: "Forbidden: no staff records found" }, 403);
|
||||||
}
|
}
|
||||||
c.set("staff", manager);
|
c.set("staff", { ...manager, isSuperUser: true });
|
||||||
await next();
|
await next();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,7 @@ export const resolveStaffMiddleware: MiddlewareHandler<AppEnv> = async (
|
|||||||
.from(staff)
|
.from(staff)
|
||||||
.where(eq(staff.userId, devUserId));
|
.where(eq(staff.userId, devUserId));
|
||||||
if (row) {
|
if (row) {
|
||||||
c.set("staff", row);
|
c.set("staff", { ...row, isSuperUser: true });
|
||||||
await next();
|
await next();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -68,7 +68,7 @@ export const resolveStaffMiddleware: MiddlewareHandler<AppEnv> = async (
|
|||||||
403
|
403
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
c.set("staff", fallbackRow);
|
c.set("staff", { ...fallbackRow, isSuperUser: true });
|
||||||
await next();
|
await next();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -125,3 +125,27 @@ export function requireRole(
|
|||||||
await next();
|
await next();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Middleware that enforces the staff member is a super user.
|
||||||
|
* Must be applied after resolveStaffMiddleware and (typically) after requireRole.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* api.use("/staff/*", requireRole("manager"));
|
||||||
|
* api.use("/staff/*", requireSuperUser());
|
||||||
|
*/
|
||||||
|
export function requireSuperUser(): MiddlewareHandler<AppEnv> {
|
||||||
|
return async (c, next) => {
|
||||||
|
const staffRow = c.get("staff");
|
||||||
|
if (!staffRow) {
|
||||||
|
return c.json({ error: "Forbidden: staff record not resolved" }, 403);
|
||||||
|
}
|
||||||
|
if (!staffRow.isSuperUser) {
|
||||||
|
return c.json(
|
||||||
|
{ error: "Forbidden: super user privileges required" },
|
||||||
|
403
|
||||||
|
);
|
||||||
|
}
|
||||||
|
await next();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -134,6 +134,13 @@
|
|||||||
"when": 1774598400000,
|
"when": 1774598400000,
|
||||||
"tag": "0018_backfill_staff_user_id",
|
"tag": "0018_backfill_staff_user_id",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 19,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1774729055924,
|
||||||
|
"tag": "0019_concerned_sunfire",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user