better settings
This commit is contained in:
@@ -103,6 +103,19 @@ describe("/api/auth/me permissions array", () => {
|
||||
expect(new Set(body.permissions).has("clients:metadata")).toBe(true);
|
||||
});
|
||||
|
||||
test("legacy system:configure extra grants the split settings permissions", async () => {
|
||||
const viewer = await tempUser("viewer");
|
||||
setUserExtraPermissions(viewer.user.id, ["system:configure"]);
|
||||
const body = await fetchMe(viewer.token);
|
||||
const set = new Set(body.permissions);
|
||||
expect(set.has("system:configure")).toBe(true);
|
||||
expect(set.has("system:security")).toBe(true);
|
||||
expect(set.has("system:tls")).toBe(true);
|
||||
expect(set.has("system:registration")).toBe(true);
|
||||
expect(set.has("system:health")).toBe(true);
|
||||
expect(set.has("system:profiler")).toBe(true);
|
||||
});
|
||||
|
||||
test("viewer in a group gains the group's permissions in /api/auth/me", async () => {
|
||||
const viewer = await tempUser("viewer");
|
||||
const group = tempGroup("me_group", ["clients:disconnect", "audit:view"]);
|
||||
|
||||
@@ -432,7 +432,7 @@ export async function handleMiscRoutes(
|
||||
}
|
||||
|
||||
try {
|
||||
requirePermission(user, "system:configure");
|
||||
requirePermission(user, "system:security");
|
||||
} catch (error) {
|
||||
if (error instanceof Response) return error;
|
||||
return new Response("Forbidden", { status: 403 });
|
||||
@@ -494,7 +494,7 @@ export async function handleMiscRoutes(
|
||||
}
|
||||
|
||||
try {
|
||||
requirePermission(user, "system:configure");
|
||||
requirePermission(user, "system:tls");
|
||||
} catch (error) {
|
||||
if (error instanceof Response) return error;
|
||||
return new Response("Forbidden", { status: 403 });
|
||||
@@ -549,7 +549,7 @@ export async function handleMiscRoutes(
|
||||
}
|
||||
|
||||
try {
|
||||
requirePermission(user, "system:configure");
|
||||
requirePermission(user, "system:tls");
|
||||
} catch (error) {
|
||||
if (error instanceof Response) return error;
|
||||
return new Response("Forbidden", { status: 403 });
|
||||
@@ -790,7 +790,7 @@ export async function handleMiscRoutes(
|
||||
return new Response("Unauthorized", { status: 401 });
|
||||
}
|
||||
try {
|
||||
requirePermission(user, "system:configure");
|
||||
requirePermission(user, "system:export-import");
|
||||
} catch (error) {
|
||||
if (error instanceof Response) return error;
|
||||
return new Response("Forbidden", { status: 403 });
|
||||
@@ -823,7 +823,7 @@ export async function handleMiscRoutes(
|
||||
return new Response("Unauthorized", { status: 401 });
|
||||
}
|
||||
try {
|
||||
requirePermission(user, "system:configure");
|
||||
requirePermission(user, "system:export-import");
|
||||
} catch (error) {
|
||||
if (error instanceof Response) return error;
|
||||
return new Response("Forbidden", { status: 403 });
|
||||
@@ -875,7 +875,7 @@ export async function handleMiscRoutes(
|
||||
}
|
||||
|
||||
try {
|
||||
requirePermission(user, "system:configure");
|
||||
requirePermission(user, "system:chat");
|
||||
} catch (error) {
|
||||
if (error instanceof Response) return error;
|
||||
return new Response("Forbidden", { status: 403 });
|
||||
@@ -916,7 +916,7 @@ export async function handleMiscRoutes(
|
||||
return new Response("Unauthorized", { status: 401 });
|
||||
}
|
||||
try {
|
||||
requirePermission(user, "system:configure");
|
||||
requirePermission(user, "system:appearance");
|
||||
} catch (error) {
|
||||
if (error instanceof Response) return error;
|
||||
return new Response("Forbidden", { status: 403 });
|
||||
@@ -981,7 +981,7 @@ export async function handleMiscRoutes(
|
||||
if (url.pathname === "/api/settings/registration") {
|
||||
const user = await authenticateRequest(req);
|
||||
if (!user) return new Response("Unauthorized", { status: 401 });
|
||||
try { requirePermission(user, "system:configure"); } catch (error) { if (error instanceof Response) return error; return new Response("Forbidden", { status: 403 }); }
|
||||
try { requirePermission(user, "system:registration"); } catch (error) { if (error instanceof Response) return error; return new Response("Forbidden", { status: 403 }); }
|
||||
|
||||
if (req.method === "GET") {
|
||||
return Response.json({ registration: getConfig().registration }, { headers: deps.CORS_HEADERS });
|
||||
@@ -1017,7 +1017,7 @@ export async function handleMiscRoutes(
|
||||
if (url.pathname === "/api/settings/build-rate-limit") {
|
||||
const user = await authenticateRequest(req);
|
||||
if (!user) return new Response("Unauthorized", { status: 401 });
|
||||
try { requirePermission(user, "system:configure"); } catch (error) { if (error instanceof Response) return error; return new Response("Forbidden", { status: 403 }); }
|
||||
try { requirePermission(user, "system:build-limits"); } catch (error) { if (error instanceof Response) return error; return new Response("Forbidden", { status: 403 }); }
|
||||
|
||||
if (req.method === "GET") {
|
||||
return Response.json({ buildRateLimit: getConfig().buildRateLimit }, { headers: deps.CORS_HEADERS });
|
||||
@@ -1058,7 +1058,7 @@ export async function handleMiscRoutes(
|
||||
}
|
||||
|
||||
if (req.method === "PUT") {
|
||||
try { requirePermission(user, "system:configure"); } catch (error) { if (error instanceof Response) return error; return new Response("Forbidden", { status: 403 }); }
|
||||
try { requirePermission(user, "system:thumbnails"); } catch (error) { if (error instanceof Response) return error; return new Response("Forbidden", { status: 403 }); }
|
||||
|
||||
let body: any = {};
|
||||
try { body = await req.json(); } catch {
|
||||
@@ -1087,7 +1087,7 @@ export async function handleMiscRoutes(
|
||||
if (req.method === "GET" && url.pathname === "/api/settings/health") {
|
||||
const user = await authenticateRequest(req);
|
||||
if (!user) return new Response("Unauthorized", { status: 401 });
|
||||
if (user.role !== "admin") return new Response("Forbidden", { status: 403 });
|
||||
try { requirePermission(user, "system:health"); } catch (error) { if (error instanceof Response) return error; return new Response("Forbidden", { status: 403 }); }
|
||||
|
||||
const mem = process.memoryUsage();
|
||||
return Response.json({
|
||||
@@ -1116,7 +1116,7 @@ export async function handleMiscRoutes(
|
||||
if (req.method === "POST" && url.pathname === "/api/settings/gc") {
|
||||
const user = await authenticateRequest(req);
|
||||
if (!user) return new Response("Unauthorized", { status: 401 });
|
||||
if (user.role !== "admin") return new Response("Forbidden", { status: 403 });
|
||||
try { requirePermission(user, "system:health:manage"); } catch (error) { if (error instanceof Response) return error; return new Response("Forbidden", { status: 403 }); }
|
||||
|
||||
const before = process.memoryUsage().heapUsed;
|
||||
if (typeof Bun !== "undefined" && typeof (Bun as any).gc === "function") {
|
||||
@@ -1130,7 +1130,7 @@ export async function handleMiscRoutes(
|
||||
if (req.method === "POST" && url.pathname === "/api/settings/profile") {
|
||||
const user = await authenticateRequest(req);
|
||||
if (!user) return new Response("Unauthorized", { status: 401 });
|
||||
if (user.role !== "admin") return new Response("Forbidden", { status: 403 });
|
||||
try { requirePermission(user, "system:profiler"); } catch (error) { if (error instanceof Response) return error; return new Response("Forbidden", { status: 403 }); }
|
||||
|
||||
if (activeServerProfile) {
|
||||
return Response.json({ error: "A server profile capture is already running." }, { status: 409 });
|
||||
|
||||
@@ -78,7 +78,7 @@ export async function handleNotificationsConfigRoutes(
|
||||
});
|
||||
}
|
||||
try {
|
||||
requirePermission(user, "system:configure");
|
||||
requirePermission(user, "system:notifications");
|
||||
} catch (error) {
|
||||
if (error instanceof Response) return error;
|
||||
return new Response("Forbidden", { status: 403 });
|
||||
@@ -95,7 +95,7 @@ export async function handleNotificationsConfigRoutes(
|
||||
});
|
||||
}
|
||||
try {
|
||||
requirePermission(user, "system:configure");
|
||||
requirePermission(user, "system:notifications");
|
||||
} catch (error) {
|
||||
if (error instanceof Response) return error;
|
||||
return new Response("Forbidden", { status: 403 });
|
||||
|
||||
Reference in New Issue
Block a user