@interop/wallet-core 0.21.0 → 0.22.1
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 +5 -2
- package/dist/descriptors/acquire.d.ts +23 -15
- package/dist/descriptors/acquire.d.ts.map +1 -1
- package/dist/descriptors/acquire.js +11 -8
- package/dist/descriptors/acquire.js.map +1 -1
- package/dist/descriptors/cipher.d.ts +9 -3
- package/dist/descriptors/cipher.d.ts.map +1 -1
- package/dist/descriptors/cipher.js +43 -12
- package/dist/descriptors/cipher.js.map +1 -1
- package/dist/descriptors/index.d.ts +6 -2
- package/dist/descriptors/index.d.ts.map +1 -1
- package/dist/descriptors/index.js +6 -2
- package/dist/descriptors/index.js.map +1 -1
- package/dist/keyring/index.d.ts +8 -3
- package/dist/keyring/index.d.ts.map +1 -1
- package/dist/keyring/index.js +8 -3
- package/dist/keyring/index.js.map +1 -1
- package/dist/keyring/record.d.ts +89 -18
- package/dist/keyring/record.d.ts.map +1 -1
- package/dist/keyring/record.js +119 -23
- package/dist/keyring/record.js.map +1 -1
- package/dist/keys/index.d.ts +5 -0
- package/dist/keys/index.d.ts.map +1 -1
- package/dist/keys/index.js +4 -0
- package/dist/keys/index.js.map +1 -1
- package/dist/keys/spaceEpochs.d.ts +95 -0
- package/dist/keys/spaceEpochs.d.ts.map +1 -0
- package/dist/keys/spaceEpochs.js +71 -0
- package/dist/keys/spaceEpochs.js.map +1 -0
- package/dist/keys/userKeyCascade.d.ts +14 -16
- package/dist/keys/userKeyCascade.d.ts.map +1 -1
- package/dist/keys/userKeyCascade.js +9 -43
- package/dist/keys/userKeyCascade.js.map +1 -1
- package/dist/recovery/recoveryRecord.d.ts +18 -13
- package/dist/recovery/recoveryRecord.d.ts.map +1 -1
- package/dist/recovery/recoveryRecord.js +15 -17
- package/dist/recovery/recoveryRecord.js.map +1 -1
- package/dist/recovery/recoveryWebvh.d.ts.map +1 -1
- package/dist/recovery/recoveryWebvh.js +4 -0
- package/dist/recovery/recoveryWebvh.js.map +1 -1
- package/dist/space/collections.d.ts +2 -2
- package/dist/space/collections.js +2 -2
- package/dist/space/index.d.ts +5 -2
- package/dist/space/index.d.ts.map +1 -1
- package/dist/space/index.js +5 -2
- package/dist/space/index.js.map +1 -1
- package/dist/space/provisioning.d.ts +25 -14
- package/dist/space/provisioning.d.ts.map +1 -1
- package/dist/space/provisioning.js +22 -33
- package/dist/space/provisioning.js.map +1 -1
- package/dist/sync/engine.d.ts +28 -1
- package/dist/sync/engine.d.ts.map +1 -1
- package/dist/sync/engine.js +5 -0
- package/dist/sync/engine.js.map +1 -1
- package/dist/sync/index.d.ts +8 -3
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +8 -3
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/push.d.ts.map +1 -1
- package/dist/sync/push.js +3 -2
- package/dist/sync/push.js.map +1 -1
- package/dist/sync/remint.d.ts +94 -0
- package/dist/sync/remint.d.ts.map +1 -0
- package/dist/sync/remint.js +111 -0
- package/dist/sync/remint.js.map +1 -0
- package/dist/sync/types.d.ts +38 -4
- package/dist/sync/types.d.ts.map +1 -1
- package/dist/sync/types.js +4 -4
- package/dist/sync/types.js.map +1 -1
- package/dist/webvh/didWebvh.d.ts.map +1 -1
- package/dist/webvh/didWebvh.js +3 -0
- package/dist/webvh/didWebvh.js.map +1 -1
- package/dist/webvh/revokeClient.d.ts.map +1 -1
- package/dist/webvh/revokeClient.js +1 -0
- package/dist/webvh/revokeClient.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -81,8 +81,11 @@ The subpaths:
|
|
|
81
81
|
staleness detected from durable state alone, history escrowed -- also the
|
|
82
82
|
completion sweep's building block), plus the detector that converges a roster
|
|
83
83
|
left wrapping the current key to a recipient the account document no longer
|
|
84
|
-
keys. Also the
|
|
85
|
-
|
|
84
|
+
keys. Also `ensureWalletSpaceEpochs`, the provision-time install of each
|
|
85
|
+
encrypted wallet collection's key epoch[0] (a fresh random epoch key wrapped
|
|
86
|
+
to the user key) -- the EDV-bearing second step of `provisionWalletSpace`.
|
|
87
|
+
Also the enrolled-client display labels (`key-map/client-labels.json`) and
|
|
88
|
+
their WAS-backed store. Also the client-key record codec: the contents and
|
|
86
89
|
strict validation of the local record each wallet client keeps its own key
|
|
87
90
|
material in (storage and wrapping stay app-side).
|
|
88
91
|
|
|
@@ -4,11 +4,16 @@
|
|
|
4
4
|
/**
|
|
5
5
|
* Collection encryption-descriptor acquisition: reading a collection's
|
|
6
6
|
* `CollectionEncryption` descriptor (its key-epoch roster) from the Collection
|
|
7
|
-
* Description, caching each success, and falling back to the cached copy
|
|
8
|
-
* the description
|
|
9
|
-
* must keep encrypting under its current
|
|
10
|
-
*
|
|
11
|
-
*
|
|
7
|
+
* Description, caching each success, and falling back to the cached copy
|
|
8
|
+
* whenever the description yields no descriptor -- whether it could not be
|
|
9
|
+
* fetched at all (offline, a collection must keep encrypting under its current
|
|
10
|
+
* epoch) or came back empty (WAS masks an unauthorized read as an absent one,
|
|
11
|
+
* so an empty description is ambiguous, never an authoritative "no
|
|
12
|
+
* encryption"). `undefined` therefore means only this: nothing, fetched or
|
|
13
|
+
* cached, describes this collection's encryption -- a plaintext collection, or
|
|
14
|
+
* an encrypted one whose epoch[0] install has not landed. A caller that has
|
|
15
|
+
* declared the collection encrypted must refuse fail-closed rather than
|
|
16
|
+
* encrypt without a roster.
|
|
12
17
|
*
|
|
13
18
|
* The two seams are deliberately narrow, so a wallet app's own classes satisfy
|
|
14
19
|
* them structurally -- no adapter needed. An {@link EncryptionDescriptorSource}
|
|
@@ -20,9 +25,11 @@
|
|
|
20
25
|
import type { CollectionEncryption, WasClient } from '@interop/was-client';
|
|
21
26
|
/**
|
|
22
27
|
* Where descriptors come from: one signed read of the collection's
|
|
23
|
-
* Description. Resolves `undefined`
|
|
24
|
-
*
|
|
25
|
-
*
|
|
28
|
+
* Description. Resolves `undefined` when the description carries no encryption
|
|
29
|
+
* member -- which a WAS host also serves for a read this client is not
|
|
30
|
+
* authorized to make, so the absence is ambiguous and callers fall back to a
|
|
31
|
+
* cached copy just as they do for a thrown fetch. Network errors throw through
|
|
32
|
+
* (callers treat the fetch as best-effort).
|
|
26
33
|
*/
|
|
27
34
|
export interface EncryptionDescriptorSource {
|
|
28
35
|
collectionEncryption(options: {
|
|
@@ -59,11 +66,12 @@ export declare function wasDescriptorSource({ was, spaceId }: {
|
|
|
59
66
|
}): EncryptionDescriptorSource;
|
|
60
67
|
/**
|
|
61
68
|
* Acquires one collection's descriptor: fetches it from the source, caching a
|
|
62
|
-
* success; falls back to the cached copy
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
69
|
+
* success; falls back to the cached copy whenever the fetch yields no
|
|
70
|
+
* descriptor (it threw, or it came back empty -- a masked 404 for an
|
|
71
|
+
* unauthorized read looks exactly like an unencrypted collection); and with no
|
|
72
|
+
* source at all (a purely local code path) reads the cache alone. Any cached
|
|
73
|
+
* copy is deliberately left in place, never cleared by an empty fetch.
|
|
74
|
+
* `undefined` means no descriptor exists anywhere for this collection.
|
|
67
75
|
*
|
|
68
76
|
* @param options {object}
|
|
69
77
|
* @param [options.source] {EncryptionDescriptorSource} omit for cache-only
|
|
@@ -71,8 +79,8 @@ export declare function wasDescriptorSource({ was, spaceId }: {
|
|
|
71
79
|
* @param options.cache {EncryptionDescriptorCache}
|
|
72
80
|
* @param options.collectionId {string}
|
|
73
81
|
* @param [options.onFetchError] {function} observes a swallowed fetch
|
|
74
|
-
* failure (the
|
|
75
|
-
* through
|
|
82
|
+
* failure (the thrown-fetch branch only; an empty description is not an
|
|
83
|
+
* error). Errors from the cache itself throw through
|
|
76
84
|
* @returns {Promise<CollectionEncryption | undefined>}
|
|
77
85
|
*/
|
|
78
86
|
export declare function acquireDescriptor({ source, cache, collectionId, onFetchError }: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acquire.d.ts","sourceRoot":"","sources":["../../src/descriptors/acquire.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"acquire.d.ts","sourceRoot":"","sources":["../../src/descriptors/acquire.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAE1E;;;;;;;GAOG;AACH,MAAM,WAAW,0BAA0B;IACzC,oBAAoB,CAAC,OAAO,EAAE;QAC5B,YAAY,EAAE,MAAM,CAAA;KACrB,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAAA;CAC9C;AAED;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACxC,cAAc,CAAC,OAAO,EAAE;QACtB,YAAY,EAAE,MAAM,CAAA;KACrB,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAAA;IAC7C,eAAe,CAAC,OAAO,EAAE;QACvB,YAAY,EAAE,MAAM,CAAA;QACpB,UAAU,EAAE,oBAAoB,CAAA;KACjC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAClB;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,GAAG,EACH,OAAO,EACR,EAAE;IACD,GAAG,EAAE,SAAS,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;CAChB,GAAG,0BAA0B,CAU7B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,MAAM,EACN,KAAK,EACL,YAAY,EACZ,YAAY,EACb,EAAE;IACD,MAAM,CAAC,EAAE,0BAA0B,CAAA;IACnC,KAAK,EAAE,yBAAyB,CAAA;IAChC,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;CACtE,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAiB5C;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,kBAAkB,CAAC,EACvC,MAAM,EACN,KAAK,EACL,aAAa,EACb,YAAY,EACb,EAAE;IACD,MAAM,CAAC,EAAE,0BAA0B,CAAA;IACnC,KAAK,EAAE,yBAAyB,CAAA;IAChC,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;CACtE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAiBhD"}
|
|
@@ -21,11 +21,12 @@ export function wasDescriptorSource({ was, spaceId }) {
|
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
23
23
|
* Acquires one collection's descriptor: fetches it from the source, caching a
|
|
24
|
-
* success; falls back to the cached copy
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
24
|
+
* success; falls back to the cached copy whenever the fetch yields no
|
|
25
|
+
* descriptor (it threw, or it came back empty -- a masked 404 for an
|
|
26
|
+
* unauthorized read looks exactly like an unencrypted collection); and with no
|
|
27
|
+
* source at all (a purely local code path) reads the cache alone. Any cached
|
|
28
|
+
* copy is deliberately left in place, never cleared by an empty fetch.
|
|
29
|
+
* `undefined` means no descriptor exists anywhere for this collection.
|
|
29
30
|
*
|
|
30
31
|
* @param options {object}
|
|
31
32
|
* @param [options.source] {EncryptionDescriptorSource} omit for cache-only
|
|
@@ -33,8 +34,8 @@ export function wasDescriptorSource({ was, spaceId }) {
|
|
|
33
34
|
* @param options.cache {EncryptionDescriptorCache}
|
|
34
35
|
* @param options.collectionId {string}
|
|
35
36
|
* @param [options.onFetchError] {function} observes a swallowed fetch
|
|
36
|
-
* failure (the
|
|
37
|
-
* through
|
|
37
|
+
* failure (the thrown-fetch branch only; an empty description is not an
|
|
38
|
+
* error). Errors from the cache itself throw through
|
|
38
39
|
* @returns {Promise<CollectionEncryption | undefined>}
|
|
39
40
|
*/
|
|
40
41
|
export async function acquireDescriptor({ source, cache, collectionId, onFetchError }) {
|
|
@@ -47,7 +48,9 @@ export async function acquireDescriptor({ source, cache, collectionId, onFetchEr
|
|
|
47
48
|
await cache.writeDescriptor({ collectionId, descriptor: fetched });
|
|
48
49
|
return fetched;
|
|
49
50
|
}
|
|
50
|
-
|
|
51
|
+
// Empty description: not authoritative (an unauthorized read is masked as
|
|
52
|
+
// an absent one), so a warm cache still serves the collection.
|
|
53
|
+
return cache.readDescriptor({ collectionId });
|
|
51
54
|
}
|
|
52
55
|
catch (err) {
|
|
53
56
|
onFetchError?.(err, { collectionId });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acquire.js","sourceRoot":"","sources":["../../src/descriptors/acquire.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"acquire.js","sourceRoot":"","sources":["../../src/descriptors/acquire.ts"],"names":[],"mappings":"AAuDA;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAClC,GAAG,EACH,OAAO,EAIR;IACC,OAAO;QACL,KAAK,CAAC,oBAAoB,CAAC,EAAE,YAAY,EAAE;YACzC,MAAM,WAAW,GAAG,MAAM,GAAG;iBAC1B,KAAK,CAAC,OAAO,CAAC;iBACd,UAAU,CAAC,YAAY,CAAC;iBACxB,QAAQ,EAAE,CAAA;YACb,OAAO,WAAW,EAAE,UAAU,IAAI,SAAS,CAAA;QAC7C,CAAC;KACF,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,EACtC,MAAM,EACN,KAAK,EACL,YAAY,EACZ,YAAY,EAMb;IACC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,KAAK,CAAC,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC,CAAA;IAC/C,CAAC;IACD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,EAAE,YAAY,EAAE,CAAC,CAAA;QACnE,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,KAAK,CAAC,eAAe,CAAC,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAA;YAClE,OAAO,OAAO,CAAA;QAChB,CAAC;QACD,0EAA0E;QAC1E,+DAA+D;QAC/D,OAAO,KAAK,CAAC,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC,CAAA;IAC/C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,YAAY,EAAE,CAAC,GAAG,EAAE,EAAE,YAAY,EAAE,CAAC,CAAA;QACrC,OAAO,KAAK,CAAC,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC,CAAA;IAC/C,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,EACvC,MAAM,EACN,KAAK,EACL,aAAa,EACb,YAAY,EAMb;IACC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAChC,aAAa,CAAC,GAAG,CACf,KAAK,EAAC,YAAY,EAAC,EAAE,CACnB;QACE,YAAY;QACZ,MAAM,iBAAiB,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;KAC9D,CACb,CACF,CAAA;IACD,MAAM,WAAW,GAAyC,EAAE,CAAA;IAC5D,KAAK,MAAM,CAAC,YAAY,EAAE,UAAU,CAAC,IAAI,QAAQ,EAAE,CAAC;QAClD,IAAI,UAAU,EAAE,CAAC;YACf,WAAW,CAAC,YAAY,CAAC,GAAG,UAAU,CAAA;QACxC,CAAC;IACH,CAAC;IACD,OAAO,WAAW,CAAA;AACpB,CAAC"}
|
|
@@ -8,14 +8,20 @@
|
|
|
8
8
|
* conflict resolver) rather than a row-scanning store.
|
|
9
9
|
*
|
|
10
10
|
* Built, the cipher acquires the collection's descriptor (fetch, cache the
|
|
11
|
-
* success, cached fallback
|
|
11
|
+
* success, cached fallback whenever the fetch yields none -- see
|
|
12
|
+
* `acquire.ts`) and constructs the
|
|
12
13
|
* underlying EDV cipher from it; with no descriptor, or a descriptor with no
|
|
13
|
-
* epochs,
|
|
14
|
+
* epochs, the build refuses fail-closed (every encrypted collection's
|
|
15
|
+
* descriptor carries an epoch roster from provisioning, so the absence can
|
|
16
|
+
* only mean the install has not landed or the host is lying). When a decrypt
|
|
17
|
+
* throws
|
|
14
18
|
* `UnknownEpochError`, the cipher re-acquires the descriptor, rebuilds itself,
|
|
15
19
|
* and retries that decrypt exactly once -- and only once per cipher instance,
|
|
16
20
|
* which the host scopes to one `(profile, collection)` session by dropping
|
|
17
21
|
* its cipher cache when the session ends. A second failure (or any unknown
|
|
18
|
-
* epoch after the one refresh is spent) propagates.
|
|
22
|
+
* epoch after the one refresh is spent) propagates. A refresh that itself
|
|
23
|
+
* fails does not count as spent -- the original `UnknownEpochError` is
|
|
24
|
+
* rethrown and a later decrypt may try again.
|
|
19
25
|
*/
|
|
20
26
|
import type { IKeyAgreementKey, IKeyResolver } from '@interop/data-integrity-core';
|
|
21
27
|
import { type DocCipher } from '@interop/was-client/edv';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cipher.d.ts","sourceRoot":"","sources":["../../src/descriptors/cipher.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"cipher.d.ts","sourceRoot":"","sources":["../../src/descriptors/cipher.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACb,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAGL,KAAK,SAAS,EACf,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAEL,KAAK,yBAAyB,EAC9B,KAAK,0BAA0B,EAChC,MAAM,cAAc,CAAA;AAErB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,4BAA4B,CAAC,EACjD,eAAe,EACf,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,MAAM,EACN,KAAK,EACL,YAAY,EACb,EAAE;IACD,eAAe,EAAE,gBAAgB,CAAA;IACjC,WAAW,EAAE,YAAY,CAAA;IACzB,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAA;IACnC,MAAM,CAAC,EAAE,0BAA0B,CAAA;IACnC,KAAK,EAAE,yBAAyB,CAAA;IAChC,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;CACtE,GAAG,OAAO,CAAC,SAAS,CAAC,CAoFrB"}
|
|
@@ -23,18 +23,26 @@ import { acquireDescriptor } from './acquire.js';
|
|
|
23
23
|
* @returns {Promise<DocCipher>}
|
|
24
24
|
*/
|
|
25
25
|
export async function createRefreshingEdvDocCipher({ keyAgreementKey, keyResolver, collectionId, idDerivation, source, cache, onFetchError }) {
|
|
26
|
-
const build = async () =>
|
|
27
|
-
|
|
28
|
-
keyResolver,
|
|
29
|
-
collectionId,
|
|
30
|
-
idDerivation,
|
|
31
|
-
encryption: await acquireDescriptor({
|
|
26
|
+
const build = async () => {
|
|
27
|
+
const encryption = await acquireDescriptor({
|
|
32
28
|
source,
|
|
33
29
|
cache,
|
|
34
30
|
collectionId,
|
|
35
31
|
onFetchError
|
|
36
|
-
})
|
|
37
|
-
|
|
32
|
+
});
|
|
33
|
+
if (!encryption) {
|
|
34
|
+
throw new Error(`Collection "${collectionId}" has no encryption descriptor available ` +
|
|
35
|
+
'(fetched or cached). Every encrypted collection carries its key ' +
|
|
36
|
+
'epochs from provisioning; refusing to build a cipher without them.');
|
|
37
|
+
}
|
|
38
|
+
return createEdvDocCipher({
|
|
39
|
+
keyAgreementKey,
|
|
40
|
+
keyResolver,
|
|
41
|
+
collectionId,
|
|
42
|
+
idDerivation,
|
|
43
|
+
encryption
|
|
44
|
+
});
|
|
45
|
+
};
|
|
38
46
|
let inner = await build();
|
|
39
47
|
// The one descriptor refresh this cipher instance (= this collection this
|
|
40
48
|
// session) may spend, shared so concurrent unknown-epoch decrypts ride a
|
|
@@ -56,10 +64,33 @@ export async function createRefreshingEdvDocCipher({ keyAgreementKey, keyResolve
|
|
|
56
64
|
if (!(err instanceof UnknownEpochError) || !source) {
|
|
57
65
|
throw err;
|
|
58
66
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
67
|
+
if (!refreshed) {
|
|
68
|
+
const attempt = build().then(cipher => {
|
|
69
|
+
inner = cipher;
|
|
70
|
+
});
|
|
71
|
+
refreshed = attempt;
|
|
72
|
+
// Only a COMPLETED refresh is spent. A rejected one (the description
|
|
73
|
+
// could not be read and no cached copy answered either) un-arms the
|
|
74
|
+
// guard so a later unknown-epoch decrypt may try again; a successful
|
|
75
|
+
// refresh that still cannot route the envelope stays spent for the
|
|
76
|
+
// session, which is what keeps a genuinely foreign envelope from
|
|
77
|
+
// driving a refetch loop.
|
|
78
|
+
attempt.catch(() => {
|
|
79
|
+
if (refreshed === attempt) {
|
|
80
|
+
refreshed = null;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
await refreshed;
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// The refresh failed, so nothing was learned about this envelope's
|
|
89
|
+
// epoch: surface the original UnknownEpochError rather than the
|
|
90
|
+
// build failure, so callers classifying on it (the create-loss
|
|
91
|
+
// re-mint) still see the row they exist to repair.
|
|
92
|
+
throw err;
|
|
93
|
+
}
|
|
63
94
|
// One retry under the swapped cipher. If the refresh was already
|
|
64
95
|
// spent before this decrypt began, this re-attempt is a local
|
|
65
96
|
// no-network decrypt that fails the same way -- so a genuinely
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cipher.js","sourceRoot":"","sources":["../../src/descriptors/cipher.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cipher.js","sourceRoot":"","sources":["../../src/descriptors/cipher.ts"],"names":[],"mappings":"AA6BA,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EAElB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,iBAAiB,EAGlB,MAAM,cAAc,CAAA;AAErB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAAC,EACjD,eAAe,EACf,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,MAAM,EACN,KAAK,EACL,YAAY,EASb;IACC,MAAM,KAAK,GAAG,KAAK,IAAwB,EAAE;QAC3C,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC;YACzC,MAAM;YACN,KAAK;YACL,YAAY;YACZ,YAAY;SACb,CAAC,CAAA;QACF,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CACb,eAAe,YAAY,2CAA2C;gBACpE,kEAAkE;gBAClE,oEAAoE,CACvE,CAAA;QACH,CAAC;QACD,OAAO,kBAAkB,CAAC;YACxB,eAAe;YACf,WAAW;YACX,YAAY;YACZ,YAAY;YACZ,UAAU;SACX,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,IAAI,KAAK,GAAG,MAAM,KAAK,EAAE,CAAA;IACzB,0EAA0E;IAC1E,yEAAyE;IACzE,+CAA+C;IAC/C,IAAI,SAAS,GAAyB,IAAI,CAAA;IAE1C,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAE1C,aAAa,EAAE,OAAO,CAAC,EAAE;YACvB,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;gBACzB,MAAM,IAAI,KAAK,CACb,eAAe,YAAY,kCAAkC,CAC9D,CAAA;YACH,CAAC;YACD,OAAO,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;QACrC,CAAC;QAED,KAAK,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE;YACxB,IAAI,CAAC;gBACH,OAAO,MAAM,KAAK,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAA;YAC1C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,CAAC,GAAG,YAAY,iBAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;oBACnD,MAAM,GAAG,CAAA;gBACX,CAAC;gBACD,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,MAAM,OAAO,GAAG,KAAK,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;wBACpC,KAAK,GAAG,MAAM,CAAA;oBAChB,CAAC,CAAC,CAAA;oBACF,SAAS,GAAG,OAAO,CAAA;oBACnB,qEAAqE;oBACrE,oEAAoE;oBACpE,qEAAqE;oBACrE,mEAAmE;oBACnE,iEAAiE;oBACjE,0BAA0B;oBAC1B,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE;wBACjB,IAAI,SAAS,KAAK,OAAO,EAAE,CAAC;4BAC1B,SAAS,GAAG,IAAI,CAAA;wBAClB,CAAC;oBACH,CAAC,CAAC,CAAA;gBACJ,CAAC;gBACD,IAAI,CAAC;oBACH,MAAM,SAAS,CAAA;gBACjB,CAAC;gBAAC,MAAM,CAAC;oBACP,mEAAmE;oBACnE,gEAAgE;oBAChE,+DAA+D;oBAC/D,mDAAmD;oBACnD,MAAM,GAAG,CAAA;gBACX,CAAC;gBACD,iEAAiE;gBACjE,8DAA8D;gBAC9D,+DAA+D;gBAC/D,iEAAiE;gBACjE,2BAA2B;gBAC3B,OAAO,KAAK,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAA;YACpC,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -15,8 +15,12 @@
|
|
|
15
15
|
* - `wasDescriptorSource` -- the `EncryptionDescriptorSource` over a
|
|
16
16
|
* was-client handle.
|
|
17
17
|
* - `acquireDescriptor` / `acquireDescriptors` -- fetch + cache with the
|
|
18
|
-
* cached fallback
|
|
19
|
-
* under its current epoch;
|
|
18
|
+
* cached fallback whenever the fetch yields no descriptor, thrown or empty
|
|
19
|
+
* (offline, a collection keeps encrypting under its current epoch; an empty
|
|
20
|
+
* description is ambiguous, since WAS masks an unauthorized read as an
|
|
21
|
+
* absent one). No descriptor anywhere means a plaintext collection, or an
|
|
22
|
+
* encrypted one whose epoch[0] install has not landed -- which a caller that
|
|
23
|
+
* has declared the collection encrypted must refuse fail-closed.
|
|
20
24
|
* - `DescriptorRefreshPolicy` -- the once-per-collection-per-session
|
|
21
25
|
* unknown-epoch refresh guard, plus the refresh-and-re-read-once wrapper
|
|
22
26
|
* for hosts whose reads scan rows and count unknown-epoch skips.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/descriptors/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/descriptors/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,cAAc,CAAA;AACrB,YAAY,EACV,yBAAyB,EACzB,0BAA0B,EAC3B,MAAM,cAAc,CAAA;AAErB,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAA;AAEtD,OAAO,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAA"}
|
|
@@ -15,8 +15,12 @@
|
|
|
15
15
|
* - `wasDescriptorSource` -- the `EncryptionDescriptorSource` over a
|
|
16
16
|
* was-client handle.
|
|
17
17
|
* - `acquireDescriptor` / `acquireDescriptors` -- fetch + cache with the
|
|
18
|
-
* cached fallback
|
|
19
|
-
* under its current epoch;
|
|
18
|
+
* cached fallback whenever the fetch yields no descriptor, thrown or empty
|
|
19
|
+
* (offline, a collection keeps encrypting under its current epoch; an empty
|
|
20
|
+
* description is ambiguous, since WAS masks an unauthorized read as an
|
|
21
|
+
* absent one). No descriptor anywhere means a plaintext collection, or an
|
|
22
|
+
* encrypted one whose epoch[0] install has not landed -- which a caller that
|
|
23
|
+
* has declared the collection encrypted must refuse fail-closed.
|
|
20
24
|
* - `DescriptorRefreshPolicy` -- the once-per-collection-per-session
|
|
21
25
|
* unknown-epoch refresh guard, plus the refresh-and-re-read-once wrapper
|
|
22
26
|
* for hosts whose reads scan rows and count unknown-epoch skips.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/descriptors/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/descriptors/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,cAAc,CAAA;AAMrB,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAA;AAEtD,OAAO,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAA"}
|
package/dist/keyring/index.d.ts
CHANGED
|
@@ -10,8 +10,13 @@
|
|
|
10
10
|
* wire-level unlock derivation (implemented over `@noble/hashes`, so it runs
|
|
11
11
|
* unchanged where WebCrypto's `deriveBits` is unavailable) and the unlock
|
|
12
12
|
* Space addressing convention.
|
|
13
|
-
* - `wrapKeyringRecord` / `unwrapKeyringRecord` -- the
|
|
14
|
-
* account-pointer record codec.
|
|
13
|
+
* - `wrapKeyringRecord` / `unwrapKeyringRecord` -- the
|
|
14
|
+
* `{ version, encryption, wrapped }` account-pointer record codec.
|
|
15
|
+
* - `mintRecordEncryption` / `recordCipher` / `parseRecordFrame` -- the
|
|
16
|
+
* record-own-epoch envelope construction the codec seals with plus the frame
|
|
17
|
+
* validation it opens with, exported so an app's own locally stored records
|
|
18
|
+
* seal and unseal the same way (under their own cipher context) rather than
|
|
19
|
+
* re-deriving the construction.
|
|
15
20
|
* - `ensureUnlockSpace` / `getUnlockKeyring` / `putUnlockKeyring` /
|
|
16
21
|
* `deleteUnlockSpace` / `deleteUnlockSpaceWithCapability` -- the unlock
|
|
17
22
|
* Space's lifecycle and its one resource.
|
|
@@ -23,7 +28,7 @@
|
|
|
23
28
|
*/
|
|
24
29
|
export { deriveUnlockIdentity, KEYRING_KDF, UNLOCK_HANDLE, UNLOCK_KEY_NAME, unlockSpaceIdFor } from './kdf.js';
|
|
25
30
|
export type { UnlockIdentity, UnlockKdf } from './kdf.js';
|
|
26
|
-
export { KEYRING_RECORD_VERSION, parseRecordPointer, unwrapKeyringRecord, wrapKeyringRecord } from './record.js';
|
|
31
|
+
export { KEYRING_RECORD_VERSION, mintRecordEncryption, parseRecordFrame, parseRecordPointer, recordCipher, unwrapKeyringRecord, wrapKeyringRecord } from './record.js';
|
|
27
32
|
export type { AccountPointer, KeyringRecordContents } from './record.js';
|
|
28
33
|
export { deleteUnlockSpace, deleteUnlockSpaceWithCapability, ensureUnlockSpace, getUnlockKeyring, putUnlockKeyring, putUnlockKeyringWithCapability, UNLOCK_SPACE_NAME } from './unlockSpace.js';
|
|
29
34
|
export { fetchKeyringRecord } from './fetch.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/keyring/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/keyring/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EACL,oBAAoB,EACpB,WAAW,EACX,aAAa,EACb,eAAe,EACf,gBAAgB,EACjB,MAAM,UAAU,CAAA;AACjB,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEzD,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAExE,OAAO,EACL,iBAAiB,EACjB,+BAA+B,EAC/B,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,8BAA8B,EAC9B,iBAAiB,EAClB,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA"}
|
package/dist/keyring/index.js
CHANGED
|
@@ -10,8 +10,13 @@
|
|
|
10
10
|
* wire-level unlock derivation (implemented over `@noble/hashes`, so it runs
|
|
11
11
|
* unchanged where WebCrypto's `deriveBits` is unavailable) and the unlock
|
|
12
12
|
* Space addressing convention.
|
|
13
|
-
* - `wrapKeyringRecord` / `unwrapKeyringRecord` -- the
|
|
14
|
-
* account-pointer record codec.
|
|
13
|
+
* - `wrapKeyringRecord` / `unwrapKeyringRecord` -- the
|
|
14
|
+
* `{ version, encryption, wrapped }` account-pointer record codec.
|
|
15
|
+
* - `mintRecordEncryption` / `recordCipher` / `parseRecordFrame` -- the
|
|
16
|
+
* record-own-epoch envelope construction the codec seals with plus the frame
|
|
17
|
+
* validation it opens with, exported so an app's own locally stored records
|
|
18
|
+
* seal and unseal the same way (under their own cipher context) rather than
|
|
19
|
+
* re-deriving the construction.
|
|
15
20
|
* - `ensureUnlockSpace` / `getUnlockKeyring` / `putUnlockKeyring` /
|
|
16
21
|
* `deleteUnlockSpace` / `deleteUnlockSpaceWithCapability` -- the unlock
|
|
17
22
|
* Space's lifecycle and its one resource.
|
|
@@ -22,7 +27,7 @@
|
|
|
22
27
|
* was-client dependency graph (the same isolation pattern as `./identity`).
|
|
23
28
|
*/
|
|
24
29
|
export { deriveUnlockIdentity, KEYRING_KDF, UNLOCK_HANDLE, UNLOCK_KEY_NAME, unlockSpaceIdFor } from './kdf.js';
|
|
25
|
-
export { KEYRING_RECORD_VERSION, parseRecordPointer, unwrapKeyringRecord, wrapKeyringRecord } from './record.js';
|
|
30
|
+
export { KEYRING_RECORD_VERSION, mintRecordEncryption, parseRecordFrame, parseRecordPointer, recordCipher, unwrapKeyringRecord, wrapKeyringRecord } from './record.js';
|
|
26
31
|
export { deleteUnlockSpace, deleteUnlockSpaceWithCapability, ensureUnlockSpace, getUnlockKeyring, putUnlockKeyring, putUnlockKeyringWithCapability, UNLOCK_SPACE_NAME } from './unlockSpace.js';
|
|
27
32
|
export { fetchKeyringRecord } from './fetch.js';
|
|
28
33
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/keyring/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/keyring/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EACL,oBAAoB,EACpB,WAAW,EACX,aAAa,EACb,eAAe,EACf,gBAAgB,EACjB,MAAM,UAAU,CAAA;AAGjB,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,aAAa,CAAA;AAGpB,OAAO,EACL,iBAAiB,EACjB,+BAA+B,EAC/B,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,8BAA8B,EAC9B,iBAAiB,EAClB,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA"}
|
package/dist/keyring/record.d.ts
CHANGED
|
@@ -2,24 +2,93 @@
|
|
|
2
2
|
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
|
-
* The keyring record codec: the `{ version, wrapped }` envelope
|
|
6
|
-
* one resource of an account's unlock Space. Its plaintext
|
|
7
|
-
* controller, the email captured at bind time, and the
|
|
8
|
-
* deliberately no key material of any kind, so the
|
|
9
|
-
* without authorizing anything against it.
|
|
5
|
+
* The keyring record codec: the `{ version, encryption, wrapped }` envelope
|
|
6
|
+
* stored as the one resource of an account's unlock Space. Its plaintext
|
|
7
|
+
* carries the account controller, the email captured at bind time, and the
|
|
8
|
+
* account pointer -- and deliberately no key material of any kind, so the
|
|
9
|
+
* record locates an account without authorizing anything against it.
|
|
10
10
|
*
|
|
11
|
-
* The wrap is an EDV document envelope under the
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* The wrap is an EDV document envelope sealed under the record's own key
|
|
12
|
+
* epoch: every EDV envelope seals to an epoch key, so the record carries its
|
|
13
|
+
* one-epoch descriptor in its `encryption` member, epoch[0] wrapped to the
|
|
14
|
+
* unlock key-agreement key. The record stays self-contained -- unlock KAK in,
|
|
15
|
+
* contents out. The cipher's `keyring` collection context labels errors only
|
|
16
|
+
* (the codec is agnostic to it); what keeps a swapped-in foreign record from
|
|
17
|
+
* being accepted is the contents validation on unwrap, not the cipher.
|
|
14
18
|
*/
|
|
15
19
|
import type { IKeyAgreementKey, IKeyResolver } from '@interop/data-integrity-core';
|
|
20
|
+
import type { CollectionEncryption } from '@interop/was-client';
|
|
21
|
+
import { type DocCipher } from '@interop/was-client/edv';
|
|
16
22
|
/**
|
|
17
|
-
* The version stamped on the stored `{ version, wrapped }` keyring
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* re-provisioned, not migrated.
|
|
23
|
+
* The version stamped on the stored `{ version, encryption, wrapped }` keyring
|
|
24
|
+
* envelope: the record whose envelope seals under the record's own key epoch
|
|
25
|
+
* (the `encryption` member). Any other version is refused as unusable -- such
|
|
26
|
+
* accounts are re-provisioned, not migrated.
|
|
21
27
|
*/
|
|
22
|
-
export declare const KEYRING_RECORD_VERSION =
|
|
28
|
+
export declare const KEYRING_RECORD_VERSION = 1;
|
|
29
|
+
/**
|
|
30
|
+
* Mints the one-epoch descriptor a fresh record is sealed under: epoch[0]
|
|
31
|
+
* wrapped to the given KAK alone, built through `initRecipients` against a
|
|
32
|
+
* throwaway in-memory store (the descriptor's home is the record itself).
|
|
33
|
+
* Exported for any consumer sealing a self-contained
|
|
34
|
+
* `{ version, encryption, wrapped }` record -- the keyring and recovery
|
|
35
|
+
* records here, and a wallet app's own locally stored records (e.g.
|
|
36
|
+
* freewallet's client-key record and unlock-methods registry).
|
|
37
|
+
*
|
|
38
|
+
* @param options {object}
|
|
39
|
+
* @param options.keyAgreementKey {IKeyAgreementKey} the wrapping KAK (for
|
|
40
|
+
* the keyring record, the unlock KAK)
|
|
41
|
+
* @returns {Promise<CollectionEncryption>}
|
|
42
|
+
*/
|
|
43
|
+
export declare function mintRecordEncryption({ keyAgreementKey }: {
|
|
44
|
+
keyAgreementKey: IKeyAgreementKey;
|
|
45
|
+
}): Promise<CollectionEncryption>;
|
|
46
|
+
/**
|
|
47
|
+
* Builds the record cipher: an EDV cipher over the record's own descriptor.
|
|
48
|
+
* Shared by the wrap and unwrap paths (and by the recovery record, which
|
|
49
|
+
* reuses the keyring cipher context verbatim); an app's own record kind
|
|
50
|
+
* passes its own `collectionId` so its failures name the record kind. The
|
|
51
|
+
* context labels errors only -- the codec is agnostic to it, so a record
|
|
52
|
+
* kind's real swap protection is its contents validation on unwrap.
|
|
53
|
+
*
|
|
54
|
+
* @param options {object}
|
|
55
|
+
* @param options.keyAgreementKey {IKeyAgreementKey} the wrapping KAK (for
|
|
56
|
+
* the keyring record, the unlock KAK)
|
|
57
|
+
* @param options.keyResolver {IKeyResolver}
|
|
58
|
+
* @param options.encryption {CollectionEncryption} the record's descriptor
|
|
59
|
+
* @param [options.collectionId] {string} the cipher context failures are
|
|
60
|
+
* labeled with; defaults to the keyring context
|
|
61
|
+
* @returns {Promise<DocCipher>}
|
|
62
|
+
*/
|
|
63
|
+
export declare function recordCipher({ keyAgreementKey, keyResolver, encryption, collectionId }: {
|
|
64
|
+
keyAgreementKey: IKeyAgreementKey;
|
|
65
|
+
keyResolver: IKeyResolver;
|
|
66
|
+
encryption: CollectionEncryption;
|
|
67
|
+
collectionId?: string;
|
|
68
|
+
}): Promise<DocCipher>;
|
|
69
|
+
/**
|
|
70
|
+
* Validates the common `{ version, encryption, wrapped }` frame of a stored
|
|
71
|
+
* record (keyring or recovery -- `label` names the refusals) and returns its
|
|
72
|
+
* members. Exported so an app's own record kinds open their records through
|
|
73
|
+
* the same frame validation the codec here seals with, rather than re-deriving
|
|
74
|
+
* the version and shape checks.
|
|
75
|
+
*
|
|
76
|
+
* @param options {object}
|
|
77
|
+
* @param options.record {unknown}
|
|
78
|
+
* @param options.label {string} `'keyring'`, `'recovery'`, or an app record
|
|
79
|
+
* kind's own label
|
|
80
|
+
* @param [options.version] {number} the version the frame must carry;
|
|
81
|
+
* defaults to the keyring record version
|
|
82
|
+
* @returns {{ encryption: CollectionEncryption, wrapped: unknown }}
|
|
83
|
+
*/
|
|
84
|
+
export declare function parseRecordFrame({ record, label, version }: {
|
|
85
|
+
record: unknown;
|
|
86
|
+
label: string;
|
|
87
|
+
version?: number;
|
|
88
|
+
}): {
|
|
89
|
+
encryption: CollectionEncryption;
|
|
90
|
+
wrapped: unknown;
|
|
91
|
+
};
|
|
23
92
|
/**
|
|
24
93
|
* The account pointer a keyring record carries in place of the retired data
|
|
25
94
|
* seed: where the account lives (`spaceId` + `host`, the WAS server origin)
|
|
@@ -45,8 +114,9 @@ export interface KeyringRecordContents {
|
|
|
45
114
|
}
|
|
46
115
|
/**
|
|
47
116
|
* Wraps the account-pointer contents into a keyring record: the controller,
|
|
48
|
-
* email, and pointer (+ timestamp)
|
|
49
|
-
*
|
|
117
|
+
* email, and pointer (+ timestamp) sealed under a freshly minted record epoch
|
|
118
|
+
* whose key is wrapped to the unlock KAK. Deliberately carries no key material
|
|
119
|
+
* of any kind.
|
|
50
120
|
*
|
|
51
121
|
* @param options {object}
|
|
52
122
|
* @param options.controller {string} the account did:key
|
|
@@ -55,7 +125,8 @@ export interface KeyringRecordContents {
|
|
|
55
125
|
* no-WAS deployments)
|
|
56
126
|
* @param options.keyAgreementKey {IKeyAgreementKey} the unlock KAK
|
|
57
127
|
* @param options.keyResolver {IKeyResolver}
|
|
58
|
-
* @returns {Promise<{ version: number,
|
|
128
|
+
* @returns {Promise<{ version: number, encryption: CollectionEncryption,
|
|
129
|
+
* wrapped: unknown }>}
|
|
59
130
|
*/
|
|
60
131
|
export declare function wrapKeyringRecord({ controller, email, pointer, keyAgreementKey, keyResolver }: {
|
|
61
132
|
controller: string;
|
|
@@ -65,12 +136,12 @@ export declare function wrapKeyringRecord({ controller, email, pointer, keyAgree
|
|
|
65
136
|
keyResolver: IKeyResolver;
|
|
66
137
|
}): Promise<{
|
|
67
138
|
version: number;
|
|
139
|
+
encryption: CollectionEncryption;
|
|
68
140
|
wrapped: unknown;
|
|
69
141
|
}>;
|
|
70
142
|
/**
|
|
71
143
|
* Unwraps and validates a keyring record. Rejects a record whose `version` is
|
|
72
|
-
* not the current one (
|
|
73
|
-
* seed and are refused -- accounts are re-provisioned, not migrated), and
|
|
144
|
+
* not the current one (accounts are re-provisioned, not migrated), and
|
|
74
145
|
* sanity-checks the decrypted plaintext (non-empty controller, well-formed
|
|
75
146
|
* pointer when present).
|
|
76
147
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../../src/keyring/record.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../../src/keyring/record.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACb,MAAM,8BAA8B,CAAA;AACrC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC/D,OAAO,EAIL,KAAK,SAAS,EAEf,MAAM,yBAAyB,CAAA;AAGhC;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,IAAI,CAAA;AAEvC;;;;;;;;;;;;;GAaG;AACH,wBAAsB,oBAAoB,CAAC,EACzC,eAAe,EAChB,EAAE;IACD,eAAe,EAAE,gBAAgB,CAAA;CAClC,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAiBhC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,YAAY,CAAC,EACjC,eAAe,EACf,WAAW,EACX,UAAU,EACV,YAAoC,EACrC,EAAE;IACD,eAAe,EAAE,gBAAgB,CAAA;IACjC,WAAW,EAAE,YAAY,CAAA;IACzB,UAAU,EAAE,oBAAoB,CAAA;IAChC,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,GAAG,OAAO,CAAC,SAAS,CAAC,CAOrB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EACN,KAAK,EACL,OAAgC,EACjC,EAAE;IACD,MAAM,EAAE,OAAO,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,GAAG;IAAE,UAAU,EAAE,oBAAoB,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAoCzD;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,cAAc,CAAA;CACzB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,UAAU,EACV,KAAK,EACL,OAAO,EACP,eAAe,EACf,WAAW,EACZ,EAAE;IACD,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,cAAc,CAAA;IACxB,eAAe,EAAE,gBAAgB,CAAA;IACjC,WAAW,EAAE,YAAY,CAAA;CAC1B,GAAG,OAAO,CAAC;IACV,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,oBAAoB,CAAA;IAChC,OAAO,EAAE,OAAO,CAAA;CACjB,CAAC,CAwBD;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CAAC,EACxC,MAAM,EACN,eAAe,EACf,WAAW,EACZ,EAAE;IACD,MAAM,EAAE,OAAO,CAAA;IACf,eAAe,EAAE,gBAAgB,CAAA;IACjC,WAAW,EAAE,YAAY,CAAA;CAC1B,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAgCjC;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,GAAG,SAAS,CAsB7E"}
|