@kya-os/mcp-i-core 1.2.3-canary.7 → 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.
Files changed (231) hide show
  1. package/.claude/settings.local.json +9 -0
  2. package/.turbo/turbo-build.log +4 -0
  3. package/.turbo/turbo-test$colon$coverage.log +4514 -0
  4. package/.turbo/turbo-test.log +2973 -0
  5. package/COMPLIANCE_IMPROVEMENT_REPORT.md +483 -0
  6. package/Composer 3.md +615 -0
  7. package/GPT-5.md +1169 -0
  8. package/OPUS-plan.md +352 -0
  9. package/PHASE_3_AND_4.1_SUMMARY.md +585 -0
  10. package/PHASE_3_SUMMARY.md +317 -0
  11. package/PHASE_4.1.3_SUMMARY.md +428 -0
  12. package/PHASE_4.1_COMPLETE.md +525 -0
  13. package/PHASE_4_USER_DID_IDENTITY_LINKING_PLAN.md +1240 -0
  14. package/SCHEMA_COMPLIANCE_REPORT.md +275 -0
  15. package/TEST_PLAN.md +571 -0
  16. package/coverage/coverage-final.json +57 -0
  17. package/dist/__tests__/utils/mock-providers.d.ts +1 -2
  18. package/dist/__tests__/utils/mock-providers.d.ts.map +1 -1
  19. package/dist/__tests__/utils/mock-providers.js.map +1 -1
  20. package/dist/cache/oauth-config-cache.d.ts +69 -0
  21. package/dist/cache/oauth-config-cache.d.ts.map +1 -0
  22. package/dist/cache/oauth-config-cache.js +76 -0
  23. package/dist/cache/oauth-config-cache.js.map +1 -0
  24. package/dist/identity/idp-token-resolver.d.ts +53 -0
  25. package/dist/identity/idp-token-resolver.d.ts.map +1 -0
  26. package/dist/identity/idp-token-resolver.js +108 -0
  27. package/dist/identity/idp-token-resolver.js.map +1 -0
  28. package/dist/identity/idp-token-storage.interface.d.ts +42 -0
  29. package/dist/identity/idp-token-storage.interface.d.ts.map +1 -0
  30. package/dist/identity/idp-token-storage.interface.js +12 -0
  31. package/dist/identity/idp-token-storage.interface.js.map +1 -0
  32. package/dist/identity/user-did-manager.d.ts +39 -1
  33. package/dist/identity/user-did-manager.d.ts.map +1 -1
  34. package/dist/identity/user-did-manager.js +69 -3
  35. package/dist/identity/user-did-manager.js.map +1 -1
  36. package/dist/index.d.ts +22 -0
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +39 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/runtime/audit-logger.d.ts +37 -0
  41. package/dist/runtime/audit-logger.d.ts.map +1 -0
  42. package/dist/runtime/audit-logger.js +9 -0
  43. package/dist/runtime/audit-logger.js.map +1 -0
  44. package/dist/runtime/base.d.ts +58 -2
  45. package/dist/runtime/base.d.ts.map +1 -1
  46. package/dist/runtime/base.js +266 -11
  47. package/dist/runtime/base.js.map +1 -1
  48. package/dist/services/access-control.service.d.ts.map +1 -1
  49. package/dist/services/access-control.service.js +200 -35
  50. package/dist/services/access-control.service.js.map +1 -1
  51. package/dist/services/authorization/authorization-registry.d.ts +29 -0
  52. package/dist/services/authorization/authorization-registry.d.ts.map +1 -0
  53. package/dist/services/authorization/authorization-registry.js +57 -0
  54. package/dist/services/authorization/authorization-registry.js.map +1 -0
  55. package/dist/services/authorization/types.d.ts +53 -0
  56. package/dist/services/authorization/types.d.ts.map +1 -0
  57. package/dist/services/authorization/types.js +10 -0
  58. package/dist/services/authorization/types.js.map +1 -0
  59. package/dist/services/batch-delegation.service.d.ts +53 -0
  60. package/dist/services/batch-delegation.service.d.ts.map +1 -0
  61. package/dist/services/batch-delegation.service.js +95 -0
  62. package/dist/services/batch-delegation.service.js.map +1 -0
  63. package/dist/services/oauth-config.service.d.ts +53 -0
  64. package/dist/services/oauth-config.service.d.ts.map +1 -0
  65. package/dist/services/oauth-config.service.js +117 -0
  66. package/dist/services/oauth-config.service.js.map +1 -0
  67. package/dist/services/oauth-provider-registry.d.ts +77 -0
  68. package/dist/services/oauth-provider-registry.d.ts.map +1 -0
  69. package/dist/services/oauth-provider-registry.js +112 -0
  70. package/dist/services/oauth-provider-registry.js.map +1 -0
  71. package/dist/services/oauth-service.d.ts +77 -0
  72. package/dist/services/oauth-service.d.ts.map +1 -0
  73. package/dist/services/oauth-service.js +348 -0
  74. package/dist/services/oauth-service.js.map +1 -0
  75. package/dist/services/oauth-token-retrieval.service.d.ts +49 -0
  76. package/dist/services/oauth-token-retrieval.service.d.ts.map +1 -0
  77. package/dist/services/oauth-token-retrieval.service.js +150 -0
  78. package/dist/services/oauth-token-retrieval.service.js.map +1 -0
  79. package/dist/services/provider-resolver.d.ts +48 -0
  80. package/dist/services/provider-resolver.d.ts.map +1 -0
  81. package/dist/services/provider-resolver.js +120 -0
  82. package/dist/services/provider-resolver.js.map +1 -0
  83. package/dist/services/provider-validator.d.ts +55 -0
  84. package/dist/services/provider-validator.d.ts.map +1 -0
  85. package/dist/services/provider-validator.js +135 -0
  86. package/dist/services/provider-validator.js.map +1 -0
  87. package/dist/services/tool-context-builder.d.ts +57 -0
  88. package/dist/services/tool-context-builder.d.ts.map +1 -0
  89. package/dist/services/tool-context-builder.js +125 -0
  90. package/dist/services/tool-context-builder.js.map +1 -0
  91. package/dist/services/tool-protection.service.d.ts +87 -10
  92. package/dist/services/tool-protection.service.d.ts.map +1 -1
  93. package/dist/services/tool-protection.service.js +282 -112
  94. package/dist/services/tool-protection.service.js.map +1 -1
  95. package/dist/types/oauth-required-error.d.ts +40 -0
  96. package/dist/types/oauth-required-error.d.ts.map +1 -0
  97. package/dist/types/oauth-required-error.js +40 -0
  98. package/dist/types/oauth-required-error.js.map +1 -0
  99. package/dist/utils/did-helpers.d.ts +33 -0
  100. package/dist/utils/did-helpers.d.ts.map +1 -1
  101. package/dist/utils/did-helpers.js +40 -0
  102. package/dist/utils/did-helpers.js.map +1 -1
  103. package/dist/utils/index.d.ts +1 -0
  104. package/dist/utils/index.d.ts.map +1 -1
  105. package/dist/utils/index.js +1 -0
  106. package/dist/utils/index.js.map +1 -1
  107. package/docs/API_REFERENCE.md +1362 -0
  108. package/docs/COMPLIANCE_MATRIX.md +691 -0
  109. package/docs/STATUSLIST2021_GUIDE.md +696 -0
  110. package/docs/W3C_VC_DELEGATION_GUIDE.md +710 -0
  111. package/package.json +24 -50
  112. package/scripts/audit-compliance.ts +724 -0
  113. package/src/__tests__/cache/tool-protection-cache.test.ts +640 -0
  114. package/src/__tests__/config/provider-runtime-config.test.ts +309 -0
  115. package/src/__tests__/delegation-e2e.test.ts +690 -0
  116. package/src/__tests__/identity/user-did-manager.test.ts +213 -0
  117. package/src/__tests__/index.test.ts +56 -0
  118. package/src/__tests__/integration/full-flow.test.ts +776 -0
  119. package/src/__tests__/integration.test.ts +281 -0
  120. package/src/__tests__/providers/base.test.ts +173 -0
  121. package/src/__tests__/providers/memory.test.ts +319 -0
  122. package/src/__tests__/regression/phase2-regression.test.ts +427 -0
  123. package/src/__tests__/runtime/audit-logger.test.ts +154 -0
  124. package/src/__tests__/runtime/base-extensions.test.ts +593 -0
  125. package/src/__tests__/runtime/base.test.ts +869 -0
  126. package/src/__tests__/runtime/delegation-flow.test.ts +164 -0
  127. package/src/__tests__/runtime/proof-client-did.test.ts +375 -0
  128. package/src/__tests__/runtime/route-interception.test.ts +686 -0
  129. package/src/__tests__/runtime/tool-protection-enforcement.test.ts +908 -0
  130. package/src/__tests__/services/agentshield-integration.test.ts +784 -0
  131. package/src/__tests__/services/provider-resolver-edge-cases.test.ts +487 -0
  132. package/src/__tests__/services/tool-protection-oauth-provider.test.ts +480 -0
  133. package/src/__tests__/services/tool-protection.service.test.ts +1366 -0
  134. package/src/__tests__/utils/mock-providers.ts +340 -0
  135. package/src/cache/oauth-config-cache.d.ts +69 -0
  136. package/src/cache/oauth-config-cache.d.ts.map +1 -0
  137. package/src/cache/oauth-config-cache.js +71 -0
  138. package/src/cache/oauth-config-cache.js.map +1 -0
  139. package/src/cache/oauth-config-cache.ts +123 -0
  140. package/src/cache/tool-protection-cache.ts +171 -0
  141. package/src/compliance/EXAMPLE.md +412 -0
  142. package/src/compliance/__tests__/schema-verifier.test.ts +797 -0
  143. package/src/compliance/index.ts +8 -0
  144. package/src/compliance/schema-registry.ts +460 -0
  145. package/src/compliance/schema-verifier.ts +708 -0
  146. package/src/config/__tests__/remote-config.spec.ts +268 -0
  147. package/src/config/remote-config.ts +174 -0
  148. package/src/config.ts +309 -0
  149. package/src/delegation/__tests__/audience-validator.test.ts +112 -0
  150. package/src/delegation/__tests__/bitstring.test.ts +346 -0
  151. package/src/delegation/__tests__/cascading-revocation.test.ts +628 -0
  152. package/src/delegation/__tests__/delegation-graph.test.ts +584 -0
  153. package/src/delegation/__tests__/utils.test.ts +152 -0
  154. package/src/delegation/__tests__/vc-issuer.test.ts +442 -0
  155. package/src/delegation/__tests__/vc-verifier.test.ts +922 -0
  156. package/src/delegation/audience-validator.ts +52 -0
  157. package/src/delegation/bitstring.ts +278 -0
  158. package/src/delegation/cascading-revocation.ts +370 -0
  159. package/src/delegation/delegation-graph.ts +299 -0
  160. package/src/delegation/index.ts +14 -0
  161. package/src/delegation/statuslist-manager.ts +353 -0
  162. package/src/delegation/storage/__tests__/memory-graph-storage.test.ts +366 -0
  163. package/src/delegation/storage/__tests__/memory-statuslist-storage.test.ts +228 -0
  164. package/src/delegation/storage/index.ts +9 -0
  165. package/src/delegation/storage/memory-graph-storage.ts +178 -0
  166. package/src/delegation/storage/memory-statuslist-storage.ts +77 -0
  167. package/src/delegation/utils.ts +42 -0
  168. package/src/delegation/vc-issuer.ts +232 -0
  169. package/src/delegation/vc-verifier.ts +568 -0
  170. package/src/identity/idp-token-resolver.ts +147 -0
  171. package/src/identity/idp-token-storage.interface.ts +59 -0
  172. package/src/identity/user-did-manager.ts +370 -0
  173. package/src/index.ts +260 -0
  174. package/src/providers/base.d.ts +91 -0
  175. package/src/providers/base.d.ts.map +1 -0
  176. package/src/providers/base.js +38 -0
  177. package/src/providers/base.js.map +1 -0
  178. package/src/providers/base.ts +96 -0
  179. package/src/providers/memory.ts +142 -0
  180. package/src/runtime/audit-logger.ts +39 -0
  181. package/src/runtime/base.ts +1329 -0
  182. package/src/services/__tests__/access-control.integration.test.ts +443 -0
  183. package/src/services/__tests__/access-control.proof-response-validation.test.ts +578 -0
  184. package/src/services/__tests__/access-control.service.test.ts +970 -0
  185. package/src/services/__tests__/batch-delegation.service.test.ts +351 -0
  186. package/src/services/__tests__/crypto.service.test.ts +531 -0
  187. package/src/services/__tests__/oauth-provider-registry.test.ts +142 -0
  188. package/src/services/__tests__/proof-verifier.integration.test.ts +485 -0
  189. package/src/services/__tests__/proof-verifier.test.ts +489 -0
  190. package/src/services/__tests__/provider-resolution.integration.test.ts +198 -0
  191. package/src/services/__tests__/provider-resolver.test.ts +217 -0
  192. package/src/services/__tests__/storage.service.test.ts +358 -0
  193. package/src/services/access-control.service.ts +990 -0
  194. package/src/services/authorization/authorization-registry.ts +66 -0
  195. package/src/services/authorization/types.ts +71 -0
  196. package/src/services/batch-delegation.service.ts +137 -0
  197. package/src/services/crypto.service.ts +302 -0
  198. package/src/services/errors.ts +76 -0
  199. package/src/services/index.ts +9 -0
  200. package/src/services/oauth-config.service.d.ts +53 -0
  201. package/src/services/oauth-config.service.d.ts.map +1 -0
  202. package/src/services/oauth-config.service.js +113 -0
  203. package/src/services/oauth-config.service.js.map +1 -0
  204. package/src/services/oauth-config.service.ts +166 -0
  205. package/src/services/oauth-provider-registry.d.ts +57 -0
  206. package/src/services/oauth-provider-registry.d.ts.map +1 -0
  207. package/src/services/oauth-provider-registry.js +73 -0
  208. package/src/services/oauth-provider-registry.js.map +1 -0
  209. package/src/services/oauth-provider-registry.ts +123 -0
  210. package/src/services/oauth-service.ts +510 -0
  211. package/src/services/oauth-token-retrieval.service.ts +245 -0
  212. package/src/services/proof-verifier.ts +478 -0
  213. package/src/services/provider-resolver.d.ts +48 -0
  214. package/src/services/provider-resolver.d.ts.map +1 -0
  215. package/src/services/provider-resolver.js +106 -0
  216. package/src/services/provider-resolver.js.map +1 -0
  217. package/src/services/provider-resolver.ts +144 -0
  218. package/src/services/provider-validator.ts +170 -0
  219. package/src/services/storage.service.ts +566 -0
  220. package/src/services/tool-context-builder.ts +172 -0
  221. package/src/services/tool-protection.service.ts +958 -0
  222. package/src/types/oauth-required-error.ts +63 -0
  223. package/src/types/tool-protection.ts +155 -0
  224. package/src/utils/__tests__/did-helpers.test.ts +101 -0
  225. package/src/utils/base64.ts +148 -0
  226. package/src/utils/cors.ts +83 -0
  227. package/src/utils/did-helpers.ts +150 -0
  228. package/src/utils/index.ts +8 -0
  229. package/src/utils/storage-keys.ts +278 -0
  230. package/tsconfig.json +21 -0
  231. 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
+ });