mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-04 05:11:35 +00:00
* fix(nodes): surface pending reapproval diagnostics * fix(nodes): harden reapproval diagnostics * fix(nodes): scope pending diagnostics * fix(nodes): request pairing diagnostics in cli * fix(nodes): reuse stored auth for diagnostics * fix(nodes): preserve selected diagnostics credentials * fix(nodes): prefer approved diagnostics auth * fix(nodes): narrow diagnostics fallbacks * fix(nodes): recover from stale diagnostics auth * fix(gateway): preserve connect error narrowing * fix(nodes): isolate privileged diagnostics auth * fix(nodes): constrain privileged diagnostics auth * fix(nodes): close diagnostics review gaps * fix(nodes): guard reapproval cleanup races * fix(nodes): defer stale pairing cleanup * fix(nodes): preserve reapproval on hello failure * test(nodes): await post-handshake reapproval cleanup * test(nodes): avoid unbound websocket send capture * fix(nodes): allow local auth-none diagnostics * fix(nodes): preserve overlapping reapproval * fix(nodes): preserve pending node metadata * fix(nodes): keep connection age with status * fix(nodes): preserve reapproval during reconnect races * fix(nodes): serialize reapproval cleanup * fix(nodes): bound reapproval reconnect races * test(nodes): satisfy cleanup claim lint --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
88 lines
3.1 KiB
TypeScript
88 lines
3.1 KiB
TypeScript
// Runtime gateway RPC helpers for node host and node pairing CLI commands.
|
|
import {
|
|
GATEWAY_CLIENT_MODES,
|
|
GATEWAY_CLIENT_NAMES,
|
|
} from "../../../packages/gateway-protocol/src/client-info.js";
|
|
import { callGateway } from "../../gateway/call.js";
|
|
import type { OperatorScope } from "../../gateway/method-scopes.js";
|
|
import { parseTimeoutMsWithFallback } from "../parse-timeout.js";
|
|
import { withProgress } from "../progress.js";
|
|
import type { NodesRpcOpts } from "./types.js";
|
|
|
|
const NODE_PAIR_APPROVAL_GATEWAY_METHODS = new Set<string>(["node.pair.list", "node.pair.approve"]);
|
|
const DEFAULT_NODES_RPC_TIMEOUT_MS = 10_000;
|
|
|
|
function resolveNodesTransportTimeoutMs(opts: NodesRpcOpts, overrideMs?: number): number {
|
|
return overrideMs ?? parseTimeoutMsWithFallback(opts.timeout, DEFAULT_NODES_RPC_TIMEOUT_MS);
|
|
}
|
|
|
|
export async function callGatewayCliRuntime(
|
|
method: string,
|
|
opts: NodesRpcOpts,
|
|
params?: unknown,
|
|
callOpts?: {
|
|
scopes?: OperatorScope[];
|
|
transportTimeoutMs?: number;
|
|
useStoredDeviceAuth?: boolean;
|
|
requiredStoredDeviceAuthScopes?: OperatorScope[];
|
|
useLocalBackendSharedAuth?: boolean;
|
|
},
|
|
) {
|
|
// Progress is suppressed for JSON callers so stdout remains structured.
|
|
return await withProgress(
|
|
{
|
|
label: `Nodes ${method}`,
|
|
indeterminate: true,
|
|
enabled: opts.json !== true,
|
|
},
|
|
async () =>
|
|
await callGateway({
|
|
url: opts.url,
|
|
token: opts.token,
|
|
method,
|
|
params,
|
|
scopes: callOpts?.scopes,
|
|
useStoredDeviceAuth: callOpts?.useStoredDeviceAuth,
|
|
requiredStoredDeviceAuthScopes: callOpts?.requiredStoredDeviceAuthScopes,
|
|
requireLocalBackendSharedAuth: callOpts?.useLocalBackendSharedAuth,
|
|
timeoutMs: resolveNodesTransportTimeoutMs(opts, callOpts?.transportTimeoutMs),
|
|
clientName: callOpts?.useLocalBackendSharedAuth
|
|
? GATEWAY_CLIENT_NAMES.GATEWAY_CLIENT
|
|
: GATEWAY_CLIENT_NAMES.CLI,
|
|
mode: callOpts?.useLocalBackendSharedAuth
|
|
? GATEWAY_CLIENT_MODES.BACKEND
|
|
: GATEWAY_CLIENT_MODES.CLI,
|
|
}),
|
|
);
|
|
}
|
|
|
|
export async function callNodePairApprovalGatewayCliRuntime(
|
|
method: "node.pair.list" | "node.pair.approve",
|
|
opts: NodesRpcOpts,
|
|
params: unknown,
|
|
callOpts: { scopes: OperatorScope[]; transportTimeoutMs?: number },
|
|
) {
|
|
if (!NODE_PAIR_APPROVAL_GATEWAY_METHODS.has(method)) {
|
|
throw new Error(`unsupported node pair approval gateway method: ${method}`);
|
|
}
|
|
// Node approval may need the local gateway's backend shared-auth authority
|
|
// before the CLI device has been granted the node's required operator scopes.
|
|
return await withProgress(
|
|
{
|
|
label: `Nodes ${method}`,
|
|
indeterminate: true,
|
|
enabled: opts.json !== true,
|
|
},
|
|
async () =>
|
|
await callGateway({
|
|
url: opts.url,
|
|
token: opts.token,
|
|
method,
|
|
params,
|
|
timeoutMs: resolveNodesTransportTimeoutMs(opts, callOpts.transportTimeoutMs),
|
|
clientName: GATEWAY_CLIENT_NAMES.GATEWAY_CLIENT,
|
|
mode: GATEWAY_CLIENT_MODES.BACKEND,
|
|
scopes: callOpts.scopes,
|
|
}),
|
|
);
|
|
}
|