@interop/was-client 0.99.1 → 0.100.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 +90 -70
- package/dist/Collection.d.ts +20 -8
- package/dist/Collection.d.ts.map +1 -1
- package/dist/Collection.js +89 -69
- package/dist/Collection.js.map +1 -1
- package/dist/Resource.d.ts +14 -3
- package/dist/Resource.d.ts.map +1 -1
- package/dist/Resource.js +38 -27
- package/dist/Resource.js.map +1 -1
- package/dist/Space.d.ts +18 -4
- package/dist/Space.d.ts.map +1 -1
- package/dist/Space.js +64 -61
- package/dist/Space.js.map +1 -1
- package/dist/WasClient.d.ts +102 -54
- package/dist/WasClient.d.ts.map +1 -1
- package/dist/WasClient.js +212 -133
- package/dist/WasClient.js.map +1 -1
- package/dist/codec.d.ts +3 -2
- package/dist/codec.d.ts.map +1 -1
- package/dist/edv/EdvCodec.js +1 -1
- package/dist/edv/EdvCodec.js.map +1 -1
- package/dist/edv/WasTransport.d.ts +7 -4
- package/dist/edv/WasTransport.d.ts.map +1 -1
- package/dist/edv/WasTransport.js +39 -20
- package/dist/edv/WasTransport.js.map +1 -1
- package/dist/edv/acquire.d.ts +3 -3
- package/dist/edv/acquire.d.ts.map +1 -1
- package/dist/edv/acquire.js +3 -3
- package/dist/edv/acquire.js.map +1 -1
- package/dist/edv/cipher.d.ts +1 -1
- package/dist/edv/cipher.js +1 -1
- package/dist/edv/docCipher.d.ts +6 -5
- package/dist/edv/docCipher.d.ts.map +1 -1
- package/dist/edv/docCipher.js +6 -5
- package/dist/edv/docCipher.js.map +1 -1
- package/dist/edv/encryption.d.ts +2 -2
- package/dist/edv/encryption.d.ts.map +1 -1
- package/dist/edv/encryption.js +8 -6
- package/dist/edv/encryption.js.map +1 -1
- package/dist/edv/refreshingDocCipher.d.ts +3 -3
- package/dist/edv/refreshingDocCipher.d.ts.map +1 -1
- package/dist/edv/refreshingDocCipher.js +3 -3
- package/dist/edv/refreshingDocCipher.js.map +1 -1
- package/dist/edv/transportFactory.d.ts +3 -3
- package/dist/edv/transportFactory.d.ts.map +1 -1
- package/dist/edv/transportFactory.js +3 -3
- package/dist/edv/transportFactory.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/codec.d.ts +7 -7
- package/dist/internal/codec.d.ts.map +1 -1
- package/dist/internal/codec.js +19 -18
- package/dist/internal/codec.js.map +1 -1
- package/dist/internal/conditional.d.ts +3 -3
- package/dist/internal/conditional.d.ts.map +1 -1
- package/dist/internal/conditional.js +5 -5
- package/dist/internal/conditional.js.map +1 -1
- package/dist/internal/grant.d.ts +15 -26
- package/dist/internal/grant.d.ts.map +1 -1
- package/dist/internal/grant.js +95 -29
- package/dist/internal/grant.js.map +1 -1
- package/dist/internal/meta.d.ts +8 -8
- package/dist/internal/meta.d.ts.map +1 -1
- package/dist/internal/meta.js +13 -10
- package/dist/internal/meta.js.map +1 -1
- package/dist/internal/paths.d.ts +332 -195
- package/dist/internal/paths.d.ts.map +1 -1
- package/dist/internal/paths.js +400 -367
- package/dist/internal/paths.js.map +1 -1
- package/dist/internal/policy.d.ts +23 -23
- package/dist/internal/policy.d.ts.map +1 -1
- package/dist/internal/policy.js +20 -20
- package/dist/internal/policy.js.map +1 -1
- package/dist/internal/request.d.ts +17 -21
- package/dist/internal/request.d.ts.map +1 -1
- package/dist/internal/request.js +10 -21
- package/dist/internal/request.js.map +1 -1
- package/dist/internal/revoke.d.ts +34 -13
- package/dist/internal/revoke.d.ts.map +1 -1
- package/dist/internal/revoke.js +97 -28
- package/dist/internal/revoke.js.map +1 -1
- package/dist/internal/service.d.ts +25 -7
- package/dist/internal/service.d.ts.map +1 -1
- package/dist/internal/service.js +49 -45
- package/dist/internal/service.js.map +1 -1
- package/dist/internal/write.d.ts +18 -18
- package/dist/internal/write.d.ts.map +1 -1
- package/dist/internal/write.js +27 -27
- package/dist/internal/write.js.map +1 -1
- package/dist/paths.d.ts +32 -25
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +32 -25
- package/dist/paths.js.map +1 -1
- package/dist/sync/port.d.ts +3 -3
- package/dist/sync/port.d.ts.map +1 -1
- package/dist/sync/port.js +12 -12
- package/dist/sync/port.js.map +1 -1
- package/dist/sync/provisioning.d.ts +10 -9
- package/dist/sync/provisioning.d.ts.map +1 -1
- package/dist/sync/provisioning.js +19 -18
- package/dist/sync/provisioning.js.map +1 -1
- package/dist/sync/types.d.ts +2 -2
- package/dist/types.d.ts +13 -5
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/WasClient.js
CHANGED
|
@@ -1,41 +1,59 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isValidTarget } from '@interop/zcap';
|
|
2
|
+
import { canonicalContainerUrl, parseAbsoluteHttpUrl, parseSpaceTarget } from './internal/paths.js';
|
|
2
3
|
import { send, rawRequest, unsignedRequest } from './internal/request.js';
|
|
3
|
-
import {
|
|
4
|
+
import { parseResource, readJsonData } from './internal/content.js';
|
|
4
5
|
import { buildPageWalk, collectPages, collectWalk, signedPageWalk, walkItems, walkPagesOrEmpty } from './internal/pagination.js';
|
|
5
6
|
import { delegateGrant } from './internal/grant.js';
|
|
6
|
-
import {
|
|
7
|
+
import { spaceUrlOf, submitRevocation } from './internal/revoke.js';
|
|
7
8
|
import { Memo } from './internal/memo.js';
|
|
8
|
-
import { discoverService, selectServiceVersion } from './internal/service.js';
|
|
9
|
+
import { discoverService, readServiceDescription, selectServiceVersion } from './internal/service.js';
|
|
9
10
|
import { IncompatibleServerError, NotSupportedError, ValidationError, WasServerError } from './errors.js';
|
|
10
11
|
import { zcapClientForSigner } from './zcapClient.js';
|
|
11
12
|
import { Space } from './Space.js';
|
|
12
13
|
import { Collection } from './Collection.js';
|
|
13
14
|
import { Resource } from './Resource.js';
|
|
15
|
+
/**
|
|
16
|
+
* Checks that `value` is an absolute `http(s)` URL and returns it as `URL`
|
|
17
|
+
* serializes it, or throws.
|
|
18
|
+
*
|
|
19
|
+
* @param options {object}
|
|
20
|
+
* @param options.name {string} the option's name, for the error
|
|
21
|
+
* @param options.value {string}
|
|
22
|
+
* @returns {string}
|
|
23
|
+
* @throws {ValidationError}
|
|
24
|
+
*/
|
|
25
|
+
function absoluteHttpUrl({ name, value }) {
|
|
26
|
+
const parsed = parseAbsoluteHttpUrl(value);
|
|
27
|
+
if (parsed === null) {
|
|
28
|
+
throw new ValidationError(`${name} "${value}" is not an absolute http(s) URL.`);
|
|
29
|
+
}
|
|
30
|
+
return parsed.toString();
|
|
31
|
+
}
|
|
14
32
|
export class WasClient {
|
|
15
33
|
/**
|
|
16
|
-
* The
|
|
17
|
-
*
|
|
34
|
+
* The service description's URL, when the client was built from one. Read
|
|
35
|
+
* directly by discovery.
|
|
18
36
|
*/
|
|
19
|
-
|
|
37
|
+
serviceUrl;
|
|
20
38
|
/**
|
|
21
|
-
* The
|
|
22
|
-
*
|
|
23
|
-
*
|
|
39
|
+
* The Spaces Repository URL the client was built from, when it was built
|
|
40
|
+
* from one, in canonical container form (trailing slash supplied).
|
|
41
|
+
* Discovery probes it for the `service` link. The URL `createSpace` and
|
|
42
|
+
* `listSpaces` address is the service description's `spaces` member, not
|
|
43
|
+
* this value.
|
|
24
44
|
*/
|
|
25
|
-
|
|
45
|
+
spacesUrl;
|
|
26
46
|
zcapClient;
|
|
27
47
|
encryption;
|
|
28
48
|
/**
|
|
29
49
|
* @param options {object}
|
|
30
|
-
* @param options.
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* server with no Spaces Repository (the spec leaves the endpoint
|
|
38
|
-
* optional) has no URL this constructor accepts and is not supported.
|
|
50
|
+
* @param [options.serviceUrl] {string} the URL of the server's service
|
|
51
|
+
* description. Discovery reads it with an unsigned `GET`. Exactly one of
|
|
52
|
+
* `serviceUrl` and `spacesUrl` is given
|
|
53
|
+
* @param [options.spacesUrl] {string} the server's Spaces Repository
|
|
54
|
+
* URL, for a caller that holds that rather than the service URL.
|
|
55
|
+
* Discovery sends an unsigned `HEAD` to it and follows the `service`
|
|
56
|
+
* link every response carries
|
|
39
57
|
* @param options.zcapClient {ZcapClient} an ezcap client holding the signer
|
|
40
58
|
* @param [options.encryption] {EncryptionProvider} the keystore that
|
|
41
59
|
* supplies keys for collections declared encrypted (by their `encryption`
|
|
@@ -46,22 +64,31 @@ export class WasClient {
|
|
|
46
64
|
* closed rather than silently downgrading to plaintext.
|
|
47
65
|
* @param [options.serviceDescription] {ServiceDescription} a service
|
|
48
66
|
* description the caller already holds (from a cache, say). The client
|
|
49
|
-
* selects its version from this copy instead of discovering the document
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
* discovers afresh.
|
|
54
|
-
* @throws {ValidationError} when
|
|
67
|
+
* selects its version from this copy instead of discovering the document,
|
|
68
|
+
* and still refuses it with `IncompatibleServerError` if it names no
|
|
69
|
+
* version this client speaks, or (for a client built from `serviceUrl`)
|
|
70
|
+
* if its `url` is another server's service URL. `service({ refresh:
|
|
71
|
+
* true })` discards it and discovers afresh.
|
|
72
|
+
* @throws {ValidationError} when neither or both of `serviceUrl` and
|
|
73
|
+
* `spacesUrl` are given, or the one given is not an absolute http(s) URL
|
|
55
74
|
*/
|
|
56
|
-
constructor({
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
75
|
+
constructor({ serviceUrl, spacesUrl, zcapClient, encryption, serviceDescription }) {
|
|
76
|
+
if ((serviceUrl === undefined) === (spacesUrl === undefined)) {
|
|
77
|
+
throw new ValidationError('A WasClient is built from exactly one of `serviceUrl` (the service ' +
|
|
78
|
+
'description URL) and `spacesUrl` (the Spaces Repository URL).');
|
|
79
|
+
}
|
|
80
|
+
if (serviceUrl !== undefined) {
|
|
81
|
+
this.serviceUrl = absoluteHttpUrl({
|
|
82
|
+
name: 'serviceUrl',
|
|
83
|
+
value: serviceUrl
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
// Canonical container form, so the probe addresses the container
|
|
88
|
+
// itself rather than its redirect, and `was.spacesUrl` reads the same
|
|
89
|
+
// as the `spacesUrl` discovery reports for the same repository.
|
|
90
|
+
this.spacesUrl = canonicalContainerUrl(absoluteHttpUrl({ name: 'spacesUrl', value: spacesUrl }));
|
|
62
91
|
}
|
|
63
|
-
this.serverUrl = spacesUrl({ baseUrl });
|
|
64
|
-
this.baseUrl = baseUrl;
|
|
65
92
|
this.zcapClient = zcapClient;
|
|
66
93
|
this.encryption = encryption;
|
|
67
94
|
this.#serviceDescription = serviceDescription;
|
|
@@ -76,16 +103,17 @@ export class WasClient {
|
|
|
76
103
|
* and never needs a JSON-LD document loader to serve the suite's context.
|
|
77
104
|
*
|
|
78
105
|
* @param options {object}
|
|
79
|
-
* @param options.
|
|
106
|
+
* @param [options.serviceUrl] {string} see the constructor
|
|
107
|
+
* @param [options.spacesUrl] {string} see the constructor
|
|
80
108
|
* @param options.signer {ISigner}
|
|
81
109
|
* @param [options.encryption] {EncryptionProvider} see the constructor
|
|
82
110
|
* @param [options.serviceDescription] {ServiceDescription} see the
|
|
83
111
|
* constructor
|
|
84
112
|
* @returns {WasClient}
|
|
85
113
|
*/
|
|
86
|
-
static fromSigner({
|
|
114
|
+
static fromSigner({ signer, encryption, serviceDescription, ...locator }) {
|
|
87
115
|
return new WasClient({
|
|
88
|
-
|
|
116
|
+
...locator,
|
|
89
117
|
zcapClient: zcapClientForSigner({ signer }),
|
|
90
118
|
encryption,
|
|
91
119
|
serviceDescription
|
|
@@ -106,35 +134,46 @@ export class WasClient {
|
|
|
106
134
|
}
|
|
107
135
|
#serviceDescription;
|
|
108
136
|
#service = new Memo(async () => {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
// that advertises its Spaces Repository elsewhere would be addressed at
|
|
114
|
-
// the wrong mount. Refuse it by name rather than misroute. Both sides are
|
|
115
|
-
// compared in canonical base-URL form, so an advertised value that differs
|
|
116
|
-
// only in serialization (host case, default port, trailing slash) passes.
|
|
117
|
-
if (info.spacesUrl !== undefined) {
|
|
118
|
-
const advertisedBase = baseUrlOfSpacesUrl(info.spacesUrl);
|
|
119
|
-
if (advertisedBase !== this.baseUrl) {
|
|
120
|
-
const why = advertisedBase === null
|
|
121
|
-
? `which is not a Spaces Repository URL (an absolute http(s) ` +
|
|
122
|
-
`URL ending in a "spaces" segment, with no query or fragment).`
|
|
123
|
-
: `but this client was given "${this.serverUrl}".`;
|
|
124
|
-
throw new IncompatibleServerError(`The server advertises its Spaces Repository at ` +
|
|
125
|
-
`"${info.spacesUrl}", ${why}`, { requestUrl: this.serverUrl });
|
|
126
|
-
}
|
|
137
|
+
if (this.#serviceDescription !== undefined) {
|
|
138
|
+
const info = selectServiceVersion(this.#serviceDescription);
|
|
139
|
+
this.#assertDescribesThisServer(info);
|
|
140
|
+
return info;
|
|
127
141
|
}
|
|
128
|
-
return
|
|
142
|
+
return this.serviceUrl !== undefined
|
|
143
|
+
? readServiceDescription({ serviceUrl: this.serviceUrl })
|
|
144
|
+
: discoverService({ url: this.spacesUrl });
|
|
129
145
|
});
|
|
146
|
+
/**
|
|
147
|
+
* Refuses a caller-supplied service description of another server than
|
|
148
|
+
* the one this client was built for: a cache entry keyed wrongly, or kept
|
|
149
|
+
* across deployments, would otherwise route `createSpace` and `listSpaces`
|
|
150
|
+
* to the other server's Spaces Repository. A server is identified by its
|
|
151
|
+
* service URL, so the description's `url` must be the `serviceUrl` given.
|
|
152
|
+
* A client built from `spacesUrl` names no service URL and is not checked;
|
|
153
|
+
* nor is a discovered description, which came from the server named.
|
|
154
|
+
*
|
|
155
|
+
* @param info {ServiceInfo}
|
|
156
|
+
* @throws {IncompatibleServerError}
|
|
157
|
+
*/
|
|
158
|
+
#assertDescribesThisServer(info) {
|
|
159
|
+
if (this.serviceUrl === undefined) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const described = parseAbsoluteHttpUrl(info.description.url)?.toString();
|
|
163
|
+
if (described !== this.serviceUrl) {
|
|
164
|
+
throw new IncompatibleServerError(`The service description given is of ` +
|
|
165
|
+
`"${info.description.url}", but this client was built for ` +
|
|
166
|
+
`"${this.serviceUrl}".`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
130
169
|
/**
|
|
131
170
|
* Discovers the server's service description and the WAS version this
|
|
132
|
-
* client speaks with it.
|
|
133
|
-
* an unsigned `
|
|
134
|
-
* the
|
|
135
|
-
* result is memoized for the life of the
|
|
136
|
-
*
|
|
137
|
-
* the next call retries.
|
|
171
|
+
* client speaks with it. A client built from `serviceUrl` reads the document
|
|
172
|
+
* with an unsigned `GET`; one built from `spacesUrl` first follows the
|
|
173
|
+
* `rel="service"` link on the response to an unsigned `HEAD` of that URL.
|
|
174
|
+
* No capability is invoked. The result is memoized for the life of the
|
|
175
|
+
* client and shared by every handle; concurrent callers share one
|
|
176
|
+
* discovery, and a failure is not memoized, so the next call retries.
|
|
138
177
|
*
|
|
139
178
|
* Every signed request waits on this discovery, so a caller rarely needs to
|
|
140
179
|
* call it first. It is the way to read the server-wide affordances:
|
|
@@ -150,10 +189,9 @@ export class WasClient {
|
|
|
150
189
|
* caller about to rely on an affordance the server may have stopped
|
|
151
190
|
* advertising
|
|
152
191
|
* @returns {Promise<ServiceInfo>}
|
|
153
|
-
* @throws {IncompatibleServerError} when the
|
|
154
|
-
* `service` link (
|
|
155
|
-
* no version this client speaks
|
|
156
|
-
* other than `serverUrl`
|
|
192
|
+
* @throws {IncompatibleServerError} when the probed response carries no
|
|
193
|
+
* `service` link (the server predates v0.5), the document is malformed,
|
|
194
|
+
* or it lists no version this client speaks
|
|
157
195
|
*/
|
|
158
196
|
async service(options = {}) {
|
|
159
197
|
if (options.refresh) {
|
|
@@ -163,31 +201,30 @@ export class WasClient {
|
|
|
163
201
|
return this.#service.get();
|
|
164
202
|
}
|
|
165
203
|
/**
|
|
166
|
-
* Waits for discovery and
|
|
167
|
-
*
|
|
168
|
-
* `spaces` URL names `serverUrl`, so callers address `serverUrl` directly.
|
|
204
|
+
* Waits for discovery and returns the Spaces Repository URL the service
|
|
205
|
+
* description names, refusing a server whose description has none.
|
|
169
206
|
*
|
|
170
|
-
* @returns {Promise<
|
|
207
|
+
* @returns {Promise<string>}
|
|
171
208
|
* @throws {NotSupportedError} when the server does not implement the
|
|
172
209
|
* Spaces Repository
|
|
173
210
|
*/
|
|
174
|
-
async #
|
|
175
|
-
const { spacesUrl, version } = await this.service();
|
|
211
|
+
async #spacesRepositoryUrl() {
|
|
212
|
+
const { spacesUrl, version, description } = await this.service();
|
|
176
213
|
if (spacesUrl === undefined) {
|
|
177
|
-
throw new NotSupportedError(`The server at "${
|
|
214
|
+
throw new NotSupportedError(`The server at "${description.url}" does not implement the Spaces ` +
|
|
178
215
|
`Repository: its WAS ${version} service description entry has no ` +
|
|
179
216
|
'`spaces` URL.');
|
|
180
217
|
}
|
|
218
|
+
return spacesUrl;
|
|
181
219
|
}
|
|
182
220
|
#cachedContext;
|
|
183
221
|
get #context() {
|
|
184
|
-
// `
|
|
185
|
-
//
|
|
186
|
-
//
|
|
222
|
+
// `zcapClient` and `encryption` are constructor-fixed, so the context is
|
|
223
|
+
// derived once and reused rather than reallocating the object on every
|
|
224
|
+
// handle access.
|
|
187
225
|
if (this.#cachedContext === undefined) {
|
|
188
226
|
const readControllerDid = () => this.controllerDid;
|
|
189
227
|
this.#cachedContext = {
|
|
190
|
-
baseUrl: this.baseUrl,
|
|
191
228
|
zcapClient: this.zcapClient,
|
|
192
229
|
// Read lazily, so building a handle costs nothing and a
|
|
193
230
|
// delegation-only client (a `ZcapClient` with a delegation signer and
|
|
@@ -204,9 +241,13 @@ export class WasClient {
|
|
|
204
241
|
return this.#cachedContext;
|
|
205
242
|
}
|
|
206
243
|
/**
|
|
207
|
-
* Returns a lazy handle to a
|
|
244
|
+
* Returns a lazy handle to a Space by its absolute URL, as the server
|
|
245
|
+
* named it (the `Location` of the create response, a listing item's `url`,
|
|
246
|
+
* a stored pointer, or the URL a self-locating DID resolves to). No I/O.
|
|
247
|
+
* The URL is canonicalized (see `canonicalSpaceUrl` on the `./paths`
|
|
248
|
+
* entry), and every Collection and Resource URL derives from it.
|
|
208
249
|
*
|
|
209
|
-
* @param
|
|
250
|
+
* @param spaceUrl {string}
|
|
210
251
|
* @param options {object}
|
|
211
252
|
* @param [options.capability] {IZcap}
|
|
212
253
|
* @param [options.encryption] {EncryptionOverride} the default encryption
|
|
@@ -214,11 +255,12 @@ export class WasClient {
|
|
|
214
255
|
* `EncryptionOverride`); `space.collection(id, { encryption })` overrides
|
|
215
256
|
* it per collection
|
|
216
257
|
* @returns {Space}
|
|
258
|
+
* @throws {ValidationError} when `spaceUrl` is not a Space URL
|
|
217
259
|
*/
|
|
218
|
-
|
|
260
|
+
spaceAt(spaceUrl, options = {}) {
|
|
219
261
|
return new Space({
|
|
220
262
|
context: this.#context,
|
|
221
|
-
|
|
263
|
+
spaceUrl,
|
|
222
264
|
capability: options.capability,
|
|
223
265
|
encryption: options.encryption
|
|
224
266
|
});
|
|
@@ -227,7 +269,9 @@ export class WasClient {
|
|
|
227
269
|
* Creates a space (server-generated id unless `id` is given). `name` is
|
|
228
270
|
* optional (both in the spec and on the reference server); `controller` must
|
|
229
271
|
* match the wrapped signer's DID (which is the default). The request goes
|
|
230
|
-
* to the Spaces Repository URL the service description names
|
|
272
|
+
* to the Spaces Repository URL the service description names, and the
|
|
273
|
+
* returned handle is opened on the Space URL the response's `Location`
|
|
274
|
+
* names: the server chooses where the Space lives.
|
|
231
275
|
*
|
|
232
276
|
* @param desc {object}
|
|
233
277
|
* @param [desc.id] {string}
|
|
@@ -239,6 +283,7 @@ export class WasClient {
|
|
|
239
283
|
* immutable after creation
|
|
240
284
|
* @returns {Promise<Space>}
|
|
241
285
|
* @throws {NotSupportedError} when the server has no Spaces Repository
|
|
286
|
+
* @throws {WasServerError} when the create response carries no `Location`
|
|
242
287
|
*/
|
|
243
288
|
async createSpace(desc = {}) {
|
|
244
289
|
const controller = desc.controller ?? this.controllerDid;
|
|
@@ -248,13 +293,22 @@ export class WasClient {
|
|
|
248
293
|
...(desc.name !== undefined && { name: desc.name }),
|
|
249
294
|
...(desc.type !== undefined && { type: desc.type })
|
|
250
295
|
};
|
|
251
|
-
await this.#
|
|
296
|
+
const spacesUrl = await this.#spacesRepositoryUrl();
|
|
252
297
|
const response = await send(this.#context, {
|
|
253
|
-
url:
|
|
298
|
+
url: spacesUrl,
|
|
254
299
|
method: 'POST',
|
|
255
300
|
json: body
|
|
256
301
|
});
|
|
257
|
-
|
|
302
|
+
// Only the `Location` is needed here: the Space id is read off the Space
|
|
303
|
+
// URL by the handle, so the response body's `id` goes unread.
|
|
304
|
+
const location = response?.headers.get('location');
|
|
305
|
+
if (!location) {
|
|
306
|
+
throw new WasServerError(`The Create Space response from "${spacesUrl}" carries no ` +
|
|
307
|
+
'`Location` header, so the new Space cannot be located.');
|
|
308
|
+
}
|
|
309
|
+
// RFC 9110 permits a relative `Location`; resolve it against the request
|
|
310
|
+
// URL so the handle is opened on an absolute Space URL.
|
|
311
|
+
return this.spaceAt(new URL(location, spacesUrl).toString());
|
|
258
312
|
}
|
|
259
313
|
/**
|
|
260
314
|
* Lists the spaces in the repository visible to the wrapped signer, as a
|
|
@@ -263,7 +317,8 @@ export class WasClient {
|
|
|
263
317
|
* authorized for, auxiliary spaces included. Each item carries the space's
|
|
264
318
|
* `type` array, the same value as its Space Metadata object's `type`, so a
|
|
265
319
|
* caller can tell an auxiliary space (one whose `type` names
|
|
266
|
-
* `AuxiliarySpace`) from a user-data one without reading each space
|
|
320
|
+
* `AuxiliarySpace`) from a user-data one without reading each space, and
|
|
321
|
+
* its `url`, the Space URL to open a handle on with {@link spaceAt}.
|
|
267
322
|
* An unauthorized caller is not an error -- the server
|
|
268
323
|
* returns an empty `items` list (the spec's explicit exception to 404
|
|
269
324
|
* masking), so nothing is revealed about which spaces exist.
|
|
@@ -277,9 +332,9 @@ export class WasClient {
|
|
|
277
332
|
* @throws {WasServerError} when the listing cannot be read in full
|
|
278
333
|
*/
|
|
279
334
|
async listSpaces() {
|
|
280
|
-
await this.#
|
|
335
|
+
const spacesUrl = await this.#spacesRepositoryUrl();
|
|
281
336
|
const walk = await signedPageWalk(this.#context, {
|
|
282
|
-
firstUrl:
|
|
337
|
+
firstUrl: spacesUrl
|
|
283
338
|
});
|
|
284
339
|
// The first page always carries the listing body (an unauthorized caller
|
|
285
340
|
// still gets an empty `items` list, not an error), so a `null` walk is a
|
|
@@ -287,7 +342,7 @@ export class WasClient {
|
|
|
287
342
|
// body did not parse as JSON. Report it as one, rather than as a
|
|
288
343
|
// `TypeError` from destructuring `null`.
|
|
289
344
|
if (walk === null) {
|
|
290
|
-
throw new WasServerError(`The space listing at "${
|
|
345
|
+
throw new WasServerError(`The space listing at "${spacesUrl}" answered with no JSON body.`);
|
|
291
346
|
}
|
|
292
347
|
return collectPages(walk);
|
|
293
348
|
}
|
|
@@ -321,7 +376,7 @@ export class WasClient {
|
|
|
321
376
|
async #publicListWalk(collectionUrl) {
|
|
322
377
|
return buildPageWalk({
|
|
323
378
|
// The collection listing endpoint is the trailing-slash items URL.
|
|
324
|
-
firstUrl:
|
|
379
|
+
firstUrl: canonicalContainerUrl(collectionUrl),
|
|
325
380
|
fetchPage: async (pageUrl) => {
|
|
326
381
|
const pageResponse = await unsignedRequest({
|
|
327
382
|
url: pageUrl,
|
|
@@ -384,7 +439,15 @@ export class WasClient {
|
|
|
384
439
|
/**
|
|
385
440
|
* Rebuilds an access handle from a received capability, returning a handle at
|
|
386
441
|
* the depth implied by the capability's `invocationTarget` (space /
|
|
387
|
-
* collection / resource), pre-bound with that capability.
|
|
442
|
+
* collection / resource), pre-bound with that capability. The Space is read
|
|
443
|
+
* off the capability's delegation chain, which starts at the Space's root
|
|
444
|
+
* capability (whose id encodes the Space URL), so a capability from any
|
|
445
|
+
* server locates its own Space with no out-of-band base. The root's target
|
|
446
|
+
* is taken to be the Space URL: a Space URL has no shape of its own, so a
|
|
447
|
+
* chain rooted elsewhere (a bare `was.grant({ target })` for a server with
|
|
448
|
+
* no Space hierarchy roots at its target) is read as if that target were
|
|
449
|
+
* the Space, and the server refuses the handle's requests. See `spaceUrlOf`
|
|
450
|
+
* on the `./paths` entry.
|
|
388
451
|
*
|
|
389
452
|
* A resource-scoped capability cannot read the Collection Metadata object, so
|
|
390
453
|
* an encryption-capable client cannot discover whether the collection is
|
|
@@ -401,28 +464,26 @@ export class WasClient {
|
|
|
401
464
|
* @param [options.encryption] {EncryptionOverride} per-handle encryption
|
|
402
465
|
* override for the returned handle (see `EncryptionOverride`)
|
|
403
466
|
* @returns {Space | Collection | Resource}
|
|
467
|
+
* @throws {ValidationError} when the capability's chain starts at no root
|
|
468
|
+
* capability or at one whose target cannot be a Space URL, or its
|
|
469
|
+
* `invocationTarget` is not at or beneath that Space, addresses a
|
|
470
|
+
* reserved sub-resource with no navigational handle, or is not in
|
|
471
|
+
* canonical form (so the handle's requests would fall outside it)
|
|
404
472
|
*/
|
|
405
473
|
fromCapability(zcap, { encryption } = {}) {
|
|
406
474
|
const target = zcap.invocationTarget;
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
//
|
|
414
|
-
|
|
415
|
-
// classifies just as a bare-origin deployment does, which `parseSpacePath`
|
|
416
|
-
// alone cannot) and percent-decodes each segment, since the path builders
|
|
417
|
-
// re-encode every id. Classifying the full segment list -- rather than
|
|
418
|
-
// destructuring the first three ids -- keeps a sub-resource target
|
|
419
|
-
// (`/space/s/policy`, `/space/s/c/r/meta`, ...) from being silently
|
|
420
|
-
// truncated to the nearest containment handle, whose derived URLs would
|
|
421
|
-
// mismatch the capability's invocation target.
|
|
422
|
-
const parsed = parseSpaceTarget({ baseUrl: this.baseUrl, target });
|
|
475
|
+
const spaceUrl = spaceUrlOf(zcap);
|
|
476
|
+
// `parseSpaceTarget` owns the grammar beneath a Space: it percent-decodes
|
|
477
|
+
// each segment (the builders re-encode every id) and classifies the full
|
|
478
|
+
// segment list, so a sub-resource target (`{s}policy`, `{s}{c}/{r}/meta`,
|
|
479
|
+
// ...) is refused rather than silently truncated to the nearest
|
|
480
|
+
// containment handle, whose derived URLs would mismatch the capability's
|
|
481
|
+
// invocation target.
|
|
482
|
+
const parsed = parseSpaceTarget({ spaceUrl, target });
|
|
423
483
|
if (parsed === null) {
|
|
424
484
|
throw new ValidationError(`Cannot derive a handle from invocationTarget "${target}": it does ` +
|
|
425
|
-
`not address
|
|
485
|
+
`not address anything at or beneath the Space "${spaceUrl}" the ` +
|
|
486
|
+
'capability is rooted in.');
|
|
426
487
|
}
|
|
427
488
|
if (parsed.kind === 'sub-resource') {
|
|
428
489
|
throw new ValidationError(`invocationTarget "${target}" addresses a reserved ` +
|
|
@@ -431,37 +492,53 @@ export class WasClient {
|
|
|
431
492
|
'`resource.meta()`), or use the `was.request()` escape hatch.');
|
|
432
493
|
}
|
|
433
494
|
const context = this.#context;
|
|
495
|
+
let handle;
|
|
434
496
|
if (parsed.kind === 'resource') {
|
|
435
|
-
|
|
497
|
+
handle = new Resource({
|
|
436
498
|
context,
|
|
437
|
-
|
|
499
|
+
spaceUrl,
|
|
438
500
|
collectionId: parsed.collectionId,
|
|
439
501
|
resourceId: parsed.resourceId,
|
|
440
502
|
capability: zcap,
|
|
441
503
|
encryption
|
|
442
504
|
});
|
|
443
505
|
}
|
|
444
|
-
if (parsed.kind === 'collection') {
|
|
445
|
-
|
|
506
|
+
else if (parsed.kind === 'collection') {
|
|
507
|
+
handle = new Collection({
|
|
446
508
|
context,
|
|
447
|
-
|
|
509
|
+
spaceUrl,
|
|
448
510
|
collectionId: parsed.collectionId,
|
|
449
511
|
capability: zcap,
|
|
450
512
|
encryption
|
|
451
513
|
});
|
|
452
514
|
}
|
|
453
|
-
|
|
454
|
-
context,
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
515
|
+
else {
|
|
516
|
+
handle = new Space({ context, spaceUrl, capability: zcap, encryption });
|
|
517
|
+
}
|
|
518
|
+
// `send` matches every request URL against the capability's target by
|
|
519
|
+
// string prefix, so a target in a non-canonical serialization (upper-case
|
|
520
|
+
// host, explicit default port) would let the handle be built and then
|
|
521
|
+
// refuse every request from it. Refuse it here, by name.
|
|
522
|
+
if (!isValidTarget({
|
|
523
|
+
invocationTarget: handle.url,
|
|
524
|
+
baseInvocationTarget: target,
|
|
525
|
+
allowTargetAttenuation: true
|
|
526
|
+
})) {
|
|
527
|
+
throw new ValidationError(`invocationTarget "${target}" is not in canonical form: the handle ` +
|
|
528
|
+
`would address "${handle.url}", which the capability does not cover.`);
|
|
529
|
+
}
|
|
530
|
+
return handle;
|
|
459
531
|
}
|
|
460
532
|
/**
|
|
461
533
|
* The general delegation primitive. Delegates a capability per `GrantOptions`
|
|
462
|
-
* and returns the signed zcap to hand off out-of-band. `target` (any URL)
|
|
463
|
-
* `
|
|
464
|
-
*
|
|
534
|
+
* and returns the signed zcap to hand off out-of-band. `target` (any URL),
|
|
535
|
+
* `spaceUrl` (the Space to root a revocable grant in) and `capability` (a
|
|
536
|
+
* parent capability to attenuate) make this a superset of the
|
|
537
|
+
* `space`/`collection` grant sugar, which fills the first two from the
|
|
538
|
+
* handle. Without `spaceUrl` or `capability`, the grant is rooted at the
|
|
539
|
+
* target's own root capability: the shape for a server with no Space
|
|
540
|
+
* hierarchy (fixed collections, or resources alone), where there is no
|
|
541
|
+
* Space to root a chain in. Such a grant is not Space-revocable.
|
|
465
542
|
*
|
|
466
543
|
* @param options {GrantOptions}
|
|
467
544
|
* @returns {Promise<IDelegatedZcap>}
|
|
@@ -470,11 +547,12 @@ export class WasClient {
|
|
|
470
547
|
return delegateGrant(this.#context, options);
|
|
471
548
|
}
|
|
472
549
|
/**
|
|
473
|
-
* The general revocation primitive -- the inverse of {@link grant}.
|
|
474
|
-
* the owning
|
|
475
|
-
*
|
|
476
|
-
*
|
|
477
|
-
* `
|
|
550
|
+
* The general revocation primitive -- the inverse of {@link grant}. Reads
|
|
551
|
+
* the owning Space off the capability's delegation chain (a Space-rooted
|
|
552
|
+
* chain starts at the Space's root capability) and submits it to that
|
|
553
|
+
* Space's revocation endpoint. Equivalent to `was.spaceAt(url).revoke(zcap)`.
|
|
554
|
+
* The chain root's target is taken to be the Space (see `spaceUrlOf` on the
|
|
555
|
+
* `./paths` entry); the server refuses a chain not rooted exactly in it.
|
|
478
556
|
*
|
|
479
557
|
* Revocation is scoped to one space: there is no cross-space or global
|
|
480
558
|
* revocation. See {@link Space.revoke} for who may call it, what it does and
|
|
@@ -482,18 +560,19 @@ export class WasClient {
|
|
|
482
560
|
*
|
|
483
561
|
* @param zcap {IDelegatedZcap} the delegated capability to revoke
|
|
484
562
|
* @returns {Promise<void>}
|
|
563
|
+
* @throws {ValidationError} when the capability's chain starts at no root
|
|
564
|
+
* capability, or at one whose target cannot be a Space URL
|
|
485
565
|
*/
|
|
486
566
|
async revoke(zcap) {
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
spaceId: spaceIdOf(context, zcap),
|
|
567
|
+
return submitRevocation(this.#context, {
|
|
568
|
+
spaceUrl: spaceUrlOf(zcap),
|
|
490
569
|
zcap
|
|
491
570
|
});
|
|
492
571
|
}
|
|
493
572
|
/**
|
|
494
|
-
* The signed escape hatch, mirroring ezcap's generic `request()`.
|
|
495
|
-
*
|
|
496
|
-
*
|
|
573
|
+
* The signed escape hatch, mirroring ezcap's generic `request()`. Takes an
|
|
574
|
+
* absolute `url`, defaults `action` to `method`, uppercases both (as
|
|
575
|
+
* {@link grant} does, so `'put'` signs `PUT`), and signs via the wrapped
|
|
497
576
|
* client. Returns the raw `HttpResponse` and throws raw ky/ezcap
|
|
498
577
|
* errors -- it does not apply the null-on-404 or typed-error conveniences.
|
|
499
578
|
* Like every signed request it waits on {@link service} first, and rejects
|
package/dist/WasClient.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WasClient.js","sourceRoot":"","sources":["../src/WasClient.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"WasClient.js","sourceRoot":"","sources":["../src/WasClient.ts"],"names":[],"mappings":"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"}
|
package/dist/codec.d.ts
CHANGED
|
@@ -444,7 +444,8 @@ export interface EncryptionProvider {
|
|
|
444
444
|
* Builds the encrypting codec for a collection already known to be encrypted.
|
|
445
445
|
*
|
|
446
446
|
* @param input {object}
|
|
447
|
-
* @param input.
|
|
447
|
+
* @param input.spaceUrl {string} the Space holding the collection, in
|
|
448
|
+
* canonical form
|
|
448
449
|
* @param input.collectionId {string}
|
|
449
450
|
* @param input.scheme {string} the declared encryption scheme (e.g. `edv`)
|
|
450
451
|
* @param [input.encryption] {CollectionEncryption} the full encryption
|
|
@@ -460,7 +461,7 @@ export interface EncryptionProvider {
|
|
|
460
461
|
* provider holds no keys / does not handle `scheme` (core then fails closed)
|
|
461
462
|
*/
|
|
462
463
|
codecFor(input: {
|
|
463
|
-
|
|
464
|
+
spaceUrl: string;
|
|
464
465
|
collectionId: string;
|
|
465
466
|
scheme: string;
|
|
466
467
|
encryption?: CollectionEncryption;
|