@kya-os/mcp-i-core 1.2.3-canary.6 → 1.3.0
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 +4 -0
- package/.turbo/turbo-test$colon$coverage.log +4514 -0
- package/.turbo/turbo-test.log +2973 -0
- package/COMPLIANCE_IMPROVEMENT_REPORT.md +483 -0
- package/Composer 3.md +615 -0
- package/GPT-5.md +1169 -0
- package/OPUS-plan.md +352 -0
- package/PHASE_3_AND_4.1_SUMMARY.md +585 -0
- package/PHASE_3_SUMMARY.md +317 -0
- package/PHASE_4.1.3_SUMMARY.md +428 -0
- package/PHASE_4.1_COMPLETE.md +525 -0
- package/PHASE_4_USER_DID_IDENTITY_LINKING_PLAN.md +1240 -0
- package/SCHEMA_COMPLIANCE_REPORT.md +275 -0
- package/TEST_PLAN.md +571 -0
- package/coverage/coverage-final.json +57 -0
- package/dist/__tests__/utils/mock-providers.d.ts +1 -2
- package/dist/__tests__/utils/mock-providers.d.ts.map +1 -1
- package/dist/__tests__/utils/mock-providers.js.map +1 -1
- package/dist/cache/oauth-config-cache.d.ts +69 -0
- package/dist/cache/oauth-config-cache.d.ts.map +1 -0
- package/dist/cache/oauth-config-cache.js +76 -0
- package/dist/cache/oauth-config-cache.js.map +1 -0
- package/dist/identity/idp-token-resolver.d.ts +53 -0
- package/dist/identity/idp-token-resolver.d.ts.map +1 -0
- package/dist/identity/idp-token-resolver.js +108 -0
- package/dist/identity/idp-token-resolver.js.map +1 -0
- package/dist/identity/idp-token-storage.interface.d.ts +42 -0
- package/dist/identity/idp-token-storage.interface.d.ts.map +1 -0
- package/dist/identity/idp-token-storage.interface.js +12 -0
- package/dist/identity/idp-token-storage.interface.js.map +1 -0
- package/dist/identity/user-did-manager.d.ts +39 -1
- package/dist/identity/user-did-manager.d.ts.map +1 -1
- package/dist/identity/user-did-manager.js +69 -3
- package/dist/identity/user-did-manager.js.map +1 -1
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +39 -1
- package/dist/index.js.map +1 -1
- package/dist/runtime/audit-logger.d.ts +37 -0
- package/dist/runtime/audit-logger.d.ts.map +1 -0
- package/dist/runtime/audit-logger.js +9 -0
- package/dist/runtime/audit-logger.js.map +1 -0
- package/dist/runtime/base.d.ts +58 -2
- package/dist/runtime/base.d.ts.map +1 -1
- package/dist/runtime/base.js +266 -11
- package/dist/runtime/base.js.map +1 -1
- package/dist/services/access-control.service.d.ts.map +1 -1
- package/dist/services/access-control.service.js +200 -35
- package/dist/services/access-control.service.js.map +1 -1
- package/dist/services/authorization/authorization-registry.d.ts +29 -0
- package/dist/services/authorization/authorization-registry.d.ts.map +1 -0
- package/dist/services/authorization/authorization-registry.js +57 -0
- package/dist/services/authorization/authorization-registry.js.map +1 -0
- package/dist/services/authorization/types.d.ts +53 -0
- package/dist/services/authorization/types.d.ts.map +1 -0
- package/dist/services/authorization/types.js +10 -0
- package/dist/services/authorization/types.js.map +1 -0
- package/dist/services/batch-delegation.service.d.ts +53 -0
- package/dist/services/batch-delegation.service.d.ts.map +1 -0
- package/dist/services/batch-delegation.service.js +95 -0
- package/dist/services/batch-delegation.service.js.map +1 -0
- package/dist/services/oauth-config.service.d.ts +53 -0
- package/dist/services/oauth-config.service.d.ts.map +1 -0
- package/dist/services/oauth-config.service.js +117 -0
- package/dist/services/oauth-config.service.js.map +1 -0
- package/dist/services/oauth-provider-registry.d.ts +77 -0
- package/dist/services/oauth-provider-registry.d.ts.map +1 -0
- package/dist/services/oauth-provider-registry.js +112 -0
- package/dist/services/oauth-provider-registry.js.map +1 -0
- package/dist/services/oauth-service.d.ts +77 -0
- package/dist/services/oauth-service.d.ts.map +1 -0
- package/dist/services/oauth-service.js +348 -0
- package/dist/services/oauth-service.js.map +1 -0
- package/dist/services/oauth-token-retrieval.service.d.ts +49 -0
- package/dist/services/oauth-token-retrieval.service.d.ts.map +1 -0
- package/dist/services/oauth-token-retrieval.service.js +150 -0
- package/dist/services/oauth-token-retrieval.service.js.map +1 -0
- package/dist/services/provider-resolver.d.ts +48 -0
- package/dist/services/provider-resolver.d.ts.map +1 -0
- package/dist/services/provider-resolver.js +120 -0
- package/dist/services/provider-resolver.js.map +1 -0
- package/dist/services/provider-validator.d.ts +55 -0
- package/dist/services/provider-validator.d.ts.map +1 -0
- package/dist/services/provider-validator.js +135 -0
- package/dist/services/provider-validator.js.map +1 -0
- package/dist/services/tool-context-builder.d.ts +57 -0
- package/dist/services/tool-context-builder.d.ts.map +1 -0
- package/dist/services/tool-context-builder.js +125 -0
- package/dist/services/tool-context-builder.js.map +1 -0
- package/dist/services/tool-protection.service.d.ts +87 -10
- package/dist/services/tool-protection.service.d.ts.map +1 -1
- package/dist/services/tool-protection.service.js +282 -112
- package/dist/services/tool-protection.service.js.map +1 -1
- package/dist/types/oauth-required-error.d.ts +40 -0
- package/dist/types/oauth-required-error.d.ts.map +1 -0
- package/dist/types/oauth-required-error.js +40 -0
- package/dist/types/oauth-required-error.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 +40 -0
- package/dist/utils/did-helpers.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/docs/API_REFERENCE.md +1362 -0
- package/docs/COMPLIANCE_MATRIX.md +691 -0
- package/docs/STATUSLIST2021_GUIDE.md +696 -0
- package/docs/W3C_VC_DELEGATION_GUIDE.md +710 -0
- package/package.json +24 -50
- package/scripts/audit-compliance.ts +724 -0
- package/src/__tests__/cache/tool-protection-cache.test.ts +640 -0
- package/src/__tests__/config/provider-runtime-config.test.ts +309 -0
- package/src/__tests__/delegation-e2e.test.ts +690 -0
- package/src/__tests__/identity/user-did-manager.test.ts +213 -0
- package/src/__tests__/index.test.ts +56 -0
- package/src/__tests__/integration/full-flow.test.ts +776 -0
- package/src/__tests__/integration.test.ts +281 -0
- package/src/__tests__/providers/base.test.ts +173 -0
- package/src/__tests__/providers/memory.test.ts +319 -0
- package/src/__tests__/regression/phase2-regression.test.ts +427 -0
- package/src/__tests__/runtime/audit-logger.test.ts +154 -0
- package/src/__tests__/runtime/base-extensions.test.ts +593 -0
- package/src/__tests__/runtime/base.test.ts +869 -0
- package/src/__tests__/runtime/delegation-flow.test.ts +164 -0
- package/src/__tests__/runtime/proof-client-did.test.ts +375 -0
- package/src/__tests__/runtime/route-interception.test.ts +686 -0
- package/src/__tests__/runtime/tool-protection-enforcement.test.ts +908 -0
- package/src/__tests__/services/agentshield-integration.test.ts +784 -0
- package/src/__tests__/services/provider-resolver-edge-cases.test.ts +487 -0
- package/src/__tests__/services/tool-protection-oauth-provider.test.ts +480 -0
- package/src/__tests__/services/tool-protection.service.test.ts +1366 -0
- package/src/__tests__/utils/mock-providers.ts +340 -0
- package/src/cache/oauth-config-cache.d.ts +69 -0
- package/src/cache/oauth-config-cache.d.ts.map +1 -0
- package/src/cache/oauth-config-cache.js +71 -0
- package/src/cache/oauth-config-cache.js.map +1 -0
- package/src/cache/oauth-config-cache.ts +123 -0
- package/src/cache/tool-protection-cache.ts +171 -0
- package/src/compliance/EXAMPLE.md +412 -0
- package/src/compliance/__tests__/schema-verifier.test.ts +797 -0
- package/src/compliance/index.ts +8 -0
- package/src/compliance/schema-registry.ts +460 -0
- package/src/compliance/schema-verifier.ts +708 -0
- package/src/config/__tests__/remote-config.spec.ts +268 -0
- package/src/config/remote-config.ts +174 -0
- package/src/config.ts +309 -0
- package/src/delegation/__tests__/audience-validator.test.ts +112 -0
- package/src/delegation/__tests__/bitstring.test.ts +346 -0
- package/src/delegation/__tests__/cascading-revocation.test.ts +628 -0
- package/src/delegation/__tests__/delegation-graph.test.ts +584 -0
- package/src/delegation/__tests__/utils.test.ts +152 -0
- package/src/delegation/__tests__/vc-issuer.test.ts +442 -0
- package/src/delegation/__tests__/vc-verifier.test.ts +922 -0
- package/src/delegation/audience-validator.ts +52 -0
- package/src/delegation/bitstring.ts +278 -0
- package/src/delegation/cascading-revocation.ts +370 -0
- package/src/delegation/delegation-graph.ts +299 -0
- package/src/delegation/index.ts +14 -0
- package/src/delegation/statuslist-manager.ts +353 -0
- package/src/delegation/storage/__tests__/memory-graph-storage.test.ts +366 -0
- package/src/delegation/storage/__tests__/memory-statuslist-storage.test.ts +228 -0
- package/src/delegation/storage/index.ts +9 -0
- package/src/delegation/storage/memory-graph-storage.ts +178 -0
- package/src/delegation/storage/memory-statuslist-storage.ts +77 -0
- package/src/delegation/utils.ts +42 -0
- package/src/delegation/vc-issuer.ts +232 -0
- package/src/delegation/vc-verifier.ts +568 -0
- package/src/identity/idp-token-resolver.ts +147 -0
- package/src/identity/idp-token-storage.interface.ts +59 -0
- package/src/identity/user-did-manager.ts +370 -0
- package/src/index.ts +260 -0
- package/src/providers/base.d.ts +91 -0
- package/src/providers/base.d.ts.map +1 -0
- package/src/providers/base.js +38 -0
- package/src/providers/base.js.map +1 -0
- package/src/providers/base.ts +96 -0
- package/src/providers/memory.ts +142 -0
- package/src/runtime/audit-logger.ts +39 -0
- package/src/runtime/base.ts +1329 -0
- package/src/services/__tests__/access-control.integration.test.ts +443 -0
- package/src/services/__tests__/access-control.proof-response-validation.test.ts +578 -0
- package/src/services/__tests__/access-control.service.test.ts +970 -0
- package/src/services/__tests__/batch-delegation.service.test.ts +351 -0
- package/src/services/__tests__/crypto.service.test.ts +531 -0
- package/src/services/__tests__/oauth-provider-registry.test.ts +142 -0
- package/src/services/__tests__/proof-verifier.integration.test.ts +485 -0
- package/src/services/__tests__/proof-verifier.test.ts +489 -0
- package/src/services/__tests__/provider-resolution.integration.test.ts +198 -0
- package/src/services/__tests__/provider-resolver.test.ts +217 -0
- package/src/services/__tests__/storage.service.test.ts +358 -0
- package/src/services/access-control.service.ts +990 -0
- package/src/services/authorization/authorization-registry.ts +66 -0
- package/src/services/authorization/types.ts +71 -0
- package/src/services/batch-delegation.service.ts +137 -0
- package/src/services/crypto.service.ts +302 -0
- package/src/services/errors.ts +76 -0
- package/src/services/index.ts +9 -0
- package/src/services/oauth-config.service.d.ts +53 -0
- package/src/services/oauth-config.service.d.ts.map +1 -0
- package/src/services/oauth-config.service.js +113 -0
- package/src/services/oauth-config.service.js.map +1 -0
- package/src/services/oauth-config.service.ts +166 -0
- package/src/services/oauth-provider-registry.d.ts +57 -0
- package/src/services/oauth-provider-registry.d.ts.map +1 -0
- package/src/services/oauth-provider-registry.js +73 -0
- package/src/services/oauth-provider-registry.js.map +1 -0
- package/src/services/oauth-provider-registry.ts +123 -0
- package/src/services/oauth-service.ts +510 -0
- package/src/services/oauth-token-retrieval.service.ts +245 -0
- package/src/services/proof-verifier.ts +478 -0
- package/src/services/provider-resolver.d.ts +48 -0
- package/src/services/provider-resolver.d.ts.map +1 -0
- package/src/services/provider-resolver.js +106 -0
- package/src/services/provider-resolver.js.map +1 -0
- package/src/services/provider-resolver.ts +144 -0
- package/src/services/provider-validator.ts +170 -0
- package/src/services/storage.service.ts +566 -0
- package/src/services/tool-context-builder.ts +172 -0
- package/src/services/tool-protection.service.ts +958 -0
- package/src/types/oauth-required-error.ts +63 -0
- package/src/types/tool-protection.ts +155 -0
- package/src/utils/__tests__/did-helpers.test.ts +101 -0
- package/src/utils/base64.ts +148 -0
- package/src/utils/cors.ts +83 -0
- package/src/utils/did-helpers.ts +150 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/storage-keys.ts +278 -0
- package/tsconfig.json +21 -0
- package/vitest.config.ts +56 -0
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for Memory Provider Implementations
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
6
|
+
import {
|
|
7
|
+
MemoryStorageProvider,
|
|
8
|
+
MemoryNonceCacheProvider,
|
|
9
|
+
MemoryIdentityProvider
|
|
10
|
+
} from '../../providers/memory';
|
|
11
|
+
import { MockCryptoProvider } from '../utils/mock-providers';
|
|
12
|
+
|
|
13
|
+
describe('MemoryStorageProvider', () => {
|
|
14
|
+
let provider: MemoryStorageProvider;
|
|
15
|
+
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
provider = new MemoryStorageProvider();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
describe('get', () => {
|
|
21
|
+
it('should return null for non-existent keys', async () => {
|
|
22
|
+
const value = await provider.get('nonexistent');
|
|
23
|
+
expect(value).toBeNull();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should return stored values', async () => {
|
|
27
|
+
await provider.set('key1', 'value1');
|
|
28
|
+
const value = await provider.get('key1');
|
|
29
|
+
expect(value).toBe('value1');
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
describe('set', () => {
|
|
34
|
+
it('should store values', async () => {
|
|
35
|
+
await provider.set('key1', 'value1');
|
|
36
|
+
const value = await provider.get('key1');
|
|
37
|
+
expect(value).toBe('value1');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should overwrite existing values', async () => {
|
|
41
|
+
await provider.set('key1', 'value1');
|
|
42
|
+
await provider.set('key1', 'value2');
|
|
43
|
+
const value = await provider.get('key1');
|
|
44
|
+
expect(value).toBe('value2');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('should handle empty string values', async () => {
|
|
48
|
+
await provider.set('key1', '');
|
|
49
|
+
const value = await provider.get('key1');
|
|
50
|
+
expect(value).toBe('');
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
describe('delete', () => {
|
|
55
|
+
it('should delete existing keys', async () => {
|
|
56
|
+
await provider.set('key1', 'value1');
|
|
57
|
+
await provider.delete('key1');
|
|
58
|
+
const value = await provider.get('key1');
|
|
59
|
+
expect(value).toBeNull();
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('should handle deleting non-existent keys', async () => {
|
|
63
|
+
await expect(provider.delete('nonexistent')).resolves.toBeUndefined();
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
describe('exists', () => {
|
|
68
|
+
it('should return false for non-existent keys', async () => {
|
|
69
|
+
const exists = await provider.exists('nonexistent');
|
|
70
|
+
expect(exists).toBe(false);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('should return true for existing keys', async () => {
|
|
74
|
+
await provider.set('key1', 'value1');
|
|
75
|
+
const exists = await provider.exists('key1');
|
|
76
|
+
expect(exists).toBe(true);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('should return true for empty string values', async () => {
|
|
80
|
+
await provider.set('key1', '');
|
|
81
|
+
const exists = await provider.exists('key1');
|
|
82
|
+
expect(exists).toBe(true);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
describe('list', () => {
|
|
87
|
+
beforeEach(async () => {
|
|
88
|
+
await provider.set('prefix/key1', 'value1');
|
|
89
|
+
await provider.set('prefix/key2', 'value2');
|
|
90
|
+
await provider.set('other/key3', 'value3');
|
|
91
|
+
await provider.set('key4', 'value4');
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should list all keys when no prefix provided', async () => {
|
|
95
|
+
const keys = await provider.list();
|
|
96
|
+
expect(keys).toHaveLength(4);
|
|
97
|
+
expect(keys).toContain('prefix/key1');
|
|
98
|
+
expect(keys).toContain('prefix/key2');
|
|
99
|
+
expect(keys).toContain('other/key3');
|
|
100
|
+
expect(keys).toContain('key4');
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('should filter by prefix', async () => {
|
|
104
|
+
const keys = await provider.list('prefix/');
|
|
105
|
+
expect(keys).toHaveLength(2);
|
|
106
|
+
expect(keys).toContain('prefix/key1');
|
|
107
|
+
expect(keys).toContain('prefix/key2');
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('should return empty array for non-matching prefix', async () => {
|
|
111
|
+
const keys = await provider.list('nonexistent/');
|
|
112
|
+
expect(keys).toHaveLength(0);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('should handle empty prefix', async () => {
|
|
116
|
+
const keys = await provider.list('');
|
|
117
|
+
expect(keys).toHaveLength(4);
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
describe('MemoryNonceCacheProvider', () => {
|
|
123
|
+
let provider: MemoryNonceCacheProvider;
|
|
124
|
+
|
|
125
|
+
beforeEach(() => {
|
|
126
|
+
provider = new MemoryNonceCacheProvider();
|
|
127
|
+
vi.useFakeTimers();
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
afterEach(() => {
|
|
131
|
+
vi.useRealTimers();
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
describe('has', () => {
|
|
135
|
+
it('should return false for non-existent nonces', async () => {
|
|
136
|
+
const has = await provider.has('nonexistent');
|
|
137
|
+
expect(has).toBe(false);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('should return true for valid nonces', async () => {
|
|
141
|
+
await provider.add('nonce1', 5); // 5 seconds TTL
|
|
142
|
+
const has = await provider.has('nonce1');
|
|
143
|
+
expect(has).toBe(true);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it('should return false for expired nonces', async () => {
|
|
147
|
+
await provider.add('nonce1', -1); // Negative TTL = expired
|
|
148
|
+
const has = await provider.has('nonce1');
|
|
149
|
+
expect(has).toBe(false);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it('should remove expired nonces when checking', async () => {
|
|
153
|
+
await provider.add('nonce1', -1); // Negative TTL = expired
|
|
154
|
+
await provider.has('nonce1'); // This should remove it
|
|
155
|
+
|
|
156
|
+
// Check internal state
|
|
157
|
+
const has = await provider.has('nonce1');
|
|
158
|
+
expect(has).toBe(false);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
describe('add', () => {
|
|
163
|
+
it('should add nonces with expiry', async () => {
|
|
164
|
+
await provider.add('nonce1', 5); // 5 seconds TTL
|
|
165
|
+
const has = await provider.has('nonce1');
|
|
166
|
+
expect(has).toBe(true);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it('should overwrite existing nonces', async () => {
|
|
170
|
+
await provider.add('nonce1', 5); // 5 seconds TTL
|
|
171
|
+
await provider.add('nonce1', 10); // 10 seconds TTL
|
|
172
|
+
|
|
173
|
+
// Advance time by 7 seconds (between 5 and 10)
|
|
174
|
+
vi.advanceTimersByTime(7000);
|
|
175
|
+
|
|
176
|
+
const has = await provider.has('nonce1');
|
|
177
|
+
expect(has).toBe(true); // Should still be valid with new expiry
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
describe('cleanup', () => {
|
|
182
|
+
it('should remove expired nonces', async () => {
|
|
183
|
+
await provider.add('expired', -1); // Negative TTL = expired
|
|
184
|
+
await provider.add('valid', 5); // 5 seconds TTL
|
|
185
|
+
|
|
186
|
+
await provider.cleanup();
|
|
187
|
+
|
|
188
|
+
expect(await provider.has('expired')).toBe(false);
|
|
189
|
+
expect(await provider.has('valid')).toBe(true);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it('should handle empty cache', async () => {
|
|
193
|
+
await expect(provider.cleanup()).resolves.toBeUndefined();
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
describe('destroy', () => {
|
|
198
|
+
it('should clear all nonces', async () => {
|
|
199
|
+
await provider.add('nonce1', 5); // 5 seconds TTL
|
|
200
|
+
await provider.add('nonce2', 5); // 5 seconds TTL
|
|
201
|
+
|
|
202
|
+
await provider.destroy();
|
|
203
|
+
|
|
204
|
+
expect(await provider.has('nonce1')).toBe(false);
|
|
205
|
+
expect(await provider.has('nonce2')).toBe(false);
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
describe('MemoryIdentityProvider', () => {
|
|
211
|
+
let provider: MemoryIdentityProvider;
|
|
212
|
+
let cryptoProvider: MockCryptoProvider;
|
|
213
|
+
|
|
214
|
+
beforeEach(() => {
|
|
215
|
+
cryptoProvider = new MockCryptoProvider();
|
|
216
|
+
provider = new MemoryIdentityProvider(cryptoProvider);
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
describe('getIdentity', () => {
|
|
220
|
+
it('should generate identity on first call', async () => {
|
|
221
|
+
const identity = await provider.getIdentity();
|
|
222
|
+
|
|
223
|
+
expect(identity).toBeDefined();
|
|
224
|
+
expect(identity.did).toMatch(/^did:key:z/);
|
|
225
|
+
expect(identity.kid).toBe(`${identity.did}#key-1`);
|
|
226
|
+
expect(identity.privateKey).toMatch(/^[A-Za-z0-9+/=]+$/); // Valid base64 string
|
|
227
|
+
expect(identity.publicKey).toMatch(/^[A-Za-z0-9+/=]+$/); // Valid base64 string
|
|
228
|
+
expect(identity.type).toBe('development');
|
|
229
|
+
expect(identity.createdAt).toBeDefined();
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
it('should return same identity on subsequent calls', async () => {
|
|
233
|
+
const identity1 = await provider.getIdentity();
|
|
234
|
+
const identity2 = await provider.getIdentity();
|
|
235
|
+
|
|
236
|
+
expect(identity1).toEqual(identity2);
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
it('should throw without crypto provider', async () => {
|
|
240
|
+
const providerNoCrypto = new MemoryIdentityProvider();
|
|
241
|
+
await expect(providerNoCrypto.getIdentity()).rejects.toThrow('Crypto provider required');
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
describe('saveIdentity', () => {
|
|
246
|
+
it('should save and return the saved identity', async () => {
|
|
247
|
+
const customIdentity = {
|
|
248
|
+
did: 'did:key:zcustom',
|
|
249
|
+
kid: 'did:key:zcustom#key-1',
|
|
250
|
+
privateKey: 'custom-private',
|
|
251
|
+
publicKey: 'custom-public',
|
|
252
|
+
createdAt: new Date().toISOString(),
|
|
253
|
+
type: 'production' as const,
|
|
254
|
+
metadata: { custom: true }
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
await provider.saveIdentity(customIdentity);
|
|
258
|
+
const retrieved = await provider.getIdentity();
|
|
259
|
+
|
|
260
|
+
expect(retrieved).toEqual(customIdentity);
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
describe('rotateKeys', () => {
|
|
265
|
+
it('should generate new identity', async () => {
|
|
266
|
+
const oldIdentity = await provider.getIdentity();
|
|
267
|
+
const newIdentity = await provider.rotateKeys();
|
|
268
|
+
|
|
269
|
+
expect(newIdentity.did).not.toBe(oldIdentity.did);
|
|
270
|
+
expect(newIdentity.privateKey).toMatch(/^[A-Za-z0-9+/=]+$/); // Valid base64 string
|
|
271
|
+
expect(newIdentity.publicKey).toMatch(/^[A-Za-z0-9+/=]+$/); // Valid base64 string
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
it('should return new identity on subsequent calls', async () => {
|
|
275
|
+
const oldIdentity = await provider.getIdentity();
|
|
276
|
+
await provider.rotateKeys();
|
|
277
|
+
const currentIdentity = await provider.getIdentity();
|
|
278
|
+
|
|
279
|
+
expect(currentIdentity.did).not.toBe(oldIdentity.did);
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
it('should throw without crypto provider', async () => {
|
|
283
|
+
const providerNoCrypto = new MemoryIdentityProvider();
|
|
284
|
+
await expect(providerNoCrypto.rotateKeys()).rejects.toThrow('Crypto provider required');
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
describe('deleteIdentity', () => {
|
|
289
|
+
it('should delete existing identity', async () => {
|
|
290
|
+
const identity = await provider.getIdentity();
|
|
291
|
+
await provider.deleteIdentity();
|
|
292
|
+
|
|
293
|
+
// Should generate new identity after deletion
|
|
294
|
+
const newIdentity = await provider.getIdentity();
|
|
295
|
+
expect(newIdentity.did).not.toBe(identity.did);
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
it('should handle deleting when no identity exists', async () => {
|
|
299
|
+
await expect(provider.deleteIdentity()).resolves.toBeUndefined();
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
describe('DID generation', () => {
|
|
304
|
+
it('should generate consistent DID format', async () => {
|
|
305
|
+
const identity = await provider.getIdentity();
|
|
306
|
+
expect(identity.did).toMatch(/^did:key:z[A-Za-z0-9_-]+$/);
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
it('should generate DID from public key', async () => {
|
|
310
|
+
// Test the DID generation logic
|
|
311
|
+
const identity = await provider.getIdentity();
|
|
312
|
+
const publicKeyPart = Buffer.from(identity.publicKey, 'base64')
|
|
313
|
+
.toString('base64url')
|
|
314
|
+
.substring(0, 32);
|
|
315
|
+
|
|
316
|
+
expect(identity.did).toBe(`did:key:z${publicKeyPart}`);
|
|
317
|
+
});
|
|
318
|
+
});
|
|
319
|
+
});
|