add a pill to show if a user is admin or not

This commit is contained in:
KingKDot
2026-04-07 10:36:29 -05:00
parent 604803b5ee
commit ff9fda24af
11 changed files with 56 additions and 8 deletions
+12 -4
View File
@@ -79,6 +79,9 @@ try {
try {
db.run(`ALTER TABLE clients ADD COLUMN ram TEXT`);
} catch {}
try {
db.run(`ALTER TABLE clients ADD COLUMN is_admin INTEGER NOT NULL DEFAULT 0`);
} catch {}
db.run(
`CREATE INDEX IF NOT EXISTS idx_clients_public_key ON clients(public_key);`,
);
@@ -250,8 +253,8 @@ export function upsertClientRow(
) {
const now = partial.lastSeen ?? Date.now();
db.run(
`INSERT INTO clients (id, hwid, role, ip, host, os, arch, version, user, nickname, custom_tag, custom_tag_note, monitors, country, last_seen, online, ping_ms, enrollment_status, public_key, key_fingerprint, cpu, gpu, ram)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`INSERT INTO clients (id, hwid, role, ip, host, os, arch, version, user, nickname, custom_tag, custom_tag_note, monitors, country, last_seen, online, ping_ms, enrollment_status, public_key, key_fingerprint, cpu, gpu, ram, is_admin)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, COALESCE(?, 0))
ON CONFLICT(id) DO UPDATE SET
hwid=COALESCE(excluded.hwid, clients.hwid),
role=COALESCE(excluded.role, clients.role),
@@ -274,7 +277,8 @@ export function upsertClientRow(
key_fingerprint=COALESCE(excluded.key_fingerprint, clients.key_fingerprint),
cpu=COALESCE(excluded.cpu, clients.cpu),
gpu=COALESCE(excluded.gpu, clients.gpu),
ram=COALESCE(excluded.ram, clients.ram)
ram=COALESCE(excluded.ram, clients.ram),
is_admin=COALESCE(excluded.is_admin, clients.is_admin)
`,
partial.id,
partial.hwid ?? partial.id,
@@ -299,6 +303,7 @@ export function upsertClientRow(
partial.cpu ?? null,
partial.gpu ?? null,
partial.ram ?? null,
partial.isAdmin !== undefined ? (partial.isAdmin ? 1 : 0) : null,
);
if (partial.hwid) {
@@ -539,6 +544,8 @@ export function listClients(filters: ListFilters): ListResult {
return `ORDER BY ${online}, ${bookmark}, LOWER(COALESCE(country, 'zz')) ASC, id ASC`;
case "country_desc":
return `ORDER BY ${online}, ${bookmark}, LOWER(COALESCE(country, 'zz')) DESC, id ASC`;
case "admin_first":
return `ORDER BY ${online}, ${bookmark}, is_admin DESC, id ASC`;
default:
return `ORDER BY ${online}, ${bookmark}, last_seen DESC, id ASC`;
}
@@ -556,7 +563,7 @@ export function listClients(filters: ListFilters): ListResult {
const rows = db
.query<any>(
`SELECT id, hwid, role, host, os, arch, version, user, nickname, custom_tag as customTag, custom_tag_note as customTagNote, monitors, country, last_seen as lastSeen, online, ping_ms as pingMs, bookmarked, enrollment_status as enrollmentStatus, public_key as publicKey, key_fingerprint as keyFingerprint, cpu, gpu, ram, disconnect_reason as disconnectReason, disconnect_detail as disconnectDetail
`SELECT id, hwid, role, host, os, arch, version, user, nickname, custom_tag as customTag, custom_tag_note as customTagNote, monitors, country, last_seen as lastSeen, online, ping_ms as pingMs, bookmarked, enrollment_status as enrollmentStatus, public_key as publicKey, key_fingerprint as keyFingerprint, cpu, gpu, ram, is_admin as isAdmin, disconnect_reason as disconnectReason, disconnect_detail as disconnectDetail
FROM clients
${whereSql}
${orderBy}
@@ -588,6 +595,7 @@ export function listClients(filters: ListFilters): ListResult {
cpu: c.cpu || null,
gpu: c.gpu || null,
ram: c.ram || null,
isAdmin: c.isAdmin === 1,
disconnectReason: c.disconnectReason || null,
disconnectDetail: c.disconnectDetail || null,
thumbnail: getThumbnail(c.id),
+6 -3
View File
@@ -25,11 +25,14 @@ export function handleClientsRequest(req: Request): Response {
const result = listClients({ page, pageSize, search, sort, statusFilter, osFilter, enrollmentFilter: "approved" });
const items = result.items.map((item) => {
const live = clientManager.getClient(item.id);
if (live?.monitorInfo?.length) {
if (live) {
return {
...item,
monitors: live.monitorInfo.length,
monitorInfo: live.monitorInfo,
isAdmin: live.isAdmin ?? item.isAdmin,
...(live.monitorInfo?.length ? {
monitors: live.monitorInfo.length,
monitorInfo: live.monitorInfo,
} : {}),
};
}
return item;
+1
View File
@@ -28,6 +28,7 @@ export type ClientInfo = {
cpu?: string;
gpu?: string;
ram?: string;
isAdmin?: boolean;
enrollmentStatus?: EnrollmentStatus;
publicKey?: string;
keyFingerprint?: string;
+6 -1
View File
@@ -89,6 +89,7 @@ export function handleHello(
info.monitors = payload.monitors;
info.monitorInfo = (payload as any).monitorInfo || info.monitorInfo;
info.inMemory = !!(payload as any).inMemory;
info.isAdmin = !!(payload as any).isAdmin;
info.cpu = (payload as any).cpu || info.cpu;
info.gpu = (payload as any).gpu || info.gpu;
info.ram = (payload as any).ram || info.ram;
@@ -117,6 +118,7 @@ export function handleHello(
cpu: info.cpu,
gpu: info.gpu,
ram: info.ram,
isAdmin: info.isAdmin,
lastSeen: info.lastSeen,
online: 1,
});
@@ -135,6 +137,7 @@ export function handlePing(info: ClientInfo, payload: WireMessage, ws: any) {
id: info.id,
lastSeen: info.lastSeen,
online: 1,
isAdmin: info.isAdmin,
});
}
ws.send(encodeMessage({ type: "pong", ts: payload.ts || Date.now() }));
@@ -191,6 +194,7 @@ export function handlePong(info: ClientInfo, payload: WireMessage) {
pingMs: info.pingMs,
lastSeen: info.lastSeen,
online: 1,
isAdmin: info.isAdmin,
});
lastClientDbSync.set(info.id, nowTs);
@@ -201,6 +205,7 @@ export function handlePong(info: ClientInfo, payload: WireMessage) {
id: info.id,
lastSeen: info.lastSeen,
online: 1,
isAdmin: info.isAdmin,
});
}
}
@@ -251,7 +256,7 @@ export function handleFrame(info: ClientInfo, payload: any) {
info.lastSeen = now;
info.online = true;
if (shouldSyncClientToDb(info.id, now)) {
queueClientDbUpdate({ id: info.id, lastSeen: now, online: 1 });
queueClientDbUpdate({ id: info.id, lastSeen: now, online: 1, isAdmin: info.isAdmin });
}
}
}