fix(frontend): shrink callback jargon and harden contract tests
cognitive committed
Mar 4, 2026 at 06:15 UTC
197e7abe7661a8613cb7898b285640abdff20dc9
3 files changed
+155
-209
cmd/relay-server/frontend/src/components/ServerListView.tsx
+31
-62
@@ -1,4 +1,4 @@
1
-import { useCallback, useEffect, useMemo, useState } from "react";
1
+import { useEffect, useMemo, useState } from "react";
2
import { Header } from "@/components/Header";
3
import { SearchBar } from "@/components/SearchBar";
4
import { ServerCard } from "@/components/ServerCard";
@@ -59,6 +59,20 @@ function toAdminServer(server: ListServer): AdminServer | undefined {
59
return isAdminServer(server) ? server : undefined;
60
}
61
62
+function wrapAdminHandler<Args extends unknown[]>(
63
+ handler?: (...args: Args) => void | Promise<void>
64
+): ((...args: Args) => void) | undefined {
65
+ if (!handler) {
66
+ return undefined;
67
+ }
68
+
69
+ return (...args: Args) => {
70
+ void Promise.resolve(handler(...args)).catch((error) => {
71
+ console.error("Failed admin action", error);
72
+ });
73
+ };
74
+}
75
+
76
export function ServerListView({
77
title = "PORTAL",
78
searchQuery,
@@ -175,74 +189,29 @@ export function ServerListView({
189
}
190
};
191
178
- const triggerBulkAction = async (handler?: (leaseIds: string[]) => void) => {
192
+ const runBulkAction = (handler?: (leaseIds: string[]) => void) => {
193
if (!handler || selectedLeaseIds.size === 0) {
194
return;
195
}
196
183
- try {
184
- await Promise.resolve(handler(Array.from(selectedLeaseIds)));
185
- handleClearSelection();
186
- } catch (err) {
187
- console.error("Failed bulk admin action", err);
188
- }
189
- };
190
-
191
- const handleBulkApprove = () => triggerBulkAction(onBulkApprove);
192
- const handleBulkDeny = () => triggerBulkAction(onBulkDeny);
193
- const handleBulkBan = () => triggerBulkAction(onBulkBan);
194
-
195
- const invokeAsyncHandler = useCallback(
196
- (action: (() => void | Promise<void>) | undefined) => {
197
- if (!action) {
198
- return;
199
- }
200
- void Promise.resolve(action()).catch((error) => {
201
- console.error("Failed admin action", error);
197
+ void Promise.resolve(handler(Array.from(selectedLeaseIds)))
198
+ .then(() => {
199
+ handleClearSelection();
200
+ })
201
+ .catch((err) => {
202
+ console.error("Failed bulk admin action", err);
203
});
203
- },
204
- []
205
- );
206
-
207
- const handleCardBanStatusChange = useCallback(
208
- (leaseId: string, isBan: boolean) =>
209
- invokeAsyncHandler(
210
- onBanStatusChange ? () => onBanStatusChange(leaseId, isBan) : undefined
211
- ),
212
- [invokeAsyncHandler, onBanStatusChange]
213
- );
214
-
215
- const handleCardBPSChange = useCallback(
216
- (leaseId: string, bps: number) =>
217
- invokeAsyncHandler(onBPSChange ? () => onBPSChange(leaseId, bps) : undefined),
218
- [invokeAsyncHandler, onBPSChange]
219
- );
220
-
221
- const handleCardApproveStatusChange = useCallback(
222
- (leaseId: string, approve: boolean) =>
223
- invokeAsyncHandler(
224
- onApproveStatusChange
225
- ? () => onApproveStatusChange(leaseId, approve)
226
- : undefined
227
- ),
228
- [invokeAsyncHandler, onApproveStatusChange]
229
- );
204
+ };
205
231
- const handleCardDenyStatusChange = useCallback(
232
- (leaseId: string, deny: boolean) =>
233
- invokeAsyncHandler(
234
- onDenyStatusChange ? () => onDenyStatusChange(leaseId, deny) : undefined
235
- ),
236
- [invokeAsyncHandler, onDenyStatusChange]
237
- );
206
+ const handleBulkApprove = () => runBulkAction(onBulkApprove);
207
+ const handleBulkDeny = () => runBulkAction(onBulkDeny);
208
+ const handleBulkBan = () => runBulkAction(onBulkBan);
209
239
- const handleCardIPBanStatusChange = useCallback(
240
- (ip: string, isBan: boolean) =>
241
- invokeAsyncHandler(
242
- onIPBanStatusChange ? () => onIPBanStatusChange(ip, isBan) : undefined
243
- ),
244
- [invokeAsyncHandler, onIPBanStatusChange]
245
- );
210
+ const handleCardBanStatusChange = wrapAdminHandler(onBanStatusChange);
211
+ const handleCardBPSChange = wrapAdminHandler(onBPSChange);
212
+ const handleCardApproveStatusChange = wrapAdminHandler(onApproveStatusChange);
213
+ const handleCardDenyStatusChange = wrapAdminHandler(onDenyStatusChange);
214
+ const handleCardIPBanStatusChange = wrapAdminHandler(onIPBanStatusChange);
215
216
const adminFilterControls = (
217
<>
cmd/relay-server/frontend/src/hooks/useAdmin.ts
+107
-146
@@ -68,13 +68,6 @@ function toAdminErrorMessage(error: unknown, fallback: string): string {
68
return fallback;
69
}
70
71
-function encodeLeaseIDForPath(raw: string): string {
72
- if (!raw) {
73
- throw new Error("Missing lease ID");
74
- }
75
- return encodeLeaseID(raw);
76
-}
77
-
71
function toAdminServer(
72
row: ServerData,
73
index: number,
@@ -172,19 +165,16 @@ export function useAdmin() {
165
);
166
}, [serverData, bannedLeaseSet]);
167
175
- const additionalFilter = useCallback(
176
- (server: AdminServer) => {
177
- switch (banFilter) {
178
- case "banned":
179
- return server.isBanned;
180
- case "active":
181
- return !server.isBanned;
182
- default:
183
- return true;
184
- }
185
- },
186
- [banFilter]
187
- );
168
+ const additionalFilter = (server: AdminServer) => {
169
+ switch (banFilter) {
170
+ case "banned":
171
+ return server.isBanned;
172
+ case "active":
173
+ return !server.isBanned;
174
+ default:
175
+ return true;
176
+ }
177
+ };
178
179
const listState = useList({
180
servers,
@@ -192,151 +182,122 @@ export function useAdmin() {
182
additionalFilter,
183
});
184
195
- const runAdminAction = useCallback(
196
- async (action: () => Promise<void>) => {
197
- setError("");
198
- try {
199
- await action();
200
- await fetchData();
201
- } catch (err: unknown) {
202
- const message = toAdminErrorMessage(err, "Action failed");
203
- console.error(err);
204
- setError(message);
205
- throw err;
206
- }
207
- },
208
- [fetchData]
209
- );
185
+ const runAdminAction = async (action: () => Promise<void>) => {
186
+ setError("");
187
+ try {
188
+ await action();
189
+ await fetchData();
190
+ } catch (err: unknown) {
191
+ const message = toAdminErrorMessage(err, "Action failed");
192
+ console.error(err);
193
+ setError(message);
194
+ throw err;
195
+ }
196
+ };
197
211
- const updateLeaseAction = useCallback(
212
- async (peerId: string, action: LeaseAction, enabled: boolean) => {
213
- const encodedLeaseID = encodeLeaseIDForPath(peerId);
214
- const method = enabled ? apiClient.post : apiClient.delete;
215
- await method<LeaseActionResult>(adminLeasePath(encodedLeaseID, action));
216
- },
217
- []
218
- );
198
+ const updateLeaseAction = async (
199
+ peerId: string,
200
+ action: LeaseAction,
201
+ enabled: boolean
202
+ ) => {
203
+ if (!peerId) {
204
+ throw new Error("Missing lease ID");
205
+ }
206
+ const encodedLeaseID = encodeLeaseID(peerId);
207
+ const method = enabled ? apiClient.post : apiClient.delete;
208
+ await method<LeaseActionResult>(adminLeasePath(encodedLeaseID, action));
209
+ };
210
220
- const handleBanFilterChange = useCallback((value: BanFilter) => {
211
+ const handleBanFilterChange = (value: BanFilter) => {
212
setBanFilter(value);
222
- }, []);
213
+ };
214
224
- const handleBanStatus = useCallback(
225
- (peerId: string, isBan: boolean) =>
226
- runAdminAction(() => updateLeaseAction(peerId, "ban", isBan)),
227
- [runAdminAction, updateLeaseAction]
228
- );
215
+ const handleBanStatus = (peerId: string, isBan: boolean) =>
216
+ runAdminAction(() => updateLeaseAction(peerId, "ban", isBan));
217
230
- const handleBPSChange = useCallback(
231
- (peerId: string, bps: number) =>
232
- runAdminAction(async () => {
233
- const encodedLeaseID = encodeLeaseIDForPath(peerId);
234
- const normalizedBPS = Math.trunc(bps);
235
- if (!Number.isFinite(normalizedBPS) || normalizedBPS <= 0) {
236
- await apiClient.delete<LeaseActionResult>(
237
- adminLeasePath(encodedLeaseID, "bps")
238
- );
239
- return;
240
- }
241
- await apiClient.post<LeaseActionResult>(adminLeasePath(encodedLeaseID, "bps"), {
242
- bps: normalizedBPS,
243
- });
244
- }),
245
- [runAdminAction]
246
- );
247
-
248
- const handleApprovalModeChange = useCallback(
249
- async (mode: ApprovalMode) => {
250
- await runAdminAction(async () => {
251
- const response = await apiClient.post<SettingsResponse>(
252
- API_PATHS.admin.approvalMode,
253
- { mode }
218
+ const handleBPSChange = (peerId: string, bps: number) =>
219
+ runAdminAction(async () => {
220
+ if (!peerId) {
221
+ throw new Error("Missing lease ID");
222
+ }
223
+ const encodedLeaseID = encodeLeaseID(peerId);
224
+ const normalizedBPS = Math.trunc(bps);
225
+ if (!Number.isFinite(normalizedBPS) || normalizedBPS <= 0) {
226
+ await apiClient.delete<LeaseActionResult>(
227
+ adminLeasePath(encodedLeaseID, "bps")
228
);
255
- const nextMode = normalizeApprovalMode(response?.approval_mode ?? mode);
256
- setApprovalMode(nextMode);
229
+ return;
230
+ }
231
+ await apiClient.post<LeaseActionResult>(adminLeasePath(encodedLeaseID, "bps"), {
232
+ bps: normalizedBPS,
233
});
258
- },
259
- [runAdminAction]
260
- );
234
+ });
235
262
- const handleApproveStatus = useCallback(
263
- (peerId: string, approve: boolean) =>
264
- runAdminAction(() => updateLeaseAction(peerId, "approve", approve)),
265
- [runAdminAction, updateLeaseAction]
266
- );
236
+ const handleApprovalModeChange = async (mode: ApprovalMode) => {
237
+ await runAdminAction(async () => {
238
+ const response = await apiClient.post<SettingsResponse>(
239
+ API_PATHS.admin.approvalMode,
240
+ { mode }
241
+ );
242
+ const nextMode = normalizeApprovalMode(response?.approval_mode ?? mode);
243
+ setApprovalMode(nextMode);
244
+ });
245
+ };
246
268
- const handleDenyStatus = useCallback(
269
- (peerId: string, deny: boolean) =>
270
- runAdminAction(() => updateLeaseAction(peerId, "deny", deny)),
271
- [runAdminAction, updateLeaseAction]
272
- );
247
+ const handleApproveStatus = (peerId: string, approve: boolean) =>
248
+ runAdminAction(() => updateLeaseAction(peerId, "approve", approve));
249
274
- const handleIPBanStatus = useCallback(
275
- (ip: string, isBan: boolean) =>
276
- runAdminAction(async () => {
277
- const normalizedIP = ip.trim();
278
- if (!normalizedIP) {
279
- throw new Error("Missing IP address");
280
- }
281
- if (isBan) {
282
- await apiClient.post<LeaseActionResult>(adminIPBanPath(normalizedIP));
283
- return;
284
- }
285
- await apiClient.delete<LeaseActionResult>(adminIPBanPath(normalizedIP));
286
- }),
287
- [runAdminAction]
288
- );
250
+ const handleDenyStatus = (peerId: string, deny: boolean) =>
251
+ runAdminAction(() => updateLeaseAction(peerId, "deny", deny));
252
290
- const runBulkLeaseAction = useCallback(
291
- async (peerIds: string[], action: LeaseAction) => {
292
- const normalizedPeerIDs = dedupeStrings(peerIds.filter((peerId) => peerId.length > 0));
293
- if (normalizedPeerIDs.length === 0) {
294
- throw new Error("No valid leases selected");
253
+ const handleIPBanStatus = (ip: string, isBan: boolean) =>
254
+ runAdminAction(async () => {
255
+ const normalizedIP = ip.trim();
256
+ if (!normalizedIP) {
257
+ throw new Error("Missing IP address");
258
+ }
259
+ if (isBan) {
260
+ await apiClient.post<LeaseActionResult>(adminIPBanPath(normalizedIP));
261
+ return;
262
}
263
+ await apiClient.delete<LeaseActionResult>(adminIPBanPath(normalizedIP));
264
+ });
265
297
- const results = await Promise.allSettled(
298
- normalizedPeerIDs.map((peerId) =>
299
- apiClient.post<LeaseActionResult>(
300
- adminLeasePath(encodeLeaseIDForPath(peerId), action)
301
- )
266
+ const runBulkLeaseAction = async (peerIds: string[], action: LeaseAction) => {
267
+ const normalizedPeerIDs = dedupeStrings(peerIds.filter((peerId) => peerId.length > 0));
268
+ if (normalizedPeerIDs.length === 0) {
269
+ throw new Error("No valid leases selected");
270
+ }
271
+
272
+ const results = await Promise.allSettled(
273
+ normalizedPeerIDs.map((peerId) =>
274
+ apiClient.post<LeaseActionResult>(
275
+ adminLeasePath(encodeLeaseID(peerId), action)
276
)
303
- );
277
+ )
278
+ );
279
305
- const failed = results.find(
306
- (
307
- result
308
- ): result is PromiseRejectedResult =>
309
- result.status === "rejected"
310
- );
311
- if (failed) {
312
- throw failed.reason instanceof Error
313
- ? failed.reason
314
- : new Error(String(failed.reason));
315
- }
316
- },
317
- []
318
- );
280
+ const failed = results.find(
281
+ (
282
+ result
283
+ ): result is PromiseRejectedResult =>
284
+ result.status === "rejected"
285
+ );
286
+ if (failed) {
287
+ throw failed.reason instanceof Error
288
+ ? failed.reason
289
+ : new Error(String(failed.reason));
290
+ }
291
+ };
292
320
- const handleBulkAction = useCallback(
321
- (peerIds: string[], action: LeaseAction) =>
322
- runAdminAction(() => runBulkLeaseAction(peerIds, action)),
323
- [runAdminAction, runBulkLeaseAction]
324
- );
293
+ const handleBulkAction = (peerIds: string[], action: LeaseAction) =>
294
+ runAdminAction(() => runBulkLeaseAction(peerIds, action));
295
326
- const handleBulkApprove = useCallback(
327
- (peerIds: string[]) => handleBulkAction(peerIds, "approve"),
328
- [handleBulkAction]
329
- );
296
+ const handleBulkApprove = (peerIds: string[]) => handleBulkAction(peerIds, "approve");
297
331
- const handleBulkDeny = useCallback(
332
- (peerIds: string[]) => handleBulkAction(peerIds, "deny"),
333
- [handleBulkAction]
334
- );
298
+ const handleBulkDeny = (peerIds: string[]) => handleBulkAction(peerIds, "deny");
299
336
- const handleBulkBan = useCallback(
337
- (peerIds: string[]) => handleBulkAction(peerIds, "ban"),
338
- [handleBulkAction]
339
- );
300
+ const handleBulkBan = (peerIds: string[]) => handleBulkAction(peerIds, "ban");
301
302
return {
303
serverData,
cmd/relay-server/frontend/src/lib/apiPaths.test.ts
+17
-1
@@ -1,6 +1,6 @@
1
import { describe, expect, it } from "vitest";
2
3
-import { API_PATHS } from "@/lib/apiPaths";
3
+import { API_PATHS, adminLeasePath, encodeLeaseID } from "@/lib/apiPaths";
4
5
describe("API_PATHS contract alignment", () => {
6
it("keeps sdk endpoint paths aligned", () => {
@@ -14,6 +14,22 @@ describe("API_PATHS contract alignment", () => {
14
});
15
});
16
17
+ it("encodes lease IDs as base64url path segments", () => {
18
+ const leaseId = "peer:legacy/123";
19
+ const expected = Buffer.from(leaseId)
20
+ .toString("base64")
21
+ .replace(/\+/g, "-")
22
+ .replace(/\//g, "_")
23
+ .replace(/=+$/, "");
24
+ const encoded = encodeLeaseID(leaseId);
25
+
26
+ expect(encoded).toBe(expected);
27
+ expect(encoded).not.toContain("=");
28
+ expect(adminLeasePath(encoded, "approve")).toBe(
29
+ `${API_PATHS.admin.leases}/${encodeURIComponent(encoded)}/approve`
30
+ );
31
+ });
32
+
33
it("keeps tunnel installer endpoint aligned", () => {
34
expect(API_PATHS.tunnel).toBe("/tunnel");
35
});