add disconnect reasons to dashboard and fix icons in sideview
This commit is contained in:
@@ -97,6 +97,12 @@ db.run(
|
||||
db.run(
|
||||
`CREATE INDEX IF NOT EXISTS idx_clients_ping_ms ON clients(ping_ms);`,
|
||||
);
|
||||
try {
|
||||
db.run(`ALTER TABLE clients ADD COLUMN disconnect_reason TEXT`);
|
||||
} catch {}
|
||||
try {
|
||||
db.run(`ALTER TABLE clients ADD COLUMN disconnect_detail TEXT`);
|
||||
} catch {}
|
||||
|
||||
db.run(`
|
||||
CREATE TABLE IF NOT EXISTS banned_ips (
|
||||
@@ -304,13 +310,22 @@ export function upsertClientRow(
|
||||
}
|
||||
}
|
||||
|
||||
export function setOnlineState(id: string, online: boolean) {
|
||||
db.run(
|
||||
`UPDATE clients SET online=?, last_seen=? WHERE id=?`,
|
||||
online ? 1 : 0,
|
||||
Date.now(),
|
||||
id,
|
||||
);
|
||||
export function setOnlineState(id: string, online: boolean, disconnectReason?: string, disconnectDetail?: string) {
|
||||
if (online) {
|
||||
db.run(
|
||||
`UPDATE clients SET online=1, last_seen=?, disconnect_reason=NULL, disconnect_detail=NULL WHERE id=?`,
|
||||
Date.now(),
|
||||
id,
|
||||
);
|
||||
} else {
|
||||
db.run(
|
||||
`UPDATE clients SET online=0, last_seen=?, disconnect_reason=?, disconnect_detail=? WHERE id=?`,
|
||||
Date.now(),
|
||||
disconnectReason ?? null,
|
||||
disconnectDetail ?? null,
|
||||
id,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function deleteClientRow(id: string) {
|
||||
@@ -541,7 +556,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
|
||||
`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
|
||||
FROM clients
|
||||
${whereSql}
|
||||
${orderBy}
|
||||
@@ -573,6 +588,8 @@ export function listClients(filters: ListFilters): ListResult {
|
||||
cpu: c.cpu || null,
|
||||
gpu: c.gpu || null,
|
||||
ram: c.ram || null,
|
||||
disconnectReason: c.disconnectReason || null,
|
||||
disconnectDetail: c.disconnectDetail || null,
|
||||
thumbnail: getThumbnail(c.id),
|
||||
}));
|
||||
|
||||
|
||||
@@ -555,6 +555,16 @@ export async function handleWebSocketMessage(
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "disconnect_info": {
|
||||
const reason = typeof (payload as any).reason === "string" ? (payload as any).reason : "";
|
||||
const detail = typeof (payload as any).detail === "string" ? (payload as any).detail : "";
|
||||
if (reason) {
|
||||
ws.data.disconnectReason = reason;
|
||||
ws.data.disconnectDetail = detail || undefined;
|
||||
logger.debug(`[disconnect_info] ${client.id} reason=${reason}`);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -709,15 +719,18 @@ export function handleWebSocketClose(
|
||||
});
|
||||
}
|
||||
|
||||
const storedDisconnectReason = ws.data.disconnectReason;
|
||||
const storedDisconnectDetail = ws.data.disconnectDetail;
|
||||
|
||||
clientManager.deleteClient(clientId);
|
||||
stopAllProxiesForClient(clientId);
|
||||
clearClientSyncState(clientId);
|
||||
deps.notifyConsoleClosed(clientId, "Client disconnected");
|
||||
setOnlineState(clientId, false);
|
||||
setOnlineState(clientId, false, storedDisconnectReason, storedDisconnectDetail);
|
||||
deps.clearPendingNotificationScreenshots(clientId);
|
||||
deps.clearClientPluginState(clientId);
|
||||
deps.notifyDashboard();
|
||||
logger.info(`[close] ${clientId} code=${code} reason=${reason}`);
|
||||
logger.info(`[close] ${clientId} code=${code} reason=${reason} disconnect_reason=${storedDisconnectReason || "unknown"}`);
|
||||
|
||||
if (role === "client") {
|
||||
deps.notifyRemoteDesktopStatus(clientId, "offline", "Client disconnected");
|
||||
@@ -729,7 +742,7 @@ export function handleWebSocketClose(
|
||||
action: AuditAction.CLIENT_DISCONNECT,
|
||||
targetClientId: clientId,
|
||||
success: true,
|
||||
details: JSON.stringify({ code, reason: String(reason || "") }),
|
||||
details: JSON.stringify({ code, reason: String(reason || ""), disconnectReason: storedDisconnectReason || null }),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ export type SocketData = {
|
||||
autoTasksRan?: boolean;
|
||||
autoDeploysRan?: boolean;
|
||||
enrollmentNonce?: string;
|
||||
disconnectReason?: string;
|
||||
disconnectDetail?: string;
|
||||
};
|
||||
|
||||
export type ConsoleSession = {
|
||||
|
||||
@@ -31,6 +31,8 @@ export type ClientInfo = {
|
||||
enrollmentStatus?: EnrollmentStatus;
|
||||
publicKey?: string;
|
||||
keyFingerprint?: string;
|
||||
disconnectReason?: string;
|
||||
disconnectDetail?: string;
|
||||
};
|
||||
|
||||
export type ListFilters = {
|
||||
|
||||
@@ -32,6 +32,7 @@ export const ALLOWED_CLIENT_MESSAGE_TYPES = new Set([
|
||||
"clipboard_content",
|
||||
"proxy_data",
|
||||
"proxy_close",
|
||||
"disconnect_info",
|
||||
]);
|
||||
|
||||
export function isAllowedClientMessageType(type: string): boolean {
|
||||
|
||||
Reference in New Issue
Block a user