refactor: reuse canonical setup bootstrap profile

This commit is contained in:
Peter Steinberger
2026-03-23 00:15:05 -07:00
parent 6686f1cb2c
commit 04c69ea3a0
4 changed files with 19 additions and 6 deletions

View File

@@ -2,8 +2,10 @@ export {
approveDevicePairing,
clearDeviceBootstrapTokens,
issueDeviceBootstrapToken,
PAIRING_SETUP_BOOTSTRAP_PROFILE,
listDevicePairing,
revokeDeviceBootstrapToken,
type DeviceBootstrapProfile,
} from "openclaw/plugin-sdk/device-bootstrap";
export { definePluginEntry, type OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
export { resolveGatewayBindUrl, resolveTailnetHostWithRunner } from "openclaw/plugin-sdk/core";

View File

@@ -22,6 +22,10 @@ const pluginApiMocks = vi.hoisted(() => ({
vi.mock("./api.js", () => {
return {
PAIRING_SETUP_BOOTSTRAP_PROFILE: {
roles: ["node"],
scopes: [],
},
approveDevicePairing: vi.fn(),
clearDeviceBootstrapTokens: pluginApiMocks.clearDeviceBootstrapTokens,
definePluginEntry: vi.fn((entry) => entry),
@@ -150,8 +154,10 @@ describe("device-pair /pair qr", () => {
expect(pluginApiMocks.renderQrPngBase64).toHaveBeenCalledTimes(1);
expect(pluginApiMocks.issueDeviceBootstrapToken).toHaveBeenCalledWith({
roles: ["node"],
scopes: [],
profile: {
roles: ["node"],
scopes: [],
},
});
expect(text).toContain("Scan this QR code with the OpenClaw iOS app:");
expect(text).toContain("![OpenClaw pairing QR](data:image/png;base64,ZmFrZXBuZw==)");

View File

@@ -7,6 +7,7 @@ import {
definePluginEntry,
issueDeviceBootstrapToken,
listDevicePairing,
PAIRING_SETUP_BOOTSTRAP_PROFILE,
renderQrPngBase64,
revokeDeviceBootstrapToken,
resolveGatewayBindUrl,
@@ -43,8 +44,6 @@ function formatDurationMinutes(expiresAtMs: number): string {
}
const DEFAULT_GATEWAY_PORT = 18789;
const SETUP_CODE_ROLES = ["node"] as const;
const SETUP_CODE_SCOPES: string[] = [];
type DevicePairPluginConfig = {
publicUrl?: string;
@@ -518,8 +517,7 @@ function resolveQrReplyTarget(ctx: QrCommandContext): string {
async function issueSetupPayload(url: string): Promise<SetupPayload> {
const issuedBootstrap = await issueDeviceBootstrapToken({
roles: SETUP_CODE_ROLES,
scopes: SETUP_CODE_SCOPES,
profile: PAIRING_SETUP_BOOTSTRAP_PROFILE,
});
return {
url,

View File

@@ -6,3 +6,10 @@ export {
issueDeviceBootstrapToken,
revokeDeviceBootstrapToken,
} from "../infra/device-bootstrap.js";
export {
normalizeDeviceBootstrapProfile,
PAIRING_SETUP_BOOTSTRAP_PROFILE,
sameDeviceBootstrapProfile,
type DeviceBootstrapProfile,
type DeviceBootstrapProfileInput,
} from "../shared/device-bootstrap-profile.js";