mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-21 06:51:01 +00:00
Gateway: preserve interactive pairing visibility on supersede
This commit is contained in:
@@ -162,6 +162,36 @@ describe("device pairing tokens", () => {
|
||||
expect(paired?.scopes).toEqual(["operator.read", "operator.write"]);
|
||||
});
|
||||
|
||||
test("keeps superseded requests interactive when an existing pending request is interactive", async () => {
|
||||
const baseDir = await mkdtemp(join(tmpdir(), "openclaw-device-pairing-"));
|
||||
const first = await requestDevicePairing(
|
||||
{
|
||||
deviceId: "device-1",
|
||||
publicKey: "public-key-1",
|
||||
role: "node",
|
||||
scopes: [],
|
||||
silent: false,
|
||||
},
|
||||
baseDir,
|
||||
);
|
||||
expect(first.request.silent).toBe(false);
|
||||
|
||||
const second = await requestDevicePairing(
|
||||
{
|
||||
deviceId: "device-1",
|
||||
publicKey: "public-key-1",
|
||||
role: "operator",
|
||||
scopes: ["operator.read"],
|
||||
silent: true,
|
||||
},
|
||||
baseDir,
|
||||
);
|
||||
|
||||
expect(second.created).toBe(true);
|
||||
expect(second.request.requestId).not.toBe(first.request.requestId);
|
||||
expect(second.request.silent).toBe(false);
|
||||
});
|
||||
|
||||
test("rejects bootstrap token replay before pending scope escalation can be approved", async () => {
|
||||
const baseDir = await mkdtemp(join(tmpdir(), "openclaw-device-pairing-"));
|
||||
const issued = await issueDeviceBootstrapToken({ baseDir });
|
||||
|
||||
@@ -236,6 +236,15 @@ function refreshPendingDevicePairingRequest(
|
||||
};
|
||||
}
|
||||
|
||||
function resolveSupersededPendingSilent(params: {
|
||||
existing: readonly DevicePairingPendingRequest[];
|
||||
incomingSilent: boolean | undefined;
|
||||
}): boolean {
|
||||
return Boolean(
|
||||
params.incomingSilent && params.existing.every((pending) => pending.silent === true),
|
||||
);
|
||||
}
|
||||
|
||||
function buildPendingDevicePairingRequest(params: {
|
||||
requestId?: string;
|
||||
deviceId: string;
|
||||
@@ -394,7 +403,15 @@ export async function requestDevicePairing(
|
||||
const superseded = buildPendingDevicePairingRequest({
|
||||
deviceId,
|
||||
isRepair,
|
||||
req,
|
||||
req: {
|
||||
...req,
|
||||
// Preserve interactive visibility when superseding pending requests:
|
||||
// if any previous pending request was interactive, keep this one interactive.
|
||||
silent: resolveSupersededPendingSilent({
|
||||
existing: pendingForDevice,
|
||||
incomingSilent: req.silent,
|
||||
}),
|
||||
},
|
||||
});
|
||||
state.pendingById[superseded.requestId] = superseded;
|
||||
await persistState(state, baseDir);
|
||||
|
||||
Reference in New Issue
Block a user