@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,133 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Simplified tests for Nonce Cache Factory
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const vitest_1 = require("vitest");
|
|
7
|
-
const nonce_cache_factory_js_1 = require("../nonce-cache-factory.js");
|
|
8
|
-
const memory_nonce_cache_js_1 = require("../memory-nonce-cache.js");
|
|
9
|
-
// Mock environment variables
|
|
10
|
-
const originalEnv = process.env;
|
|
11
|
-
(0, vitest_1.describe)("Nonce Cache Factory (Simplified)", () => {
|
|
12
|
-
(0, vitest_1.beforeEach)(() => {
|
|
13
|
-
vitest_1.vi.clearAllMocks();
|
|
14
|
-
// Reset environment
|
|
15
|
-
process.env = { ...originalEnv };
|
|
16
|
-
});
|
|
17
|
-
(0, vitest_1.afterEach)(() => {
|
|
18
|
-
process.env = originalEnv;
|
|
19
|
-
});
|
|
20
|
-
(0, vitest_1.describe)("detectCacheType", () => {
|
|
21
|
-
(0, vitest_1.it)("should detect explicit cache type from environment", () => {
|
|
22
|
-
process.env.mcpi_NONCE_CACHE_TYPE = "redis";
|
|
23
|
-
(0, vitest_1.expect)((0, nonce_cache_factory_js_1.detectCacheType)()).toBe("redis");
|
|
24
|
-
process.env.mcpi_NONCE_CACHE_TYPE = "dynamodb";
|
|
25
|
-
(0, vitest_1.expect)((0, nonce_cache_factory_js_1.detectCacheType)()).toBe("dynamodb");
|
|
26
|
-
process.env.mcpi_NONCE_CACHE_TYPE = "cloudflare-kv";
|
|
27
|
-
(0, vitest_1.expect)((0, nonce_cache_factory_js_1.detectCacheType)()).toBe("cloudflare-kv");
|
|
28
|
-
process.env.mcpi_NONCE_CACHE_TYPE = "memory";
|
|
29
|
-
(0, vitest_1.expect)((0, nonce_cache_factory_js_1.detectCacheType)()).toBe("memory");
|
|
30
|
-
});
|
|
31
|
-
(0, vitest_1.it)("should ignore invalid explicit cache types", () => {
|
|
32
|
-
process.env.mcpi_NONCE_CACHE_TYPE = "invalid-type";
|
|
33
|
-
(0, vitest_1.expect)((0, nonce_cache_factory_js_1.detectCacheType)()).toBe("memory");
|
|
34
|
-
});
|
|
35
|
-
(0, vitest_1.it)("should detect Redis from environment variables", () => {
|
|
36
|
-
process.env.REDIS_URL = "redis://localhost:6379";
|
|
37
|
-
(0, vitest_1.expect)((0, nonce_cache_factory_js_1.detectCacheType)()).toBe("redis");
|
|
38
|
-
delete process.env.REDIS_URL;
|
|
39
|
-
process.env.mcpi_REDIS_URL = "redis://localhost:6379";
|
|
40
|
-
(0, vitest_1.expect)((0, nonce_cache_factory_js_1.detectCacheType)()).toBe("redis");
|
|
41
|
-
});
|
|
42
|
-
(0, vitest_1.it)("should detect DynamoDB from environment variables", () => {
|
|
43
|
-
process.env.AWS_REGION = "us-east-1";
|
|
44
|
-
process.env.mcpi_DYNAMODB_TABLE = "nonce-cache";
|
|
45
|
-
(0, vitest_1.expect)((0, nonce_cache_factory_js_1.detectCacheType)()).toBe("dynamodb");
|
|
46
|
-
delete process.env.AWS_REGION;
|
|
47
|
-
process.env.AWS_DEFAULT_REGION = "us-west-2";
|
|
48
|
-
(0, vitest_1.expect)((0, nonce_cache_factory_js_1.detectCacheType)()).toBe("dynamodb");
|
|
49
|
-
});
|
|
50
|
-
(0, vitest_1.it)("should default to memory cache", () => {
|
|
51
|
-
(0, vitest_1.expect)((0, nonce_cache_factory_js_1.detectCacheType)()).toBe("memory");
|
|
52
|
-
});
|
|
53
|
-
(0, vitest_1.it)("should warn about memory cache in production", () => {
|
|
54
|
-
const consoleSpy = vitest_1.vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
55
|
-
process.env.NODE_ENV = "production";
|
|
56
|
-
(0, nonce_cache_factory_js_1.detectCacheType)();
|
|
57
|
-
(0, vitest_1.expect)(consoleSpy).toHaveBeenCalledWith(vitest_1.expect.stringContaining("Using memory cache in production"));
|
|
58
|
-
consoleSpy.mockRestore();
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
(0, vitest_1.describe)("createNonceCache", () => {
|
|
62
|
-
(0, vitest_1.it)("should create memory cache by default", async () => {
|
|
63
|
-
const cache = await (0, nonce_cache_factory_js_1.createNonceCache)();
|
|
64
|
-
(0, vitest_1.expect)(cache).toBeInstanceOf(memory_nonce_cache_js_1.MemoryNonceCache);
|
|
65
|
-
// Cleanup
|
|
66
|
-
if (cache instanceof memory_nonce_cache_js_1.MemoryNonceCache) {
|
|
67
|
-
cache.destroy();
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
(0, vitest_1.it)("should create memory cache when explicitly configured", async () => {
|
|
71
|
-
const cache = await (0, nonce_cache_factory_js_1.createNonceCache)({ type: "memory" });
|
|
72
|
-
(0, vitest_1.expect)(cache).toBeInstanceOf(memory_nonce_cache_js_1.MemoryNonceCache);
|
|
73
|
-
// Cleanup
|
|
74
|
-
if (cache instanceof memory_nonce_cache_js_1.MemoryNonceCache) {
|
|
75
|
-
cache.destroy();
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
(0, vitest_1.it)("should fall back to memory cache when Redis URL is missing", async () => {
|
|
79
|
-
const consoleSpy = vitest_1.vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
80
|
-
const cache = await (0, nonce_cache_factory_js_1.createNonceCache)({ type: "redis" });
|
|
81
|
-
(0, vitest_1.expect)(cache).toBeInstanceOf(memory_nonce_cache_js_1.MemoryNonceCache);
|
|
82
|
-
(0, vitest_1.expect)(consoleSpy).toHaveBeenCalledWith("Redis URL not found, falling back to memory cache");
|
|
83
|
-
consoleSpy.mockRestore();
|
|
84
|
-
if (cache instanceof memory_nonce_cache_js_1.MemoryNonceCache) {
|
|
85
|
-
cache.destroy();
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
(0, vitest_1.it)("should fall back to memory cache when DynamoDB table is missing", async () => {
|
|
89
|
-
const consoleSpy = vitest_1.vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
90
|
-
const cache = await (0, nonce_cache_factory_js_1.createNonceCache)({ type: "dynamodb" });
|
|
91
|
-
(0, vitest_1.expect)(cache).toBeInstanceOf(memory_nonce_cache_js_1.MemoryNonceCache);
|
|
92
|
-
(0, vitest_1.expect)(consoleSpy).toHaveBeenCalledWith("DynamoDB table name not found, falling back to memory cache");
|
|
93
|
-
consoleSpy.mockRestore();
|
|
94
|
-
if (cache instanceof memory_nonce_cache_js_1.MemoryNonceCache) {
|
|
95
|
-
cache.destroy();
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
(0, vitest_1.it)("should fall back to memory cache when KV namespace is missing", async () => {
|
|
99
|
-
const consoleSpy = vitest_1.vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
100
|
-
const cache = await (0, nonce_cache_factory_js_1.createNonceCache)({ type: "cloudflare-kv" });
|
|
101
|
-
(0, vitest_1.expect)(cache).toBeInstanceOf(memory_nonce_cache_js_1.MemoryNonceCache);
|
|
102
|
-
(0, vitest_1.expect)(consoleSpy).toHaveBeenCalledWith("Cloudflare KV namespace not found, falling back to memory cache");
|
|
103
|
-
consoleSpy.mockRestore();
|
|
104
|
-
if (cache instanceof memory_nonce_cache_js_1.MemoryNonceCache) {
|
|
105
|
-
cache.destroy();
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
});
|
|
109
|
-
(0, vitest_1.describe)("createNonceCacheWithConfig", () => {
|
|
110
|
-
(0, vitest_1.it)("should create cache with default options", async () => {
|
|
111
|
-
const cache = await (0, nonce_cache_factory_js_1.createNonceCacheWithConfig)();
|
|
112
|
-
(0, vitest_1.expect)(cache).toBeInstanceOf(memory_nonce_cache_js_1.MemoryNonceCache);
|
|
113
|
-
if (cache instanceof memory_nonce_cache_js_1.MemoryNonceCache) {
|
|
114
|
-
cache.destroy();
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
(0, vitest_1.it)("should fall back to memory cache on errors by default", async () => {
|
|
118
|
-
const consoleSpy = vitest_1.vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
119
|
-
const cache = await (0, nonce_cache_factory_js_1.createNonceCacheWithConfig)({
|
|
120
|
-
config: {
|
|
121
|
-
type: "redis",
|
|
122
|
-
// No URL provided, should cause fallback
|
|
123
|
-
},
|
|
124
|
-
});
|
|
125
|
-
(0, vitest_1.expect)(cache).toBeInstanceOf(memory_nonce_cache_js_1.MemoryNonceCache);
|
|
126
|
-
(0, vitest_1.expect)(consoleSpy).toHaveBeenCalled();
|
|
127
|
-
consoleSpy.mockRestore();
|
|
128
|
-
if (cache instanceof memory_nonce_cache_js_1.MemoryNonceCache) {
|
|
129
|
-
cache.destroy();
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
});
|
|
133
|
-
});
|
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Tests for Nonce Cache Factory
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const vitest_1 = require("vitest");
|
|
7
|
-
const nonce_cache_factory_js_1 = require("../nonce-cache-factory.js");
|
|
8
|
-
const memory_nonce_cache_js_1 = require("../memory-nonce-cache.js");
|
|
9
|
-
// Mock environment variables
|
|
10
|
-
const originalEnv = process.env;
|
|
11
|
-
(0, vitest_1.describe)("Nonce Cache Factory", () => {
|
|
12
|
-
(0, vitest_1.beforeEach)(() => {
|
|
13
|
-
vitest_1.vi.clearAllMocks();
|
|
14
|
-
// Reset environment
|
|
15
|
-
process.env = { ...originalEnv };
|
|
16
|
-
});
|
|
17
|
-
(0, vitest_1.afterEach)(() => {
|
|
18
|
-
process.env = originalEnv;
|
|
19
|
-
});
|
|
20
|
-
(0, vitest_1.describe)("detectCacheType", () => {
|
|
21
|
-
(0, vitest_1.it)("should detect explicit cache type from environment", () => {
|
|
22
|
-
process.env.mcpi_NONCE_CACHE_TYPE = "redis";
|
|
23
|
-
(0, vitest_1.expect)((0, nonce_cache_factory_js_1.detectCacheType)()).toBe("redis");
|
|
24
|
-
process.env.mcpi_NONCE_CACHE_TYPE = "dynamodb";
|
|
25
|
-
(0, vitest_1.expect)((0, nonce_cache_factory_js_1.detectCacheType)()).toBe("dynamodb");
|
|
26
|
-
process.env.mcpi_NONCE_CACHE_TYPE = "cloudflare-kv";
|
|
27
|
-
(0, vitest_1.expect)((0, nonce_cache_factory_js_1.detectCacheType)()).toBe("cloudflare-kv");
|
|
28
|
-
process.env.mcpi_NONCE_CACHE_TYPE = "memory";
|
|
29
|
-
(0, vitest_1.expect)((0, nonce_cache_factory_js_1.detectCacheType)()).toBe("memory");
|
|
30
|
-
});
|
|
31
|
-
(0, vitest_1.it)("should ignore invalid explicit cache types", () => {
|
|
32
|
-
process.env.mcpi_NONCE_CACHE_TYPE = "invalid-type";
|
|
33
|
-
(0, vitest_1.expect)((0, nonce_cache_factory_js_1.detectCacheType)()).toBe("memory");
|
|
34
|
-
});
|
|
35
|
-
(0, vitest_1.it)("should detect Redis from environment variables", () => {
|
|
36
|
-
process.env.REDIS_URL = "redis://localhost:6379";
|
|
37
|
-
(0, vitest_1.expect)((0, nonce_cache_factory_js_1.detectCacheType)()).toBe("redis");
|
|
38
|
-
delete process.env.REDIS_URL;
|
|
39
|
-
process.env.mcpi_REDIS_URL = "redis://localhost:6379";
|
|
40
|
-
(0, vitest_1.expect)((0, nonce_cache_factory_js_1.detectCacheType)()).toBe("redis");
|
|
41
|
-
});
|
|
42
|
-
(0, vitest_1.it)("should detect DynamoDB from environment variables", () => {
|
|
43
|
-
process.env.AWS_REGION = "us-east-1";
|
|
44
|
-
process.env.mcpi_DYNAMODB_TABLE = "nonce-cache";
|
|
45
|
-
(0, vitest_1.expect)((0, nonce_cache_factory_js_1.detectCacheType)()).toBe("dynamodb");
|
|
46
|
-
delete process.env.AWS_REGION;
|
|
47
|
-
process.env.AWS_DEFAULT_REGION = "us-west-2";
|
|
48
|
-
(0, vitest_1.expect)((0, nonce_cache_factory_js_1.detectCacheType)()).toBe("dynamodb");
|
|
49
|
-
});
|
|
50
|
-
(0, vitest_1.it)("should detect Cloudflare Workers environment", () => {
|
|
51
|
-
// Mock Cloudflare Workers globals
|
|
52
|
-
const originalGlobalThis = globalThis;
|
|
53
|
-
Object.defineProperty(globalThis, "caches", {
|
|
54
|
-
value: {},
|
|
55
|
-
configurable: true,
|
|
56
|
-
});
|
|
57
|
-
Object.defineProperty(globalThis, "fetch", {
|
|
58
|
-
value: () => { },
|
|
59
|
-
configurable: true,
|
|
60
|
-
});
|
|
61
|
-
Object.defineProperty(globalThis, "addEventListener", {
|
|
62
|
-
value: () => { },
|
|
63
|
-
configurable: true,
|
|
64
|
-
});
|
|
65
|
-
(0, vitest_1.expect)((0, nonce_cache_factory_js_1.detectCacheType)()).toBe("cloudflare-kv");
|
|
66
|
-
// Cleanup
|
|
67
|
-
delete globalThis.caches;
|
|
68
|
-
delete globalThis.addEventListener;
|
|
69
|
-
});
|
|
70
|
-
(0, vitest_1.it)("should default to memory cache", () => {
|
|
71
|
-
(0, vitest_1.expect)((0, nonce_cache_factory_js_1.detectCacheType)()).toBe("memory");
|
|
72
|
-
});
|
|
73
|
-
(0, vitest_1.it)("should warn about memory cache in production", () => {
|
|
74
|
-
const consoleSpy = vitest_1.vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
75
|
-
process.env.NODE_ENV = "production";
|
|
76
|
-
(0, nonce_cache_factory_js_1.detectCacheType)();
|
|
77
|
-
(0, vitest_1.expect)(consoleSpy).toHaveBeenCalledWith(vitest_1.expect.stringContaining("Using memory cache in production"));
|
|
78
|
-
consoleSpy.mockRestore();
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
(0, vitest_1.describe)("createNonceCache", () => {
|
|
82
|
-
(0, vitest_1.it)("should create memory cache by default", async () => {
|
|
83
|
-
const cache = await (0, nonce_cache_factory_js_1.createNonceCache)();
|
|
84
|
-
(0, vitest_1.expect)(cache).toBeInstanceOf(memory_nonce_cache_js_1.MemoryNonceCache);
|
|
85
|
-
// Cleanup
|
|
86
|
-
if (cache instanceof memory_nonce_cache_js_1.MemoryNonceCache) {
|
|
87
|
-
cache.destroy();
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
(0, vitest_1.it)("should create memory cache when explicitly configured", async () => {
|
|
91
|
-
const cache = await (0, nonce_cache_factory_js_1.createNonceCache)({ type: "memory" });
|
|
92
|
-
(0, vitest_1.expect)(cache).toBeInstanceOf(memory_nonce_cache_js_1.MemoryNonceCache);
|
|
93
|
-
// Cleanup
|
|
94
|
-
if (cache instanceof memory_nonce_cache_js_1.MemoryNonceCache) {
|
|
95
|
-
cache.destroy();
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
(0, vitest_1.it)("should fall back to memory cache when Redis URL is missing", async () => {
|
|
99
|
-
const consoleSpy = vitest_1.vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
100
|
-
const cache = await (0, nonce_cache_factory_js_1.createNonceCache)({ type: "redis" });
|
|
101
|
-
(0, vitest_1.expect)(cache).toBeInstanceOf(memory_nonce_cache_js_1.MemoryNonceCache);
|
|
102
|
-
(0, vitest_1.expect)(consoleSpy).toHaveBeenCalledWith("Redis URL not found, falling back to memory cache");
|
|
103
|
-
consoleSpy.mockRestore();
|
|
104
|
-
if (cache instanceof memory_nonce_cache_js_1.MemoryNonceCache) {
|
|
105
|
-
cache.destroy();
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
(0, vitest_1.it)("should fall back to memory cache when DynamoDB table is missing", async () => {
|
|
109
|
-
const consoleSpy = vitest_1.vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
110
|
-
const cache = await (0, nonce_cache_factory_js_1.createNonceCache)({ type: "dynamodb" });
|
|
111
|
-
(0, vitest_1.expect)(cache).toBeInstanceOf(memory_nonce_cache_js_1.MemoryNonceCache);
|
|
112
|
-
(0, vitest_1.expect)(consoleSpy).toHaveBeenCalledWith("DynamoDB table name not found, falling back to memory cache");
|
|
113
|
-
consoleSpy.mockRestore();
|
|
114
|
-
if (cache instanceof memory_nonce_cache_js_1.MemoryNonceCache) {
|
|
115
|
-
cache.destroy();
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
(0, vitest_1.it)("should fall back to memory cache when KV namespace is missing", async () => {
|
|
119
|
-
const consoleSpy = vitest_1.vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
120
|
-
const cache = await (0, nonce_cache_factory_js_1.createNonceCache)({ type: "cloudflare-kv" });
|
|
121
|
-
(0, vitest_1.expect)(cache).toBeInstanceOf(memory_nonce_cache_js_1.MemoryNonceCache);
|
|
122
|
-
(0, vitest_1.expect)(consoleSpy).toHaveBeenCalledWith("Cloudflare KV namespace not found, falling back to memory cache");
|
|
123
|
-
consoleSpy.mockRestore();
|
|
124
|
-
if (cache instanceof memory_nonce_cache_js_1.MemoryNonceCache) {
|
|
125
|
-
cache.destroy();
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
(0, vitest_1.it)("should handle Redis connection failures gracefully", async () => {
|
|
129
|
-
const consoleSpy = vitest_1.vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
130
|
-
// Mock Redis import to throw error
|
|
131
|
-
vitest_1.vi.doMock("redis", () => {
|
|
132
|
-
throw new Error("Redis not available");
|
|
133
|
-
});
|
|
134
|
-
const cache = await (0, nonce_cache_factory_js_1.createNonceCache)({
|
|
135
|
-
type: "redis",
|
|
136
|
-
redis: { url: "redis://localhost:6379", keyPrefix: "test:" },
|
|
137
|
-
});
|
|
138
|
-
(0, vitest_1.expect)(cache).toBeInstanceOf(memory_nonce_cache_js_1.MemoryNonceCache);
|
|
139
|
-
(0, vitest_1.expect)(consoleSpy).toHaveBeenCalledWith(vitest_1.expect.stringContaining("Failed to connect to Redis"), vitest_1.expect.any(Error));
|
|
140
|
-
consoleSpy.mockRestore();
|
|
141
|
-
if (cache instanceof memory_nonce_cache_js_1.MemoryNonceCache) {
|
|
142
|
-
cache.destroy();
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
(0, vitest_1.it)("should handle DynamoDB initialization failures gracefully", async () => {
|
|
146
|
-
const consoleSpy = vitest_1.vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
147
|
-
// Mock AWS SDK import to throw error
|
|
148
|
-
vitest_1.vi.doMock("@aws-sdk/client-dynamodb", () => {
|
|
149
|
-
throw new Error("AWS SDK not available");
|
|
150
|
-
});
|
|
151
|
-
const cache = await (0, nonce_cache_factory_js_1.createNonceCache)({
|
|
152
|
-
type: "dynamodb",
|
|
153
|
-
dynamodb: {
|
|
154
|
-
tableName: "test-table",
|
|
155
|
-
keyAttribute: "nonce",
|
|
156
|
-
ttlAttribute: "ttl",
|
|
157
|
-
},
|
|
158
|
-
});
|
|
159
|
-
(0, vitest_1.expect)(cache).toBeInstanceOf(memory_nonce_cache_js_1.MemoryNonceCache);
|
|
160
|
-
(0, vitest_1.expect)(consoleSpy).toHaveBeenCalledWith(vitest_1.expect.stringContaining("Failed to initialize DynamoDB"), vitest_1.expect.any(Error));
|
|
161
|
-
consoleSpy.mockRestore();
|
|
162
|
-
if (cache instanceof memory_nonce_cache_js_1.MemoryNonceCache) {
|
|
163
|
-
cache.destroy();
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
(0, vitest_1.it)("should handle Cloudflare KV namespace not found", async () => {
|
|
167
|
-
const consoleSpy = vitest_1.vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
168
|
-
const cache = await (0, nonce_cache_factory_js_1.createNonceCache)({
|
|
169
|
-
type: "cloudflare-kv",
|
|
170
|
-
cloudflareKv: {
|
|
171
|
-
namespace: "NONEXISTENT_KV",
|
|
172
|
-
keyPrefix: "test:",
|
|
173
|
-
},
|
|
174
|
-
});
|
|
175
|
-
(0, vitest_1.expect)(cache).toBeInstanceOf(memory_nonce_cache_js_1.MemoryNonceCache);
|
|
176
|
-
(0, vitest_1.expect)(consoleSpy).toHaveBeenCalledWith(vitest_1.expect.stringContaining("Failed to initialize Cloudflare KV"), vitest_1.expect.any(Error));
|
|
177
|
-
consoleSpy.mockRestore();
|
|
178
|
-
if (cache instanceof memory_nonce_cache_js_1.MemoryNonceCache) {
|
|
179
|
-
cache.destroy();
|
|
180
|
-
}
|
|
181
|
-
});
|
|
182
|
-
});
|
|
183
|
-
(0, vitest_1.describe)("createNonceCacheWithConfig", () => {
|
|
184
|
-
(0, vitest_1.it)("should create cache with default options", async () => {
|
|
185
|
-
const cache = await (0, nonce_cache_factory_js_1.createNonceCacheWithConfig)();
|
|
186
|
-
(0, vitest_1.expect)(cache).toBeInstanceOf(memory_nonce_cache_js_1.MemoryNonceCache);
|
|
187
|
-
if (cache instanceof memory_nonce_cache_js_1.MemoryNonceCache) {
|
|
188
|
-
cache.destroy();
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
|
-
(0, vitest_1.it)("should fall back to memory cache on errors by default", async () => {
|
|
192
|
-
const consoleSpy = vitest_1.vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
193
|
-
// Mock to throw error
|
|
194
|
-
vitest_1.vi.doMock("redis", () => {
|
|
195
|
-
throw new Error("Connection failed");
|
|
196
|
-
});
|
|
197
|
-
const cache = await (0, nonce_cache_factory_js_1.createNonceCacheWithConfig)({
|
|
198
|
-
config: {
|
|
199
|
-
type: "redis",
|
|
200
|
-
redis: { url: "redis://localhost:6379", keyPrefix: "test:" },
|
|
201
|
-
},
|
|
202
|
-
});
|
|
203
|
-
(0, vitest_1.expect)(cache).toBeInstanceOf(memory_nonce_cache_js_1.MemoryNonceCache);
|
|
204
|
-
(0, vitest_1.expect)(consoleSpy).toHaveBeenCalled();
|
|
205
|
-
consoleSpy.mockRestore();
|
|
206
|
-
if (cache instanceof memory_nonce_cache_js_1.MemoryNonceCache) {
|
|
207
|
-
cache.destroy();
|
|
208
|
-
}
|
|
209
|
-
});
|
|
210
|
-
(0, vitest_1.it)("should throw error when fallbackToMemory is false", async () => {
|
|
211
|
-
// Mock to throw error
|
|
212
|
-
vitest_1.vi.doMock("redis", () => {
|
|
213
|
-
throw new Error("Connection failed");
|
|
214
|
-
});
|
|
215
|
-
await (0, vitest_1.expect)((0, nonce_cache_factory_js_1.createNonceCacheWithConfig)({
|
|
216
|
-
config: {
|
|
217
|
-
type: "redis",
|
|
218
|
-
redis: { url: "redis://localhost:6379", keyPrefix: "test:" },
|
|
219
|
-
},
|
|
220
|
-
fallbackToMemory: false,
|
|
221
|
-
})).rejects.toThrow();
|
|
222
|
-
});
|
|
223
|
-
});
|
|
224
|
-
(0, vitest_1.describe)("Environment Variable Priority", () => {
|
|
225
|
-
(0, vitest_1.it)("should prioritize config over environment variables", async () => {
|
|
226
|
-
process.env.REDIS_URL = "redis://env-redis:6379";
|
|
227
|
-
const consoleSpy = vitest_1.vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
228
|
-
const cache = await (0, nonce_cache_factory_js_1.createNonceCache)({
|
|
229
|
-
type: "redis",
|
|
230
|
-
redis: { url: "redis://config-redis:6379", keyPrefix: "test:" },
|
|
231
|
-
});
|
|
232
|
-
(0, vitest_1.expect)(cache).toBeInstanceOf(memory_nonce_cache_js_1.MemoryNonceCache);
|
|
233
|
-
// Should have tried to use config URL, not env URL
|
|
234
|
-
(0, vitest_1.expect)(consoleSpy).toHaveBeenCalledWith(vitest_1.expect.stringContaining("Failed to connect to Redis"), vitest_1.expect.any(Error));
|
|
235
|
-
consoleSpy.mockRestore();
|
|
236
|
-
if (cache instanceof memory_nonce_cache_js_1.MemoryNonceCache) {
|
|
237
|
-
cache.destroy();
|
|
238
|
-
}
|
|
239
|
-
});
|
|
240
|
-
(0, vitest_1.it)("should use environment variables when config is not provided", async () => {
|
|
241
|
-
process.env.mcpi_REDIS_URL = "redis://env-redis:6379";
|
|
242
|
-
const consoleSpy = vitest_1.vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
243
|
-
const cache = await (0, nonce_cache_factory_js_1.createNonceCache)({ type: "redis" });
|
|
244
|
-
(0, vitest_1.expect)(cache).toBeInstanceOf(memory_nonce_cache_js_1.MemoryNonceCache);
|
|
245
|
-
(0, vitest_1.expect)(consoleSpy).toHaveBeenCalledWith(vitest_1.expect.stringContaining("Failed to connect to Redis"), vitest_1.expect.any(Error));
|
|
246
|
-
consoleSpy.mockRestore();
|
|
247
|
-
if (cache instanceof memory_nonce_cache_js_1.MemoryNonceCache) {
|
|
248
|
-
cache.destroy();
|
|
249
|
-
}
|
|
250
|
-
});
|
|
251
|
-
});
|
|
252
|
-
});
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Tests for Redis Nonce Cache
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const vitest_1 = require("vitest");
|
|
7
|
-
const redis_nonce_cache_js_1 = require("../redis-nonce-cache.js");
|
|
8
|
-
// Mock Redis client
|
|
9
|
-
const mockRedis = {
|
|
10
|
-
exists: vitest_1.vi.fn(),
|
|
11
|
-
set: vitest_1.vi.fn(),
|
|
12
|
-
};
|
|
13
|
-
(0, vitest_1.describe)("RedisNonceCache", () => {
|
|
14
|
-
let cache;
|
|
15
|
-
(0, vitest_1.beforeEach)(() => {
|
|
16
|
-
vitest_1.vi.clearAllMocks();
|
|
17
|
-
cache = new redis_nonce_cache_js_1.RedisNonceCache(mockRedis, "test:nonce:");
|
|
18
|
-
});
|
|
19
|
-
(0, vitest_1.describe)("Basic Operations", () => {
|
|
20
|
-
(0, vitest_1.it)("should add and check nonce existence", async () => {
|
|
21
|
-
const nonce = "test-nonce-123";
|
|
22
|
-
// Mock Redis responses
|
|
23
|
-
mockRedis.exists.mockResolvedValue(0); // doesn't exist
|
|
24
|
-
mockRedis.set.mockResolvedValue("OK"); // successful set
|
|
25
|
-
// Initially should not exist
|
|
26
|
-
(0, vitest_1.expect)(await cache.has(nonce)).toBe(false);
|
|
27
|
-
(0, vitest_1.expect)(mockRedis.exists).toHaveBeenCalledWith("test:nonce:test-nonce-123");
|
|
28
|
-
// Add nonce
|
|
29
|
-
await cache.add(nonce, 60);
|
|
30
|
-
(0, vitest_1.expect)(mockRedis.set).toHaveBeenCalledWith("test:nonce:test-nonce-123", "1", "EX", 60, "NX");
|
|
31
|
-
// Mock that it now exists
|
|
32
|
-
mockRedis.exists.mockResolvedValue(1);
|
|
33
|
-
(0, vitest_1.expect)(await cache.has(nonce)).toBe(true);
|
|
34
|
-
});
|
|
35
|
-
(0, vitest_1.it)("should prevent duplicate nonce addition", async () => {
|
|
36
|
-
const nonce = "duplicate-nonce";
|
|
37
|
-
// Mock Redis SET NX returning null (key already exists)
|
|
38
|
-
mockRedis.set.mockResolvedValue(null);
|
|
39
|
-
// Adding duplicate nonce should throw
|
|
40
|
-
await (0, vitest_1.expect)(cache.add(nonce, 60)).rejects.toThrow("Nonce duplicate-nonce already exists - potential replay attack");
|
|
41
|
-
});
|
|
42
|
-
(0, vitest_1.it)("should handle Redis connection errors gracefully", async () => {
|
|
43
|
-
const nonce = "error-nonce";
|
|
44
|
-
// Mock Redis throwing connection error
|
|
45
|
-
mockRedis.exists.mockRejectedValue(new Error("Connection failed"));
|
|
46
|
-
mockRedis.set.mockRejectedValue(new Error("Connection failed"));
|
|
47
|
-
// Should propagate errors with context
|
|
48
|
-
await (0, vitest_1.expect)(cache.has(nonce)).rejects.toThrow("Failed to check nonce existence");
|
|
49
|
-
await (0, vitest_1.expect)(cache.add(nonce, 60)).rejects.toThrow("Failed to add nonce to cache");
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
(0, vitest_1.describe)("Atomic Operations", () => {
|
|
53
|
-
(0, vitest_1.it)("should use atomic SET NX EX command", async () => {
|
|
54
|
-
const nonce = "atomic-test-nonce";
|
|
55
|
-
const ttl = 300;
|
|
56
|
-
mockRedis.set.mockResolvedValue("OK");
|
|
57
|
-
await cache.add(nonce, ttl);
|
|
58
|
-
// Verify atomic command was used
|
|
59
|
-
(0, vitest_1.expect)(mockRedis.set).toHaveBeenCalledWith("test:nonce:atomic-test-nonce", "1", "EX", ttl, "NX");
|
|
60
|
-
});
|
|
61
|
-
(0, vitest_1.it)("should handle concurrent add attempts", async () => {
|
|
62
|
-
const nonce = "concurrent-nonce";
|
|
63
|
-
// First call succeeds
|
|
64
|
-
mockRedis.set.mockResolvedValueOnce("OK");
|
|
65
|
-
// Second call fails (key exists)
|
|
66
|
-
mockRedis.set.mockResolvedValueOnce(null);
|
|
67
|
-
// First add should succeed
|
|
68
|
-
await (0, vitest_1.expect)(cache.add(nonce, 60)).resolves.not.toThrow();
|
|
69
|
-
// Second add should fail
|
|
70
|
-
await (0, vitest_1.expect)(cache.add(nonce, 60)).rejects.toThrow("potential replay attack");
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
(0, vitest_1.describe)("Cleanup", () => {
|
|
74
|
-
(0, vitest_1.it)("should be a no-op since Redis handles expiry", async () => {
|
|
75
|
-
// cleanup() should not call any Redis methods
|
|
76
|
-
await cache.cleanup();
|
|
77
|
-
(0, vitest_1.expect)(mockRedis.exists).not.toHaveBeenCalled();
|
|
78
|
-
(0, vitest_1.expect)(mockRedis.set).not.toHaveBeenCalled();
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
(0, vitest_1.describe)("Key Prefix", () => {
|
|
82
|
-
(0, vitest_1.it)("should use custom key prefix", () => {
|
|
83
|
-
const customCache = new redis_nonce_cache_js_1.RedisNonceCache(mockRedis, "custom:prefix:");
|
|
84
|
-
mockRedis.exists.mockResolvedValue(0);
|
|
85
|
-
customCache.has("test-nonce");
|
|
86
|
-
(0, vitest_1.expect)(mockRedis.exists).toHaveBeenCalledWith("custom:prefix:test-nonce");
|
|
87
|
-
});
|
|
88
|
-
(0, vitest_1.it)("should use default key prefix", () => {
|
|
89
|
-
const defaultCache = new redis_nonce_cache_js_1.RedisNonceCache(mockRedis);
|
|
90
|
-
mockRedis.exists.mockResolvedValue(0);
|
|
91
|
-
defaultCache.has("test-nonce");
|
|
92
|
-
(0, vitest_1.expect)(mockRedis.exists).toHaveBeenCalledWith("mcpi:nonce:test-nonce");
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
});
|