mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-19 11:08:37 +00:00
refactor: trim bootstrap token metadata
This commit is contained in:
@@ -405,14 +405,7 @@ export default function register(api: OpenClawPluginApi) {
|
|||||||
|
|
||||||
const payload: SetupPayload = {
|
const payload: SetupPayload = {
|
||||||
url: urlResult.url,
|
url: urlResult.url,
|
||||||
bootstrapToken: (
|
bootstrapToken: (await issueDeviceBootstrapToken()).token,
|
||||||
await issueDeviceBootstrapToken({
|
|
||||||
channel: ctx.channel,
|
|
||||||
senderId: ctx.senderId ?? ctx.from ?? ctx.to,
|
|
||||||
accountId: ctx.accountId,
|
|
||||||
threadId: ctx.messageThreadId != null ? String(ctx.messageThreadId) : undefined,
|
|
||||||
})
|
|
||||||
).token,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (action === "qr") {
|
if (action === "qr") {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { mkdtemp, rm } from "node:fs/promises";
|
import { mkdtemp, readFile, rm } from "node:fs/promises";
|
||||||
import { tmpdir } from "node:os";
|
import { tmpdir } from "node:os";
|
||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||||
@@ -95,4 +95,20 @@ describe("device bootstrap tokens", () => {
|
|||||||
}),
|
}),
|
||||||
).resolves.toEqual({ ok: false, reason: "bootstrap_token_invalid" });
|
).resolves.toEqual({ ok: false, reason: "bootstrap_token_invalid" });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("persists only token state that verification actually consumes", async () => {
|
||||||
|
const baseDir = await createBaseDir();
|
||||||
|
const issued = await issueDeviceBootstrapToken({ baseDir });
|
||||||
|
const raw = await readFile(join(baseDir, "devices", "bootstrap.json"), "utf8");
|
||||||
|
const state = JSON.parse(raw) as Record<string, Record<string, unknown>>;
|
||||||
|
const record = state[issued.token];
|
||||||
|
|
||||||
|
expect(record).toMatchObject({
|
||||||
|
token: issued.token,
|
||||||
|
});
|
||||||
|
expect(record).not.toHaveProperty("channel");
|
||||||
|
expect(record).not.toHaveProperty("senderId");
|
||||||
|
expect(record).not.toHaveProperty("accountId");
|
||||||
|
expect(record).not.toHaveProperty("threadId");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -17,10 +17,6 @@ export type DeviceBootstrapTokenRecord = {
|
|||||||
publicKey?: string;
|
publicKey?: string;
|
||||||
roles?: string[];
|
roles?: string[];
|
||||||
scopes?: string[];
|
scopes?: string[];
|
||||||
channel?: string;
|
|
||||||
senderId?: string;
|
|
||||||
accountId?: string;
|
|
||||||
threadId?: string;
|
|
||||||
issuedAtMs: number;
|
issuedAtMs: number;
|
||||||
lastUsedAtMs?: number;
|
lastUsedAtMs?: number;
|
||||||
};
|
};
|
||||||
@@ -29,11 +25,6 @@ type DeviceBootstrapStateFile = Record<string, DeviceBootstrapTokenRecord>;
|
|||||||
|
|
||||||
const withLock = createAsyncLock();
|
const withLock = createAsyncLock();
|
||||||
|
|
||||||
function normalizeOptionalString(value: string | undefined): string | undefined {
|
|
||||||
const trimmed = value?.trim();
|
|
||||||
return trimmed ? trimmed : undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function mergeRoles(existing: string[] | undefined, role: string): string[] {
|
function mergeRoles(existing: string[] | undefined, role: string): string[] {
|
||||||
const out = new Set<string>(existing ?? []);
|
const out = new Set<string>(existing ?? []);
|
||||||
const trimmed = role.trim();
|
const trimmed = role.trim();
|
||||||
@@ -80,10 +71,6 @@ async function persistState(state: DeviceBootstrapStateFile, baseDir?: string):
|
|||||||
|
|
||||||
export async function issueDeviceBootstrapToken(
|
export async function issueDeviceBootstrapToken(
|
||||||
params: {
|
params: {
|
||||||
channel?: string;
|
|
||||||
senderId?: string;
|
|
||||||
accountId?: string;
|
|
||||||
threadId?: string;
|
|
||||||
baseDir?: string;
|
baseDir?: string;
|
||||||
} = {},
|
} = {},
|
||||||
): Promise<{ token: string; expiresAtMs: number }> {
|
): Promise<{ token: string; expiresAtMs: number }> {
|
||||||
@@ -94,10 +81,6 @@ export async function issueDeviceBootstrapToken(
|
|||||||
state[token] = {
|
state[token] = {
|
||||||
token,
|
token,
|
||||||
ts: issuedAtMs,
|
ts: issuedAtMs,
|
||||||
channel: normalizeOptionalString(params.channel),
|
|
||||||
senderId: normalizeOptionalString(params.senderId),
|
|
||||||
accountId: normalizeOptionalString(params.accountId),
|
|
||||||
threadId: normalizeOptionalString(params.threadId),
|
|
||||||
issuedAtMs,
|
issuedAtMs,
|
||||||
};
|
};
|
||||||
await persistState(state, params.baseDir);
|
await persistState(state, params.baseDir);
|
||||||
|
|||||||
Reference in New Issue
Block a user