@kya-os/mcp-i 1.2.1 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/149.js +1 -1
- package/dist/261.js +1 -1
- package/dist/742.js +1 -1
- package/dist/904.js +1 -1
- package/dist/cli-adapter/index.d.ts +54 -0
- package/dist/cli-adapter/index.js +84 -0
- package/dist/cli-adapter/kta-registration.d.ts +39 -0
- package/dist/cli-adapter/kta-registration.js +92 -0
- package/dist/compiler/get-webpack-config/get-externals.js +2 -2
- package/dist/compiler/get-webpack-config/plugins.js +1 -13
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.LICENSE.txt +14 -0
- package/dist/runtime/session.js +4 -2
- package/dist/storage/encryption.d.ts +61 -0
- package/dist/storage/encryption.js +151 -0
- package/dist/storage/index.d.ts +11 -0
- package/dist/storage/index.js +26 -0
- package/package.json +2 -2
- package/dist/cache/__tests__/cloudflare-kv-nonce-cache.test.d.ts +0 -4
- package/dist/cache/__tests__/cloudflare-kv-nonce-cache.test.js +0 -176
- package/dist/cache/__tests__/concurrency.test.d.ts +0 -5
- package/dist/cache/__tests__/concurrency.test.js +0 -300
- package/dist/cache/__tests__/dynamodb-nonce-cache.test.d.ts +0 -4
- package/dist/cache/__tests__/dynamodb-nonce-cache.test.js +0 -176
- package/dist/cache/__tests__/memory-nonce-cache.test.d.ts +0 -4
- package/dist/cache/__tests__/memory-nonce-cache.test.js +0 -132
- package/dist/cache/__tests__/nonce-cache-factory-simple.test.d.ts +0 -4
- package/dist/cache/__tests__/nonce-cache-factory-simple.test.js +0 -133
- package/dist/cache/__tests__/nonce-cache-factory.test.d.ts +0 -4
- package/dist/cache/__tests__/nonce-cache-factory.test.js +0 -252
- package/dist/cache/__tests__/redis-nonce-cache.test.d.ts +0 -4
- package/dist/cache/__tests__/redis-nonce-cache.test.js +0 -95
- package/dist/runtime/__tests__/audit.test.d.ts +0 -4
- package/dist/runtime/__tests__/audit.test.js +0 -328
- package/dist/runtime/__tests__/identity.test.d.ts +0 -4
- package/dist/runtime/__tests__/identity.test.js +0 -164
- package/dist/runtime/__tests__/mcpi-runtime.test.d.ts +0 -4
- package/dist/runtime/__tests__/mcpi-runtime.test.js +0 -372
- package/dist/runtime/__tests__/proof.test.d.ts +0 -4
- package/dist/runtime/__tests__/proof.test.js +0 -302
- package/dist/runtime/__tests__/session.test.d.ts +0 -4
- package/dist/runtime/__tests__/session.test.js +0 -254
- package/dist/runtime/__tests__/well-known.test.d.ts +0 -4
- package/dist/runtime/__tests__/well-known.test.js +0 -312
- package/dist/test/__tests__/nonce-cache-integration.test.d.ts +0 -1
- package/dist/test/__tests__/nonce-cache-integration.test.js +0 -116
- package/dist/test/__tests__/nonce-cache.test.d.ts +0 -1
- package/dist/test/__tests__/nonce-cache.test.js +0 -122
- package/dist/test/__tests__/runtime-integration.test.d.ts +0 -4
- package/dist/test/__tests__/runtime-integration.test.js +0 -192
- package/dist/test/__tests__/test-infrastructure.test.d.ts +0 -4
- package/dist/test/__tests__/test-infrastructure.test.js +0 -178
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const vitest_1 = require("vitest");
|
|
4
|
-
const index_js_1 = require("../../cache/index.js");
|
|
5
|
-
/**
|
|
6
|
-
* Integration tests showing how nonce cache would be used in session management
|
|
7
|
-
*/
|
|
8
|
-
(0, vitest_1.describe)("Nonce Cache Integration", () => {
|
|
9
|
-
let cache;
|
|
10
|
-
(0, vitest_1.beforeEach)(async () => {
|
|
11
|
-
cache = await (0, index_js_1.createNonceCache)();
|
|
12
|
-
});
|
|
13
|
-
(0, vitest_1.describe)("Session Management Integration", () => {
|
|
14
|
-
class MockSessionManager {
|
|
15
|
-
nonceCache;
|
|
16
|
-
constructor(nonceCache) {
|
|
17
|
-
this.nonceCache = nonceCache;
|
|
18
|
-
}
|
|
19
|
-
async validateHandshake(nonce, sessionTtl) {
|
|
20
|
-
// Check for replay attack
|
|
21
|
-
if (await this.nonceCache.has(nonce)) {
|
|
22
|
-
throw new Error("XMCP_I_EHANDSHAKE: Nonce already used - potential replay attack");
|
|
23
|
-
}
|
|
24
|
-
// Add nonce with session TTL to prevent replay
|
|
25
|
-
await this.nonceCache.add(nonce, sessionTtl);
|
|
26
|
-
}
|
|
27
|
-
async isNonceUsed(nonce) {
|
|
28
|
-
return await this.nonceCache.has(nonce);
|
|
29
|
-
}
|
|
30
|
-
async cleanup() {
|
|
31
|
-
await this.nonceCache.cleanup();
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
(0, vitest_1.it)("should prevent replay attacks in session management", async () => {
|
|
35
|
-
const sessionManager = new MockSessionManager(cache);
|
|
36
|
-
const nonce = "test-nonce-123";
|
|
37
|
-
const sessionTtl = 1800; // 30 minutes
|
|
38
|
-
// First handshake should succeed
|
|
39
|
-
await (0, vitest_1.expect)(sessionManager.validateHandshake(nonce, sessionTtl)).resolves.not.toThrow();
|
|
40
|
-
// Verify nonce is now marked as used
|
|
41
|
-
(0, vitest_1.expect)(await sessionManager.isNonceUsed(nonce)).toBe(true);
|
|
42
|
-
// Second handshake with same nonce should fail (replay attack)
|
|
43
|
-
await (0, vitest_1.expect)(sessionManager.validateHandshake(nonce, sessionTtl)).rejects.toThrow("potential replay attack");
|
|
44
|
-
});
|
|
45
|
-
(0, vitest_1.it)("should handle sequential nonce validation attempts", async () => {
|
|
46
|
-
const sessionManager = new MockSessionManager(cache);
|
|
47
|
-
const nonce = "sequential-nonce";
|
|
48
|
-
const sessionTtl = 1800;
|
|
49
|
-
// First attempt should succeed
|
|
50
|
-
await (0, vitest_1.expect)(sessionManager.validateHandshake(nonce, sessionTtl)).resolves.not.toThrow();
|
|
51
|
-
// Subsequent attempts should fail (replay attack)
|
|
52
|
-
await (0, vitest_1.expect)(sessionManager.validateHandshake(nonce, sessionTtl)).rejects.toThrow("potential replay attack");
|
|
53
|
-
await (0, vitest_1.expect)(sessionManager.validateHandshake(nonce, sessionTtl)).rejects.toThrow("potential replay attack");
|
|
54
|
-
});
|
|
55
|
-
(0, vitest_1.it)("should allow different nonces in the same session window", async () => {
|
|
56
|
-
const sessionManager = new MockSessionManager(cache);
|
|
57
|
-
const sessionTtl = 1800;
|
|
58
|
-
// Different nonces should all be allowed
|
|
59
|
-
const nonces = ["nonce-1", "nonce-2", "nonce-3"];
|
|
60
|
-
for (const nonce of nonces) {
|
|
61
|
-
await (0, vitest_1.expect)(sessionManager.validateHandshake(nonce, sessionTtl)).resolves.not.toThrow();
|
|
62
|
-
}
|
|
63
|
-
// All nonces should be marked as used
|
|
64
|
-
for (const nonce of nonces) {
|
|
65
|
-
(0, vitest_1.expect)(await sessionManager.isNonceUsed(nonce)).toBe(true);
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
(0, vitest_1.it)("should handle nonce expiry correctly", async () => {
|
|
69
|
-
const sessionManager = new MockSessionManager(cache);
|
|
70
|
-
const nonce = "expiring-nonce";
|
|
71
|
-
const shortTtl = 0.1; // 0.1 seconds
|
|
72
|
-
// Add nonce with short TTL
|
|
73
|
-
await sessionManager.validateHandshake(nonce, shortTtl);
|
|
74
|
-
// Should be marked as used immediately
|
|
75
|
-
(0, vitest_1.expect)(await sessionManager.isNonceUsed(nonce)).toBe(true);
|
|
76
|
-
// Wait for expiry
|
|
77
|
-
await new Promise((resolve) => setTimeout(resolve, 150));
|
|
78
|
-
// Should no longer be marked as used after expiry
|
|
79
|
-
(0, vitest_1.expect)(await sessionManager.isNonceUsed(nonce)).toBe(false);
|
|
80
|
-
// Should be able to use the same nonce again after expiry
|
|
81
|
-
await (0, vitest_1.expect)(sessionManager.validateHandshake(nonce, shortTtl)).resolves.not.toThrow();
|
|
82
|
-
});
|
|
83
|
-
(0, vitest_1.it)("should handle cleanup operations safely", async () => {
|
|
84
|
-
const sessionManager = new MockSessionManager(cache);
|
|
85
|
-
// Add some nonces with different TTLs
|
|
86
|
-
await sessionManager.validateHandshake("long-lived", 3600);
|
|
87
|
-
await sessionManager.validateHandshake("short-lived", 0.1);
|
|
88
|
-
// Wait for short-lived to expire
|
|
89
|
-
await new Promise((resolve) => setTimeout(resolve, 150));
|
|
90
|
-
// Cleanup should not throw
|
|
91
|
-
await (0, vitest_1.expect)(sessionManager.cleanup()).resolves.not.toThrow();
|
|
92
|
-
// Long-lived should still exist, short-lived should be gone
|
|
93
|
-
(0, vitest_1.expect)(await sessionManager.isNonceUsed("long-lived")).toBe(true);
|
|
94
|
-
(0, vitest_1.expect)(await sessionManager.isNonceUsed("short-lived")).toBe(false);
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
(0, vitest_1.describe)("Error Handling Integration", () => {
|
|
98
|
-
(0, vitest_1.it)("should provide structured error messages for replay attacks", async () => {
|
|
99
|
-
const nonce = "error-test-nonce";
|
|
100
|
-
await cache.add(nonce, 60);
|
|
101
|
-
try {
|
|
102
|
-
await cache.add(nonce, 60);
|
|
103
|
-
vitest_1.expect.fail("Should have thrown an error");
|
|
104
|
-
}
|
|
105
|
-
catch (error) {
|
|
106
|
-
(0, vitest_1.expect)(error.message).toContain("Nonce error-test-nonce already exists");
|
|
107
|
-
(0, vitest_1.expect)(error.message).toContain("potential replay attack");
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
(0, vitest_1.it)("should handle cache backend failures gracefully", async () => {
|
|
111
|
-
// This test verifies that the factory falls back to memory cache
|
|
112
|
-
// when other backends fail (already tested in the factory tests)
|
|
113
|
-
(0, vitest_1.expect)(cache).toBeInstanceOf(index_js_1.MemoryNonceCache);
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const vitest_1 = require("vitest");
|
|
4
|
-
const memory_nonce_cache_js_1 = require("../../cache/memory-nonce-cache.js");
|
|
5
|
-
const nonce_cache_factory_js_1 = require("../../cache/nonce-cache-factory.js");
|
|
6
|
-
(0, vitest_1.describe)("NonceCache", () => {
|
|
7
|
-
(0, vitest_1.describe)("MemoryNonceCache", () => {
|
|
8
|
-
let cache;
|
|
9
|
-
(0, vitest_1.beforeEach)(() => {
|
|
10
|
-
cache = new memory_nonce_cache_js_1.MemoryNonceCache();
|
|
11
|
-
});
|
|
12
|
-
(0, vitest_1.it)("should not find non-existent nonce", async () => {
|
|
13
|
-
const exists = await cache.has("non-existent-nonce");
|
|
14
|
-
(0, vitest_1.expect)(exists).toBe(false);
|
|
15
|
-
});
|
|
16
|
-
(0, vitest_1.it)("should add and find nonce", async () => {
|
|
17
|
-
const nonce = "test-nonce-123";
|
|
18
|
-
await cache.add(nonce, 60); // 60 seconds TTL
|
|
19
|
-
const exists = await cache.has(nonce);
|
|
20
|
-
(0, vitest_1.expect)(exists).toBe(true);
|
|
21
|
-
});
|
|
22
|
-
(0, vitest_1.it)("should prevent replay attacks by rejecting duplicate nonces", async () => {
|
|
23
|
-
const nonce = "duplicate-nonce";
|
|
24
|
-
await cache.add(nonce, 60);
|
|
25
|
-
await (0, vitest_1.expect)(cache.add(nonce, 60)).rejects.toThrow("Nonce duplicate-nonce already exists - potential replay attack");
|
|
26
|
-
});
|
|
27
|
-
(0, vitest_1.it)("should expire nonces after TTL", async () => {
|
|
28
|
-
const nonce = "expiring-nonce";
|
|
29
|
-
await cache.add(nonce, 0.1); // 0.1 seconds TTL
|
|
30
|
-
// Should exist immediately
|
|
31
|
-
(0, vitest_1.expect)(await cache.has(nonce)).toBe(true);
|
|
32
|
-
// Wait for expiry
|
|
33
|
-
await new Promise((resolve) => setTimeout(resolve, 150));
|
|
34
|
-
// Should be expired
|
|
35
|
-
(0, vitest_1.expect)(await cache.has(nonce)).toBe(false);
|
|
36
|
-
});
|
|
37
|
-
(0, vitest_1.it)("should clean up expired entries", async () => {
|
|
38
|
-
const nonce1 = "nonce-1";
|
|
39
|
-
const nonce2 = "nonce-2";
|
|
40
|
-
await cache.add(nonce1, 0.1); // Short TTL
|
|
41
|
-
await cache.add(nonce2, 60); // Long TTL
|
|
42
|
-
// Wait for first nonce to expire
|
|
43
|
-
await new Promise((resolve) => setTimeout(resolve, 150));
|
|
44
|
-
await cache.cleanup();
|
|
45
|
-
(0, vitest_1.expect)(await cache.has(nonce1)).toBe(false);
|
|
46
|
-
(0, vitest_1.expect)(await cache.has(nonce2)).toBe(true);
|
|
47
|
-
});
|
|
48
|
-
(0, vitest_1.it)("should handle atomic add-if-absent semantics", async () => {
|
|
49
|
-
const nonce = "atomic-test";
|
|
50
|
-
// First add should succeed
|
|
51
|
-
await (0, vitest_1.expect)(cache.add(nonce, 60)).resolves.not.toThrow();
|
|
52
|
-
// Second add should fail
|
|
53
|
-
await (0, vitest_1.expect)(cache.add(nonce, 60)).rejects.toThrow("potential replay attack");
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
(0, vitest_1.describe)("Cache Type Detection", () => {
|
|
57
|
-
(0, vitest_1.beforeEach)(() => {
|
|
58
|
-
// Clear environment variables
|
|
59
|
-
delete process.env.mcpi_NONCE_CACHE_TYPE;
|
|
60
|
-
delete process.env.REDIS_URL;
|
|
61
|
-
delete process.env.mcpi_REDIS_URL;
|
|
62
|
-
delete process.env.AWS_REGION;
|
|
63
|
-
delete process.env.mcpi_DYNAMODB_TABLE;
|
|
64
|
-
});
|
|
65
|
-
(0, vitest_1.it)("should detect memory cache by default", () => {
|
|
66
|
-
const type = (0, nonce_cache_factory_js_1.detectCacheType)();
|
|
67
|
-
(0, vitest_1.expect)(type).toBe("memory");
|
|
68
|
-
});
|
|
69
|
-
(0, vitest_1.it)("should detect redis when REDIS_URL is set", () => {
|
|
70
|
-
process.env.REDIS_URL = "redis://localhost:6379";
|
|
71
|
-
const type = (0, nonce_cache_factory_js_1.detectCacheType)();
|
|
72
|
-
(0, vitest_1.expect)(type).toBe("redis");
|
|
73
|
-
});
|
|
74
|
-
(0, vitest_1.it)("should detect dynamodb when AWS_REGION is set", () => {
|
|
75
|
-
process.env.AWS_REGION = "us-east-1";
|
|
76
|
-
const type = (0, nonce_cache_factory_js_1.detectCacheType)();
|
|
77
|
-
(0, vitest_1.expect)(type).toBe("dynamodb");
|
|
78
|
-
});
|
|
79
|
-
(0, vitest_1.it)("should respect explicit cache type configuration", () => {
|
|
80
|
-
process.env.REDIS_URL = "redis://localhost:6379"; // This would normally trigger redis
|
|
81
|
-
process.env.mcpi_NONCE_CACHE_TYPE = "memory";
|
|
82
|
-
const type = (0, nonce_cache_factory_js_1.detectCacheType)();
|
|
83
|
-
(0, vitest_1.expect)(type).toBe("memory");
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
(0, vitest_1.describe)("Cache Factory", () => {
|
|
87
|
-
(0, vitest_1.it)("should create memory cache by default", async () => {
|
|
88
|
-
const cache = await (0, nonce_cache_factory_js_1.createNonceCache)();
|
|
89
|
-
(0, vitest_1.expect)(cache).toBeInstanceOf(memory_nonce_cache_js_1.MemoryNonceCache);
|
|
90
|
-
});
|
|
91
|
-
(0, vitest_1.it)("should create memory cache when redis connection fails", async () => {
|
|
92
|
-
// Mock console.warn to avoid noise in tests
|
|
93
|
-
const warnSpy = vitest_1.vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
94
|
-
const cache = await (0, nonce_cache_factory_js_1.createNonceCache)({
|
|
95
|
-
type: "redis",
|
|
96
|
-
redis: { url: "redis://invalid-host:6379", keyPrefix: "test:" },
|
|
97
|
-
});
|
|
98
|
-
(0, vitest_1.expect)(cache).toBeInstanceOf(memory_nonce_cache_js_1.MemoryNonceCache);
|
|
99
|
-
// Check that we got a warning about Redis failure (the exact message may vary)
|
|
100
|
-
(0, vitest_1.expect)(warnSpy).toHaveBeenCalledWith(vitest_1.expect.stringContaining("Failed to"), vitest_1.expect.anything());
|
|
101
|
-
warnSpy.mockRestore();
|
|
102
|
-
});
|
|
103
|
-
(0, vitest_1.it)("should handle missing configuration gracefully", async () => {
|
|
104
|
-
const warnSpy = vitest_1.vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
105
|
-
const cache = await (0, nonce_cache_factory_js_1.createNonceCache)({
|
|
106
|
-
type: "dynamodb",
|
|
107
|
-
// Missing tableName
|
|
108
|
-
});
|
|
109
|
-
(0, vitest_1.expect)(cache).toBeInstanceOf(memory_nonce_cache_js_1.MemoryNonceCache);
|
|
110
|
-
(0, vitest_1.expect)(warnSpy).toHaveBeenCalledWith(vitest_1.expect.stringContaining("DynamoDB table name not found"));
|
|
111
|
-
warnSpy.mockRestore();
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
(0, vitest_1.describe)("Multi-instance Warning", () => {
|
|
115
|
-
(0, vitest_1.it)("should warn about multi-instance limitations for memory cache", () => {
|
|
116
|
-
const warnSpy = vitest_1.vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
117
|
-
new memory_nonce_cache_js_1.MemoryNonceCache();
|
|
118
|
-
(0, vitest_1.expect)(warnSpy).toHaveBeenCalledWith(vitest_1.expect.stringContaining("not suitable for multi-instance deployments"));
|
|
119
|
-
warnSpy.mockRestore();
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
});
|
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Runtime integration tests
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const vitest_1 = require("vitest");
|
|
7
|
-
const test_environment_js_1 = require("../test-environment.js");
|
|
8
|
-
const mock_identity_provider_js_1 = require("../mock-identity-provider.js");
|
|
9
|
-
const runtime_integration_js_1 = require("../runtime-integration.js");
|
|
10
|
-
const test_1 = require("@kya-os/contracts/test");
|
|
11
|
-
(0, vitest_1.describe)("Runtime Integration", () => {
|
|
12
|
-
(0, vitest_1.beforeEach)(() => {
|
|
13
|
-
(0, test_environment_js_1.configureTestEnvironment)({ seed: "runtime-test" });
|
|
14
|
-
(0, mock_identity_provider_js_1.resetMockIdentityProvider)();
|
|
15
|
-
});
|
|
16
|
-
(0, vitest_1.describe)("Test Runtime Configuration", () => {
|
|
17
|
-
(0, vitest_1.it)("should provide test runtime config in test mode", () => {
|
|
18
|
-
const config = (0, runtime_integration_js_1.getTestRuntimeConfig)();
|
|
19
|
-
(0, vitest_1.expect)(config).toBeDefined();
|
|
20
|
-
(0, vitest_1.expect)(config?.skipKTACalls).toBe(true);
|
|
21
|
-
(0, vitest_1.expect)(config?.useMockIdentities).toBe(true);
|
|
22
|
-
(0, vitest_1.expect)(config?.deterministicKeys).toBe(true);
|
|
23
|
-
(0, vitest_1.expect)(config?.mockKTAResponses).toBe(true);
|
|
24
|
-
});
|
|
25
|
-
(0, vitest_1.it)("should return null config outside test mode", () => {
|
|
26
|
-
// Temporarily disable test mode
|
|
27
|
-
const originalEnv = process.env.XMCP_ENV;
|
|
28
|
-
process.env.XMCP_ENV = "production";
|
|
29
|
-
const config = (0, runtime_integration_js_1.getTestRuntimeConfig)();
|
|
30
|
-
(0, vitest_1.expect)(config).toBeNull();
|
|
31
|
-
// Restore test mode
|
|
32
|
-
process.env.XMCP_ENV = originalEnv;
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
(0, vitest_1.describe)("KTA Call Interception", () => {
|
|
36
|
-
(0, vitest_1.it)("should intercept register calls", async () => {
|
|
37
|
-
const result = await (0, runtime_integration_js_1.interceptKTACall)("register", async () => {
|
|
38
|
-
throw new Error("Should not call original");
|
|
39
|
-
});
|
|
40
|
-
(0, vitest_1.expect)(result).toMatchObject({
|
|
41
|
-
success: true,
|
|
42
|
-
agentURL: vitest_1.expect.stringContaining("test-kta.example.com"),
|
|
43
|
-
conformanceCapabilities: ["handshake", "signing", "verification"],
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
(0, vitest_1.it)("should intercept delegation checks", async () => {
|
|
47
|
-
const result = await (0, runtime_integration_js_1.interceptKTACall)("checkDelegation", async () => {
|
|
48
|
-
throw new Error("Should not call original");
|
|
49
|
-
});
|
|
50
|
-
(0, vitest_1.expect)(result).toMatchObject({
|
|
51
|
-
status: "active",
|
|
52
|
-
valid: true,
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
(0, vitest_1.it)("should intercept claim calls", async () => {
|
|
56
|
-
const result = await (0, runtime_integration_js_1.interceptKTACall)("claim", async () => {
|
|
57
|
-
throw new Error("Should not call original");
|
|
58
|
-
});
|
|
59
|
-
(0, vitest_1.expect)(result).toMatchObject({
|
|
60
|
-
success: true,
|
|
61
|
-
claimed: true,
|
|
62
|
-
agentURL: vitest_1.expect.stringContaining("test-kta.example.com"),
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
(0, vitest_1.it)("should use custom mock response when provided", async () => {
|
|
66
|
-
const customResponse = { custom: "response" };
|
|
67
|
-
const result = await (0, runtime_integration_js_1.interceptKTACall)("register", async () => {
|
|
68
|
-
throw new Error("Should not call original");
|
|
69
|
-
}, async () => customResponse);
|
|
70
|
-
(0, vitest_1.expect)(result).toEqual(customResponse);
|
|
71
|
-
});
|
|
72
|
-
(0, vitest_1.it)("should call original function when not in test mode", async () => {
|
|
73
|
-
// Temporarily disable test mode
|
|
74
|
-
const originalEnv = process.env.XMCP_ENV;
|
|
75
|
-
process.env.XMCP_ENV = "production";
|
|
76
|
-
let originalCalled = false;
|
|
77
|
-
await (0, runtime_integration_js_1.interceptKTACall)("register", async () => {
|
|
78
|
-
originalCalled = true;
|
|
79
|
-
return { called: true };
|
|
80
|
-
});
|
|
81
|
-
(0, vitest_1.expect)(originalCalled).toBe(true);
|
|
82
|
-
// Restore test mode
|
|
83
|
-
process.env.XMCP_ENV = originalEnv;
|
|
84
|
-
});
|
|
85
|
-
(0, vitest_1.it)("should throw error for unknown operations", async () => {
|
|
86
|
-
await (0, vitest_1.expect)((0, runtime_integration_js_1.interceptKTACall)("unknownOperation", async () => ({ success: true }))).rejects.toThrow(test_1.TEST_ERROR_CODES.INVALID_TEST_CONFIGURATION);
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
(0, vitest_1.describe)("Test Identity for Runtime", () => {
|
|
90
|
-
(0, vitest_1.it)("should get test identity for runtime", () => {
|
|
91
|
-
const identity = (0, runtime_integration_js_1.getTestIdentityForRuntime)("agent1");
|
|
92
|
-
(0, vitest_1.expect)(identity).toBeDefined();
|
|
93
|
-
(0, vitest_1.expect)(identity.did).toBeDefined();
|
|
94
|
-
(0, vitest_1.expect)(identity.keyId).toBeDefined();
|
|
95
|
-
(0, vitest_1.expect)(identity.privateKey).toBeDefined();
|
|
96
|
-
(0, vitest_1.expect)(identity.publicKey).toBeDefined();
|
|
97
|
-
});
|
|
98
|
-
(0, vitest_1.it)("should throw error for non-existent identity", () => {
|
|
99
|
-
(0, vitest_1.expect)(() => {
|
|
100
|
-
(0, runtime_integration_js_1.getTestIdentityForRuntime)("nonexistent");
|
|
101
|
-
}).toThrow(test_1.TEST_ERROR_CODES.INVALID_TEST_CONFIGURATION);
|
|
102
|
-
});
|
|
103
|
-
(0, vitest_1.it)("should throw error outside test mode", () => {
|
|
104
|
-
// Temporarily disable test mode
|
|
105
|
-
const originalEnv = process.env.XMCP_ENV;
|
|
106
|
-
process.env.XMCP_ENV = "production";
|
|
107
|
-
(0, vitest_1.expect)(() => {
|
|
108
|
-
(0, runtime_integration_js_1.getTestIdentityForRuntime)("agent1");
|
|
109
|
-
}).toThrow(test_1.TEST_ERROR_CODES.INVALID_TEST_CONFIGURATION);
|
|
110
|
-
// Restore test mode
|
|
111
|
-
process.env.XMCP_ENV = originalEnv;
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
(0, vitest_1.describe)("Test Session Context", () => {
|
|
115
|
-
(0, vitest_1.it)("should create test session context with defaults", () => {
|
|
116
|
-
const context = (0, runtime_integration_js_1.createTestSessionContext)();
|
|
117
|
-
(0, vitest_1.expect)(context).toMatchObject({
|
|
118
|
-
sessionId: "sess_test_default",
|
|
119
|
-
audience: "test.example.com",
|
|
120
|
-
nonce: "test_nonce_123",
|
|
121
|
-
timestamp: vitest_1.expect.any(Number),
|
|
122
|
-
createdAt: vitest_1.expect.any(Number),
|
|
123
|
-
lastActivity: vitest_1.expect.any(Number),
|
|
124
|
-
ttlMinutes: 30,
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
(0, vitest_1.it)("should create test session context with custom options", () => {
|
|
128
|
-
const options = {
|
|
129
|
-
sessionId: "custom_session",
|
|
130
|
-
audience: "custom.example.com",
|
|
131
|
-
nonce: "custom_nonce",
|
|
132
|
-
timestamp: 1234567890,
|
|
133
|
-
};
|
|
134
|
-
const context = (0, runtime_integration_js_1.createTestSessionContext)(options);
|
|
135
|
-
(0, vitest_1.expect)(context).toMatchObject({
|
|
136
|
-
sessionId: "custom_session",
|
|
137
|
-
audience: "custom.example.com",
|
|
138
|
-
nonce: "custom_nonce",
|
|
139
|
-
timestamp: 1234567890,
|
|
140
|
-
ttlMinutes: 30,
|
|
141
|
-
});
|
|
142
|
-
});
|
|
143
|
-
(0, vitest_1.it)("should throw error outside test mode", () => {
|
|
144
|
-
// Temporarily disable test mode
|
|
145
|
-
const originalEnv = process.env.XMCP_ENV;
|
|
146
|
-
process.env.XMCP_ENV = "production";
|
|
147
|
-
(0, vitest_1.expect)(() => {
|
|
148
|
-
(0, runtime_integration_js_1.createTestSessionContext)();
|
|
149
|
-
}).toThrow(test_1.TEST_ERROR_CODES.INVALID_TEST_CONFIGURATION);
|
|
150
|
-
// Restore test mode
|
|
151
|
-
process.env.XMCP_ENV = originalEnv;
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
(0, vitest_1.describe)("Test Environment Validation", () => {
|
|
155
|
-
(0, vitest_1.it)("should validate test environment successfully", () => {
|
|
156
|
-
const validation = (0, runtime_integration_js_1.validateTestEnvironment)();
|
|
157
|
-
(0, vitest_1.expect)(validation.valid).toBe(true);
|
|
158
|
-
(0, vitest_1.expect)(validation.errors).toHaveLength(0);
|
|
159
|
-
});
|
|
160
|
-
(0, vitest_1.it)("should detect invalid test environment", () => {
|
|
161
|
-
// Temporarily disable test mode
|
|
162
|
-
const originalEnv = process.env.XMCP_ENV;
|
|
163
|
-
process.env.XMCP_ENV = "production";
|
|
164
|
-
const validation = (0, runtime_integration_js_1.validateTestEnvironment)();
|
|
165
|
-
(0, vitest_1.expect)(validation.valid).toBe(false);
|
|
166
|
-
(0, vitest_1.expect)(validation.errors).toContain("XMCP_ENV is not set to 'test'");
|
|
167
|
-
// Restore test mode
|
|
168
|
-
process.env.XMCP_ENV = originalEnv;
|
|
169
|
-
});
|
|
170
|
-
});
|
|
171
|
-
(0, vitest_1.describe)("Test Mode Guard", () => {
|
|
172
|
-
(0, vitest_1.it)("should allow function execution in test mode", () => {
|
|
173
|
-
const testFunction = (0, runtime_integration_js_1.testModeOnly)(() => "test result");
|
|
174
|
-
(0, vitest_1.expect)(testFunction()).toBe("test result");
|
|
175
|
-
});
|
|
176
|
-
(0, vitest_1.it)("should prevent function execution outside test mode", () => {
|
|
177
|
-
// Temporarily disable test mode
|
|
178
|
-
const originalEnv = process.env.XMCP_ENV;
|
|
179
|
-
process.env.XMCP_ENV = "production";
|
|
180
|
-
const testFunction = (0, runtime_integration_js_1.testModeOnly)(() => "test result");
|
|
181
|
-
(0, vitest_1.expect)(() => {
|
|
182
|
-
testFunction();
|
|
183
|
-
}).toThrow(test_1.TEST_ERROR_CODES.INVALID_TEST_CONFIGURATION);
|
|
184
|
-
// Restore test mode
|
|
185
|
-
process.env.XMCP_ENV = originalEnv;
|
|
186
|
-
});
|
|
187
|
-
(0, vitest_1.it)("should preserve function arguments and return types", () => {
|
|
188
|
-
const testFunction = (0, runtime_integration_js_1.testModeOnly)((a, b) => `${a}-${b}`);
|
|
189
|
-
(0, vitest_1.expect)(testFunction(42, "test")).toBe("42-test");
|
|
190
|
-
});
|
|
191
|
-
});
|
|
192
|
-
});
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Test infrastructure validation tests
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const vitest_1 = require("vitest");
|
|
7
|
-
const test_environment_js_1 = require("../test-environment.js");
|
|
8
|
-
const deterministic_keys_js_1 = require("../deterministic-keys.js");
|
|
9
|
-
const mock_identity_provider_js_1 = require("../mock-identity-provider.js");
|
|
10
|
-
const local_verification_js_1 = require("../local-verification.js");
|
|
11
|
-
const test_1 = require("@kya-os/contracts/test");
|
|
12
|
-
(0, vitest_1.describe)("Test Infrastructure", () => {
|
|
13
|
-
(0, vitest_1.beforeEach)(() => {
|
|
14
|
-
// Configure test environment
|
|
15
|
-
(0, test_environment_js_1.configureTestEnvironment)({ seed: "test-seed" });
|
|
16
|
-
(0, mock_identity_provider_js_1.resetMockIdentityProvider)();
|
|
17
|
-
});
|
|
18
|
-
(0, vitest_1.describe)("Test Environment", () => {
|
|
19
|
-
(0, vitest_1.it)("should detect test mode", () => {
|
|
20
|
-
(0, vitest_1.expect)((0, test_environment_js_1.isTestMode)()).toBe(true);
|
|
21
|
-
});
|
|
22
|
-
(0, vitest_1.it)("should skip KTA calls in test mode", () => {
|
|
23
|
-
(0, vitest_1.expect)((0, test_environment_js_1.shouldSkipKTACalls)()).toBe(true);
|
|
24
|
-
});
|
|
25
|
-
(0, vitest_1.it)("should configure test environment", () => {
|
|
26
|
-
(0, test_environment_js_1.configureTestEnvironment)({
|
|
27
|
-
seed: "custom-seed",
|
|
28
|
-
skipKTACalls: true,
|
|
29
|
-
});
|
|
30
|
-
(0, vitest_1.expect)(process.env.XMCP_TEST_SEED).toBe("custom-seed");
|
|
31
|
-
(0, vitest_1.expect)(process.env.XMCP_SKIP_KTA_CALLS).toBe("true");
|
|
32
|
-
(0, vitest_1.expect)(process.env.XMCP_ENV).toBe("test");
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
(0, vitest_1.describe)("Deterministic Keys", () => {
|
|
36
|
-
(0, vitest_1.it)("should generate deterministic key pairs", () => {
|
|
37
|
-
const keys1 = (0, deterministic_keys_js_1.generateDeterministicKeyPair)("test-seed-1");
|
|
38
|
-
const keys2 = (0, deterministic_keys_js_1.generateDeterministicKeyPair)("test-seed-1");
|
|
39
|
-
const keys3 = (0, deterministic_keys_js_1.generateDeterministicKeyPair)("test-seed-2");
|
|
40
|
-
// Same seed should produce same keys
|
|
41
|
-
(0, vitest_1.expect)(keys1.privateKey).toBe(keys2.privateKey);
|
|
42
|
-
(0, vitest_1.expect)(keys1.publicKey).toBe(keys2.publicKey);
|
|
43
|
-
// Different seed should produce different keys
|
|
44
|
-
(0, vitest_1.expect)(keys1.privateKey).not.toBe(keys3.privateKey);
|
|
45
|
-
(0, vitest_1.expect)(keys1.publicKey).not.toBe(keys3.publicKey);
|
|
46
|
-
});
|
|
47
|
-
(0, vitest_1.it)("should generate test identities", () => {
|
|
48
|
-
const identity = (0, deterministic_keys_js_1.generateTestIdentity)("test-identity", {
|
|
49
|
-
did: test_1.TEST_DIDS.AGENT_1,
|
|
50
|
-
keyId: test_1.TEST_KEY_IDS.KEY_TEST_1,
|
|
51
|
-
});
|
|
52
|
-
(0, vitest_1.expect)(identity.did).toBe(test_1.TEST_DIDS.AGENT_1);
|
|
53
|
-
(0, vitest_1.expect)(identity.keyId).toBe(test_1.TEST_KEY_IDS.KEY_TEST_1);
|
|
54
|
-
(0, vitest_1.expect)(identity.privateKey).toBeDefined();
|
|
55
|
-
(0, vitest_1.expect)(identity.publicKey).toBeDefined();
|
|
56
|
-
(0, vitest_1.expect)(identity.createdAt).toBeDefined();
|
|
57
|
-
(0, vitest_1.expect)(identity.lastRotated).toBeDefined();
|
|
58
|
-
});
|
|
59
|
-
(0, vitest_1.it)("should provide predefined test identities", () => {
|
|
60
|
-
const identities = (0, deterministic_keys_js_1.getPredefinedTestIdentities)();
|
|
61
|
-
(0, vitest_1.expect)(identities.agent1).toBeDefined();
|
|
62
|
-
(0, vitest_1.expect)(identities.agent2).toBeDefined();
|
|
63
|
-
(0, vitest_1.expect)(identities.verifier1).toBeDefined();
|
|
64
|
-
(0, vitest_1.expect)(identities.agent1.did).toBe(test_1.TEST_DIDS.AGENT_1);
|
|
65
|
-
(0, vitest_1.expect)(identities.agent2.did).toBe(test_1.TEST_DIDS.AGENT_2);
|
|
66
|
-
(0, vitest_1.expect)(identities.verifier1.did).toBe(test_1.TEST_DIDS.VERIFIER_1);
|
|
67
|
-
});
|
|
68
|
-
(0, vitest_1.it)("should generate deterministic nonces", () => {
|
|
69
|
-
const nonce1 = (0, deterministic_keys_js_1.generateTestNonce)("seed1");
|
|
70
|
-
const nonce2 = (0, deterministic_keys_js_1.generateTestNonce)("seed1");
|
|
71
|
-
const nonce3 = (0, deterministic_keys_js_1.generateTestNonce)("seed2");
|
|
72
|
-
(0, vitest_1.expect)(nonce1).toBe(nonce2);
|
|
73
|
-
(0, vitest_1.expect)(nonce1).not.toBe(nonce3);
|
|
74
|
-
});
|
|
75
|
-
(0, vitest_1.it)("should generate deterministic session IDs", () => {
|
|
76
|
-
const sessionId1 = (0, deterministic_keys_js_1.generateTestSessionId)("seed1");
|
|
77
|
-
const sessionId2 = (0, deterministic_keys_js_1.generateTestSessionId)("seed1");
|
|
78
|
-
const sessionId3 = (0, deterministic_keys_js_1.generateTestSessionId)("seed2");
|
|
79
|
-
(0, vitest_1.expect)(sessionId1).toBe(sessionId2);
|
|
80
|
-
(0, vitest_1.expect)(sessionId1).not.toBe(sessionId3);
|
|
81
|
-
(0, vitest_1.expect)(sessionId1).toMatch(/^sess_test_/);
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
(0, vitest_1.describe)("Mock Identity Provider", () => {
|
|
85
|
-
(0, vitest_1.it)("should create mock identity provider", () => {
|
|
86
|
-
const provider = new mock_identity_provider_js_1.MockIdentityProvider();
|
|
87
|
-
const identities = provider.getAllIdentities();
|
|
88
|
-
(0, vitest_1.expect)(Object.keys(identities)).toContain("agent1");
|
|
89
|
-
(0, vitest_1.expect)(Object.keys(identities)).toContain("agent2");
|
|
90
|
-
(0, vitest_1.expect)(Object.keys(identities)).toContain("verifier1");
|
|
91
|
-
});
|
|
92
|
-
(0, vitest_1.it)("should manage identities", () => {
|
|
93
|
-
const provider = new mock_identity_provider_js_1.MockIdentityProvider();
|
|
94
|
-
const testIdentity = (0, deterministic_keys_js_1.generateTestIdentity)("custom-test");
|
|
95
|
-
provider.setIdentity("custom", testIdentity);
|
|
96
|
-
const retrieved = provider.getIdentity("custom");
|
|
97
|
-
(0, vitest_1.expect)(retrieved).toEqual(testIdentity);
|
|
98
|
-
});
|
|
99
|
-
(0, vitest_1.it)("should manage delegation status", () => {
|
|
100
|
-
const provider = new mock_identity_provider_js_1.MockIdentityProvider();
|
|
101
|
-
provider.setDelegation("did:test:agent-1:key-test-1", "active");
|
|
102
|
-
(0, vitest_1.expect)(provider.getDelegationStatus("did:test:agent-1", "key-test-1")).toBe("active");
|
|
103
|
-
provider.setDelegation("did:test:agent-1:key-test-1", "revoked");
|
|
104
|
-
(0, vitest_1.expect)(provider.getDelegationStatus("did:test:agent-1", "key-test-1")).toBe("revoked");
|
|
105
|
-
});
|
|
106
|
-
(0, vitest_1.it)("should simulate KTA failures", () => {
|
|
107
|
-
const provider = new mock_identity_provider_js_1.MockIdentityProvider();
|
|
108
|
-
provider.simulateKTAFailure("network");
|
|
109
|
-
(0, vitest_1.expect)(provider.shouldSimulateKTAFailure("network")).toBe(true);
|
|
110
|
-
(0, vitest_1.expect)(provider.shouldSimulateKTAFailure("auth")).toBe(false);
|
|
111
|
-
provider.clearKTAFailure("network");
|
|
112
|
-
(0, vitest_1.expect)(provider.shouldSimulateKTAFailure("network")).toBe(false);
|
|
113
|
-
});
|
|
114
|
-
(0, vitest_1.it)("should mock registration calls", async () => {
|
|
115
|
-
const provider = new mock_identity_provider_js_1.MockIdentityProvider();
|
|
116
|
-
// Success case
|
|
117
|
-
const result = await provider.mockRegister("did:test:agent-1", "key-test-1");
|
|
118
|
-
(0, vitest_1.expect)(result.success).toBe(true);
|
|
119
|
-
(0, vitest_1.expect)(result.agentURL).toContain("agent-1");
|
|
120
|
-
// Failure case
|
|
121
|
-
provider.simulateKTAFailure("auth");
|
|
122
|
-
const failResult = await provider.mockRegister("did:test:agent-1", "key-test-1");
|
|
123
|
-
(0, vitest_1.expect)(failResult.success).toBe(false);
|
|
124
|
-
(0, vitest_1.expect)(failResult.error).toBeDefined();
|
|
125
|
-
});
|
|
126
|
-
(0, vitest_1.it)("should use global provider", () => {
|
|
127
|
-
const provider1 = (0, mock_identity_provider_js_1.getMockIdentityProvider)();
|
|
128
|
-
const provider2 = (0, mock_identity_provider_js_1.getMockIdentityProvider)();
|
|
129
|
-
(0, vitest_1.expect)(provider1).toBe(provider2);
|
|
130
|
-
provider1.setIdentity("test", (0, deterministic_keys_js_1.generateTestIdentity)("test"));
|
|
131
|
-
(0, vitest_1.expect)(provider2.getIdentity("test")).toBeDefined();
|
|
132
|
-
});
|
|
133
|
-
});
|
|
134
|
-
(0, vitest_1.describe)("Local Verification", () => {
|
|
135
|
-
(0, vitest_1.it)("should verify mock proofs locally", async () => {
|
|
136
|
-
const mockProof = (0, local_verification_js_1.createMockProof)({
|
|
137
|
-
did: test_1.TEST_DIDS.AGENT_1,
|
|
138
|
-
keyId: test_1.TEST_KEY_IDS.KEY_TEST_1,
|
|
139
|
-
});
|
|
140
|
-
const result = await (0, local_verification_js_1.verifyProofLocally)(mockProof);
|
|
141
|
-
(0, vitest_1.expect)(result.valid).toBe(true);
|
|
142
|
-
(0, vitest_1.expect)(result.did).toBe(test_1.TEST_DIDS.AGENT_1);
|
|
143
|
-
(0, vitest_1.expect)(result.keyId).toBe(test_1.TEST_KEY_IDS.KEY_TEST_1);
|
|
144
|
-
(0, vitest_1.expect)(result.signature.valid).toBe(true);
|
|
145
|
-
(0, vitest_1.expect)(result.proof.valid).toBe(true);
|
|
146
|
-
(0, vitest_1.expect)(result.session.valid).toBe(true);
|
|
147
|
-
});
|
|
148
|
-
(0, vitest_1.it)("should detect invalid proofs", async () => {
|
|
149
|
-
const invalidProof = {
|
|
150
|
-
jws: "invalid-signature",
|
|
151
|
-
meta: {
|
|
152
|
-
did: "invalid-did",
|
|
153
|
-
kid: "invalid-key",
|
|
154
|
-
ts: Date.now() / 1000,
|
|
155
|
-
nonce: "test-nonce",
|
|
156
|
-
audience: "test.example.com",
|
|
157
|
-
sessionId: "sess_test",
|
|
158
|
-
requestHash: "sha256:invalid",
|
|
159
|
-
responseHash: "sha256:invalid",
|
|
160
|
-
},
|
|
161
|
-
};
|
|
162
|
-
const result = await (0, local_verification_js_1.verifyProofLocally)(invalidProof);
|
|
163
|
-
(0, vitest_1.expect)(result.valid).toBe(false);
|
|
164
|
-
(0, vitest_1.expect)(result.errors.length).toBeGreaterThan(0);
|
|
165
|
-
});
|
|
166
|
-
(0, vitest_1.it)("should verify DID documents locally", async () => {
|
|
167
|
-
const result = await (0, local_verification_js_1.verifyDIDDocumentLocally)(test_1.TEST_DIDS.AGENT_1);
|
|
168
|
-
(0, vitest_1.expect)(result.valid).toBe(true);
|
|
169
|
-
(0, vitest_1.expect)(result.document).toBeDefined();
|
|
170
|
-
(0, vitest_1.expect)(result.document.id).toBe(test_1.TEST_DIDS.AGENT_1);
|
|
171
|
-
});
|
|
172
|
-
(0, vitest_1.it)("should handle missing DID documents", async () => {
|
|
173
|
-
const result = await (0, local_verification_js_1.verifyDIDDocumentLocally)("did:test:nonexistent");
|
|
174
|
-
(0, vitest_1.expect)(result.valid).toBe(false);
|
|
175
|
-
(0, vitest_1.expect)(result.error).toContain("No identity found");
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
});
|