open-design/apps/daemon/tests/tool-tokens.test.ts
marco 5dd70b5016
Some checks failed
ci / Validate workspace (push) Successful in 12m32s
landing-page-ci / Validate landing page (push) Successful in 9m41s
landing-page-deploy / Deploy landing page (push) Failing after 5m23s
github-metrics / Generate repository metrics SVG (push) Failing after 2m3s
refresh-contributors-wall / Refresh contributors wall cache bust (push) Failing after 11s
Initial import: open-design source for helix-mind.ai distribution
This repository contains the open-design daemon CLI source code, built
and packaged at https://helix-mind.ai/cli/open-design/latest.tgz for use
by the HelixMind /design slash command.

Licenses: Apache-2.0 (root) + MIT (skills/*)
2026-05-06 20:50:24 +02:00

90 lines
3.6 KiB
TypeScript

import { afterEach, describe, expect, it, vi } from 'vitest';
import { CHAT_TOOL_ENDPOINTS, CHAT_TOOL_OPERATIONS, ToolTokenRegistry } from '../src/tool-tokens.js';
afterEach(() => {
vi.useRealTimers();
});
describe('run-scoped tool tokens', () => {
it('mints isolated tokens for concurrent runs under the same project', () => {
const registry = new ToolTokenRegistry();
const first = registry.mint({ runId: 'run-1', projectId: 'project-a', nowMs: 1_000 });
const second = registry.mint({ runId: 'run-2', projectId: 'project-a', nowMs: 1_000 });
expect(first.token).not.toBe(second.token);
expect(first.runId).toBe('run-1');
expect(second.runId).toBe('run-2');
expect(first.projectId).toBe('project-a');
expect(second.projectId).toBe('project-a');
expect(registry.activeRunTokenCount('run-1')).toBe(1);
expect(registry.activeRunTokenCount('run-2')).toBe(1);
registry.revokeRun('run-1', 'child_exit');
expect(registry.validate(first.token, { nowMs: 1_001 }).ok).toBe(false);
expect(registry.validate(second.token, { nowMs: 1_001 }).ok).toBe(true);
expect(registry.activeRunTokenCount('run-1')).toBe(0);
expect(registry.activeRunTokenCount('run-2')).toBe(1);
registry.clear();
});
it('binds tokens to endpoint and operation allowlists', () => {
const registry = new ToolTokenRegistry();
const grant = registry.mint({
runId: 'run-allowlist',
projectId: 'project-a',
allowedEndpoints: ['/api/tools/live-artifacts/create'],
allowedOperations: ['live-artifacts:create'],
nowMs: 1_000,
});
expect(registry.validate(grant.token, {
endpoint: '/api/tools/live-artifacts/create',
operation: 'live-artifacts:create',
nowMs: 1_001,
})).toMatchObject({ ok: true });
expect(registry.validate(grant.token, {
endpoint: '/api/tools/live-artifacts/list',
operation: 'live-artifacts:create',
nowMs: 1_001,
})).toMatchObject({ ok: false, code: 'TOOL_ENDPOINT_DENIED' });
expect(registry.validate(grant.token, {
endpoint: '/api/tools/live-artifacts/create',
operation: 'live-artifacts:update',
nowMs: 1_001,
})).toMatchObject({ ok: false, code: 'TOOL_OPERATION_DENIED' });
registry.clear();
});
it('expires and revokes tokens by TTL', () => {
vi.useFakeTimers();
const registry = new ToolTokenRegistry();
const grant = registry.mint({ runId: 'run-ttl', projectId: 'project-a', ttlMs: 10, nowMs: 1_000 });
expect(registry.activeTokenCount()).toBe(1);
vi.advanceTimersByTime(10);
expect(registry.activeTokenCount()).toBe(0);
expect(registry.validate(grant.token)).toMatchObject({ ok: false, code: 'TOOL_TOKEN_INVALID' });
registry.clear();
});
it('reports expiry when validation observes an expired active token', () => {
const registry = new ToolTokenRegistry();
const grant = registry.mint({ runId: 'run-expired', projectId: 'project-a', ttlMs: 10, nowMs: 1_000 });
expect(registry.validate(grant.token, { nowMs: 1_010 })).toMatchObject({ ok: false, code: 'TOOL_TOKEN_EXPIRED' });
expect(registry.activeTokenCount()).toBe(0);
});
it('uses the chat tool endpoint and operation allowlists by default', () => {
const registry = new ToolTokenRegistry();
const grant = registry.mint({ runId: 'run-defaults', projectId: 'project-a', nowMs: 1_000 });
expect(grant.allowedEndpoints).toEqual([...CHAT_TOOL_ENDPOINTS]);
expect(grant.allowedOperations).toEqual([...CHAT_TOOL_OPERATIONS]);
registry.clear();
});
});