@interop/wallet-core 0.101.1 → 0.104.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 +36 -17
- package/dist/audiences/audienceGrant.d.ts +49 -0
- package/dist/audiences/audienceGrant.d.ts.map +1 -0
- package/dist/audiences/audienceGrant.js +46 -0
- package/dist/audiences/audienceGrant.js.map +1 -0
- package/dist/audiences/index.d.ts +10 -0
- package/dist/audiences/index.d.ts.map +1 -0
- package/dist/audiences/index.js +10 -0
- package/dist/audiences/index.js.map +1 -0
- package/dist/clientAnnex/grantRevocation.d.ts +0 -18
- package/dist/clientAnnex/grantRevocation.d.ts.map +1 -1
- package/dist/clientAnnex/grantRevocation.js +2 -40
- package/dist/clientAnnex/grantRevocation.js.map +1 -1
- package/dist/clientAnnex/index.d.ts +2 -1
- package/dist/clientAnnex/index.d.ts.map +1 -1
- package/dist/clientAnnex/index.js +2 -1
- package/dist/clientAnnex/index.js.map +1 -1
- package/dist/clientAnnex/log.d.ts +4 -42
- package/dist/clientAnnex/log.d.ts.map +1 -1
- package/dist/clientAnnex/log.js +10 -65
- package/dist/clientAnnex/log.js.map +1 -1
- package/dist/clients/rosterPolicy.d.ts.map +1 -1
- package/dist/clients/rosterPolicy.js +3 -1
- package/dist/clients/rosterPolicy.js.map +1 -1
- package/dist/connections/didKey.d.ts +27 -0
- package/dist/connections/didKey.d.ts.map +1 -1
- package/dist/connections/didKey.js +42 -6
- package/dist/connections/didKey.js.map +1 -1
- package/dist/connections/entry.d.ts +95 -13
- package/dist/connections/entry.d.ts.map +1 -1
- package/dist/connections/entry.js +102 -16
- package/dist/connections/entry.js.map +1 -1
- package/dist/connections/grantProof.d.ts +64 -0
- package/dist/connections/grantProof.d.ts.map +1 -0
- package/dist/connections/grantProof.js +195 -0
- package/dist/connections/grantProof.js.map +1 -0
- package/dist/connections/grants.d.ts +225 -3
- package/dist/connections/grants.d.ts.map +1 -1
- package/dist/connections/grants.js +293 -8
- package/dist/connections/grants.js.map +1 -1
- package/dist/connections/index.d.ts +22 -8
- package/dist/connections/index.d.ts.map +1 -1
- package/dist/connections/index.js +19 -6
- package/dist/connections/index.js.map +1 -1
- package/dist/connections/read.d.ts.map +1 -1
- package/dist/connections/read.js +2 -1
- package/dist/connections/read.js.map +1 -1
- package/dist/connections/resourceId.d.ts +33 -0
- package/dist/connections/resourceId.d.ts.map +1 -1
- package/dist/connections/resourceId.js +88 -8
- package/dist/connections/resourceId.js.map +1 -1
- package/dist/connections/upsert.d.ts +252 -7
- package/dist/connections/upsert.d.ts.map +1 -1
- package/dist/connections/upsert.js +674 -41
- package/dist/connections/upsert.js.map +1 -1
- package/dist/connections/writers.js +2 -1
- package/dist/connections/writers.js.map +1 -1
- package/dist/descriptors/index.d.ts +5 -0
- package/dist/descriptors/index.d.ts.map +1 -1
- package/dist/descriptors/index.js +5 -0
- package/dist/descriptors/index.js.map +1 -1
- package/dist/descriptors/logSource.d.ts +9 -4
- package/dist/descriptors/logSource.d.ts.map +1 -1
- package/dist/descriptors/logSource.js +13 -6
- package/dist/descriptors/logSource.js.map +1 -1
- package/dist/jsonObject.d.ts +16 -0
- package/dist/jsonObject.d.ts.map +1 -0
- package/dist/jsonObject.js +18 -0
- package/dist/jsonObject.js.map +1 -0
- package/dist/keys/index.d.ts +13 -9
- package/dist/keys/index.d.ts.map +1 -1
- package/dist/keys/index.js +11 -7
- package/dist/keys/index.js.map +1 -1
- package/dist/keys/userKeyCascade.d.ts +46 -0
- package/dist/keys/userKeyCascade.d.ts.map +1 -1
- package/dist/keys/userKeyCascade.js +153 -65
- package/dist/keys/userKeyCascade.js.map +1 -1
- package/dist/keys/userKeyRoster.d.ts +60 -7
- package/dist/keys/userKeyRoster.d.ts.map +1 -1
- package/dist/keys/userKeyRoster.js +165 -47
- package/dist/keys/userKeyRoster.js.map +1 -1
- package/dist/keys/userKeyRosterCascade.d.ts.map +1 -1
- package/dist/keys/userKeyRosterCascade.js +1 -0
- package/dist/keys/userKeyRosterCascade.js.map +1 -1
- package/dist/menders/ids.d.ts +1 -1
- package/dist/menders/ids.d.ts.map +1 -1
- package/dist/menders/ids.js +20 -4
- package/dist/menders/ids.js.map +1 -1
- package/dist/resourceLog/controller.d.ts +11 -7
- package/dist/resourceLog/controller.d.ts.map +1 -1
- package/dist/resourceLog/controller.js +15 -31
- package/dist/resourceLog/controller.js.map +1 -1
- package/dist/resourceLog/document.d.ts +9 -11
- package/dist/resourceLog/document.d.ts.map +1 -1
- package/dist/resourceLog/document.js +9 -11
- package/dist/resourceLog/document.js.map +1 -1
- package/dist/space/collections.d.ts +23 -3
- package/dist/space/collections.d.ts.map +1 -1
- package/dist/space/collections.js +26 -2
- package/dist/space/collections.js.map +1 -1
- package/dist/space/inboxMessage.d.ts +47 -0
- package/dist/space/inboxMessage.d.ts.map +1 -0
- package/dist/space/inboxMessage.js +86 -0
- package/dist/space/inboxMessage.js.map +1 -0
- package/dist/space/index.d.ts +6 -1
- package/dist/space/index.d.ts.map +1 -1
- package/dist/space/index.js +5 -1
- package/dist/space/index.js.map +1 -1
- package/dist/sync/contactsConflict.d.ts +23 -10
- package/dist/sync/contactsConflict.d.ts.map +1 -1
- package/dist/sync/contactsConflict.js +40 -21
- package/dist/sync/contactsConflict.js.map +1 -1
- package/dist/unlock/index.d.ts +1 -1
- package/dist/unlock/index.d.ts.map +1 -1
- package/dist/unlock/index.js +1 -1
- package/dist/unlock/index.js.map +1 -1
- package/dist/webvh/clientAnnexDid.d.ts +76 -0
- package/dist/webvh/clientAnnexDid.d.ts.map +1 -0
- package/dist/webvh/clientAnnexDid.js +117 -0
- package/dist/webvh/clientAnnexDid.js.map +1 -0
- package/dist/webvh/didWebProjection.d.ts +38 -5
- package/dist/webvh/didWebProjection.d.ts.map +1 -1
- package/dist/webvh/didWebProjection.js +35 -22
- package/dist/webvh/didWebProjection.js.map +1 -1
- package/dist/webvh/documentDids.d.ts +3 -3
- package/dist/webvh/documentDids.js +3 -3
- package/dist/webvh/index.d.ts +4 -3
- package/dist/webvh/index.d.ts.map +1 -1
- package/dist/webvh/index.js +4 -3
- package/dist/webvh/index.js.map +1 -1
- package/dist/webvh/standingZcap.d.ts +27 -2
- package/dist/webvh/standingZcap.d.ts.map +1 -1
- package/dist/webvh/standingZcap.js +42 -4
- package/dist/webvh/standingZcap.js.map +1 -1
- package/package.json +14 -7
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
* its writer, so the storage host can plant one. The grant checks in
|
|
20
20
|
* `grants.ts` bound what a planted grant can steer.
|
|
21
21
|
*/
|
|
22
|
+
import { base64urlnopad } from '@scure/base';
|
|
23
|
+
import { isJsonObject } from '../jsonObject.js';
|
|
22
24
|
import { normalizeDisplayName } from '../labelText.js';
|
|
23
25
|
/**
|
|
24
26
|
* The entry version this build reads for writing and writes.
|
|
@@ -40,6 +42,19 @@ export const CONNECTION_KINDS = [
|
|
|
40
42
|
* capability. A reader treats any other stored value as a plain grant.
|
|
41
43
|
*/
|
|
42
44
|
export const GRANT_KINDS = ['grant', 'share'];
|
|
45
|
+
/**
|
|
46
|
+
* The `grantKind` vocabulary of `grantsReceived`, the capabilities a party
|
|
47
|
+
* handed the wallet: `'inbox'` is the party's POST capability on its own
|
|
48
|
+
* inbox, the channel a push goes through. An unknown stored value is kept as
|
|
49
|
+
* stored.
|
|
50
|
+
*/
|
|
51
|
+
export const RECEIVED_GRANT_KINDS = ['inbox'];
|
|
52
|
+
/**
|
|
53
|
+
* The byte length of the pairwise seed, and the length of its base64url
|
|
54
|
+
* no-pad text.
|
|
55
|
+
*/
|
|
56
|
+
export const CONNECTION_SEED_BYTES = 32;
|
|
57
|
+
const CONNECTION_SEED_TEXT_LENGTH = 43;
|
|
43
58
|
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
44
59
|
/**
|
|
45
60
|
* The writer policy: inactive after 90 days, at most 8 writers per entry,
|
|
@@ -103,6 +118,8 @@ export function newConnectionEntry({ kind, did, now }) {
|
|
|
103
118
|
firstSeen: stamp,
|
|
104
119
|
lastSeen: stamp,
|
|
105
120
|
grants: [],
|
|
121
|
+
grantsReceived: [],
|
|
122
|
+
outbox: [],
|
|
106
123
|
writers: []
|
|
107
124
|
};
|
|
108
125
|
}
|
|
@@ -116,15 +133,6 @@ export function newConnectionEntry({ kind, did, now }) {
|
|
|
116
133
|
export function isWritableConnectionEntry(entry) {
|
|
117
134
|
return entry.version === CONNECTION_ENTRY_VERSION;
|
|
118
135
|
}
|
|
119
|
-
/**
|
|
120
|
-
* Whether a value is a plain JSON object (not null, not an array).
|
|
121
|
-
*
|
|
122
|
-
* @param value {unknown}
|
|
123
|
-
* @returns {boolean}
|
|
124
|
-
*/
|
|
125
|
-
export function isJsonObject(value) {
|
|
126
|
-
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
127
|
-
}
|
|
128
136
|
/**
|
|
129
137
|
* Whether a value is a string `Date.parse` reads as a time.
|
|
130
138
|
*
|
|
@@ -145,7 +153,8 @@ function isOptionalString(value) {
|
|
|
145
153
|
}
|
|
146
154
|
/**
|
|
147
155
|
* Reads a stored capability's known members, or `undefined` when one of them
|
|
148
|
-
* has the wrong shape. The capability itself is
|
|
156
|
+
* has the wrong shape or `expires` is absent. The capability itself is
|
|
157
|
+
* returned verbatim.
|
|
149
158
|
*
|
|
150
159
|
* @param value {unknown}
|
|
151
160
|
* @returns {ConnectionZcap | undefined}
|
|
@@ -163,7 +172,7 @@ export function parseConnectionZcap(value) {
|
|
|
163
172
|
typeof allowedAction !== 'string' &&
|
|
164
173
|
!(Array.isArray(allowedAction) &&
|
|
165
174
|
allowedAction.every(action => typeof action === 'string'))) ||
|
|
166
|
-
|
|
175
|
+
!isTimestamp(expires)) {
|
|
167
176
|
return undefined;
|
|
168
177
|
}
|
|
169
178
|
return value;
|
|
@@ -181,11 +190,70 @@ function parseGrantRecord(value) {
|
|
|
181
190
|
}
|
|
182
191
|
if (parseConnectionZcap(value.zcap) === undefined ||
|
|
183
192
|
typeof value.grantKind !== 'string' ||
|
|
184
|
-
!isTimestamp(value.grantedAt)
|
|
193
|
+
!isTimestamp(value.grantedAt) ||
|
|
194
|
+
(value.renewedAt !== undefined && !isTimestamp(value.renewedAt))) {
|
|
195
|
+
return undefined;
|
|
196
|
+
}
|
|
197
|
+
return value;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Reads one stored received-grant wrapper, or `undefined` when a known
|
|
201
|
+
* member has the wrong shape. The wrapper is returned verbatim, unknown
|
|
202
|
+
* members included.
|
|
203
|
+
*
|
|
204
|
+
* @param value {unknown}
|
|
205
|
+
* @returns {ConnectionReceivedGrantRecord | undefined}
|
|
206
|
+
*/
|
|
207
|
+
function parseReceivedGrantRecord(value) {
|
|
208
|
+
if (!isJsonObject(value)) {
|
|
209
|
+
return undefined;
|
|
210
|
+
}
|
|
211
|
+
if (parseConnectionZcap(value.zcap) === undefined ||
|
|
212
|
+
typeof value.grantKind !== 'string' ||
|
|
213
|
+
!isTimestamp(value.receivedAt)) {
|
|
214
|
+
return undefined;
|
|
215
|
+
}
|
|
216
|
+
return value;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Reads one stored outbox item, or `undefined` when a known member has the
|
|
220
|
+
* wrong shape: `message` must be a JSON object and `createdAt` a timestamp.
|
|
221
|
+
* The item is returned verbatim.
|
|
222
|
+
*
|
|
223
|
+
* @param value {unknown}
|
|
224
|
+
* @returns {ConnectionOutboxItem | undefined}
|
|
225
|
+
*/
|
|
226
|
+
function parseOutboxItem(value) {
|
|
227
|
+
if (!isJsonObject(value)) {
|
|
228
|
+
return undefined;
|
|
229
|
+
}
|
|
230
|
+
if (!isJsonObject(value.message) || !isTimestamp(value.createdAt)) {
|
|
185
231
|
return undefined;
|
|
186
232
|
}
|
|
187
233
|
return value;
|
|
188
234
|
}
|
|
235
|
+
/**
|
|
236
|
+
* The seed bytes a stored `seed` member decodes to, or `undefined` when it
|
|
237
|
+
* is not 43 characters of base64url with no padding decoding to 32 bytes.
|
|
238
|
+
* The same rule reads a stored `seedTag`, which has the same length.
|
|
239
|
+
*
|
|
240
|
+
* @param value {unknown}
|
|
241
|
+
* @returns {Uint8Array | undefined}
|
|
242
|
+
*/
|
|
243
|
+
export function decodeConnectionSeed(value) {
|
|
244
|
+
if (typeof value !== 'string' ||
|
|
245
|
+
value.length !== CONNECTION_SEED_TEXT_LENGTH) {
|
|
246
|
+
return undefined;
|
|
247
|
+
}
|
|
248
|
+
let bytes;
|
|
249
|
+
try {
|
|
250
|
+
bytes = base64urlnopad.decode(value);
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
return undefined;
|
|
254
|
+
}
|
|
255
|
+
return bytes.length === CONNECTION_SEED_BYTES ? bytes : undefined;
|
|
256
|
+
}
|
|
189
257
|
/**
|
|
190
258
|
* Reads one stored writer member, or `undefined` when a known member has the
|
|
191
259
|
* wrong shape. The member is returned verbatim, unknown members included.
|
|
@@ -217,9 +285,12 @@ function parseWriter(value) {
|
|
|
217
285
|
* is not a DID, a `name`, `label`, or writer `label` outside the display-name
|
|
218
286
|
* rule (1 to 64 code points once the control and bidi characters are stripped
|
|
219
287
|
* and the result trimmed), a timestamp `Date.parse` cannot read, a malformed
|
|
220
|
-
* grant wrapper
|
|
221
|
-
*
|
|
222
|
-
*
|
|
288
|
+
* grant wrapper, received-grant wrapper, outbox item, or writer member, a
|
|
289
|
+
* `seed` or `seedTag` that is not 43 characters of base64url decoding to 32
|
|
290
|
+
* bytes, a `seed` with no `seedTag` (or the reverse), or no `id` beside
|
|
291
|
+
* anything but exactly one writer. Every display string a view renders is
|
|
292
|
+
* held to that one rule. An absent `grantsReceived` or `outbox` (a body an
|
|
293
|
+
* older build wrote) reads as empty. Unknown members are ignored. A body with a `version` above this build's
|
|
223
294
|
* that passes every check is returned for display;
|
|
224
295
|
* {@link isWritableConnectionEntry} says it cannot be written.
|
|
225
296
|
*
|
|
@@ -234,7 +305,7 @@ export function parseConnectionEntry(body) {
|
|
|
234
305
|
if (!isJsonObject(body)) {
|
|
235
306
|
return undefined;
|
|
236
307
|
}
|
|
237
|
-
const { version, kind, id, name, label, origin, url, appKey, firstSeen, lastSeen, retired, grants, writers } = body;
|
|
308
|
+
const { version, kind, id, name, label, origin, url, appKey, firstSeen, lastSeen, retired, declined, seed, seedTag, grants, grantsReceived, outbox, writers } = body;
|
|
238
309
|
if (typeof version !== 'number' ||
|
|
239
310
|
!Number.isInteger(version) ||
|
|
240
311
|
version < 1 ||
|
|
@@ -249,7 +320,13 @@ export function parseConnectionEntry(body) {
|
|
|
249
320
|
!isTimestamp(firstSeen) ||
|
|
250
321
|
!isTimestamp(lastSeen) ||
|
|
251
322
|
(retired !== undefined && !isTimestamp(retired)) ||
|
|
323
|
+
(declined !== undefined && !isTimestamp(declined)) ||
|
|
324
|
+
(seed !== undefined && decodeConnectionSeed(seed) === undefined) ||
|
|
325
|
+
(seedTag !== undefined && decodeConnectionSeed(seedTag) === undefined) ||
|
|
326
|
+
(seed === undefined) !== (seedTag === undefined) ||
|
|
252
327
|
!Array.isArray(grants) ||
|
|
328
|
+
(grantsReceived !== undefined && !Array.isArray(grantsReceived)) ||
|
|
329
|
+
(outbox !== undefined && !Array.isArray(outbox)) ||
|
|
253
330
|
!Array.isArray(writers)) {
|
|
254
331
|
return undefined;
|
|
255
332
|
}
|
|
@@ -260,8 +337,12 @@ export function parseConnectionEntry(body) {
|
|
|
260
337
|
return undefined;
|
|
261
338
|
}
|
|
262
339
|
const parsedGrants = grants.map(parseGrantRecord);
|
|
340
|
+
const parsedReceived = (grantsReceived ?? []).map(parseReceivedGrantRecord);
|
|
341
|
+
const parsedOutbox = (outbox ?? []).map(parseOutboxItem);
|
|
263
342
|
const parsedWriters = writers.map(parseWriter);
|
|
264
343
|
if (parsedGrants.some(grant => grant === undefined) ||
|
|
344
|
+
parsedReceived.some(grant => grant === undefined) ||
|
|
345
|
+
parsedOutbox.some(item => item === undefined) ||
|
|
265
346
|
parsedWriters.some(writer => writer === undefined)) {
|
|
266
347
|
return undefined;
|
|
267
348
|
}
|
|
@@ -280,7 +361,12 @@ export function parseConnectionEntry(body) {
|
|
|
280
361
|
firstSeen,
|
|
281
362
|
lastSeen,
|
|
282
363
|
...(retired !== undefined && { retired }),
|
|
364
|
+
...(declined !== undefined && { declined }),
|
|
365
|
+
...(seed !== undefined && { seed: seed }),
|
|
366
|
+
...(seedTag !== undefined && { seedTag: seedTag }),
|
|
283
367
|
grants: parsedGrants,
|
|
368
|
+
grantsReceived: parsedReceived,
|
|
369
|
+
outbox: parsedOutbox,
|
|
284
370
|
writers: parsedWriters
|
|
285
371
|
};
|
|
286
372
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../../src/connections/entry.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAEtD;;GAEG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAA;AAEzC;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,KAAK;IACL,OAAO;IACP,eAAe;IACf,SAAS;CACD,CAAA;AAOV;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,OAAO,CAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../../src/connections/entry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { ConnectionZcap } from './entry.js';
|
|
2
|
+
import type { PublishedKeyDocument } from '../webvh/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Why a recorded grant's proof does not verify as this account's. On the
|
|
5
|
+
* root arm the reasons describe the grant's own proof; on the annex arm they
|
|
6
|
+
* describe the embedded parent's, since that is the proof verified there.
|
|
7
|
+
*
|
|
8
|
+
* - `unsigned` -- the proof is absent or names no `verificationMethod`.
|
|
9
|
+
* - `unsupported-suite` -- the proof is not an `eddsa-jcs-2022`
|
|
10
|
+
* `DataIntegrityProof` for `capabilityDelegation`, the one suite every
|
|
11
|
+
* delegation this library mints carries.
|
|
12
|
+
* - `signer-unlisted` -- the proof's `verificationMethod` dereferences to no
|
|
13
|
+
* `capabilityDelegation` member of the current document that publishes a
|
|
14
|
+
* key (`relationMemberNamed`, then `memberKeyMultibase`: the fragment is an
|
|
15
|
+
* opaque selector, never read as the key), and it is not the did:key form
|
|
16
|
+
* of a key the relation publishes: the current-key-set rule.
|
|
17
|
+
* - `signature-invalid` -- the signer is listed, and the signature does not
|
|
18
|
+
* verify over the capability under the key the document publishes for it.
|
|
19
|
+
* - `parent-not-annex` -- the grant embeds a parent whose `controller` is
|
|
20
|
+
* not an annex DID in the account's auxiliary Space, or the account points
|
|
21
|
+
* at no annex generation.
|
|
22
|
+
*/
|
|
23
|
+
export type GrantProofRefusal = 'unsigned' | 'unsupported-suite' | 'signer-unlisted' | 'signature-invalid' | 'parent-not-annex';
|
|
24
|
+
/**
|
|
25
|
+
* The outcome of {@link verifyRecordedGrantProof}: verified, with the id of
|
|
26
|
+
* the verification method whose signature was checked (the grant's own
|
|
27
|
+
* signer on the root arm, the parent's on the annex arm), or refused with
|
|
28
|
+
* the reason.
|
|
29
|
+
*/
|
|
30
|
+
export type GrantProofResult = {
|
|
31
|
+
verified: true;
|
|
32
|
+
signerKeyId: string;
|
|
33
|
+
} | {
|
|
34
|
+
verified: false;
|
|
35
|
+
reason: GrantProofRefusal;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Whether a recorded grant's delegation proof verifies as this account's,
|
|
39
|
+
* against the locally verified account document. A grant with no embedded
|
|
40
|
+
* parent is verified by its own proof (the root arm); a grant embedding its
|
|
41
|
+
* parent delegation as the last link of its `proof.capabilityChain` is
|
|
42
|
+
* verified by that parent's proof, after the parent's `controller` is found
|
|
43
|
+
* to be an annex DID in the account's auxiliary Space (the annex arm). A
|
|
44
|
+
* refusal says why. The check reads the current document alone, with no log
|
|
45
|
+
* history and no network.
|
|
46
|
+
*
|
|
47
|
+
* @param options {object}
|
|
48
|
+
* @param options.zcap {ConnectionZcap} the recorded capability, verbatim
|
|
49
|
+
* @param options.signerCheck {object} what the grant is read against
|
|
50
|
+
* @param options.signerCheck.doc {PublishedKeyDocument} the locally
|
|
51
|
+
* verified account document
|
|
52
|
+
* @param [options.signerCheck.clientAnnexDid] {string} the annex DID the
|
|
53
|
+
* document's delegated-clients pointer currently names; absent when it
|
|
54
|
+
* names none, which refuses every annex-arm grant
|
|
55
|
+
* @returns {Promise<GrantProofResult>}
|
|
56
|
+
*/
|
|
57
|
+
export declare function verifyRecordedGrantProof({ zcap, signerCheck }: {
|
|
58
|
+
zcap: ConnectionZcap;
|
|
59
|
+
signerCheck: {
|
|
60
|
+
doc: PublishedKeyDocument;
|
|
61
|
+
clientAnnexDid?: string;
|
|
62
|
+
};
|
|
63
|
+
}): Promise<GrantProofResult>;
|
|
64
|
+
//# sourceMappingURL=grantProof.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grantProof.d.ts","sourceRoot":"","sources":["../../src/connections/grantProof.ts"],"names":[],"mappings":"AAyCA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAKhD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAG7D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,iBAAiB,GACzB,UAAU,GACV,mBAAmB,GACnB,iBAAiB,GACjB,mBAAmB,GACnB,kBAAkB,CAAA;AAEtB;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,EAAE,IAAI,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,QAAQ,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,iBAAiB,CAAA;CAAE,CAAA;AAuJlD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,wBAAwB,CAAC,EAC7C,IAAI,EACJ,WAAW,EACZ,EAAE;IACD,IAAI,EAAE,cAAc,CAAA;IACpB,WAAW,EAAE;QAAE,GAAG,EAAE,oBAAoB,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CACpE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAiB5B"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* The proof check a recorded grant passes before the wallet renews it under
|
|
6
|
+
* the account's authority: whether the grant's delegation proof was signed
|
|
7
|
+
* by a key the locally verified account document lists now, with the
|
|
8
|
+
* signature verified over the capability rather than the signer's name
|
|
9
|
+
* matched alone.
|
|
10
|
+
*
|
|
11
|
+
* The check exists because only the host can plant a directory entry, and a
|
|
12
|
+
* host colluding with a withdrawn party that kept the directory's
|
|
13
|
+
* blinded-index key can write an agent entry at a valid id carrying forged
|
|
14
|
+
* grants whose proofs name a current key. A renewal pass that matched the
|
|
15
|
+
* proof's `verificationMethod` against the document and verified no
|
|
16
|
+
* signature would then sign real account delegations for the planted party.
|
|
17
|
+
*
|
|
18
|
+
* Two arms, by how the grant was delegated. A grant delegated straight under
|
|
19
|
+
* the Space root is signed by an enrolled client's key or a ladder VM, and
|
|
20
|
+
* its own proof is verified: the signer must stand under
|
|
21
|
+
* `capabilityDelegation` in the current document, and the signature must
|
|
22
|
+
* verify over the capability under that key. A grant a transient session
|
|
23
|
+
* minted chains under the generation delegation embedded as the last link
|
|
24
|
+
* of its `proof.capabilityChain`, and the parent is what is verified: it
|
|
25
|
+
* must be delegated to an annex DID in the account's auxiliary Space (the
|
|
26
|
+
* Space the account's delegated-clients pointer names, compared by host and
|
|
27
|
+
* Space id, so a grant minted under a generation a later GC collected still
|
|
28
|
+
* passes), and its own proof must verify under a key or ladder VM the
|
|
29
|
+
* current document lists. The leaf's per-visit annex VM is not verified:
|
|
30
|
+
* once its generation is collected its method is gone, and the account
|
|
31
|
+
* document never listed it.
|
|
32
|
+
*/
|
|
33
|
+
import { DataIntegrityProof } from '@interop/data-integrity-proof';
|
|
34
|
+
import { createVerifyCryptosuite } from '@interop/ed25519-signature/eddsa-jcs-2022';
|
|
35
|
+
import { memberKeyMultibase, relationKeyMultibases, relationMemberNamed, vmFragmentOf } from '@interop/vh-resource-log';
|
|
36
|
+
import { embeddedParentCapability, firstDelegationProof } from '../webvh/index.js';
|
|
37
|
+
import { parseClientAnnexDid } from '../webvh/clientAnnexDid.js';
|
|
38
|
+
/**
|
|
39
|
+
* The suite every delegation proof this library mints carries, and the one
|
|
40
|
+
* this check verifies.
|
|
41
|
+
*/
|
|
42
|
+
const DELEGATION_PROOF_SHAPE = {
|
|
43
|
+
type: 'DataIntegrityProof',
|
|
44
|
+
cryptosuite: 'eddsa-jcs-2022',
|
|
45
|
+
proofPurpose: 'capabilityDelegation'
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Verifies one capability's delegation proof against the current document:
|
|
49
|
+
* the signer must stand under `capabilityDelegation`, and the signature must
|
|
50
|
+
* verify over the capability under that key. The key material is what the
|
|
51
|
+
* document publishes for the signer, so no resolver is consulted. A proof
|
|
52
|
+
* naming a `capabilityDelegation` member of the document (`${did}#${fragment}`
|
|
53
|
+
* dereferenced through the library's `relationMemberNamed`) verifies under
|
|
54
|
+
* that member's `publicKeyMultibase`; the fragment is an opaque selector and
|
|
55
|
+
* is never read as the key, the rule the library's own log verifier applies.
|
|
56
|
+
* A proof naming the did:key form of a key (`did:key:<key>#<key>`, the form a
|
|
57
|
+
* client signs under) verifies under that key when the relation publishes it.
|
|
58
|
+
* A proof set is read by its first proof, as every other reader of a
|
|
59
|
+
* delegation does.
|
|
60
|
+
*
|
|
61
|
+
* @param options {object}
|
|
62
|
+
* @param options.zcap {IZcap} the capability, proof included
|
|
63
|
+
* @param options.doc {PublishedKeyDocument} the locally verified account
|
|
64
|
+
* document
|
|
65
|
+
* @returns {Promise<GrantProofResult>}
|
|
66
|
+
*/
|
|
67
|
+
async function verifyDelegationProof({ zcap, doc }) {
|
|
68
|
+
const { proof: _proof, ...document } = zcap;
|
|
69
|
+
const single = firstDelegationProof(zcap);
|
|
70
|
+
if (single === undefined || typeof single.verificationMethod !== 'string') {
|
|
71
|
+
return { verified: false, reason: 'unsigned' };
|
|
72
|
+
}
|
|
73
|
+
if (single.type !== DELEGATION_PROOF_SHAPE.type ||
|
|
74
|
+
single.cryptosuite !== DELEGATION_PROOF_SHAPE.cryptosuite ||
|
|
75
|
+
single.proofPurpose !== DELEGATION_PROOF_SHAPE.proofPurpose) {
|
|
76
|
+
return { verified: false, reason: 'unsupported-suite' };
|
|
77
|
+
}
|
|
78
|
+
const signerKeyId = single.verificationMethod;
|
|
79
|
+
const keyMultibase = listedSignerKey({ doc, signerKeyId });
|
|
80
|
+
if (keyMultibase === undefined) {
|
|
81
|
+
return { verified: false, reason: 'signer-unlisted' };
|
|
82
|
+
}
|
|
83
|
+
const suite = new DataIntegrityProof({
|
|
84
|
+
cryptosuite: createVerifyCryptosuite()
|
|
85
|
+
});
|
|
86
|
+
// The suite's verify step edits the document's `@context` in place and
|
|
87
|
+
// the proof's copy is read beside it, so both are handed over as copies.
|
|
88
|
+
const result = await suite.verifyProof({
|
|
89
|
+
proof: structuredClone(single),
|
|
90
|
+
document: structuredClone(document),
|
|
91
|
+
documentLoader: async (url) => {
|
|
92
|
+
if (url !== signerKeyId) {
|
|
93
|
+
throw new Error(`No document is served for "${url}".`);
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
documentUrl: url,
|
|
97
|
+
document: {
|
|
98
|
+
id: signerKeyId,
|
|
99
|
+
type: 'Multikey',
|
|
100
|
+
controller: signerKeyId.slice(0, signerKeyId.indexOf('#')),
|
|
101
|
+
publicKeyMultibase: keyMultibase
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
if (!result.verified) {
|
|
107
|
+
return { verified: false, reason: 'signature-invalid' };
|
|
108
|
+
}
|
|
109
|
+
return { verified: true, signerKeyId };
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* The key the document publishes under `capabilityDelegation` for a proof's
|
|
113
|
+
* `verificationMethod` DID URL, or `undefined` when the URL names no listed
|
|
114
|
+
* key. A URL under the document's DID dereferences to the member it names
|
|
115
|
+
* and takes that member's published key. A did:key URL carries its key in
|
|
116
|
+
* the DID itself and must name a key the relation publishes.
|
|
117
|
+
*
|
|
118
|
+
* @param options {object}
|
|
119
|
+
* @param options.doc {PublishedKeyDocument}
|
|
120
|
+
* @param options.signerKeyId {string} the proof's `verificationMethod`
|
|
121
|
+
* @returns {string | undefined}
|
|
122
|
+
*/
|
|
123
|
+
function listedSignerKey({ doc, signerKeyId }) {
|
|
124
|
+
const hash = signerKeyId.indexOf('#');
|
|
125
|
+
const fragment = vmFragmentOf(signerKeyId);
|
|
126
|
+
if (hash === -1 || fragment === undefined) {
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
const did = signerKeyId.slice(0, hash);
|
|
130
|
+
const relation = 'capabilityDelegation';
|
|
131
|
+
const member = relationMemberNamed({ doc, relation, did, fragment });
|
|
132
|
+
if (member !== undefined) {
|
|
133
|
+
return memberKeyMultibase(member);
|
|
134
|
+
}
|
|
135
|
+
if (did === `did:key:${fragment}` &&
|
|
136
|
+
relationKeyMultibases({ doc, relation }).has(fragment)) {
|
|
137
|
+
return fragment;
|
|
138
|
+
}
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Whether two annex DIDs name the same auxiliary Space: the same host and
|
|
143
|
+
* the same Space id, whatever their generations. A string that is not an
|
|
144
|
+
* annex DID names no Space.
|
|
145
|
+
*
|
|
146
|
+
* @param options {object}
|
|
147
|
+
* @param options.did {string}
|
|
148
|
+
* @param options.other {string}
|
|
149
|
+
* @returns {boolean}
|
|
150
|
+
*/
|
|
151
|
+
function sameAuxiliarySpace({ did, other }) {
|
|
152
|
+
const parts = parseClientAnnexDid(did);
|
|
153
|
+
const otherParts = parseClientAnnexDid(other);
|
|
154
|
+
return (parts !== undefined &&
|
|
155
|
+
otherParts !== undefined &&
|
|
156
|
+
parts.host === otherParts.host &&
|
|
157
|
+
parts.spaceId === otherParts.spaceId);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Whether a recorded grant's delegation proof verifies as this account's,
|
|
161
|
+
* against the locally verified account document. A grant with no embedded
|
|
162
|
+
* parent is verified by its own proof (the root arm); a grant embedding its
|
|
163
|
+
* parent delegation as the last link of its `proof.capabilityChain` is
|
|
164
|
+
* verified by that parent's proof, after the parent's `controller` is found
|
|
165
|
+
* to be an annex DID in the account's auxiliary Space (the annex arm). A
|
|
166
|
+
* refusal says why. The check reads the current document alone, with no log
|
|
167
|
+
* history and no network.
|
|
168
|
+
*
|
|
169
|
+
* @param options {object}
|
|
170
|
+
* @param options.zcap {ConnectionZcap} the recorded capability, verbatim
|
|
171
|
+
* @param options.signerCheck {object} what the grant is read against
|
|
172
|
+
* @param options.signerCheck.doc {PublishedKeyDocument} the locally
|
|
173
|
+
* verified account document
|
|
174
|
+
* @param [options.signerCheck.clientAnnexDid] {string} the annex DID the
|
|
175
|
+
* document's delegated-clients pointer currently names; absent when it
|
|
176
|
+
* names none, which refuses every annex-arm grant
|
|
177
|
+
* @returns {Promise<GrantProofResult>}
|
|
178
|
+
*/
|
|
179
|
+
export async function verifyRecordedGrantProof({ zcap, signerCheck }) {
|
|
180
|
+
const parent = embeddedParentCapability(zcap);
|
|
181
|
+
if (parent === undefined) {
|
|
182
|
+
return verifyDelegationProof({
|
|
183
|
+
zcap: zcap,
|
|
184
|
+
doc: signerCheck.doc
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
const { controller } = parent;
|
|
188
|
+
if (typeof controller !== 'string' ||
|
|
189
|
+
signerCheck.clientAnnexDid === undefined ||
|
|
190
|
+
!sameAuxiliarySpace({ did: controller, other: signerCheck.clientAnnexDid })) {
|
|
191
|
+
return { verified: false, reason: 'parent-not-annex' };
|
|
192
|
+
}
|
|
193
|
+
return verifyDelegationProof({ zcap: parent, doc: signerCheck.doc });
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=grantProof.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grantProof.js","sourceRoot":"","sources":["../../src/connections/grantProof.ts"],"names":[],"mappings":"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"}
|