@interop/was-conformance-suite 0.2.0 → 0.3.1

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 (69) hide show
  1. package/dist/suites/authz-ordering-api.d.ts +9 -0
  2. package/dist/suites/authz-ordering-api.d.ts.map +1 -0
  3. package/dist/suites/authz-ordering-api.js +286 -0
  4. package/dist/suites/authz-ordering-api.js.map +1 -0
  5. package/dist/suites/blinded-index-api.d.ts +11 -0
  6. package/dist/suites/blinded-index-api.d.ts.map +1 -0
  7. package/dist/suites/blinded-index-api.js +468 -0
  8. package/dist/suites/blinded-index-api.js.map +1 -0
  9. package/dist/suites/changes-query-api.d.ts.map +1 -1
  10. package/dist/suites/changes-query-api.js +61 -0
  11. package/dist/suites/changes-query-api.js.map +1 -1
  12. package/dist/suites/chunks-api.d.ts +27 -0
  13. package/dist/suites/chunks-api.d.ts.map +1 -0
  14. package/dist/suites/chunks-api.js +613 -0
  15. package/dist/suites/chunks-api.js.map +1 -0
  16. package/dist/suites/client-backends.d.ts.map +1 -1
  17. package/dist/suites/client-backends.js +23 -0
  18. package/dist/suites/client-backends.js.map +1 -1
  19. package/dist/suites/client-delegation.d.ts.map +1 -1
  20. package/dist/suites/client-delegation.js +12 -0
  21. package/dist/suites/client-delegation.js.map +1 -1
  22. package/dist/suites/client-export-import.d.ts.map +1 -1
  23. package/dist/suites/client-export-import.js +1 -0
  24. package/dist/suites/client-export-import.js.map +1 -1
  25. package/dist/suites/client-resources.d.ts.map +1 -1
  26. package/dist/suites/client-resources.js +30 -0
  27. package/dist/suites/client-resources.js.map +1 -1
  28. package/dist/suites/client-spaces.d.ts.map +1 -1
  29. package/dist/suites/client-spaces.js +27 -0
  30. package/dist/suites/client-spaces.js.map +1 -1
  31. package/dist/suites/collection-api.d.ts.map +1 -1
  32. package/dist/suites/collection-api.js +151 -0
  33. package/dist/suites/collection-api.js.map +1 -1
  34. package/dist/suites/conditional-requests-api.d.ts +11 -0
  35. package/dist/suites/conditional-requests-api.d.ts.map +1 -0
  36. package/dist/suites/conditional-requests-api.js +444 -0
  37. package/dist/suites/conditional-requests-api.js.map +1 -0
  38. package/dist/suites/digest-api.d.ts +7 -0
  39. package/dist/suites/digest-api.d.ts.map +1 -0
  40. package/dist/suites/digest-api.js +157 -0
  41. package/dist/suites/digest-api.js.map +1 -0
  42. package/dist/suites/encryption-marker-api.d.ts.map +1 -1
  43. package/dist/suites/encryption-marker-api.js +132 -8
  44. package/dist/suites/encryption-marker-api.js.map +1 -1
  45. package/dist/suites/index.d.ts +8 -1
  46. package/dist/suites/index.d.ts.map +1 -1
  47. package/dist/suites/index.js +16 -2
  48. package/dist/suites/index.js.map +1 -1
  49. package/dist/suites/invocation-target-api.d.ts +12 -0
  50. package/dist/suites/invocation-target-api.d.ts.map +1 -0
  51. package/dist/suites/invocation-target-api.js +252 -0
  52. package/dist/suites/invocation-target-api.js.map +1 -0
  53. package/dist/suites/policy-api.d.ts.map +1 -1
  54. package/dist/suites/policy-api.js +23 -0
  55. package/dist/suites/policy-api.js.map +1 -1
  56. package/dist/suites/resource-api.d.ts.map +1 -1
  57. package/dist/suites/resource-api.js +269 -0
  58. package/dist/suites/resource-api.js.map +1 -1
  59. package/dist/suites/server.d.ts.map +1 -1
  60. package/dist/suites/server.js +1 -0
  61. package/dist/suites/server.js.map +1 -1
  62. package/dist/suites/spaces-api.d.ts.map +1 -1
  63. package/dist/suites/spaces-api.js +579 -1
  64. package/dist/suites/spaces-api.js.map +1 -1
  65. package/dist/suites/write-validation-api.d.ts +7 -0
  66. package/dist/suites/write-validation-api.d.ts.map +1 -0
  67. package/dist/suites/write-validation-api.js +186 -0
  68. package/dist/suites/write-validation-api.js.map +1 -0
  69. package/package.json +5 -3
