@interop/was-react 0.3.5 → 0.4.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.
@@ -16,6 +16,7 @@
16
16
  * storage layer above needs no encrypted-vs-plaintext fork.
17
17
  */
18
18
  import type { IKeyAgreementKey, IKeyResolver } from '@interop/data-integrity-core';
19
+ import type { CollectionEncryption } from '@interop/was-client';
19
20
  import type { Json } from './types.js';
20
21
  /**
21
22
  * A per-collection document cipher. `encrypt` is the create path (mints a random
@@ -76,15 +77,29 @@ export declare function createPlaintextDocCodec({ collectionId }: {
76
77
  * place via `sequence` -- the mutable head-document model every entity here uses
77
78
  * (constant bump / toggle / re-categorize edits).
78
79
  *
80
+ * Delegates to `@interop/was-client`'s `createEdvDocCipher`: with no
81
+ * `encryption` marker (or a marker with no key epochs) the cipher is
82
+ * single-recipient (the key-agreement key encrypts and decrypts directly, the
83
+ * behavior every collection has had); with epochs on the marker the cipher
84
+ * becomes multi-recipient -- writes stamp the marker's current epoch and reads
85
+ * route by the envelope's recipient key id, while a pre-epoch envelope still
86
+ * decrypts through the single-key path (a permanent tolerance, not a migration
87
+ * shim). The returned cipher's shape matches {@link DocCipher} exactly; only the
88
+ * nominal `Json` origin differs, so it crosses the boundary with a cast.
89
+ *
79
90
  * @param options {object}
80
91
  * @param options.keyAgreementKey {IKeyAgreementKey}
81
92
  * @param options.keyResolver {IKeyResolver}
82
93
  * @param options.collectionId {string} labels errors; the codec is agnostic
94
+ * @param [options.encryption] {CollectionEncryption} the collection's
95
+ * encryption marker; when it carries key epochs the cipher becomes
96
+ * multi-recipient
83
97
  * @returns {Promise<DocCipher>}
84
98
  */
