add bookmarking clients, fix sorting issues, add sorting by country and only showing specific countries.

This commit is contained in:
KingKDot
2026-03-17 00:11:25 -05:00
parent 0cdc5efefb
commit 50bc381943
9 changed files with 561 additions and 9 deletions
@@ -11,6 +11,8 @@ import {
isIpBanned,
listBannedIps,
listClients,
listDistinctCountries,
setClientBookmark,
setClientNickname,
setClientTag,
setOnlineState,
@@ -71,8 +73,9 @@ export async function handleClientRoutes(
const sort = url.searchParams.get("sort") || "last_seen_desc";
const statusFilter = url.searchParams.get("status") || "all";
const osFilter = url.searchParams.get("os") || "all";
const countryFilter = url.searchParams.get("country") || "all";
if (user.role === "admin") {
const result = listClients({ page, pageSize, search, sort, statusFilter, osFilter });
const result = listClients({ page, pageSize, search, sort, statusFilter, osFilter, countryFilter });
return Response.json(result, { headers: deps.CORS_HEADERS });
}
@@ -100,12 +103,20 @@ export async function handleClientRoutes(
sort,
statusFilter,
osFilter,
countryFilter,
allowedClientIds,
deniedClientIds,
});
return Response.json(result, { headers: deps.CORS_HEADERS });
}
if (url.pathname === "/api/clients/countries") {
const user = await authenticateRequest(req);
if (!user) return new Response("Unauthorized", { status: 401 });
const countries = listDistinctCountries();
return Response.json({ countries }, { headers: deps.CORS_HEADERS });
}
if (url.pathname === "/api/clients/banned-ips") {
const user = await authenticateRequest(req);
if (!user) return new Response("Unauthorized", { status: 401 });
@@ -398,6 +409,35 @@ export async function handleClientRoutes(
);
}
const bookmarkMatch = url.pathname.match(/^\/api\/clients\/([^/]+)\/bookmark$/);
if (req.method === "PATCH" && bookmarkMatch) {
const user = await authenticateRequest(req);
if (!user) return new Response("Unauthorized", { status: 401 });
const targetId = bookmarkMatch[1];
if (!canUserAccessClient(user.userId, user.role, targetId)) {
return new Response("Forbidden: Client access denied", { status: 403 });
}
if (!clientExists(targetId)) {
return Response.json({ error: "Client not found" }, { status: 404 });
}
let body: any = {};
try {
body = await req.json();
} catch {
return Response.json({ error: "Invalid JSON body" }, { status: 400 });
}
const bookmarked = !!body?.bookmarked;
const updated = setClientBookmark(targetId, bookmarked);
if (!updated) {
return Response.json({ error: "Client not found" }, { status: 404 });
}
return Response.json({ ok: true, bookmarked }, { headers: deps.CORS_HEADERS });
}
if (req.method === "POST") {
const cmdMatch = url.pathname.match(/^\/api\/clients\/(.+)\/command$/);
if (cmdMatch) {