@interop/was-react 0.10.0 → 0.11.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 +17 -17
- package/dist/auth/loginFlow.d.ts +2 -2
- package/dist/auth/loginRequest.d.ts +15 -12
- package/dist/auth/loginRequest.d.ts.map +1 -1
- package/dist/auth/loginRequest.js +12 -10
- package/dist/auth/loginRequest.js.map +1 -1
- package/dist/auth/walletRequestTypes.d.ts +3 -2
- package/dist/auth/walletRequestTypes.d.ts.map +1 -1
- package/dist/dev/provisionDevGrants.d.ts +13 -5
- package/dist/dev/provisionDevGrants.d.ts.map +1 -1
- package/dist/dev/provisionDevGrants.js +55 -23
- package/dist/dev/provisionDevGrants.js.map +1 -1
- package/dist/identity/documentLoader.d.ts.map +1 -1
- package/dist/identity/documentLoader.js +9 -2
- package/dist/identity/documentLoader.js.map +1 -1
- package/dist/identity/seedStore.d.ts +15 -4
- package/dist/identity/seedStore.d.ts.map +1 -1
- package/dist/identity/seedStore.js +17 -5
- package/dist/identity/seedStore.js.map +1 -1
- package/dist/session/authStore.d.ts.map +1 -1
- package/dist/session/authStore.js +147 -35
- package/dist/session/authStore.js.map +1 -1
- package/dist/storage/localStore.d.ts +12 -7
- package/dist/storage/localStore.d.ts.map +1 -1
- package/dist/storage/localStore.js +35 -20
- package/dist/storage/localStore.js.map +1 -1
- package/dist/storage/sharedCollectionReader.d.ts +6 -6
- package/dist/storage/sharedCollectionReader.d.ts.map +1 -1
- package/dist/storage/sharedCollectionReader.js +19 -17
- package/dist/storage/sharedCollectionReader.js.map +1 -1
- package/dist/storage/wasSync.d.ts +22 -1
- package/dist/storage/wasSync.d.ts.map +1 -1
- package/dist/storage/wasSync.js +45 -1
- package/dist/storage/wasSync.js.map +1 -1
- package/dist/sync/docCipher.d.ts +44 -17
- package/dist/sync/docCipher.d.ts.map +1 -1
- package/dist/sync/docCipher.js +60 -13
- package/dist/sync/docCipher.js.map +1 -1
- package/dist/sync/index.d.ts +1 -1
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +1 -1
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/syncedDocSchema.js +1 -1
- package/dist/sync/syncedDocSchema.js.map +1 -1
- package/dist/sync/types.d.ts +2 -2
- package/dist/sync/wasSyncPort.js +1 -1
- package/dist/sync/wasSyncPort.js.map +1 -1
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -125,14 +125,14 @@ without them a concurrent multi-device edit falls back to server-wins.
|
|
|
125
125
|
|
|
126
126
|
At login, a public collection is requested from the wallet with the distinct
|
|
127
127
|
`https://w3id.org/byoe#public-collection` descriptor type (private collections
|
|
128
|
-
use `https://w3id.org/byoe#collection`): the wallet provisions it
|
|
129
|
-
a public-read policy, shows a world-readable consent warning, and
|
|
130
|
-
usual read/write capability (public covers only unauthenticated
|
|
131
|
-
stay capability-only). A wallet that predates the descriptor
|
|
132
|
-
unsatisfiable rather than silently provisioning a private
|
|
133
|
-
feature fails closed with older wallets. Publicness is
|
|
134
|
-
by the wallet -- the app itself can never escalate an
|
|
135
|
-
collection to public.
|
|
128
|
+
use `https://w3id.org/byoe#private-collection`): the wallet provisions it
|
|
129
|
+
plaintext with a public-read policy, shows a world-readable consent warning, and
|
|
130
|
+
delegates the usual read/write capability (public covers only unauthenticated
|
|
131
|
+
reads; writes stay capability-only). A wallet that predates the descriptor
|
|
132
|
+
reports the request unsatisfiable rather than silently provisioning a private
|
|
133
|
+
collection, so the feature fails closed with older wallets. Publicness is
|
|
134
|
+
granted at consent time by the wallet -- the app itself can never escalate an
|
|
135
|
+
existing private collection to public.
|
|
136
136
|
|
|
137
137
|
#### Shared (wallet-owned) collections
|
|
138
138
|
|
|
@@ -173,13 +173,13 @@ the same `key` or `id` in each is rejected at store open
|
|
|
173
173
|
(`validateSharedCollections`).
|
|
174
174
|
|
|
175
175
|
At login each shared collection is requested with the distinct
|
|
176
|
-
`https://w3id.org/byoe#shared-collection` descriptor type and the
|
|
177
|
-
action set `SHARED_ACTIONS` (`GET`/`HEAD`) -- an app never asks to
|
|
178
|
-
wallet collection. As with `https://w3id.org/byoe#public-collection`, a
|
|
179
|
-
that predates the type reports the request unsatisfiable and the feature
|
|
180
|
-
closed, which is the point: a share fuses two axes -- the read zcap AND an
|
|
181
|
-
in the collection's key-epoch roster -- and a wallet that granted only the
|
|
182
|
-
would hand the app ciphertext it cannot decrypt, surfacing as corrupt data
|
|
176
|
+
`https://w3id.org/byoe#shared-wallet-collection` descriptor type and the
|
|
177
|
+
read-only action set `SHARED_ACTIONS` (`GET`/`HEAD`) -- an app never asks to
|
|
178
|
+
write a wallet collection. As with `https://w3id.org/byoe#public-collection`, a
|
|
179
|
+
wallet that predates the type reports the request unsatisfiable and the feature
|
|
180
|
+
fails closed, which is the point: a share fuses two axes -- the read zcap AND an
|
|
181
|
+
entry in the collection's key-epoch roster -- and a wallet that granted only the
|
|
182
|
+
zcap would hand the app ciphertext it cannot decrypt, surfacing as corrupt data
|
|
183
183
|
rather than as a wallet that needs updating.
|
|
184
184
|
|
|
185
185
|
Decryption uses the app's **identity** key-agreement key: the X25519 twin of its
|
|
@@ -395,8 +395,8 @@ a progress line (`connecting` to `verifying`):
|
|
|
395
395
|
2. **One popup.** A VPR carrying a `DIDAuthentication` query plus one
|
|
396
396
|
`AppConnectQuery` -- the app's display name, `credentialType`, and
|
|
397
397
|
`vocabBase`, a `capabilityQuery` entry per configured collection, and a
|
|
398
|
-
`https://w3id.org/byoe#shared-collection` entry per shared collection
|
|
399
|
-
sent via `navigator.credentials.get` (`buildAppConnectVpr`). A `null`
|
|
398
|
+
`https://w3id.org/byoe#shared-wallet-collection` entry per shared collection
|
|
399
|
+
-- is sent via `navigator.credentials.get` (`buildAppConnectVpr`). A `null`
|
|
400
400
|
response is a user cancel (`LoginCancelledError`), not an error.
|
|
401
401
|
3. **The wallet matches or mints.** On a first run the wallet generates the
|
|
402
402
|
32-byte seed itself, self-issues the origin-bound app-key credential, and
|
package/dist/auth/loginFlow.d.ts
CHANGED
|
@@ -50,8 +50,8 @@ export interface LoginConfig {
|
|
|
50
50
|
collections: GrantRequestCollection[];
|
|
51
51
|
/**
|
|
52
52
|
* WAS collection ids of wallet-owned collections to request read-and-decrypt
|
|
53
|
-
* access to (the `https://w3id.org/byoe#shared-collection` grant).
|
|
54
|
-
* replicated.
|
|
53
|
+
* access to (the `https://w3id.org/byoe#shared-wallet-collection` grant).
|
|
54
|
+
* Read-only; never replicated.
|
|
55
55
|
*/
|
|
56
56
|
sharedCollections?: string[];
|
|
57
57
|
/**
|
|
@@ -32,8 +32,9 @@
|
|
|
32
32
|
* fails closed rather than degrading into a partial generic flow.
|
|
33
33
|
*
|
|
34
34
|
* A SHARED collection -- one the wallet already owns and encrypts, which the app
|
|
35
|
-
* asks to read and decrypt -- uses the
|
|
36
|
-
* type, and the
|
|
35
|
+
* asks to read and decrypt -- uses the
|
|
36
|
+
* `https://w3id.org/byoe#shared-wallet-collection` descriptor type, and the
|
|
37
|
+
* actions are read-only by construction ({@link SHARED_ACTIONS}):
|
|
37
38
|
* the app never requests writes on a wallet collection. Exactly like
|
|
38
39
|
* `https://w3id.org/byoe#public-collection`, a wallet that predates the type resolves the
|
|
39
40
|
* descriptor UNSATISFIABLE and fails closed -- which is the point here. A share
|
|
@@ -50,8 +51,8 @@ import type { SeedCredentialConfig } from '../identity/seedCredential.js';
|
|
|
50
51
|
import type { IVPRDetails } from './walletRequestTypes.js';
|
|
51
52
|
/**
|
|
52
53
|
* Default read/write actions requested on each private app collection -- also
|
|
53
|
-
* the `https://w3id.org/byoe#collection` class ceiling (the full WAS
|
|
54
|
-
* vocabulary).
|
|
54
|
+
* the `https://w3id.org/byoe#private-collection` class ceiling (the full WAS
|
|
55
|
+
* action vocabulary).
|
|
55
56
|
*/
|
|
56
57
|
export declare const RW_ACTIONS: string[];
|
|
57
58
|
/**
|
|
@@ -73,8 +74,9 @@ export declare const SHARED_ACTIONS: string[];
|
|
|
73
74
|
* The action ceiling of the descriptor class a collection is requested with
|
|
74
75
|
* (the App Connect spec's "Action ceilings" table): add-only for
|
|
75
76
|
* `visibility: 'public'` (`https://w3id.org/byoe#public-collection`), the full
|
|
76
|
-
* vocabulary otherwise (`https://w3id.org/byoe#collection`). Shares
|
|
77
|
-
* own fixed {@link SHARED_ACTIONS} and never consult a configured
|
|
77
|
+
* vocabulary otherwise (`https://w3id.org/byoe#private-collection`). Shares
|
|
78
|
+
* have their own fixed {@link SHARED_ACTIONS} and never consult a configured
|
|
79
|
+
* action set.
|
|
78
80
|
*
|
|
79
81
|
* @param [visibility] {'private' | 'public'}
|
|
80
82
|
* @returns {string[]}
|
|
@@ -91,8 +93,8 @@ export interface GrantRequestCollection {
|
|
|
91
93
|
id: string;
|
|
92
94
|
/**
|
|
93
95
|
* Who can read the collection; selects the descriptor type
|
|
94
|
-
* (`https://w3id.org/byoe#collection` for `'private'`/unset,
|
|
95
|
-
* for `'public'`).
|
|
96
|
+
* (`https://w3id.org/byoe#private-collection` for `'private'`/unset,
|
|
97
|
+
* `https://w3id.org/byoe#public-collection` for `'public'`).
|
|
96
98
|
*/
|
|
97
99
|
visibility?: 'private' | 'public';
|
|
98
100
|
}
|
|
@@ -110,8 +112,8 @@ export declare function newChallenge(): string;
|
|
|
110
112
|
* shape MINUS `controller` (the wallet fills it with the app-key subject DID)
|
|
111
113
|
* and MINUS `reason` (the App Connect consent screen supersedes per-grant
|
|
112
114
|
* reasons). A `visibility: 'public'` collection uses the
|
|
113
|
-
* `https://w3id.org/byoe#public-collection` descriptor type; everything else
|
|
114
|
-
* `https://w3id.org/byoe#collection`.
|
|
115
|
+
* `https://w3id.org/byoe#public-collection` descriptor type; everything else
|
|
116
|
+
* uses `https://w3id.org/byoe#private-collection`.
|
|
115
117
|
*
|
|
116
118
|
* @param options {object}
|
|
117
119
|
* @param options.challenge {string}
|
|
@@ -123,8 +125,9 @@ export declare function newChallenge(): string;
|
|
|
123
125
|
* @param options.collections {GrantRequestCollection[]} the collections to
|
|
124
126
|
* request (WAS collection id + visibility)
|
|
125
127
|
* @param [options.sharedCollections] {string[]} WAS collection ids of
|
|
126
|
-
* wallet-owned collections to request read-and-decrypt access to; each gets
|
|
127
|
-
* `https://w3id.org/byoe#shared-collection` descriptor with
|
|
128
|
+
* wallet-owned collections to request read-and-decrypt access to; each gets
|
|
129
|
+
* a `https://w3id.org/byoe#shared-wallet-collection` descriptor with
|
|
130
|
+
* {@link SHARED_ACTIONS}
|
|
128
131
|
* @param [options.actions] {string[]} the action set to request on each app
|
|
129
132
|
* collection; when omitted each collection requests exactly its class
|
|
130
133
|
* ceiling ({@link actionCeiling}). An explicit set naming an action above a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loginRequest.d.ts","sourceRoot":"","sources":["../../src/auth/loginRequest.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"loginRequest.d.ts","sourceRoot":"","sources":["../../src/auth/loginRequest.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAA;AACzE,OAAO,KAAK,EAEV,WAAW,EACZ,MAAM,yBAAyB,CAAA;AAEhC;;;;GAIG;AACH,eAAO,MAAM,UAAU,UAA2C,CAAA;AAElE;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,UAA0B,CAAA;AAErD;;;;GAIG;AACH,eAAO,MAAM,cAAc,UAAkB,CAAA;AAE7C;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,UAAU,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,EAAE,CAEzE;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,EAAE,EAAE,MAAM,CAAA;IACV;;;;OAIG;IACH,UAAU,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAA;CAClC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AA+CD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,SAAS,EACT,MAAM,EACN,OAAO,EACP,UAAU,EACV,WAAW,EACX,iBAAsB,EACtB,OAAO,EACR,EAAE;IACD,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,oBAAoB,CAAA;IAChC,WAAW,EAAE,sBAAsB,EAAE,CAAA;IACrC,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC5B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CACnB,GAAG,WAAW,CA2Cd"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Default read/write actions requested on each private app collection -- also
|
|
3
|
-
* the `https://w3id.org/byoe#collection` class ceiling (the full WAS
|
|
4
|
-
* vocabulary).
|
|
3
|
+
* the `https://w3id.org/byoe#private-collection` class ceiling (the full WAS
|
|
4
|
+
* action vocabulary).
|
|
5
5
|
*/
|
|
6
6
|
export const RW_ACTIONS = ['GET', 'HEAD', 'PUT', 'POST', 'DELETE'];
|
|
7
7
|
/**
|
|
@@ -23,8 +23,9 @@ export const SHARED_ACTIONS = ['GET', 'HEAD'];
|
|
|
23
23
|
* The action ceiling of the descriptor class a collection is requested with
|
|
24
24
|
* (the App Connect spec's "Action ceilings" table): add-only for
|
|
25
25
|
* `visibility: 'public'` (`https://w3id.org/byoe#public-collection`), the full
|
|
26
|
-
* vocabulary otherwise (`https://w3id.org/byoe#collection`). Shares
|
|
27
|
-
* own fixed {@link SHARED_ACTIONS} and never consult a configured
|
|
26
|
+
* vocabulary otherwise (`https://w3id.org/byoe#private-collection`). Shares
|
|
27
|
+
* have their own fixed {@link SHARED_ACTIONS} and never consult a configured
|
|
28
|
+
* action set.
|
|
28
29
|
*
|
|
29
30
|
* @param [visibility] {'private' | 'public'}
|
|
30
31
|
* @returns {string[]}
|
|
@@ -82,8 +83,8 @@ function requestedActions({ id, visibility, actions }) {
|
|
|
82
83
|
* shape MINUS `controller` (the wallet fills it with the app-key subject DID)
|
|
83
84
|
* and MINUS `reason` (the App Connect consent screen supersedes per-grant
|
|
84
85
|
* reasons). A `visibility: 'public'` collection uses the
|
|
85
|
-
* `https://w3id.org/byoe#public-collection` descriptor type; everything else
|
|
86
|
-
* `https://w3id.org/byoe#collection`.
|
|
86
|
+
* `https://w3id.org/byoe#public-collection` descriptor type; everything else
|
|
87
|
+
* uses `https://w3id.org/byoe#private-collection`.
|
|
87
88
|
*
|
|
88
89
|
* @param options {object}
|
|
89
90
|
* @param options.challenge {string}
|
|
@@ -95,8 +96,9 @@ function requestedActions({ id, visibility, actions }) {
|
|
|
95
96
|
* @param options.collections {GrantRequestCollection[]} the collections to
|
|
96
97
|
* request (WAS collection id + visibility)
|
|
97
98
|
* @param [options.sharedCollections] {string[]} WAS collection ids of
|
|
98
|
-
* wallet-owned collections to request read-and-decrypt access to; each gets
|
|
99
|
-
* `https://w3id.org/byoe#shared-collection` descriptor with
|
|
99
|
+
* wallet-owned collections to request read-and-decrypt access to; each gets
|
|
100
|
+
* a `https://w3id.org/byoe#shared-wallet-collection` descriptor with
|
|
101
|
+
* {@link SHARED_ACTIONS}
|
|
100
102
|
* @param [options.actions] {string[]} the action set to request on each app
|
|
101
103
|
* collection; when omitted each collection requests exactly its class
|
|
102
104
|
* ceiling ({@link actionCeiling}). An explicit set naming an action above a
|
|
@@ -111,7 +113,7 @@ export function buildAppConnectVpr({ challenge, domain, appName, credential, col
|
|
|
111
113
|
invocationTarget: {
|
|
112
114
|
type: visibility === 'public'
|
|
113
115
|
? 'https://w3id.org/byoe#public-collection'
|
|
114
|
-
: 'https://w3id.org/byoe#collection',
|
|
116
|
+
: 'https://w3id.org/byoe#private-collection',
|
|
115
117
|
name: id
|
|
116
118
|
}
|
|
117
119
|
}));
|
|
@@ -120,7 +122,7 @@ export function buildAppConnectVpr({ challenge, domain, appName, credential, col
|
|
|
120
122
|
referenceId: id,
|
|
121
123
|
allowedAction: SHARED_ACTIONS,
|
|
122
124
|
invocationTarget: {
|
|
123
|
-
type: 'https://w3id.org/byoe#shared-collection',
|
|
125
|
+
type: 'https://w3id.org/byoe#shared-wallet-collection',
|
|
124
126
|
name: id
|
|
125
127
|
}
|
|
126
128
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loginRequest.js","sourceRoot":"","sources":["../../src/auth/loginRequest.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"loginRequest.js","sourceRoot":"","sources":["../../src/auth/loginRequest.ts"],"names":[],"mappings":"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"}
|
|
@@ -45,8 +45,9 @@ export type IDIDAuthenticationQuery = {
|
|
|
45
45
|
* (`controller`) wants on which storage target (`invocationTarget`), with an
|
|
46
46
|
* optional human-readable `reason` and RP-chosen `referenceId`. The
|
|
47
47
|
* `invocationTarget` is either a plain URL (satisfied only under the user's own
|
|
48
|
-
* Space) or a wallet-defined descriptor object
|
|
49
|
-
*
|
|
48
|
+
* Space) or a wallet-defined descriptor object
|
|
49
|
+
* (`https://w3id.org/byoe#private-collection`), resolved by
|
|
50
|
+
* `resolveInvocationTarget`. Login requests only ever ask for
|
|
50
51
|
* collection-scoped capabilities.
|
|
51
52
|
*/
|
|
52
53
|
export type ICapabilityQueryDetail = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"walletRequestTypes.d.ts","sourceRoot":"","sources":["../../src/auth/walletRequestTypes.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EACV,qBAAqB,EACrB,uBAAuB,EACvB,KAAK,EACN,MAAM,8BAA8B,CAAA;AAErC;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,SAAS,GAAG,SAAS,EAAE,CAAA;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,uBAAuB,GAAG,gBAAgB,CAAA;AAElE;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,mBAAmB,CAAA;IACzB,eAAe,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC3C,oBAAoB,CAAC,EAAE,KAAK,CAAC;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACtD,CAAA;AAED
|
|
1
|
+
{"version":3,"file":"walletRequestTypes.d.ts","sourceRoot":"","sources":["../../src/auth/walletRequestTypes.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EACV,qBAAqB,EACrB,uBAAuB,EACvB,KAAK,EACN,MAAM,8BAA8B,CAAA;AAErC;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,SAAS,GAAG,SAAS,EAAE,CAAA;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,uBAAuB,GAAG,gBAAgB,CAAA;AAElE;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,mBAAmB,CAAA;IACzB,eAAe,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC3C,oBAAoB,CAAC,EAAE,KAAK,CAAC;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACtD,CAAA;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACjC,UAAU,EAAE,MAAM,CAAA;IAClB,gBAAgB,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAC3D,CAAA;AAED;;;;;GAKG;AACH,MAAM,MAAM,0BAA0B,GAAG,IAAI,CAC3C,sBAAsB,EACtB,YAAY,GAAG,QAAQ,CACxB,CAAA;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,iBAAiB,CAAA;IACvB,GAAG,EAAE;QACH,IAAI,EAAE,MAAM,CAAA;QACZ,cAAc,EAAE,MAAM,CAAA;QACtB,SAAS,EAAE,MAAM,CAAA;KAClB,CAAA;IACD,eAAe,EAAE,0BAA0B,GAAG,0BAA0B,EAAE,CAAA;CAC3E,CAAA;AAED,YAAY,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,KAAK,EAAE,CAAA"}
|
|
@@ -34,7 +34,8 @@ export interface ProvisionDevGrantsResult {
|
|
|
34
34
|
provisionerDid: string;
|
|
35
35
|
/**
|
|
36
36
|
* Present only when `probe` was requested: the result of PUTting the
|
|
37
|
-
*
|
|
37
|
+
* collection description (read first, written back verbatim) with the app's
|
|
38
|
+
* delegated RW zcap.
|
|
38
39
|
*/
|
|
39
40
|
probe?: {
|
|
40
41
|
authorized: boolean;
|
|
@@ -50,8 +51,11 @@ export interface ProvisionDevGrantsResult {
|
|
|
50
51
|
* @param options.serverUrl {string} base URL of a running was-teaching-server
|
|
51
52
|
* @param options.seed {Uint8Array} the app (relying party) master seed; the
|
|
52
53
|
* app DID the grants are delegated to is derived from it
|
|
53
|
-
* @param options.collections {string
|
|
54
|
-
* grant (
|
|
54
|
+
* @param options.collections {Array<string | object>} the WAS collections to
|
|
55
|
+
* create and grant: a bare id string (private by default) or
|
|
56
|
+
* `{ id, visibility }`. A private collection is declared `edv` and gets its
|
|
57
|
+
* epoch[0] roster (sole recipient: the app's identity key-agreement key); a
|
|
58
|
+
* public one stays plaintext
|
|
55
59
|
* @param [options.spaceName] {string} human-readable Space name (defaults to
|
|
56
60
|
* `'Dev Space'`)
|
|
57
61
|
* @param [options.outFile] {string} when given, the `{ grants }` JSON is
|
|
@@ -63,7 +67,8 @@ export interface ProvisionDevGrantsResult {
|
|
|
63
67
|
* @param [options.actions] {ActionInput[]} the RW action set delegated per
|
|
64
68
|
* collection (defaults to the auth layer's `RW_ACTIONS`)
|
|
65
69
|
* @param [options.probe] {boolean} when true, probe whether the delegated RW
|
|
66
|
-
* zcap authorizes a PUT of the
|
|
70
|
+
* zcap authorizes a PUT of the collection description (read first and written
|
|
71
|
+
* back verbatim, so an installed epoch roster is never clobbered)
|
|
67
72
|
* @param [options.log] {(message: string) => void} progress sink (defaults to
|
|
68
73
|
* a no-op; the CLI passes `console.log`)
|
|
69
74
|
* @returns {Promise<ProvisionDevGrantsResult>}
|
|
@@ -71,7 +76,10 @@ export interface ProvisionDevGrantsResult {
|
|
|
71
76
|
export declare function provisionDevGrants({ serverUrl, seed, collections, spaceName, outFile, provisionerSeed, identityHandle, actions, probe, log }: {
|
|
72
77
|
serverUrl: string;
|
|
73
78
|
seed: Uint8Array;
|
|
74
|
-
collections: string
|
|
79
|
+
collections: Array<string | {
|
|
80
|
+
id: string;
|
|
81
|
+
visibility?: 'private' | 'public';
|
|
82
|
+
}>;
|
|
75
83
|
spaceName?: string;
|
|
76
84
|
outFile?: string;
|
|
77
85
|
provisionerSeed?: Uint8Array;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provisionDevGrants.d.ts","sourceRoot":"","sources":["../../src/dev/provisionDevGrants.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"provisionDevGrants.d.ts","sourceRoot":"","sources":["../../src/dev/provisionDevGrants.ts"],"names":[],"mappings":"AAyBA,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAQlE;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,EAAE,UAIrC,CAAA;AAEF;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,MAAM,EAAE,cAAc,EAAE,CAAA;IACxB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IACf;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;OAEG;IACH,cAAc,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,KAAK,CAAC,EAAE;QACN,UAAU,EAAE,OAAO,CAAA;QACnB,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,IAAI,CAAC,EAAE,OAAO,CAAA;KACf,CAAA;CACF;AA0BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAsB,kBAAkB,CAAC,EACvC,SAAS,EACT,IAAI,EACJ,WAAW,EACX,SAAuB,EACvB,OAAO,EACP,eAA0C,EAC1C,cAAc,EAGd,OAAqC,EACrC,KAAa,EACb,GAAc,EACf,EAAE;IACD,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,UAAU,CAAA;IAChB,WAAW,EAAE,KAAK,CAAC,MAAM,GAAG;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAA;KAAE,CAAC,CAAA;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,eAAe,CAAC,EAAE,UAAU,CAAA;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,OAAO,CAAC,EAAE,WAAW,EAAE,CAAA;IACvB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAChC,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAiIpC"}
|
|
@@ -6,22 +6,25 @@
|
|
|
6
6
|
* this:
|
|
7
7
|
*
|
|
8
8
|
* 1. derives a throwaway "provisioner" identity (stands in for the wallet that
|
|
9
|
-
* owns the Space) and the app's own
|
|
9
|
+
* owns the Space) and the app's own identity from the supplied seed;
|
|
10
10
|
* 2. creates a Space (owned by the provisioner) and the requested collections,
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* mirroring what a wallet does when it provisions RP-requested collections:
|
|
12
|
+
* a PRIVATE collection is declared `edv` and gets its epoch[0] roster
|
|
13
|
+
* installed (`ensureFirstEpoch`) with the app's identity key-agreement key
|
|
14
|
+
* as the sole recipient -- epoch-from-birth, no plaintext interlude; a
|
|
15
|
+
* PUBLIC collection stays plaintext with no descriptor;
|
|
13
16
|
* 3. delegates a per-collection read/write zcap to the app's controller DID;
|
|
14
17
|
* 4. returns the signed grants and (optionally) writes them to a JSON file the
|
|
15
18
|
* app loads in dev-sync mode;
|
|
16
19
|
* 5. optionally probes the open question: does the delegated, collection-scoped
|
|
17
|
-
* RW zcap authorize an RP-side PUT of the collection description
|
|
18
|
-
* { encryption: { scheme: 'edv' } } descriptor?
|
|
20
|
+
* RW zcap authorize an RP-side PUT of the collection description?
|
|
19
21
|
*
|
|
20
22
|
* Node only (uses `fs`); consumed through the package `./dev` subpath.
|
|
21
23
|
*/
|
|
22
24
|
import { mkdir, writeFile } from 'node:fs/promises';
|
|
23
25
|
import { dirname } from 'node:path';
|
|
24
26
|
import { WasClient } from '@interop/was-client';
|
|
27
|
+
import { ensureFirstEpoch, ownerRecipient } from '@interop/was-client/edv';
|
|
25
28
|
import { CapabilityAgent } from '@interop/webkms-client';
|
|
26
29
|
import { agentsFromKeyAgent } from '@interop/wallet-core/identity';
|
|
27
30
|
import { deriveIdentity } from '../identity/agents.js';
|
|
@@ -63,8 +66,11 @@ async function provisionerClient({ serverUrl, seed }) {
|
|
|
63
66
|
* @param options.serverUrl {string} base URL of a running was-teaching-server
|
|
64
67
|
* @param options.seed {Uint8Array} the app (relying party) master seed; the
|
|
65
68
|
* app DID the grants are delegated to is derived from it
|
|
66
|
-
* @param options.collections {string
|
|
67
|
-
* grant (
|
|
69
|
+
* @param options.collections {Array<string | object>} the WAS collections to
|
|
70
|
+
* create and grant: a bare id string (private by default) or
|
|
71
|
+
* `{ id, visibility }`. A private collection is declared `edv` and gets its
|
|
72
|
+
* epoch[0] roster (sole recipient: the app's identity key-agreement key); a
|
|
73
|
+
* public one stays plaintext
|
|
68
74
|
* @param [options.spaceName] {string} human-readable Space name (defaults to
|
|
69
75
|
* `'Dev Space'`)
|
|
70
76
|
* @param [options.outFile] {string} when given, the `{ grants }` JSON is
|
|
@@ -76,7 +82,8 @@ async function provisionerClient({ serverUrl, seed }) {
|
|
|
76
82
|
* @param [options.actions] {ActionInput[]} the RW action set delegated per
|
|
77
83
|
* collection (defaults to the auth layer's `RW_ACTIONS`)
|
|
78
84
|
* @param [options.probe] {boolean} when true, probe whether the delegated RW
|
|
79
|
-
* zcap authorizes a PUT of the
|
|
85
|
+
* zcap authorizes a PUT of the collection description (read first and written
|
|
86
|
+
* back verbatim, so an installed epoch roster is never clobbered)
|
|
80
87
|
* @param [options.log] {(message: string) => void} progress sink (defaults to
|
|
81
88
|
* a no-op; the CLI passes `console.log`)
|
|
82
89
|
* @returns {Promise<ProvisionDevGrantsResult>}
|
|
@@ -85,7 +92,7 @@ export async function provisionDevGrants({ serverUrl, seed, collections, spaceNa
|
|
|
85
92
|
// The server accepts HEAD even though storage-core's ActionInput union omits
|
|
86
93
|
// it, hence the assertion.
|
|
87
94
|
actions = RW_ACTIONS, probe = false, log = () => { } }) {
|
|
88
|
-
const [{ controllerDid: appDid, zcapClient: appZcapClient }, { was: provisioner, did: provisionerDid }] = await Promise.all([
|
|
95
|
+
const [{ controllerDid: appDid, zcapClient: appZcapClient, keyAgreementKey }, { was: provisioner, did: provisionerDid }] = await Promise.all([
|
|
89
96
|
deriveIdentity({ seed, identityHandle }),
|
|
90
97
|
provisionerClient({ serverUrl, seed: provisionerSeed })
|
|
91
98
|
]);
|
|
@@ -113,17 +120,32 @@ actions = RW_ACTIONS, probe = false, log = () => { } }) {
|
|
|
113
120
|
};
|
|
114
121
|
// `Promise.all` preserves input order, so `grants[i]` still corresponds to
|
|
115
122
|
// `collections[i]` (the probe below relies on that for `[0]`).
|
|
116
|
-
const grants = await Promise.all(collections.map(async (
|
|
117
|
-
|
|
118
|
-
// provisioning
|
|
119
|
-
|
|
123
|
+
const grants = await Promise.all(collections.map(async (entry) => {
|
|
124
|
+
const { id, visibility = 'private' } = typeof entry === 'string' ? { id: entry } : entry;
|
|
125
|
+
// A private collection mirrors wallet provisioning: declared `edv` at
|
|
126
|
+
// creation, epoch[0] installed with the app's identity key-agreement
|
|
127
|
+
// key as the sole recipient (the roster entry a wallet would write for
|
|
128
|
+
// an app-owned collection). A public collection stays plaintext.
|
|
129
|
+
const collection = await space.createCollection({
|
|
130
|
+
id,
|
|
131
|
+
name: id,
|
|
132
|
+
...(visibility === 'private' && {
|
|
133
|
+
encryption: { scheme: 'edv' }
|
|
134
|
+
})
|
|
135
|
+
});
|
|
136
|
+
if (visibility === 'private') {
|
|
137
|
+
await ensureFirstEpoch({
|
|
138
|
+
collection,
|
|
139
|
+
recipients: [ownerRecipient({ keyAgreementKey })]
|
|
140
|
+
});
|
|
141
|
+
}
|
|
120
142
|
const zcap = await provisioner.grant({
|
|
121
143
|
to: appDid,
|
|
122
144
|
actions,
|
|
123
145
|
target: `${spaceUrl}/${id}`,
|
|
124
146
|
capability: spaceRoot
|
|
125
147
|
});
|
|
126
|
-
log(` collection "${id}": created + delegated RW to app`);
|
|
148
|
+
log(` collection "${id}": created (${visibility}) + delegated RW to app`);
|
|
127
149
|
return zcap;
|
|
128
150
|
}));
|
|
129
151
|
if (outFile !== undefined) {
|
|
@@ -141,22 +163,32 @@ actions = RW_ACTIONS, probe = false, log = () => { } }) {
|
|
|
141
163
|
if (!probe) {
|
|
142
164
|
return result;
|
|
143
165
|
}
|
|
144
|
-
// ---
|
|
166
|
+
// --- Description-write probe --------------------------------------------------
|
|
145
167
|
// Using the app's OWN delegated RW zcap (not the provisioner root key),
|
|
146
|
-
// attempt to PUT the collection description
|
|
168
|
+
// attempt to PUT the collection description. The description is read first
|
|
169
|
+
// and written back verbatim: authorization is what is probed, and a blind
|
|
170
|
+
// descriptor PUT would try to clobber the installed epoch roster (which the
|
|
171
|
+
// server refuses -- epochs are append-only -- muddying the answer).
|
|
147
172
|
const appWas = new WasClient({ serverUrl, zcapClient: appZcapClient });
|
|
148
|
-
const
|
|
173
|
+
const firstEntry = collections[0];
|
|
174
|
+
const probeCollectionId = typeof firstEntry === 'string' ? firstEntry : firstEntry.id;
|
|
149
175
|
const probeCapability = grants[0];
|
|
150
|
-
|
|
176
|
+
const probePath = collectionPath({
|
|
177
|
+
spaceId: space.id,
|
|
178
|
+
collectionId: probeCollectionId
|
|
179
|
+
});
|
|
180
|
+
log(`\nDescription-write probe on "${probeCollectionId}" (delegated RW zcap):`);
|
|
151
181
|
try {
|
|
182
|
+
const current = await appWas.request({
|
|
183
|
+
capability: probeCapability,
|
|
184
|
+
path: probePath,
|
|
185
|
+
method: 'GET'
|
|
186
|
+
});
|
|
152
187
|
const response = await appWas.request({
|
|
153
188
|
capability: probeCapability,
|
|
154
|
-
path:
|
|
155
|
-
spaceId: space.id,
|
|
156
|
-
collectionId: probeCollectionId
|
|
157
|
-
}),
|
|
189
|
+
path: probePath,
|
|
158
190
|
method: 'PUT',
|
|
159
|
-
json: { id: probeCollectionId
|
|
191
|
+
json: (current.data ?? { id: probeCollectionId })
|
|
160
192
|
});
|
|
161
193
|
log(` AUTHORIZED -- server responded ${response.status}`);
|
|
162
194
|
result.probe = { authorized: true, status: response.status };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provisionDevGrants.js","sourceRoot":"","sources":["../../src/dev/provisionDevGrants.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"provisionDevGrants.js","sourceRoot":"","sources":["../../src/dev/provisionDevGrants.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,SAAS,EAAoB,MAAM,qBAAqB,CAAA;AACjE,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAE1E,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAA;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAe,IAAI,UAAU,CAAC;IACjE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAC5E,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAC5E,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;CACnC,CAAC,CAAA;AAwCF;;;;;;;GAOG;AACH,KAAK,UAAU,iBAAiB,CAAC,EAC/B,SAAS,EACT,IAAI,EAIL;IACC,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,QAAQ,CAAC;QAC3C,IAAI;QACJ,MAAM,EAAE,iBAAiB;QACzB,OAAO,EAAE,iBAAiB;KAC3B,CAAC,CAAA;IACF,MAAM,EAAE,UAAU,EAAE,GAAG,kBAAkB,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAA;IAC9D,OAAO,EAAE,GAAG,EAAE,IAAI,SAAS,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAA;AACzE,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,EACvC,SAAS,EACT,IAAI,EACJ,WAAW,EACX,SAAS,GAAG,WAAW,EACvB,OAAO,EACP,eAAe,GAAG,wBAAwB,EAC1C,cAAc;AACd,6EAA6E;AAC7E,2BAA2B;AAC3B,OAAO,GAAG,UAA2B,EACrC,KAAK,GAAG,KAAK,EACb,GAAG,GAAG,GAAG,EAAE,GAAE,CAAC,EAYf;IACC,MAAM,CACJ,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,EACrE,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,cAAc,EAAE,CAC1C,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACpB,cAAc,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;QACxC,iBAAiB,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;KACxD,CAAC,CAAA;IAEF,GAAG,CAAC,wBAAwB,SAAS,EAAE,CAAC,CAAA;IACxC,GAAG,CAAC,sBAAsB,cAAc,EAAE,CAAC,CAAA;IAC3C,GAAG,CAAC,sBAAsB,MAAM,EAAE,CAAC,CAAA;IAEnC,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,WAAW,CAAC;QAC1C,IAAI,EAAE,SAAS;QACf,UAAU,EAAE,cAAc;KAC3B,CAAC,CAAA;IACF,GAAG,CAAC,sBAAsB,KAAK,CAAC,EAAE,EAAE,CAAC,CAAA;IAErC,6EAA6E;IAC7E,2EAA2E;IAC3E,4EAA4E;IAC5E,8EAA8E;IAC9E,2EAA2E;IAC3E,sEAAsE;IACtE,qEAAqE;IACrE,MAAM,QAAQ,GAAG,GAAG,SAAS,UAAU,KAAK,CAAC,EAAE,EAAE,CAAA;IACjD,MAAM,SAAS,GAAG;QAChB,UAAU,EAAE,0BAA0B;QACtC,EAAE,EAAE,iBAAiB,kBAAkB,CAAC,QAAQ,CAAC,EAAE;QACnD,UAAU,EAAE,cAAc;QAC1B,gBAAgB,EAAE,QAAQ;KACyC,CAAA;IAErE,2EAA2E;IAC3E,+DAA+D;IAC/D,MAAM,MAAM,GAAqB,MAAM,OAAO,CAAC,GAAG,CAChD,WAAW,CAAC,GAAG,CAAC,KAAK,EAAC,KAAK,EAAC,EAAE;QAC5B,MAAM,EAAE,EAAE,EAAE,UAAU,GAAG,SAAS,EAAE,GAClC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAA;QACnD,sEAAsE;QACtE,qEAAqE;QACrE,uEAAuE;QACvE,iEAAiE;QACjE,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,gBAAgB,CAAC;YAC9C,EAAE;YACF,IAAI,EAAE,EAAE;YACR,GAAG,CAAC,UAAU,KAAK,SAAS,IAAI;gBAC9B,UAAU,EAAE,EAAE,MAAM,EAAE,KAAc,EAAE;aACvC,CAAC;SACH,CAAC,CAAA;QACF,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM,gBAAgB,CAAC;gBACrB,UAAU;gBACV,UAAU,EAAE,CAAC,cAAc,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC;aAClD,CAAC,CAAA;QACJ,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,KAAK,CAAC;YACnC,EAAE,EAAE,MAAM;YACV,OAAO;YACP,MAAM,EAAE,GAAG,QAAQ,IAAI,EAAE,EAAE;YAC3B,UAAU,EAAE,SAAS;SACtB,CAAC,CAAA;QACF,GAAG,CAAC,iBAAiB,EAAE,eAAe,UAAU,yBAAyB,CAAC,CAAA;QAC1E,OAAO,IAAI,CAAA;IACb,CAAC,CAAC,CACH,CAAA;IAED,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAClD,MAAM,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;QAC7D,GAAG,CAAC,WAAW,MAAM,CAAC,MAAM,cAAc,OAAO,EAAE,CAAC,CAAA;IACtD,CAAC;IAED,MAAM,MAAM,GAA6B;QACvC,MAAM;QACN,OAAO,EAAE,KAAK,CAAC,EAAE;QACjB,QAAQ;QACR,MAAM;QACN,cAAc;KACf,CAAA;IAED,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,MAAM,CAAA;IACf,CAAC;IAED,iFAAiF;IACjF,wEAAwE;IACxE,2EAA2E;IAC3E,0EAA0E;IAC1E,4EAA4E;IAC5E,oEAAoE;IACpE,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC,CAAA;IACtE,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAE,CAAA;IAClC,MAAM,iBAAiB,GACrB,OAAO,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAA;IAC7D,MAAM,eAAe,GAAG,MAAM,CAAC,CAAC,CAAE,CAAA;IAClC,MAAM,SAAS,GAAG,cAAc,CAAC;QAC/B,OAAO,EAAE,KAAK,CAAC,EAAE;QACjB,YAAY,EAAE,iBAAiB;KAChC,CAAC,CAAA;IACF,GAAG,CACD,iCAAiC,iBAAiB,wBAAwB,CAC3E,CAAA;IACD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC;YACnC,UAAU,EAAE,eAAe;YAC3B,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,KAAK;SACd,CAAC,CAAA;QACF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC;YACpC,UAAU,EAAE,eAAe;YAC3B,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,EAAE,EAAE,iBAAiB,EAAE,CAAW;SAC5D,CAAC,CAAA;QACF,GAAG,CAAC,oCAAoC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;QAC1D,MAAM,CAAC,KAAK,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAA;IAC9D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;QAC/B,MAAM,IAAI,GAAI,GAA0B,CAAC,IAAI,CAAA;QAC7C,GAAG,CAAC,8BAA8B,MAAM,IAAI,KAAK,EAAE,CAAC,CAAA;QACpD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,GAAG,CAAC,kBAAkB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAC/C,CAAC;QACD,MAAM,CAAC,KAAK,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;IAC1D,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documentLoader.d.ts","sourceRoot":"","sources":["../../src/identity/documentLoader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"documentLoader.d.ts","sourceRoot":"","sources":["../../src/identity/documentLoader.ts"],"names":[],"mappings":"AAuBA;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACpD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,QAAQ,EAAE,OAAO,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAC,CAAA;AAqBF;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,cAAc,CAErD"}
|
|
@@ -16,15 +16,22 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { createDidWebvhDriver } from '@interop/did-method-webvh/driver';
|
|
18
18
|
import { createDefaultDidResolver, securityLoader } from '@interop/security-document-loader';
|
|
19
|
+
import { contexts as byoeContexts } from 'byoe-context';
|
|
19
20
|
const didResolver = createDefaultDidResolver();
|
|
20
21
|
// The webvh driver is resolution-only (`{ method, get, resolveDID }`) by
|
|
21
22
|
// design; did-io's DidMethodDriver type also demands the key-generation
|
|
22
23
|
// surface (generate, fromKeyPair, ...), which resolution never calls.
|
|
23
24
|
didResolver.use(createDidWebvhDriver());
|
|
24
|
-
const
|
|
25
|
+
const loader = securityLoader({
|
|
25
26
|
fetchRemoteContexts: true,
|
|
26
27
|
didResolver
|
|
27
|
-
})
|
|
28
|
+
});
|
|
29
|
+
// The BYOE App Connect context is registered here, not bundled in the security
|
|
30
|
+
// loader, so vocabulary additions ship with a `byoe-context` bump alone.
|
|
31
|
+
for (const [url, context] of byoeContexts) {
|
|
32
|
+
loader.addStatic(url, context);
|
|
33
|
+
}
|
|
34
|
+
const baseLoader = loader.build();
|
|
28
35
|
/**
|
|
29
36
|
* Builds the JSON-LD document loader handed to `@interop/vc` issuance and
|
|
30
37
|
* verifier-core verification.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documentLoader.js","sourceRoot":"","sources":["../../src/identity/documentLoader.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAA;AACvE,OAAO,EACL,wBAAwB,EACxB,cAAc,EACf,MAAM,mCAAmC,CAAA;
|
|
1
|
+
{"version":3,"file":"documentLoader.js","sourceRoot":"","sources":["../../src/identity/documentLoader.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAA;AACvE,OAAO,EACL,wBAAwB,EACxB,cAAc,EACf,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,cAAc,CAAA;AAWvD,MAAM,WAAW,GAAG,wBAAwB,EAAE,CAAA;AAC9C,yEAAyE;AACzE,wEAAwE;AACxE,sEAAsE;AACtE,WAAW,CAAC,GAAG,CACb,oBAAoB,EAAsD,CAC3E,CAAA;AAED,MAAM,MAAM,GAAG,cAAc,CAAC;IAC5B,mBAAmB,EAAE,IAAI;IACzB,WAAW;CACZ,CAAC,CAAA;AACF,+EAA+E;AAC/E,yEAAyE;AACzE,KAAK,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,YAAY,EAAE,CAAC;IAC1C,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;AAChC,CAAC;AACD,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,EAAE,CAAA;AAEjC;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO,UAA4B,CAAA;AACrC,CAAC"}
|
|
@@ -20,9 +20,10 @@ export interface SeedStore {
|
|
|
20
20
|
*/
|
|
21
21
|
loadRecord(): Promise<unknown | null>;
|
|
22
22
|
/**
|
|
23
|
-
* Persists the collection-encryption descriptor cache (keyed by
|
|
24
|
-
* id
|
|
25
|
-
*
|
|
23
|
+
* Persists the collection-encryption descriptor cache (descriptors keyed by
|
|
24
|
+
* WAS collection id, stamped with the controller DID they belong to), so an
|
|
25
|
+
* offline / hot-restore session can rebuild its epoch-aware ciphers without
|
|
26
|
+
* a live description read.
|
|
26
27
|
*/
|
|
27
28
|
saveDescriptors(descriptors: unknown): Promise<void>;
|
|
28
29
|
/**
|
|
@@ -53,6 +54,13 @@ export declare function createSeedStore({ dbName, idb }: {
|
|
|
53
54
|
* acquires through: per-collection get/put over the single stored blob, already
|
|
54
55
|
* scoped to one session's Space by the store it is bound to.
|
|
55
56
|
*
|
|
57
|
+
* The blob is stamped with the `controller` DID whose descriptors it holds, and
|
|
58
|
+
* a cache bound to a different controller reads it as empty (and overwrites the
|
|
59
|
+
* stamp on its first write). Descriptors name key-epoch rosters a specific
|
|
60
|
+
* identity is a recipient of, so a login under a different controller than the
|
|
61
|
+
* one that cached them must never trust them: a stale hit would build ciphers
|
|
62
|
+
* the new identity cannot unwrap.
|
|
63
|
+
*
|
|
56
64
|
* The blob is read-modify-written on every put. That is fine at this scale (an
|
|
57
65
|
* app registers a handful of collections) and it is the only shape the existing
|
|
58
66
|
* one-record persistence allows; concurrent puts are serialized through a
|
|
@@ -60,9 +68,12 @@ export declare function createSeedStore({ dbName, idb }: {
|
|
|
60
68
|
*
|
|
61
69
|
* @param options {object}
|
|
62
70
|
* @param options.store {SeedStore} the session seed store to persist through
|
|
71
|
+
* @param options.controller {string} the controller DID the cached
|
|
72
|
+
* descriptors belong to
|
|
63
73
|
* @returns {EncryptionDescriptorCache}
|
|
64
74
|
*/
|
|
65
|
-
export declare function createDescriptorCache({ store }: {
|
|
75
|
+
export declare function createDescriptorCache({ store, controller }: {
|
|
66
76
|
store: SeedStore;
|
|
77
|
+
controller: string;
|
|
67
78
|
}): EncryptionDescriptorCache;
|
|
68
79
|
//# sourceMappingURL=seedStore.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seedStore.d.ts","sourceRoot":"","sources":["../../src/identity/seedStore.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAA;AAOjF;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACzC;;OAEG;IACH,QAAQ,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAA;IACtC;;OAEG;IACH,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1C;;OAEG;IACH,UAAU,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;IACrC
|
|
1
|
+
{"version":3,"file":"seedStore.d.ts","sourceRoot":"","sources":["../../src/identity/seedStore.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAA;AAOjF;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACzC;;OAEG;IACH,QAAQ,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAA;IACtC;;OAEG;IACH,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1C;;OAEG;IACH,UAAU,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;IACrC;;;;;OAKG;IACH,eAAe,CAAC,WAAW,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACpD;;OAEG;IACH,eAAe,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;IAC1C;;OAEG;IACH,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAChC;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,GAAe,EAChB,EAAE;IACD,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,UAAU,CAAA;CACjB,GAAG,SAAS,CAyEZ;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,KAAK,EACL,UAAU,EACX,EAAE;IACD,KAAK,EAAE,SAAS,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;CACnB,GAAG,yBAAyB,CA2C5B"}
|
|
@@ -73,6 +73,13 @@ export function createSeedStore({ dbName, idb = indexedDB }) {
|
|
|
73
73
|
* acquires through: per-collection get/put over the single stored blob, already
|
|
74
74
|
* scoped to one session's Space by the store it is bound to.
|
|
75
75
|
*
|
|
76
|
+
* The blob is stamped with the `controller` DID whose descriptors it holds, and
|
|
77
|
+
* a cache bound to a different controller reads it as empty (and overwrites the
|
|
78
|
+
* stamp on its first write). Descriptors name key-epoch rosters a specific
|
|
79
|
+
* identity is a recipient of, so a login under a different controller than the
|
|
80
|
+
* one that cached them must never trust them: a stale hit would build ciphers
|
|
81
|
+
* the new identity cannot unwrap.
|
|
82
|
+
*
|
|
76
83
|
* The blob is read-modify-written on every put. That is fine at this scale (an
|
|
77
84
|
* app registers a handful of collections) and it is the only shape the existing
|
|
78
85
|
* one-record persistence allows; concurrent puts are serialized through a
|
|
@@ -80,13 +87,18 @@ export function createSeedStore({ dbName, idb = indexedDB }) {
|
|
|
80
87
|
*
|
|
81
88
|
* @param options {object}
|
|
82
89
|
* @param options.store {SeedStore} the session seed store to persist through
|
|
90
|
+
* @param options.controller {string} the controller DID the cached
|
|
91
|
+
* descriptors belong to
|
|
83
92
|
* @returns {EncryptionDescriptorCache}
|
|
84
93
|
*/
|
|
85
|
-
export function createDescriptorCache({ store }) {
|
|
94
|
+
export function createDescriptorCache({ store, controller }) {
|
|
86
95
|
async function readAll() {
|
|
87
|
-
const stored = await store.loadDescriptors();
|
|
88
|
-
if (stored
|
|
89
|
-
|
|
96
|
+
const stored = (await store.loadDescriptors());
|
|
97
|
+
if (stored?.controller === controller &&
|
|
98
|
+
stored.descriptors &&
|
|
99
|
+
typeof stored.descriptors === 'object' &&
|
|
100
|
+
!Array.isArray(stored.descriptors)) {
|
|
101
|
+
return { ...stored.descriptors };
|
|
90
102
|
}
|
|
91
103
|
return {};
|
|
92
104
|
}
|
|
@@ -100,7 +112,7 @@ export function createDescriptorCache({ store }) {
|
|
|
100
112
|
const next = writes.then(async () => {
|
|
101
113
|
const descriptors = await readAll();
|
|
102
114
|
descriptors[collectionId] = descriptor;
|
|
103
|
-
await store.saveDescriptors(descriptors);
|
|
115
|
+
await store.saveDescriptors({ controller, descriptors });
|
|
104
116
|
});
|
|
105
117
|
writes = next.then(() => { }, () => { });
|
|
106
118
|
return next;
|