@kya-os/mcp-i-core 1.3.10-canary.clientinfo.20251126124133 → 1.3.11
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/.claude/settings.local.json +9 -0
- package/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-test$colon$coverage.log +3419 -3072
- package/.turbo/turbo-test.log +1805 -1680
- package/coverage/coverage-final.json +59 -56
- 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/idp-token-resolver.d.ts +17 -1
- package/dist/identity/idp-token-resolver.d.ts.map +1 -1
- package/dist/identity/idp-token-resolver.js +34 -6
- package/dist/identity/idp-token-resolver.js.map +1 -1
- package/dist/identity/idp-token-storage.interface.d.ts +38 -7
- package/dist/identity/idp-token-storage.interface.d.ts.map +1 -1
- package/dist/identity/idp-token-storage.interface.js +2 -0
- package/dist/identity/idp-token-storage.interface.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 +6 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -2
- 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-context-builder.d.ts +18 -1
- package/dist/services/tool-context-builder.d.ts.map +1 -1
- package/dist/services/tool-context-builder.js +63 -10
- package/dist/services/tool-context-builder.js.map +1 -1
- package/dist/services/tool-protection.service.d.ts +6 -3
- package/dist/services/tool-protection.service.d.ts.map +1 -1
- package/dist/services/tool-protection.service.js +89 -34
- 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/dist/utils/did-helpers.d.ts +33 -0
- package/dist/utils/did-helpers.d.ts.map +1 -1
- package/dist/utils/did-helpers.js +53 -0
- package/dist/utils/did-helpers.js.map +1 -1
- 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/__tests__/vc-issuer.test.ts +1 -1
- package/src/delegation/did-key-resolver.ts +179 -0
- package/src/delegation/utils.ts +179 -0
- package/src/identity/idp-token-resolver.ts +41 -7
- package/src/identity/idp-token-storage.interface.ts +42 -7
- package/src/identity/user-did-manager.ts +185 -29
- package/src/index.ts +42 -3
- package/src/runtime/base.ts +84 -21
- package/src/services/session-registration.service.ts +26 -121
- package/src/services/tool-context-builder.ts +75 -10
- package/src/services/tool-protection.service.ts +176 -88
- package/src/utils/__tests__/did-helpers.test.ts +55 -0
- package/src/utils/base58.ts +109 -0
- package/src/utils/did-helpers.ts +60 -0
- package/dist/__tests__/utils/mock-providers.d.ts +0 -103
- package/dist/__tests__/utils/mock-providers.d.ts.map +0 -1
- package/dist/__tests__/utils/mock-providers.js +0 -293
- package/dist/__tests__/utils/mock-providers.js.map +0 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* User DID Manager Tests
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Phase 5: Anonymous Sessions Until OAuth
|
|
5
|
+
* Tests for user DID lookup and storage (no ephemeral generation).
|
|
5
6
|
*/
|
|
6
7
|
|
|
7
8
|
import { describe, test, expect, beforeEach, vi } from 'vitest';
|
|
@@ -26,36 +27,37 @@ describe('UserDidManager', () => {
|
|
|
26
27
|
});
|
|
27
28
|
});
|
|
28
29
|
|
|
29
|
-
describe('getOrCreateUserDid', () => {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
// Mock generateKeyPair to return valid base64 keys
|
|
34
|
-
const mockKeyPair = {
|
|
35
|
-
privateKey: Buffer.from(new Uint8Array(32).fill(1)).toString('base64'),
|
|
36
|
-
publicKey: Buffer.from(new Uint8Array(32).fill(2)).toString('base64'),
|
|
37
|
-
};
|
|
38
|
-
vi.spyOn(cryptoProvider, 'generateKeyPair').mockResolvedValue(mockKeyPair);
|
|
39
|
-
|
|
40
|
-
const userDid = await manager.getOrCreateUserDid(sessionId);
|
|
30
|
+
describe('getOrCreateUserDid (Phase 5)', () => {
|
|
31
|
+
test('should return null for new session without existing DID', async () => {
|
|
32
|
+
const sessionId = 'session-123';
|
|
33
|
+
(storage.get as ReturnType<typeof vi.fn>).mockResolvedValue(null);
|
|
41
34
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
});
|
|
35
|
+
// Phase 5: No ephemeral DID generation - returns null for anonymous session
|
|
36
|
+
const userDid = await manager.getOrCreateUserDid(sessionId);
|
|
45
37
|
|
|
46
|
-
|
|
38
|
+
expect(userDid).toBeNull();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('should return same null for same session (cache hit)', async () => {
|
|
47
42
|
const sessionId = 'session-123';
|
|
43
|
+
(storage.get as ReturnType<typeof vi.fn>).mockResolvedValue(null);
|
|
44
|
+
|
|
48
45
|
const did1 = await manager.getOrCreateUserDid(sessionId);
|
|
49
46
|
const did2 = await manager.getOrCreateUserDid(sessionId);
|
|
50
47
|
|
|
51
|
-
expect(did1).
|
|
48
|
+
expect(did1).toBeNull();
|
|
49
|
+
expect(did2).toBeNull();
|
|
52
50
|
});
|
|
53
51
|
|
|
54
|
-
test('should return
|
|
52
|
+
test('should return null for different sessions without OAuth', async () => {
|
|
53
|
+
(storage.get as ReturnType<typeof vi.fn>).mockResolvedValue(null);
|
|
54
|
+
|
|
55
55
|
const did1 = await manager.getOrCreateUserDid('session-1');
|
|
56
56
|
const did2 = await manager.getOrCreateUserDid('session-2');
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
// Phase 5: Both sessions are anonymous (null userDid)
|
|
59
|
+
expect(did1).toBeNull();
|
|
60
|
+
expect(did2).toBeNull();
|
|
59
61
|
});
|
|
60
62
|
|
|
61
63
|
test('should retrieve DID from storage if available', async () => {
|
|
@@ -69,33 +71,42 @@ describe('UserDidManager', () => {
|
|
|
69
71
|
expect(storage.get).toHaveBeenCalledWith(sessionId);
|
|
70
72
|
});
|
|
71
73
|
|
|
72
|
-
test('should
|
|
74
|
+
test('should not call storage.set for new sessions (Phase 5)', async () => {
|
|
73
75
|
const sessionId = 'session-123';
|
|
76
|
+
(storage.get as ReturnType<typeof vi.fn>).mockResolvedValue(null);
|
|
77
|
+
|
|
78
|
+
// Phase 5: No DID generated, no storage write
|
|
74
79
|
const did = await manager.getOrCreateUserDid(sessionId);
|
|
75
80
|
|
|
76
|
-
expect(
|
|
81
|
+
expect(did).toBeNull();
|
|
82
|
+
expect(storage.set).not.toHaveBeenCalled();
|
|
77
83
|
});
|
|
78
84
|
|
|
79
|
-
test('should use cache for subsequent calls', async () => {
|
|
85
|
+
test('should use cache for existing DID on subsequent calls', async () => {
|
|
80
86
|
const sessionId = 'session-123';
|
|
87
|
+
const storedDid = 'did:key:zTestStoredDID';
|
|
88
|
+
(storage.get as ReturnType<typeof vi.fn>).mockResolvedValue(storedDid);
|
|
89
|
+
|
|
81
90
|
const did1 = await manager.getOrCreateUserDid(sessionId);
|
|
82
|
-
|
|
83
|
-
// Clear storage mock
|
|
91
|
+
|
|
92
|
+
// Clear storage mock - next call should use cache
|
|
93
|
+
(storage.get as ReturnType<typeof vi.fn>).mockReset();
|
|
84
94
|
(storage.get as ReturnType<typeof vi.fn>).mockResolvedValue(null);
|
|
85
|
-
|
|
95
|
+
|
|
86
96
|
const did2 = await manager.getOrCreateUserDid(sessionId);
|
|
87
97
|
|
|
88
|
-
expect(did1).toBe(
|
|
89
|
-
expect(
|
|
98
|
+
expect(did1).toBe(storedDid);
|
|
99
|
+
expect(did2).toBe(storedDid); // Cache hit
|
|
90
100
|
});
|
|
91
101
|
|
|
92
|
-
test('should
|
|
102
|
+
test('should return null without storage provider (Phase 5)', async () => {
|
|
93
103
|
const ephemeralManager = new UserDidManager({
|
|
94
104
|
crypto: cryptoProvider,
|
|
95
105
|
});
|
|
96
106
|
|
|
107
|
+
// Phase 5: No storage, no OAuth → anonymous session (null)
|
|
97
108
|
const did = await ephemeralManager.getOrCreateUserDid('session-123');
|
|
98
|
-
expect(did).
|
|
109
|
+
expect(did).toBeNull();
|
|
99
110
|
});
|
|
100
111
|
});
|
|
101
112
|
|
|
@@ -158,16 +169,23 @@ describe('UserDidManager', () => {
|
|
|
158
169
|
});
|
|
159
170
|
|
|
160
171
|
describe('DID format validation', () => {
|
|
161
|
-
test('should
|
|
162
|
-
const
|
|
163
|
-
|
|
172
|
+
test('should return stored DID if it has valid did:key format', async () => {
|
|
173
|
+
const sessionId = 'session-123';
|
|
174
|
+
const validDid = 'did:key:z6MkhaXgBZDvotDUGnNPEFXjSNbMoRmbW2BgUjH9tmp1hQ1R';
|
|
175
|
+
(storage.get as ReturnType<typeof vi.fn>).mockResolvedValue(validDid);
|
|
176
|
+
|
|
177
|
+
const did = await manager.getOrCreateUserDid(sessionId);
|
|
178
|
+
|
|
164
179
|
// did:key format: did:key:z<base58-encoded-multicodec-key>
|
|
180
|
+
expect(did).not.toBeNull();
|
|
165
181
|
expect(did).toMatch(/^did:key:z[1-9A-HJ-NP-Za-km-z]+$/);
|
|
166
182
|
});
|
|
167
183
|
|
|
168
|
-
test('should
|
|
169
|
-
|
|
170
|
-
|
|
184
|
+
test('should return null for new sessions without OAuth (Phase 5)', async () => {
|
|
185
|
+
// Phase 5: getOrCreateUserDid returns null for new sessions without existing DID
|
|
186
|
+
// No ephemeral DID generation - sessions stay anonymous until OAuth
|
|
187
|
+
const dids = new Set<string | null>();
|
|
188
|
+
|
|
171
189
|
for (let i = 0; i < 10; i++) {
|
|
172
190
|
const manager = new UserDidManager({
|
|
173
191
|
crypto: cryptoProvider,
|
|
@@ -176,28 +194,29 @@ describe('UserDidManager', () => {
|
|
|
176
194
|
dids.add(did);
|
|
177
195
|
}
|
|
178
196
|
|
|
179
|
-
// All DIDs should be
|
|
180
|
-
expect(dids.size).toBe(
|
|
197
|
+
// Phase 5: All DIDs should be null (no generation)
|
|
198
|
+
expect(dids.size).toBe(1);
|
|
199
|
+
expect(dids.has(null)).toBe(true);
|
|
181
200
|
});
|
|
182
201
|
});
|
|
183
202
|
|
|
184
203
|
describe('error handling', () => {
|
|
185
|
-
test('should handle storage.get errors gracefully', async () => {
|
|
204
|
+
test('should handle storage.get errors gracefully (Phase 5)', async () => {
|
|
186
205
|
const sessionId = 'session-123';
|
|
187
206
|
(storage.get as ReturnType<typeof vi.fn>).mockRejectedValue(new Error('Storage error'));
|
|
188
207
|
|
|
189
|
-
//
|
|
208
|
+
// Phase 5: Returns null when storage errors occur (no ephemeral generation)
|
|
190
209
|
const did = await manager.getOrCreateUserDid(sessionId);
|
|
191
|
-
expect(did).
|
|
210
|
+
expect(did).toBeNull();
|
|
192
211
|
});
|
|
193
212
|
|
|
194
|
-
test('should
|
|
213
|
+
test('should return null when no existing DID found (Phase 5)', async () => {
|
|
195
214
|
const sessionId = 'session-123';
|
|
196
|
-
(storage.
|
|
215
|
+
(storage.get as ReturnType<typeof vi.fn>).mockResolvedValue(null);
|
|
197
216
|
|
|
198
|
-
//
|
|
217
|
+
// Phase 5: Returns null instead of generating ephemeral DID
|
|
199
218
|
const did = await manager.getOrCreateUserDid(sessionId);
|
|
200
|
-
expect(did).
|
|
219
|
+
expect(did).toBeNull();
|
|
201
220
|
});
|
|
202
221
|
|
|
203
222
|
test('should handle storage.delete errors gracefully', async () => {
|
|
@@ -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
|
});
|