mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-06 14:51:08 +00:00
70 lines
2.4 KiB
TypeScript
70 lines
2.4 KiB
TypeScript
import { approveDevicePairing, listDevicePairing } from "./api.js";
|
|
import { formatPendingRequests } from "./notify.js";
|
|
|
|
type PendingPairingEntry = Awaited<ReturnType<typeof listDevicePairing>>["pending"][number];
|
|
type ApprovePairingResult = Awaited<ReturnType<typeof approveDevicePairing>>;
|
|
type ApprovedPairingEntry = Exclude<ApprovePairingResult, null | { status: "forbidden" }>;
|
|
|
|
function buildMultiplePendingApprovalReply(pending: PendingPairingEntry[]): { text: string } {
|
|
return {
|
|
text:
|
|
`${formatPendingRequests(pending)}\n\n` +
|
|
"Multiple pending requests found. Approve one explicitly:\n" +
|
|
"/pair approve <requestId>\n" +
|
|
"Or approve the most recent:\n" +
|
|
"/pair approve latest",
|
|
};
|
|
}
|
|
|
|
export function selectPendingApprovalRequest(params: {
|
|
pending: PendingPairingEntry[];
|
|
requested?: string;
|
|
}): { pending?: PendingPairingEntry; reply?: { text: string } } {
|
|
if (params.pending.length === 0) {
|
|
return { reply: { text: "No pending device pairing requests." } };
|
|
}
|
|
|
|
if (!params.requested) {
|
|
return params.pending.length === 1
|
|
? { pending: params.pending[0] }
|
|
: { reply: buildMultiplePendingApprovalReply(params.pending) };
|
|
}
|
|
|
|
if (params.requested.toLowerCase() === "latest") {
|
|
return {
|
|
pending: [...params.pending].toSorted((a, b) => (b.ts ?? 0) - (a.ts ?? 0))[0],
|
|
};
|
|
}
|
|
|
|
return {
|
|
pending: params.pending.find((entry) => entry.requestId === params.requested),
|
|
reply: undefined,
|
|
};
|
|
}
|
|
|
|
function formatApprovedPairingReply(approved: ApprovedPairingEntry): { text: string } {
|
|
const label = approved.device.displayName?.trim() || approved.device.deviceId;
|
|
const platform = approved.device.platform?.trim();
|
|
const platformLabel = platform ? ` (${platform})` : "";
|
|
return { text: `✅ Paired ${label}${platformLabel}.` };
|
|
}
|
|
|
|
export async function approvePendingPairingRequest(params: {
|
|
requestId: string;
|
|
callerScopes?: readonly string[];
|
|
}): Promise<{ text: string }> {
|
|
const approved =
|
|
params.callerScopes === undefined
|
|
? await approveDevicePairing(params.requestId)
|
|
: await approveDevicePairing(params.requestId, { callerScopes: params.callerScopes });
|
|
if (!approved) {
|
|
return { text: "Pairing request not found." };
|
|
}
|
|
if (approved.status === "forbidden") {
|
|
return {
|
|
text: `⚠️ This command requires ${approved.missingScope} to approve this pairing request.`,
|
|
};
|
|
}
|
|
return formatApprovedPairingReply(approved);
|
|
}
|