74 lines
3.0 KiB
TypeScript
74 lines
3.0 KiB
TypeScript
import fs from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { describe, expect, it } from "vitest";
|
|
import { withStateDirEnv } from "../test-helpers/state-dir-env.js";
|
|
import { loadOrCreateDeviceIdentity } from "./device-identity.js";
|
|
|
|
describe("device identity state dir defaults", () => {
|
|
it("writes the default identity file under OPENCLAW_STATE_DIR", async () => {
|
|
await withStateDirEnv("openclaw-identity-state-", async ({ stateDir }) => {
|
|
const identity = loadOrCreateDeviceIdentity();
|
|
const identityPath = path.join(stateDir, "identity", "device.json");
|
|
const raw = JSON.parse(await fs.readFile(identityPath, "utf8")) as { deviceId?: string };
|
|
expect(raw.deviceId).toBe(identity.deviceId);
|
|
});
|
|
});
|
|
|
|
it("reuses the stored identity on subsequent loads", async () => {
|
|
await withStateDirEnv("openclaw-identity-state-", async ({ stateDir }) => {
|
|
const first = loadOrCreateDeviceIdentity();
|
|
const second = loadOrCreateDeviceIdentity();
|
|
const identityPath = path.join(stateDir, "identity", "device.json");
|
|
const raw = JSON.parse(await fs.readFile(identityPath, "utf8")) as {
|
|
deviceId?: string;
|
|
publicKeyPem?: string;
|
|
};
|
|
|
|
expect(second).toEqual(first);
|
|
expect(raw.deviceId).toBe(first.deviceId);
|
|
expect(raw.publicKeyPem).toBe(first.publicKeyPem);
|
|
});
|
|
});
|
|
|
|
it("repairs stored device IDs that no longer match the public key", async () => {
|
|
await withStateDirEnv("openclaw-identity-state-", async ({ stateDir }) => {
|
|
const original = loadOrCreateDeviceIdentity();
|
|
const identityPath = path.join(stateDir, "identity", "device.json");
|
|
const raw = JSON.parse(await fs.readFile(identityPath, "utf8")) as Record<string, unknown>;
|
|
|
|
await fs.writeFile(
|
|
identityPath,
|
|
`${JSON.stringify({ ...raw, deviceId: "stale-device-id" }, null, 2)}\n`,
|
|
"utf8",
|
|
);
|
|
|
|
const repaired = loadOrCreateDeviceIdentity();
|
|
const stored = JSON.parse(await fs.readFile(identityPath, "utf8")) as { deviceId?: string };
|
|
|
|
expect(repaired.deviceId).toBe(original.deviceId);
|
|
expect(stored.deviceId).toBe(original.deviceId);
|
|
});
|
|
});
|
|
|
|
it("regenerates the identity when the stored file is invalid", async () => {
|
|
await withStateDirEnv("openclaw-identity-state-", async ({ stateDir }) => {
|
|
const identityPath = path.join(stateDir, "identity", "device.json");
|
|
await fs.mkdir(path.dirname(identityPath), { recursive: true });
|
|
await fs.writeFile(identityPath, '{"version":1,"deviceId":"broken"}\n', "utf8");
|
|
|
|
const regenerated = loadOrCreateDeviceIdentity();
|
|
const stored = JSON.parse(await fs.readFile(identityPath, "utf8")) as {
|
|
version?: number;
|
|
deviceId?: string;
|
|
publicKeyPem?: string;
|
|
privateKeyPem?: string;
|
|
};
|
|
|
|
expect(stored.version).toBe(1);
|
|
expect(stored.deviceId).toBe(regenerated.deviceId);
|
|
expect(stored.publicKeyPem).toBe(regenerated.publicKeyPem);
|
|
expect(stored.privateKeyPem).toBe(regenerated.privateKeyPem);
|
|
});
|
|
});
|
|
});
|