@interop/wallet-core 0.23.1 → 0.25.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 +41 -22
- package/dist/clients/index.d.ts +6 -4
- package/dist/clients/index.d.ts.map +1 -1
- package/dist/clients/index.js +5 -3
- package/dist/clients/index.js.map +1 -1
- package/dist/clients/policy.d.ts +11 -3
- package/dist/clients/policy.d.ts.map +1 -1
- package/dist/clients/policy.js +12 -4
- package/dist/clients/policy.js.map +1 -1
- package/dist/clients/revocation.d.ts +24 -9
- package/dist/clients/revocation.d.ts.map +1 -1
- package/dist/clients/revocation.js +23 -10
- package/dist/clients/revocation.js.map +1 -1
- package/dist/clients/rosterPolicy.d.ts +23 -22
- package/dist/clients/rosterPolicy.d.ts.map +1 -1
- package/dist/clients/rosterPolicy.js +50 -31
- package/dist/clients/rosterPolicy.js.map +1 -1
- package/dist/descriptors/acquire.d.ts +4 -1
- package/dist/descriptors/acquire.d.ts.map +1 -1
- package/dist/descriptors/acquire.js +29 -1
- package/dist/descriptors/acquire.js.map +1 -1
- package/dist/descriptors/index.d.ts +9 -1
- package/dist/descriptors/index.d.ts.map +1 -1
- package/dist/descriptors/index.js +9 -1
- package/dist/descriptors/index.js.map +1 -1
- package/dist/descriptors/logSource.d.ts +33 -0
- package/dist/descriptors/logSource.d.ts.map +1 -0
- package/dist/descriptors/logSource.js +49 -0
- package/dist/descriptors/logSource.js.map +1 -0
- package/dist/enrollment/enrollment.d.ts +2 -2
- package/dist/enrollment/enrollment.d.ts.map +1 -1
- package/dist/enrollment/enrollment.js +15 -10
- package/dist/enrollment/enrollment.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/keys/index.d.ts +15 -8
- package/dist/keys/index.d.ts.map +1 -1
- package/dist/keys/index.js +14 -8
- package/dist/keys/index.js.map +1 -1
- package/dist/keys/rosterLogStore.d.ts +53 -0
- package/dist/keys/rosterLogStore.d.ts.map +1 -0
- package/dist/keys/rosterLogStore.js +134 -0
- package/dist/keys/rosterLogStore.js.map +1 -0
- package/dist/keys/rosterStore.d.ts +20 -6
- package/dist/keys/rosterStore.d.ts.map +1 -1
- package/dist/keys/rosterStore.js +36 -17
- package/dist/keys/rosterStore.js.map +1 -1
- package/dist/keys/userKeyCascade.d.ts +14 -7
- package/dist/keys/userKeyCascade.d.ts.map +1 -1
- package/dist/keys/userKeyCascade.js +12 -3
- package/dist/keys/userKeyCascade.js.map +1 -1
- package/dist/keys/userKeyRoster.d.ts +50 -97
- package/dist/keys/userKeyRoster.d.ts.map +1 -1
- package/dist/keys/userKeyRoster.js +44 -145
- package/dist/keys/userKeyRoster.js.map +1 -1
- package/dist/request/appKey.d.ts +255 -0
- package/dist/request/appKey.d.ts.map +1 -0
- package/dist/request/appKey.js +492 -0
- package/dist/request/appKey.js.map +1 -0
- package/dist/request/classify.d.ts +54 -3
- package/dist/request/classify.d.ts.map +1 -1
- package/dist/request/classify.js +106 -0
- package/dist/request/classify.js.map +1 -1
- package/dist/request/composeVp.d.ts +6 -7
- package/dist/request/composeVp.d.ts.map +1 -1
- package/dist/request/composeVp.js +44 -55
- package/dist/request/composeVp.js.map +1 -1
- package/dist/request/index.d.ts +4 -0
- package/dist/request/index.d.ts.map +1 -1
- package/dist/request/index.js +4 -0
- package/dist/request/index.js.map +1 -1
- package/dist/request/processRequest.d.ts +1 -4
- package/dist/request/processRequest.d.ts.map +1 -1
- package/dist/request/processRequest.js +17 -11
- package/dist/request/processRequest.js.map +1 -1
- package/dist/request/types.d.ts +45 -2
- package/dist/request/types.d.ts.map +1 -1
- package/dist/resourceLog/append.d.ts +103 -0
- package/dist/resourceLog/append.d.ts.map +1 -0
- package/dist/resourceLog/append.js +190 -0
- package/dist/resourceLog/append.js.map +1 -0
- package/dist/resourceLog/controller.d.ts +57 -0
- package/dist/resourceLog/controller.d.ts.map +1 -0
- package/dist/resourceLog/controller.js +81 -0
- package/dist/resourceLog/controller.js.map +1 -0
- package/dist/resourceLog/entry.d.ts +68 -0
- package/dist/resourceLog/entry.d.ts.map +1 -0
- package/dist/resourceLog/entry.js +167 -0
- package/dist/resourceLog/entry.js.map +1 -0
- package/dist/resourceLog/errors.d.ts +75 -0
- package/dist/resourceLog/errors.d.ts.map +1 -0
- package/dist/resourceLog/errors.js +76 -0
- package/dist/resourceLog/errors.js.map +1 -0
- package/dist/resourceLog/index.d.ts +26 -0
- package/dist/resourceLog/index.d.ts.map +1 -0
- package/dist/resourceLog/index.js +26 -0
- package/dist/resourceLog/index.js.map +1 -0
- package/dist/resourceLog/pin.d.ts +44 -0
- package/dist/resourceLog/pin.d.ts.map +1 -0
- package/dist/resourceLog/pin.js +32 -0
- package/dist/resourceLog/pin.js.map +1 -0
- package/dist/resourceLog/seal.d.ts +86 -0
- package/dist/resourceLog/seal.d.ts.map +1 -0
- package/dist/resourceLog/seal.js +99 -0
- package/dist/resourceLog/seal.js.map +1 -0
- package/dist/resourceLog/verify.d.ts +95 -0
- package/dist/resourceLog/verify.d.ts.map +1 -0
- package/dist/resourceLog/verify.js +435 -0
- package/dist/resourceLog/verify.js.map +1 -0
- package/dist/space/collections.d.ts +14 -11
- package/dist/space/collections.d.ts.map +1 -1
- package/dist/space/collections.js +14 -11
- package/dist/space/collections.js.map +1 -1
- package/dist/space/index.d.ts +2 -2
- package/dist/space/index.d.ts.map +1 -1
- package/dist/space/index.js +2 -2
- package/dist/space/index.js.map +1 -1
- package/dist/webvh/didWeb.d.ts +4 -6
- package/dist/webvh/didWeb.d.ts.map +1 -1
- package/dist/webvh/didWeb.js.map +1 -1
- package/dist/webvh/didWebvh.d.ts +1 -2
- package/dist/webvh/didWebvh.d.ts.map +1 -1
- package/dist/webvh/didWebvh.js +1 -6
- package/dist/webvh/didWebvh.js.map +1 -1
- package/package.json +11 -4
package/dist/keys/index.js
CHANGED
|
@@ -13,13 +13,18 @@
|
|
|
13
13
|
* strict validation of the local client-key record each client keeps its own
|
|
14
14
|
* key material in (storage and wrapping stay app-side).
|
|
15
15
|
* - `ensureUserKeyRoster` / `addUserKeyRosterRecipient` / `readUserKeyRoster` /
|
|
16
|
-
* `userKeyRosterRecipientResolver` -- the
|
|
17
|
-
* was-client descriptor-store seam, with the
|
|
18
|
-
* resource-hosted descriptor needs (
|
|
19
|
-
* and a recipient resolver backed by the locally
|
|
20
|
-
* document).
|
|
21
|
-
* - `userKeyRosterDescriptorStore` -- that
|
|
22
|
-
*
|
|
16
|
+
* `userKeyRosterRecipientResolver` -- the user key roster over the
|
|
17
|
+
* was-client descriptor-store seam, with the client-side guards a
|
|
18
|
+
* resource-hosted descriptor needs (the governing resource log, the
|
|
19
|
+
* latest-seen epoch pin, and a recipient resolver backed by the locally
|
|
20
|
+
* verified did:webvh document).
|
|
21
|
+
* - `userKeyRosterDescriptorStore` / `logGovernedDescriptorStore` -- that
|
|
22
|
+
* descriptor store: reads resolve to the roster log's verified head
|
|
23
|
+
* (`key-map/user-key.jsonl`), writes append signed entries; built from a
|
|
24
|
+
* bare signing client for the login-time direct read. Sealable
|
|
25
|
+
* (`SealableEncryptionDescriptorStore` / `isSealableDescriptorStore`):
|
|
26
|
+
* `seal()` appends the idempotent backstop entry when the log's head still
|
|
27
|
+
* anchors before the account document's latest membership change.
|
|
23
28
|
* - `rosterRecipientKid` -- the one builder of a client's roster kid, shared by
|
|
24
29
|
* the enrollment wrap, the roster read, and the rotation that retires it.
|
|
25
30
|
* - `convergeUserKeyRosterToDocument` -- the standing detector for a revocation
|
|
@@ -42,9 +47,10 @@
|
|
|
42
47
|
*/
|
|
43
48
|
export { mintUserKey, userKeyVaultKeys } from './userKey.js';
|
|
44
49
|
export { assertEnrolledClientKeyRecord, decodeClientKeyRecord, encodeClientKeyRecord, parseClientRecordUserKey, parseClientRecordWebvhKeys } from './clientKeyRecord.js';
|
|
45
|
-
export { addUserKeyRosterRecipient, convergeUserKeyRosterToDocument, ensureUserKeyRoster, UserKeyRosterContinuityError, UserKeyRosterIntegrityError, UserKeyRosterUnwrapError,
|
|
50
|
+
export { addUserKeyRosterRecipient, convergeUserKeyRosterToDocument, ensureUserKeyRoster, UserKeyRosterContinuityError, UserKeyRosterIntegrityError, UserKeyRosterUnwrapError, userKeyRosterLogSigner, userKeyRosterRecipientResolver, readUserKeyRoster, rosterRecipientKid, rotateUserKeyRoster } from './userKeyRoster.js';
|
|
46
51
|
export { cascadeCollectionsToUserKey, userKeyAsRecipient, rotateCollectionEpochsToUserKey, unwrapUserKeyGenerations } from './userKeyCascade.js';
|
|
47
52
|
export { userKeyRosterDescriptorStore } from './rosterStore.js';
|
|
53
|
+
export { EPOCH_CONFIGURATION_STATE_TYPE, isSealableDescriptorStore, logGovernedDescriptorStore } from './rosterLogStore.js';
|
|
48
54
|
export { ensureWalletSpaceEpochs } from './spaceEpochs.js';
|
|
49
55
|
export { readClientLabels, removeClientLabel, setClientLabel } from './clientLabels.js';
|
|
50
56
|
export { wasClientLabelsStore } from './wasLabelsStore.js';
|
package/dist/keys/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/keys/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/keys/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAG5D,OAAO,EACL,6BAA6B,EAC7B,qBAAqB,EACrB,qBAAqB,EACrB,wBAAwB,EACxB,0BAA0B,EAC3B,MAAM,sBAAsB,CAAA;AAO7B,OAAO,EACL,yBAAyB,EACzB,+BAA+B,EAC/B,mBAAmB,EACnB,4BAA4B,EAC5B,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EACtB,8BAA8B,EAC9B,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,EAClB,+BAA+B,EAC/B,wBAAwB,EACzB,MAAM,qBAAqB,CAAA;AAU5B,OAAO,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAA;AAC/D,OAAO,EACL,8BAA8B,EAC9B,yBAAyB,EACzB,0BAA0B,EAC3B,MAAM,qBAAqB,CAAA;AAG5B,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAA;AAG1D,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACf,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { EncryptionDescriptorStore } from '@interop/was-client/edv';
|
|
2
|
+
import { type ResourceLogStore } from '@interop/was-client/log';
|
|
3
|
+
import { type ResourceLogController, type ResourceLogPinStore, type ResourceLogSigner } from '../resourceLog/index.js';
|
|
4
|
+
import { EPOCH_CONFIGURATION_STATE_TYPE } from '../descriptors/logSource.js';
|
|
5
|
+
export { EPOCH_CONFIGURATION_STATE_TYPE };
|
|
6
|
+
/**
|
|
7
|
+
* An `EncryptionDescriptorStore` whose resource is governed by a resource
|
|
8
|
+
* log, and can therefore be SEALED: `seal()` runs the sealing sweep
|
|
9
|
+
* (`sealResourceLog`) against the caller's currently verified controller
|
|
10
|
+
* view, appending the idempotent no-op backstop entry when the log's head
|
|
11
|
+
* still anchors before the controller's latest membership change --
|
|
12
|
+
* `'sealed'` -- and writing nothing when the log is already sealed, absent,
|
|
13
|
+
* or has no membership change to seal against -- `'noop'`.
|
|
14
|
+
*/
|
|
15
|
+
export interface SealableEncryptionDescriptorStore extends EncryptionDescriptorStore {
|
|
16
|
+
seal(): Promise<'sealed' | 'noop'>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Whether a descriptor store is log-governed and sealable -- the guard the
|
|
20
|
+
* ceremonies and sweeps use to run the seal backstop only where a governing
|
|
21
|
+
* log exists (an ordinary Collection-Description-backed store has nothing to
|
|
22
|
+
* seal).
|
|
23
|
+
*
|
|
24
|
+
* @param store {EncryptionDescriptorStore}
|
|
25
|
+
* @returns {boolean}
|
|
26
|
+
*/
|
|
27
|
+
export declare function isSealableDescriptorStore(store: EncryptionDescriptorStore): store is SealableEncryptionDescriptorStore;
|
|
28
|
+
/**
|
|
29
|
+
* Builds the log-governed `EncryptionDescriptorStore`.
|
|
30
|
+
*
|
|
31
|
+
* The controller view is resolved per operation (never held), so a caller
|
|
32
|
+
* that just edited the account document -- a revocation about to rotate the
|
|
33
|
+
* roster -- writes entries anchored at the post-edit head it now verifies,
|
|
34
|
+
* which is exactly what makes its rotation the sealing append.
|
|
35
|
+
*
|
|
36
|
+
* @param options {object}
|
|
37
|
+
* @param options.log {ResourceLogStore} the log's transport seam
|
|
38
|
+
* @param options.resolveController {function} `() => Promise<ResourceLogController>`
|
|
39
|
+
* -- the caller's currently verified controller view
|
|
40
|
+
* (`webvhResourceLogController` over a `verifyAccountLog` result)
|
|
41
|
+
* @param options.pinStore {ResourceLogPinStore} this client's chain-head pin
|
|
42
|
+
* for this log
|
|
43
|
+
* @param options.signer {ResourceLogSigner} this client's enrolled signing
|
|
44
|
+
* key, for the appends this store writes
|
|
45
|
+
* @returns {SealableEncryptionDescriptorStore}
|
|
46
|
+
*/
|
|
47
|
+
export declare function logGovernedDescriptorStore({ log, resolveController, pinStore, signer }: {
|
|
48
|
+
log: ResourceLogStore;
|
|
49
|
+
resolveController: () => Promise<ResourceLogController>;
|
|
50
|
+
pinStore: ResourceLogPinStore;
|
|
51
|
+
signer: ResourceLogSigner;
|
|
52
|
+
}): SealableEncryptionDescriptorStore;
|
|
53
|
+
//# sourceMappingURL=rosterLogStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rosterLogStore.d.ts","sourceRoot":"","sources":["../../src/keys/rosterLogStore.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAA;AACxE,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAQL,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EAEvB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,8BAA8B,EAAE,MAAM,6BAA6B,CAAA;AAE5E,OAAO,EAAE,8BAA8B,EAAE,CAAA;AAEzC;;;;;;;;GAQG;AACH,MAAM,WAAW,iCAAkC,SAAQ,yBAAyB;IAClF,IAAI,IAAI,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC,CAAA;CACnC;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,yBAAyB,GAC/B,KAAK,IAAI,iCAAiC,CAK5C;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,0BAA0B,CAAC,EACzC,GAAG,EACH,iBAAiB,EACjB,QAAQ,EACR,MAAM,EACP,EAAE;IACD,GAAG,EAAE,gBAAgB,CAAA;IACrB,iBAAiB,EAAE,MAAM,OAAO,CAAC,qBAAqB,CAAC,CAAA;IACvD,QAAQ,EAAE,mBAAmB,CAAA;IAC7B,MAAM,EAAE,iBAAiB,CAAA;CAC1B,GAAG,iCAAiC,CAoHpC"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { confirmAppend, WAS_RESOURCE_LOG_METHOD } from '@interop/was-client/log';
|
|
2
|
+
import { buildResourceLogEntry, buildResourceLogGenesis, readResourceLog, ResourceLogClosedError, ResourceLogIntegrityError, sealResourceLog, verifyResourceLog } from '../resourceLog/index.js';
|
|
3
|
+
import { EPOCH_CONFIGURATION_STATE_TYPE } from '../descriptors/logSource.js';
|
|
4
|
+
export { EPOCH_CONFIGURATION_STATE_TYPE };
|
|
5
|
+
/**
|
|
6
|
+
* Whether a descriptor store is log-governed and sealable -- the guard the
|
|
7
|
+
* ceremonies and sweeps use to run the seal backstop only where a governing
|
|
8
|
+
* log exists (an ordinary Collection-Description-backed store has nothing to
|
|
9
|
+
* seal).
|
|
10
|
+
*
|
|
11
|
+
* @param store {EncryptionDescriptorStore}
|
|
12
|
+
* @returns {boolean}
|
|
13
|
+
*/
|
|
14
|
+
export function isSealableDescriptorStore(store) {
|
|
15
|
+
return (typeof store.seal ===
|
|
16
|
+
'function');
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Builds the log-governed `EncryptionDescriptorStore`.
|
|
20
|
+
*
|
|
21
|
+
* The controller view is resolved per operation (never held), so a caller
|
|
22
|
+
* that just edited the account document -- a revocation about to rotate the
|
|
23
|
+
* roster -- writes entries anchored at the post-edit head it now verifies,
|
|
24
|
+
* which is exactly what makes its rotation the sealing append.
|
|
25
|
+
*
|
|
26
|
+
* @param options {object}
|
|
27
|
+
* @param options.log {ResourceLogStore} the log's transport seam
|
|
28
|
+
* @param options.resolveController {function} `() => Promise<ResourceLogController>`
|
|
29
|
+
* -- the caller's currently verified controller view
|
|
30
|
+
* (`webvhResourceLogController` over a `verifyAccountLog` result)
|
|
31
|
+
* @param options.pinStore {ResourceLogPinStore} this client's chain-head pin
|
|
32
|
+
* for this log
|
|
33
|
+
* @param options.signer {ResourceLogSigner} this client's enrolled signing
|
|
34
|
+
* key, for the appends this store writes
|
|
35
|
+
* @returns {SealableEncryptionDescriptorStore}
|
|
36
|
+
*/
|
|
37
|
+
export function logGovernedDescriptorStore({ log, resolveController, pinStore, signer }) {
|
|
38
|
+
// The verified log observed by the most recent read on this store instance;
|
|
39
|
+
// a replace builds its entry on that head, pinned to the same read's etag,
|
|
40
|
+
// so a stale head loses the CAS instead of forking.
|
|
41
|
+
let lastVerified = null;
|
|
42
|
+
function toState(descriptor) {
|
|
43
|
+
const { history: _history, ...rest } = descriptor;
|
|
44
|
+
return { ...rest, type: EPOCH_CONFIGURATION_STATE_TYPE };
|
|
45
|
+
}
|
|
46
|
+
async function settle({ entry, controller }) {
|
|
47
|
+
const readBack = await confirmAppend({ store: log, entry });
|
|
48
|
+
const confirmed = await verifyResourceLog({
|
|
49
|
+
entries: readBack.entries,
|
|
50
|
+
controller,
|
|
51
|
+
expectedMethod: WAS_RESOURCE_LOG_METHOD,
|
|
52
|
+
pin: await pinStore.read()
|
|
53
|
+
});
|
|
54
|
+
await pinStore.write(confirmed.pin);
|
|
55
|
+
lastVerified = confirmed;
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
async read() {
|
|
59
|
+
const controller = await resolveController();
|
|
60
|
+
const current = await readResourceLog({
|
|
61
|
+
store: log,
|
|
62
|
+
controller,
|
|
63
|
+
expectedMethod: WAS_RESOURCE_LOG_METHOD,
|
|
64
|
+
pinStore
|
|
65
|
+
});
|
|
66
|
+
if (current === null) {
|
|
67
|
+
lastVerified = null;
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
const state = current.verified.state;
|
|
71
|
+
if (state.type !== EPOCH_CONFIGURATION_STATE_TYPE) {
|
|
72
|
+
throw new ResourceLogIntegrityError(`The governed descriptor log carries state of type ` +
|
|
73
|
+
`"${state.type}", not "${EPOCH_CONFIGURATION_STATE_TYPE}".`);
|
|
74
|
+
}
|
|
75
|
+
lastVerified = current.verified;
|
|
76
|
+
return {
|
|
77
|
+
descriptor: state,
|
|
78
|
+
etag: current.etag
|
|
79
|
+
};
|
|
80
|
+
},
|
|
81
|
+
async replace(descriptor, { ifMatch }) {
|
|
82
|
+
if (lastVerified === null) {
|
|
83
|
+
throw new Error('Cannot replace the governed descriptor: replace must follow a ' +
|
|
84
|
+
'read on the same store instance.');
|
|
85
|
+
}
|
|
86
|
+
if (ifMatch === undefined) {
|
|
87
|
+
throw new Error('Cannot replace the governed descriptor: the backend returned no ' +
|
|
88
|
+
'validator, and the profile forbids an unconditional write.');
|
|
89
|
+
}
|
|
90
|
+
if (lastVerified.terminal) {
|
|
91
|
+
throw new ResourceLogClosedError({ nextLog: lastVerified.terminal });
|
|
92
|
+
}
|
|
93
|
+
const controller = await resolveController();
|
|
94
|
+
const entry = await buildResourceLogEntry({
|
|
95
|
+
head: lastVerified.head,
|
|
96
|
+
state: toState(descriptor),
|
|
97
|
+
controller,
|
|
98
|
+
signer
|
|
99
|
+
});
|
|
100
|
+
// A stale validator throws PreconditionFailedError here, which the edv
|
|
101
|
+
// machinery's CAS loop re-reads and rebases on.
|
|
102
|
+
await log.append(entry, { ifMatch });
|
|
103
|
+
await settle({ entry, controller });
|
|
104
|
+
},
|
|
105
|
+
async create(descriptor) {
|
|
106
|
+
const controller = await resolveController();
|
|
107
|
+
const genesis = await buildResourceLogGenesis({
|
|
108
|
+
state: toState(descriptor),
|
|
109
|
+
method: WAS_RESOURCE_LOG_METHOD,
|
|
110
|
+
controller,
|
|
111
|
+
signer
|
|
112
|
+
});
|
|
113
|
+
// A lost guarded-create race throws PreconditionFailedError, and the
|
|
114
|
+
// edv machinery re-reads and adopts the winner's descriptor.
|
|
115
|
+
await log.create(genesis);
|
|
116
|
+
await settle({ entry: genesis, controller });
|
|
117
|
+
},
|
|
118
|
+
async seal() {
|
|
119
|
+
const controller = await resolveController();
|
|
120
|
+
const { sealed, verified } = await sealResourceLog({
|
|
121
|
+
store: log,
|
|
122
|
+
controller,
|
|
123
|
+
expectedMethod: WAS_RESOURCE_LOG_METHOD,
|
|
124
|
+
pinStore,
|
|
125
|
+
signer
|
|
126
|
+
});
|
|
127
|
+
if (verified !== null) {
|
|
128
|
+
lastVerified = verified;
|
|
129
|
+
}
|
|
130
|
+
return sealed ? 'sealed' : 'noop';
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=rosterLogStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rosterLogStore.js","sourceRoot":"","sources":["../../src/keys/rosterLogStore.ts"],"names":[],"mappings":"AA6BA,OAAO,EACL,aAAa,EACb,uBAAuB,EAExB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,eAAe,EACf,sBAAsB,EACtB,yBAAyB,EACzB,eAAe,EACf,iBAAiB,EAKlB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,8BAA8B,EAAE,MAAM,6BAA6B,CAAA;AAE5E,OAAO,EAAE,8BAA8B,EAAE,CAAA;AAezC;;;;;;;;GAQG;AACH,MAAM,UAAU,yBAAyB,CACvC,KAAgC;IAEhC,OAAO,CACL,OAAQ,KAAoD,CAAC,IAAI;QACjE,UAAU,CACX,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,0BAA0B,CAAC,EACzC,GAAG,EACH,iBAAiB,EACjB,QAAQ,EACR,MAAM,EAMP;IACC,4EAA4E;IAC5E,2EAA2E;IAC3E,oDAAoD;IACpD,IAAI,YAAY,GAA+B,IAAI,CAAA;IAEnD,SAAS,OAAO,CACd,UAAgC;QAEhC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,UAAU,CAAA;QACjD,OAAO,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,8BAA8B,EAAE,CAAA;IAC1D,CAAC;IAED,KAAK,UAAU,MAAM,CAAC,EACpB,KAAK,EACL,UAAU,EAIX;QACC,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAA;QAC3D,MAAM,SAAS,GAAG,MAAM,iBAAiB,CAAC;YACxC,OAAO,EAAE,QAAQ,CAAC,OAAO;YACzB,UAAU;YACV,cAAc,EAAE,uBAAuB;YACvC,GAAG,EAAE,MAAM,QAAQ,CAAC,IAAI,EAAE;SAC3B,CAAC,CAAA;QACF,MAAM,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QACnC,YAAY,GAAG,SAAS,CAAA;IAC1B,CAAC;IAED,OAAO;QACL,KAAK,CAAC,IAAI;YACR,MAAM,UAAU,GAAG,MAAM,iBAAiB,EAAE,CAAA;YAC5C,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC;gBACpC,KAAK,EAAE,GAAG;gBACV,UAAU;gBACV,cAAc,EAAE,uBAAuB;gBACvC,QAAQ;aACT,CAAC,CAAA;YACF,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBACrB,YAAY,GAAG,IAAI,CAAA;gBACnB,OAAO,IAAI,CAAA;YACb,CAAC;YACD,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAA;YACpC,IAAI,KAAK,CAAC,IAAI,KAAK,8BAA8B,EAAE,CAAC;gBAClD,MAAM,IAAI,yBAAyB,CACjC,oDAAoD;oBAClD,IAAI,KAAK,CAAC,IAAI,WAAW,8BAA8B,IAAI,CAC9D,CAAA;YACH,CAAC;YACD,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAA;YAC/B,OAAO;gBACL,UAAU,EAAE,KAA6B;gBACzC,IAAI,EAAE,OAAO,CAAC,IAAI;aACnB,CAAA;QACH,CAAC;QAED,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,OAAO,EAAE;YACnC,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;gBAC1B,MAAM,IAAI,KAAK,CACb,gEAAgE;oBAC9D,kCAAkC,CACrC,CAAA;YACH,CAAC;YACD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC1B,MAAM,IAAI,KAAK,CACb,kEAAkE;oBAChE,4DAA4D,CAC/D,CAAA;YACH,CAAC;YACD,IAAI,YAAY,CAAC,QAAQ,EAAE,CAAC;gBAC1B,MAAM,IAAI,sBAAsB,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAA;YACtE,CAAC;YACD,MAAM,UAAU,GAAG,MAAM,iBAAiB,EAAE,CAAA;YAC5C,MAAM,KAAK,GAAG,MAAM,qBAAqB,CAAC;gBACxC,IAAI,EAAE,YAAY,CAAC,IAAI;gBACvB,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC;gBAC1B,UAAU;gBACV,MAAM;aACP,CAAC,CAAA;YACF,uEAAuE;YACvE,gDAAgD;YAChD,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;YACpC,MAAM,MAAM,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAA;QACrC,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,UAAU;YACrB,MAAM,UAAU,GAAG,MAAM,iBAAiB,EAAE,CAAA;YAC5C,MAAM,OAAO,GAAG,MAAM,uBAAuB,CAAC;gBAC5C,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC;gBAC1B,MAAM,EAAE,uBAAuB;gBAC/B,UAAU;gBACV,MAAM;aACP,CAAC,CAAA;YACF,qEAAqE;YACrE,6DAA6D;YAC7D,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YACzB,MAAM,MAAM,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAA;QAC9C,CAAC;QAED,KAAK,CAAC,IAAI;YACR,MAAM,UAAU,GAAG,MAAM,iBAAiB,EAAE,CAAA;YAC5C,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,eAAe,CAAC;gBACjD,KAAK,EAAE,GAAG;gBACV,UAAU;gBACV,cAAc,EAAE,uBAAuB;gBACvC,QAAQ;gBACR,MAAM;aACP,CAAC,CAAA;YACF,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;gBACtB,YAAY,GAAG,QAAQ,CAAA;YACzB,CAAC;YACD,OAAO,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAA;QACnC,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -1,18 +1,32 @@
|
|
|
1
1
|
import type { ZcapClient } from '@interop/ezcap';
|
|
2
|
-
import {
|
|
2
|
+
import type { ResourceLogController, ResourceLogPinStore, ResourceLogSigner } from '../resourceLog/index.js';
|
|
3
|
+
import { type SealableEncryptionDescriptorStore } from './rosterLogStore.js';
|
|
3
4
|
/**
|
|
4
|
-
* Builds the
|
|
5
|
-
*
|
|
5
|
+
* Builds the log-governed descriptor store over the user key roster in a
|
|
6
|
+
* data Space: reads resolve to the verified head of
|
|
7
|
+
* `key-map/user-key.jsonl`, writes append to it.
|
|
6
8
|
*
|
|
7
9
|
* @param options {object}
|
|
8
10
|
* @param options.storageServerUrl {string}
|
|
9
11
|
* @param options.zcapClient {ZcapClient} the session's root signing client
|
|
10
12
|
* @param options.spaceId {string} the data Space id
|
|
11
|
-
* @
|
|
13
|
+
* @param options.resolveController {function}
|
|
14
|
+
* `() => Promise<ResourceLogController>` -- the caller's currently verified
|
|
15
|
+
* controller view (`webvhResourceLogController` over a `verifyAccountLog`
|
|
16
|
+
* result), resolved per operation so post-edit writers anchor at the head
|
|
17
|
+
* they just verified
|
|
18
|
+
* @param options.pinStore {ResourceLogPinStore} this client's chain-head
|
|
19
|
+
* pin for the roster log
|
|
20
|
+
* @param options.signer {ResourceLogSigner} this client's enrolled signing
|
|
21
|
+
* key ({@link userKeyRosterLogSigner})
|
|
22
|
+
* @returns {SealableEncryptionDescriptorStore}
|
|
12
23
|
*/
|
|
13
|
-
export declare function userKeyRosterDescriptorStore({ storageServerUrl, zcapClient, spaceId }: {
|
|
24
|
+
export declare function userKeyRosterDescriptorStore({ storageServerUrl, zcapClient, spaceId, resolveController, pinStore, signer }: {
|
|
14
25
|
storageServerUrl: string;
|
|
15
26
|
zcapClient: ZcapClient;
|
|
16
27
|
spaceId: string;
|
|
17
|
-
|
|
28
|
+
resolveController: () => Promise<ResourceLogController>;
|
|
29
|
+
pinStore: ResourceLogPinStore;
|
|
30
|
+
signer: ResourceLogSigner;
|
|
31
|
+
}): SealableEncryptionDescriptorStore;
|
|
18
32
|
//# sourceMappingURL=rosterStore.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rosterStore.d.ts","sourceRoot":"","sources":["../../src/keys/rosterStore.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rosterStore.d.ts","sourceRoot":"","sources":["../../src/keys/rosterStore.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAEhD,OAAO,KAAK,EACV,qBAAqB,EACrB,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,yBAAyB,CAAA;AAKhC,OAAO,EAEL,KAAK,iCAAiC,EACvC,MAAM,qBAAqB,CAAA;AAE5B;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,4BAA4B,CAAC,EAC3C,gBAAgB,EAChB,UAAU,EACV,OAAO,EACP,iBAAiB,EACjB,QAAQ,EACR,MAAM,EACP,EAAE;IACD,gBAAgB,EAAE,MAAM,CAAA;IACxB,UAAU,EAAE,UAAU,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,iBAAiB,EAAE,MAAM,OAAO,CAAC,qBAAqB,CAAC,CAAA;IACvD,QAAQ,EAAE,mBAAmB,CAAA;IAC7B,MAAM,EAAE,iBAAiB,CAAA;CAC1B,GAAG,iCAAiC,CAapC"}
|
package/dist/keys/rosterStore.js
CHANGED
|
@@ -2,37 +2,56 @@
|
|
|
2
2
|
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
|
-
* The descriptor store over a Space's user key wrap-set roster
|
|
6
|
-
* (`key-map/user-key.
|
|
7
|
-
* remote-store class, because the
|
|
8
|
-
* BEFORE any storage client (or
|
|
9
|
-
* client instead of a store
|
|
5
|
+
* The descriptor store over a Space's user key wrap-set roster -- since the
|
|
6
|
+
* roster became log-governed, over its resource log (`key-map/user-key.jsonl`).
|
|
7
|
+
* Standalone rather than a method on a wallet's remote-store class, because the
|
|
8
|
+
* login-time direct read checks the roster BEFORE any storage client (or
|
|
9
|
+
* cipher) is built: it takes the bare signing client instead of a store
|
|
10
|
+
* instance.
|
|
10
11
|
*
|
|
11
|
-
* The `plaintext` collection override is load-bearing. Without it
|
|
12
|
-
* decides plaintext vs encrypted by describing the collection
|
|
13
|
-
* from an absent Space or collection then surfaces as an
|
|
14
|
-
* rather than as an absent roster
|
|
12
|
+
* The `plaintext` collection override is load-bearing twice over. Without it
|
|
13
|
+
* the client decides plaintext vs encrypted by describing the collection
|
|
14
|
+
* first, and a 404 from an absent Space or collection then surfaces as an
|
|
15
|
+
* encryption error rather than as an absent roster; and on an encrypted
|
|
16
|
+
* collection the EDV codec would compute the write preconditions itself, so
|
|
17
|
+
* the log's compare-and-swap append guard would not be honored.
|
|
15
18
|
*/
|
|
16
19
|
import { WasClient } from '@interop/was-client';
|
|
17
|
-
import {
|
|
18
|
-
import { KEY_MAP_COLLECTION,
|
|
20
|
+
import { resourceLogStore } from '@interop/was-client/log';
|
|
21
|
+
import { KEY_MAP_COLLECTION, USER_KEY_ROSTER_LOG_RESOURCE } from '../space/collections.js';
|
|
22
|
+
import { logGovernedDescriptorStore } from './rosterLogStore.js';
|
|
19
23
|
/**
|
|
20
|
-
* Builds the
|
|
21
|
-
*
|
|
24
|
+
* Builds the log-governed descriptor store over the user key roster in a
|
|
25
|
+
* data Space: reads resolve to the verified head of
|
|
26
|
+
* `key-map/user-key.jsonl`, writes append to it.
|
|
22
27
|
*
|
|
23
28
|
* @param options {object}
|
|
24
29
|
* @param options.storageServerUrl {string}
|
|
25
30
|
* @param options.zcapClient {ZcapClient} the session's root signing client
|
|
26
31
|
* @param options.spaceId {string} the data Space id
|
|
27
|
-
* @
|
|
32
|
+
* @param options.resolveController {function}
|
|
33
|
+
* `() => Promise<ResourceLogController>` -- the caller's currently verified
|
|
34
|
+
* controller view (`webvhResourceLogController` over a `verifyAccountLog`
|
|
35
|
+
* result), resolved per operation so post-edit writers anchor at the head
|
|
36
|
+
* they just verified
|
|
37
|
+
* @param options.pinStore {ResourceLogPinStore} this client's chain-head
|
|
38
|
+
* pin for the roster log
|
|
39
|
+
* @param options.signer {ResourceLogSigner} this client's enrolled signing
|
|
40
|
+
* key ({@link userKeyRosterLogSigner})
|
|
41
|
+
* @returns {SealableEncryptionDescriptorStore}
|
|
28
42
|
*/
|
|
29
|
-
export function userKeyRosterDescriptorStore({ storageServerUrl, zcapClient, spaceId }) {
|
|
43
|
+
export function userKeyRosterDescriptorStore({ storageServerUrl, zcapClient, spaceId, resolveController, pinStore, signer }) {
|
|
30
44
|
const was = new WasClient({ serverUrl: storageServerUrl, zcapClient });
|
|
31
45
|
const collection = was
|
|
32
46
|
.space(spaceId)
|
|
33
47
|
.collection(KEY_MAP_COLLECTION.id, { encryption: 'plaintext' });
|
|
34
|
-
return
|
|
35
|
-
|
|
48
|
+
return logGovernedDescriptorStore({
|
|
49
|
+
log: resourceLogStore({
|
|
50
|
+
resource: collection.resource(USER_KEY_ROSTER_LOG_RESOURCE)
|
|
51
|
+
}),
|
|
52
|
+
resolveController,
|
|
53
|
+
pinStore,
|
|
54
|
+
signer
|
|
36
55
|
});
|
|
37
56
|
}
|
|
38
57
|
//# sourceMappingURL=rosterStore.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rosterStore.js","sourceRoot":"","sources":["../../src/keys/rosterStore.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"rosterStore.js","sourceRoot":"","sources":["../../src/keys/rosterStore.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAE/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAM1D,OAAO,EACL,kBAAkB,EAClB,4BAA4B,EAC7B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,0BAA0B,EAE3B,MAAM,qBAAqB,CAAA;AAE5B;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,4BAA4B,CAAC,EAC3C,gBAAgB,EAChB,UAAU,EACV,OAAO,EACP,iBAAiB,EACjB,QAAQ,EACR,MAAM,EAQP;IACC,MAAM,GAAG,GAAG,IAAI,SAAS,CAAC,EAAE,SAAS,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC,CAAA;IACtE,MAAM,UAAU,GAAG,GAAG;SACnB,KAAK,CAAC,OAAO,CAAC;SACd,UAAU,CAAC,kBAAkB,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAA;IACjE,OAAO,0BAA0B,CAAC;QAChC,GAAG,EAAE,gBAAgB,CAAC;YACpB,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC,4BAA4B,CAAC;SAC5D,CAAC;QACF,iBAAiB;QACjB,QAAQ;QACR,MAAM;KACP,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -65,11 +65,13 @@ export declare function unwrapUserKeyGenerations({ descriptor, clientKeyAgreemen
|
|
|
65
65
|
}): Promise<UserKey[]>;
|
|
66
66
|
/**
|
|
67
67
|
* What one collection's cascade step did: `noop` (already on the current user
|
|
68
|
-
* key), `
|
|
69
|
-
*
|
|
70
|
-
* current user key
|
|
68
|
+
* key), `sealed` (already on the current user key, but the collection's
|
|
69
|
+
* governing log still anchored before the membership change -- the backstop
|
|
70
|
+
* append landed), `escrowed` (the current user key's wrap was completed into
|
|
71
|
+
* history with no stale epoch to rotate), or `rotated` (a fresh epoch sealed
|
|
72
|
+
* to the current user key, the stale generations retired).
|
|
71
73
|
*/
|
|
72
|
-
export type CollectionUserKeyRotationOutcome = 'noop' | 'escrowed' | 'rotated';
|
|
74
|
+
export type CollectionUserKeyRotationOutcome = 'noop' | 'sealed' | 'escrowed' | 'rotated';
|
|
73
75
|
/**
|
|
74
76
|
* Brings ONE encrypted collection's epoch roster onto the current user key --
|
|
75
77
|
* the per-collection op of the revocation cascade and of the completion sweep:
|
|
@@ -79,8 +81,13 @@ export type CollectionUserKeyRotationOutcome = 'noop' | 'escrowed' | 'rotated';
|
|
|
79
81
|
* a fresh epoch minted without the stale generations. Two requests per
|
|
80
82
|
* collection; app recipients and other readers ride through untouched (the
|
|
81
83
|
* default did:key resolver re-wraps them).
|
|
82
|
-
* - **Current already** and fully escrowed: no write at all, so a naive
|
|
83
|
-
* re-run after a mid-cascade crash converges with zero redundant epochs.
|
|
84
|
+
* - **Current already** and fully escrowed: no epoch write at all, so a naive
|
|
85
|
+
* re-run after a mid-cascade crash converges with zero redundant epochs. On
|
|
86
|
+
* a log-governed (sealable) store this is exactly where an unsealed log can
|
|
87
|
+
* hide -- the rotation that should have re-anchored the log never wrote --
|
|
88
|
+
* so the store's seal backstop runs here (`sealed` when it appended);
|
|
89
|
+
* rotated and escrowed writes seal by construction, anchored at the
|
|
90
|
+
* caller's current controller head.
|
|
84
91
|
* - **No epochs**: refused fail-closed (see the module doc) -- provisioning
|
|
85
92
|
* installs every encrypted collection's epoch[0], so the cascade never
|
|
86
93
|
* mints a first epoch.
|
|
@@ -138,7 +145,7 @@ export interface UserKeyCascadeResult {
|
|
|
138
145
|
* own task so a throwing check lands in that collection's `failed` entry
|
|
139
146
|
* (e.g. a standard collection an account never provisioned server-side)
|
|
140
147
|
* @param options.rosterDescriptor {CollectionEncryption} the freshly read
|
|
141
|
-
* `key-map/user-key.
|
|
148
|
+
* `key-map/user-key.jsonl` roster (the source of the user key generations)
|
|
142
149
|
* @param options.clientKeyAgreementKey {IKeyAgreementKey} this client's own
|
|
143
150
|
* (identity) key-agreement key, unwrapping the generations
|
|
144
151
|
* @param options.userKey {UserKey} the roster's current user key
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userKeyCascade.d.ts","sourceRoot":"","sources":["../../src/keys/userKeyCascade.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC/D,OAAO,EAKL,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EACxB,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"userKeyCascade.d.ts","sourceRoot":"","sources":["../../src/keys/userKeyCascade.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC/D,OAAO,EAKL,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EACxB,MAAM,yBAAyB,CAAA;AAEhC,OAAO,EAAoB,KAAK,OAAO,EAAE,MAAM,cAAc,CAAA;AAE7D;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACR,EAAE;IACD,OAAO,EAAE,OAAO,CAAA;CACjB,GAAG,kBAAkB,CAKrB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,wBAAwB,CAAC,EAC7C,UAAU,EACV,qBAAqB,EACtB,EAAE;IACD,UAAU,EAAE,oBAAoB,CAAA;IAChC,qBAAqB,EAAE,gBAAgB,CAAA;CACxC,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAkBrB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,gCAAgC,GAC1C,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAA;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAsB,+BAA+B,CAAC,EACpD,KAAK,EACL,OAAO,EACP,WAAW,EACZ,EAAE;IACD,KAAK,EAAE,yBAAyB,CAAA;IAChC,OAAO,EAAE,OAAO,CAAA;IAChB,WAAW,EAAE,OAAO,EAAE,CAAA;CACvB,GAAG,OAAO,CAAC,gCAAgC,CAAC,CAmG5C;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,gCAAgC,CAAC,CAAA;IAC1D,MAAM,EAAE,KAAK,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAA;CACxD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,2BAA2B,CAAC,EAChD,aAAa,EACb,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,qBAAqB,EACrB,OAAO,EACR,EAAE;IACD,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,yBAAyB,CAAA;IAC7D,WAAW,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACxD,gBAAgB,EAAE,oBAAoB,CAAA;IACtC,qBAAqB,EAAE,gBAAgB,CAAA;IACvC,OAAO,EAAE,OAAO,CAAA;CACjB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAwBhC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { addRecipient, epochKeyIdFor, replaceRecipient, unwrapEpochSecret } from '@interop/was-client/edv';
|
|
2
|
+
import { isSealableDescriptorStore } from './rosterLogStore.js';
|
|
2
3
|
import { userKeyVaultKeys } from './userKey.js';
|
|
3
4
|
/**
|
|
4
5
|
* A user key presented as an epoch-roster recipient: the kid is the
|
|
@@ -57,8 +58,13 @@ export async function unwrapUserKeyGenerations({ descriptor, clientKeyAgreementK
|
|
|
57
58
|
* a fresh epoch minted without the stale generations. Two requests per
|
|
58
59
|
* collection; app recipients and other readers ride through untouched (the
|
|
59
60
|
* default did:key resolver re-wraps them).
|
|
60
|
-
* - **Current already** and fully escrowed: no write at all, so a naive
|
|
61
|
-
* re-run after a mid-cascade crash converges with zero redundant epochs.
|
|
61
|
+
* - **Current already** and fully escrowed: no epoch write at all, so a naive
|
|
62
|
+
* re-run after a mid-cascade crash converges with zero redundant epochs. On
|
|
63
|
+
* a log-governed (sealable) store this is exactly where an unsealed log can
|
|
64
|
+
* hide -- the rotation that should have re-anchored the log never wrote --
|
|
65
|
+
* so the store's seal backstop runs here (`sealed` when it appended);
|
|
66
|
+
* rotated and escrowed writes seal by construction, anchored at the
|
|
67
|
+
* caller's current controller head.
|
|
62
68
|
* - **No epochs**: refused fail-closed (see the module doc) -- provisioning
|
|
63
69
|
* installs every encrypted collection's epoch[0], so the cascade never
|
|
64
70
|
* mints a first epoch.
|
|
@@ -99,6 +105,9 @@ export async function rotateCollectionEpochsToUserKey({ store, userKey, generati
|
|
|
99
105
|
if (staleKids.length === 0) {
|
|
100
106
|
const escrowComplete = (descriptor.epochs ?? []).every(epoch => epoch.recipients.some(entry => entry.header.kid === userKeyKid));
|
|
101
107
|
if (currentKids.has(userKeyKid) && escrowComplete) {
|
|
108
|
+
if (isSealableDescriptorStore(store)) {
|
|
109
|
+
return (await store.seal()) === 'sealed' ? 'sealed' : 'noop';
|
|
110
|
+
}
|
|
102
111
|
return 'noop';
|
|
103
112
|
}
|
|
104
113
|
}
|
|
@@ -170,7 +179,7 @@ export async function rotateCollectionEpochsToUserKey({ store, userKey, generati
|
|
|
170
179
|
* own task so a throwing check lands in that collection's `failed` entry
|
|
171
180
|
* (e.g. a standard collection an account never provisioned server-side)
|
|
172
181
|
* @param options.rosterDescriptor {CollectionEncryption} the freshly read
|
|
173
|
-
* `key-map/user-key.
|
|
182
|
+
* `key-map/user-key.jsonl` roster (the source of the user key generations)
|
|
174
183
|
* @param options.clientKeyAgreementKey {IKeyAgreementKey} this client's own
|
|
175
184
|
* (identity) key-agreement key, unwrapping the generations
|
|
176
185
|
* @param options.userKey {UserKey} the roster's current user key
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userKeyCascade.js","sourceRoot":"","sources":["../../src/keys/userKeyCascade.ts"],"names":[],"mappings":"AA+BA,OAAO,EACL,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EAGlB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,gBAAgB,EAAgB,MAAM,cAAc,CAAA;AAE7D;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,EACjC,OAAO,EAGR;IACC,OAAO;QACL,EAAE,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,kBAAkB,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE;KAC9C,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,EAC7C,UAAU,EACV,qBAAqB,EAItB;IACC,MAAM,WAAW,GAAc,EAAE,CAAA;IACjC,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;QAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,IAAI,CACjC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,KAAK,qBAAqB,CAAC,EAAE,CAC/D,CAAA;QACD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,SAAQ;QACV,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC;YACrC,KAAK;YACL,eAAe,EAAE,qBAAqB;SACvC,CAAC,CAAA;QACF,IAAI,MAAM,EAAE,CAAC;YACX,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;QAC5C,CAAC;IACH,CAAC;IACD,OAAO,WAAW,CAAA;AACpB,CAAC;
|
|
1
|
+
{"version":3,"file":"userKeyCascade.js","sourceRoot":"","sources":["../../src/keys/userKeyCascade.ts"],"names":[],"mappings":"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"}
|