85
- export declare function createDocCipher({ keyAgreementKey, keyResolver, collectionId }: {
99
+ export declare function createDocCipher({ keyAgreementKey, keyResolver, collectionId, encryption }: {
86
100
  keyAgreementKey: IKeyAgreementKey;
87
101
  keyResolver: IKeyResolver;
88
102
  collectionId: string;
103
+ encryption?: CollectionEncryption;
89
104
  }): Promise<DocCipher>;
90
105
  //# sourceMappingURL=docCipher.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"docCipher.d.ts","sourceRoot":"","sources":["../../src/sync/docCipher.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACb,MAAM,8BAA8B,CAAA;AAErC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAEtC;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAE,CAAC,CAAA;IACzE,aAAa,CAAC,OAAO,EAAE;QACrB,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,IAAI,CAAA;QACV,OAAO,EAAE,IAAI,CAAA;KACd,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAE,CAAC,CAAA;IAC3C,OAAO,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACpD;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,GAAG,OAAO,CAMnE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,YAAY,EACb,EAAE;IACD,YAAY,EAAE,MAAM,CAAA;CACrB,GAAG,SAAS,CAiCZ;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,eAAe,CAAC,EACpC,eAAe,EACf,WAAW,EACX,YAAY,EACb,EAAE;IACD,eAAe,EAAE,gBAAgB,CAAA;IACjC,WAAW,EAAE,YAAY,CAAA;IACzB,YAAY,EAAE,MAAM,CAAA;CACrB,GAAG,OAAO,CAAC,SAAS,CAAC,CA+ErB"}
1
+ {"version":3,"file":"docCipher.d.ts","sourceRoot":"","sources":["../../src/sync/docCipher.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACb,MAAM,8BAA8B,CAAA;AACrC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAE/D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAEtC;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAE,CAAC,CAAA;IACzE,aAAa,CAAC,OAAO,EAAE;QACrB,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,IAAI,CAAA;QACV,OAAO,EAAE,IAAI,CAAA;KACd,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAE,CAAC,CAAA;IAC3C,OAAO,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACpD;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,GAAG,OAAO,CAMnE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,YAAY,EACb,EAAE;IACD,YAAY,EAAE,MAAM,CAAA;CACrB,GAAG,SAAS,CAiCZ;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,eAAe,CAAC,EACpC,eAAe,EACf,WAAW,EACX,YAAY,EACZ,UAAU,EACX,EAAE;IACD,eAAe,EAAE,gBAAgB,CAAA;IACjC,WAAW,EAAE,YAAY,CAAA;IACzB,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,oBAAoB,CAAA;CAClC,GAAG,OAAO,CAAC,SAAS,CAAC,CASrB"}
@@ -1,4 +1,4 @@
1
- import { createEdvEncryption } from '@interop/was-client/edv';
1
+ import { createEdvDocCipher } from '@interop/was-client/edv';
2
2
  /**
3
3
  * Whether a stored body is an EDV encryption envelope (carries an object `jwe`)
4
4
  * rather than plaintext. Lets read paths stay tolerant of any legacy plaintext
@@ -63,69 +63,33 @@ export function createPlaintextDocCodec({ collectionId }) {
63
63
  * place via `sequence` -- the mutable head-document model every entity here uses
64
64
  * (constant bump / toggle / re-categorize edits).
65
65
  *
66
+ * Delegates to `@interop/was-client`'s `createEdvDocCipher`: with no
67
+ * `encryption` marker (or a marker with no key epochs) the cipher is
68
+ * single-recipient (the key-agreement key encrypts and decrypts directly, the
69
+ * behavior every collection has had); with epochs on the marker the cipher
70
+ * becomes multi-recipient -- writes stamp the marker's current epoch and reads
71
+ * route by the envelope's recipient key id, while a pre-epoch envelope still
72
+ * decrypts through the single-key path (a permanent tolerance, not a migration
73
+ * shim). The returned cipher's shape matches {@link DocCipher} exactly; only the
74
+ * nominal `Json` origin differs, so it crosses the boundary with a cast.
75
+ *
66
76
  * @param options {object}
67
77
  * @param options.keyAgreementKey {IKeyAgreementKey}
68
78
  * @param options.keyResolver {IKeyResolver}
69
79
  * @param options.collectionId {string} labels errors; the codec is agnostic
80
+ * @param [options.encryption] {CollectionEncryption} the collection's
81
+ * encryption marker; when it carries key epochs the cipher becomes
82
+ * multi-recipient
70
83
  * @returns {Promise<DocCipher>}
71
84
  */
72
- export async function createDocCipher({ keyAgreementKey, keyResolver, collectionId }) {
73
- const provider = createEdvEncryption({
74
- resolveKeys: async () => null,
75
- idDerivation: 'random'
76
- });
77
- const codec = await provider.codecFor({
78
- spaceId: 'local',
85
+ export async function createDocCipher({ keyAgreementKey, keyResolver, collectionId, encryption }) {
86
+ const cipher = await createEdvDocCipher({
87
+ keyAgreementKey,
88
+ keyResolver,
79
89
  collectionId,
80
- scheme: 'edv',
81
- keys: { keyAgreementKey, keyResolver }
90
+ idDerivation: 'random',
91
+ ...(encryption && { encryption })
82
92
  });
83
- if (!codec) {
84
- throw new Error(`Could not build the EDV cipher for collection "${collectionId}".`);
85
- }
86
- // Parses the codec's `EncodedWrite` (id + envelope body bytes) into the
87
- // stored `{ id, envelope }` shape. Shared by the create and update paths.
88
- const readEncoded = (encoded) => {
89
- if (typeof encoded.id !== 'string' ||
90
- !(encoded.body instanceof Uint8Array)) {
91
- throw new Error(`EDV encrypt for collection "${collectionId}" returned no id/envelope body.`);
92
- }
93
- const envelope = JSON.parse(new TextDecoder().decode(encoded.body));
94
- return { id: encoded.id, envelope };
95
- };
96
- return {
97
- async encrypt({ data }) {
98
- // `encode` with no caller id is the create path: encrypt, then use the
99
- // minted random id.
100
- const encoded = await codec.encode({
101
- data: data
102
- });
103
- return readEncoded(encoded);
104
- },
105
- async encryptUpdate({ id, data, current }) {
106
- // The update path: hand the codec the prior stored envelope so it advances
107
- // `sequence` from it and re-encrypts under the same id. The codec reads
108
- // `current.data` (the prior envelope) and its `etag` header (unused here;
109
- // the wire `If-Match` is derived from the synced-doc `version`, not this).
110
- const priorResponse = {
111
- data: current,
112
- json: async () => current,
113
- headers: { get: () => null }
114
- };
115
- const encoded = await codec.encode({
116
- id,
117
- data: data,
118
- current: priorResponse
119
- });
120
- return readEncoded(encoded);
121
- },
122
- async decrypt({ envelope }) {
123
- const response = {
124
- data: envelope,
125
- json: async () => envelope
126
- };
127
- return (await codec.decode(response));
128
- }
129
- };
93
+ return cipher;
130
94
  }
131
95
  //# sourceMappingURL=docCipher.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"docCipher.js","sourceRoot":"","sources":["../../src/sync/docCipher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"docCipher.js","sourceRoot":"","sources":["../../src/sync/docCipher.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAmB5D;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAsB;IACxD,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACpE,OAAO,KAAK,CAAA;IACd,CAAC;IACD,MAAM,GAAG,GAAI,IAA0B,CAAC,GAAG,CAAA;IAC3C,OAAO,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,CAAA;AAChD,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,uBAAuB,CAAC,EACtC,YAAY,EAGb;IACC,MAAM,SAAS,GAAG,CAAC,IAAU,EAAU,EAAE;QACvC,MAAM,EAAE,GAAI,IAAgC,EAAE,EAAE,CAAA;QAChD,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9C,MAAM,IAAI,KAAK,CACb,kCAAkC,YAAY,2BAA2B,CAC1E,CAAA;QACH,CAAC;QACD,OAAO,EAAE,CAAA;IACX,CAAC,CAAA;IACD,MAAM,eAAe,GAAG,CAAC,IAAU,EAAQ,EAAE;QAC3C,IAAI,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CACb,eAAe,YAAY,yCAAyC;gBAClE,yBAAyB,CAC5B,CAAA;QACH,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC,CAAA;IAED,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,EAAE,IAAI,EAAkB;YACpC,OAAO,EAAE,EAAE,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAA;QAChD,CAAC;QAED,KAAK,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,IAAI,EAA8B;YAC1D,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAA;QAC/B,CAAC;QAED,KAAK,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAsB;YAC5C,OAAO,eAAe,CAAC,QAAQ,CAAC,CAAA;QAClC,CAAC;KACF,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EACpC,eAAe,EACf,WAAW,EACX,YAAY,EACZ,UAAU,EAMX;IACC,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC;QACtC,eAAe;QACf,WAAW;QACX,YAAY;QACZ,YAAY,EAAE,QAAQ;QACtB,GAAG,CAAC,UAAU,IAAI,EAAE,UAAU,EAAE,CAAC;KAClC,CAAC,CAAA;IACF,OAAO,MAA8B,CAAA;AACvC,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@interop/was-react",
3
3
  "description": "React library for building 'Bring Your Own Everything' (BYOE) apps on Wallet Attached Storage: DID Auth login via CHAPI wallet, local-first encrypted storage, and background sync to a WAS server.",
4
- "version": "0.3.5",
4
+ "version": "0.4.0",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "build": "pnpm run clear && tsc",
@@ -46,13 +46,14 @@
46
46
  "types": "dist/index.d.ts",
47
47
  "sideEffects": false,
48
48
  "dependencies": {
49
- "@interop/data-integrity-core": "^8.3.0",
49
+ "@interop/data-integrity-core": "^8.4.0",
50
50
  "@interop/ed25519-signature": "^7.1.4",
51
51
  "@interop/ezcap": "^7.4.1",
52
52
  "@interop/security-document-loader": "^9.4.4",
53
53
  "@interop/vc": "^11.0.6",
54
54
  "@interop/verifier-core": "^3.4.1",
55
- "@interop/was-client": "^0.19.0",
55
+ "@interop/wallet-core": "^0.5.0",
56
+ "@interop/was-client": "^0.20.0",
56
57
  "@interop/webkms-client": "^14.7.1",
57
58
  "@interop/x25519-key-agreement-key": "^5.2.1",
58
59
  "@scure/base": "^2.2.0",