@interop/was-react 0.1.2 → 0.1.4

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 (150) hide show
  1. package/README.md +9 -1
  2. package/dist/auth/chapi.d.ts +3 -1
  3. package/dist/auth/chapi.d.ts.map +1 -1
  4. package/dist/auth/chapi.js +6 -2
  5. package/dist/auth/chapi.js.map +1 -1
  6. package/dist/auth/loginFlow.d.ts +30 -10
  7. package/dist/auth/loginFlow.d.ts.map +1 -1
  8. package/dist/auth/loginFlow.js +3 -1
  9. package/dist/auth/loginFlow.js.map +1 -1
  10. package/dist/auth/loginRequest.d.ts +9 -3
  11. package/dist/auth/loginRequest.d.ts.map +1 -1
  12. package/dist/auth/loginRequest.js +9 -3
  13. package/dist/auth/loginRequest.js.map +1 -1
  14. package/dist/auth/verifyResponse.d.ts +9 -3
  15. package/dist/auth/verifyResponse.d.ts.map +1 -1
  16. package/dist/auth/verifyResponse.js +6 -2
  17. package/dist/auth/verifyResponse.js.map +1 -1
  18. package/dist/config.d.ts +60 -20
  19. package/dist/config.d.ts.map +1 -1
  20. package/dist/config.js +12 -4
  21. package/dist/config.js.map +1 -1
  22. package/dist/dev/cli.d.ts.map +1 -1
  23. package/dist/dev/cli.js +4 -7
  24. package/dist/dev/cli.js.map +1 -1
  25. package/dist/dev/provisionDevGrants.d.ts +15 -5
  26. package/dist/dev/provisionDevGrants.d.ts.map +1 -1
  27. package/dist/dev/provisionDevGrants.js +2 -2
  28. package/dist/dev/provisionDevGrants.js.map +1 -1
  29. package/dist/grants.d.ts +7 -19
  30. package/dist/grants.d.ts.map +1 -1
  31. package/dist/grants.js +28 -7
  32. package/dist/grants.js.map +1 -1
  33. package/dist/identity/appSession.d.ts +9 -3
  34. package/dist/identity/appSession.d.ts.map +1 -1
  35. package/dist/identity/appSession.js +3 -1
  36. package/dist/identity/appSession.js.map +1 -1
  37. package/dist/identity/documentLoader.d.ts +3 -1
  38. package/dist/identity/documentLoader.d.ts.map +1 -1
  39. package/dist/identity/documentLoader.js +6 -2
  40. package/dist/identity/documentLoader.js.map +1 -1
  41. package/dist/identity/seedCredential.d.ts +9 -3
  42. package/dist/identity/seedCredential.d.ts.map +1 -1
  43. package/dist/identity/seedCredential.js +9 -15
  44. package/dist/identity/seedCredential.js.map +1 -1
  45. package/dist/identity/seedStore.d.ts +18 -6
  46. package/dist/identity/seedStore.d.ts.map +1 -1
  47. package/dist/identity/seedStore.js.map +1 -1
  48. package/dist/index.d.ts +2 -2
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +2 -2
  51. package/dist/index.js.map +1 -1
  52. package/dist/react/WasSessionProvider.d.ts.map +1 -1
  53. package/dist/react/WasSessionProvider.js +10 -1
  54. package/dist/react/WasSessionProvider.js.map +1 -1
  55. package/dist/react/hooks.d.ts +10 -5
  56. package/dist/react/hooks.d.ts.map +1 -1
  57. package/dist/react/hooks.js +6 -30
  58. package/dist/react/hooks.js.map +1 -1
  59. package/dist/session/authStore.d.ts +29 -7
  60. package/dist/session/authStore.d.ts.map +1 -1
  61. package/dist/session/authStore.js +125 -64
  62. package/dist/session/authStore.js.map +1 -1
  63. package/dist/storage/entityStore.d.ts +32 -9
  64. package/dist/storage/entityStore.d.ts.map +1 -1
  65. package/dist/storage/entityStore.js +88 -48
  66. package/dist/storage/entityStore.js.map +1 -1
  67. package/dist/storage/localStore.d.ts +53 -0
  68. package/dist/storage/localStore.d.ts.map +1 -1
  69. package/dist/storage/localStore.js +140 -12
  70. package/dist/storage/localStore.js.map +1 -1
  71. package/dist/storage/rehydrate.d.ts +8 -0
  72. package/dist/storage/rehydrate.d.ts.map +1 -1
  73. package/dist/storage/rehydrate.js +31 -2
  74. package/dist/storage/rehydrate.js.map +1 -1
  75. package/dist/storage/syncController.d.ts +7 -3
  76. package/dist/storage/syncController.d.ts.map +1 -1
  77. package/dist/storage/syncController.js +28 -15
  78. package/dist/storage/syncController.js.map +1 -1
  79. package/dist/storage/syncStatusStore.d.ts +26 -1
  80. package/dist/storage/syncStatusStore.d.ts.map +1 -1
  81. package/dist/storage/syncStatusStore.js +40 -0
  82. package/dist/storage/syncStatusStore.js.map +1 -1
  83. package/dist/storage/wasRemoteStore.d.ts +3 -1
  84. package/dist/storage/wasRemoteStore.d.ts.map +1 -1
  85. package/dist/storage/wasRemoteStore.js +3 -3
  86. package/dist/storage/wasRemoteStore.js.map +1 -1
  87. package/dist/sync/feedMasterPort.d.ts +21 -19
  88. package/dist/sync/feedMasterPort.d.ts.map +1 -1
  89. package/dist/sync/feedMasterPort.js +18 -5
  90. package/dist/sync/feedMasterPort.js.map +1 -1
  91. package/dist/sync/index.d.ts +3 -3
  92. package/dist/sync/index.d.ts.map +1 -1
  93. package/dist/sync/index.js +2 -2
  94. package/dist/sync/index.js.map +1 -1
  95. package/dist/sync/lwwConflictHandler.d.ts +35 -2
  96. package/dist/sync/lwwConflictHandler.d.ts.map +1 -1
  97. package/dist/sync/lwwConflictHandler.js +47 -9
  98. package/dist/sync/lwwConflictHandler.js.map +1 -1
  99. package/dist/sync/pushWrites.d.ts +27 -8
  100. package/dist/sync/pushWrites.d.ts.map +1 -1
  101. package/dist/sync/pushWrites.js +43 -15
  102. package/dist/sync/pushWrites.js.map +1 -1
  103. package/dist/sync/types.d.ts +49 -16
  104. package/dist/sync/types.d.ts.map +1 -1
  105. package/dist/sync/types.js +17 -0
  106. package/dist/sync/types.js.map +1 -1
  107. package/dist/sync/wasReplication.d.ts.map +1 -1
  108. package/dist/sync/wasReplication.js +38 -1
  109. package/dist/sync/wasReplication.js.map +1 -1
  110. package/dist/sync/wasSyncPort.d.ts +29 -6
  111. package/dist/sync/wasSyncPort.d.ts.map +1 -1
  112. package/dist/sync/wasSyncPort.js +105 -101
  113. package/dist/sync/wasSyncPort.js.map +1 -1
  114. package/package.json +4 -3
  115. package/dist/auth/verifyResponse.test.d.ts +0 -2
  116. package/dist/auth/verifyResponse.test.d.ts.map +0 -1
  117. package/dist/auth/verifyResponse.test.js +0 -282
  118. package/dist/auth/verifyResponse.test.js.map +0 -1
  119. package/dist/dev/cli.test.d.ts +0 -2
  120. package/dist/dev/cli.test.d.ts.map +0 -1
  121. package/dist/dev/cli.test.js +0 -39
  122. package/dist/dev/cli.test.js.map +0 -1
  123. package/dist/grants.test.d.ts +0 -2
  124. package/dist/grants.test.d.ts.map +0 -1
  125. package/dist/grants.test.js +0 -79
  126. package/dist/grants.test.js.map +0 -1
  127. package/dist/identity/seedCredential.test.d.ts +0 -2
  128. package/dist/identity/seedCredential.test.d.ts.map +0 -1
  129. package/dist/identity/seedCredential.test.js +0 -205
  130. package/dist/identity/seedCredential.test.js.map +0 -1
  131. package/dist/storage/rehydrate.test.d.ts +0 -2
  132. package/dist/storage/rehydrate.test.d.ts.map +0 -1
  133. package/dist/storage/rehydrate.test.js +0 -172
  134. package/dist/storage/rehydrate.test.js.map +0 -1
  135. package/dist/sync/changesQuery.test.d.ts +0 -2
  136. package/dist/sync/changesQuery.test.d.ts.map +0 -1
  137. package/dist/sync/changesQuery.test.js +0 -145
  138. package/dist/sync/changesQuery.test.js.map +0 -1
  139. package/dist/sync/lww.test.d.ts +0 -2
  140. package/dist/sync/lww.test.d.ts.map +0 -1
  141. package/dist/sync/lww.test.js +0 -28
  142. package/dist/sync/lww.test.js.map +0 -1
  143. package/dist/sync/lwwConflictHandler.test.d.ts +0 -2
  144. package/dist/sync/lwwConflictHandler.test.d.ts.map +0 -1
  145. package/dist/sync/lwwConflictHandler.test.js +0 -78
  146. package/dist/sync/lwwConflictHandler.test.js.map +0 -1
  147. package/dist/sync/pushWrites.test.d.ts +0 -2
  148. package/dist/sync/pushWrites.test.d.ts.map +0 -1
  149. package/dist/sync/pushWrites.test.js +0 -287
  150. package/dist/sync/pushWrites.test.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"verifyResponse.test.d.ts","sourceRoot":"","sources":["../../src/auth/verifyResponse.test.ts"],"names":[],"mappings":""}