@@ -0,0 +1,613 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * WAS conformance tests -- Chunked Resources (the `chunked-streams` feature).
6
+ *
7
+ * Chunked Resources are an OPTIONAL feature (spec "Chunked Resources"), gated on
8
+ * a backend advertising the `chunked-streams` token in its Backend description.
9
+ * Rather than mark the whole suite optional, setup() probes the Space's backend
10
+ * list for that token and stashes the result; each test skips when the feature
11
+ * is absent. Once a backend advertises `chunked-streams` the behaviors below are
12
+ * MUST-level, so the tests run at the required tier.
13
+ *
14
+ * A chunk is addressed at
15
+ * `/space/{space}/{collection}/{resource}/chunks/{index}` in member form and
16
+ * `.../chunks/` in container form. A chunk body is opaque bytes plus a content
17
+ * type -- the server stores it exactly like a binary Resource representation and
18
+ * never parses it (framing and any client-side encryption are the client's
19
+ * concern). The parent Resource MUST already exist before any chunk is written.
20
+ */
21
+ import { signCapabilityInvocation } from '@interop/http-signature-zcap-invoke';
22
+ import assert from '../harness/assert.js';
23
+ /**
24
+ * A minimal conforming EDV Encrypted Document, the stored representation an
25
+ * `edv` (encrypted) Collection requires for a Resource's own content. Reused as
26
+ * the parent-Resource body when exercising the "chunk bodies are never parsed,
27
+ * even under an encryption marker" rule.
28
+ */
29
+ const edvDocument = {
30
+ id: 'stream-parent',
31
+ sequence: 0,
32
+ indexed: [],
33
+ jwe: { protected: 'eyJhbGciOiJkaXI', ciphertext: 'c1phertext' }
34
+ };
35
+ /**
36
+ * Signs and sends a raw chunk write against an arbitrary URL with an arbitrary
37
+ * capability -- the mismatched-target invocation a well-behaved client refuses
38
+ * to build (ezcap's confused-deputy guard), so the bytes are signed with the
39
+ * low-level `signCapabilityInvocation` primitive and sent via raw `fetch`.
40
+ *
41
+ * @param options {object}
42
+ * @param options.url {string} the request URL to invoke against
43
+ * @param options.capability {IZcap} the delegated capability to embed
44
+ * @param options.body {Uint8Array} the raw chunk bytes
45
+ * @param options.invocationSigner {ISigner} the invoker's signer
46
+ * @returns {Promise<Response>}
47
+ */
48
+ async function writeChunkAt({ url, capability, body, invocationSigner }) {
49
+ const signatureHeaders = await signCapabilityInvocation({
50
+ url,
51
+ method: 'PUT',
52
+ headers: { date: new Date().toUTCString() },
53
+ invocationSigner,
54
+ capability,
55
+ capabilityAction: 'PUT',
56
+ body
57
+ });
58
+ // Send the exact signed bytes -- fetch's `BodyInit` typing rejects a bare
59
+ // `Uint8Array<ArrayBufferLike>` (a lib variance quirk), so cast; the explicit
60
+ // `content-type` set in `signatureHeaders` stands.
61
+ return fetch(url, {
62
+ method: 'PUT',
63
+ headers: signatureHeaders,
64
+ body: body
65
+ });
66
+ }
67
+ /**
68
+ * Resolves a signed request to its HTTP status and (for a problem response) its
69
+ * error `type`, whether the underlying client fulfills or rejects. The ezcap
70
+ * client throws on a non-2xx, carrying the status and parsed body on the error.
71
+ *
72
+ * @param promise {Promise<any>} a signed-request promise
73
+ * @returns {Promise<{ status: number; type?: string }>}
74
+ */
75
+ async function resolveStatus(promise) {
76
+ try {
77
+ const response = await promise;
78
+ return { status: response.status, type: response.data?.type };
79
+ }
80
+ catch (err) {
81
+ return {
82
+ status: err.response?.status ?? err.status ?? 0,
83
+ type: err.data?.type
84
+ };
85
+ }
86
+ }
87
+ export const chunksApi = {
88
+ id: 'chunks-api',
89
+ name: 'Chunked Resources API',
90
+ specRefs: ['https://wallet.storage/spec#chunked-resources'],
91
+ setup: async (ctx) => {
92
+ const alice = { ...ctx.actors.alice };
93
+ const bob = { ...ctx.actors.bob };
94
+ alice.space1 = { id: ctx.generateId() };
95
+ await ctx.createSpace({
96
+ spaceDescription: {
97
+ id: alice.space1.id,
98
+ name: "Alice's Chunk Space",
99
+ controller: alice.did
100
+ },
101
+ rootClient: alice.rootClient
102
+ });
103
+ function chunkUrl({ collectionId, resourceId, index }) {
104
+ return new URL(`/space/${alice.space1.id}/${collectionId}/${resourceId}/chunks/${index}`, ctx.serverUrl).toString();
105
+ }
106
+ function chunksListUrl({ collectionId, resourceId }) {
107
+ return new URL(`/space/${alice.space1.id}/${collectionId}/${resourceId}/chunks/`, ctx.serverUrl).toString();
108
+ }
109
+ function resourceUrl({ collectionId, resourceId }) {
110
+ return new URL(`/space/${alice.space1.id}/${collectionId}/${resourceId}`, ctx.serverUrl).toString();
111
+ }
112
+ // A plaintext Collection for the bulk of the round-trip cases.
113
+ await alice.rootClient.request({
114
+ url: new URL(`/space/${alice.space1.id}/`, ctx.serverUrl).toString(),
115
+ method: 'POST',
116
+ action: 'POST',
117
+ json: { id: 'data', name: 'Chunked Data' }
118
+ });
119
+ // An encrypted (`edv`) Collection for the "chunk bytes are never parsed,
120
+ // even under an encryption marker" rule.
121
+ await alice.rootClient.request({
122
+ url: new URL(`/space/${alice.space1.id}/`, ctx.serverUrl).toString(),
123
+ method: 'POST',
124
+ action: 'POST',
125
+ json: { id: 'vault', name: 'Vault', encryption: { scheme: 'edv' } }
126
+ });
127
+ // Discover whether any of the Space's backends advertises `chunked-streams`
128
+ // (spec "Backends"). Absent the token the endpoints are OPTIONAL and each
129
+ // test skips.
130
+ const backendsResponse = await alice.rootClient.request({
131
+ url: new URL(`/space/${alice.space1.id}/backends`, ctx.serverUrl).toString(),
132
+ method: 'GET'
133
+ });
134
+ const backends = Array.isArray(backendsResponse.data)
135
+ ? backendsResponse.data
136
+ : (backendsResponse.data?.backends ?? []);
137
+ const chunkedSupported = backends.some(backend => backend.features?.includes('chunked-streams'));
138
+ async function createParent(resourceId) {
139
+ await alice.rootClient.request({
140
+ url: resourceUrl({ collectionId: 'data', resourceId }),
141
+ method: 'PUT',
142
+ action: 'PUT',
143
+ json: { id: resourceId, name: 'Parent Manifest' }
144
+ });
145
+ }
146
+ return {
147
+ alice,
148
+ bob,
149
+ chunkedSupported,
150
+ chunkUrl,
151
+ chunksListUrl,
152
+ resourceUrl,
153
+ createParent
154
+ };
155
+ },
156
+ teardown: async (ctx, state) => {
157
+ const { alice } = state;
158
+ try {
159
+ await alice.rootClient.request({
160
+ url: new URL(`/space/${alice.space1.id}`, ctx.serverUrl).toString(),
161
+ method: 'DELETE'
162
+ });
163
+ }
164
+ catch {
165
+ /* best-effort cleanup */
166
+ }
167
+ },
168
+ tests: [
169
+ {
170
+ id: 'chunks.roundtrip-put-get-head-delete',
171
+ name: '[root] PUT / GET / HEAD / DELETE a raw octet-stream chunk round-trips',
172
+ specRefs: [
173
+ 'https://wallet.storage/spec#store-chunk-operation',
174
+ 'https://wallet.storage/spec#read-chunk-operation',
175
+ 'https://wallet.storage/spec#delete-chunk-operation'
176
+ ],
177
+ run: async (ctx, state) => {
178
+ const { alice, chunkUrl, chunkedSupported, createParent } = state;
179
+ if (!chunkedSupported) {
180
+ ctx.skip('backend does not advertise chunked-streams');
181
+ }
182
+ const resourceId = 'binary-blob';
183
+ await createParent(resourceId);
184
+ const url = chunkUrl({ collectionId: 'data', resourceId, index: 0 });
185
+ const bytes = new Uint8Array([0, 1, 2, 253, 254, 255]);
186
+ // Store: raw bytes upsert returns 204 carrying the chunk's own ETag.
187
+ const putResponse = await alice.rootClient.request({
188
+ url,
189
+ method: 'PUT',
190
+ action: 'PUT',
191
+ body: bytes
192
+ });
193
+ assert.equal(putResponse.status, 204);
194
+ assert.ok(putResponse.headers.get('etag'), 'expected the chunk write to return an ETag');
195
+ // Read: the exact stored bytes come back under their stored content
196
+ // type (a byte-array body is stored as application/octet-stream).
197
+ const getResponse = await alice.rootClient.request({
198
+ url,
199
+ method: 'GET'
200
+ });
201
+ assert.equal(getResponse.status, 200);
202
+ assert.match(getResponse.headers.get('content-type') ?? '', /application\/octet-stream/);
203
+ assert.deepEqual(new Uint8Array(await getResponse.arrayBuffer()), bytes);
204
+ // Head: the same payload headers, no body.
205
+ const headResponse = await alice.rootClient.request({
206
+ url,
207
+ method: 'HEAD'
208
+ });
209
+ assert.equal(headResponse.status, 200);
210
+ assert.match(headResponse.headers.get('content-type') ?? '', /application\/octet-stream/);
211
+ assert.equal(headResponse.headers.get('content-length'), String(bytes.length));
212
+ assert.equal(await headResponse.text(), '');
213
+ // Delete: 204, and the chunk is then gone (a later read is 404).
214
+ const deleteResponse = await alice.rootClient.request({
215
+ url,
216
+ method: 'DELETE'
217
+ });
218
+ assert.equal(deleteResponse.status, 204);
219
+ assert.equal((await resolveStatus(alice.rootClient.request({ url, method: 'GET' }))).status, 404);
220
+ }
221
+ },
222
+ {
223
+ id: 'chunks.non-canonical-index-invalid-id',
224
+ name: '[root] a non-canonical {index} is rejected with 400 invalid-id',
225
+ specRefs: [
226
+ 'https://wallet.storage/spec#the-chunk-address',
227
+ 'https://wallet.storage/spec#invalid-id'
228
+ ],
229
+ run: async (ctx, state) => {
230
+ const { alice, chunkUrl, chunkedSupported, createParent } = state;
231
+ if (!chunkedSupported) {
232
+ ctx.skip('backend does not advertise chunked-streams');
233
+ }
234
+ const resourceId = 'bad-index';
235
+ await createParent(resourceId);
236
+ // The `{index}` segment MUST be a canonical non-negative decimal: a
237
+ // leading zero, a sign, or a non-integer spelling is rejected up front
238
+ // with invalid-id (400), on both the read and the write path.
239
+ for (const badIndex of ['01', '+1', '-1', '1.5']) {
240
+ const readResult = await resolveStatus(alice.rootClient.request({
241
+ url: chunkUrl({
242
+ collectionId: 'data',
243
+ resourceId,
244
+ index: badIndex
245
+ }),
246
+ method: 'GET'
247
+ }));
248
+ assert.equal(readResult.status, 400, `expected 400 reading chunk index "${badIndex}"`);
249
+ assert.equal(readResult.type, 'https://wallet.storage/spec#invalid-id', `expected invalid-id for chunk index "${badIndex}"`);
250
+ }
251
+ // The write path rejects the same way (invalid-id runs before storage).
252
+ const writeResult = await resolveStatus(alice.rootClient.request({
253
+ url: chunkUrl({ collectionId: 'data', resourceId, index: '01' }),
254
+ method: 'PUT',
255
+ action: 'PUT',
256
+ body: new Uint8Array([1])
257
+ }));
258
+ assert.equal(writeResult.status, 400);
259
+ assert.equal(writeResult.type, 'https://wallet.storage/spec#invalid-id');
260
+ }
261
+ },
262
+ {
263
+ id: 'chunks.opaque-body-not-parsed',
264
+ name: '[root] a chunk body is stored verbatim and never parsed, even under an encryption marker',
265
+ specRefs: [
266
+ 'https://wallet.storage/spec#store-chunk-operation',
267
+ 'https://wallet.storage/spec#read-chunk-operation'
268
+ ],
269
+ run: async (ctx, state) => {
270
+ const { alice, chunkUrl, resourceUrl, chunkedSupported } = state;
271
+ if (!chunkedSupported) {
272
+ ctx.skip('backend does not advertise chunked-streams');
273
+ }
274
+ // The parent Resource lives in the encrypted `vault` Collection, so its
275
+ // own content MUST be a conforming EDV envelope...
276
+ const resourceId = 'stream-parent';
277
+ await alice.rootClient.request({
278
+ url: resourceUrl({ collectionId: 'vault', resourceId }),
279
+ method: 'PUT',
280
+ action: 'PUT',
281
+ body: new TextEncoder().encode(JSON.stringify(edvDocument)),
282
+ headers: { 'content-type': 'application/json' }
283
+ });
284
+ // ...but the scheme's envelope validation MUST NOT apply to a chunk: a
285
+ // chunk of an encrypted stream is a ciphertext fragment, not an
286
+ // envelope document. Bytes that are not even valid JSON are accepted
287
+ // verbatim and round-trip byte-identical.
288
+ const nonJson = new TextEncoder().encode('{ this is ] not json <<<');
289
+ const url = chunkUrl({ collectionId: 'vault', resourceId, index: 0 });
290
+ const putResponse = await alice.rootClient.request({
291
+ url,
292
+ method: 'PUT',
293
+ action: 'PUT',
294
+ body: nonJson
295
+ });
296
+ assert.equal(putResponse.status, 204, 'a non-JSON chunk MUST be accepted even in an encrypted Collection');
297
+ const getResponse = await alice.rootClient.request({
298
+ url,
299
+ method: 'GET'
300
+ });
301
+ assert.equal(getResponse.status, 200);
302
+ assert.deepEqual(new Uint8Array(await getResponse.arrayBuffer()), nonJson);
303
+ }
304
+ },
305
+ {
306
+ id: 'chunks.put-missing-parent-404',
307
+ name: '[root] a chunk PUT to a missing parent Resource is rejected with 404',
308
+ specRefs: ['https://wallet.storage/spec#store-chunk-operation'],
309
+ run: async (ctx, state) => {
310
+ const { alice, chunkUrl, chunkedSupported } = state;
311
+ if (!chunkedSupported) {
312
+ ctx.skip('backend does not advertise chunked-streams');
313
+ }
314
+ // No parent Resource was created: the parent MUST already exist, so a
315
+ // chunk can never be orphaned.
316
+ const result = await resolveStatus(alice.rootClient.request({
317
+ url: chunkUrl({
318
+ collectionId: 'data',
319
+ resourceId: 'never-created',
320
+ index: 0
321
+ }),
322
+ method: 'PUT',
323
+ action: 'PUT',
324
+ body: new Uint8Array([9])
325
+ }));
326
+ assert.equal(result.status, 404);
327
+ }
328
+ },
329
+ {
330
+ id: 'chunks.delete-absent-not-idempotent',
331
+ name: '[root] deleting an absent chunk is 404 (not idempotent), unlike Delete Resource',
332
+ specRefs: ['https://wallet.storage/spec#delete-chunk-operation'],
333
+ run: async (ctx, state) => {
334
+ const { alice, chunkUrl, chunkedSupported, createParent } = state;
335
+ if (!chunkedSupported) {
336
+ ctx.skip('backend does not advertise chunked-streams');
337
+ }
338
+ const resourceId = 'delete-absent';
339
+ await createParent(resourceId);
340
+ // Unlike a Resource delete, a chunk delete is deliberately not
341
+ // idempotent: deleting a chunk that was never written is a 404, so a
342
+ // reassembling reader can tell "gone" from "never written".
343
+ const result = await resolveStatus(alice.rootClient.request({
344
+ url: chunkUrl({ collectionId: 'data', resourceId, index: 0 }),
345
+ method: 'DELETE'
346
+ }));
347
+ assert.equal(result.status, 404);
348
+ }
349
+ },
350
+ {
351
+ id: 'chunks.list-reflects-stored-and-empty',
352
+ name: '[root] the chunk listing reports stored chunks in index order, and count 0 once emptied',
353
+ specRefs: ['https://wallet.storage/spec#list-chunks-operation'],
354
+ run: async (ctx, state) => {
355
+ const { alice, chunkUrl, chunksListUrl, chunkedSupported, createParent } = state;
356
+ if (!chunkedSupported) {
357
+ ctx.skip('backend does not advertise chunked-streams');
358
+ }
359
+ const resourceId = 'multi-chunk';
360
+ await createParent(resourceId);
361
+ const listUrl = chunksListUrl({ collectionId: 'data', resourceId });
362
+ // A Resource that exists but has no chunks lists as count 0.
363
+ const emptyListing = await alice.rootClient.request({
364
+ url: listUrl,
365
+ method: 'GET'
366
+ });
367
+ assert.equal(emptyListing.status, 200);
368
+ assert.match(emptyListing.headers.get('content-type') ?? '', /application\/json/);
369
+ assert.equal(emptyListing.data.resourceId, resourceId);
370
+ assert.equal(emptyListing.data.count, 0);
371
+ assert.deepEqual(emptyListing.data.chunks, []);
372
+ // Write three chunks out of order to prove the listing sorts by index.
373
+ const chunkBytes = [
374
+ new Uint8Array([1]),
375
+ new Uint8Array([2, 2]),
376
+ new Uint8Array([3, 3, 3])
377
+ ];
378
+ for (const index of [2, 0, 1]) {
379
+ const response = await alice.rootClient.request({
380
+ url: chunkUrl({ collectionId: 'data', resourceId, index }),
381
+ method: 'PUT',
382
+ action: 'PUT',
383
+ body: chunkBytes[index]
384
+ });
385
+ assert.equal(response.status, 204);
386
+ }
387
+ const listing = await alice.rootClient.request({
388
+ url: listUrl,
389
+ method: 'GET'
390
+ });
391
+ assert.equal(listing.status, 200);
392
+ assert.equal(listing.data.count, 3);
393
+ assert.deepEqual(listing.data.chunks.map((chunk) => chunk.index), [0, 1, 2]);
394
+ assert.deepEqual(listing.data.chunks.map((chunk) => chunk.size), [1, 2, 3]);
395
+ for (const chunk of listing.data.chunks) {
396
+ assert.equal(chunk.contentType, 'application/octet-stream');
397
+ }
398
+ // Deleting every chunk returns the listing to count 0 (the parent
399
+ // Resource still exists, so the container still lists).
400
+ for (const index of [0, 1, 2]) {
401
+ await alice.rootClient.request({
402
+ url: chunkUrl({ collectionId: 'data', resourceId, index }),
403
+ method: 'DELETE'
404
+ });
405
+ }
406
+ const afterDelete = await alice.rootClient.request({
407
+ url: listUrl,
408
+ method: 'GET'
409
+ });
410
+ assert.equal(afterDelete.status, 200);
411
+ assert.equal(afterDelete.data.count, 0);
412
+ assert.deepEqual(afterDelete.data.chunks, []);
413
+ }
414
+ },
415
+ {
416
+ id: 'chunks.parent-delete-cascade',
417
+ name: '[root] deleting the parent Resource cascades: its chunks and listing become 404',
418
+ specRefs: [
419
+ 'https://wallet.storage/spec#chunked-resources',
420
+ 'https://wallet.storage/spec#delete-resource-operation'
421
+ ],
422
+ run: async (ctx, state) => {
423
+ const { alice, chunkUrl, chunksListUrl, resourceUrl, chunkedSupported, createParent } = state;
424
+ if (!chunkedSupported) {
425
+ ctx.skip('backend does not advertise chunked-streams');
426
+ }
427
+ const resourceId = 'cascade';
428
+ await createParent(resourceId);
429
+ for (const index of [0, 1]) {
430
+ await alice.rootClient.request({
431
+ url: chunkUrl({ collectionId: 'data', resourceId, index }),
432
+ method: 'PUT',
433
+ action: 'PUT',
434
+ body: new Uint8Array([index])
435
+ });
436
+ }
437
+ const deleted = await alice.rootClient.request({
438
+ url: resourceUrl({ collectionId: 'data', resourceId }),
439
+ method: 'DELETE'
440
+ });
441
+ assert.equal(deleted.status, 204);
442
+ // The previously stored chunk is gone, and the listing 404s (its parent
443
+ // Resource -- and therefore its `chunks/` container -- no longer exists).
444
+ assert.equal((await resolveStatus(alice.rootClient.request({
445
+ url: chunkUrl({ collectionId: 'data', resourceId, index: 0 }),
446
+ method: 'GET'
447
+ }))).status, 404);
448
+ assert.equal((await resolveStatus(alice.rootClient.request({
449
+ url: chunksListUrl({ collectionId: 'data', resourceId }),
450
+ method: 'GET'
451
+ }))).status, 404);
452
+ }
453
+ },
454
+ {
455
+ id: 'chunks.invisible-to-changes-feed',
456
+ name: '[root] chunk writes and deletes do not surface on the collection changes feed',
457
+ specRefs: [
458
+ 'https://wallet.storage/spec#store-chunk-operation',
459
+ 'https://wallet.storage/spec#list-chunks-operation'
460
+ ],
461
+ run: async (ctx, state) => {
462
+ const { alice, chunkUrl, resourceUrl, chunkedSupported } = state;
463
+ if (!chunkedSupported) {
464
+ ctx.skip('backend does not advertise chunked-streams');
465
+ }
466
+ const resourceId = 'feed-manifest';
467
+ const queryUrl = new URL(`/space/${alice.space1.id}/data/query`, ctx.serverUrl).toString();
468
+ // Seed the parent manifest, then drain the feed and keep a checkpoint.
469
+ await alice.rootClient.request({
470
+ url: resourceUrl({ collectionId: 'data', resourceId }),
471
+ method: 'PUT',
472
+ action: 'PUT',
473
+ json: { id: resourceId, sequence: 0 }
474
+ });
475
+ const initial = await alice.rootClient.request({
476
+ url: queryUrl,
477
+ method: 'POST',
478
+ action: 'POST',
479
+ json: { profile: 'changes', limit: 100 }
480
+ });
481
+ assert.equal(initial.status, 200);
482
+ assert.ok(initial.data.documents.some((document) => document.id === resourceId), 'expected the seeded manifest in the initial feed');
483
+ const checkpoint = initial.data.checkpoint;
484
+ // A chunk write and a chunk delete bump only the chunk's own version:
485
+ // neither MUST touch the parent Resource's feed position.
486
+ for (const index of [0, 1]) {
487
+ await alice.rootClient.request({
488
+ url: chunkUrl({ collectionId: 'data', resourceId, index }),
489
+ method: 'PUT',
490
+ action: 'PUT',
491
+ body: new Uint8Array([index])
492
+ });
493
+ }
494
+ await alice.rootClient.request({
495
+ url: chunkUrl({ collectionId: 'data', resourceId, index: 1 }),
496
+ method: 'DELETE'
497
+ });
498
+ const afterChunks = await alice.rootClient.request({
499
+ url: queryUrl,
500
+ method: 'POST',
501
+ action: 'POST',
502
+ json: { profile: 'changes', limit: 100, checkpoint }
503
+ });
504
+ assert.equal(afterChunks.status, 200);
505
+ assert.deepEqual(afterChunks.data.documents, [], 'chunk writes MUST NOT surface on the changes feed');
506
+ // A subsequent parent-manifest PUT is what surfaces the change: the
507
+ // feed reacts to the Resource, not to its chunks.
508
+ await alice.rootClient.request({
509
+ url: resourceUrl({ collectionId: 'data', resourceId }),
510
+ method: 'PUT',
511
+ action: 'PUT',
512
+ json: { id: resourceId, sequence: 1 }
513
+ });
514
+ const afterManifest = await alice.rootClient.request({
515
+ url: queryUrl,
516
+ method: 'POST',
517
+ action: 'POST',
518
+ json: { profile: 'changes', limit: 100, checkpoint }
519
+ });
520
+ assert.deepEqual(afterManifest.data.documents.map((document) => document.id), [resourceId]);
521
+ }
522
+ },
523
+ {
524
+ id: 'chunks.write-cap-bound-to-chunk-url',
525
+ name: '[delegated] a capability for one chunk cannot write a sibling chunk',
526
+ specRefs: [
527
+ 'https://wallet.storage/spec#chunk-authorization',
528
+ 'https://wallet.storage/spec#store-chunk-operation'
529
+ ],
530
+ run: async (ctx, state) => {
531
+ const { alice, bob, chunkUrl, chunkedSupported, createParent } = state;
532
+ if (!chunkedSupported) {
533
+ ctx.skip('backend does not advertise chunked-streams');
534
+ }
535
+ const resourceId = 'target-binding';
536
+ await createParent(resourceId);
537
+ const chunkZeroUrl = chunkUrl({
538
+ collectionId: 'data',
539
+ resourceId,
540
+ index: 0
541
+ });
542
+ const chunkOneUrl = chunkUrl({
543
+ collectionId: 'data',
544
+ resourceId,
545
+ index: 1
546
+ });
547
+ // A chunk-write capability's `invocationTarget` is the chunk's own full
548
+ // URL. Alice grants Bob a PUT capability on chunk index 1's URL; invoked
549
+ // against chunk index 0 -- a sibling, not the same URL and not an
550
+ // ancestor of it -- the capability does not authorize the write, so the
551
+ // server rejects the invocation without performing it. (The reference
552
+ // server permits an ancestor-scoped capability to attenuate down to a
553
+ // descendant, so the binding is probed with a non-ancestor sibling.)
554
+ const zcap = await alice.was.grant({
555
+ to: bob.did,
556
+ actions: ['PUT'],
557
+ target: chunkOneUrl
558
+ });
559
+ const response = await writeChunkAt({
560
+ url: chunkZeroUrl,
561
+ capability: zcap,
562
+ body: new Uint8Array([7]),
563
+ invocationSigner: bob.rootClient.invocationSigner
564
+ });
565
+ assert.ok(response.status === 400 || response.status === 404, `expected the sibling-chunk invocation to be rejected with ` +
566
+ `400 or 404, got ${response.status}`);
567
+ assert.match(response.headers.get('content-type') ?? '', /application\/problem\+json/);
568
+ // The operation MUST NOT have been performed: chunk 0 was not written.
569
+ assert.equal((await resolveStatus(alice.rootClient.request({ url: chunkZeroUrl, method: 'GET' }))).status, 404);
570
+ }
571
+ },
572
+ {
573
+ id: 'chunks.no-leak-foreign-controller-404',
574
+ name: "[cross-controller] Bob reading or writing Alice's chunk URL is masked as 404",
575
+ specRefs: [
576
+ 'https://wallet.storage/spec#chunk-authorization',
577
+ 'https://wallet.storage/spec#error-handling'
578
+ ],
579
+ run: async (ctx, state) => {
580
+ const { alice, bob, chunkUrl, chunkedSupported, createParent } = state;
581
+ if (!chunkedSupported) {
582
+ ctx.skip('backend does not advertise chunked-streams');
583
+ }
584
+ const resourceId = 'foreign';
585
+ await createParent(resourceId);
586
+ const url = chunkUrl({ collectionId: 'data', resourceId, index: 0 });
587
+ // Alice stores a chunk Bob has no authority over.
588
+ await alice.rootClient.request({
589
+ url,
590
+ method: 'PUT',
591
+ action: 'PUT',
592
+ body: new Uint8Array([1, 2, 3])
593
+ });
594
+ // Bob root-invokes against Alice's chunk URL: the synthesized root
595
+ // capability is controlled by Alice, so Bob's signature does not verify
596
+ // and, per the maximum-privacy rule, both the read and the write are
597
+ // masked as 404 rather than disclosing the chunk's existence.
598
+ assert.equal((await resolveStatus(bob.rootClient.request({ url, method: 'GET' })))
599
+ .status, 404);
600
+ assert.equal((await resolveStatus(bob.rootClient.request({
601
+ url,
602
+ method: 'PUT',
603
+ action: 'PUT',
604
+ body: new Uint8Array([9])
605
+ }))).status, 404);
606
+ // Alice's chunk is untouched.
607
+ const readBack = await alice.rootClient.request({ url, method: 'GET' });
608
+ assert.deepEqual(new Uint8Array(await readBack.arrayBuffer()), new Uint8Array([1, 2, 3]));
609
+ }
610
+ }
611
+ ]
612
+ };
613
+ //# sourceMappingURL=chunks-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunks-api.js","sourceRoot":"","sources":["../../src/suites/chunks-api.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"client-backends.d.ts","sourceRoot":"","sources":["../../src/suites/client-backends.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAGhD,OAAO,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAErE,UAAU,KAAK;IACb,KAAK,EAAE,GAAG,CAAA;IACV,aAAa,EAAE,KAAK,EAAE,CAAA;IACtB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC,CAAA;IAC1C,kBAAkB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,mBAAmB,CAAA;CACxD;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,KAAK,CA+MvC,CAAA"}
1
+ {"version":3,"file":"client-backends.d.ts","sourceRoot":"","sources":["../../src/suites/client-backends.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAGhD,OAAO,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAErE,UAAU,KAAK;IACb,KAAK,EAAE,GAAG,CAAA;IACV,aAAa,EAAE,KAAK,EAAE,CAAA;IACtB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC,CAAA;IAC1C,kBAAkB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,mBAAmB,CAAA;CACxD;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,KAAK,CAsOvC,CAAA"}