NODEDC_DESIGN_GUIDELINE/server/foundry-agent-store.test.mjs

74 lines
3.7 KiB
JavaScript

import assert from "node:assert/strict";
import { mkdtemp, readFile, rm } from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import test from "node:test";
import { createFoundryAgentStore } from "./foundry-agent-store.mjs";
test("Foundry agent setup issues separate durable credentials and revoke closes both", async () => {
const dataRoot = await mkdtemp(path.join(os.tmpdir(), "nodedc-foundry-agent-store-"));
let currentTime = Date.parse("2026-07-18T12:00:00.000Z");
const store = createFoundryAgentStore({ dataRoot, now: () => currentTime });
try {
const created = await store.createAgent({
ownerId: "user_root",
ownerKey: "dcctouch@gmail.com",
name: "Foundry Codex",
});
assert.equal(created.status, "active");
assert.equal(created.deviceCount, 0);
assert.equal((await store.listAgents("another@nodedc.local")).length, 0);
const setup = await store.issueSetupCode("dcctouch@gmail.com", created.id);
const redeemed = await store.redeemSetupCode(setup.code, "Mac Pro Codex Desktop");
assert.match(redeemed.foundryToken, /^fnda_/);
assert.match(redeemed.ontologyToken, /^fndo_/);
assert.notEqual(redeemed.foundryToken, redeemed.ontologyToken);
assert.equal(redeemed.device.revokedAt, null);
assert.equal(Object.hasOwn(redeemed.device, "foundryTokenHash"), false);
assert.equal(Object.hasOwn(redeemed.device, "ontologyTokenHash"), false);
await assert.rejects(
() => store.redeemSetupCode(setup.code, "Replay"),
/setup_code_already_redeemed/,
);
const foundrySession = await store.authenticateFoundryToken(redeemed.foundryToken, { check: true });
const ontologySession = await store.authenticateOntologyToken(redeemed.ontologyToken, { check: true });
assert.equal(foundrySession.actor.actorId, "user_root");
assert.equal(ontologySession.actor.ownerKey, "dcctouch@gmail.com");
assert.equal(await store.authenticateFoundryToken(redeemed.ontologyToken), null);
assert.equal(await store.authenticateOntologyToken(redeemed.foundryToken), null);
currentTime += 3 * 365 * 24 * 60 * 60_000;
assert.ok(await store.authenticateFoundryToken(redeemed.foundryToken));
assert.ok(await store.authenticateOntologyToken(redeemed.ontologyToken));
const revoked = await store.revokeAgent("dcctouch@gmail.com", created.id);
assert.equal(revoked.status, "revoked");
assert.equal(await store.authenticateFoundryToken(redeemed.foundryToken), null);
assert.equal(await store.authenticateOntologyToken(redeemed.ontologyToken), null);
const persisted = await readFile(path.join(dataRoot, "agents.json"), "utf8");
assert.equal(persisted.includes(redeemed.foundryToken), false);
assert.equal(persisted.includes(redeemed.ontologyToken), false);
} finally {
await rm(dataRoot, { recursive: true, force: true });
}
});
test("Foundry setup codes expire and cannot cross owner boundaries", async () => {
const dataRoot = await mkdtemp(path.join(os.tmpdir(), "nodedc-foundry-agent-expiry-"));
let currentTime = Date.parse("2026-07-18T12:00:00.000Z");
const store = createFoundryAgentStore({ dataRoot, now: () => currentTime });
try {
const agent = await store.createAgent({ ownerId: "user_root", ownerKey: "owner@nodedc.local", name: "Owner agent" });
await assert.rejects(() => store.issueSetupCode("other@nodedc.local", agent.id), /foundry_agent_not_found/);
const setup = await store.issueSetupCode("owner@nodedc.local", agent.id);
currentTime += 16 * 60_000;
await assert.rejects(() => store.redeemSetupCode(setup.code, "Late device"), /setup_code_expired/);
} finally {
await rm(dataRoot, { recursive: true, force: true });
}
});