change around pings, fix main.js so the actual real fucking number shows instead of it freaking out.
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { decodeMessage } from "../../protocol";
|
||||
import type { ClientInfo } from "../../types";
|
||||
import { dispatchPingBulk } from "./client-command-routes";
|
||||
|
||||
function makeClient(): ClientInfo {
|
||||
const sent: Uint8Array[] = [];
|
||||
return {
|
||||
id: "bulk-ping-client",
|
||||
role: "client",
|
||||
lastSeen: Date.now(),
|
||||
ws: {
|
||||
send(data: Uint8Array) {
|
||||
sent.push(data);
|
||||
},
|
||||
_sent: sent,
|
||||
},
|
||||
} as any;
|
||||
}
|
||||
|
||||
describe("client command ping diagnostics", () => {
|
||||
test("dispatchPingBulk sends the requested number of pings", () => {
|
||||
const client = makeClient();
|
||||
const sent = (client.ws as any)._sent as Uint8Array[];
|
||||
|
||||
const count = dispatchPingBulk(client, 3);
|
||||
|
||||
expect(count).toBe(3);
|
||||
expect(sent.length).toBe(3);
|
||||
for (const raw of sent) {
|
||||
const payload = decodeMessage(raw) as any;
|
||||
expect(payload.type).toBe("ping");
|
||||
expect(typeof payload.ts).toBe("number");
|
||||
}
|
||||
expect(typeof client.lastPingNonce).toBe("number");
|
||||
});
|
||||
|
||||
test("dispatchPingBulk clamps invalid and large counts", () => {
|
||||
const invalid = makeClient();
|
||||
expect(dispatchPingBulk(invalid, "bad")).toBe(1);
|
||||
expect((invalid.ws as any)._sent.length).toBe(1);
|
||||
|
||||
const large = makeClient();
|
||||
expect(dispatchPingBulk(large, 5000)).toBe(1000);
|
||||
expect((large.ws as any)._sent.length).toBe(1000);
|
||||
});
|
||||
});
|
||||
@@ -7,6 +7,8 @@ import { metrics } from "../../metrics";
|
||||
import { encodeMessage } from "../../protocol";
|
||||
import { requireClientAccess, requireFeatureAccess, requirePermission } from "../../rbac";
|
||||
import { clearThumbnail } from "../../thumbnails";
|
||||
import type { ClientInfo } from "../../types";
|
||||
import { sendPingRequest } from "../../wsHandlers";
|
||||
|
||||
type RequestIpProvider = {
|
||||
requestIP: (req: Request) => { address?: string } | null | undefined;
|
||||
@@ -32,6 +34,20 @@ type ClientCommandDeps = {
|
||||
pendingCommandReplies: Map<string, PendingCommandReply>;
|
||||
};
|
||||
|
||||
function clampPositiveInt(value: unknown, fallback: number, max: number): number {
|
||||
const parsed = Number(value);
|
||||
if (!Number.isFinite(parsed) || parsed <= 0) return fallback;
|
||||
return Math.min(max, Math.max(1, Math.floor(parsed)));
|
||||
}
|
||||
|
||||
export function dispatchPingBulk(target: ClientInfo, countValue: unknown): number {
|
||||
const count = clampPositiveInt(countValue, 1, 1000);
|
||||
for (let i = 0; i < count; i++) {
|
||||
sendPingRequest(target, target.ws, "manual-bulk", 0);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
export async function handleClientCommandRoute(
|
||||
req: Request,
|
||||
url: URL,
|
||||
@@ -71,12 +87,13 @@ export async function handleClientCommandRoute(
|
||||
let success = true;
|
||||
|
||||
if (action === "ping") {
|
||||
const nonce = Date.now() + Math.floor(Math.random() * 1000);
|
||||
target.lastPingSent = Date.now();
|
||||
target.lastPingNonce = nonce;
|
||||
target.ws.send(encodeMessage({ type: "ping", ts: nonce }));
|
||||
sendPingRequest(target, target.ws, "manual", 0);
|
||||
metrics.recordCommand("ping");
|
||||
} else if (action === "ping_bulk") {
|
||||
Math.max(1, Math.min(1000, Number(body?.count || 1)));
|
||||
const count = dispatchPingBulk(target, body?.count);
|
||||
metrics.recordCommand("ping_bulk");
|
||||
logAudit({ timestamp: Date.now(), username: user.username, ip, action: AuditAction.COMMAND, targetClientId: targetId, details: `ping_bulk:${count}`, success: true });
|
||||
return Response.json({ ok: true, sent: count }, { headers: deps.CORS_HEADERS });
|
||||
} else if (action === "disconnect") {
|
||||
try {
|
||||
requirePermission(user, "clients:disconnect");
|
||||
|
||||
Reference in New Issue
Block a user