@interop/wallet-core 0.44.0 → 0.45.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/dist/clients/revocation.d.ts +2 -25
- package/dist/clients/revocation.d.ts.map +1 -1
- package/dist/clients/revocation.js +25 -96
- package/dist/clients/revocation.js.map +1 -1
- package/dist/keys/index.d.ts +7 -0
- package/dist/keys/index.d.ts.map +1 -1
- package/dist/keys/index.js +6 -0
- package/dist/keys/index.js.map +1 -1
- package/dist/keys/userKeyRosterCascade.d.ts +121 -0
- package/dist/keys/userKeyRosterCascade.d.ts.map +1 -0
- package/dist/keys/userKeyRosterCascade.js +125 -0
- package/dist/keys/userKeyRosterCascade.js.map +1 -0
- package/dist/recovery/recoveryWebvh.d.ts +9 -2
- package/dist/recovery/recoveryWebvh.d.ts.map +1 -1
- package/dist/recovery/recoveryWebvh.js +4 -2
- package/dist/recovery/recoveryWebvh.js.map +1 -1
- package/dist/unlock/index.d.ts +5 -0
- package/dist/unlock/index.d.ts.map +1 -1
- package/dist/unlock/index.js +4 -0
- package/dist/unlock/index.js.map +1 -1
- package/dist/unlock/retire.d.ts +126 -0
- package/dist/unlock/retire.d.ts.map +1 -0
- package/dist/unlock/retire.js +83 -0
- package/dist/unlock/retire.js.map +1 -0
- package/dist/unlock/standingWebvh.d.ts +11 -3
- package/dist/unlock/standingWebvh.d.ts.map +1 -1
- package/dist/unlock/standingWebvh.js +9 -5
- package/dist/unlock/standingWebvh.js.map +1 -1
- package/package.json +1 -1
|
@@ -62,31 +62,8 @@ import type { IKeyAgreementKey } from '@interop/data-integrity-core';
|
|
|
62
62
|
import type { CollectionEncryption } from '@interop/was-client';
|
|
63
63
|
import type { EncryptionDescriptorStore } from '@interop/was-client/edv';
|
|
64
64
|
import { type ClientWebvhUpdateKeys, type PublishedKeyDocument, type RevokedClientKeys, type WebvhIdStore } from '../webvh/index.js';
|
|
65
|
-
import { type UserKey, type UserKeyCascadeResult } from '../keys/index.js';
|
|
66
|
-
|
|
67
|
-
* What the roster's seal backstop reported: `sealed` (the roster log's head
|
|
68
|
-
* still anchored before the document edit, and the backstop append landed),
|
|
69
|
-
* `noop` (already sealed -- the rotation itself was the sealing append, or a
|
|
70
|
-
* re-run found nothing to do), or `failed` (the seal could not run; carried
|
|
71
|
-
* in `error`, never thrown -- the cascade stays a resumable success and the
|
|
72
|
-
* login sweep re-seals).
|
|
73
|
-
*/
|
|
74
|
-
export interface RosterSealReport {
|
|
75
|
-
outcome: 'sealed' | 'noop' | 'failed';
|
|
76
|
-
error?: unknown;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Where the cascade's collection fan-out gets its work: which encrypted
|
|
80
|
-
* collections exist (only the app knows -- a mobile replica names the
|
|
81
|
-
* collections it replicates, a web wallet also lists the app-provisioned ones
|
|
82
|
-
* remotely) and how each one's descriptor store and encryption declaration are
|
|
83
|
-
* reached.
|
|
84
|
-
*/
|
|
85
|
-
export interface CascadeCollections {
|
|
86
|
-
collectionIds: string[] | (() => Promise<string[]>);
|
|
87
|
-
storeFor: (collectionId: string) => EncryptionDescriptorStore;
|
|
88
|
-
isEncrypted?: (collectionId: string) => Promise<boolean>;
|
|
89
|
-
}
|
|
65
|
+
import { type CascadeCollections, type RosterSealReport, type UserKey, type UserKeyCascadeResult } from '../keys/index.js';
|
|
66
|
+
export type { CascadeCollections, RosterSealReport };
|
|
90
67
|
/**
|
|
91
68
|
* What a completed cascade reports: whether the roster actually rotated on
|
|
92
69
|
* this run (a re-run of an already-complete revocation reports `false`), the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"revocation.d.ts","sourceRoot":"","sources":["../../src/clients/revocation.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC/D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"revocation.d.ts","sourceRoot":"","sources":["../../src/clients/revocation.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC/D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAA;AACxE,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EAClB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,OAAO,EACZ,KAAK,oBAAoB,EAC1B,MAAM,kBAAkB,CAAA;AAEzB,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,CAAA;AAEpD;;;;;;GAMG;AACH,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,CAAC,EAAE,gBAAgB,CAAA;IAC7B,WAAW,EAAE,oBAAoB,CAAA;IACjC,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,gBAAgB,CAAC,EAAE,oBAAoB,CAAA;IACvC,QAAQ,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;CACjD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,wBAAsB,mBAAmB,CAAC,EACxC,OAAO,EACP,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,sBAAsB,EACtB,WAAW,EACX,OAAO,EACP,qBAAqB,EACrB,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,yBAAyB,EACzB,iBAAiB,EAClB,EAAE;IACD,OAAO,EAAE,YAAY,CAAA;IACrB,UAAU,EAAE,qBAAqB,CAAA;IACjC,aAAa,EAAE,iBAAiB,CAAA;IAChC,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,WAAW,EAAE,yBAAyB,CAAA;IACtC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,qBAAqB,EAAE,gBAAgB,CAAA;IACvC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE;QAC3B,OAAO,EAAE,OAAO,CAAA;QAChB,aAAa,EAAE,MAAM,CAAA;QACrB,UAAU,EAAE,oBAAoB,CAAA;KACjC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACnB,WAAW,EAAE,kBAAkB,CAAA;IAC/B,yBAAyB,CAAC,EAAE,CAAC,OAAO,EAAE;QACpC,QAAQ,EAAE,oBAAoB,CAAA;KAC/B,KAAK,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACpD,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACtE,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAqElC"}
|
|
@@ -1,20 +1,5 @@
|
|
|
1
|
-
import { webvhResourceLogController } from '../resourceLog/index.js';
|
|
2
1
|
import { revokeWebvhClient } from '../webvh/index.js';
|
|
3
|
-
import {
|
|
4
|
-
/**
|
|
5
|
-
* Resolves the collection ids the fan-out covers, whether they are a fixed set
|
|
6
|
-
* or a listing the app performs.
|
|
7
|
-
*
|
|
8
|
-
* @param options {object}
|
|
9
|
-
* @param options.collections {CascadeCollections}
|
|
10
|
-
* @returns {Promise<string[]>}
|
|
11
|
-
*/
|
|
12
|
-
async function collectionIdsOf({ collections }) {
|
|
13
|
-
const { collectionIds } = collections;
|
|
14
|
-
return typeof collectionIds === 'function'
|
|
15
|
-
? await collectionIds()
|
|
16
|
-
: collectionIds;
|
|
17
|
-
}
|
|
2
|
+
import { rotateRosterToDocumentAndCascade } from '../keys/index.js';
|
|
18
3
|
/**
|
|
19
4
|
* Runs the whole revocation cascade for one enrolled wallet client. See the
|
|
20
5
|
* module doc for the order and the convergence story. Throws before touching
|
|
@@ -87,98 +72,42 @@ export async function revokeAccountClient({ idStore, updateKeys, revokedClient,
|
|
|
87
72
|
...(knownLatentHashes ? { knownLatentHashes } : {}),
|
|
88
73
|
...(expectedDid !== undefined ? { expectedDid } : {})
|
|
89
74
|
});
|
|
90
|
-
// The
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
// Whether there IS a roster is settled BY the convergence call itself: a
|
|
104
|
-
// `null` descriptor back means the account has no `key-map/user-key.jsonl`
|
|
105
|
-
// yet (its collections are not encrypted yet), so there is nothing to
|
|
106
|
-
// rotate. The document edit has already landed, so the client IS
|
|
107
|
-
// disconnected -- a completed cascade with nothing rotated, not a failure.
|
|
108
|
-
// Pairing-free: rather than naming the revoked client's kid, the rotation
|
|
109
|
-
// retires every current-epoch recipient the post-edit document no longer
|
|
110
|
-
// keys -- which is exactly the revoked client's entry, plus anything an
|
|
111
|
-
// earlier torn cascade left behind, in one rotation.
|
|
112
|
-
const converged = await convergeUserKeyRosterToDocument({
|
|
113
|
-
store: rosterStore,
|
|
114
|
-
document: doc
|
|
75
|
+
// 2-3. The shared roster-and-cascade tail: the roster rotation onto the
|
|
76
|
+
// post-edit document (with its post-edit controller floor and its seal
|
|
77
|
+
// backstop), then the collection fan-out onto the fresh key.
|
|
78
|
+
const tail = await rotateRosterToDocumentAndCascade({
|
|
79
|
+
rosterStore,
|
|
80
|
+
did,
|
|
81
|
+
doc,
|
|
82
|
+
log,
|
|
83
|
+
...(userKey ? { userKey } : {}),
|
|
84
|
+
clientKeyAgreementKey,
|
|
85
|
+
pinnedEpochId,
|
|
86
|
+
...(onUserKeyAdopted ? { onUserKeyAdopted } : {}),
|
|
87
|
+
collections
|
|
115
88
|
});
|
|
116
|
-
if (
|
|
89
|
+
if (!tail.rosterDescriptor || !tail.userKey) {
|
|
90
|
+
// No roster to rotate: the document edit has landed, so the client IS
|
|
91
|
+
// disconnected -- a completed cascade with nothing rotated.
|
|
117
92
|
return {
|
|
118
93
|
rotated: false,
|
|
119
|
-
collections:
|
|
94
|
+
collections: tail.collections,
|
|
120
95
|
document: doc
|
|
121
96
|
};
|
|
122
97
|
}
|
|
123
|
-
// The rotation's own verified result is threaded into the adopting read, so
|
|
124
|
-
// one cascade run acquires the roster once for both halves of stage 2 (the
|
|
125
|
-
// continuity and possession checks still run on the threaded descriptor).
|
|
126
|
-
const read = await readUserKeyRoster({
|
|
127
|
-
store: rosterStore,
|
|
128
|
-
descriptor: converged.descriptor,
|
|
129
|
-
...(userKey ? { userKey } : {}),
|
|
130
|
-
clientKeyAgreementKey,
|
|
131
|
-
pinnedEpochId
|
|
132
|
-
});
|
|
133
|
-
if (read.rotated) {
|
|
134
|
-
await onUserKeyAdopted?.({
|
|
135
|
-
userKey: read.userKey,
|
|
136
|
-
latestEpochId: read.latestEpochId,
|
|
137
|
-
descriptor: read.descriptor
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
// 2b. The seal backstop: an ordinary rotation is the sealing append by
|
|
141
|
-
// construction, but a rotation that no-op'd (the revoked client held no
|
|
142
|
-
// current-epoch wrap -- an orphan client, or any re-run) appended nothing,
|
|
143
|
-
// leaving the roster log's head anchored before the document edit. Sealing
|
|
144
|
-
// is best-effort and reported, never thrown: the wallet IS disconnected
|
|
145
|
-
// (stage 1 landed), and an unsealed log is durable state the login sweep
|
|
146
|
-
// re-detects and finishes.
|
|
147
|
-
let rosterSeal;
|
|
148
|
-
if (isSealableDescriptorStore(rosterStore)) {
|
|
149
|
-
try {
|
|
150
|
-
rosterSeal = { outcome: await rosterStore.seal() };
|
|
151
|
-
}
|
|
152
|
-
catch (err) {
|
|
153
|
-
rosterSeal = { outcome: 'failed', error: err };
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
// 3. The collection fan-out, in parallel -- run even when this call found
|
|
157
|
-
// the roster already rotated (a re-run after a crash), because the staleness
|
|
158
|
-
// rule finds exactly the stranded collections.
|
|
159
|
-
const cascade = await cascadeCollectionsToUserKey({
|
|
160
|
-
collectionIds: await collectionIdsOf({ collections }),
|
|
161
|
-
storeFor: collections.storeFor,
|
|
162
|
-
...(collections.isEncrypted
|
|
163
|
-
? { isEncrypted: collections.isEncrypted }
|
|
164
|
-
: {}),
|
|
165
|
-
rosterDescriptor: read.descriptor,
|
|
166
|
-
clientKeyAgreementKey,
|
|
167
|
-
userKey: read.userKey
|
|
168
|
-
});
|
|
169
98
|
// 4. The recovery re-mints, while the registry is still readable under the
|
|
170
99
|
// session's pre-adoption vault keys.
|
|
171
100
|
const recovery = await remintRecoveryDelegations?.({ document: doc });
|
|
172
|
-
if (
|
|
173
|
-
await onRotationAdopted?.({ userKey:
|
|
101
|
+
if (tail.rotated) {
|
|
102
|
+
await onRotationAdopted?.({ userKey: tail.userKey });
|
|
174
103
|
}
|
|
175
104
|
return {
|
|
176
|
-
rotated:
|
|
177
|
-
...(rosterSeal ? { rosterSeal } : {}),
|
|
178
|
-
collections:
|
|
105
|
+
rotated: tail.rotated,
|
|
106
|
+
...(tail.rosterSeal ? { rosterSeal: tail.rosterSeal } : {}),
|
|
107
|
+
collections: tail.collections,
|
|
179
108
|
document: doc,
|
|
180
|
-
userKey:
|
|
181
|
-
rosterDescriptor:
|
|
109
|
+
userKey: tail.userKey,
|
|
110
|
+
rosterDescriptor: tail.rosterDescriptor,
|
|
182
111
|
...(recovery ? { recovery } : {})
|
|
183
112
|
};
|
|
184
113
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"revocation.js","sourceRoot":"","sources":["../../src/clients/revocation.ts"],"names":[],"mappings":"AA+DA,OAAO,
|
|
1
|
+
{"version":3,"file":"revocation.js","sourceRoot":"","sources":["../../src/clients/revocation.ts"],"names":[],"mappings":"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"}
|
package/dist/keys/index.d.ts
CHANGED
|
@@ -42,6 +42,11 @@
|
|
|
42
42
|
* re-epoch that brings an encrypted collection onto the roster's current
|
|
43
43
|
* user key, and the parallel best-effort fan-out over the collections the wallet
|
|
44
44
|
* names (also the completion sweep's driver).
|
|
45
|
+
* - `rotateRosterToDocumentAndCascade` -- the shared roster-and-cascade tail
|
|
46
|
+
* every account-membership ceremony ends with (a client disconnected, a
|
|
47
|
+
* standing unlock credential retired): the post-edit controller floor, the
|
|
48
|
+
* convergence rotation with its seal backstop, and the collection fan-out
|
|
49
|
+
* onto the fresh user key.
|
|
45
50
|
* - `ensureWalletSpaceEpochs` -- the provision-time epoch[0] install for the
|
|
46
51
|
* wallet Space's encrypted collections, the EDV-bearing second step of
|
|
47
52
|
* `provisionWalletSpace`.
|
|
@@ -55,6 +60,8 @@ export type { ClientKeyRecord, ClientKeyRecordJson, EnrolledClientKeyRecord } fr
|
|
|
55
60
|
export { addUserKeyRosterRecipient, convergeUserKeyRosterToDocument, ensureUserKeyRoster, UserKeyRosterContinuityError, UserKeyRosterIntegrityError, UserKeyRosterUnwrapError, userKeyRosterLogSigner, userKeyRosterRecipientResolver, readUserKeyRoster, rosterRecipientKid, rotateUserKeyRoster } from './userKeyRoster.js';
|
|
56
61
|
export { cascadeCollectionsToUserKey, userKeyAsRecipient, rotateCollectionEpochsToUserKey, unwrapUserKeyGenerations } from './userKeyCascade.js';
|
|
57
62
|
export type { CollectionUserKeyRotationOutcome, UserKeyCascadeResult } from './userKeyCascade.js';
|
|
63
|
+
export { rotateRosterToDocumentAndCascade } from './userKeyRosterCascade.js';
|
|
64
|
+
export type { CascadeCollections, RosterCascadeResult, RosterSealReport } from './userKeyRosterCascade.js';
|
|
58
65
|
export type { UserKeyRosterReadResult } from './userKeyRoster.js';
|
|
59
66
|
export type { KeyAgreementDocument } from '../webvh/keyAgreement.js';
|
|
60
67
|
export { userKeyRosterDescriptorStore, userKeyRosterPinId } from './rosterStore.js';
|
package/dist/keys/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/keys/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/keys/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC5D,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAE3C,OAAO,EACL,6BAA6B,EAC7B,qBAAqB,EACrB,qBAAqB,EACrB,wBAAwB,EACxB,0BAA0B,EAC3B,MAAM,sBAAsB,CAAA;AAC7B,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EACL,yBAAyB,EACzB,+BAA+B,EAC/B,mBAAmB,EACnB,4BAA4B,EAC5B,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EACtB,8BAA8B,EAC9B,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,EAClB,+BAA+B,EAC/B,wBAAwB,EACzB,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EACV,gCAAgC,EAChC,oBAAoB,EACrB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,gCAAgC,EAAE,MAAM,2BAA2B,CAAA;AAC5E,YAAY,EACV,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,2BAA2B,CAAA;AAClC,YAAY,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAA;AACjE,YAAY,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAA;AAEpE,OAAO,EACL,4BAA4B,EAC5B,kBAAkB,EACnB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,8BAA8B,EAC9B,yBAAyB,EACzB,0BAA0B,EAC3B,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EAAE,iCAAiC,EAAE,MAAM,qBAAqB,CAAA;AAE5E,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACxB,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAA;AAE/D,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACf,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAE9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA"}
|
package/dist/keys/index.js
CHANGED
|
@@ -42,6 +42,11 @@
|
|
|
42
42
|
* re-epoch that brings an encrypted collection onto the roster's current
|
|
43
43
|
* user key, and the parallel best-effort fan-out over the collections the wallet
|
|
44
44
|
* names (also the completion sweep's driver).
|
|
45
|
+
* - `rotateRosterToDocumentAndCascade` -- the shared roster-and-cascade tail
|
|
46
|
+
* every account-membership ceremony ends with (a client disconnected, a
|
|
47
|
+
* standing unlock credential retired): the post-edit controller floor, the
|
|
48
|
+
* convergence rotation with its seal backstop, and the collection fan-out
|
|
49
|
+
* onto the fresh user key.
|
|
45
50
|
* - `ensureWalletSpaceEpochs` -- the provision-time epoch[0] install for the
|
|
46
51
|
* wallet Space's encrypted collections, the EDV-bearing second step of
|
|
47
52
|
* `provisionWalletSpace`.
|
|
@@ -52,6 +57,7 @@ export { mintUserKey, userKeyVaultKeys } from './userKey.js';
|
|
|
52
57
|
export { assertEnrolledClientKeyRecord, decodeClientKeyRecord, encodeClientKeyRecord, parseClientRecordUserKey, parseClientRecordWebvhKeys } from './clientKeyRecord.js';
|
|
53
58
|
export { addUserKeyRosterRecipient, convergeUserKeyRosterToDocument, ensureUserKeyRoster, UserKeyRosterContinuityError, UserKeyRosterIntegrityError, UserKeyRosterUnwrapError, userKeyRosterLogSigner, userKeyRosterRecipientResolver, readUserKeyRoster, rosterRecipientKid, rotateUserKeyRoster } from './userKeyRoster.js';
|
|
54
59
|
export { cascadeCollectionsToUserKey, userKeyAsRecipient, rotateCollectionEpochsToUserKey, unwrapUserKeyGenerations } from './userKeyCascade.js';
|
|
60
|
+
export { rotateRosterToDocumentAndCascade } from './userKeyRosterCascade.js';
|
|
55
61
|
export { userKeyRosterDescriptorStore, userKeyRosterPinId } from './rosterStore.js';
|
|
56
62
|
export { EPOCH_CONFIGURATION_STATE_TYPE, isSealableDescriptorStore, logGovernedDescriptorStore } from './rosterLogStore.js';
|
|
57
63
|
export { ensureIndexedFirstEpoch, ensureWalletSpaceEpochs } from './spaceEpochs.js';
|
package/dist/keys/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/keys/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/keys/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAG5D,OAAO,EACL,6BAA6B,EAC7B,qBAAqB,EACrB,qBAAqB,EACrB,wBAAwB,EACxB,0BAA0B,EAC3B,MAAM,sBAAsB,CAAA;AAO7B,OAAO,EACL,yBAAyB,EACzB,+BAA+B,EAC/B,mBAAmB,EACnB,4BAA4B,EAC5B,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EACtB,8BAA8B,EAC9B,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,EAClB,+BAA+B,EAC/B,wBAAwB,EACzB,MAAM,qBAAqB,CAAA;AAK5B,OAAO,EAAE,gCAAgC,EAAE,MAAM,2BAA2B,CAAA;AAS5E,OAAO,EACL,4BAA4B,EAC5B,kBAAkB,EACnB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,8BAA8B,EAC9B,yBAAyB,EACzB,0BAA0B,EAC3B,MAAM,qBAAqB,CAAA;AAG5B,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACxB,MAAM,kBAAkB,CAAA;AAGzB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACf,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* The shared roster-and-cascade tail every account-membership ceremony ends
|
|
6
|
+
* with: once a ceremony has published its own did:webvh document edit --
|
|
7
|
+
* disconnecting an enrolled client, retiring a standing unlock credential --
|
|
8
|
+
* what remains is the same two stages, and they are the same code.
|
|
9
|
+
*
|
|
10
|
+
* 1. **The user key rotation** in the wrap-set roster, recipients resolved
|
|
11
|
+
* from the document the edit itself just resolved to (no re-fetch of the
|
|
12
|
+
* log the ceremony just extended). On a log-governed roster store this
|
|
13
|
+
* function itself guarantees post-edit anchoring: the controller view built
|
|
14
|
+
* from the edit's own post-edit log is set as the store's freshness floor
|
|
15
|
+
* (`setControllerFloor`) before anything roster-side runs, so the rotation
|
|
16
|
+
* and the seal backstop anchor at or past the edit even where the app's
|
|
17
|
+
* injected controller resolution still serves a cached pre-edit view. The
|
|
18
|
+
* roster delivers, never sources, so the stage names no recipient at all:
|
|
19
|
+
* it converges the roster onto that document (the login sweep's own path),
|
|
20
|
+
* retiring every current-epoch recipient the document no longer keys in one
|
|
21
|
+
* rotation. An account with no roster yet stops here: the document edit has
|
|
22
|
+
* landed, so the membership change IS in force, with nothing to rotate. On
|
|
23
|
+
* a sealable (log-governed) roster store, the seal backstop follows: a
|
|
24
|
+
* rotation that no-op'd appended nothing, so the roster log may still be
|
|
25
|
+
* anchored before the document edit -- `seal()` re-anchors it with an
|
|
26
|
+
* idempotent no-op entry, best-effort and reported rather than thrown.
|
|
27
|
+
* 2. **The collection fan-out**: every encrypted collection is re-epoch'd onto
|
|
28
|
+
* the fresh key in parallel, so writes stop landing under epochs the
|
|
29
|
+
* removed party can still decrypt. Failures are collected per collection
|
|
30
|
+
* and never abort the fan-out.
|
|
31
|
+
*
|
|
32
|
+
* Convergence is the design: both stages detect their own completion from
|
|
33
|
+
* durable state alone -- the roster no-ops once every current-epoch recipient
|
|
34
|
+
* is document-backed, and a collection is stale exactly when its current
|
|
35
|
+
* epoch names a non-current key generation -- so a mid-cascade crash strands
|
|
36
|
+
* nothing permanently and a naive full re-run finishes it (the login-time
|
|
37
|
+
* completion sweep is the standing backstop).
|
|
38
|
+
*/
|
|
39
|
+
import type { DIDDoc, DIDLog } from '@interop/did-method-webvh';
|
|
40
|
+
import type { IKeyAgreementKey } from '@interop/data-integrity-core';
|
|
41
|
+
import type { CollectionEncryption } from '@interop/was-client';
|
|
42
|
+
import type { EncryptionDescriptorStore } from '@interop/was-client/edv';
|
|
43
|
+
import { type UserKeyCascadeResult } from './userKeyCascade.js';
|
|
44
|
+
import type { UserKey } from './userKey.js';
|
|
45
|
+
/**
|
|
46
|
+
* What the roster's seal backstop reported: `sealed` (the roster log's head
|
|
47
|
+
* still anchored before the document edit, and the backstop append landed),
|
|
48
|
+
* `noop` (already sealed -- the rotation itself was the sealing append, or a
|
|
49
|
+
* re-run found nothing to do), or `failed` (the seal could not run; carried
|
|
50
|
+
* in `error`, never thrown -- the ceremony stays a resumable success and the
|
|
51
|
+
* login sweep re-seals).
|
|
52
|
+
*/
|
|
53
|
+
export interface RosterSealReport {
|
|
54
|
+
outcome: 'sealed' | 'noop' | 'failed';
|
|
55
|
+
error?: unknown;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Where the cascade's collection fan-out gets its work: which encrypted
|
|
59
|
+
* collections exist (only the app knows -- a mobile replica names the
|
|
60
|
+
* collections it replicates, a web wallet also lists the app-provisioned ones
|
|
61
|
+
* remotely) and how each one's descriptor store and encryption declaration are
|
|
62
|
+
* reached.
|
|
63
|
+
*/
|
|
64
|
+
export interface CascadeCollections {
|
|
65
|
+
collectionIds: string[] | (() => Promise<string[]>);
|
|
66
|
+
storeFor: (collectionId: string) => EncryptionDescriptorStore;
|
|
67
|
+
isEncrypted?: (collectionId: string) => Promise<boolean>;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* What the shared tail reports: whether the roster actually rotated on this
|
|
71
|
+
* run (a re-run of an already-complete ceremony reports `false`), the roster's
|
|
72
|
+
* seal-backstop report (present when the roster store is sealable and the
|
|
73
|
+
* roster stage ran), the per-collection fan-out result, and the rotated key
|
|
74
|
+
* with the roster descriptor it was read from.
|
|
75
|
+
*/
|
|
76
|
+
export interface RosterCascadeResult {
|
|
77
|
+
rotated: boolean;
|
|
78
|
+
rosterSeal?: RosterSealReport;
|
|
79
|
+
collections: UserKeyCascadeResult;
|
|
80
|
+
userKey?: UserKey;
|
|
81
|
+
rosterDescriptor?: CollectionEncryption;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Runs the roster rotation (with its seal backstop) and the collection
|
|
85
|
+
* fan-out over the document a ceremony's own edit just published. See the
|
|
86
|
+
* module doc for the order and the convergence story.
|
|
87
|
+
*
|
|
88
|
+
* @param options {object}
|
|
89
|
+
* @param options.rosterStore {EncryptionDescriptorStore} the
|
|
90
|
+
* `key-map/user-key.jsonl` roster store
|
|
91
|
+
* @param options.did {string} the account's did:webvh
|
|
92
|
+
* @param options.doc {DIDDoc} the document as the ceremony's edit left it
|
|
93
|
+
* @param options.log {DIDLog} the post-edit log, which the controller floor
|
|
94
|
+
* is built from
|
|
95
|
+
* @param [options.userKey] {UserKey} this client's cached user key
|
|
96
|
+
* @param options.clientKeyAgreementKey {IKeyAgreementKey} this client's own
|
|
97
|
+
* (identity) key-agreement key -- its roster entry
|
|
98
|
+
* @param [options.pinnedEpochId] {string} the locally pinned latest-seen
|
|
99
|
+
* roster epoch
|
|
100
|
+
* @param [options.onUserKeyAdopted] {Function} persists a rotated key:
|
|
101
|
+
* called with `{ userKey, latestEpochId, descriptor }` after the roster read
|
|
102
|
+
* and BEFORE the fan-out. The key and the epoch pin must persist atomically
|
|
103
|
+
* @param options.collections {CascadeCollections} the fan-out's work
|
|
104
|
+
* @returns {Promise<RosterCascadeResult>}
|
|
105
|
+
*/
|
|
106
|
+
export declare function rotateRosterToDocumentAndCascade({ rosterStore, did, doc, log, userKey, clientKeyAgreementKey, pinnedEpochId, onUserKeyAdopted, collections }: {
|
|
107
|
+
rosterStore: EncryptionDescriptorStore;
|
|
108
|
+
did: string;
|
|
109
|
+
doc: DIDDoc;
|
|
110
|
+
log: DIDLog;
|
|
111
|
+
userKey?: UserKey;
|
|
112
|
+
clientKeyAgreementKey: IKeyAgreementKey;
|
|
113
|
+
pinnedEpochId?: string | null;
|
|
114
|
+
onUserKeyAdopted?: (adopted: {
|
|
115
|
+
userKey: UserKey;
|
|
116
|
+
latestEpochId: string;
|
|
117
|
+
descriptor: CollectionEncryption;
|
|
118
|
+
}) => Promise<void>;
|
|
119
|
+
collections: CascadeCollections;
|
|
120
|
+
}): Promise<RosterCascadeResult>;
|
|
121
|
+
//# sourceMappingURL=userKeyRosterCascade.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"userKeyRosterCascade.d.ts","sourceRoot":"","sources":["../../src/keys/userKeyRosterCascade.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAA;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC/D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAA;AAExE,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,qBAAqB,CAAA;AAM5B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAE3C;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAA;IACrC,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;IACnD,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,yBAAyB,CAAA;IAC7D,WAAW,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CACzD;AAED;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,CAAC,EAAE,gBAAgB,CAAA;IAC7B,WAAW,EAAE,oBAAoB,CAAA;IACjC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,gBAAgB,CAAC,EAAE,oBAAoB,CAAA;CACxC;AAqBD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,gCAAgC,CAAC,EACrD,WAAW,EACX,GAAG,EACH,GAAG,EACH,GAAG,EACH,OAAO,EACP,qBAAqB,EACrB,aAAa,EACb,gBAAgB,EAChB,WAAW,EACZ,EAAE;IACD,WAAW,EAAE,yBAAyB,CAAA;IACtC,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,qBAAqB,EAAE,gBAAgB,CAAA;IACvC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE;QAC3B,OAAO,EAAE,OAAO,CAAA;QAChB,aAAa,EAAE,MAAM,CAAA;QACrB,UAAU,EAAE,oBAAoB,CAAA;KACjC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACnB,WAAW,EAAE,kBAAkB,CAAA;CAChC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAqF/B"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { webvhResourceLogController } from '../resourceLog/index.js';
|
|
2
|
+
import { cascadeCollectionsToUserKey } from './userKeyCascade.js';
|
|
3
|
+
import { isSealableDescriptorStore } from './rosterLogStore.js';
|
|
4
|
+
import { convergeUserKeyRosterToDocument, readUserKeyRoster } from './userKeyRoster.js';
|
|
5
|
+
/**
|
|
6
|
+
* Resolves the collection ids the fan-out covers, whether they are a fixed set
|
|
7
|
+
* or a listing the app performs.
|
|
8
|
+
*
|
|
9
|
+
* @param options {object}
|
|
10
|
+
* @param options.collections {CascadeCollections}
|
|
11
|
+
* @returns {Promise<string[]>}
|
|
12
|
+
*/
|
|
13
|
+
async function collectionIdsOf({ collections }) {
|
|
14
|
+
const { collectionIds } = collections;
|
|
15
|
+
return typeof collectionIds === 'function'
|
|
16
|
+
? await collectionIds()
|
|
17
|
+
: collectionIds;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Runs the roster rotation (with its seal backstop) and the collection
|
|
21
|
+
* fan-out over the document a ceremony's own edit just published. See the
|
|
22
|
+
* module doc for the order and the convergence story.
|
|
23
|
+
*
|
|
24
|
+
* @param options {object}
|
|
25
|
+
* @param options.rosterStore {EncryptionDescriptorStore} the
|
|
26
|
+
* `key-map/user-key.jsonl` roster store
|
|
27
|
+
* @param options.did {string} the account's did:webvh
|
|
28
|
+
* @param options.doc {DIDDoc} the document as the ceremony's edit left it
|
|
29
|
+
* @param options.log {DIDLog} the post-edit log, which the controller floor
|
|
30
|
+
* is built from
|
|
31
|
+
* @param [options.userKey] {UserKey} this client's cached user key
|
|
32
|
+
* @param options.clientKeyAgreementKey {IKeyAgreementKey} this client's own
|
|
33
|
+
* (identity) key-agreement key -- its roster entry
|
|
34
|
+
* @param [options.pinnedEpochId] {string} the locally pinned latest-seen
|
|
35
|
+
* roster epoch
|
|
36
|
+
* @param [options.onUserKeyAdopted] {Function} persists a rotated key:
|
|
37
|
+
* called with `{ userKey, latestEpochId, descriptor }` after the roster read
|
|
38
|
+
* and BEFORE the fan-out. The key and the epoch pin must persist atomically
|
|
39
|
+
* @param options.collections {CascadeCollections} the fan-out's work
|
|
40
|
+
* @returns {Promise<RosterCascadeResult>}
|
|
41
|
+
*/
|
|
42
|
+
export async function rotateRosterToDocumentAndCascade({ rosterStore, did, doc, log, userKey, clientKeyAgreementKey, pinnedEpochId, onUserKeyAdopted, collections }) {
|
|
43
|
+
// The post-edit anchoring guarantee: the roster appends -- and the seal
|
|
44
|
+
// backstop's removal detection -- must run under a controller view that
|
|
45
|
+
// includes the edit the ceremony just published, or the rotation anchors
|
|
46
|
+
// pre-edit and the log stays unsealed with the seal blind to the removal.
|
|
47
|
+
// Rather than leaving that to the injected store's own controller wiring,
|
|
48
|
+
// the view built from the edit's post-edit log is set as the store's floor;
|
|
49
|
+
// a fresher resolved view still wins.
|
|
50
|
+
if (isSealableDescriptorStore(rosterStore)) {
|
|
51
|
+
rosterStore.setControllerFloor({
|
|
52
|
+
controller: webvhResourceLogController({ did, log })
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
// The roster rotation, recipients resolved from that same document.
|
|
56
|
+
// Whether there IS a roster is settled BY the convergence call itself: a
|
|
57
|
+
// `null` descriptor back means the account has no `key-map/user-key.jsonl`
|
|
58
|
+
// yet (its collections are not encrypted yet), so there is nothing to
|
|
59
|
+
// rotate. The document edit has already landed, so the membership change IS
|
|
60
|
+
// in force -- a completed ceremony with nothing rotated, not a failure.
|
|
61
|
+
// Pairing-free: rather than naming the removed party's kid, the rotation
|
|
62
|
+
// retires every current-epoch recipient the post-edit document no longer
|
|
63
|
+
// keys -- which is exactly that party's entry, plus anything an earlier torn
|
|
64
|
+
// run left behind, in one rotation.
|
|
65
|
+
const converged = await convergeUserKeyRosterToDocument({
|
|
66
|
+
store: rosterStore,
|
|
67
|
+
document: doc
|
|
68
|
+
});
|
|
69
|
+
if (converged.descriptor === null) {
|
|
70
|
+
return { rotated: false, collections: { outcomes: {}, failed: [] } };
|
|
71
|
+
}
|
|
72
|
+
// The rotation's own verified result is threaded into the adopting read, so
|
|
73
|
+
// one run acquires the roster once for both halves of the stage (the
|
|
74
|
+
// continuity and possession checks still run on the threaded descriptor).
|
|
75
|
+
const read = await readUserKeyRoster({
|
|
76
|
+
store: rosterStore,
|
|
77
|
+
descriptor: converged.descriptor,
|
|
78
|
+
...(userKey ? { userKey } : {}),
|
|
79
|
+
clientKeyAgreementKey,
|
|
80
|
+
pinnedEpochId
|
|
81
|
+
});
|
|
82
|
+
if (read.rotated) {
|
|
83
|
+
await onUserKeyAdopted?.({
|
|
84
|
+
userKey: read.userKey,
|
|
85
|
+
latestEpochId: read.latestEpochId,
|
|
86
|
+
descriptor: read.descriptor
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
// The seal backstop: an ordinary rotation is the sealing append by
|
|
90
|
+
// construction, but a rotation that no-op'd (the removed party held no
|
|
91
|
+
// current-epoch wrap -- an orphan entry, or any re-run) appended nothing,
|
|
92
|
+
// leaving the roster log's head anchored before the document edit. Sealing
|
|
93
|
+
// is best-effort and reported, never thrown: the document edit landed, and
|
|
94
|
+
// an unsealed log is durable state the login sweep re-detects and finishes.
|
|
95
|
+
let rosterSeal;
|
|
96
|
+
if (isSealableDescriptorStore(rosterStore)) {
|
|
97
|
+
try {
|
|
98
|
+
rosterSeal = { outcome: await rosterStore.seal() };
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
rosterSeal = { outcome: 'failed', error: err };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// The collection fan-out, in parallel -- run even when this call found the
|
|
105
|
+
// roster already rotated (a re-run after a crash), because the staleness
|
|
106
|
+
// rule finds exactly the stranded collections.
|
|
107
|
+
const cascade = await cascadeCollectionsToUserKey({
|
|
108
|
+
collectionIds: await collectionIdsOf({ collections }),
|
|
109
|
+
storeFor: collections.storeFor,
|
|
110
|
+
...(collections.isEncrypted
|
|
111
|
+
? { isEncrypted: collections.isEncrypted }
|
|
112
|
+
: {}),
|
|
113
|
+
rosterDescriptor: read.descriptor,
|
|
114
|
+
clientKeyAgreementKey,
|
|
115
|
+
userKey: read.userKey
|
|
116
|
+
});
|
|
117
|
+
return {
|
|
118
|
+
rotated: read.rotated,
|
|
119
|
+
...(rosterSeal ? { rosterSeal } : {}),
|
|
120
|
+
collections: cascade,
|
|
121
|
+
userKey: read.userKey,
|
|
122
|
+
rosterDescriptor: read.descriptor
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=userKeyRosterCascade.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"userKeyRosterCascade.js","sourceRoot":"","sources":["../../src/keys/userKeyRosterCascade.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DIDDoc, DIDLog } from '@interop/did-method-webvh';
|
|
1
2
|
import type { ClientWebvhUpdateKeys, WebvhEnrollmentKeys, WebvhIdStore } from '../webvh/didWebvh.js';
|
|
2
3
|
/**
|
|
3
4
|
* The verification-method id a code's key-agreement key publishes under --
|
|
@@ -55,7 +56,8 @@ export type RecoveryLogStore = Pick<WebvhIdStore, 'getIdResourceRaw' | 'putIdRes
|
|
|
55
56
|
* @param options.recovery {RecoveryPublicKeys} the code's public halves
|
|
56
57
|
* @param [options.expectedDid] {string} the account DID the log must
|
|
57
58
|
* resolve to, from the caller's stored account pointer
|
|
58
|
-
* @returns {Promise<{ did: string }>}
|
|
59
|
+
* @returns {Promise<{ did: string, doc: DIDDoc, log: DIDLog }>} the account
|
|
60
|
+
* DID and the document and log as this call leaves them
|
|
59
61
|
*/
|
|
60
62
|
export declare function publishRecoveryKey({ idStore, updateKeys, recovery, expectedDid }: {
|
|
61
63
|
idStore: WebvhIdStore;
|
|
@@ -64,6 +66,8 @@ export declare function publishRecoveryKey({ idStore, updateKeys, recovery, expe
|
|
|
64
66
|
expectedDid?: string;
|
|
65
67
|
}): Promise<{
|
|
66
68
|
did: string;
|
|
69
|
+
doc: DIDDoc;
|
|
70
|
+
log: DIDLog;
|
|
67
71
|
}>;
|
|
68
72
|
/**
|
|
69
73
|
* REVOCATION (run by an enrolled client, root authority): removes a recovery
|
|
@@ -74,7 +78,8 @@ export declare function publishRecoveryKey({ idStore, updateKeys, recovery, expe
|
|
|
74
78
|
* the resolver's document no longer backs the removed entry.
|
|
75
79
|
*
|
|
76
80
|
* @param options {object} see {@link publishRecoveryKey}
|
|
77
|
-
* @returns {Promise<{ did: string }>}
|
|
81
|
+
* @returns {Promise<{ did: string, doc: DIDDoc, log: DIDLog }>} see
|
|
82
|
+
* {@link publishRecoveryKey}
|
|
78
83
|
*/
|
|
79
84
|
export declare function removeRecoveryKey({ idStore, updateKeys, recovery, expectedDid }: {
|
|
80
85
|
idStore: WebvhIdStore;
|
|
@@ -83,6 +88,8 @@ export declare function removeRecoveryKey({ idStore, updateKeys, recovery, expec
|
|
|
83
88
|
expectedDid?: string;
|
|
84
89
|
}): Promise<{
|
|
85
90
|
did: string;
|
|
91
|
+
doc: DIDDoc;
|
|
92
|
+
log: DIDLog;
|
|
86
93
|
}>;
|
|
87
94
|
/**
|
|
88
95
|
* RECOVERY (run by the code-derived client through the delegated `did.jsonl`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recoveryWebvh.d.ts","sourceRoot":"","sources":["../../src/recovery/recoveryWebvh.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"recoveryWebvh.d.ts","sourceRoot":"","sources":["../../src/recovery/recoveryWebvh.ts"],"names":[],"mappings":"AAoCA,OAAO,KAAK,EACV,MAAM,EACN,MAAM,EAEP,MAAM,2BAA2B,CAAA;AAWlC,OAAO,KAAK,EACV,qBAAqB,EAErB,mBAAmB,EACnB,YAAY,EACb,MAAM,sBAAsB,CAAA;AAG7B;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,EAC3B,GAAG,EACH,wBAAwB,EACzB,EAAE;IACD,GAAG,EAAE,MAAM,CAAA;IACX,wBAAwB,EAAE,MAAM,CAAA;CACjC,GAAG,MAAM,CAET;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,wBAAwB,EAAE,MAAM,CAAA;IAChC,kBAAkB,EAAE,MAAM,CAAA;CAC3B;AAED;;;;GAIG;AACH,qBAAa,4BAA6B,SAAQ,KAAK;gBAEnD,OAAO,SACuC;CAKjD;AAED;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,CACjC,YAAY,EACZ,kBAAkB,GAAG,eAAe,CACrC,CAAA;AAsDD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,kBAAkB,CAAC,EACvC,OAAO,EACP,UAAU,EACV,QAAQ,EACR,WAAW,EACZ,EAAE;IACD,OAAO,EAAE,YAAY,CAAA;IACrB,UAAU,EAAE,qBAAqB,CAAA;IACjC,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAarD;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,OAAO,EACP,UAAU,EACV,QAAQ,EACR,WAAW,EACZ,EAAE;IACD,OAAO,EAAE,YAAY,CAAA;IACrB,UAAU,EAAE,qBAAqB,CAAA;IACjC,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAarD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE;IAChD,KAAK,EAAE,gBAAgB,CAAA;IACvB,QAAQ,EAAE,kBAAkB,GAAG;QAAE,UAAU,EAAE,UAAU,CAAA;KAAE,CAAA;IACzD,aAAa,EAAE,mBAAmB,CAAA;IAClC,oBAAoB,EAAE,qBAAqB,CAAA;IAC3C,WAAW,EAAE,kBAAkB,CAAA;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAE5C"}
|
|
@@ -116,7 +116,8 @@ async function publishLogOnly({ store, log, ifMatch }) {
|
|
|
116
116
|
* @param options.recovery {RecoveryPublicKeys} the code's public halves
|
|
117
117
|
* @param [options.expectedDid] {string} the account DID the log must
|
|
118
118
|
* resolve to, from the caller's stored account pointer
|
|
119
|
-
* @returns {Promise<{ did: string }>}
|
|
119
|
+
* @returns {Promise<{ did: string, doc: DIDDoc, log: DIDLog }>} the account
|
|
120
|
+
* DID and the document and log as this call leaves them
|
|
120
121
|
*/
|
|
121
122
|
export async function publishRecoveryKey({ idStore, updateKeys, recovery, expectedDid }) {
|
|
122
123
|
return publishUnlockKey({
|
|
@@ -141,7 +142,8 @@ export async function publishRecoveryKey({ idStore, updateKeys, recovery, expect
|
|
|
141
142
|
* the resolver's document no longer backs the removed entry.
|
|
142
143
|
*
|
|
143
144
|
* @param options {object} see {@link publishRecoveryKey}
|
|
144
|
-
* @returns {Promise<{ did: string }>}
|
|
145
|
+
* @returns {Promise<{ did: string, doc: DIDDoc, log: DIDLog }>} see
|
|
146
|
+
* {@link publishRecoveryKey}
|
|
145
147
|
*/
|
|
146
148
|
export async function removeRecoveryKey({ idStore, updateKeys, recovery, expectedDid }) {
|
|
147
149
|
return removeUnlockKey({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recoveryWebvh.js","sourceRoot":"","sources":["../../src/recovery/recoveryWebvh.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;
|
|
1
|
+
{"version":3,"file":"recoveryWebvh.js","sourceRoot":"","sources":["../../src/recovery/recoveryWebvh.ts"],"names":[],"mappings":"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"}
|
package/dist/unlock/index.d.ts
CHANGED
|
@@ -21,6 +21,9 @@
|
|
|
21
21
|
* - `publishUnlockKey` / `removeUnlockKey` -- the merged document posture
|
|
22
22
|
* edit, parameterized by credential class: a verbatim `keyAgreement` entry,
|
|
23
23
|
* or a `MultikeyCommitment` entry for a low-entropy-derived key.
|
|
24
|
+
* - `retireUnlockCredential` -- the retirement ceremony behind "change my
|
|
25
|
+
* passphrase" and "remove this passkey": the posture edit, then the shared
|
|
26
|
+
* roster rotation and collection fan-out off the retired credential's wrap.
|
|
24
27
|
* - `selfEnrollWebvhClient` / `selfEnrollClientCore` -- the self-enrolling
|
|
25
28
|
* continuation (reveal a rung, add an ordinary client, retire the rung) and
|
|
26
29
|
* the composed completion a fresh browser runs end to end.
|
|
@@ -36,5 +39,7 @@ export { computeUnlockBinding, remintUnlockRecordBridge, UnlockBindingError, unl
|
|
|
36
39
|
export type { SealedRecordMember, SignedUnlockRecord, UnlockRecordContents, UnlockRecordProofState } from './unlockRecord.js';
|
|
37
40
|
export { publishUnlockKey, removeUnlockKey, selfEnrollWebvhClient, unlockKeyVerificationMethod, unlockKeyVmId } from './standingWebvh.js';
|
|
38
41
|
export type { StandingUnlockKeys, UnlockKeyAgreementPublication, UnlockLogStore } from './standingWebvh.js';
|
|
42
|
+
export { retireUnlockCredential } from './retire.js';
|
|
43
|
+
export type { UnlockCredentialRetirementResult } from './retire.js';
|
|
39
44
|
export { selfEnrollClientCore } from './selfEnroll.js';
|
|
40
45
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/unlock/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/unlock/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,EACL,4BAA4B,EAC5B,oBAAoB,EACpB,4BAA4B,EAC7B,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EACV,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,sBAAsB,EACtB,UAAU,EACV,cAAc,EACf,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE9D,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,2BAA2B,EAC3B,aAAa,EACd,MAAM,oBAAoB,CAAA;AAC3B,YAAY,EACV,kBAAkB,EAClB,6BAA6B,EAC7B,cAAc,EACf,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AACpD,YAAY,EAAE,gCAAgC,EAAE,MAAM,aAAa,CAAA;AAEnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA"}
|
package/dist/unlock/index.js
CHANGED
|
@@ -21,6 +21,9 @@
|
|
|
21
21
|
* - `publishUnlockKey` / `removeUnlockKey` -- the merged document posture
|
|
22
22
|
* edit, parameterized by credential class: a verbatim `keyAgreement` entry,
|
|
23
23
|
* or a `MultikeyCommitment` entry for a low-entropy-derived key.
|
|
24
|
+
* - `retireUnlockCredential` -- the retirement ceremony behind "change my
|
|
25
|
+
* passphrase" and "remove this passkey": the posture edit, then the shared
|
|
26
|
+
* roster rotation and collection fan-out off the retired credential's wrap.
|
|
24
27
|
* - `selfEnrollWebvhClient` / `selfEnrollClientCore` -- the self-enrolling
|
|
25
28
|
* continuation (reveal a rung, add an ordinary client, retire the rung) and
|
|
26
29
|
* the composed completion a fresh browser runs end to end.
|
|
@@ -32,5 +35,6 @@ export { standingClientFromUnlockSeed, STANDING_CLIENT_SALT, unlockClientIdentit
|
|
|
32
35
|
export { attributeLadderRung, generateLadderSeed, LADDER_MAX_SCAN, LADDER_SEED_BYTES, LadderAttributionError, ladderRung, ladderRungSeed } from './ladder.js';
|
|
33
36
|
export { computeUnlockBinding, remintUnlockRecordBridge, UnlockBindingError, unlockRecordBinding, unwrapUnlockRecord, wrapUnlockRecord } from './unlockRecord.js';
|
|
34
37
|
export { publishUnlockKey, removeUnlockKey, selfEnrollWebvhClient, unlockKeyVerificationMethod, unlockKeyVmId } from './standingWebvh.js';
|
|
38
|
+
export { retireUnlockCredential } from './retire.js';
|
|
35
39
|
export { selfEnrollClientCore } from './selfEnroll.js';
|
|
36
40
|
//# sourceMappingURL=index.js.map
|
package/dist/unlock/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/unlock/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/unlock/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,EACL,4BAA4B,EAC5B,oBAAoB,EACpB,4BAA4B,EAC7B,MAAM,qBAAqB,CAAA;AAM5B,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,sBAAsB,EACtB,UAAU,EACV,cAAc,EACf,MAAM,aAAa,CAAA;AAGpB,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,mBAAmB,CAAA;AAQ1B,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,2BAA2B,EAC3B,aAAa,EACd,MAAM,oBAAoB,CAAA;AAO3B,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAGpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Retiring a standing unlock credential: the ceremony behind "change my
|
|
6
|
+
* passphrase" and "remove this passkey", run synchronously in an enrolled
|
|
7
|
+
* client, in dependency order. A standing credential is not a stored string to
|
|
8
|
+
* overwrite -- it holds a wrap in the user key roster and a `keyAgreement`
|
|
9
|
+
* posture in the account's did:webvh document -- so retiring one is a real
|
|
10
|
+
* rotation, on the same stages the client-revocation cascade runs.
|
|
11
|
+
*
|
|
12
|
+
* 1. **The document posture edit** (`removeUnlockKey`): the credential's
|
|
13
|
+
* `keyAgreement` entry (verbatim key or commitment) and its committed
|
|
14
|
+
* update-key hash leave the document in one log entry. That kills the
|
|
15
|
+
* credential's latent self-enrollment authority -- with its rung
|
|
16
|
+
* commitment gone, no reveal entry it could sign verifies -- and it is
|
|
17
|
+
* what makes stage 2 converge: the roster resolver, backed by this
|
|
18
|
+
* document, no longer keys the credential's entry.
|
|
19
|
+
* 2. **The roster rotation and the collection fan-out**
|
|
20
|
+
* (`rotateRosterToDocumentAndCascade`): the user key rotates off the
|
|
21
|
+
* credential's wrap and every encrypted collection re-epochs onto the
|
|
22
|
+
* fresh key, so writes stop landing under epochs the retired credential
|
|
23
|
+
* could open.
|
|
24
|
+
*
|
|
25
|
+
* The order is load-bearing, and in that direction: the document removal
|
|
26
|
+
* first means a run torn anywhere after it leaves the roster keying a
|
|
27
|
+
* recipient the document no longer backs -- exactly the state the login-time
|
|
28
|
+
* sweep detects and finishes. Torn the other way around, a rotation with the
|
|
29
|
+
* posture still standing would simply re-escrow the credential and look
|
|
30
|
+
* healthy.
|
|
31
|
+
*
|
|
32
|
+
* There is deliberately no recovery-delegation re-mint stage here (the
|
|
33
|
+
* client-revocation cascade's fourth stage). A retired credential signs no
|
|
34
|
+
* delegations: its own bridge delegation dies with its unlock Space, which
|
|
35
|
+
* the app deletes as part of the change-method ceremony, and no other
|
|
36
|
+
* credential's bridge chains through it.
|
|
37
|
+
*
|
|
38
|
+
* Convergence is the design: every stage detects its own completion from
|
|
39
|
+
* durable state alone -- the posture edit no-ops when the document is already
|
|
40
|
+
* settled, the rotation no-ops once every current-epoch recipient is
|
|
41
|
+
* document-backed, and a collection is stale exactly when its current epoch
|
|
42
|
+
* names a non-current user key generation -- so a naive full re-run finishes
|
|
43
|
+
* a torn ceremony and a healthy account writes nothing.
|
|
44
|
+
*
|
|
45
|
+
* The honest limitation is the cascade's: ciphertext the credential's holder
|
|
46
|
+
* already fetched and decrypted stays readable, and old epochs stay open to
|
|
47
|
+
* the user key generations the credential already delivered. Retirement stops
|
|
48
|
+
* future reads.
|
|
49
|
+
*/
|
|
50
|
+
import type { IKeyAgreementKey } from '@interop/data-integrity-core';
|
|
51
|
+
import type { CollectionEncryption } from '@interop/was-client';
|
|
52
|
+
import type { EncryptionDescriptorStore } from '@interop/was-client/edv';
|
|
53
|
+
import { type CascadeCollections, type RosterSealReport, type UserKey, type UserKeyCascadeResult } from '../keys/index.js';
|
|
54
|
+
import type { ClientWebvhUpdateKeys, WebvhIdStore } from '../webvh/index.js';
|
|
55
|
+
import { type StandingUnlockKeys } from './standingWebvh.js';
|
|
56
|
+
/**
|
|
57
|
+
* What a completed retirement reports: whether the roster actually rotated on
|
|
58
|
+
* this run (a re-run of an already-complete retirement reports `false`), the
|
|
59
|
+
* roster's seal-backstop report (present when the roster store is sealable and
|
|
60
|
+
* the roster stage ran), the per-collection fan-out result, the document as
|
|
61
|
+
* the posture edit left it, and the rotated key with the roster descriptor it
|
|
62
|
+
* was read from.
|
|
63
|
+
*/
|
|
64
|
+
export interface UnlockCredentialRetirementResult {
|
|
65
|
+
rotated: boolean;
|
|
66
|
+
rosterSeal?: RosterSealReport;
|
|
67
|
+
collections: UserKeyCascadeResult;
|
|
68
|
+
document: object;
|
|
69
|
+
userKey?: UserKey;
|
|
70
|
+
rosterDescriptor?: CollectionEncryption;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Retires one standing unlock credential from an account. See the module doc
|
|
74
|
+
* for the order and the convergence story. Once the posture edit lands, a
|
|
75
|
+
* thrown later stage leaves durable state a naive re-run -- or the login-time
|
|
76
|
+
* sweep -- converges from.
|
|
77
|
+
*
|
|
78
|
+
* @param options {object}
|
|
79
|
+
* @param options.idStore {WebvhIdStore} the account's `id` collection store
|
|
80
|
+
* @param options.updateKeys {ClientWebvhUpdateKeys} the RETIRING (enrolled)
|
|
81
|
+
* client's own did:webvh update-key seeds, which sign the posture edit
|
|
82
|
+
* @param options.unlockKeys {StandingUnlockKeys} the retired credential's
|
|
83
|
+
* public posture (its key-agreement publication and its committed update
|
|
84
|
+
* key)
|
|
85
|
+
* @param [options.expectedDid] {string} the account DID from the caller's
|
|
86
|
+
* stored account pointer; supplied, the posture edit refuses a `did.jsonl`
|
|
87
|
+
* resolving to any other account
|
|
88
|
+
* @param [options.verb] {string} what the caller is doing, for the
|
|
89
|
+
* pending-rotation refusal message (e.g. `'changing your passphrase'`)
|
|
90
|
+
* @param options.rosterStore {EncryptionDescriptorStore} the
|
|
91
|
+
* `key-map/user-key.jsonl` roster store
|
|
92
|
+
* @param [options.userKey] {UserKey} this client's cached user key
|
|
93
|
+
* @param options.clientKeyAgreementKey {IKeyAgreementKey} this client's own
|
|
94
|
+
* (identity) key-agreement key -- its roster entry
|
|
95
|
+
* @param [options.pinnedEpochId] {string} the locally pinned latest-seen
|
|
96
|
+
* roster epoch
|
|
97
|
+
* @param [options.onUserKeyAdopted] {Function} persists a rotated key:
|
|
98
|
+
* called with `{ userKey, latestEpochId, descriptor }` after the roster read
|
|
99
|
+
* and BEFORE the fan-out. The key and the epoch pin must persist atomically
|
|
100
|
+
* @param options.collections {CascadeCollections} the fan-out's work
|
|
101
|
+
* @param [options.onRotationAdopted] {Function} `({ userKey }) =>
|
|
102
|
+
* Promise<void>` -- the live-session adoption of a rotated key, run last so
|
|
103
|
+
* the session keeps operating without a re-login
|
|
104
|
+
* @returns {Promise<UnlockCredentialRetirementResult>}
|
|
105
|
+
*/
|
|
106
|
+
export declare function retireUnlockCredential({ idStore, updateKeys, unlockKeys, expectedDid, verb, rosterStore, userKey, clientKeyAgreementKey, pinnedEpochId, onUserKeyAdopted, collections, onRotationAdopted }: {
|
|
107
|
+
idStore: WebvhIdStore;
|
|
108
|
+
updateKeys: ClientWebvhUpdateKeys;
|
|
109
|
+
unlockKeys: StandingUnlockKeys;
|
|
110
|
+
expectedDid?: string;
|
|
111
|
+
verb?: string;
|
|
112
|
+
rosterStore: EncryptionDescriptorStore;
|
|
113
|
+
userKey?: UserKey;
|
|
114
|
+
clientKeyAgreementKey: IKeyAgreementKey;
|
|
115
|
+
pinnedEpochId?: string | null;
|
|
116
|
+
onUserKeyAdopted?: (adopted: {
|
|
117
|
+
userKey: UserKey;
|
|
118
|
+
latestEpochId: string;
|
|
119
|
+
descriptor: CollectionEncryption;
|
|
120
|
+
}) => Promise<void>;
|
|
121
|
+
collections: CascadeCollections;
|
|
122
|
+
onRotationAdopted?: (rotation: {
|
|
123
|
+
userKey: UserKey;
|
|
124
|
+
}) => Promise<void>;
|
|
125
|
+
}): Promise<UnlockCredentialRetirementResult>;
|
|
126
|
+
//# sourceMappingURL=retire.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retire.d.ts","sourceRoot":"","sources":["../../src/unlock/retire.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC/D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAA;AACxE,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,OAAO,EACZ,KAAK,oBAAoB,EAC1B,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAC5E,OAAO,EAAmB,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAE7E;;;;;;;GAOG;AACH,MAAM,WAAW,gCAAgC;IAC/C,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,CAAC,EAAE,gBAAgB,CAAA;IAC7B,WAAW,EAAE,oBAAoB,CAAA;IACjC,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,gBAAgB,CAAC,EAAE,oBAAoB,CAAA;CACxC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAsB,sBAAsB,CAAC,EAC3C,OAAO,EACP,UAAU,EACV,UAAU,EACV,WAAW,EACX,IAAI,EACJ,WAAW,EACX,OAAO,EACP,qBAAqB,EACrB,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,iBAAiB,EAClB,EAAE;IACD,OAAO,EAAE,YAAY,CAAA;IACrB,UAAU,EAAE,qBAAqB,CAAA;IACjC,UAAU,EAAE,kBAAkB,CAAA;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,yBAAyB,CAAA;IACtC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,qBAAqB,EAAE,gBAAgB,CAAA;IACvC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE;QAC3B,OAAO,EAAE,OAAO,CAAA;QAChB,aAAa,EAAE,MAAM,CAAA;QACrB,UAAU,EAAE,oBAAoB,CAAA;KACjC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACnB,WAAW,EAAE,kBAAkB,CAAA;IAC/B,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACtE,GAAG,OAAO,CAAC,gCAAgC,CAAC,CAgD5C"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { rotateRosterToDocumentAndCascade } from '../keys/index.js';
|
|
2
|
+
import { removeUnlockKey } from './standingWebvh.js';
|
|
3
|
+
/**
|
|
4
|
+
* Retires one standing unlock credential from an account. See the module doc
|
|
5
|
+
* for the order and the convergence story. Once the posture edit lands, a
|
|
6
|
+
* thrown later stage leaves durable state a naive re-run -- or the login-time
|
|
7
|
+
* sweep -- converges from.
|
|
8
|
+
*
|
|
9
|
+
* @param options {object}
|
|
10
|
+
* @param options.idStore {WebvhIdStore} the account's `id` collection store
|
|
11
|
+
* @param options.updateKeys {ClientWebvhUpdateKeys} the RETIRING (enrolled)
|
|
12
|
+
* client's own did:webvh update-key seeds, which sign the posture edit
|
|
13
|
+
* @param options.unlockKeys {StandingUnlockKeys} the retired credential's
|
|
14
|
+
* public posture (its key-agreement publication and its committed update
|
|
15
|
+
* key)
|
|
16
|
+
* @param [options.expectedDid] {string} the account DID from the caller's
|
|
17
|
+
* stored account pointer; supplied, the posture edit refuses a `did.jsonl`
|
|
18
|
+
* resolving to any other account
|
|
19
|
+
* @param [options.verb] {string} what the caller is doing, for the
|
|
20
|
+
* pending-rotation refusal message (e.g. `'changing your passphrase'`)
|
|
21
|
+
* @param options.rosterStore {EncryptionDescriptorStore} the
|
|
22
|
+
* `key-map/user-key.jsonl` roster store
|
|
23
|
+
* @param [options.userKey] {UserKey} this client's cached user key
|
|
24
|
+
* @param options.clientKeyAgreementKey {IKeyAgreementKey} this client's own
|
|
25
|
+
* (identity) key-agreement key -- its roster entry
|
|
26
|
+
* @param [options.pinnedEpochId] {string} the locally pinned latest-seen
|
|
27
|
+
* roster epoch
|
|
28
|
+
* @param [options.onUserKeyAdopted] {Function} persists a rotated key:
|
|
29
|
+
* called with `{ userKey, latestEpochId, descriptor }` after the roster read
|
|
30
|
+
* and BEFORE the fan-out. The key and the epoch pin must persist atomically
|
|
31
|
+
* @param options.collections {CascadeCollections} the fan-out's work
|
|
32
|
+
* @param [options.onRotationAdopted] {Function} `({ userKey }) =>
|
|
33
|
+
* Promise<void>` -- the live-session adoption of a rotated key, run last so
|
|
34
|
+
* the session keeps operating without a re-login
|
|
35
|
+
* @returns {Promise<UnlockCredentialRetirementResult>}
|
|
36
|
+
*/
|
|
37
|
+
export async function retireUnlockCredential({ idStore, updateKeys, unlockKeys, expectedDid, verb, rosterStore, userKey, clientKeyAgreementKey, pinnedEpochId, onUserKeyAdopted, collections, onRotationAdopted }) {
|
|
38
|
+
// 1. The document posture edit -- the credential's standing, first. It
|
|
39
|
+
// resolves the document as it now stands, which is what stage 2 resolves
|
|
40
|
+
// its remaining recipients from.
|
|
41
|
+
const { did, doc, log } = await removeUnlockKey({
|
|
42
|
+
idStore,
|
|
43
|
+
updateKeys,
|
|
44
|
+
unlockKeys,
|
|
45
|
+
...(expectedDid !== undefined ? { expectedDid } : {}),
|
|
46
|
+
...(verb !== undefined ? { verb } : {})
|
|
47
|
+
});
|
|
48
|
+
// 2. The shared roster-and-cascade tail: the roster rotation onto the
|
|
49
|
+
// post-edit document (with its post-edit controller floor and its seal
|
|
50
|
+
// backstop), then the collection fan-out onto the fresh key.
|
|
51
|
+
const tail = await rotateRosterToDocumentAndCascade({
|
|
52
|
+
rosterStore,
|
|
53
|
+
did,
|
|
54
|
+
doc,
|
|
55
|
+
log,
|
|
56
|
+
...(userKey ? { userKey } : {}),
|
|
57
|
+
clientKeyAgreementKey,
|
|
58
|
+
pinnedEpochId,
|
|
59
|
+
...(onUserKeyAdopted ? { onUserKeyAdopted } : {}),
|
|
60
|
+
collections
|
|
61
|
+
});
|
|
62
|
+
if (!tail.rosterDescriptor || !tail.userKey) {
|
|
63
|
+
// No roster to rotate: the posture edit has landed, so the credential IS
|
|
64
|
+
// retired -- a completed ceremony with nothing rotated.
|
|
65
|
+
return {
|
|
66
|
+
rotated: false,
|
|
67
|
+
collections: tail.collections,
|
|
68
|
+
document: doc
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
if (tail.rotated) {
|
|
72
|
+
await onRotationAdopted?.({ userKey: tail.userKey });
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
rotated: tail.rotated,
|
|
76
|
+
...(tail.rosterSeal ? { rosterSeal: tail.rosterSeal } : {}),
|
|
77
|
+
collections: tail.collections,
|
|
78
|
+
document: doc,
|
|
79
|
+
userKey: tail.userKey,
|
|
80
|
+
rosterDescriptor: tail.rosterDescriptor
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=retire.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retire.js","sourceRoot":"","sources":["../../src/unlock/retire.ts"],"names":[],"mappings":"AAoDA,OAAO,EACL,gCAAgC,EAKjC,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAE,eAAe,EAA2B,MAAM,oBAAoB,CAAA;AAmB7E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,EAC3C,OAAO,EACP,UAAU,EACV,UAAU,EACV,WAAW,EACX,IAAI,EACJ,WAAW,EACX,OAAO,EACP,qBAAqB,EACrB,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,iBAAiB,EAkBlB;IACC,uEAAuE;IACvE,yEAAyE;IACzE,iCAAiC;IACjC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,eAAe,CAAC;QAC9C,OAAO;QACP,UAAU;QACV,UAAU;QACV,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxC,CAAC,CAAA;IAEF,sEAAsE;IACtE,uEAAuE;IACvE,6DAA6D;IAC7D,MAAM,IAAI,GAAG,MAAM,gCAAgC,CAAC;QAClD,WAAW;QACX,GAAG;QACH,GAAG;QACH,GAAG;QACH,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/B,qBAAqB;QACrB,aAAa;QACb,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,WAAW;KACZ,CAAC,CAAA;IACF,IAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAC5C,yEAAyE;QACzE,wDAAwD;QACxD,OAAO;YACL,OAAO,EAAE,KAAK;YACd,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,QAAQ,EAAE,GAAG;SACd,CAAA;IACH,CAAC;IAED,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,iBAAiB,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAA;IACtD,CAAC;IAED,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,QAAQ,EAAE,GAAG;QACb,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;KACxC,CAAA;AACH,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { VerificationMethod } from '@interop/did-method-webvh';
|
|
1
|
+
import type { DIDDoc, DIDLog, VerificationMethod } from '@interop/did-method-webvh';
|
|
2
2
|
import type { ClientWebvhUpdateKeys, WebvhEnrollmentKeys, WebvhIdStore } from '../webvh/didWebvh.js';
|
|
3
3
|
/**
|
|
4
4
|
* The narrow store seam the self-enrollment continuation writes through: a
|
|
@@ -82,7 +82,10 @@ export declare function unlockKeyVerificationMethod({ did, keyAgreement }: {
|
|
|
82
82
|
* to, from the caller's stored account pointer
|
|
83
83
|
* @param [options.verb] {string} what the caller is doing, for the
|
|
84
84
|
* pending-rotation refusal message (e.g. `'issuing a recovery code'`)
|
|
85
|
-
* @returns {Promise<{ did: string }>}
|
|
85
|
+
* @returns {Promise<{ did: string, doc: DIDDoc, log: DIDLog }>} the account
|
|
86
|
+
* DID and the document and log as this call leaves them (unchanged when the
|
|
87
|
+
* posture was already settled), which is what the caller's roster-side half
|
|
88
|
+
* converges onto
|
|
86
89
|
*/
|
|
87
90
|
export declare function publishUnlockKey(options: {
|
|
88
91
|
idStore: WebvhIdStore;
|
|
@@ -92,6 +95,8 @@ export declare function publishUnlockKey(options: {
|
|
|
92
95
|
verb?: string;
|
|
93
96
|
}): Promise<{
|
|
94
97
|
did: string;
|
|
98
|
+
doc: DIDDoc;
|
|
99
|
+
log: DIDLog;
|
|
95
100
|
}>;
|
|
96
101
|
/**
|
|
97
102
|
* REMOVAL (run by an enrolled client, root authority): removes a standing
|
|
@@ -102,7 +107,8 @@ export declare function publishUnlockKey(options: {
|
|
|
102
107
|
* entry.
|
|
103
108
|
*
|
|
104
109
|
* @param options {object} see {@link publishUnlockKey}
|
|
105
|
-
* @returns {Promise<{ did: string }>}
|
|
110
|
+
* @returns {Promise<{ did: string, doc: DIDDoc, log: DIDLog }>} see
|
|
111
|
+
* {@link publishUnlockKey}
|
|
106
112
|
*/
|
|
107
113
|
export declare function removeUnlockKey(options: {
|
|
108
114
|
idStore: WebvhIdStore;
|
|
@@ -112,6 +118,8 @@ export declare function removeUnlockKey(options: {
|
|
|
112
118
|
verb?: string;
|
|
113
119
|
}): Promise<{
|
|
114
120
|
did: string;
|
|
121
|
+
doc: DIDDoc;
|
|
122
|
+
log: DIDLog;
|
|
115
123
|
}>;
|
|
116
124
|
/**
|
|
117
125
|
* SELF-ENROLLMENT (run by the credential-derived client through the delegated
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standingWebvh.d.ts","sourceRoot":"","sources":["../../src/unlock/standingWebvh.ts"],"names":[],"mappings":"AA4CA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"standingWebvh.d.ts","sourceRoot":"","sources":["../../src/unlock/standingWebvh.ts"],"names":[],"mappings":"AA4CA,OAAO,KAAK,EACV,MAAM,EACN,MAAM,EACN,kBAAkB,EACnB,MAAM,2BAA2B,CAAA;AAelC,OAAO,KAAK,EACV,qBAAqB,EAErB,mBAAmB,EACnB,YAAY,EACb,MAAM,sBAAsB,CAAA;AAG7B;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,IAAI,CAC/B,YAAY,EACZ,kBAAkB,GAAG,eAAe,CACrC,CAAA;AAED;;;;;;GAMG;AACH,MAAM,MAAM,6BAA6B,GACvC;IAAE,kBAAkB,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,CAAA;AAEzD;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,6BAA6B,CAAA;IAC3C,kBAAkB,EAAE,MAAM,CAAA;CAC3B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,EAC5B,GAAG,EACH,YAAY,EACb,EAAE;IACD,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,6BAA6B,CAAA;CAC5C,GAAG,MAAM,CAMT;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,2BAA2B,CAAC,EAC1C,GAAG,EACH,YAAY,EACb,EAAE;IACD,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,6BAA6B,CAAA;CAC5C,GAAG,kBAAkB,CAgBrB;AAsDD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE;IAC9C,OAAO,EAAE,YAAY,CAAA;IACrB,UAAU,EAAE,qBAAqB,CAAA;IACjC,UAAU,EAAE,kBAAkB,CAAA;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAIrD;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE;IAC7C,OAAO,EAAE,YAAY,CAAA;IACrB,UAAU,EAAE,qBAAqB,CAAA;IACjC,UAAU,EAAE,kBAAkB,CAAA;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAIrD;AAkGD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE;IACnD,KAAK,EAAE,cAAc,CAAA;IACrB,UAAU,EAAE,UAAU,CAAA;IACtB,aAAa,EAAE,mBAAmB,CAAA;IAClC,oBAAoB,EAAE,qBAAqB,CAAA;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAE5C"}
|
|
@@ -150,7 +150,10 @@ async function publishLogOnly({ store, log, ifMatch }) {
|
|
|
150
150
|
* to, from the caller's stored account pointer
|
|
151
151
|
* @param [options.verb] {string} what the caller is doing, for the
|
|
152
152
|
* pending-rotation refusal message (e.g. `'issuing a recovery code'`)
|
|
153
|
-
* @returns {Promise<{ did: string }>}
|
|
153
|
+
* @returns {Promise<{ did: string, doc: DIDDoc, log: DIDLog }>} the account
|
|
154
|
+
* DID and the document and log as this call leaves them (unchanged when the
|
|
155
|
+
* posture was already settled), which is what the caller's roster-side half
|
|
156
|
+
* converges onto
|
|
154
157
|
*/
|
|
155
158
|
export async function publishUnlockKey(options) {
|
|
156
159
|
return withLogConflictRetry(() => setUnlockKeyPostureOnce({ ...options, polarity: 'publish' }));
|
|
@@ -164,7 +167,8 @@ export async function publishUnlockKey(options) {
|
|
|
164
167
|
* entry.
|
|
165
168
|
*
|
|
166
169
|
* @param options {object} see {@link publishUnlockKey}
|
|
167
|
-
* @returns {Promise<{ did: string }>}
|
|
170
|
+
* @returns {Promise<{ did: string, doc: DIDDoc, log: DIDLog }>} see
|
|
171
|
+
* {@link publishUnlockKey}
|
|
168
172
|
*/
|
|
169
173
|
export async function removeUnlockKey(options) {
|
|
170
174
|
return withLogConflictRetry(() => setUnlockKeyPostureOnce({ ...options, polarity: 'remove' }));
|
|
@@ -176,7 +180,7 @@ export async function removeUnlockKey(options) {
|
|
|
176
180
|
* between two copies would be published into an append-only log.
|
|
177
181
|
*
|
|
178
182
|
* @param options {object} see {@link publishUnlockKey}, plus `polarity`
|
|
179
|
-
* @returns {Promise<{ did: string }>}
|
|
183
|
+
* @returns {Promise<{ did: string, doc: DIDDoc, log: DIDLog }>}
|
|
180
184
|
*/
|
|
181
185
|
async function setUnlockKeyPostureOnce({ idStore, updateKeys, unlockKeys, expectedDid, verb, polarity }) {
|
|
182
186
|
const published = await readLogOrThrow({
|
|
@@ -192,7 +196,7 @@ async function setUnlockKeyPostureOnce({ idStore, updateKeys, unlockKeys, expect
|
|
|
192
196
|
? vmPresent && hashCommitted
|
|
193
197
|
: !vmPresent && !hashCommitted;
|
|
194
198
|
if (settled) {
|
|
195
|
-
return { did };
|
|
199
|
+
return { did, doc, log: published.log };
|
|
196
200
|
}
|
|
197
201
|
const activeKey = await updateKeyMultibase({ seed: updateKeys.updateSeed });
|
|
198
202
|
if (!published.updateKeys.includes(activeKey)) {
|
|
@@ -236,7 +240,7 @@ async function setUnlockKeyPostureOnce({ idStore, updateKeys, unlockKeys, expect
|
|
|
236
240
|
capabilityDelegation: relationIds(doc.capabilityDelegation)
|
|
237
241
|
});
|
|
238
242
|
await publishUpdatedLog({ idStore, updated, ifMatch: published.etag });
|
|
239
|
-
return { did: updated.did };
|
|
243
|
+
return { did: updated.did, doc: updated.doc, log: updated.log };
|
|
240
244
|
}
|
|
241
245
|
/**
|
|
242
246
|
* SELF-ENROLLMENT (run by the credential-derived client through the delegated
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standingWebvh.js","sourceRoot":"","sources":["../../src/unlock/standingWebvh.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;
|
|
1
|
+
{"version":3,"file":"standingWebvh.js","sourceRoot":"","sources":["../../src/unlock/standingWebvh.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@interop/wallet-core",
|
|
3
3
|
"description": "Shared wallet-domain logic (WAS sync engine core and wallet Space layout contracts) for Interop wallet apps.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.45.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "pnpm run clear && tsc",
|