@kya-os/mcp-i-core 1.3.10-canary.clientinfo.20251126124133 → 1.3.10
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/.turbo/turbo-build.log +1 -1
- package/dist/__tests__/utils/mock-providers.d.ts +2 -1
- package/dist/__tests__/utils/mock-providers.d.ts.map +1 -1
- package/dist/__tests__/utils/mock-providers.js.map +1 -1
- package/dist/config/remote-config.d.ts +51 -0
- package/dist/config/remote-config.d.ts.map +1 -1
- package/dist/config/remote-config.js +74 -0
- package/dist/config/remote-config.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -1
- package/dist/config.js.map +1 -1
- package/dist/delegation/did-key-resolver.d.ts +64 -0
- package/dist/delegation/did-key-resolver.d.ts.map +1 -0
- package/dist/delegation/did-key-resolver.js +159 -0
- package/dist/delegation/did-key-resolver.js.map +1 -0
- package/dist/delegation/utils.d.ts +76 -0
- package/dist/delegation/utils.d.ts.map +1 -1
- package/dist/delegation/utils.js +117 -0
- package/dist/delegation/utils.js.map +1 -1
- package/dist/identity/user-did-manager.d.ts +95 -12
- package/dist/identity/user-did-manager.d.ts.map +1 -1
- package/dist/identity/user-did-manager.js +107 -25
- package/dist/identity/user-did-manager.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -1
- package/dist/index.js.map +1 -1
- package/dist/runtime/base.d.ts +25 -8
- package/dist/runtime/base.d.ts.map +1 -1
- package/dist/runtime/base.js +74 -21
- package/dist/runtime/base.js.map +1 -1
- package/dist/services/session-registration.service.d.ts.map +1 -1
- package/dist/services/session-registration.service.js +10 -90
- package/dist/services/session-registration.service.js.map +1 -1
- package/dist/services/tool-protection.service.d.ts +5 -2
- package/dist/services/tool-protection.service.d.ts.map +1 -1
- package/dist/services/tool-protection.service.js +72 -24
- package/dist/services/tool-protection.service.js.map +1 -1
- package/dist/utils/base58.d.ts +31 -0
- package/dist/utils/base58.d.ts.map +1 -0
- package/dist/utils/base58.js +103 -0
- package/dist/utils/base58.js.map +1 -0
- package/package.json +3 -3
- package/src/__tests__/identity/user-did-manager.test.ts +64 -45
- package/src/__tests__/integration/full-flow.test.ts +23 -10
- package/src/__tests__/runtime/base-extensions.test.ts +23 -21
- package/src/__tests__/runtime/proof-client-did.test.ts +19 -18
- package/src/__tests__/services/agentshield-integration.test.ts +10 -3
- package/src/__tests__/services/tool-protection-merged-config.test.ts +485 -0
- package/src/__tests__/services/tool-protection.service.test.ts +18 -11
- package/src/config/__tests__/merged-config.spec.ts +445 -0
- package/src/config/remote-config.ts +90 -0
- package/src/config.ts +3 -0
- package/src/delegation/__tests__/did-key-resolver.test.ts +265 -0
- package/src/delegation/did-key-resolver.ts +179 -0
- package/src/delegation/utils.ts +179 -0
- package/src/identity/user-did-manager.ts +185 -29
- package/src/index.ts +36 -1
- package/src/runtime/base.ts +84 -21
- package/src/services/session-registration.service.ts +26 -121
- package/src/services/tool-protection.service.ts +125 -56
- package/src/utils/base58.ts +109 -0
- package/coverage/coverage-final.json +0 -57
|
@@ -358,14 +358,20 @@ describe("Full Flow Integration", () => {
|
|
|
358
358
|
});
|
|
359
359
|
|
|
360
360
|
describe("AgentShield integration flow", () => {
|
|
361
|
-
test("should fetch tool protection config from AgentShield", async () => {
|
|
361
|
+
test("should fetch tool protection config from AgentShield merged config", async () => {
|
|
362
|
+
// Merged config format - tools embedded at config.toolProtection.tools
|
|
362
363
|
const apiResponse = {
|
|
363
364
|
success: true,
|
|
364
365
|
data: {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
366
|
+
config: {
|
|
367
|
+
toolProtection: {
|
|
368
|
+
source: 'agentshield',
|
|
369
|
+
tools: {
|
|
370
|
+
protected_tool: {
|
|
371
|
+
requiresDelegation: true,
|
|
372
|
+
requiredScopes: ["scope1"],
|
|
373
|
+
},
|
|
374
|
+
},
|
|
369
375
|
},
|
|
370
376
|
},
|
|
371
377
|
},
|
|
@@ -384,22 +390,29 @@ describe("Full Flow Integration", () => {
|
|
|
384
390
|
expect(config.toolProtections.protected_tool.requiresDelegation).toBe(
|
|
385
391
|
true
|
|
386
392
|
);
|
|
393
|
+
// Now calls /config endpoint (not /tool-protections)
|
|
387
394
|
expect(global.fetch).toHaveBeenCalledWith(
|
|
388
395
|
expect.stringContaining(
|
|
389
|
-
"/api/v1/bouncer/projects/test-project/
|
|
396
|
+
"/api/v1/bouncer/projects/test-project/config"
|
|
390
397
|
),
|
|
391
398
|
expect.any(Object)
|
|
392
399
|
);
|
|
393
400
|
});
|
|
394
401
|
|
|
395
402
|
test("should cache tool protection config", async () => {
|
|
403
|
+
// Merged config format - tools embedded at config.toolProtection.tools
|
|
396
404
|
const apiResponse = {
|
|
397
405
|
success: true,
|
|
398
406
|
data: {
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
407
|
+
config: {
|
|
408
|
+
toolProtection: {
|
|
409
|
+
source: 'agentshield',
|
|
410
|
+
tools: {
|
|
411
|
+
tool1: {
|
|
412
|
+
requiresDelegation: true,
|
|
413
|
+
requiredScopes: ["scope1"],
|
|
414
|
+
},
|
|
415
|
+
},
|
|
403
416
|
},
|
|
404
417
|
},
|
|
405
418
|
},
|
|
@@ -108,7 +108,8 @@ describe('MCPIRuntimeBase - Base Extensions', () => {
|
|
|
108
108
|
});
|
|
109
109
|
|
|
110
110
|
describe('handleHandshake with user DID generation', () => {
|
|
111
|
-
it('should
|
|
111
|
+
it('should start session as anonymous (Phase 5)', async () => {
|
|
112
|
+
// Phase 5: Sessions start anonymous - userDid is only set after OAuth
|
|
112
113
|
const configWithUserDid = {
|
|
113
114
|
...config,
|
|
114
115
|
identity: {
|
|
@@ -124,11 +125,16 @@ describe('MCPIRuntimeBase - Base Extensions', () => {
|
|
|
124
125
|
audience: 'https://client.example.com'
|
|
125
126
|
});
|
|
126
127
|
|
|
127
|
-
|
|
128
|
-
expect(response.userDid).
|
|
128
|
+
// Phase 5: userDid is undefined in response - session is anonymous
|
|
129
|
+
expect(response.userDid).toBeUndefined();
|
|
130
|
+
|
|
131
|
+
// Check session's identityState
|
|
132
|
+
const session = await runtimeWithUserDid.getCurrentSession();
|
|
133
|
+
expect(session.identityState).toBe('anonymous');
|
|
129
134
|
});
|
|
130
135
|
|
|
131
|
-
it('should use provided clientDid
|
|
136
|
+
it('should use provided clientDid with anonymous session (Phase 5)', async () => {
|
|
137
|
+
// Phase 5: clientDid can be set while session stays anonymous (no userDid)
|
|
132
138
|
const configWithUserDid = {
|
|
133
139
|
...config,
|
|
134
140
|
identity: {
|
|
@@ -147,13 +153,10 @@ describe('MCPIRuntimeBase - Base Extensions', () => {
|
|
|
147
153
|
|
|
148
154
|
const session = await runtimeWithUserDid.getCurrentSession();
|
|
149
155
|
expect(session.clientDid).toBe('did:key:zprovided123');
|
|
150
|
-
|
|
151
|
-
//
|
|
152
|
-
|
|
153
|
-
expect(session.
|
|
154
|
-
expect(session.userDid).toMatch(/^did:key:z/);
|
|
155
|
-
// userDid should be different from clientDid
|
|
156
|
-
expect(session.userDid).not.toBe(session.clientDid);
|
|
156
|
+
|
|
157
|
+
// Phase 5: userDid is undefined - session is anonymous until OAuth
|
|
158
|
+
expect(session.userDid).toBeUndefined();
|
|
159
|
+
expect(session.identityState).toBe('anonymous');
|
|
157
160
|
});
|
|
158
161
|
|
|
159
162
|
it('should handle user DID generation errors gracefully', async () => {
|
|
@@ -168,25 +171,24 @@ describe('MCPIRuntimeBase - Base Extensions', () => {
|
|
|
168
171
|
const runtimeWithUserDid = new MCPIRuntimeBase(configWithUserDid);
|
|
169
172
|
await runtimeWithUserDid.initialize();
|
|
170
173
|
|
|
171
|
-
//
|
|
174
|
+
// Phase 5: getOrCreateUserDid now returns null instead of generating ephemeral DIDs
|
|
175
|
+
// Sessions start anonymous - no userDid at handshake
|
|
172
176
|
const userDidManager = (runtimeWithUserDid as any).userDidManager;
|
|
173
177
|
const originalGetOrCreate = userDidManager.getOrCreateUserDid;
|
|
174
|
-
userDidManager.getOrCreateUserDid = vi.fn().
|
|
175
|
-
|
|
176
|
-
const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
178
|
+
userDidManager.getOrCreateUserDid = vi.fn().mockResolvedValue(null);
|
|
177
179
|
|
|
178
180
|
const response = await runtimeWithUserDid.handleHandshake({
|
|
179
181
|
audience: 'https://client.example.com'
|
|
180
182
|
});
|
|
181
183
|
|
|
182
|
-
// Should
|
|
184
|
+
// Should succeed with anonymous session (no userDid)
|
|
183
185
|
expect(response.sessionId).toBeDefined();
|
|
184
|
-
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
185
|
-
expect.stringContaining('[MCP-I] Failed to generate user DID'),
|
|
186
|
-
expect.any(Error)
|
|
187
|
-
);
|
|
188
186
|
|
|
189
|
-
|
|
187
|
+
// Phase 5: Session should be anonymous without userDid
|
|
188
|
+
const session = await runtimeWithUserDid.getCurrentSession();
|
|
189
|
+
expect(session.userDid).toBeUndefined();
|
|
190
|
+
expect(session.identityState).toBe('anonymous');
|
|
191
|
+
|
|
190
192
|
userDidManager.getOrCreateUserDid = originalGetOrCreate;
|
|
191
193
|
});
|
|
192
194
|
});
|
|
@@ -143,8 +143,8 @@ describe('MCPIRuntimeBase - Proof Client DID', () => {
|
|
|
143
143
|
expect(session.clientDid).toBe('did:key:zhandshake123');
|
|
144
144
|
});
|
|
145
145
|
|
|
146
|
-
it('should handle
|
|
147
|
-
//
|
|
146
|
+
it('should handle anonymous session from handshake (Phase 5)', async () => {
|
|
147
|
+
// Phase 5: Sessions start anonymous - no userDid at handshake
|
|
148
148
|
const configWithUserDid = {
|
|
149
149
|
...config,
|
|
150
150
|
identity: {
|
|
@@ -162,12 +162,12 @@ describe('MCPIRuntimeBase - Proof Client DID', () => {
|
|
|
162
162
|
|
|
163
163
|
const session = await runtimeWithUserDid.getCurrentSession();
|
|
164
164
|
expect(session).toBeDefined();
|
|
165
|
-
|
|
166
|
-
//
|
|
167
|
-
//
|
|
168
|
-
expect(session.userDid).
|
|
169
|
-
expect(session.
|
|
170
|
-
|
|
165
|
+
|
|
166
|
+
// Phase 5: Sessions start anonymous without userDid
|
|
167
|
+
// userDid is only set after OAuth identity resolution
|
|
168
|
+
expect(session.userDid).toBeUndefined();
|
|
169
|
+
expect(session.identityState).toBe('anonymous');
|
|
170
|
+
|
|
171
171
|
const proof = await runtimeWithUserDid.createProof(
|
|
172
172
|
{ test: 'data' },
|
|
173
173
|
session
|
|
@@ -234,7 +234,8 @@ describe('MCPIRuntimeBase - Proof Client DID', () => {
|
|
|
234
234
|
expect(session.clientDid).toBe('did:key:zclient789');
|
|
235
235
|
});
|
|
236
236
|
|
|
237
|
-
it('should
|
|
237
|
+
it('should handle anonymous session when no clientDid provided (Phase 5)', async () => {
|
|
238
|
+
// Phase 5: Sessions start anonymous - userDid and clientDid may both be undefined
|
|
238
239
|
const configWithUserDid = {
|
|
239
240
|
...config,
|
|
240
241
|
identity: {
|
|
@@ -252,15 +253,15 @@ describe('MCPIRuntimeBase - Proof Client DID', () => {
|
|
|
252
253
|
|
|
253
254
|
const session = await runtimeWithUserDid.getCurrentSession();
|
|
254
255
|
expect(session).toBeDefined();
|
|
255
|
-
|
|
256
|
-
//
|
|
257
|
-
//
|
|
258
|
-
expect(session.userDid).
|
|
259
|
-
expect(session.
|
|
260
|
-
|
|
261
|
-
// clientDid
|
|
262
|
-
|
|
263
|
-
|
|
256
|
+
|
|
257
|
+
// Phase 5: Sessions start anonymous without userDid
|
|
258
|
+
// userDid is only set after OAuth identity resolution
|
|
259
|
+
expect(session.userDid).toBeUndefined();
|
|
260
|
+
expect(session.identityState).toBe('anonymous');
|
|
261
|
+
|
|
262
|
+
// clientDid can also be undefined in anonymous sessions
|
|
263
|
+
// Both will be set after OAuth completes
|
|
264
|
+
|
|
264
265
|
// Verify proof includes the session
|
|
265
266
|
const proof = await runtimeWithUserDid.createProof(
|
|
266
267
|
{ test: 'data' },
|
|
@@ -144,11 +144,17 @@ describe('AgentShield Integration', () => {
|
|
|
144
144
|
});
|
|
145
145
|
|
|
146
146
|
describe('Endpoint Selection', () => {
|
|
147
|
-
test('should use project-scoped endpoint when projectId is available', async () => {
|
|
147
|
+
test('should use project-scoped /config endpoint when projectId is available', async () => {
|
|
148
|
+
// Merged config format - tools embedded at config.toolProtection.tools
|
|
148
149
|
const apiResponse = {
|
|
149
150
|
success: true,
|
|
150
151
|
data: {
|
|
151
|
-
|
|
152
|
+
config: {
|
|
153
|
+
toolProtection: {
|
|
154
|
+
source: 'agentshield',
|
|
155
|
+
tools: {},
|
|
156
|
+
},
|
|
157
|
+
},
|
|
152
158
|
},
|
|
153
159
|
metadata: {},
|
|
154
160
|
};
|
|
@@ -160,8 +166,9 @@ describe('AgentShield Integration', () => {
|
|
|
160
166
|
|
|
161
167
|
await service.getToolProtectionConfig(mockAgentDid);
|
|
162
168
|
|
|
169
|
+
// Now calls /config endpoint (not /tool-protections)
|
|
163
170
|
expect(global.fetch).toHaveBeenCalledWith(
|
|
164
|
-
`${baseUrl}/api/v1/bouncer/projects/test-project-123/
|
|
171
|
+
`${baseUrl}/api/v1/bouncer/projects/test-project-123/config`,
|
|
165
172
|
expect.any(Object)
|
|
166
173
|
);
|
|
167
174
|
});
|