@interop/was-client 0.9.1 → 0.10.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/README.md +27 -1
- package/dist/Collection.d.ts +49 -10
- package/dist/Collection.d.ts.map +1 -1
- package/dist/Collection.js +161 -61
- package/dist/Collection.js.map +1 -1
- package/dist/Resource.d.ts +13 -5
- package/dist/Resource.d.ts.map +1 -1
- package/dist/Resource.js +50 -38
- package/dist/Resource.js.map +1 -1
- package/dist/Space.d.ts +1 -0
- package/dist/Space.d.ts.map +1 -1
- package/dist/Space.js +24 -27
- package/dist/Space.js.map +1 -1
- package/dist/WasClient.d.ts +43 -2
- package/dist/WasClient.d.ts.map +1 -1
- package/dist/WasClient.js +90 -14
- package/dist/WasClient.js.map +1 -1
- package/dist/codec.d.ts +11 -4
- package/dist/codec.d.ts.map +1 -1
- package/dist/edv/EdvCodec.d.ts +64 -33
- package/dist/edv/EdvCodec.d.ts.map +1 -1
- package/dist/edv/EdvCodec.js +194 -86
- package/dist/edv/EdvCodec.js.map +1 -1
- package/dist/edv/WasTransport.d.ts +6 -12
- package/dist/edv/WasTransport.d.ts.map +1 -1
- package/dist/edv/WasTransport.js +6 -21
- package/dist/edv/WasTransport.js.map +1 -1
- package/dist/edv/constants.d.ts +30 -0
- package/dist/edv/constants.d.ts.map +1 -0
- package/dist/edv/constants.js +30 -0
- package/dist/edv/constants.js.map +1 -0
- package/dist/edv/index.d.ts +1 -1
- package/dist/edv/index.d.ts.map +1 -1
- package/dist/edv/index.js +1 -1
- package/dist/edv/index.js.map +1 -1
- package/dist/errors.d.ts +3 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +15 -5
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/internal/codec.d.ts +69 -4
- package/dist/internal/codec.d.ts.map +1 -1
- package/dist/internal/codec.js +93 -5
- package/dist/internal/codec.js.map +1 -1
- package/dist/internal/content.d.ts +74 -3
- package/dist/internal/content.d.ts.map +1 -1
- package/dist/internal/content.js +78 -7
- package/dist/internal/content.js.map +1 -1
- package/dist/internal/describe.d.ts.map +1 -1
- package/dist/internal/describe.js +2 -1
- package/dist/internal/describe.js.map +1 -1
- package/dist/internal/pagination.d.ts +45 -0
- package/dist/internal/pagination.d.ts.map +1 -0
- package/dist/internal/pagination.js +53 -0
- package/dist/internal/pagination.js.map +1 -0
- package/dist/internal/paths.d.ts +4 -0
- package/dist/internal/paths.d.ts.map +1 -1
- package/dist/internal/paths.js +10 -1
- package/dist/internal/paths.js.map +1 -1
- package/dist/internal/policy.d.ts +54 -0
- package/dist/internal/policy.d.ts.map +1 -0
- package/dist/internal/policy.js +58 -0
- package/dist/internal/policy.js.map +1 -0
- package/dist/internal/request.d.ts +4 -2
- package/dist/internal/request.d.ts.map +1 -1
- package/dist/internal/request.js +9 -2
- package/dist/internal/request.js.map +1 -1
- package/dist/internal/reserved.d.ts +3 -8
- package/dist/internal/reserved.d.ts.map +1 -1
- package/dist/internal/reserved.js +10 -20
- package/dist/internal/reserved.js.map +1 -1
- package/dist/internal/write.d.ts +37 -0
- package/dist/internal/write.d.ts.map +1 -0
- package/dist/internal/write.js +29 -0
- package/dist/internal/write.js.map +1 -0
- package/dist/types.d.ts +14 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -6
package/dist/WasClient.js
CHANGED
|
@@ -13,7 +13,8 @@ import { ZcapClient } from '@interop/ezcap';
|
|
|
13
13
|
import { Ed25519Signature2020 } from '@interop/ed25519-signature';
|
|
14
14
|
import { spacesRoot } from './internal/paths.js';
|
|
15
15
|
import { send, rawRequest, unsignedRequest } from './internal/request.js';
|
|
16
|
-
import { parseResource, readJsonData } from './internal/content.js';
|
|
16
|
+
import { createdId, parseResource, readJsonData } from './internal/content.js';
|
|
17
|
+
import { collectPages, walkPages } from './internal/pagination.js';
|
|
17
18
|
import { delegateGrant } from './internal/grant.js';
|
|
18
19
|
import { ValidationError } from './errors.js';
|
|
19
20
|
import { Space } from './Space.js';
|
|
@@ -120,8 +121,7 @@ export class WasClient {
|
|
|
120
121
|
method: 'POST',
|
|
121
122
|
json: body
|
|
122
123
|
});
|
|
123
|
-
|
|
124
|
-
return this.space(created.id);
|
|
124
|
+
return this.space(createdId(response));
|
|
125
125
|
}
|
|
126
126
|
/**
|
|
127
127
|
* Lists the spaces in the repository visible to the wrapped signer, as a
|
|
@@ -159,16 +159,15 @@ export class WasClient {
|
|
|
159
159
|
return parseResource(response);
|
|
160
160
|
}
|
|
161
161
|
/**
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
162
|
+
* Reads the first page of a public (`PublicCanRead`) collection listing with an
|
|
163
|
+
* unsigned `GET` and packages the means to follow its `next` links. Returns
|
|
164
|
+
* `null` if the collection is missing or not publicly readable (404 conflation
|
|
165
|
+
* caveat).
|
|
166
166
|
*
|
|
167
|
-
* @param
|
|
168
|
-
* @
|
|
169
|
-
* @returns {Promise<CollectionResourcesList | null>}
|
|
167
|
+
* @param collectionUrl {string} the absolute collection URL
|
|
168
|
+
* @returns {Promise<PageWalk | null>}
|
|
170
169
|
*/
|
|
171
|
-
async
|
|
170
|
+
async _publicListWalk(collectionUrl) {
|
|
172
171
|
// The collection listing endpoint is the trailing-slash items URL.
|
|
173
172
|
const url = collectionUrl.endsWith('/')
|
|
174
173
|
? collectionUrl
|
|
@@ -177,7 +176,73 @@ export class WasClient {
|
|
|
177
176
|
if (response === null) {
|
|
178
177
|
return null;
|
|
179
178
|
}
|
|
180
|
-
return
|
|
179
|
+
return {
|
|
180
|
+
first: (await readJsonData(response)),
|
|
181
|
+
firstUrl: url,
|
|
182
|
+
fetchPage: async (pageUrl) => {
|
|
183
|
+
const pageResponse = await unsignedRequest({
|
|
184
|
+
url: pageUrl,
|
|
185
|
+
method: 'GET',
|
|
186
|
+
read: true
|
|
187
|
+
});
|
|
188
|
+
return pageResponse === null
|
|
189
|
+
? null
|
|
190
|
+
: (await readJsonData(pageResponse));
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Lists a public (`PublicCanRead`) collection by its URL with no authorization
|
|
196
|
+
* -- an unsigned `GET` -- e.g. to browse a blog published as a public-read
|
|
197
|
+
* collection. Transparently follows the server's `next` pagination links,
|
|
198
|
+
* buffering every page into a single list (the returned envelope omits `next`).
|
|
199
|
+
* For a large collection prefer `publicListCollectionPages()` or
|
|
200
|
+
* `publicListCollectionItems()`, which stream one page at a time and allow
|
|
201
|
+
* stopping early. Returns `null` if the collection is missing or not publicly
|
|
202
|
+
* readable (404 conflation caveat).
|
|
203
|
+
*
|
|
204
|
+
* @param options {object}
|
|
205
|
+
* @param options.collectionUrl {string} the absolute collection URL
|
|
206
|
+
* @returns {Promise<CollectionResourcesList | null>}
|
|
207
|
+
*/
|
|
208
|
+
async publicListCollection({ collectionUrl }) {
|
|
209
|
+
const walk = await this._publicListWalk(collectionUrl);
|
|
210
|
+
return walk === null ? null : collectPages(walk);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Lazily yields a public collection listing one page at a time, following the
|
|
214
|
+
* server's `next` links on demand with unsigned `GET`s. Use this to stream a
|
|
215
|
+
* large public collection in constant memory or to stop early. Yields nothing
|
|
216
|
+
* if the collection is missing or not publicly readable (404 conflation
|
|
217
|
+
* caveat).
|
|
218
|
+
*
|
|
219
|
+
* @param options {object}
|
|
220
|
+
* @param options.collectionUrl {string} the absolute collection URL
|
|
221
|
+
* @returns {AsyncGenerator<CollectionResourcesList>}
|
|
222
|
+
*/
|
|
223
|
+
async *publicListCollectionPages({ collectionUrl }) {
|
|
224
|
+
const walk = await this._publicListWalk(collectionUrl);
|
|
225
|
+
if (walk === null) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
yield* walkPages(walk);
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Lazily yields each item of a public collection across every page, flattening
|
|
232
|
+
* `publicListCollectionPages()`. Yields the listing's `ResourceSummary` entries
|
|
233
|
+
* (id / url / contentType / name), not the resource bodies. Yields nothing if
|
|
234
|
+
* the collection is missing or not publicly readable (404 conflation caveat).
|
|
235
|
+
*
|
|
236
|
+
* @param options {object}
|
|
237
|
+
* @param options.collectionUrl {string} the absolute collection URL
|
|
238
|
+
* @returns {AsyncGenerator<ResourceSummary>}
|
|
239
|
+
*/
|
|
240
|
+
async *publicListCollectionItems({ collectionUrl }) {
|
|
241
|
+
for await (const page of this.publicListCollectionPages({
|
|
242
|
+
collectionUrl
|
|
243
|
+
})) {
|
|
244
|
+
yield* page.items;
|
|
245
|
+
}
|
|
181
246
|
}
|
|
182
247
|
/**
|
|
183
248
|
* Rebuilds an access handle from a received capability, returning a handle at
|
|
@@ -188,8 +253,19 @@ export class WasClient {
|
|
|
188
253
|
* @returns {Space | Collection | Resource}
|
|
189
254
|
*/
|
|
190
255
|
fromCapability(zcap) {
|
|
191
|
-
|
|
192
|
-
|
|
256
|
+
let pathname;
|
|
257
|
+
try {
|
|
258
|
+
;
|
|
259
|
+
({ pathname } = new URL(zcap.invocationTarget));
|
|
260
|
+
}
|
|
261
|
+
catch (err) {
|
|
262
|
+
throw new ValidationError(`invocationTarget "${zcap.invocationTarget}" is not a valid ` +
|
|
263
|
+
'absolute URL.', { cause: err });
|
|
264
|
+
}
|
|
265
|
+
// Decode each path segment before splitting it back into handle ids: the
|
|
266
|
+
// path builders re-encode every id with encodeURIComponent, so passing a
|
|
267
|
+
// still-encoded segment through would double-encode it.
|
|
268
|
+
const segments = pathname.split('/').filter(Boolean).map(decodeURIComponent);
|
|
193
269
|
if (segments[0] !== 'space') {
|
|
194
270
|
throw new ValidationError(`Cannot derive a handle from invocationTarget "${zcap.invocationTarget}".`);
|
|
195
271
|
}
|
package/dist/WasClient.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WasClient.js","sourceRoot":"","sources":["../src/WasClient.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;GAOG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAA;AAEjE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAEhD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACzE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"WasClient.js","sourceRoot":"","sources":["../src/WasClient.ts"],"names":[],"mappings":"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"}
|
package/dist/codec.d.ts
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
* silently writing plaintext.
|
|
32
32
|
*/
|
|
33
33
|
import type { HttpResponse } from '@interop/http-client';
|
|
34
|
-
import type { Json } from './types.js';
|
|
34
|
+
import type { Json, ResourceData } from './types.js';
|
|
35
35
|
/**
|
|
36
36
|
* The result of {@link ResourceCodec.encode}: the stored representation of a
|
|
37
37
|
* write, plus the id to store it under.
|
|
@@ -43,7 +43,13 @@ import type { Json } from './types.js';
|
|
|
43
43
|
* - `json` / `body` -- mutually exclusive payloads, mirroring the request
|
|
44
44
|
* layer: `json` for a structured body, `body` for raw bytes.
|
|
45
45
|
* - `contentType` -- the content type to send for a `body` write (e.g.
|
|
46
|
-
* `application/
|
|
46
|
+
* `application/jose+json` for an encrypted envelope).
|
|
47
|
+
* - `resourceContentType` -- the plaintext content type of the resource, when it
|
|
48
|
+
* differs from the stored `contentType`. An encrypting codec sets this to the
|
|
49
|
+
* caller's resolved type (e.g. `image/png`) while `contentType` stays the
|
|
50
|
+
* opaque envelope type, so `add()` can report the real type in
|
|
51
|
+
* {@link AddResult.contentType}. Absent for the identity codec (its
|
|
52
|
+
* `contentType` already is the resource type).
|
|
47
53
|
* - `ifMatch` / `ifNoneMatch` -- an optional conditional-write precondition the
|
|
48
54
|
* codec computed (e.g. the EDV codec maps its `sequence` onto an `If-Match`
|
|
49
55
|
* ETag for lost-update-safe updates, or `If-None-Match: *` for a fresh
|
|
@@ -55,6 +61,7 @@ export interface EncodedWrite {
|
|
|
55
61
|
json?: object;
|
|
56
62
|
body?: Uint8Array | Blob;
|
|
57
63
|
contentType?: string;
|
|
64
|
+
resourceContentType?: string;
|
|
58
65
|
ifMatch?: string;
|
|
59
66
|
ifNoneMatch?: boolean;
|
|
60
67
|
}
|
|
@@ -88,7 +95,7 @@ export interface ResourceCodec {
|
|
|
88
95
|
*
|
|
89
96
|
* @param input {object}
|
|
90
97
|
* @param [input.id] {string} resource id (absent on add)
|
|
91
|
-
* @param input.data {
|
|
98
|
+
* @param input.data {ResourceData} the plaintext value
|
|
92
99
|
* @param [input.contentType] {string} caller-supplied content type
|
|
93
100
|
* @param [input.current] {HttpResponse | null} the current stored response
|
|
94
101
|
* (or `null` if absent), supplied only when {@link conditionalWrites} is set,
|
|
@@ -97,7 +104,7 @@ export interface ResourceCodec {
|
|
|
97
104
|
*/
|
|
98
105
|
encode(input: {
|
|
99
106
|
id?: string;
|
|
100
|
-
data:
|
|
107
|
+
data: ResourceData;
|
|
101
108
|
contentType?: string;
|
|
102
109
|
current?: HttpResponse | null;
|
|
103
110
|
}): Promise<EncodedWrite>;
|
package/dist/codec.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../src/codec.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../src/codec.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEpD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,UAAU,GAAG,IAAI,CAAA;IACxB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;OAKG;IACH,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAA;IAEtC;;;;;;;;OAQG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAEpC;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,KAAK,EAAE;QACZ,EAAE,CAAC,EAAE,MAAM,CAAA;QACX,IAAI,EAAE,YAAY,CAAA;QAClB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI,CAAA;KAC9B,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IAEzB;;;;;;;OAOG;IACH,MAAM,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAA;CACrD;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,KAAK,EAAE;QACd,OAAO,EAAE,MAAM,CAAA;QACf,YAAY,EAAE,MAAM,CAAA;QACpB,MAAM,EAAE,MAAM,CAAA;QACd,IAAI,CAAC,EAAE,OAAO,CAAA;KACf,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAA;CAClC"}
|
package/dist/edv/EdvCodec.d.ts
CHANGED
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
* app's `resolveKeys`; they never reach the server, which stores only opaque
|
|
12
12
|
* JWE envelopes.
|
|
13
13
|
*
|
|
14
|
-
* This reuses `EdvClientCore`'s
|
|
15
|
-
*
|
|
16
|
-
* the
|
|
17
|
-
* I/O, so the codec is a
|
|
18
|
-
* its own.
|
|
14
|
+
* This reuses `EdvClientCore`'s transport-free `documentCipher` (its public
|
|
15
|
+
* `EdvDocumentCipher` -- the same JWE machinery as the standalone
|
|
16
|
+
* `WasTransport`), but here the WAS Resource CRUD -- the transport role -- is
|
|
17
|
+
* played by core was-client's `Collection`/`Resource` I/O, so the codec is a
|
|
18
|
+
* pure encode/decode transform and needs no transport of its own.
|
|
19
19
|
*
|
|
20
20
|
* Scope (documents-only):
|
|
21
21
|
*
|
|
@@ -24,9 +24,12 @@
|
|
|
24
24
|
* a human-readable id is rejected (it would leak onto the URL). Carry a
|
|
25
25
|
* human-readable label inside the encrypted content instead. (Blind-derived
|
|
26
26
|
* ids are a deferred future item.)
|
|
27
|
-
* - **
|
|
28
|
-
* is
|
|
29
|
-
* (
|
|
27
|
+
* - **Inline non-JSON as a single JWE.** A `Blob`/`Uint8Array` under the size cap
|
|
28
|
+
* is encrypted as one document -- stored as a legible UTF-8 string for a
|
|
29
|
+
* text-family type (else base64) -- with the plaintext content type and the
|
|
30
|
+
* encoding carried in the document `meta`. An oversized one is
|
|
31
|
+
* rejected (large chunked encrypted blobs need the server's `chunked-streams`
|
|
32
|
+
* affordance).
|
|
30
33
|
* - **Enforced sequence (conditional writes).** The codec sets
|
|
31
34
|
* `conditionalWrites`, so the write path pre-reads the current envelope and
|
|
32
35
|
* hands it to `encode`: an update advances `sequence` from its prior value and
|
|
@@ -43,11 +46,10 @@ import { EdvClientCore } from '@interop/edv-client';
|
|
|
43
46
|
import type { HttpResponse } from '@interop/http-client';
|
|
44
47
|
import type { IKeyAgreementKey, IKeyResolver } from '@interop/data-integrity-core';
|
|
45
48
|
import type { EncodedWrite, EncryptionProvider, ResourceCodec } from '../codec.js';
|
|
46
|
-
import type { Json } from '../types.js';
|
|
47
|
-
import { EDV_CONTENT_TYPE } from './WasTransport.js';
|
|
49
|
+
import type { Json, ResourceData } from '../types.js';
|
|
48
50
|
/**
|
|
49
51
|
* A {@link ResourceCodec} that encrypts on write and decrypts on read using an
|
|
50
|
-
* `EdvClientCore`'s
|
|
52
|
+
* `EdvClientCore`'s public `documentCipher`. One instance is bound per encrypted
|
|
51
53
|
* collection handle.
|
|
52
54
|
*/
|
|
53
55
|
export declare class EdvCodec implements ResourceCodec {
|
|
@@ -75,7 +77,7 @@ export declare class EdvCodec implements ResourceCodec {
|
|
|
75
77
|
*/
|
|
76
78
|
encode({ id, data, contentType, current }: {
|
|
77
79
|
id?: string;
|
|
78
|
-
data:
|
|
80
|
+
data: ResourceData;
|
|
79
81
|
contentType?: string;
|
|
80
82
|
current?: HttpResponse | null;
|
|
81
83
|
}): Promise<EncodedWrite>;
|
|
@@ -87,35 +89,65 @@ export declare class EdvCodec implements ResourceCodec {
|
|
|
87
89
|
json(): Promise<unknown>;
|
|
88
90
|
}): Promise<Json | Blob>;
|
|
89
91
|
/**
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
* `
|
|
92
|
+
* Asserts that a document read from an encrypted collection is an EDV envelope
|
|
93
|
+
* (`{ jwe, ... }`) before it is handed to the cipher. A plaintext or foreign
|
|
94
|
+
* resource -- one written without this codec -- carries no `jwe`, which would
|
|
95
|
+
* otherwise make the EDV core throw a raw `TypeError`. Surfacing a typed
|
|
96
|
+
* `EncryptionError` keeps the fail-closed contract legible to callers.
|
|
94
97
|
*
|
|
95
|
-
* @param
|
|
96
|
-
* @param
|
|
97
|
-
*
|
|
98
|
+
* @param doc {unknown}
|
|
99
|
+
* @param context {string} the operation in progress (`read` / `update`),
|
|
100
|
+
* for the message
|
|
101
|
+
* @returns {asserts doc is IEncryptedDocument}
|
|
98
102
|
*/
|
|
99
|
-
private
|
|
103
|
+
private _assertEnvelope;
|
|
100
104
|
/**
|
|
101
|
-
*
|
|
102
|
-
*
|
|
105
|
+
* Splits a caller value into a decrypted EDV document `{ content, meta }`,
|
|
106
|
+
* carrying the plaintext content type and inline-encoding discriminator in
|
|
107
|
+
* `meta`. Three cases:
|
|
103
108
|
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
109
|
+
* 1. JSON object/array to `content` verbatim, `meta = { contentType }` (no
|
|
110
|
+
* `encoding`); the shape of `content` is never inspected on read, so a
|
|
111
|
+
* caller object shaped like `{ text }` / `{ bytes }` round-trips as itself.
|
|
112
|
+
* 2. Text (`Blob`/`Uint8Array` of a text-family type that is valid UTF-8)
|
|
113
|
+
* to `content = { text }`, `meta = { contentType, encoding: 'utf-8' }`;
|
|
114
|
+
* stored legibly with no base64 inflation.
|
|
115
|
+
* 3. Binary (any other `Blob`/`Uint8Array`) to `content = { bytes: base64 }`,
|
|
116
|
+
* `meta = { contentType, encoding: 'base64' }`.
|
|
117
|
+
*
|
|
118
|
+
* A bare primitive is rejected (mirroring the plaintext `prepareBody`
|
|
119
|
+
* contract). The binary/text content type resolves as
|
|
120
|
+
* `contentType || blob.type || guessContentTypeFromId(id) || octet-stream`,
|
|
121
|
+
* mirroring `prepareBody`.
|
|
122
|
+
*
|
|
123
|
+
* @param data {ResourceData}
|
|
124
|
+
* @param [contentType] {string} caller-supplied content type
|
|
125
|
+
* @param [id] {string} resource id, for the extension guess
|
|
126
|
+
* @returns {Promise<{ content: Record<string, unknown>; meta:
|
|
127
|
+
* Record<string, unknown> }>}
|
|
107
128
|
*/
|
|
108
|
-
private
|
|
129
|
+
private _toDocument;
|
|
109
130
|
/**
|
|
110
|
-
* Reconstructs a caller value from decrypted EDV document
|
|
111
|
-
*
|
|
131
|
+
* Reconstructs a caller value from a decrypted EDV document, discriminating
|
|
132
|
+
* on `meta.encoding`:
|
|
133
|
+
*
|
|
134
|
+
* - `'utf-8'` to a `Blob` typed `meta.contentType` from `content.text`.
|
|
135
|
+
* - `'base64'` to a `Blob` typed `meta.contentType` from `content.bytes`.
|
|
136
|
+
* - absent (or `meta` absent) to `content` returned verbatim as JSON.
|
|
137
|
+
*
|
|
138
|
+
* A malformed inner shape (an encoding that does not match its container key's
|
|
139
|
+
* type) throws {@link EncryptionError} -- the decrypted-document analogue of
|
|
140
|
+
* `_assertEnvelope`'s outer guard.
|
|
112
141
|
*
|
|
113
142
|
* @param content {unknown}
|
|
143
|
+
* @param [meta] {Record<string, unknown>}
|
|
114
144
|
* @returns {Json | Blob}
|
|
115
145
|
*/
|
|
116
|
-
private
|
|
146
|
+
private _fromDocument;
|
|
117
147
|
}
|
|
118
|
-
/**
|
|
148
|
+
/**
|
|
149
|
+
* The per-collection key material an EDV codec is built from.
|
|
150
|
+
*/
|
|
119
151
|
export interface EdvKeys {
|
|
120
152
|
keyAgreementKey: IKeyAgreementKey;
|
|
121
153
|
keyResolver: IKeyResolver;
|
|
@@ -139,8 +171,8 @@ export interface EdvKeys {
|
|
|
139
171
|
* `{ keyAgreementKey, keyResolver }`, or `null` if this client holds no keys
|
|
140
172
|
* for it (fail-closed -- not a plaintext signal)
|
|
141
173
|
* @param [options.contentType] {string} stored envelope content type;
|
|
142
|
-
* defaults to `application/json`. Pass `
|
|
143
|
-
* (`application/
|
|
174
|
+
* defaults to `application/json`. Pass `JOSE_CONTENT_TYPE`
|
|
175
|
+
* (`application/jose+json`) against a server that registers an
|
|
144
176
|
* `application/*+json` parser.
|
|
145
177
|
* @param [options.maxBlobBytes] {number} single-document binary cap (default
|
|
146
178
|
* 1 MiB)
|
|
@@ -154,5 +186,4 @@ export declare function createEdvEncryption({ resolveKeys, contentType, maxBlobB
|
|
|
154
186
|
contentType?: string;
|
|
155
187
|
maxBlobBytes?: number;
|
|
156
188
|
}): EncryptionProvider;
|
|
157
|
-
export { EDV_CONTENT_TYPE };
|
|
158
189
|
//# sourceMappingURL=EdvCodec.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EdvCodec.d.ts","sourceRoot":"","sources":["../../src/edv/EdvCodec.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"EdvCodec.d.ts","sourceRoot":"","sources":["../../src/edv/EdvCodec.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,KAAK,EAEV,gBAAgB,EAChB,YAAY,EACb,MAAM,8BAA8B,CAAA;AACrC,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACd,MAAM,aAAa,CAAA;AAQpB,OAAO,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AA0DrD;;;;GAIG;AACH,qBAAa,QAAS,YAAW,aAAa;IAC5C,QAAQ,CAAC,oBAAoB,SAAQ;IACrC,QAAQ,CAAC,iBAAiB,QAAO;IAEjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAe;IACpC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkB;IACnD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;IACrC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;IAEtC;;;;;;OAMG;gBACS,EACV,GAAG,EACH,eAAe,EACf,WAAW,EACX,YAAY,EACb,EAAE;QACD,GAAG,EAAE,aAAa,CAAA;QAClB,eAAe,EAAE,gBAAgB,CAAA;QACjC,WAAW,EAAE,MAAM,CAAA;QACnB,YAAY,EAAE,MAAM,CAAA;KACrB;IAOD;;OAEG;IACG,MAAM,CAAC,EACX,EAAE,EACF,IAAI,EACJ,WAAW,EACX,OAAO,EACR,EAAE;QACD,EAAE,CAAC,EAAE,MAAM,CAAA;QACX,IAAI,EAAE,YAAY,CAAA;QAClB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI,CAAA;KAC9B,GAAG,OAAO,CAAC,YAAY,CAAC;IAiEzB;;OAEG;IACG,MAAM,CAAC,QAAQ,EAAE;QACrB,IAAI,CAAC,EAAE,OAAO,CAAA;QACd,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;KACzB,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAYxB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,eAAe;IAkBvB;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;YACW,WAAW;IAoEzB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,aAAa;CA+BtB;AAsBD;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,eAAe,EAAE,gBAAgB,CAAA;IACjC,WAAW,EAAE,YAAY,CAAA;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,WAAW,EACX,WAAkC,EAClC,YAAqC,EACtC,EAAE;IACD,WAAW,EAAE,CAAC,GAAG,EAAE;QACjB,OAAO,EAAE,MAAM,CAAA;QACf,YAAY,EAAE,MAAM,CAAA;KACrB,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,GAAG,kBAAkB,CAyBrB"}
|