@@ -1,282 +0,0 @@
1
- /*!
2
- * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
- */
4
- /**
5
- * verifyResponse tests. A mock "wallet" (its own did:key identity, distinct
6
- * from the app's) signs presentations exactly the way freewallet does --
7
- * Ed25519Signature2020 DIDAuth proof over a VP with the app-key VC embedded
8
- * and/or a `zcap` grant array (bare term added to the context) -- and the
9
- * RP-side checks are exercised against good and crafted-bad inputs.
10
- */
11
- import { beforeAll, describe, expect, it } from 'vitest';
12
- import * as vc from '@interop/vc';
13
- import { Ed25519Signature2020 } from '@interop/ed25519-signature';
14
- import { CapabilityAgent } from '@interop/webkms-client';
15
- import { issueSeedCredential } from '../identity/seedCredential.js';
16
- import { createDocumentLoader } from '../identity/documentLoader.js';
17
- import { deriveIdentity } from '../identity/agents.js';
18
- import { checkGrants, grantsOf, verifyLoginPresentation } from './verifyResponse.js';
19
- const ORIGIN = 'http://localhost:5173';
20
- const SERVER_URL = 'http://localhost:3999';
21
- const SPACE_URL = `${SERVER_URL}/space/e2e-space`;
22
- const CONFIG = {
23
- credentialType: 'TestAppKey',
24
- vocabBase: 'urn:test-app:vocab#'
25
- };
26
- const TEST_COLLECTIONS = [
27
- 'action-items',
28
- 'projects',
29
- 'goals',
30
- 'questions',
31
- 'answers',
32
- 'web-links',
33
- 'thoughts',
34
- 'current-focus'
35
- ];
36
- const documentLoader = createDocumentLoader();
37
- const ZCAP_TERM_CONTEXT = {
38
- '@protected': true,
39
- zcap: { '@id': 'urn:freewallet:vocab#zcap', '@container': '@set' }
40
- };
41
- let wallet;
42
- let appDid;
43
- let appSeed;
44
- beforeAll(async () => {
45
- const agent = await CapabilityAgent.fromSeed({
46
- seed: crypto.getRandomValues(new Uint8Array(32)),
47
- handle: 'mock-wallet',
48
- keyName: 'wallet-key'
49
- });
50
- wallet = {
51
- holder: agent.id,
52
- suite: new Ed25519Signature2020({ signer: agent.getSigner() })
53
- };
54
- appSeed = crypto.getRandomValues(new Uint8Array(32));
55
- appDid = (await deriveIdentity({ seed: appSeed })).controllerDid;
56
- });
57
- /** An UNSIGNED structural grant (checkGrants is structural, not cryptographic). */
58
- function grantFor({ collectionId, controller = appDid, expires = new Date(Date.now() + 86_400_000).toISOString(), actions = ['GET', 'HEAD', 'PUT', 'POST', 'DELETE'], spaceUrl = SPACE_URL }) {
59
- return {
60
- '@context': 'https://w3id.org/zcap/v1',
61
- id: `urn:zcap:${crypto.randomUUID()}`,
62
- controller,
63
- parentCapability: `urn:zcap:root:${encodeURIComponent(spaceUrl)}`,
64
- invocationTarget: collectionId ? `${spaceUrl}/${collectionId}` : spaceUrl,
65
- allowedAction: actions,
66
- expires
67
- };
68
- }
69
- /** The full wallet-shaped grant set: RW collection grants + space read. */
70
- function fullGrantSet() {
71
- const grants = TEST_COLLECTIONS.map(id => grantFor({ collectionId: id }));
72
- grants.push(grantFor({ actions: ['GET', 'HEAD'] }));
73
- return grants;
74
- }
75
- /** Signs a wallet-style VP with optional embedded VC and zcap array. */
76
- async function walletVp({ challenge, domain = ORIGIN, credential, zcaps }) {
77
- const presentation = vc.createPresentation({
78
- holder: wallet.holder,
79
- ...(credential && { verifiableCredential: [credential] }),
80
- verify: false,
81
- version: 1.0
82
- });
83
- if (zcaps && zcaps.length > 0) {
84
- const base = presentation['@context'];
85
- presentation['@context'] = [
86
- ...(Array.isArray(base) ? base : [base]),
87
- ZCAP_TERM_CONTEXT
88
- ];
89
- presentation.zcap = zcaps;
90
- }
91
- return (await vc.signPresentation({
92
- presentation: presentation,
93
- challenge,
94
- domain,
95
- documentLoader,
96
- suite: wallet.suite
97
- }));
98
- }
99
- describe('verifyLoginPresentation', () => {
100
- it('accepts a wallet-signed VP with an embedded app key and grants', async () => {
101
- const challenge = crypto.randomUUID();
102
- const credential = await issueSeedCredential({
103
- seed: appSeed,
104
- origin: ORIGIN,
105
- config: CONFIG,
106
- documentLoader
107
- });
108
- const presentation = await walletVp({
109
- challenge,
110
- credential,
111
- zcaps: fullGrantSet()
112
- });
113
- await expect(verifyLoginPresentation({
114
- presentation,
115
- challenge,
116
- domain: ORIGIN,
117
- documentLoader
118
- })).resolves.toBeUndefined();
119
- expect(grantsOf(presentation)).toHaveLength(TEST_COLLECTIONS.length + 1);
120
- });
121
- it('rejects a challenge mismatch', async () => {
122
- const presentation = await walletVp({ challenge: 'sent-nonce' });
123
- await expect(verifyLoginPresentation({
124
- presentation,
125
- challenge: 'other-nonce',
126
- domain: ORIGIN,
127
- documentLoader
128
- })).rejects.toThrow();
129
- });
130
- it('rejects a domain mismatch', async () => {
131
- const challenge = crypto.randomUUID();
132
- const presentation = await walletVp({
133
- challenge,
134
- domain: 'https://evil.example'
135
- });
136
- await expect(verifyLoginPresentation({
137
- presentation,
138
- challenge,
139
- domain: ORIGIN,
140
- documentLoader
141
- })).rejects.toThrow(/domain/);
142
- });
143
- it('rejects a tampered presentation', async () => {
144
- const challenge = crypto.randomUUID();
145
- const presentation = await walletVp({
146
- challenge,
147
- zcaps: fullGrantSet()
148
- });
149
- const tampered = {
150
- ...presentation,
151
- zcap: [
152
- ...presentation.zcap.slice(1),
153
- grantFor({
154
- collectionId: 'injected',
155
- controller: 'did:example:mallory'
156
- })
157
- ]
158
- };
159
- await expect(verifyLoginPresentation({
160
- presentation: tampered,
161
- challenge,
162
- domain: ORIGIN,
163
- documentLoader
164
- })).rejects.toThrow();
165
- });
166
- it('rejects an unsigned presentation', async () => {
167
- const presentation = {
168
- '@context': ['https://www.w3.org/2018/credentials/v1'],
169
- type: ['VerifiablePresentation']
170
- };
171
- await expect(verifyLoginPresentation({
172
- presentation,
173
- challenge: 'x',
174
- domain: ORIGIN,
175
- documentLoader
176
- })).rejects.toThrow();
177
- });
178
- it('rejects a tampered embedded credential', async () => {
179
- const challenge = crypto.randomUUID();
180
- const credential = await issueSeedCredential({
181
- seed: appSeed,
182
- origin: ORIGIN,
183
- config: CONFIG,
184
- documentLoader
185
- });
186
- const subject = credential.credentialSubject;
187
- const tamperedVc = {
188
- ...credential,
189
- credentialSubject: { ...subject, origin: 'https://evil.example' }
190
- };
191
- const presentation = await walletVp({ challenge });
192
- presentation.verifiableCredential =
193
- [tamperedVc];
194
- await expect(verifyLoginPresentation({
195
- presentation,
196
- challenge,
197
- domain: ORIGIN,
198
- documentLoader
199
- })).rejects.toThrow();
200
- });
201
- });
202
- describe('checkGrants', () => {
203
- it('accepts the full wallet grant set and reports topology + expiry', () => {
204
- const soon = new Date(Date.now() + 3_600_000).toISOString();
205
- const later = new Date(Date.now() + 86_400_000).toISOString();
206
- const grants = TEST_COLLECTIONS.map((id, index) => grantFor({ collectionId: id, expires: index === 0 ? soon : later }));
207
- grants.push(grantFor({ actions: ['GET', 'HEAD'], expires: later }));
208
- const checked = checkGrants({
209
- grants,
210
- controllerDid: appDid,
211
- collections: TEST_COLLECTIONS,
212
- expectedServerUrl: SERVER_URL
213
- });
214
- expect(checked.parsed.serverUrl).toBe(SERVER_URL);
215
- expect(checked.parsed.spaceId).toBe('e2e-space');
216
- expect(Object.keys(checked.parsed.byCollectionId)).toHaveLength(TEST_COLLECTIONS.length);
217
- expect(checked.expires).toBe(soon);
218
- });
219
- it('rejects an empty grant set', () => {
220
- expect(() => checkGrants({
221
- grants: [],
222
- controllerDid: appDid,
223
- collections: TEST_COLLECTIONS
224
- })).toThrow(/no storage grants/);
225
- });
226
- it('rejects a grant controlled by another DID', () => {
227
- const grants = fullGrantSet();
228
- grants[0].controller = 'did:example:mallory';
229
- expect(() => checkGrants({
230
- grants,
231
- controllerDid: appDid,
232
- collections: TEST_COLLECTIONS
233
- })).toThrow(/controlled by/);
234
- });
235
- it('rejects an expired grant', () => {
236
- const grants = fullGrantSet();
237
- grants[2].expires = new Date(Date.now() - 1000).toISOString();
238
- expect(() => checkGrants({
239
- grants,
240
- controllerDid: appDid,
241
- collections: TEST_COLLECTIONS
242
- })).toThrow(/expired/);
243
- });
244
- it('rejects a grant set on the wrong server', () => {
245
- expect(() => checkGrants({
246
- grants: fullGrantSet(),
247
- controllerDid: appDid,
248
- collections: TEST_COLLECTIONS,
249
- expectedServerUrl: 'http://localhost:4000'
250
- })).toThrow(/expected/);
251
- });
252
- it('rejects a grant set spanning two spaces', () => {
253
- const grants = fullGrantSet();
254
- grants.push(grantFor({
255
- collectionId: 'projects',
256
- spaceUrl: `${SERVER_URL}/space/other-space`
257
- }));
258
- expect(() => checkGrants({
259
- grants,
260
- controllerDid: appDid,
261
- collections: TEST_COLLECTIONS
262
- })).toThrow(/two spaces/);
263
- });
264
- it('rejects a set missing a collection', () => {
265
- const grants = TEST_COLLECTIONS.slice(1).map(id => grantFor({ collectionId: id }));
266
- expect(() => checkGrants({
267
- grants,
268
- controllerDid: appDid,
269
- collections: TEST_COLLECTIONS
270
- })).toThrow(new RegExp(`No grant covers the "${TEST_COLLECTIONS[0]}"`));
271
- });
272
- it('rejects a collection grant with insufficient actions', () => {
273
- const grants = fullGrantSet();
274
- grants[0].allowedAction = ['GET', 'HEAD'];
275
- expect(() => checkGrants({
276
- grants,
277
- controllerDid: appDid,
278
- collections: TEST_COLLECTIONS
279
- })).toThrow(/lacks required actions/);
280
- });
281
- });
282
- //# sourceMappingURL=verifyResponse.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"verifyResponse.test.js","sourceRoot":"","sources":["../../src/auth/verifyResponse.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=cli.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli.test.d.ts","sourceRoot":"","sources":["../../src/dev/cli.test.ts"],"names":[],"mappings":""}
@@ -1,39 +0,0 @@
1
- /*!
2
- * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
- */
4
- import { describe, it, expect } from 'vitest';
5
- import { parseSeed, parseCollections } from './cli.js';
6
- describe('parseSeed', () => {
7
- it('decodes a hex seed to raw bytes', () => {
8
- // "life-advisor-dev-seed-0123456789" as hex (32 bytes).
9
- const hex = '6c6966652d6164766973';
10
- expect(Array.from(parseSeed(hex))).toEqual([
11
- 0x6c, 0x69, 0x66, 0x65, 0x2d, 0x61, 0x64, 0x76, 0x69, 0x73
12
- ]);
13
- });
14
- it('decodes uppercase hex', () => {
15
- expect(Array.from(parseSeed('DEADBEEF'))).toEqual([0xde, 0xad, 0xbe, 0xef]);
16
- });
17
- it('decodes a base64url seed to raw bytes', () => {
18
- // Bytes [0xfb, 0xff, 0xbf] encode as base64url "-_-_" (uses - and _).
19
- expect(Array.from(parseSeed('-_-_'))).toEqual([0xfb, 0xff, 0xbf]);
20
- });
21
- it('trims surrounding whitespace', () => {
22
- expect(Array.from(parseSeed(' deadbeef '))).toEqual([
23
- 0xde, 0xad, 0xbe, 0xef
24
- ]);
25
- });
26
- });
27
- describe('parseCollections', () => {
28
- it('splits a comma-separated list', () => {
29
- expect(parseCollections('action-items,projects,goals')).toEqual([
30
- 'action-items',
31
- 'projects',
32
- 'goals'
33
- ]);
34
- });
35
- it('trims and drops empty entries', () => {
36
- expect(parseCollections(' a , , b ,')).toEqual(['a', 'b']);
37
- });
38
- });
39
- //# sourceMappingURL=cli.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli.test.js","sourceRoot":"","sources":["../../src/dev/cli.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAEtD,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,wDAAwD;QACxD,MAAM,GAAG,GAAG,sBAAsB,CAAA;QAClC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YACzC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;SAC3D,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAA;IAC7E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,sEAAsE;QACtE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAA;IACnE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YACpD,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;SACvB,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,gBAAgB,CAAC,6BAA6B,CAAC,CAAC,CAAC,OAAO,CAAC;YAC9D,cAAc;YACd,UAAU;YACV,OAAO;SACR,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;IAC5D,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=grants.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"grants.test.d.ts","sourceRoot":"","sources":["../src/grants.test.ts"],"names":[],"mappings":""}
@@ -1,79 +0,0 @@
1
- /*!
2
- * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
- */
4
- import { describe, it, expect } from 'vitest';
5
- import { parseGrants, parseInvocationTarget } from './grants.js';
6
- /** Minimal delegated-zcap stub carrying just the fields `parseGrants` reads. */
7
- function grant(invocationTarget) {
8
- return {
9
- '@context': ['https://w3id.org/zcap/v1'],
10
- id: `urn:uuid:${invocationTarget}`,
11
- parentCapability: 'urn:zcap:root:x',
12
- controller: 'did:key:zApp',
13
- invocationTarget,
14
- allowedAction: ['GET', 'PUT'],
15
- expires: '2099-01-01T00:00:00Z',
16
- proof: {}
17
- };
18
- }
19
- describe('parseInvocationTarget', () => {
20
- it('splits a collection target into origin, space, collection', () => {
21
- const parsed = parseInvocationTarget('http://localhost:3002/space/abc123/action-items');
22
- expect(parsed).toEqual({
23
- serverUrl: 'http://localhost:3002',
24
- spaceId: 'abc123',
25
- collectionId: 'action-items'
26
- });
27
- });
28
- it('tolerates a trailing slash and omits collection on a space target', () => {
29
- const parsed = parseInvocationTarget('https://was.example/space/s1/');
30
- expect(parsed.serverUrl).toBe('https://was.example');
31
- expect(parsed.spaceId).toBe('s1');
32
- expect(parsed.collectionId).toBeUndefined();
33
- });
34
- it('rejects a non-WAS URL', () => {
35
- expect(() => parseInvocationTarget('http://x/not-a-space/y')).toThrow();
36
- expect(() => parseInvocationTarget('not-a-url')).toThrow();
37
- });
38
- });
39
- describe('parseGrants', () => {
40
- it('routes per-collection grants and derives one server + space', () => {
41
- const parsed = parseGrants([
42
- grant('http://localhost:3002/space/abc/action-items'),
43
- grant('http://localhost:3002/space/abc/projects'),
44
- grant('http://localhost:3002/space/abc/current-focus')
45
- ]);
46
- expect(parsed.serverUrl).toBe('http://localhost:3002');
47
- expect(parsed.spaceId).toBe('abc');
48
- expect(Object.keys(parsed.byCollectionId).sort()).toEqual([
49
- 'action-items',
50
- 'current-focus',
51
- 'projects'
52
- ]);
53
- expect(parsed.byCollectionId['action-items']?.invocationTarget).toBe('http://localhost:3002/space/abc/action-items');
54
- });
55
- it('includes a space-scoped grant in topology but not routing', () => {
56
- const parsed = parseGrants([
57
- grant('http://localhost:3002/space/abc/'),
58
- grant('http://localhost:3002/space/abc/goals')
59
- ]);
60
- expect(parsed.spaceId).toBe('abc');
61
- expect(Object.keys(parsed.byCollectionId)).toEqual(['goals']);
62
- });
63
- it('rejects grants spanning two servers', () => {
64
- expect(() => parseGrants([
65
- grant('http://localhost:3002/space/abc/goals'),
66
- grant('http://localhost:4000/space/abc/projects')
67
- ])).toThrow(/two servers/);
68
- });
69
- it('rejects grants spanning two spaces', () => {
70
- expect(() => parseGrants([
71
- grant('http://localhost:3002/space/abc/goals'),
72
- grant('http://localhost:3002/space/def/projects')
73
- ])).toThrow(/two spaces/);
74
- });
75
- it('rejects an empty grant set', () => {
76
- expect(() => parseGrants([])).toThrow();
77
- });
78
- });
79
- //# sourceMappingURL=grants.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"grants.test.js","sourceRoot":"","sources":["../src/grants.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=seedCredential.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"seedCredential.test.d.ts","sourceRoot":"","sources":["../../src/identity/seedCredential.test.ts"],"names":[],"mappings":""}
@@ -1,205 +0,0 @@
1
- /*!
2
- * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
- */
4
- /**
5
- * Seed-credential tests: issue/parse round trip, the self-issue / origin /
6
- * seed-to-DID structural contract, and cryptographic verifiability of the
7
- * issued credential.
8
- */
9
- import { describe, expect, it } from 'vitest';
10
- import { verifyCredential } from '@interop/verifier-core';
11
- import { base64urlToBytes, bytesToBase64url, findSeedCredential, issueSeedCredential, parseSeedCredential, wrapCredentialForStore } from './seedCredential.js';
12
- import { createDocumentLoader } from './documentLoader.js';
13
- import { deriveIdentity } from './agents.js';
14
- const ORIGIN = 'http://localhost:5173';
15
- const CONFIG = {
16
- credentialType: 'TestAppKey',
17
- vocabBase: 'urn:test-app:vocab#'
18
- };
19
- const documentLoader = createDocumentLoader();
20
- function randomSeed() {
21
- return crypto.getRandomValues(new Uint8Array(32));
22
- }
23
- describe('base64url helpers', () => {
24
- it('round-trips arbitrary bytes', () => {
25
- const bytes = randomSeed();
26
- expect(base64urlToBytes(bytesToBase64url(bytes))).toEqual(bytes);
27
- });
28
- it('produces no padding or unsafe characters', () => {
29
- const encoded = bytesToBase64url(randomSeed());
30
- expect(encoded).toMatch(/^[A-Za-z0-9_-]+$/);
31
- });
32
- });
33
- describe('issueSeedCredential', () => {
34
- it('issues a self-issued app key bound to the seed-derived DID', async () => {
35
- const seed = randomSeed();
36
- const { controllerDid } = await deriveIdentity({ seed });
37
- const credential = await issueSeedCredential({
38
- seed,
39
- origin: ORIGIN,
40
- config: CONFIG,
41
- documentLoader
42
- });
43
- expect(credential.type).toContain(CONFIG.credentialType);
44
- expect(credential.issuer).toBe(controllerDid);
45
- const subject = credential.credentialSubject;
46
- expect(subject.id).toBe(controllerDid);
47
- expect(subject.origin).toBe(ORIGIN);
48
- expect(base64urlToBytes(subject.seed)).toEqual(seed);
49
- expect(credential.proof).toBeDefined();
50
- });
51
- it('issues a cryptographically verifiable credential', async () => {
52
- const credential = await issueSeedCredential({
53
- seed: randomSeed(),
54
- origin: ORIGIN,
55
- config: CONFIG,
56
- documentLoader
57
- });
58
- const result = await verifyCredential({
59
- credential,
60
- registries: [],
61
- documentLoader
62
- });
63
- expect(result.verified).toBe(true);
64
- });
65
- it('rejects a seed that is not 32 bytes', async () => {
66
- await expect(issueSeedCredential({
67
- seed: new Uint8Array(16),
68
- origin: ORIGIN,
69
- config: CONFIG,
70
- documentLoader
71
- })).rejects.toThrow(/32 bytes/);
72
- });
73
- });
74
- describe('parseSeedCredential', () => {
75
- it('round-trips the seed and controller DID', async () => {
76
- const seed = randomSeed();
77
- const { controllerDid } = await deriveIdentity({ seed });
78
- const credential = await issueSeedCredential({
79
- seed,
80
- origin: ORIGIN,
81
- config: CONFIG,
82
- documentLoader
83
- });
84
- const parsed = await parseSeedCredential({
85
- credential,
86
- origin: ORIGIN,
87
- config: CONFIG
88
- });
89
- expect(parsed.seed).toEqual(seed);
90
- expect(parsed.controllerDid).toBe(controllerDid);
91
- });
92
- it('rejects an origin mismatch', async () => {
93
- const credential = await issueSeedCredential({
94
- seed: randomSeed(),
95
- origin: 'https://evil.example',
96
- config: CONFIG,
97
- documentLoader
98
- });
99
- await expect(parseSeedCredential({ credential, origin: ORIGIN, config: CONFIG })).rejects.toThrow(/origin/);
100
- });
101
- it('rejects a non-self-issued credential', async () => {
102
- const credential = await issueSeedCredential({
103
- seed: randomSeed(),
104
- origin: ORIGIN,
105
- config: CONFIG,
106
- documentLoader
107
- });
108
- const tampered = {
109
- ...credential,
110
- issuer: 'did:key:z6MkfDbczcXk3XiivKp9kJvBGnBcyhrbsmLAjLgyDJnYCyj4'
111
- };
112
- await expect(parseSeedCredential({
113
- credential: tampered,
114
- origin: ORIGIN,
115
- config: CONFIG
116
- })).rejects.toThrow(/self-issued/);
117
- });
118
- it('rejects a credential whose seed does not derive its subject DID', async () => {
119
- const credential = await issueSeedCredential({
120
- seed: randomSeed(),
121
- origin: ORIGIN,
122
- config: CONFIG,
123
- documentLoader
124
- });
125
- const subject = credential.credentialSubject;
126
- const tampered = {
127
- ...credential,
128
- credentialSubject: {
129
- ...subject,
130
- seed: bytesToBase64url(randomSeed())
131
- }
132
- };
133
- await expect(parseSeedCredential({
134
- credential: tampered,
135
- origin: ORIGIN,
136
- config: CONFIG
137
- })).rejects.toThrow(/does not derive/);
138
- });
139
- it('rejects the wrong credential type', async () => {
140
- const credential = {
141
- '@context': ['https://www.w3.org/2018/credentials/v1'],
142
- type: ['VerifiableCredential'],
143
- issuer: 'did:example:x',
144
- credentialSubject: { id: 'did:example:x' }
145
- };
146
- await expect(parseSeedCredential({ credential, origin: ORIGIN, config: CONFIG })).rejects.toThrow(/not a TestAppKey/);
147
- });
148
- it('rejects a malformed seed', async () => {
149
- const credential = await issueSeedCredential({
150
- seed: randomSeed(),
151
- origin: ORIGIN,
152
- config: CONFIG,
153
- documentLoader
154
- });
155
- const subject = credential.credentialSubject;
156
- const tampered = {
157
- ...credential,
158
- credentialSubject: {
159
- ...subject,
160
- seed: bytesToBase64url(new Uint8Array(8))
161
- }
162
- };
163
- await expect(parseSeedCredential({
164
- credential: tampered,
165
- origin: ORIGIN,
166
- config: CONFIG
167
- })).rejects.toThrow(/32 bytes/);
168
- });
169
- });
170
- describe('findSeedCredential / wrapCredentialForStore', () => {
171
- it('finds the app key inside a VP and ignores other credentials', async () => {
172
- const credential = await issueSeedCredential({
173
- seed: randomSeed(),
174
- origin: ORIGIN,
175
- config: CONFIG,
176
- documentLoader
177
- });
178
- const other = {
179
- '@context': ['https://www.w3.org/2018/credentials/v1'],
180
- type: ['VerifiableCredential'],
181
- issuer: 'did:example:x',
182
- credentialSubject: {}
183
- };
184
- const vp = wrapCredentialForStore(credential);
185
- vp.verifiableCredential = [
186
- other,
187
- credential
188
- ];
189
- expect(findSeedCredential({
190
- presentation: vp,
191
- credentialType: CONFIG.credentialType
192
- })).toBe(credential);
193
- });
194
- it('returns null when the VP carries no app key (first-run signal)', () => {
195
- const vp = {
196
- '@context': ['https://www.w3.org/2018/credentials/v1'],
197
- type: ['VerifiablePresentation']
198
- };
199
- expect(findSeedCredential({
200
- presentation: vp,
201
- credentialType: CONFIG.credentialType
202
- })).toBeNull();
203
- });
204
- });
205
- //# sourceMappingURL=seedCredential.test.js.map