@interop/wallet-core 0.71.0 → 0.72.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 +14 -3
- package/dist/clientAnnex/forget.d.ts.map +1 -1
- package/dist/clientAnnex/forget.js +4 -3
- package/dist/clientAnnex/forget.js.map +1 -1
- package/dist/clientAnnex/forgetLast.d.ts +55 -35
- package/dist/clientAnnex/forgetLast.d.ts.map +1 -1
- package/dist/clientAnnex/forgetLast.js +87 -35
- package/dist/clientAnnex/forgetLast.js.map +1 -1
- package/dist/clientAnnex/gc.d.ts +48 -19
- package/dist/clientAnnex/gc.d.ts.map +1 -1
- package/dist/clientAnnex/gc.js +82 -31
- package/dist/clientAnnex/gc.js.map +1 -1
- package/dist/clientAnnex/grantRevocation.d.ts +137 -0
- package/dist/clientAnnex/grantRevocation.d.ts.map +1 -0
- package/dist/clientAnnex/grantRevocation.js +135 -0
- package/dist/clientAnnex/grantRevocation.js.map +1 -0
- package/dist/clientAnnex/index.d.ts +4 -2
- package/dist/clientAnnex/index.d.ts.map +1 -1
- package/dist/clientAnnex/index.js +2 -1
- package/dist/clientAnnex/index.js.map +1 -1
- package/dist/clientAnnex/ladderAnchored.d.ts +0 -22
- package/dist/clientAnnex/ladderAnchored.d.ts.map +1 -1
- package/dist/clientAnnex/ladderAnchored.js +8 -34
- package/dist/clientAnnex/ladderAnchored.js.map +1 -1
- package/dist/clientAnnex/log.d.ts +65 -13
- package/dist/clientAnnex/log.d.ts.map +1 -1
- package/dist/clientAnnex/log.js +160 -67
- package/dist/clientAnnex/log.js.map +1 -1
- package/dist/clientAnnex/mend.js +51 -24
- package/dist/clientAnnex/mend.js.map +1 -1
- package/dist/clients/grantState.d.ts +6 -3
- package/dist/clients/grantState.d.ts.map +1 -1
- package/dist/clients/grantState.js +6 -3
- package/dist/clients/grantState.js.map +1 -1
- package/dist/clients/policy.d.ts.map +1 -1
- package/dist/clients/policy.js +3 -0
- package/dist/clients/policy.js.map +1 -1
- package/dist/keyring/fetch.d.ts +6 -2
- package/dist/keyring/fetch.d.ts.map +1 -1
- package/dist/keyring/fetch.js +7 -3
- package/dist/keyring/fetch.js.map +1 -1
- package/dist/keyring/index.d.ts +7 -5
- package/dist/keyring/index.d.ts.map +1 -1
- package/dist/keyring/index.js +7 -5
- package/dist/keyring/index.js.map +1 -1
- package/dist/keyring/kdf.d.ts +1 -1
- package/dist/keyring/kdf.d.ts.map +1 -1
- package/dist/keyring/kdf.js +1 -1
- package/dist/keyring/kdf.js.map +1 -1
- package/dist/keyring/unlockSpace.d.ts +45 -68
- package/dist/keyring/unlockSpace.d.ts.map +1 -1
- package/dist/keyring/unlockSpace.js +66 -88
- package/dist/keyring/unlockSpace.js.map +1 -1
- package/dist/menders/derive.d.ts +85 -0
- package/dist/menders/derive.d.ts.map +1 -0
- package/dist/menders/derive.js +138 -0
- package/dist/menders/derive.js.map +1 -0
- package/dist/menders/ids.d.ts +20 -0
- package/dist/menders/ids.d.ts.map +1 -0
- package/dist/menders/ids.js +85 -0
- package/dist/menders/ids.js.map +1 -0
- package/dist/menders/index.d.ts +42 -0
- package/dist/menders/index.d.ts.map +1 -0
- package/dist/menders/index.js +37 -0
- package/dist/menders/index.js.map +1 -0
- package/dist/menders/registry.d.ts +84 -0
- package/dist/menders/registry.d.ts.map +1 -0
- package/dist/menders/registry.js +62 -0
- package/dist/menders/registry.js.map +1 -0
- package/dist/menders/runner.d.ts +143 -0
- package/dist/menders/runner.d.ts.map +1 -0
- package/dist/menders/runner.js +222 -0
- package/dist/menders/runner.js.map +1 -0
- package/dist/menders/types.d.ts +146 -0
- package/dist/menders/types.d.ts.map +1 -0
- package/dist/menders/types.js +2 -0
- package/dist/menders/types.js.map +1 -0
- package/dist/menders/vocabulary.d.ts +88 -0
- package/dist/menders/vocabulary.d.ts.map +1 -0
- package/dist/menders/vocabulary.js +83 -0
- package/dist/menders/vocabulary.js.map +1 -0
- package/dist/recovery/index.d.ts +1 -1
- package/dist/recovery/index.js +1 -1
- package/dist/recovery/recoveryWebvh.d.ts.map +1 -1
- package/dist/recovery/recoveryWebvh.js +11 -17
- package/dist/recovery/recoveryWebvh.js.map +1 -1
- package/dist/resourceLog/document.d.ts.map +1 -1
- package/dist/resourceLog/document.js +30 -6
- package/dist/resourceLog/document.js.map +1 -1
- package/dist/space/activity.d.ts +70 -0
- package/dist/space/activity.d.ts.map +1 -1
- package/dist/space/activity.js +82 -0
- package/dist/space/activity.js.map +1 -1
- package/dist/space/deleteSpace.d.ts.map +1 -1
- package/dist/space/deleteSpace.js +6 -5
- package/dist/space/deleteSpace.js.map +1 -1
- package/dist/space/index.d.ts +1 -1
- package/dist/space/index.d.ts.map +1 -1
- package/dist/space/index.js +1 -1
- package/dist/space/index.js.map +1 -1
- package/dist/testing.d.ts +78 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +89 -0
- package/dist/testing.js.map +1 -0
- package/dist/unlock/index.d.ts +2 -2
- package/dist/unlock/index.d.ts.map +1 -1
- package/dist/unlock/index.js +1 -1
- package/dist/unlock/retire.d.ts +20 -5
- package/dist/unlock/retire.d.ts.map +1 -1
- package/dist/unlock/retire.js.map +1 -1
- package/dist/unlock/standingWebvh.d.ts +22 -2
- package/dist/unlock/standingWebvh.d.ts.map +1 -1
- package/dist/unlock/standingWebvh.js +22 -2
- package/dist/unlock/standingWebvh.js.map +1 -1
- package/dist/webvh/didWebvh.d.ts +33 -0
- package/dist/webvh/didWebvh.d.ts.map +1 -1
- package/dist/webvh/didWebvh.js +50 -11
- package/dist/webvh/didWebvh.js.map +1 -1
- package/dist/webvh/enrollClient.d.ts.map +1 -1
- package/dist/webvh/enrollClient.js +4 -16
- package/dist/webvh/enrollClient.js.map +1 -1
- package/dist/webvh/index.d.ts +13 -3
- package/dist/webvh/index.d.ts.map +1 -1
- package/dist/webvh/index.js +13 -3
- package/dist/webvh/index.js.map +1 -1
- package/dist/webvh/listClients.d.ts +47 -0
- package/dist/webvh/listClients.d.ts.map +1 -1
- package/dist/webvh/listClients.js +40 -1
- package/dist/webvh/listClients.js.map +1 -1
- package/dist/webvh/standingZcap.d.ts +66 -0
- package/dist/webvh/standingZcap.d.ts.map +1 -1
- package/dist/webvh/standingZcap.js +96 -0
- package/dist/webvh/standingZcap.js.map +1 -1
- package/dist/webvh/zcap.d.ts +1 -1
- package/package.json +18 -6
|
@@ -6,9 +6,15 @@
|
|
|
6
6
|
* and separate from the wallet data Space, holding the one keyring record.
|
|
7
7
|
* These are standalone functions rather than methods on a wallet's remote-store
|
|
8
8
|
* class (that store is bound to the data identity): each builds its own
|
|
9
|
-
* `WasClient` over the
|
|
10
|
-
* the unlock root key (root invocation,
|
|
11
|
-
* invocation shape the data Space uses).
|
|
9
|
+
* `WasClient` over the caller's `zcapClient`. By default that is the unlock
|
|
10
|
+
* agent's, whose invocation signer is the unlock root key (root invocation,
|
|
11
|
+
* no capability attached -- the same invocation shape the data Space uses).
|
|
12
|
+
* Each read/write/delete also takes an optional `capability`: an enrolled
|
|
13
|
+
* client's `zcapClient` then invokes the management zcap the unlock identity
|
|
14
|
+
* delegated at bind time, which is how a ceremony reaches an unlock Space
|
|
15
|
+
* without holding its secret (the revocation cascade's re-mint reading and
|
|
16
|
+
* re-PUTting a recovery code's standing record, or a lost unlock method's
|
|
17
|
+
* Space being retired).
|
|
12
18
|
*
|
|
13
19
|
* The one resource is a plaintext JSON document (its keyring payload is
|
|
14
20
|
* already ciphertext), so no encryption provider is wired in and every
|
|
@@ -16,7 +22,6 @@
|
|
|
16
22
|
* here for the absent Space a fresh unlock secret's keyring lookup meets.
|
|
17
23
|
*/
|
|
18
24
|
import { WasClient } from '@interop/was-client';
|
|
19
|
-
import { resourcePath } from '@interop/was-client/paths';
|
|
20
25
|
import { KEYRING_COLLECTION, KEYRING_RESOURCE } from '../space/collections.js';
|
|
21
26
|
import { plaintextCollection } from '../space/plaintextCollection.js';
|
|
22
27
|
/**
|
|
@@ -74,11 +79,18 @@ async function ensurePlaintextCollection({ storageServerUrl, zcapClient, spaceId
|
|
|
74
79
|
* @param options.spaceId {string}
|
|
75
80
|
* @param options.collectionId {string}
|
|
76
81
|
* @param options.resourceId {string}
|
|
82
|
+
* @param [options.capability] {IZcap} an invocation capability the GET
|
|
83
|
+
* rides; absent, the request invokes the root capability
|
|
77
84
|
* @returns {Promise<unknown | null>}
|
|
78
85
|
*/
|
|
79
|
-
async function getPlaintextRecord({ storageServerUrl, zcapClient, spaceId, collectionId, resourceId }) {
|
|
86
|
+
async function getPlaintextRecord({ storageServerUrl, zcapClient, spaceId, collectionId, resourceId, capability }) {
|
|
80
87
|
const was = unlockSpaceClient({ storageServerUrl, zcapClient });
|
|
81
|
-
const result = await plaintextCollection({
|
|
88
|
+
const result = await plaintextCollection({
|
|
89
|
+
was,
|
|
90
|
+
spaceId,
|
|
91
|
+
collectionId,
|
|
92
|
+
capability
|
|
93
|
+
})
|
|
82
94
|
.resource(resourceId)
|
|
83
95
|
.get();
|
|
84
96
|
return result === null ? null : result;
|
|
@@ -94,12 +106,14 @@ async function getPlaintextRecord({ storageServerUrl, zcapClient, spaceId, colle
|
|
|
94
106
|
* @param options.collectionId {string}
|
|
95
107
|
* @param options.resourceId {string}
|
|
96
108
|
* @param options.record {object}
|
|
109
|
+
* @param [options.capability] {IZcap} an invocation capability the PUT
|
|
110
|
+
* rides; absent, the request invokes the root capability
|
|
97
111
|
* @returns {Promise<void>}
|
|
98
112
|
*/
|
|
99
|
-
async function putPlaintextRecord({ storageServerUrl, zcapClient, spaceId, collectionId, resourceId, record }) {
|
|
113
|
+
async function putPlaintextRecord({ storageServerUrl, zcapClient, spaceId, collectionId, resourceId, record, capability }) {
|
|
100
114
|
const was = unlockSpaceClient({ storageServerUrl, zcapClient });
|
|
101
115
|
const body = new TextEncoder().encode(JSON.stringify(record));
|
|
102
|
-
await plaintextCollection({ was, spaceId, collectionId })
|
|
116
|
+
await plaintextCollection({ was, spaceId, collectionId, capability })
|
|
103
117
|
.resource(resourceId)
|
|
104
118
|
.put(body, { contentType: 'application/json' });
|
|
105
119
|
}
|
|
@@ -133,126 +147,90 @@ export async function ensureUnlockSpace({ storageServerUrl, zcapClient, spaceId,
|
|
|
133
147
|
* does not exist yet. A network / unreachable error propagates, so callers can
|
|
134
148
|
* distinguish "no keyring" from "could not check".
|
|
135
149
|
*
|
|
150
|
+
* With a `capability`, the `zcapClient` is an enrolled client's rather than
|
|
151
|
+
* the unlock identity's, and the attached management zcap (delegated by the
|
|
152
|
+
* unlock identity at bind time; it must allow GET) authorizes the read. This
|
|
153
|
+
* is what lets the revocation cascade's re-mint read a recovery code's
|
|
154
|
+
* standing record without holding the code: the record's code-authenticated
|
|
155
|
+
* binding rides the frame in the clear, so carrying it forward verbatim needs
|
|
156
|
+
* no decryption.
|
|
157
|
+
*
|
|
136
158
|
* @param options {object}
|
|
137
159
|
* @param options.storageServerUrl {string}
|
|
138
160
|
* @param options.zcapClient {ZcapClient}
|
|
139
161
|
* @param options.spaceId {string} the unlock Space id
|
|
162
|
+
* @param [options.capability] {IZcap} the delegated management zcap;
|
|
163
|
+
* absent, the read is a root invocation
|
|
140
164
|
* @returns {Promise<unknown | null>}
|
|
141
165
|
*/
|
|
142
|
-
export async function getUnlockKeyring({ storageServerUrl, zcapClient, spaceId }) {
|
|
166
|
+
export async function getUnlockKeyring({ storageServerUrl, zcapClient, spaceId, capability }) {
|
|
143
167
|
return getPlaintextRecord({
|
|
144
168
|
storageServerUrl,
|
|
145
169
|
zcapClient,
|
|
146
170
|
spaceId,
|
|
147
171
|
collectionId: KEYRING_COLLECTION.id,
|
|
148
|
-
resourceId: KEYRING_RESOURCE
|
|
172
|
+
resourceId: KEYRING_RESOURCE,
|
|
173
|
+
capability
|
|
149
174
|
});
|
|
150
175
|
}
|
|
151
176
|
/**
|
|
152
177
|
* Writes (upserts) the keyring record into the unlock Space as a JSON document.
|
|
153
178
|
*
|
|
179
|
+
* With a `capability`, the `zcapClient` is an enrolled client's rather than
|
|
180
|
+
* the unlock identity's, and the attached management zcap (delegated by the
|
|
181
|
+
* unlock identity at bind time; it must allow PUT) authorizes the write. This
|
|
182
|
+
* is what lets the revocation cascade re-PUT a recovery code's unlock record
|
|
183
|
+
* (a fresh `did.jsonl` delegation inside a re-wrapped record) without holding
|
|
184
|
+
* the code: the record's JWE recipient is the code's unlock KAK, whose PUBLIC
|
|
185
|
+
* half the issuing client recorded, so re-encryption needs no secret.
|
|
186
|
+
*
|
|
154
187
|
* @param options {object}
|
|
155
188
|
* @param options.storageServerUrl {string}
|
|
156
189
|
* @param options.zcapClient {ZcapClient}
|
|
157
190
|
* @param options.spaceId {string} the unlock Space id
|
|
158
191
|
* @param options.record {object} the keyring record
|
|
192
|
+
* @param [options.capability] {IZcap} the delegated management zcap;
|
|
193
|
+
* absent, the write is a root invocation
|
|
159
194
|
* @returns {Promise<void>}
|
|
160
195
|
*/
|
|
161
|
-
export async function putUnlockKeyring({ storageServerUrl, zcapClient, spaceId, record }) {
|
|
196
|
+
export async function putUnlockKeyring({ storageServerUrl, zcapClient, spaceId, record, capability }) {
|
|
162
197
|
await putPlaintextRecord({
|
|
163
198
|
storageServerUrl,
|
|
164
199
|
zcapClient,
|
|
165
200
|
spaceId,
|
|
166
201
|
collectionId: KEYRING_COLLECTION.id,
|
|
167
202
|
resourceId: KEYRING_RESOURCE,
|
|
168
|
-
record
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Reads the keyring record with an explicitly attached management capability,
|
|
173
|
-
* rather than by root invocation, or returns `null` when it does not exist.
|
|
174
|
-
* The `zcapClient` here is an enrolled client's (not the unlock identity's);
|
|
175
|
-
* the attached `capability` -- the management zcap the unlock identity
|
|
176
|
-
* delegated at bind time, provided it allows GET -- authorizes the read
|
|
177
|
-
* against the unlock Space. This is what lets the revocation cascade's
|
|
178
|
-
* re-mint read a recovery code's standing record without holding the code:
|
|
179
|
-
* the record's code-authenticated binding rides the frame in the clear, so
|
|
180
|
-
* carrying it forward verbatim needs no decryption.
|
|
181
|
-
*
|
|
182
|
-
* @param options {object}
|
|
183
|
-
* @param options.storageServerUrl {string}
|
|
184
|
-
* @param options.zcapClient {ZcapClient} an enrolled client's zcap client
|
|
185
|
-
* @param options.spaceId {string} the unlock Space id
|
|
186
|
-
* @param options.capability {IZcap} the delegated management zcap (must
|
|
187
|
-
* allow GET)
|
|
188
|
-
* @returns {Promise<unknown | null>}
|
|
189
|
-
*/
|
|
190
|
-
export async function getUnlockKeyringWithCapability({ storageServerUrl, zcapClient, spaceId, capability }) {
|
|
191
|
-
const was = unlockSpaceClient({ storageServerUrl, zcapClient });
|
|
192
|
-
const result = await plaintextCollection({
|
|
193
|
-
was,
|
|
194
|
-
spaceId,
|
|
195
|
-
collectionId: KEYRING_COLLECTION.id,
|
|
203
|
+
record,
|
|
196
204
|
capability
|
|
197
|
-
})
|
|
198
|
-
.resource(KEYRING_RESOURCE)
|
|
199
|
-
.get();
|
|
200
|
-
return result === null ? null : result;
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Writes (upserts) the keyring record with an explicitly attached management
|
|
204
|
-
* capability, rather than by root invocation. The `zcapClient` here is an
|
|
205
|
-
* enrolled client's (not the unlock identity's); the attached `capability` --
|
|
206
|
-
* the management zcap the unlock identity delegated at bind time, provided it
|
|
207
|
-
* allows PUT -- authorizes the write against the unlock Space. This is what
|
|
208
|
-
* lets the revocation cascade re-PUT a recovery code's unlock record (a fresh
|
|
209
|
-
* `did.jsonl` delegation inside a re-wrapped record) without holding the
|
|
210
|
-
* code: the record's JWE recipient is the code's unlock KAK, whose PUBLIC
|
|
211
|
-
* half the issuing client recorded, so re-encryption needs no secret.
|
|
212
|
-
*
|
|
213
|
-
* @param options {object}
|
|
214
|
-
* @param options.storageServerUrl {string}
|
|
215
|
-
* @param options.zcapClient {ZcapClient} an enrolled client's zcap client
|
|
216
|
-
* @param options.spaceId {string} the unlock Space id
|
|
217
|
-
* @param options.record {object} the keyring record
|
|
218
|
-
* @param options.capability {IZcap} the delegated management zcap (must
|
|
219
|
-
* allow PUT)
|
|
220
|
-
* @returns {Promise<void>}
|
|
221
|
-
*/
|
|
222
|
-
export async function putUnlockKeyringWithCapability({ storageServerUrl, zcapClient, spaceId, record, capability }) {
|
|
223
|
-
const was = unlockSpaceClient({ storageServerUrl, zcapClient });
|
|
224
|
-
const body = new TextEncoder().encode(JSON.stringify(record));
|
|
225
|
-
await was.request({
|
|
226
|
-
capability,
|
|
227
|
-
path: resourcePath(spaceId, KEYRING_COLLECTION.id, KEYRING_RESOURCE),
|
|
228
|
-
method: 'PUT',
|
|
229
|
-
headers: { 'content-type': 'application/json' },
|
|
230
|
-
body
|
|
231
205
|
});
|
|
232
206
|
}
|
|
233
207
|
/**
|
|
234
208
|
* Deletes the whole unlock Space (what retires an old passphrase on a
|
|
235
|
-
* passphrase change).
|
|
236
|
-
* Space
|
|
209
|
+
* passphrase change, or a lost unlock method). The server's answer is
|
|
210
|
+
* reported rather than decided here: an already-absent Space comes back as
|
|
211
|
+
* `not-found`, and only a non-404 error propagates, so a caller that treats
|
|
212
|
+
* the delete as idempotent ignores the outcome.
|
|
213
|
+
*
|
|
214
|
+
* With a `capability`, the `zcapClient` is an enrolled client's rather than
|
|
215
|
+
* the unlock identity's, and the attached management zcap (delegated by the
|
|
216
|
+
* unlock identity to the data identity at bind time; it must allow DELETE on
|
|
217
|
+
* the Space's own URL) authorizes the delete -- retiring a lost unlock method
|
|
218
|
+
* without re-deriving its identity from the (possibly lost) secret. The
|
|
219
|
+
* server answers 404 both for an absent Space and for a refused capability,
|
|
220
|
+
* so `not-found` is not a statement of absence on its own.
|
|
237
221
|
*
|
|
238
222
|
* @param options {object}
|
|
239
223
|
* @param options.storageServerUrl {string}
|
|
240
224
|
* @param options.zcapClient {ZcapClient}
|
|
241
225
|
* @param options.spaceId {string} the unlock Space id
|
|
242
|
-
* @
|
|
226
|
+
* @param [options.capability] {IZcap} the delegated management zcap;
|
|
227
|
+
* absent, the delete is a root invocation
|
|
228
|
+
* @returns {Promise<{ outcome: 'deleted' | 'not-found' }>} `not-found`
|
|
229
|
+
* when the server answered 404 (absent, or unauthorized under a
|
|
230
|
+
* capability); every other error propagates unchanged
|
|
243
231
|
*/
|
|
244
|
-
export async function deleteUnlockSpace({ storageServerUrl, zcapClient, spaceId }) {
|
|
232
|
+
export async function deleteUnlockSpace({ storageServerUrl, zcapClient, spaceId, capability }) {
|
|
245
233
|
const was = unlockSpaceClient({ storageServerUrl, zcapClient });
|
|
246
|
-
|
|
234
|
+
return was.space(spaceId, { capability }).deleteWithOutcome();
|
|
247
235
|
}
|
|
248
|
-
/**
|
|
249
|
-
* The unlock Space's name for the one capability-authorized Space DELETE
|
|
250
|
-
* ({@link deleteSpaceWithCapability}). The alias stands because an unlock
|
|
251
|
-
* Space's deletion is the one this module's callers reach for -- retiring a
|
|
252
|
-
* lost unlock method with the management zcap the unlock identity delegated
|
|
253
|
-
* to the data identity at bind time, rather than by re-deriving the unlock
|
|
254
|
-
* identity from the (possibly lost) secret -- while the request itself is
|
|
255
|
-
* the shared one, 404 outcome and all.
|
|
256
|
-
*/
|
|
257
|
-
export { deleteSpaceWithCapability as deleteUnlockSpaceWithCapability } from '../space/deleteSpace.js';
|
|
258
236
|
//# sourceMappingURL=unlockSpace.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unlockSpace.js","sourceRoot":"","sources":["../../src/keyring/unlockSpace.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"unlockSpace.js","sourceRoot":"","sources":["../../src/keyring/unlockSpace.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAG/C,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAA;AAErE;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,oBAAoB,CAAA;AAErD;;;;;;;;GAQG;AACH,SAAS,iBAAiB,CAAC,EACzB,gBAAgB,EAChB,UAAU,EAIX;IACC,OAAO,IAAI,SAAS,CAAC;QACnB,SAAS,EAAE,gBAAgB;QAC3B,UAAU;KACX,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,KAAK,UAAU,yBAAyB,CAAC,EACvC,gBAAgB,EAChB,UAAU,EACV,OAAO,EACP,YAAY,EACZ,IAAI,EAOL;IACC,MAAM,GAAG,GAAG,iBAAiB,CAAC,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC,CAAA;IAC/D,MAAM,GAAG;SACN,KAAK,CAAC,OAAO,CAAC;SACd,UAAU,CAAC,YAAY,CAAC;SACxB,SAAS,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;AACrC,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,KAAK,UAAU,kBAAkB,CAAC,EAChC,gBAAgB,EAChB,UAAU,EACV,OAAO,EACP,YAAY,EACZ,UAAU,EACV,UAAU,EAQX;IACC,MAAM,GAAG,GAAG,iBAAiB,CAAC,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC,CAAA;IAC/D,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC;QACvC,GAAG;QACH,OAAO;QACP,YAAY;QACZ,UAAU;KACX,CAAC;SACC,QAAQ,CAAC,UAAU,CAAC;SACpB,GAAG,EAAE,CAAA;IACR,OAAO,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAA;AACxC,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,KAAK,UAAU,kBAAkB,CAAC,EAChC,gBAAgB,EAChB,UAAU,EACV,OAAO,EACP,YAAY,EACZ,UAAU,EACV,MAAM,EACN,UAAU,EASX;IACC,MAAM,GAAG,GAAG,iBAAiB,CAAC,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC,CAAA;IAC/D,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAA;IAC7D,MAAM,mBAAmB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC;SAClE,QAAQ,CAAC,UAAU,CAAC;SACpB,GAAG,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC,CAAA;AACnD,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,EACtC,gBAAgB,EAChB,UAAU,EACV,OAAO,EACP,UAAU,EACV,IAAI,GAAG,iBAAiB,EAOzB;IACC,MAAM,GAAG,GAAG,iBAAiB,CAAC,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC,CAAA;IAC/D,MAAM,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAA;IACxD,MAAM,yBAAyB,CAAC;QAC9B,gBAAgB;QAChB,UAAU;QACV,OAAO;QACP,YAAY,EAAE,kBAAkB,CAAC,EAAE;QACnC,IAAI,EAAE,kBAAkB,CAAC,IAAI;KAC9B,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,EACrC,gBAAgB,EAChB,UAAU,EACV,OAAO,EACP,UAAU,EAMX;IACC,OAAO,kBAAkB,CAAC;QACxB,gBAAgB;QAChB,UAAU;QACV,OAAO;QACP,YAAY,EAAE,kBAAkB,CAAC,EAAE;QACnC,UAAU,EAAE,gBAAgB;QAC5B,UAAU;KACX,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,EACrC,gBAAgB,EAChB,UAAU,EACV,OAAO,EACP,MAAM,EACN,UAAU,EAOX;IACC,MAAM,kBAAkB,CAAC;QACvB,gBAAgB;QAChB,UAAU;QACV,OAAO;QACP,YAAY,EAAE,kBAAkB,CAAC,EAAE;QACnC,UAAU,EAAE,gBAAgB;QAC5B,MAAM;QACN,UAAU;KACX,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,EACtC,gBAAgB,EAChB,UAAU,EACV,OAAO,EACP,UAAU,EAMX;IACC,MAAM,GAAG,GAAG,iBAAiB,CAAC,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC,CAAA;IAC/D,OAAO,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC,iBAAiB,EAAE,CAAA;AAC/D,CAAC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* The derived sets a wallet's audit tests assert: the invariants a transient
|
|
6
|
+
* visit reaches, the gaps the registration index implies, and census
|
|
7
|
+
* completeness. Each is computed from the table and the sites alone, so a
|
|
8
|
+
* converger that quietly loses a trigger a transient visit fires, or an
|
|
9
|
+
* invariant no registration reports any more, moves a derived set and fails
|
|
10
|
+
* the wallet's pin.
|
|
11
|
+
*/
|
|
12
|
+
import { type InvariantId } from './ids.js';
|
|
13
|
+
import type { MenderRegistry } from './registry.js';
|
|
14
|
+
import type { InvariantGap, RegistrationSite } from './types.js';
|
|
15
|
+
/**
|
|
16
|
+
* One derived gap: the declared row's key and kind, without its prose.
|
|
17
|
+
*/
|
|
18
|
+
type DerivedGap = Pick<InvariantGap, 'invariant' | 'kind'>;
|
|
19
|
+
/**
|
|
20
|
+
* The invariants a transient visit on a standing credential reaches. The
|
|
21
|
+
* two chain triggers are read through `dueAt` over the ladder held set; a
|
|
22
|
+
* `login-routing` site counts unless the client-key-record probe guards it;
|
|
23
|
+
* a `ceremony-tail` entry counts, every such ceremony running on any
|
|
24
|
+
* session type; and a detector no site reports (a declaration carrying
|
|
25
|
+
* `holdsWhen`) counts when it is checked at a trigger a transient visit
|
|
26
|
+
* fires and, on the chain, under an authority the ladder held set carries.
|
|
27
|
+
* An unreported declaration with no detector is reached by nothing.
|
|
28
|
+
*
|
|
29
|
+
* @param options {object}
|
|
30
|
+
* @param options.registry {MenderRegistry}
|
|
31
|
+
* @returns {ReadonlyArray<InvariantId>} in table order
|
|
32
|
+
*/
|
|
33
|
+
export declare function transientReachableInvariants({ registry }: {
|
|
34
|
+
registry: MenderRegistry<RegistrationSite, never>;
|
|
35
|
+
}): ReadonlyArray<InvariantId>;
|
|
36
|
+
/**
|
|
37
|
+
* The gaps the index implies. An invariant no site reports derives `none`,
|
|
38
|
+
* unless it is checked at ceremony tails alone (converged by the ceremony's
|
|
39
|
+
* own sequenced code, which is never registered). A detector is not a
|
|
40
|
+
* mender: a declaration carrying `holdsWhen` and no registration derives
|
|
41
|
+
* `none` like any other unreported one, so adding a detector never retires
|
|
42
|
+
* a gap. A declaration naming a chain or routing trigger no site backs
|
|
43
|
+
* derives `none` whatever else it names. An invariant reported only at sites
|
|
44
|
+
* a transient visit cannot reach, on an account shape the violation can
|
|
45
|
+
* stand on, derives `unreachable`. Nothing else derives a gap.
|
|
46
|
+
*
|
|
47
|
+
* @param options {object}
|
|
48
|
+
* @param options.registry {MenderRegistry}
|
|
49
|
+
* @returns {ReadonlyArray<DerivedGap>}
|
|
50
|
+
*/
|
|
51
|
+
export declare function deriveGaps({ registry }: {
|
|
52
|
+
registry: MenderRegistry<RegistrationSite, never>;
|
|
53
|
+
}): ReadonlyArray<DerivedGap>;
|
|
54
|
+
/**
|
|
55
|
+
* Compares the derived gaps with a wallet's declared allowlist. The
|
|
56
|
+
* derivation admits gaps and retires none: a declared row the derivation no
|
|
57
|
+
* longer produces passes, and a derived gap with no declaration fails. A
|
|
58
|
+
* derived `none` needs a declared `none` row for its invariant; a derived
|
|
59
|
+
* `unreachable` needs any declared row for it, since a declared `none` may
|
|
60
|
+
* be scoped to a different torn state of the same predicate.
|
|
61
|
+
*
|
|
62
|
+
* @param options {object}
|
|
63
|
+
* @param options.derived {ReadonlyArray<DerivedGap>}
|
|
64
|
+
* @param options.declared {ReadonlyArray<InvariantGap>}
|
|
65
|
+
* @returns {ReadonlyArray<DerivedGap>} the
|
|
66
|
+
* derived gaps no declaration covers; empty when the allowlist is complete
|
|
67
|
+
*/
|
|
68
|
+
export declare function undeclaredGaps({ derived, declared }: {
|
|
69
|
+
derived: ReadonlyArray<DerivedGap>;
|
|
70
|
+
declared: ReadonlyArray<InvariantGap>;
|
|
71
|
+
}): ReadonlyArray<DerivedGap>;
|
|
72
|
+
/**
|
|
73
|
+
* Census completeness: the ids in {@link INVARIANT_IDS} the table does not
|
|
74
|
+
* declare. Duplicated ids and undeclared reports are refused by
|
|
75
|
+
* `menderRegistry` at construction, so a registry in hand has neither.
|
|
76
|
+
*
|
|
77
|
+
* @param options {object}
|
|
78
|
+
* @param options.registry {MenderRegistry}
|
|
79
|
+
* @returns {ReadonlyArray<InvariantId>} empty when the census is complete
|
|
80
|
+
*/
|
|
81
|
+
export declare function undeclaredInvariants({ registry }: {
|
|
82
|
+
registry: MenderRegistry<RegistrationSite, never>;
|
|
83
|
+
}): ReadonlyArray<InvariantId>;
|
|
84
|
+
export {};
|
|
85
|
+
//# sourceMappingURL=derive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"derive.d.ts","sourceRoot":"","sources":["../../src/menders/derive.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;GAOG;AACH,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,UAAU,CAAA;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAEnD,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAEhE;;GAEG;AACH,KAAK,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,WAAW,GAAG,MAAM,CAAC,CAAA;AAW1D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,4BAA4B,CAAC,EAC3C,QAAQ,EACT,EAAE;IACD,QAAQ,EAAE,cAAc,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAA;CAClD,GAAG,aAAa,CAAC,WAAW,CAAC,CAuC7B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACT,EAAE;IACD,QAAQ,EAAE,cAAc,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAA;CAClD,GAAG,aAAa,CAAC,UAAU,CAAC,CAoB5B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,QAAQ,EACT,EAAE;IACD,OAAO,EAAE,aAAa,CAAC,UAAU,CAAC,CAAA;IAClC,QAAQ,EAAE,aAAa,CAAC,YAAY,CAAC,CAAA;CACtC,GAAG,aAAa,CAAC,UAAU,CAAC,CAS5B;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,QAAQ,EACT,EAAE;IACD,QAAQ,EAAE,cAAc,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAA;CAClD,GAAG,aAAa,CAAC,WAAW,CAAC,CAG7B"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* The derived sets a wallet's audit tests assert: the invariants a transient
|
|
6
|
+
* visit reaches, the gaps the registration index implies, and census
|
|
7
|
+
* completeness. Each is computed from the table and the sites alone, so a
|
|
8
|
+
* converger that quietly loses a trigger a transient visit fires, or an
|
|
9
|
+
* invariant no registration reports any more, moves a derived set and fails
|
|
10
|
+
* the wallet's pin.
|
|
11
|
+
*/
|
|
12
|
+
import { INVARIANT_IDS } from './ids.js';
|
|
13
|
+
import { heldAuthorities } from './registry.js';
|
|
14
|
+
/**
|
|
15
|
+
* The ids some site reports, whatever its trigger.
|
|
16
|
+
*/
|
|
17
|
+
function reportedIds(registry) {
|
|
18
|
+
return new Set(registry.sites().flatMap(site => site.reports));
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The invariants a transient visit on a standing credential reaches. The
|
|
22
|
+
* two chain triggers are read through `dueAt` over the ladder held set; a
|
|
23
|
+
* `login-routing` site counts unless the client-key-record probe guards it;
|
|
24
|
+
* a `ceremony-tail` entry counts, every such ceremony running on any
|
|
25
|
+
* session type; and a detector no site reports (a declaration carrying
|
|
26
|
+
* `holdsWhen`) counts when it is checked at a trigger a transient visit
|
|
27
|
+
* fires and, on the chain, under an authority the ladder held set carries.
|
|
28
|
+
* An unreported declaration with no detector is reached by nothing.
|
|
29
|
+
*
|
|
30
|
+
* @param options {object}
|
|
31
|
+
* @param options.registry {MenderRegistry}
|
|
32
|
+
* @returns {ReadonlyArray<InvariantId>} in table order
|
|
33
|
+
*/
|
|
34
|
+
export function transientReachableInvariants({ registry }) {
|
|
35
|
+
const reached = new Set();
|
|
36
|
+
const held = heldAuthorities({ kind: 'ladder' });
|
|
37
|
+
for (const site of registry.dueAt({
|
|
38
|
+
held,
|
|
39
|
+
trigger: 'transient-login-chain'
|
|
40
|
+
})) {
|
|
41
|
+
for (const id of site.reports) {
|
|
42
|
+
reached.add(id);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
for (const site of registry.sites()) {
|
|
46
|
+
if (site.trigger === 'login-routing' && !site.guardedBy) {
|
|
47
|
+
for (const id of site.reports) {
|
|
48
|
+
reached.add(id);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const reported = reportedIds(registry);
|
|
53
|
+
for (const decl of registry.all()) {
|
|
54
|
+
if (decl.triggers.includes('ceremony-tail')) {
|
|
55
|
+
reached.add(decl.id);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (reported.has(decl.id) || !decl.holdsWhen) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const checkedOnVisit = decl.triggers.includes('login-routing') ||
|
|
62
|
+
(decl.triggers.includes('transient-login-chain') &&
|
|
63
|
+
held.includes(decl.authority));
|
|
64
|
+
if (checkedOnVisit) {
|
|
65
|
+
reached.add(decl.id);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return registry
|
|
69
|
+
.all()
|
|
70
|
+
.filter(decl => reached.has(decl.id))
|
|
71
|
+
.map(decl => decl.id);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The gaps the index implies. An invariant no site reports derives `none`,
|
|
75
|
+
* unless it is checked at ceremony tails alone (converged by the ceremony's
|
|
76
|
+
* own sequenced code, which is never registered). A detector is not a
|
|
77
|
+
* mender: a declaration carrying `holdsWhen` and no registration derives
|
|
78
|
+
* `none` like any other unreported one, so adding a detector never retires
|
|
79
|
+
* a gap. A declaration naming a chain or routing trigger no site backs
|
|
80
|
+
* derives `none` whatever else it names. An invariant reported only at sites
|
|
81
|
+
* a transient visit cannot reach, on an account shape the violation can
|
|
82
|
+
* stand on, derives `unreachable`. Nothing else derives a gap.
|
|
83
|
+
*
|
|
84
|
+
* @param options {object}
|
|
85
|
+
* @param options.registry {MenderRegistry}
|
|
86
|
+
* @returns {ReadonlyArray<DerivedGap>}
|
|
87
|
+
*/
|
|
88
|
+
export function deriveGaps({ registry }) {
|
|
89
|
+
const reported = reportedIds(registry);
|
|
90
|
+
const reachable = new Set(transientReachableInvariants({ registry }));
|
|
91
|
+
const gaps = [];
|
|
92
|
+
for (const decl of registry.all()) {
|
|
93
|
+
if (!reported.has(decl.id)) {
|
|
94
|
+
const tailOnly = decl.triggers.length > 0 &&
|
|
95
|
+
decl.triggers.every(trigger => trigger === 'ceremony-tail');
|
|
96
|
+
if (!tailOnly) {
|
|
97
|
+
gaps.push({ invariant: decl.id, kind: 'none' });
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
else if (!reachable.has(decl.id) &&
|
|
101
|
+
decl.standsOn.includes('client-less')) {
|
|
102
|
+
gaps.push({ invariant: decl.id, kind: 'unreachable' });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return gaps;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Compares the derived gaps with a wallet's declared allowlist. The
|
|
109
|
+
* derivation admits gaps and retires none: a declared row the derivation no
|
|
110
|
+
* longer produces passes, and a derived gap with no declaration fails. A
|
|
111
|
+
* derived `none` needs a declared `none` row for its invariant; a derived
|
|
112
|
+
* `unreachable` needs any declared row for it, since a declared `none` may
|
|
113
|
+
* be scoped to a different torn state of the same predicate.
|
|
114
|
+
*
|
|
115
|
+
* @param options {object}
|
|
116
|
+
* @param options.derived {ReadonlyArray<DerivedGap>}
|
|
117
|
+
* @param options.declared {ReadonlyArray<InvariantGap>}
|
|
118
|
+
* @returns {ReadonlyArray<DerivedGap>} the
|
|
119
|
+
* derived gaps no declaration covers; empty when the allowlist is complete
|
|
120
|
+
*/
|
|
121
|
+
export function undeclaredGaps({ derived, declared }) {
|
|
122
|
+
return derived.filter(({ invariant, kind }) => !declared.some(gap => gap.invariant === invariant &&
|
|
123
|
+
(kind === 'unreachable' || gap.kind === 'none')));
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Census completeness: the ids in {@link INVARIANT_IDS} the table does not
|
|
127
|
+
* declare. Duplicated ids and undeclared reports are refused by
|
|
128
|
+
* `menderRegistry` at construction, so a registry in hand has neither.
|
|
129
|
+
*
|
|
130
|
+
* @param options {object}
|
|
131
|
+
* @param options.registry {MenderRegistry}
|
|
132
|
+
* @returns {ReadonlyArray<InvariantId>} empty when the census is complete
|
|
133
|
+
*/
|
|
134
|
+
export function undeclaredInvariants({ registry }) {
|
|
135
|
+
const declared = new Set(registry.all().map(decl => decl.id));
|
|
136
|
+
return INVARIANT_IDS.filter(id => !declared.has(id));
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=derive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"derive.js","sourceRoot":"","sources":["../../src/menders/derive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* The invariant ids: the closed census both wallets declare against and the
|
|
6
|
+
* mender event channel keys on. Each names the predicate an entry makes
|
|
7
|
+
* true rather than the code that converges it, so moving a converger between
|
|
8
|
+
* modules renames nothing. The ids are code-only; nothing persists them.
|
|
9
|
+
* Numbered in the order the design table assigned them, and a new one takes
|
|
10
|
+
* the next free number rather than renumbering.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Every invariant id, in design-table order.
|
|
14
|
+
*/
|
|
15
|
+
export declare const INVARIANT_IDS: readonly ["roster-wraps-exactly-the-document-key-set", "governed-log-heads-anchor-past-the-membership-change", "collection-epochs-name-the-current-user-key", "unlock-registry-opens-under-the-current-user-key", "registry-passphrase-entry-names-the-standing-credential", "passkey-entry-carries-its-standing-configuration", "registry-lists-the-passphrase-method", "standing-delegations-verify-under-the-current-document", "registry-records-the-committed-ladder-rung", "unlock-record-points-at-the-account-did", "account-pointer-names-the-account-did", "space-controller-is-the-account-did", "roster-and-collection-epochs-exist", "registry-records-the-establishing-credential", "annex-generation-is-reachable", "generation-delegation-is-current", "acting-credential-manage-zcap-is-current", "did-web-projection-matches-the-log", "no-annex-generation-outlives-its-pointer", "app-keys-live-only-in-app-connections", "client-key-record-matches-the-pointed-account", "this-browser-is-still-an-enrolled-client", "no-client-key-record-stays-pending", "recovery-spend-is-completed", "retired-credential-leaves-no-annex-inventory", "document-lists-the-acting-credential", "keystore-controller-is-the-account-did", "account-document-publishes-an-authentication-key", "every-document-key-agreement-entry-has-a-locatable-credential", "no-unlock-space-outlives-its-credential", "no-keystore-outlives-its-account", "saved-recovery-codes-locate-their-account", "standard-collections-are-provisioned", "no-auxiliary-space-stands-unnamed"];
|
|
16
|
+
/**
|
|
17
|
+
* One id from {@link INVARIANT_IDS}.
|
|
18
|
+
*/
|
|
19
|
+
export type InvariantId = (typeof INVARIANT_IDS)[number];
|
|
20
|
+
//# sourceMappingURL=ids.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../../src/menders/ids.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;GAOG;AAEH;;GAEG;AACH,eAAO,MAAM,aAAa,i/CAqEhB,CAAA;AAEV;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAA"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* The invariant ids: the closed census both wallets declare against and the
|
|
6
|
+
* mender event channel keys on. Each names the predicate an entry makes
|
|
7
|
+
* true rather than the code that converges it, so moving a converger between
|
|
8
|
+
* modules renames nothing. The ids are code-only; nothing persists them.
|
|
9
|
+
* Numbered in the order the design table assigned them, and a new one takes
|
|
10
|
+
* the next free number rather than renumbering.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Every invariant id, in design-table order.
|
|
14
|
+
*/
|
|
15
|
+
export const INVARIANT_IDS = [
|
|
16
|
+
// 1
|
|
17
|
+
'roster-wraps-exactly-the-document-key-set',
|
|
18
|
+
// 2
|
|
19
|
+
'governed-log-heads-anchor-past-the-membership-change',
|
|
20
|
+
// 3
|
|
21
|
+
'collection-epochs-name-the-current-user-key',
|
|
22
|
+
// 4
|
|
23
|
+
'unlock-registry-opens-under-the-current-user-key',
|
|
24
|
+
// 5
|
|
25
|
+
'registry-passphrase-entry-names-the-standing-credential',
|
|
26
|
+
// 6
|
|
27
|
+
'passkey-entry-carries-its-standing-configuration',
|
|
28
|
+
// 7
|
|
29
|
+
'registry-lists-the-passphrase-method',
|
|
30
|
+
// 8
|
|
31
|
+
'standing-delegations-verify-under-the-current-document',
|
|
32
|
+
// 9
|
|
33
|
+
'registry-records-the-committed-ladder-rung',
|
|
34
|
+
// 10
|
|
35
|
+
'unlock-record-points-at-the-account-did',
|
|
36
|
+
// 11
|
|
37
|
+
'account-pointer-names-the-account-did',
|
|
38
|
+
// 12
|
|
39
|
+
'space-controller-is-the-account-did',
|
|
40
|
+
// 13
|
|
41
|
+
'roster-and-collection-epochs-exist',
|
|
42
|
+
// 14
|
|
43
|
+
'registry-records-the-establishing-credential',
|
|
44
|
+
// 15
|
|
45
|
+
'annex-generation-is-reachable',
|
|
46
|
+
// 16
|
|
47
|
+
'generation-delegation-is-current',
|
|
48
|
+
// 17
|
|
49
|
+
'acting-credential-manage-zcap-is-current',
|
|
50
|
+
// 18
|
|
51
|
+
'did-web-projection-matches-the-log',
|
|
52
|
+
// 19
|
|
53
|
+
'no-annex-generation-outlives-its-pointer',
|
|
54
|
+
// 20
|
|
55
|
+
'app-keys-live-only-in-app-connections',
|
|
56
|
+
// 21
|
|
57
|
+
'client-key-record-matches-the-pointed-account',
|
|
58
|
+
// 22
|
|
59
|
+
'this-browser-is-still-an-enrolled-client',
|
|
60
|
+
// 23
|
|
61
|
+
'no-client-key-record-stays-pending',
|
|
62
|
+
// 24
|
|
63
|
+
'recovery-spend-is-completed',
|
|
64
|
+
// 25
|
|
65
|
+
'retired-credential-leaves-no-annex-inventory',
|
|
66
|
+
// 26
|
|
67
|
+
'document-lists-the-acting-credential',
|
|
68
|
+
// 27
|
|
69
|
+
'keystore-controller-is-the-account-did',
|
|
70
|
+
// 28
|
|
71
|
+
'account-document-publishes-an-authentication-key',
|
|
72
|
+
// 29
|
|
73
|
+
'every-document-key-agreement-entry-has-a-locatable-credential',
|
|
74
|
+
// 30
|
|
75
|
+
'no-unlock-space-outlives-its-credential',
|
|
76
|
+
// 31
|
|
77
|
+
'no-keystore-outlives-its-account',
|
|
78
|
+
// 32
|
|
79
|
+
'saved-recovery-codes-locate-their-account',
|
|
80
|
+
// 33
|
|
81
|
+
'standard-collections-are-provisioned',
|
|
82
|
+
// 34
|
|
83
|
+
'no-auxiliary-space-stands-unnamed'
|
|
84
|
+
];
|
|
85
|
+
//# sourceMappingURL=ids.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ids.js","sourceRoot":"","sources":["../../src/menders/ids.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;GAOG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,IAAI;IACJ,2CAA2C;IAC3C,IAAI;IACJ,sDAAsD;IACtD,IAAI;IACJ,6CAA6C;IAC7C,IAAI;IACJ,kDAAkD;IAClD,IAAI;IACJ,yDAAyD;IACzD,IAAI;IACJ,kDAAkD;IAClD,IAAI;IACJ,sCAAsC;IACtC,IAAI;IACJ,wDAAwD;IACxD,IAAI;IACJ,4CAA4C;IAC5C,KAAK;IACL,yCAAyC;IACzC,KAAK;IACL,uCAAuC;IACvC,KAAK;IACL,qCAAqC;IACrC,KAAK;IACL,oCAAoC;IACpC,KAAK;IACL,8CAA8C;IAC9C,KAAK;IACL,+BAA+B;IAC/B,KAAK;IACL,kCAAkC;IAClC,KAAK;IACL,0CAA0C;IAC1C,KAAK;IACL,oCAAoC;IACpC,KAAK;IACL,0CAA0C;IAC1C,KAAK;IACL,uCAAuC;IACvC,KAAK;IACL,+CAA+C;IAC/C,KAAK;IACL,0CAA0C;IAC1C,KAAK;IACL,oCAAoC;IACpC,KAAK;IACL,6BAA6B;IAC7B,KAAK;IACL,8CAA8C;IAC9C,KAAK;IACL,sCAAsC;IACtC,KAAK;IACL,wCAAwC;IACxC,KAAK;IACL,kDAAkD;IAClD,KAAK;IACL,+DAA+D;IAC/D,KAAK;IACL,yCAAyC;IACzC,KAAK;IACL,kCAAkC;IAClC,KAAK;IACL,2CAA2C;IAC3C,KAAK;IACL,sCAAsC;IACtC,KAAK;IACL,mCAAmC;CAC3B,CAAA"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* The `@interop/wallet-core/menders` subpath: the mender registry keyed by
|
|
6
|
+
* invariant. A wallet declares its own table of invariants (data: what must
|
|
7
|
+
* hold between ceremonies) and its own registrations (code: what converges a
|
|
8
|
+
* violated one); this module carries the structure both wallets share.
|
|
9
|
+
*
|
|
10
|
+
* - the vocabularies: `AUTHORITIES`, `TRIGGERS`, `CHAIN_TRIGGERS`,
|
|
11
|
+
* `ACCOUNT_SHAPES`, `EVIDENCE`, `MEND_OUTCOMES`, `GAP_KINDS`, and
|
|
12
|
+
* `INVARIANT_IDS`, each an `as const` array with its union
|
|
13
|
+
* - the types: `InvariantDeclaration`, `RegistrationSite`, `Registration`,
|
|
14
|
+
* `MendOutcome`, `MendReportEntry`, `MendReport`, `InvariantGap`,
|
|
15
|
+
* `LoginRoute`
|
|
16
|
+
* - the readers: `menderRegistry` (`all`, `byId`, `sites`, `admits`,
|
|
17
|
+
* `dueAt`), which refuses a duplicated id, an undeclared report, or a
|
|
18
|
+
* guard on a non-routing site at construction, and `heldAuthorities`, the
|
|
19
|
+
* held set a session's account-ceremony context derives
|
|
20
|
+
* - the runner: `runMenderBlock`, one try, warn, and skip discipline over
|
|
21
|
+
* one chain trigger's registrations, `mendReportAccumulator`, the
|
|
22
|
+
* pre-session report collector its `onOutcome` feeds, and `errorNameOf`,
|
|
23
|
+
* the name a report carries for a thrown value of any shape
|
|
24
|
+
* - the derived sets a wallet's audit tests pin:
|
|
25
|
+
* `transientReachableInvariants`, `deriveGaps`, `undeclaredGaps`, and
|
|
26
|
+
* `undeclaredInvariants`
|
|
27
|
+
*
|
|
28
|
+
* Nothing here executes a ceremony. The runner calls the convergers a
|
|
29
|
+
* wallet registers and nothing else; the ceremonies stay explicit sequenced
|
|
30
|
+
* code, and the registry describes the menders from the outside.
|
|
31
|
+
*/
|
|
32
|
+
export { deriveGaps, transientReachableInvariants, undeclaredGaps, undeclaredInvariants } from './derive.js';
|
|
33
|
+
export { INVARIANT_IDS } from './ids.js';
|
|
34
|
+
export type { InvariantId } from './ids.js';
|
|
35
|
+
export { heldAuthorities, menderRegistry } from './registry.js';
|
|
36
|
+
export type { MenderRegistry, ResolvedAuthority } from './registry.js';
|
|
37
|
+
export { errorNameOf, MEND_REPORT_SHAPE_ERROR, mendReportAccumulator, runMenderBlock } from './runner.js';
|
|
38
|
+
export type { MendReportAccumulator } from './runner.js';
|
|
39
|
+
export type { InvariantDeclaration, InvariantGap, LoginRoute, MendOutcome, MendReport, MendReportEntry, Registration, RegistrationSite } from './types.js';
|
|
40
|
+
export { ACCOUNT_SHAPES, AUTHORITIES, CHAIN_TRIGGERS, EVIDENCE, GAP_KINDS, MEND_OUTCOMES, TRIGGERS } from './vocabulary.js';
|
|
41
|
+
export type { AccountShape, Authority, ChainTrigger, Evidence, GapKind, MendOutcomeKind, Trigger } from './vocabulary.js';
|
|
42
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/menders/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,EACL,UAAU,EACV,4BAA4B,EAC5B,cAAc,EACd,oBAAoB,EACrB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC/D,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AACtE,OAAO,EACL,WAAW,EACX,uBAAuB,EACvB,qBAAqB,EACrB,cAAc,EACf,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACxD,YAAY,EACV,oBAAoB,EACpB,YAAY,EACZ,UAAU,EACV,WAAW,EACX,UAAU,EACV,eAAe,EACf,YAAY,EACZ,gBAAgB,EACjB,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,cAAc,EACd,WAAW,EACX,cAAc,EACd,QAAQ,EACR,SAAS,EACT,aAAa,EACb,QAAQ,EACT,MAAM,iBAAiB,CAAA;AACxB,YAAY,EACV,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,OAAO,EACP,eAAe,EACf,OAAO,EACR,MAAM,iBAAiB,CAAA"}
|