@interop/wallet-core 0.66.0 → 0.68.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 +12 -8
- package/dist/clientAnnex/credentialAnchoredGenesis.d.ts +6 -10
- package/dist/clientAnnex/credentialAnchoredGenesis.d.ts.map +1 -1
- package/dist/clientAnnex/credentialAnchoredGenesis.js +34 -56
- package/dist/clientAnnex/credentialAnchoredGenesis.js.map +1 -1
- package/dist/clientAnnex/establish.d.ts +46 -29
- package/dist/clientAnnex/establish.d.ts.map +1 -1
- package/dist/clientAnnex/establish.js +111 -86
- package/dist/clientAnnex/establish.js.map +1 -1
- package/dist/clientAnnex/forget.d.ts +7 -16
- package/dist/clientAnnex/forget.d.ts.map +1 -1
- package/dist/clientAnnex/forget.js +13 -24
- package/dist/clientAnnex/forget.js.map +1 -1
- package/dist/clientAnnex/forgetLast.d.ts +33 -129
- package/dist/clientAnnex/forgetLast.d.ts.map +1 -1
- package/dist/clientAnnex/forgetLast.js +43 -182
- package/dist/clientAnnex/forgetLast.js.map +1 -1
- package/dist/clientAnnex/gc.d.ts +26 -12
- package/dist/clientAnnex/gc.d.ts.map +1 -1
- package/dist/clientAnnex/gc.js +60 -57
- package/dist/clientAnnex/gc.js.map +1 -1
- package/dist/clientAnnex/heal.d.ts +75 -18
- package/dist/clientAnnex/heal.d.ts.map +1 -1
- package/dist/clientAnnex/heal.js +79 -147
- package/dist/clientAnnex/heal.js.map +1 -1
- package/dist/clientAnnex/index.d.ts +8 -8
- package/dist/clientAnnex/index.d.ts.map +1 -1
- package/dist/clientAnnex/index.js +5 -5
- package/dist/clientAnnex/index.js.map +1 -1
- package/dist/clientAnnex/ladder.d.ts +51 -4
- package/dist/clientAnnex/ladder.d.ts.map +1 -1
- package/dist/clientAnnex/ladder.js +283 -47
- package/dist/clientAnnex/ladder.js.map +1 -1
- package/dist/clientAnnex/ladderAnchored.d.ts +62 -73
- package/dist/clientAnnex/ladderAnchored.d.ts.map +1 -1
- package/dist/clientAnnex/ladderAnchored.js +103 -117
- package/dist/clientAnnex/ladderAnchored.js.map +1 -1
- package/dist/clientAnnex/log.d.ts +123 -125
- package/dist/clientAnnex/log.d.ts.map +1 -1
- package/dist/clientAnnex/log.js +174 -233
- package/dist/clientAnnex/log.js.map +1 -1
- package/dist/clientAnnex/mend.d.ts +0 -4
- package/dist/clientAnnex/mend.d.ts.map +1 -1
- package/dist/clientAnnex/mend.js +50 -51
- package/dist/clientAnnex/mend.js.map +1 -1
- package/dist/clientAnnex/recoveryLadderAnchored.d.ts +25 -13
- package/dist/clientAnnex/recoveryLadderAnchored.d.ts.map +1 -1
- package/dist/clientAnnex/recoveryLadderAnchored.js +80 -303
- package/dist/clientAnnex/recoveryLadderAnchored.js.map +1 -1
- package/dist/clientAnnex/rosterDeliveredEpochs.d.ts +13 -5
- package/dist/clientAnnex/rosterDeliveredEpochs.d.ts.map +1 -1
- package/dist/clientAnnex/rosterDeliveredEpochs.js +18 -9
- package/dist/clientAnnex/rosterDeliveredEpochs.js.map +1 -1
- package/dist/clientAnnex/selfEnroll.d.ts +6 -10
- package/dist/clientAnnex/selfEnroll.d.ts.map +1 -1
- package/dist/clientAnnex/selfEnroll.js +13 -18
- package/dist/clientAnnex/selfEnroll.js.map +1 -1
- package/dist/clientAnnex/zcap.d.ts +19 -0
- package/dist/clientAnnex/zcap.d.ts.map +1 -1
- package/dist/clientAnnex/zcap.js +80 -12
- package/dist/clientAnnex/zcap.js.map +1 -1
- package/dist/clients/index.d.ts +3 -2
- package/dist/clients/index.d.ts.map +1 -1
- package/dist/clients/index.js +3 -2
- package/dist/clients/index.js.map +1 -1
- package/dist/clients/listing.d.ts.map +1 -1
- package/dist/clients/listing.js +33 -15
- package/dist/clients/listing.js.map +1 -1
- package/dist/clients/policy.d.ts +18 -0
- package/dist/clients/policy.d.ts.map +1 -1
- package/dist/clients/policy.js +22 -8
- package/dist/clients/policy.js.map +1 -1
- package/dist/clients/revocation.d.ts +18 -30
- package/dist/clients/revocation.d.ts.map +1 -1
- package/dist/clients/revocation.js +12 -27
- package/dist/clients/revocation.js.map +1 -1
- package/dist/clients/rosterPolicy.d.ts +6 -1
- package/dist/clients/rosterPolicy.d.ts.map +1 -1
- package/dist/clients/rosterPolicy.js +27 -30
- package/dist/clients/rosterPolicy.js.map +1 -1
- package/dist/descriptors/errors.d.ts +6 -5
- package/dist/descriptors/errors.d.ts.map +1 -1
- package/dist/descriptors/errors.js +6 -5
- package/dist/descriptors/errors.js.map +1 -1
- package/dist/descriptors/index.d.ts +7 -3
- package/dist/descriptors/index.d.ts.map +1 -1
- package/dist/descriptors/index.js +7 -3
- package/dist/descriptors/index.js.map +1 -1
- package/dist/descriptors/logSource.d.ts +28 -6
- package/dist/descriptors/logSource.d.ts.map +1 -1
- package/dist/descriptors/logSource.js +33 -7
- package/dist/descriptors/logSource.js.map +1 -1
- package/dist/enrollment/enrollment.d.ts.map +1 -1
- package/dist/enrollment/enrollment.js +3 -7
- package/dist/enrollment/enrollment.js.map +1 -1
- package/dist/genesis/accountGenesis.d.ts +11 -16
- package/dist/genesis/accountGenesis.d.ts.map +1 -1
- package/dist/genesis/accountGenesis.js +43 -47
- package/dist/genesis/accountGenesis.js.map +1 -1
- package/dist/genesis/kmsAuthentication.d.ts +50 -0
- package/dist/genesis/kmsAuthentication.d.ts.map +1 -0
- package/dist/genesis/kmsAuthentication.js +49 -0
- package/dist/genesis/kmsAuthentication.js.map +1 -0
- package/dist/keyring/kdf.d.ts +16 -20
- package/dist/keyring/kdf.d.ts.map +1 -1
- package/dist/keyring/kdf.js +2 -2
- package/dist/keyring/kdf.js.map +1 -1
- package/dist/keyring/unlockSpace.d.ts +8 -30
- package/dist/keyring/unlockSpace.d.ts.map +1 -1
- package/dist/keyring/unlockSpace.js +8 -31
- package/dist/keyring/unlockSpace.js.map +1 -1
- package/dist/keys/clientKeyRecord.d.ts +2 -1
- package/dist/keys/clientKeyRecord.d.ts.map +1 -1
- package/dist/keys/clientKeyRecord.js +28 -11
- package/dist/keys/clientKeyRecord.js.map +1 -1
- package/dist/keys/index.d.ts +6 -2
- package/dist/keys/index.d.ts.map +1 -1
- package/dist/keys/index.js +5 -1
- package/dist/keys/index.js.map +1 -1
- package/dist/keys/rosterLogStore.d.ts.map +1 -1
- package/dist/keys/rosterLogStore.js +14 -5
- package/dist/keys/rosterLogStore.js.map +1 -1
- package/dist/keys/spaceEpochs.d.ts +92 -3
- package/dist/keys/spaceEpochs.d.ts.map +1 -1
- package/dist/keys/spaceEpochs.js +110 -4
- package/dist/keys/spaceEpochs.js.map +1 -1
- package/dist/keys/userKeyRoster.d.ts +30 -3
- package/dist/keys/userKeyRoster.d.ts.map +1 -1
- package/dist/keys/userKeyRoster.js +90 -15
- package/dist/keys/userKeyRoster.js.map +1 -1
- package/dist/keys/userKeyRosterCascade.d.ts.map +1 -1
- package/dist/keys/userKeyRosterCascade.js +5 -1
- package/dist/keys/userKeyRosterCascade.js.map +1 -1
- package/dist/recovery/continuation.d.ts +250 -0
- package/dist/recovery/continuation.d.ts.map +1 -0
- package/dist/recovery/continuation.js +467 -0
- package/dist/recovery/continuation.js.map +1 -0
- package/dist/recovery/index.d.ts +12 -8
- package/dist/recovery/index.d.ts.map +1 -1
- package/dist/recovery/index.js +11 -7
- package/dist/recovery/index.js.map +1 -1
- package/dist/recovery/recoveryDelegation.d.ts +23 -126
- package/dist/recovery/recoveryDelegation.d.ts.map +1 -1
- package/dist/recovery/recoveryDelegation.js +1 -266
- package/dist/recovery/recoveryDelegation.js.map +1 -1
- package/dist/recovery/recoveryWebvh.d.ts +52 -107
- package/dist/recovery/recoveryWebvh.d.ts.map +1 -1
- package/dist/recovery/recoveryWebvh.js +54 -403
- package/dist/recovery/recoveryWebvh.js.map +1 -1
- package/dist/request/classify.d.ts +3 -14
- package/dist/request/classify.d.ts.map +1 -1
- package/dist/request/classify.js +19 -40
- package/dist/request/classify.js.map +1 -1
- package/dist/request/index.d.ts +1 -0
- package/dist/request/index.d.ts.map +1 -1
- package/dist/request/index.js +1 -0
- package/dist/request/index.js.map +1 -1
- package/dist/request/onboarding.d.ts.map +1 -1
- package/dist/request/onboarding.js +19 -27
- package/dist/request/onboarding.js.map +1 -1
- package/dist/request/parse.d.ts +5 -3
- package/dist/request/parse.d.ts.map +1 -1
- package/dist/request/parse.js +7 -6
- package/dist/request/parse.js.map +1 -1
- package/dist/request/processRequest.d.ts.map +1 -1
- package/dist/request/processRequest.js +2 -1
- package/dist/request/processRequest.js.map +1 -1
- package/dist/request/queryPredicates.d.ts +98 -0
- package/dist/request/queryPredicates.d.ts.map +1 -0
- package/dist/request/queryPredicates.js +107 -0
- package/dist/request/queryPredicates.js.map +1 -0
- package/dist/resourceLog/document.d.ts +39 -0
- package/dist/resourceLog/document.d.ts.map +1 -1
- package/dist/resourceLog/document.js +41 -0
- package/dist/resourceLog/document.js.map +1 -1
- package/dist/resourceLog/index.d.ts +2 -2
- package/dist/resourceLog/index.js +2 -2
- package/dist/resourceLog/ladderRungs.d.ts.map +1 -1
- package/dist/resourceLog/ladderRungs.js +3 -2
- package/dist/resourceLog/ladderRungs.js.map +1 -1
- package/dist/sync/contactsConflict.d.ts.map +1 -1
- package/dist/sync/contactsConflict.js +8 -2
- package/dist/sync/contactsConflict.js.map +1 -1
- package/dist/sync/engine.d.ts +38 -23
- package/dist/sync/engine.d.ts.map +1 -1
- package/dist/sync/engine.js +36 -5
- package/dist/sync/engine.js.map +1 -1
- package/dist/sync/index.d.ts +9 -12
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +8 -11
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/push.d.ts.map +1 -1
- package/dist/sync/push.js +1 -2
- package/dist/sync/push.js.map +1 -1
- package/dist/sync/remint.d.ts +0 -31
- package/dist/sync/remint.d.ts.map +1 -1
- package/dist/sync/remint.js +32 -1
- package/dist/sync/remint.js.map +1 -1
- package/dist/sync/types.d.ts +4 -41
- package/dist/sync/types.d.ts.map +1 -1
- package/dist/sync/types.js +4 -47
- package/dist/sync/types.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/unlock/retire.d.ts +16 -64
- package/dist/unlock/retire.d.ts.map +1 -1
- package/dist/unlock/retire.js +7 -86
- package/dist/unlock/retire.js.map +1 -1
- package/dist/unlock/standingWebvh.d.ts +27 -61
- package/dist/unlock/standingWebvh.d.ts.map +1 -1
- package/dist/unlock/standingWebvh.js +40 -92
- package/dist/unlock/standingWebvh.js.map +1 -1
- package/dist/unlock/unlockRecord.d.ts.map +1 -1
- package/dist/unlock/unlockRecord.js +69 -44
- package/dist/unlock/unlockRecord.js.map +1 -1
- package/dist/webvh/accountEntry.d.ts +68 -19
- package/dist/webvh/accountEntry.d.ts.map +1 -1
- package/dist/webvh/accountEntry.js +117 -37
- package/dist/webvh/accountEntry.js.map +1 -1
- package/dist/webvh/delegatedLogStore.d.ts +24 -13
- package/dist/webvh/delegatedLogStore.d.ts.map +1 -1
- package/dist/webvh/delegatedLogStore.js +40 -11
- package/dist/webvh/delegatedLogStore.js.map +1 -1
- package/dist/webvh/didWebvh.d.ts +91 -86
- package/dist/webvh/didWebvh.d.ts.map +1 -1
- package/dist/webvh/didWebvh.js +117 -142
- package/dist/webvh/didWebvh.js.map +1 -1
- package/dist/webvh/enrollClient.d.ts +2 -8
- package/dist/webvh/enrollClient.d.ts.map +1 -1
- package/dist/webvh/enrollClient.js +22 -31
- package/dist/webvh/enrollClient.js.map +1 -1
- package/dist/webvh/index.d.ts +12 -8
- package/dist/webvh/index.d.ts.map +1 -1
- package/dist/webvh/index.js +10 -7
- package/dist/webvh/index.js.map +1 -1
- package/dist/webvh/listClients.d.ts.map +1 -1
- package/dist/webvh/listClients.js +102 -65
- package/dist/webvh/listClients.js.map +1 -1
- package/dist/webvh/mergeMethods.d.ts +84 -0
- package/dist/webvh/mergeMethods.d.ts.map +1 -0
- package/dist/webvh/mergeMethods.js +46 -0
- package/dist/webvh/mergeMethods.js.map +1 -0
- package/dist/webvh/revokeClient.d.ts +15 -11
- package/dist/webvh/revokeClient.d.ts.map +1 -1
- package/dist/webvh/revokeClient.js +130 -57
- package/dist/webvh/revokeClient.js.map +1 -1
- package/dist/webvh/verifyLog.d.ts +45 -4
- package/dist/webvh/verifyLog.d.ts.map +1 -1
- package/dist/webvh/verifyLog.js +62 -21
- package/dist/webvh/verifyLog.js.map +1 -1
- package/dist/webvh/wasIdStore.d.ts +16 -3
- package/dist/webvh/wasIdStore.d.ts.map +1 -1
- package/dist/webvh/wasIdStore.js +18 -3
- package/dist/webvh/wasIdStore.js.map +1 -1
- package/package.json +11 -11
|
@@ -38,11 +38,11 @@
|
|
|
38
38
|
* the ENROLLED client's root authority, and not through the credential's
|
|
39
39
|
* bridge delegation. The bridge is often signed by the very VM the strike
|
|
40
40
|
* removes -- the readiness stage's renewal mints it as the ladder, and
|
|
41
|
-
* stage
|
|
41
|
+
* stage 5 re-signs it as the ladder again -- so a bridge-invoked reinstall
|
|
42
42
|
* would be authorized against the post-strike document under the
|
|
43
43
|
* current-key-set rule and refused, leaving the account VM-less with every
|
|
44
44
|
* ladder-signed delegation rotted and a re-run failing identically. The
|
|
45
|
-
* client stands until stage
|
|
45
|
+
* client stands until stage 6 and holds root authority on the Space, so
|
|
46
46
|
* its store is the one that carries the pair. Only the HTTP invocation
|
|
47
47
|
* changes: both entries stay ladder-SIGNED.
|
|
48
48
|
* 2. **The roster rotation**, ladder-signed, anchored at the reinstall entry,
|
|
@@ -73,39 +73,18 @@
|
|
|
73
73
|
* is what keeps a torn run from stranding the generation delegation-less.
|
|
74
74
|
* A delegation a surviving sibling credential's ladder signed is left
|
|
75
75
|
* standing, since the revocation loop never reaches it either.
|
|
76
|
-
* 5. **The
|
|
77
|
-
* other standing credential's and recovery code's bridge (and
|
|
78
|
-
* `delegatedClients` sibling, where the record carries one) is re-signed
|
|
79
|
-
* by the ladder VM and its record re-sealed through the entry's
|
|
80
|
-
* management zcap -- the revocation cascade's re-mint pass
|
|
81
|
-
* (`remintRecoveryDelegations`), run with the ladder VM as the delegating
|
|
82
|
-
* and record-signing key and the forgotten client named as retiring, so
|
|
83
|
-
* every delegation it signed counts as rotted ahead of the removal entry.
|
|
84
|
-
* Delegations the removed client had signed rot at that entry, and on a
|
|
85
|
-
* client-less account no remembered login's refresh block will ever run
|
|
86
|
-
* again to heal them, so this is the one pass that reaches them. The
|
|
87
|
-
* HTTP side still invokes under the still-standing client (the
|
|
88
|
-
* management zcaps are granted to the account DID, which only an enrolled
|
|
89
|
-
* client can invoke) -- which is why the stage must run before the
|
|
90
|
-
* removal entry. The pass walks every entry and reports each one's fate,
|
|
91
|
-
* but the ceremony does not carry an unsettled entry past this point: a
|
|
92
|
-
* `failed` or `pending-entry` outcome refuses the removal entry
|
|
93
|
-
* ({@link RecordRemintFailedError}, naming the records the pass left
|
|
94
|
-
* unreached), since after the removal nothing could ever re-sign that
|
|
95
|
-
* record's bridge. The client stays
|
|
96
|
-
* enrolled, and a re-run reaches the entry again.
|
|
97
|
-
* 6. **The record re-bind seam** (`onBeforeRemoval`, required): the caller
|
|
76
|
+
* 5. **The record re-bind seam** (`onBeforeRemoval`, required): the caller
|
|
98
77
|
* re-signs the LOGIN credential's bridge and `delegatedClients` sibling
|
|
99
78
|
* with the ladder VM and re-seals its unlock record with the credential
|
|
100
|
-
* in hand (a full re-wrap, proof verified rather than settled).
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* client -- an account nothing can write to --
|
|
107
|
-
* omits the seam is refused before any read.
|
|
108
|
-
*
|
|
79
|
+
* in hand (a full re-wrap, proof verified rather than settled). It is the
|
|
80
|
+
* only unlock record this ceremony writes. Every OTHER credential's
|
|
81
|
+
* record is signed by its own credential's ladder VM, which this ceremony
|
|
82
|
+
* does not strike, so this transition rots no sibling record and re-seals
|
|
83
|
+
* none (`decisions/0019`). Without the seam the removal entry would leave
|
|
84
|
+
* the login credential's own bridge signed by the struck client's key on
|
|
85
|
+
* an account with no enrolled client -- an account nothing can write to --
|
|
86
|
+
* which is why a call that omits the seam is refused before any read.
|
|
87
|
+
* 6. **The removal entry** ({@link forgetLastWebvhClient}): the client's
|
|
109
88
|
* whole document inventory out while the reinstalled ladder VM keeps the
|
|
110
89
|
* account anchored. The post-removal `did:web` projection is PUT through
|
|
111
90
|
* `clientLogStore` immediately BEFORE that entry, since the entry itself
|
|
@@ -133,9 +112,7 @@
|
|
|
133
112
|
* the generation stage re-asks the same staleness policy (a prior run's own
|
|
134
113
|
* fresh delegation reads as retiring, so a re-run churns one delegation and
|
|
135
114
|
* strands nothing, while a sibling-signed one churns none), and the record
|
|
136
|
-
* re-
|
|
137
|
-
* already ladder-signed reads as current, one whose re-mint failed is still
|
|
138
|
-
* rotted and is re-minted). Torn after the removal entry is the
|
|
115
|
+
* re-bind seam is idempotent. Torn after the removal entry is the
|
|
139
116
|
* finish-the-wipe state the app's next login maps.
|
|
140
117
|
*
|
|
141
118
|
* The honest limitation is the cascade's, as everywhere: ciphertext this
|
|
@@ -143,16 +120,12 @@
|
|
|
143
120
|
* and old epochs stay open to keys it already held.
|
|
144
121
|
*/
|
|
145
122
|
import type { DIDDoc, DIDLog } from '@interop/did-method-webvh';
|
|
146
|
-
import type { IKeyAgreementKey
|
|
147
|
-
import type { ZcapClient } from '@interop/ezcap';
|
|
123
|
+
import type { IKeyAgreementKey } from '@interop/data-integrity-core';
|
|
148
124
|
import type { CollectionEncryption, IDelegatedZcap } from '@interop/was-client';
|
|
149
125
|
import type { WebvhIdStore } from '../webvh/didWebvh.js';
|
|
150
126
|
import { type RevokedClientKeys } from '../webvh/revokeClient.js';
|
|
151
|
-
import type { ResourceLogPinStore } from '@interop/vh-resource-log';
|
|
152
127
|
import { type CascadeCollections, type SealableEncryptionDescriptorStore, type UserKey, type UserKeyAdoptedHook, type UserKeyCascadeResult } from '../keys/index.js';
|
|
153
128
|
import type { UnlockLogStore } from '../unlock/standingWebvh.js';
|
|
154
|
-
import type { AccountPointer } from '../keyring/record.js';
|
|
155
|
-
import { type RecordRemintOutcome, type RecoveryDelegationEntry } from '../recovery/recoveryDelegation.js';
|
|
156
129
|
import { type ClientAnnexWriteStore } from './log.js';
|
|
157
130
|
/**
|
|
158
131
|
* What the ceremony's generation stage did: the revoked delegation ids, and
|
|
@@ -173,76 +146,26 @@ export interface GenerationDelegationRetirement {
|
|
|
173
146
|
replaced: boolean;
|
|
174
147
|
skipped?: 'no-pointer' | 'log-unreadable' | 'rung-uncommitted' | 'already-removed';
|
|
175
148
|
}
|
|
176
|
-
/**
|
|
177
|
-
* The other unlock methods' reach for the record re-mint stage: the registry
|
|
178
|
-
* entries to walk (the OTHER methods' -- the login credential's own record is
|
|
179
|
-
* the `onBeforeRemoval` seam's, re-wrapped with the credential in hand; an
|
|
180
|
-
* entry for it here is harmless but redundant), the unlock Spaces' storage
|
|
181
|
-
* server, the management-zcap client factory (invoking as the still-standing
|
|
182
|
-
* client), and the registry record-back seam. The shape is the revocation
|
|
183
|
-
* cascade's re-mint seams verbatim, so an app binds both from one place.
|
|
184
|
-
*/
|
|
185
|
-
export interface UnlockMethodsRemintReach<Entry extends RecoveryDelegationEntry = RecoveryDelegationEntry> {
|
|
186
|
-
entries: Entry[];
|
|
187
|
-
pointer: AccountPointer;
|
|
188
|
-
storageServerUrl: string;
|
|
189
|
-
managementZcapClient: (options: {
|
|
190
|
-
capability: IZcap;
|
|
191
|
-
}) => ZcapClient;
|
|
192
|
-
recordEntry: (options: {
|
|
193
|
-
entry: Entry;
|
|
194
|
-
}) => Promise<void>;
|
|
195
|
-
}
|
|
196
149
|
/**
|
|
197
150
|
* What a completed last-client forget reports: whether the reinstall half of
|
|
198
151
|
* the strike-and-reinstall pair ran on this call (`false` on a resumed run
|
|
199
152
|
* that owed no rotation, so neither entry was published), whether the
|
|
200
153
|
* roster's wrap for the
|
|
201
154
|
* forgotten client was retired on this run, the per-collection fan-out
|
|
202
|
-
* result, the generation stage's report, the
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
* since that refuses the removal entry instead), the document as the removal
|
|
206
|
-
* entry left it, and -- when the account has a roster -- the rotated key with
|
|
207
|
-
* the roster descriptor it was read from.
|
|
155
|
+
* result, the generation stage's report, the document as the removal entry
|
|
156
|
+
* left it, and -- when the account has a roster -- the rotated key with the
|
|
157
|
+
* roster descriptor it was read from.
|
|
208
158
|
*/
|
|
209
159
|
export interface LastEnrolledClientForgetResult {
|
|
210
160
|
reinstalled: boolean;
|
|
211
161
|
rotated: boolean;
|
|
212
162
|
collections: UserKeyCascadeResult;
|
|
213
163
|
generation: GenerationDelegationRetirement;
|
|
214
|
-
unlockMethods?: {
|
|
215
|
-
reminted: number;
|
|
216
|
-
skipped: number;
|
|
217
|
-
outcomes: RecordRemintOutcome[];
|
|
218
|
-
};
|
|
219
164
|
did: string;
|
|
220
165
|
document: object;
|
|
221
166
|
userKey?: UserKey;
|
|
222
167
|
rosterDescriptor?: CollectionEncryption;
|
|
223
168
|
}
|
|
224
|
-
/**
|
|
225
|
-
* The record re-mint stage could not settle every other unlock method's
|
|
226
|
-
* record, so the removal entry was refused: `failed` names the entries the
|
|
227
|
-
* pass left unreached -- those whose re-mint threw (each carrying its cause)
|
|
228
|
-
* and those it skipped as pending-shaped (the entry's identity members name
|
|
229
|
-
* a credential other than the one its record is sealed to) -- and
|
|
230
|
-
* `unlockMethods` is the whole stage report. A pending-shaped entry blocks
|
|
231
|
-
* for the same reason a failed one does: its bridge is left signed by the
|
|
232
|
-
* key the removal entry strikes, and on a client-less account no login will
|
|
233
|
-
* ever heal it. The mender is a remembered login, which is exactly what the
|
|
234
|
-
* removal would end. The forgotten client is still enrolled and every stage
|
|
235
|
-
* before this one has landed, so a re-run resumes at the re-mint. Matched
|
|
236
|
-
* on `name` (the errors cross app-injected seams that may resolve to another
|
|
237
|
-
* copy of this package).
|
|
238
|
-
*/
|
|
239
|
-
export declare class RecordRemintFailedError extends Error {
|
|
240
|
-
readonly failed: RecordRemintOutcome[];
|
|
241
|
-
readonly unlockMethods: NonNullable<LastEnrolledClientForgetResult['unlockMethods']>;
|
|
242
|
-
constructor({ unlockMethods }: {
|
|
243
|
-
unlockMethods: NonNullable<LastEnrolledClientForgetResult['unlockMethods']>;
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
169
|
/**
|
|
247
170
|
* Forgets the account's LAST enrolled client -- this browser's own
|
|
248
171
|
* -- transitioning the account to the client-less, ladder-anchored state.
|
|
@@ -254,7 +177,13 @@ export declare class RecordRemintFailedError extends Error {
|
|
|
254
177
|
*
|
|
255
178
|
* @param options {object}
|
|
256
179
|
* @param options.logStore {UnlockLogStore} the credential's delegated
|
|
257
|
-
* `did.jsonl` bridge store; also serves the ceremony's public reads
|
|
180
|
+
* `did.jsonl` bridge store; also serves the ceremony's public reads. Every
|
|
181
|
+
* account-log read the ceremony makes -- the opening read, and the strike,
|
|
182
|
+
* reinstall, and removal entries' own reads inside their conflict-retry
|
|
183
|
+
* loops -- is checked against the chain-head pin its store carries, so a
|
|
184
|
+
* served truncated prefix is refused (`ResourceLogContinuityError`,
|
|
185
|
+
* `rollback`) before any roster append or log publish, and each entry
|
|
186
|
+
* advances the pin to the head it publishes
|
|
258
187
|
* @param options.clientLogStore {UnlockLogStore} the account-log store
|
|
259
188
|
* invoked under the STILL-STANDING enrolled client's root authority (an
|
|
260
189
|
* app's `wasWebvhIdStore` satisfies the narrower shape). The
|
|
@@ -262,17 +191,9 @@ export declare class RecordRemintFailedError extends Error {
|
|
|
262
191
|
* `logStore` is often signed by the ladder VM the strike removes and the
|
|
263
192
|
* reinstall would then be refused under the current-key-set rule. Both
|
|
264
193
|
* entries stay ladder-signed; only the HTTP invocation differs. It also
|
|
265
|
-
* carries the removal entry's pre-entry `did:web` projection PUT (stage
|
|
194
|
+
* carries the removal entry's pre-entry `did:web` projection PUT (stage 6),
|
|
266
195
|
* the one write the bridge store cannot make. Required: a call without it
|
|
267
196
|
* throws a `TypeError` before any read
|
|
268
|
-
* @param [options.pinStore] {ResourceLogPinStore} this client's chain-head
|
|
269
|
-
* pins, the account log's slot derived from `annex.accountSpaceId`. Every
|
|
270
|
-
* account-log read the ceremony makes -- the opening read, and the strike,
|
|
271
|
-
* reinstall, and removal entries' own reads inside their conflict-retry
|
|
272
|
-
* loops -- is checked against the pinned head, so a served truncated
|
|
273
|
-
* prefix is refused (`ResourceLogContinuityError`, `rollback`) before any
|
|
274
|
-
* roster append or log publish, and each entry advances the pin to the
|
|
275
|
-
* head it publishes. Without it the ceremony checks `expectedDid` only
|
|
276
197
|
* @param options.ladderSeed {Uint8Array} the login credential's ladder seed
|
|
277
198
|
* @param options.forgottenClient {RevokedClientKeys} this client's public
|
|
278
199
|
* halves; an `updateKeyMultibase` the log does not authorize (stale, or the
|
|
@@ -320,33 +241,20 @@ export declare class RecordRemintFailedError extends Error {
|
|
|
320
241
|
* server (the fresh generation delegation's target host)
|
|
321
242
|
* @param options.annex.accountSpaceId {string} the ACCOUNT Space's id (the
|
|
322
243
|
* fresh delegation's target subtree)
|
|
323
|
-
* @param [options.annex.pinStore] {ResourceLogPinStore} chain-head pins
|
|
324
|
-
* for the pointed generation's read
|
|
325
|
-
* @param [options.unlockMethods] {UnlockMethodsRemintReach} the other
|
|
326
|
-
* unlock methods' record re-mint reach (stage 5): the registry entries
|
|
327
|
-
* whose bridge (and sibling) the ladder VM re-signs and whose records it
|
|
328
|
-
* re-seals through their management zcaps, invoked as the still-standing
|
|
329
|
-
* client. Omitted, the stage is skipped and the result carries no
|
|
330
|
-
* `unlockMethods` report -- the residue decision 0004's amendment stated.
|
|
331
|
-
* Supplied, an entry the pass could not re-mint -- or skipped as
|
|
332
|
-
* pending-shaped -- refuses the removal entry
|
|
333
|
-
* (`RecordRemintFailedError`)
|
|
334
244
|
* @param options.onBeforeRemoval {Function}
|
|
335
245
|
* `({ did, doc, log }) => Promise<void>` -- the record re-bind seam: runs
|
|
336
|
-
*
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
* without it throws a `TypeError` before any read
|
|
246
|
+
* immediately before the removal entry, with the post-reinstall published
|
|
247
|
+
* state. The caller re-signs the login credential's bridge and
|
|
248
|
+
* `delegatedClients` sibling with the ladder VM and re-seals its unlock
|
|
249
|
+
* record here -- the only unlock record this ceremony writes. Must be
|
|
250
|
+
* idempotent (a resumed run invokes it again). Required: a call without it
|
|
251
|
+
* throws a `TypeError` before any read
|
|
343
252
|
* @param [options.now] {number} epoch milliseconds, for tests
|
|
344
253
|
* @returns {Promise<LastEnrolledClientForgetResult>}
|
|
345
254
|
*/
|
|
346
|
-
export declare function forgetLastEnrolledClient({ logStore, clientLogStore,
|
|
255
|
+
export declare function forgetLastEnrolledClient({ logStore, clientLogStore, ladderSeed, forgottenClient, forgottenKeyAgreementKeyMultibase, knownLatentHashes, expectedDid, rosterStore, credentialKeyAgreementKey, userKey, pinnedEpochId, onUserKeyAdopted, collections, annex, onBeforeRemoval, now }: {
|
|
347
256
|
logStore: UnlockLogStore;
|
|
348
257
|
clientLogStore: UnlockLogStore;
|
|
349
|
-
pinStore?: ResourceLogPinStore;
|
|
350
258
|
ladderSeed: Uint8Array;
|
|
351
259
|
forgottenClient: RevokedClientKeys;
|
|
352
260
|
forgottenKeyAgreementKeyMultibase: string;
|
|
@@ -366,9 +274,7 @@ export declare function forgetLastEnrolledClient({ logStore, clientLogStore, pin
|
|
|
366
274
|
revoke: (delegation: IDelegatedZcap) => Promise<void>;
|
|
367
275
|
wasServerUrl: string;
|
|
368
276
|
accountSpaceId: string;
|
|
369
|
-
pinStore?: ResourceLogPinStore;
|
|
370
277
|
};
|
|
371
|
-
unlockMethods?: UnlockMethodsRemintReach;
|
|
372
278
|
onBeforeRemoval: (published: {
|
|
373
279
|
did: string;
|
|
374
280
|
doc: object;
|
|
@@ -377,7 +283,7 @@ export declare function forgetLastEnrolledClient({ logStore, clientLogStore, pin
|
|
|
377
283
|
now?: number;
|
|
378
284
|
}): Promise<LastEnrolledClientForgetResult>;
|
|
379
285
|
/**
|
|
380
|
-
* THE LAST-CLIENT REMOVAL ENTRY (stage
|
|
286
|
+
* THE LAST-CLIENT REMOVAL ENTRY (stage 6, the transition's own removal): the
|
|
381
287
|
* plain forget's removal shape (`clientForgetEntryOnce`) with this ceremony's
|
|
382
288
|
* removability invariant injected instead of the plain forget's last-client
|
|
383
289
|
* refusal -- the forgotten client IS the last enrolled client, and the
|
|
@@ -396,8 +302,6 @@ export declare function forgetLastWebvhClient(options: {
|
|
|
396
302
|
forgottenClient: RevokedClientKeys;
|
|
397
303
|
knownLatentHashes?: string[];
|
|
398
304
|
expectedDid?: string;
|
|
399
|
-
pinStore?: ResourceLogPinStore;
|
|
400
|
-
logId?: string;
|
|
401
305
|
}): Promise<{
|
|
402
306
|
did: string;
|
|
403
307
|
doc: DIDDoc;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forgetLast.d.ts","sourceRoot":"","sources":["../../src/clientAnnex/forgetLast.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"forgetLast.d.ts","sourceRoot":"","sources":["../../src/clientAnnex/forgetLast.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqHG;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,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAK/E,OAAO,KAAK,EAAqB,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAC3E,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAA;AAGjC,OAAO,EAML,KAAK,kBAAkB,EACvB,KAAK,iCAAiC,EACtC,KAAK,OAAO,EACZ,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EAC1B,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAUhE,OAAO,EAQL,KAAK,qBAAqB,EAC3B,MAAM,UAAU,CAAA;AAEjB;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,8BAA8B;IAC7C,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EACN,YAAY,GAAG,gBAAgB,GAAG,kBAAkB,GAAG,iBAAiB,CAAA;CAC3E;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,8BAA8B;IAC7C,WAAW,EAAE,OAAO,CAAA;IACpB,OAAO,EAAE,OAAO,CAAA;IAChB,WAAW,EAAE,oBAAoB,CAAA;IACjC,UAAU,EAAE,8BAA8B,CAAA;IAC1C,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,gBAAgB,CAAC,EAAE,oBAAoB,CAAA;CACxC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqFG;AACH,wBAAsB,wBAAwB,CAAC,EAC7C,QAAQ,EACR,cAAc,EACd,UAAU,EACV,eAAe,EACf,iCAAiC,EACjC,iBAAiB,EACjB,WAAW,EACX,WAAW,EACX,yBAAyB,EACzB,OAAO,EACP,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,KAAK,EACL,eAAe,EACf,GAAgB,EACjB,EAAE;IACD,QAAQ,EAAE,cAAc,CAAA;IACxB,cAAc,EAAE,cAAc,CAAA;IAC9B,UAAU,EAAE,UAAU,CAAA;IACtB,eAAe,EAAE,iBAAiB,CAAA;IAClC,iCAAiC,EAAE,MAAM,CAAA;IACzC,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,iCAAiC,CAAA;IAC9C,yBAAyB,EAAE,gBAAgB,CAAA;IAC3C,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,gBAAgB,CAAC,EAAE,kBAAkB,CAAA;IACrC,WAAW,EAAE,kBAAkB,CAAA;IAC/B,KAAK,EAAE;QACL,QAAQ,EAAE,CAAC,OAAO,EAAE;YAClB,OAAO,EAAE,MAAM,CAAA;YACf,YAAY,EAAE,MAAM,CAAA;SACrB,KAAK,qBAAqB,CAAA;QAC3B,MAAM,EAAE,CAAC,UAAU,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;QACrD,YAAY,EAAE,MAAM,CAAA;QACpB,cAAc,EAAE,MAAM,CAAA;KACvB,CAAA;IACD,eAAe,EAAE,CAAC,SAAS,EAAE;QAC3B,GAAG,EAAE,MAAM,CAAA;QACX,GAAG,EAAE,MAAM,CAAA;QACX,GAAG,EAAE,MAAM,CAAA;KACZ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACnB,GAAG,CAAC,EAAE,MAAM,CAAA;CACb,GAAG,OAAO,CAAC,8BAA8B,CAAC,CA2N1C;AAyJD;;;;;;;;;;;;GAYG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE;IACnD,KAAK,EAAE,cAAc,CAAA;IACrB,eAAe,CAAC,EAAE,IAAI,CAAC,YAAY,EAAE,kBAAkB,GAAG,eAAe,CAAC,CAAA;IAC1E,UAAU,EAAE,UAAU,CAAA;IACtB,eAAe,EAAE,iBAAiB,CAAA;IAClC,iBAAiB,CAAC,EAAE,MAAM,EAAE,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,CAWrD"}
|
|
@@ -1,58 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { accountLogPinId } from '../webvh/verifyLog.js';
|
|
1
|
+
import { readPublishedLogOrThrow, withLogConflictRetry } from '../webvh/didWebvh.js';
|
|
3
2
|
import { clientRemovalTarget } from '../webvh/revokeClient.js';
|
|
4
3
|
import { delegationProofKeyId } from '../webvh/standingZcap.js';
|
|
5
4
|
import { vmFragmentOf } from '@interop/vh-resource-log';
|
|
6
5
|
import { anchorRosterStoreAt, isSealableDescriptorStore, retireRosterRecipientAndCascade, rosterRecipientKid, rosterWrapsRecipient } from '../keys/index.js';
|
|
7
|
-
import { recordSignerFromAgent } from '../keyring/record.js';
|
|
8
|
-
import { remintRecoveryDelegations } from '../recovery/recoveryDelegation.js';
|
|
9
6
|
import { ladderVmKeyMultibase } from './ladder.js';
|
|
10
7
|
import { ladderVmIds, relationIds } from '../resourceLog/document.js';
|
|
11
|
-
import {
|
|
8
|
+
import { ladderVmZcapClient } from './zcap.js';
|
|
12
9
|
import { clientForgetEntryOnce, installLadderVmWebvh, strikeLadderVmWebvh } from './ladderAnchored.js';
|
|
13
|
-
import { clientAnnexDidParts,
|
|
14
|
-
/**
|
|
15
|
-
* The re-mint outcomes that withhold the removal entry: a record the pass
|
|
16
|
-
* could not reach, and a pending-shaped entry it deliberately did not write
|
|
17
|
-
* (re-minting one would seal a half-retired credential a fresh bridge into
|
|
18
|
-
* the standing credential's record). Both leave a bridge the removal entry
|
|
19
|
-
* would rot for good on an account that will never see a remembered login
|
|
20
|
-
* again.
|
|
21
|
-
*/
|
|
22
|
-
const REMINT_BLOCKING_OUTCOMES = [
|
|
23
|
-
'failed',
|
|
24
|
-
'pending-entry'
|
|
25
|
-
];
|
|
26
|
-
/**
|
|
27
|
-
* The record re-mint stage could not settle every other unlock method's
|
|
28
|
-
* record, so the removal entry was refused: `failed` names the entries the
|
|
29
|
-
* pass left unreached -- those whose re-mint threw (each carrying its cause)
|
|
30
|
-
* and those it skipped as pending-shaped (the entry's identity members name
|
|
31
|
-
* a credential other than the one its record is sealed to) -- and
|
|
32
|
-
* `unlockMethods` is the whole stage report. A pending-shaped entry blocks
|
|
33
|
-
* for the same reason a failed one does: its bridge is left signed by the
|
|
34
|
-
* key the removal entry strikes, and on a client-less account no login will
|
|
35
|
-
* ever heal it. The mender is a remembered login, which is exactly what the
|
|
36
|
-
* removal would end. The forgotten client is still enrolled and every stage
|
|
37
|
-
* before this one has landed, so a re-run resumes at the re-mint. Matched
|
|
38
|
-
* on `name` (the errors cross app-injected seams that may resolve to another
|
|
39
|
-
* copy of this package).
|
|
40
|
-
*/
|
|
41
|
-
export class RecordRemintFailedError extends Error {
|
|
42
|
-
failed;
|
|
43
|
-
unlockMethods;
|
|
44
|
-
constructor({ unlockMethods }) {
|
|
45
|
-
const failed = unlockMethods.outcomes.filter(outcome => REMINT_BLOCKING_OUTCOMES.includes(outcome.outcome));
|
|
46
|
-
super('did:webvh: the last-client forget could not settle the record of ' +
|
|
47
|
-
`${failed.length} other unlock method(s) (` +
|
|
48
|
-
failed.map(outcome => `"${outcome.label}"`).join(', ') +
|
|
49
|
-
'); the removal entry was not published. The client stays enrolled; ' +
|
|
50
|
-
'run the forget again.');
|
|
51
|
-
this.name = 'RecordRemintFailedError';
|
|
52
|
-
this.failed = failed;
|
|
53
|
-
this.unlockMethods = unlockMethods;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
10
|
+
import { clientAnnexDidParts, delegatedClientsPointer, ensureGenerationDelegationCurrent, generationDelegationHistory, mintGenerationDelegation, readClientAnnexLogOrAbsent, revokeTreatingAlreadyRevokedAsSuccess } from './log.js';
|
|
56
11
|
/**
|
|
57
12
|
* Forgets the account's LAST enrolled client -- this browser's own
|
|
58
13
|
* -- transitioning the account to the client-less, ladder-anchored state.
|
|
@@ -64,7 +19,13 @@ export class RecordRemintFailedError extends Error {
|
|
|
64
19
|
*
|
|
65
20
|
* @param options {object}
|
|
66
21
|
* @param options.logStore {UnlockLogStore} the credential's delegated
|
|
67
|
-
* `did.jsonl` bridge store; also serves the ceremony's public reads
|
|
22
|
+
* `did.jsonl` bridge store; also serves the ceremony's public reads. Every
|
|
23
|
+
* account-log read the ceremony makes -- the opening read, and the strike,
|
|
24
|
+
* reinstall, and removal entries' own reads inside their conflict-retry
|
|
25
|
+
* loops -- is checked against the chain-head pin its store carries, so a
|
|
26
|
+
* served truncated prefix is refused (`ResourceLogContinuityError`,
|
|
27
|
+
* `rollback`) before any roster append or log publish, and each entry
|
|
28
|
+
* advances the pin to the head it publishes
|
|
68
29
|
* @param options.clientLogStore {UnlockLogStore} the account-log store
|
|
69
30
|
* invoked under the STILL-STANDING enrolled client's root authority (an
|
|
70
31
|
* app's `wasWebvhIdStore` satisfies the narrower shape). The
|
|
@@ -72,17 +33,9 @@ export class RecordRemintFailedError extends Error {
|
|
|
72
33
|
* `logStore` is often signed by the ladder VM the strike removes and the
|
|
73
34
|
* reinstall would then be refused under the current-key-set rule. Both
|
|
74
35
|
* entries stay ladder-signed; only the HTTP invocation differs. It also
|
|
75
|
-
* carries the removal entry's pre-entry `did:web` projection PUT (stage
|
|
36
|
+
* carries the removal entry's pre-entry `did:web` projection PUT (stage 6),
|
|
76
37
|
* the one write the bridge store cannot make. Required: a call without it
|
|
77
38
|
* throws a `TypeError` before any read
|
|
78
|
-
* @param [options.pinStore] {ResourceLogPinStore} this client's chain-head
|
|
79
|
-
* pins, the account log's slot derived from `annex.accountSpaceId`. Every
|
|
80
|
-
* account-log read the ceremony makes -- the opening read, and the strike,
|
|
81
|
-
* reinstall, and removal entries' own reads inside their conflict-retry
|
|
82
|
-
* loops -- is checked against the pinned head, so a served truncated
|
|
83
|
-
* prefix is refused (`ResourceLogContinuityError`, `rollback`) before any
|
|
84
|
-
* roster append or log publish, and each entry advances the pin to the
|
|
85
|
-
* head it publishes. Without it the ceremony checks `expectedDid` only
|
|
86
39
|
* @param options.ladderSeed {Uint8Array} the login credential's ladder seed
|
|
87
40
|
* @param options.forgottenClient {RevokedClientKeys} this client's public
|
|
88
41
|
* halves; an `updateKeyMultibase` the log does not authorize (stale, or the
|
|
@@ -130,30 +83,18 @@ export class RecordRemintFailedError extends Error {
|
|
|
130
83
|
* server (the fresh generation delegation's target host)
|
|
131
84
|
* @param options.annex.accountSpaceId {string} the ACCOUNT Space's id (the
|
|
132
85
|
* fresh delegation's target subtree)
|
|
133
|
-
* @param [options.annex.pinStore] {ResourceLogPinStore} chain-head pins
|
|
134
|
-
* for the pointed generation's read
|
|
135
|
-
* @param [options.unlockMethods] {UnlockMethodsRemintReach} the other
|
|
136
|
-
* unlock methods' record re-mint reach (stage 5): the registry entries
|
|
137
|
-
* whose bridge (and sibling) the ladder VM re-signs and whose records it
|
|
138
|
-
* re-seals through their management zcaps, invoked as the still-standing
|
|
139
|
-
* client. Omitted, the stage is skipped and the result carries no
|
|
140
|
-
* `unlockMethods` report -- the residue decision 0004's amendment stated.
|
|
141
|
-
* Supplied, an entry the pass could not re-mint -- or skipped as
|
|
142
|
-
* pending-shaped -- refuses the removal entry
|
|
143
|
-
* (`RecordRemintFailedError`)
|
|
144
86
|
* @param options.onBeforeRemoval {Function}
|
|
145
87
|
* `({ did, doc, log }) => Promise<void>` -- the record re-bind seam: runs
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
* without it throws a `TypeError` before any read
|
|
88
|
+
* immediately before the removal entry, with the post-reinstall published
|
|
89
|
+
* state. The caller re-signs the login credential's bridge and
|
|
90
|
+
* `delegatedClients` sibling with the ladder VM and re-seals its unlock
|
|
91
|
+
* record here -- the only unlock record this ceremony writes. Must be
|
|
92
|
+
* idempotent (a resumed run invokes it again). Required: a call without it
|
|
93
|
+
* throws a `TypeError` before any read
|
|
153
94
|
* @param [options.now] {number} epoch milliseconds, for tests
|
|
154
95
|
* @returns {Promise<LastEnrolledClientForgetResult>}
|
|
155
96
|
*/
|
|
156
|
-
export async function forgetLastEnrolledClient({ logStore, clientLogStore,
|
|
97
|
+
export async function forgetLastEnrolledClient({ logStore, clientLogStore, ladderSeed, forgottenClient, forgottenKeyAgreementKeyMultibase, knownLatentHashes, expectedDid, rosterStore, credentialKeyAgreementKey, userKey, pinnedEpochId, onUserKeyAdopted, collections, annex, onBeforeRemoval, now = Date.now() }) {
|
|
157
98
|
// The seam is the only stage that re-signs the login credential's bridge
|
|
158
99
|
// with the ladder VM; a run without it would land the removal entry over
|
|
159
100
|
// a record the struck key signed, on an account nothing could then write
|
|
@@ -186,14 +127,9 @@ export async function forgetLastEnrolledClient({ logStore, clientLogStore, pinSt
|
|
|
186
127
|
// state the app's next login maps -- nothing here can still invoke), and
|
|
187
128
|
// an account with another enrolled client belongs to the ordinary
|
|
188
129
|
// forget ceremony.
|
|
189
|
-
// The account log's pin slot, shared by every read and entry below.
|
|
190
|
-
const pinned = pinStore
|
|
191
|
-
? { pinStore, logId: accountLogPinId({ spaceId: annex.accountSpaceId }) }
|
|
192
|
-
: {};
|
|
193
130
|
const before = await readPublishedLogOrThrow({
|
|
194
131
|
idStore: logStore,
|
|
195
132
|
expectedDid,
|
|
196
|
-
...pinned,
|
|
197
133
|
missingMessage: 'did:webvh: did.jsonl is missing; nothing to enroll into.'
|
|
198
134
|
});
|
|
199
135
|
const preTarget = await clientRemovalTarget({
|
|
@@ -280,14 +216,12 @@ export async function forgetLastEnrolledClient({ logStore, clientLogStore, pinSt
|
|
|
280
216
|
await strikeLadderVmWebvh({
|
|
281
217
|
store: clientLogStore,
|
|
282
218
|
ladderSeed,
|
|
283
|
-
expectedDid
|
|
284
|
-
...pinned
|
|
219
|
+
expectedDid
|
|
285
220
|
});
|
|
286
221
|
const install = await installLadderVmWebvh({
|
|
287
222
|
store: clientLogStore,
|
|
288
223
|
ladderSeed,
|
|
289
|
-
expectedDid
|
|
290
|
-
...pinned
|
|
224
|
+
expectedDid
|
|
291
225
|
});
|
|
292
226
|
reinstalled = install.installed;
|
|
293
227
|
anchor = { did: install.did, doc: install.doc, log: install.log };
|
|
@@ -327,32 +261,8 @@ export async function forgetLastEnrolledClient({ logStore, clientLogStore, pinSt
|
|
|
327
261
|
annex,
|
|
328
262
|
now
|
|
329
263
|
});
|
|
330
|
-
// Stage 5: the
|
|
331
|
-
//
|
|
332
|
-
// still lists it, so without that axis every bridge it signed would read
|
|
333
|
-
// as standing and be left to rot at the removal entry.
|
|
334
|
-
let remint;
|
|
335
|
-
if (unlockMethods !== undefined) {
|
|
336
|
-
remint = await remintUnlockMethodRecordsAsLadder({
|
|
337
|
-
doc: anchor.doc,
|
|
338
|
-
accountDid: anchor.did,
|
|
339
|
-
ladderSeed,
|
|
340
|
-
retiringSigningKeyMultibase: forgottenClient.signingKeyMultibase,
|
|
341
|
-
reach: unlockMethods,
|
|
342
|
-
now
|
|
343
|
-
});
|
|
344
|
-
// The one pass that will ever reach these records on a client-less
|
|
345
|
-
// account: a record it could not re-seal -- or deliberately did not
|
|
346
|
-
// write, the pending-shaped entry -- would be left with a bridge the
|
|
347
|
-
// removal entry rots for good, so the removal is refused instead. The
|
|
348
|
-
// stages already landed are idempotent and the client still stands, so
|
|
349
|
-
// the re-run resumes here.
|
|
350
|
-
if (remint.outcomes.some(outcome => REMINT_BLOCKING_OUTCOMES.includes(outcome.outcome))) {
|
|
351
|
-
throw new RecordRemintFailedError({ unlockMethods: remint });
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
// Stage 6: the record re-bind seam -- the login credential's record, the
|
|
355
|
-
// one stage 5 skipped -- while the removal has not landed (a
|
|
264
|
+
// Stage 5: the record re-bind seam -- the login credential's record, the
|
|
265
|
+
// only one this ceremony writes -- while the removal has not landed (a
|
|
356
266
|
// ladder-VM-signed bridge verifies from the reinstall entry on, and the old
|
|
357
267
|
// client-signed one keeps verifying until the removal -- so a tear on
|
|
358
268
|
// either side of this callback leaves a working login).
|
|
@@ -361,7 +271,7 @@ export async function forgetLastEnrolledClient({ logStore, clientLogStore, pinSt
|
|
|
361
271
|
doc: anchor.doc,
|
|
362
272
|
log: anchor.log
|
|
363
273
|
});
|
|
364
|
-
// Stage
|
|
274
|
+
// Stage 6: the removal entry -- the client's whole inventory out, the
|
|
365
275
|
// installed ladder VM keeping the account anchored.
|
|
366
276
|
const removed = await forgetLastWebvhClient({
|
|
367
277
|
store: logStore,
|
|
@@ -369,15 +279,13 @@ export async function forgetLastEnrolledClient({ logStore, clientLogStore, pinSt
|
|
|
369
279
|
ladderSeed,
|
|
370
280
|
forgottenClient,
|
|
371
281
|
...(knownLatentHashes ? { knownLatentHashes } : {}),
|
|
372
|
-
expectedDid
|
|
373
|
-
...pinned
|
|
282
|
+
expectedDid
|
|
374
283
|
});
|
|
375
284
|
return {
|
|
376
285
|
reinstalled,
|
|
377
286
|
rotated: tail.rotated,
|
|
378
287
|
collections: tail.collections,
|
|
379
288
|
generation,
|
|
380
|
-
...(remint ? { unlockMethods: remint } : {}),
|
|
381
289
|
did: removed.did,
|
|
382
290
|
document: removed.doc,
|
|
383
291
|
...(tail.userKey && tail.rosterDescriptor
|
|
@@ -399,7 +307,7 @@ export async function forgetLastEnrolledClient({ logStore, clientLogStore, pinSt
|
|
|
399
307
|
* PROJECTED post-edit document, not by an unconditional force: this
|
|
400
308
|
* credential's ladder VM is named as retiring (the revocations below end its
|
|
401
309
|
* delegations, a state no client-side predicate can read) and so is the
|
|
402
|
-
* forgotten client (the removal entry in stage
|
|
310
|
+
* forgotten client (the removal entry in stage 6 has yet to strike it). A
|
|
403
311
|
* delegation signed by neither -- a sibling credential's ladder VM, which
|
|
404
312
|
* survives the transition -- stands, and keeping it is the right answer: the
|
|
405
313
|
* revocation loop below never reaches it.
|
|
@@ -421,11 +329,12 @@ async function retireLadderGenerationDelegations({ doc, accountDid, ladderSeed,
|
|
|
421
329
|
}
|
|
422
330
|
const parts = clientAnnexDidParts({ did: pointedDid });
|
|
423
331
|
const store = annex.storeFor(parts);
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
332
|
+
// Absence is read as absence even under a pin this client holds from an
|
|
333
|
+
// earlier read: a generation that is gone is the `log-unreadable` escape,
|
|
334
|
+
// and a refusal here would wedge the transition after the roster rotation.
|
|
335
|
+
const published = await readClientAnnexLogOrAbsent({
|
|
336
|
+
store,
|
|
337
|
+
expectedDid: pointedDid
|
|
429
338
|
});
|
|
430
339
|
if (published === undefined) {
|
|
431
340
|
return { revoked: [], replaced: false, skipped: 'log-unreadable' };
|
|
@@ -468,9 +377,6 @@ async function retireLadderGenerationDelegations({ doc, accountDid, ladderSeed,
|
|
|
468
377
|
expectedDid: pointedDid,
|
|
469
378
|
accountDoc: doc,
|
|
470
379
|
retiringKeyMultibases: [ladderVmKey, retiringSigningKeyMultibase],
|
|
471
|
-
...(annex.pinStore !== undefined
|
|
472
|
-
? { pinStore: annex.pinStore, logId }
|
|
473
|
-
: {}),
|
|
474
380
|
now
|
|
475
381
|
});
|
|
476
382
|
// `replaced` reports what the stage actually wrote. A delegation the
|
|
@@ -480,73 +386,28 @@ async function retireLadderGenerationDelegations({ doc, accountDid, ladderSeed,
|
|
|
480
386
|
replaced = ensured.renewed;
|
|
481
387
|
}
|
|
482
388
|
catch (err) {
|
|
483
|
-
if (err
|
|
389
|
+
if (err?.name !==
|
|
390
|
+
'ClientAnnexRungUncommittedError') {
|
|
484
391
|
throw err;
|
|
485
392
|
}
|
|
486
393
|
rungUncommitted = true;
|
|
487
394
|
}
|
|
488
395
|
// The revocations, blind and resumable (400 already-revoked as success).
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
}
|
|
499
|
-
}
|
|
396
|
+
// They target independent delegations, so they run together; the reported
|
|
397
|
+
// ids keep the doomed list's order.
|
|
398
|
+
await Promise.all(doomed.map(delegation => revokeTreatingAlreadyRevokedAsSuccess({
|
|
399
|
+
revoke: annex.revoke,
|
|
400
|
+
delegation
|
|
401
|
+
})));
|
|
402
|
+
const revoked = doomed
|
|
403
|
+
.map(delegation => delegation.id)
|
|
404
|
+
.filter((id) => typeof id === 'string');
|
|
500
405
|
return rungUncommitted
|
|
501
406
|
? { revoked, replaced, skipped: 'rung-uncommitted' }
|
|
502
407
|
: { revoked, replaced };
|
|
503
408
|
}
|
|
504
409
|
/**
|
|
505
|
-
*
|
|
506
|
-
* other unlock methods' registry entries, with the ladder VM as both the
|
|
507
|
-
* delegating key (the fresh bridge and sibling) and the record-frame signer
|
|
508
|
-
* (`ladderVmAgent`'s did:key form, whose multibase the post-reinstall document
|
|
509
|
-
* lists, so a reader settling the mixed-signer proof against the account
|
|
510
|
-
* document accepts it after the removal too -- `currentAccountRecordSigners`
|
|
511
|
-
* is that allowlist), and the forgotten client named as retiring. The sibling
|
|
512
|
-
* minter reads the annex pointer off the post-reinstall document. The HTTP
|
|
513
|
-
* side rides the caller's management-zcap clients, still invocable here.
|
|
514
|
-
*
|
|
515
|
-
* @param options {object}
|
|
516
|
-
* @param options.doc {DIDDoc} the post-reinstall account document
|
|
517
|
-
* @param options.accountDid {string}
|
|
518
|
-
* @param options.ladderSeed {Uint8Array}
|
|
519
|
-
* @param options.retiringSigningKeyMultibase {string} the forgotten
|
|
520
|
-
* client's signing key
|
|
521
|
-
* @param options.reach {UnlockMethodsRemintReach}
|
|
522
|
-
* @param options.now {number}
|
|
523
|
-
* @returns {Promise<object>} the pass's counts and per-entry outcomes
|
|
524
|
-
*/
|
|
525
|
-
async function remintUnlockMethodRecordsAsLadder({ doc, accountDid, ladderSeed, retiringSigningKeyMultibase, reach, now }) {
|
|
526
|
-
const ladderClient = await ladderVmZcapClient({ accountDid, ladderSeed });
|
|
527
|
-
const recordSigner = recordSignerFromAgent({
|
|
528
|
-
keyAgent: await ladderVmAgent({ ladderSeed })
|
|
529
|
-
});
|
|
530
|
-
return remintRecoveryDelegations({
|
|
531
|
-
doc,
|
|
532
|
-
entries: reach.entries,
|
|
533
|
-
pointer: reach.pointer,
|
|
534
|
-
storageServerUrl: reach.storageServerUrl,
|
|
535
|
-
zcapClient: ladderClient,
|
|
536
|
-
recordSigner,
|
|
537
|
-
managementZcapClient: reach.managementZcapClient,
|
|
538
|
-
recordEntry: reach.recordEntry,
|
|
539
|
-
mintDelegatedClientsDelegation: delegatedClientsDelegationMinter({
|
|
540
|
-
doc,
|
|
541
|
-
zcapClient: ladderClient,
|
|
542
|
-
wasServerUrl: reach.pointer.host
|
|
543
|
-
}),
|
|
544
|
-
retiringKeyMultibases: [retiringSigningKeyMultibase],
|
|
545
|
-
now
|
|
546
|
-
});
|
|
547
|
-
}
|
|
548
|
-
/**
|
|
549
|
-
* THE LAST-CLIENT REMOVAL ENTRY (stage 7, the transition's own removal): the
|
|
410
|
+
* THE LAST-CLIENT REMOVAL ENTRY (stage 6, the transition's own removal): the
|
|
550
411
|
* plain forget's removal shape (`clientForgetEntryOnce`) with this ceremony's
|
|
551
412
|
* removability invariant injected instead of the plain forget's last-client
|
|
552
413
|
* refusal -- the forgotten client IS the last enrolled client, and the
|