@enbox/dwn-sdk-js 0.4.14 → 0.4.16
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/dist/browser.mjs +1 -1
- package/dist/browser.mjs.map +4 -4
- package/dist/esm/src/core/constants.js +2 -0
- package/dist/esm/src/core/constants.js.map +1 -1
- package/dist/esm/src/core/dwn-error.js +2 -0
- package/dist/esm/src/core/dwn-error.js.map +1 -1
- package/dist/esm/src/core/protocol-authorization-validation.js +9 -0
- package/dist/esm/src/core/protocol-authorization-validation.js.map +1 -1
- package/dist/esm/src/handlers/messages-query.js +2 -29
- package/dist/esm/src/handlers/messages-query.js.map +1 -1
- package/dist/esm/src/handlers/messages-subscribe.js +52 -1
- package/dist/esm/src/handlers/messages-subscribe.js.map +1 -1
- package/dist/esm/src/handlers/protocols-configure.js +157 -7
- package/dist/esm/src/handlers/protocols-configure.js.map +1 -1
- package/dist/esm/src/index.js +2 -2
- package/dist/esm/src/index.js.map +1 -1
- package/dist/esm/src/protocols/encryption.js +41 -10
- package/dist/esm/src/protocols/encryption.js.map +1 -1
- package/dist/esm/src/store/message-store-level.js +4 -2
- package/dist/esm/src/store/message-store-level.js.map +1 -1
- package/dist/esm/src/types/protocols-types.js.map +1 -1
- package/dist/esm/src/utils/messages.js +36 -0
- package/dist/esm/src/utils/messages.js.map +1 -1
- package/dist/esm/src/utils/replication.js +14 -0
- package/dist/esm/src/utils/replication.js.map +1 -1
- package/dist/esm/tests/features/protocol-composition.spec.js +5 -1
- package/dist/esm/tests/features/protocol-composition.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-query.spec.js +7 -15
- package/dist/esm/tests/handlers/messages-query.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-subscribe.spec.js +129 -1
- package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/handlers/protocols-configure.spec.js +244 -1
- package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-read.spec.js +2 -1
- package/dist/esm/tests/handlers/records-read.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-write.spec.js +24 -1
- package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
- package/dist/esm/tests/protocols/encryption.spec.js +3 -1
- package/dist/esm/tests/protocols/encryption.spec.js.map +1 -1
- package/dist/esm/tests/store/message-store-level.spec.js +21 -0
- package/dist/esm/tests/store/message-store-level.spec.js.map +1 -1
- package/dist/types/src/core/constants.d.ts +2 -0
- package/dist/types/src/core/constants.d.ts.map +1 -1
- package/dist/types/src/core/dwn-error.d.ts +2 -0
- package/dist/types/src/core/dwn-error.d.ts.map +1 -1
- package/dist/types/src/core/protocol-authorization-validation.d.ts.map +1 -1
- package/dist/types/src/handlers/messages-query.d.ts +0 -2
- package/dist/types/src/handlers/messages-query.d.ts.map +1 -1
- package/dist/types/src/handlers/messages-subscribe.d.ts +16 -0
- package/dist/types/src/handlers/messages-subscribe.d.ts.map +1 -1
- package/dist/types/src/handlers/protocols-configure.d.ts +17 -0
- package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +2 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/protocols/encryption.d.ts +3 -1
- package/dist/types/src/protocols/encryption.d.ts.map +1 -1
- package/dist/types/src/store/message-store-level.d.ts.map +1 -1
- package/dist/types/src/types/messages-types.d.ts +14 -0
- package/dist/types/src/types/messages-types.d.ts.map +1 -1
- package/dist/types/src/types/protocols-types.d.ts +2 -1
- package/dist/types/src/types/protocols-types.d.ts.map +1 -1
- package/dist/types/src/utils/messages.d.ts +8 -0
- package/dist/types/src/utils/messages.d.ts.map +1 -1
- package/dist/types/src/utils/replication.d.ts +8 -1
- package/dist/types/src/utils/replication.d.ts.map +1 -1
- package/dist/types/tests/features/protocol-composition.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/messages-query.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/messages-subscribe.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/protocols-configure.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/records-read.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/records-write.spec.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/core/constants.ts +2 -0
- package/src/core/dwn-error.ts +2 -0
- package/src/core/protocol-authorization-validation.ts +14 -0
- package/src/handlers/messages-query.ts +3 -41
- package/src/handlers/messages-subscribe.ts +67 -3
- package/src/handlers/protocols-configure.ts +236 -7
- package/src/index.ts +3 -0
- package/src/protocols/encryption.ts +54 -11
- package/src/store/message-store-level.ts +4 -2
- package/src/types/messages-types.ts +14 -0
- package/src/types/protocols-types.ts +2 -1
- package/src/utils/messages.ts +45 -0
- package/src/utils/replication.ts +19 -1
|
@@ -46,7 +46,8 @@ export type ProtocolType = {
|
|
|
46
46
|
* DID must have an X25519 keyAgreement key; protocol installation will
|
|
47
47
|
* fail if it does not.
|
|
48
48
|
*
|
|
49
|
-
* When `false` or omitted,
|
|
49
|
+
* When `false` or omitted, records of this type **must** be plaintext at the
|
|
50
|
+
* DWN record level. Applications cannot override this protocol policy per write.
|
|
50
51
|
*/
|
|
51
52
|
encryptionRequired?: boolean;
|
|
52
53
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocols-types.d.ts","sourceRoot":"","sources":["../../../../src/types/protocols-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAClG,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAExF,MAAM,MAAM,4BAA4B,GAAG;IACzC,SAAS,EAAG,gBAAgB,CAAC,SAAS,CAAC;IACvC,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,oBAAoB,CAAC;IACrC;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB;;;;;;;;;OASG;IACH,IAAI,CAAC,EAAE,YAAY,CAAC;IAEpB,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE;QACT,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAAC;KAChC,CAAA;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAEvB
|
|
1
|
+
{"version":3,"file":"protocols-types.d.ts","sourceRoot":"","sources":["../../../../src/types/protocols-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -36,6 +36,14 @@ export declare class Messages {
|
|
|
36
36
|
* (including cursor-based subscriptions) also apply to the shadow filter.
|
|
37
37
|
*/
|
|
38
38
|
private static constructProtocolConfigureShadowFilter;
|
|
39
|
+
/**
|
|
40
|
+
* Maps a filter set onto the replication fingerprint domains it covers, or
|
|
41
|
+
* `undefined` when the filters do not correspond to fingerprint domains.
|
|
42
|
+
* An empty filter set covers the global domain; a set of protocol-only
|
|
43
|
+
* filters covers each protocol's domain plus its tagged core-protocol
|
|
44
|
+
* domains. Any other filter shape has no domain mapping.
|
|
45
|
+
*/
|
|
46
|
+
static computeFingerprintScopes(filters: MessagesFilter[]): string[] | undefined;
|
|
39
47
|
/**
|
|
40
48
|
* Returns a copy of a RecordsWrite message without inline encodedData, and the
|
|
41
49
|
* detached encodedData value for wire surfaces that carry data beside the message.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../../src/utils/messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../../src/utils/messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAWjE;;GAEG;AACH,qBAAa,QAAQ;IACnB;;OAEG;WACW,gBAAgB,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE;IAwB3E;;;;;;;;;;OAUG;WACW,cAAc,CAAC,OAAO,EAAE,cAAc,EAAE,EAAE,aAAa,CAAC,EAAE,oBAAoB,GAAG,MAAM,EAAE;IAoBvG;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,4BAA4B;IAgB3C;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,sCAAsC;IAqBrD;;;;;;OAMG;WACW,wBAAwB,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,MAAM,EAAE,GAAG,SAAS;IAqCvF;;;OAGG;WACW,iBAAiB,CAAC,OAAO,EAAE,cAAc,GAAG;QAAE,OAAO,EAAE,cAAc,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE;IAY3G;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IAmC5B,OAAO,CAAC,MAAM,CAAC,cAAc;CAG9B"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { GenericMessage } from '../types/message-types.js';
|
|
2
2
|
import type { KeyValues } from '../types/query-types.js';
|
|
3
|
+
import type { ReplicationFeedReader } from '../types/subscriptions.js';
|
|
3
4
|
/**
|
|
4
5
|
* Shared helpers for the replication log substrate.
|
|
5
6
|
*/
|
|
@@ -9,12 +10,18 @@ export declare class Replication {
|
|
|
9
10
|
static permissionDomain(protocolUri: string): string;
|
|
10
11
|
static encryptionDomain(protocolUri: string): string;
|
|
11
12
|
static taggedCoreProtocolDomains(protocolUri: string, protocolsInScope?: ReadonlySet<string>): string[];
|
|
13
|
+
/**
|
|
14
|
+
* Narrows a message store to its replication feed surface when it implements
|
|
15
|
+
* one. Returns `undefined` for stores without replication feed support.
|
|
16
|
+
*/
|
|
17
|
+
static asFeedReader(candidate: unknown): ReplicationFeedReader | undefined;
|
|
12
18
|
static deriveStreamId(tenant: string): Promise<string>;
|
|
13
19
|
static computeFingerprintScopes(message: GenericMessage, indexes: KeyValues): string[];
|
|
14
20
|
static assertFingerprintScopesUntouched(persistedScopes: string[], message: GenericMessage, messageCid: string, newIndexes: KeyValues): void;
|
|
15
21
|
private static scopeSetsMatch;
|
|
16
22
|
private static throwFingerprintScopeMutation;
|
|
17
|
-
|
|
23
|
+
/** Whether a protocol URI is one of the core protocols (permissions, encryption). */
|
|
24
|
+
static isCoreProtocolUri(protocolUri: string): boolean;
|
|
18
25
|
static hashMessageCid(messageCid: string): Promise<Uint8Array>;
|
|
19
26
|
static emptyFingerprint(): Uint8Array;
|
|
20
27
|
static xorFingerprint(fingerprint: Uint8Array, contribution: Uint8Array): Uint8Array;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replication.d.ts","sourceRoot":"","sources":["../../../../src/utils/replication.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"replication.d.ts","sourceRoot":"","sources":["../../../../src/utils/replication.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAYvE;;GAEG;AACH,qBAAa,WAAW;IACtB,gBAAuB,YAAY,MAAM;WAE3B,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;WAI3C,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;WAI7C,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;WAI7C,yBAAyB,CAAC,WAAW,EAAE,MAAM,EAAE,gBAAgB,GAAE,WAAW,CAAC,MAAM,CAAa,GAAG,MAAM,EAAE;IAezH;;;OAGG;WACW,YAAY,CAAC,SAAS,EAAE,OAAO,GAAG,qBAAqB,GAAG,SAAS;WAY7D,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;WAOrD,wBAAwB,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS,GAAG,MAAM,EAAE;WAsB/E,gCAAgC,CAC5C,eAAe,EAAE,MAAM,EAAE,EACzB,OAAO,EAAE,cAAc,EACvB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,SAAS,GACpB,IAAI;IAOP,OAAO,CAAC,MAAM,CAAC,cAAc;IAQ7B,OAAO,CAAC,MAAM,CAAC,6BAA6B;IAO5C,qFAAqF;WACvE,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;WAIzC,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;WAM7D,gBAAgB,IAAI,UAAU;WAI9B,cAAc,CAAC,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,GAAG,UAAU;WAQ7E,gBAAgB,CAAC,WAAW,EAAE,UAAU,GAAG,MAAM;WAIjD,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU;WAQzC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;CAW1D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol-composition.spec.d.ts","sourceRoot":"","sources":["../../../../tests/features/protocol-composition.spec.ts"],"names":[],"mappings":"AAyBA;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"protocol-composition.spec.d.ts","sourceRoot":"","sources":["../../../../tests/features/protocol-composition.spec.ts"],"names":[],"mappings":"AAyBA;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,IAAI,CA0+E9C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages-query.spec.d.ts","sourceRoot":"","sources":["../../../../tests/handlers/messages-query.spec.ts"],"names":[],"mappings":"AAoCA,wBAAgB,wBAAwB,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"messages-query.spec.d.ts","sourceRoot":"","sources":["../../../../tests/handlers/messages-query.spec.ts"],"names":[],"mappings":"AAoCA,wBAAgB,wBAAwB,IAAI,IAAI,CA8a/C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages-subscribe.spec.d.ts","sourceRoot":"","sources":["../../../../tests/handlers/messages-subscribe.spec.ts"],"names":[],"mappings":"AA6BA,wBAAgB,4BAA4B,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"messages-subscribe.spec.d.ts","sourceRoot":"","sources":["../../../../tests/handlers/messages-subscribe.spec.ts"],"names":[],"mappings":"AA6BA,wBAAgB,4BAA4B,IAAI,IAAI,CAohDnD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocols-configure.spec.d.ts","sourceRoot":"","sources":["../../../../tests/handlers/protocols-configure.spec.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"protocols-configure.spec.d.ts","sourceRoot":"","sources":["../../../../tests/handlers/protocols-configure.spec.ts"],"names":[],"mappings":"AAwEA,wBAAgB,6BAA6B,IAAI,IAAI,CA+zEpD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"records-read.spec.d.ts","sourceRoot":"","sources":["../../../../tests/handlers/records-read.spec.ts"],"names":[],"mappings":"AAqCA,wBAAgB,sBAAsB,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"records-read.spec.d.ts","sourceRoot":"","sources":["../../../../tests/handlers/records-read.spec.ts"],"names":[],"mappings":"AAqCA,wBAAgB,sBAAsB,IAAI,IAAI,CAmpE7C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"records-write.spec.d.ts","sourceRoot":"","sources":["../../../../tests/handlers/records-write.spec.ts"],"names":[],"mappings":"AA+DA,wBAAgB,uBAAuB,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"records-write.spec.d.ts","sourceRoot":"","sources":["../../../../tests/handlers/records-write.spec.ts"],"names":[],"mappings":"AA+DA,wBAAgB,uBAAuB,IAAI,IAAI,CAg1M9C"}
|
package/package.json
CHANGED
package/src/core/constants.ts
CHANGED
|
@@ -19,6 +19,8 @@ export const PERMISSIONS_PROTOCOL_URI = 'https://identity.foundation/dwn/permiss
|
|
|
19
19
|
* The DWN Encryption protocol URI.
|
|
20
20
|
*/
|
|
21
21
|
export const ENCRYPTION_PROTOCOL_URI = 'https://identity.foundation/dwn/protocols/encryption';
|
|
22
|
+
export const ENCRYPTION_PROTOCOL_GRANT_KEY_PATH = 'grantKey';
|
|
23
|
+
export const ENCRYPTION_PROTOCOL_WRAPPED_GRANT_KEY_PATH = 'wrappedGrantKey';
|
|
22
24
|
|
|
23
25
|
/**
|
|
24
26
|
* Reserved virtual protocol path root for source-protocol-native encryption
|
package/src/core/dwn-error.ts
CHANGED
|
@@ -145,6 +145,7 @@ export enum DwnErrorCode {
|
|
|
145
145
|
ProtocolAuthorizationIncorrectProtocolPath = 'ProtocolAuthorizationIncorrectProtocolPath',
|
|
146
146
|
ProtocolAuthorizationInitialWriteRevalidationNotInitial = 'ProtocolAuthorizationInitialWriteRevalidationNotInitial',
|
|
147
147
|
ProtocolAuthorizationDuplicateRoleRecipient = 'ProtocolAuthorizationDuplicateRoleRecipient',
|
|
148
|
+
ProtocolAuthorizationEncryptionNotAllowed = 'ProtocolAuthorizationEncryptionNotAllowed',
|
|
148
149
|
ProtocolAuthorizationEncryptionRequired = 'ProtocolAuthorizationEncryptionRequired',
|
|
149
150
|
ProtocolAuthorizationEncryptionKeyAgreementMissing = 'ProtocolAuthorizationEncryptionKeyAgreementMissing',
|
|
150
151
|
ProtocolAuthorizationEncryptionProtocolPathEntryMissing = 'ProtocolAuthorizationEncryptionProtocolPathEntryMissing',
|
|
@@ -196,6 +197,7 @@ export enum DwnErrorCode {
|
|
|
196
197
|
ProtocolsConfigureInvalidEncryptedRoleMissingKeyAgreement = 'ProtocolsConfigureInvalidEncryptedRoleMissingKeyAgreement',
|
|
197
198
|
ProtocolsConfigureMissingEncryptedPathKeyAgreement = 'ProtocolsConfigureMissingEncryptedPathKeyAgreement',
|
|
198
199
|
ProtocolsConfigureMissingTopLevelKeyAgreement = 'ProtocolsConfigureMissingTopLevelKeyAgreement',
|
|
200
|
+
ProtocolsConfigureEncryptionPolicyImmutable = 'ProtocolsConfigureEncryptionPolicyImmutable',
|
|
199
201
|
ProtocolsConfigureInvalidRecipientOfAction = 'ProtocolsConfigureInvalidRecipientOfAction',
|
|
200
202
|
ProtocolsConfigureInvalidRuleSetRecordType = 'ProtocolsConfigureInvalidRuleSetRecordType',
|
|
201
203
|
ProtocolsConfigureInvalidTagSchema = 'ProtocolsConfigureInvalidTagSchema',
|
|
@@ -9,6 +9,7 @@ import { Records } from '../utils/records.js';
|
|
|
9
9
|
import { validateProtocolTags } from '../utils/protocol-tags.js';
|
|
10
10
|
import { DwnError, DwnErrorCode } from './dwn-error.js';
|
|
11
11
|
import { Encryption, ROLE_AUDIENCE_DERIVATION_SCHEME } from '../utils/encryption.js';
|
|
12
|
+
import { ENCRYPTION_PROTOCOL_GRANT_KEY_PATH, ENCRYPTION_PROTOCOL_URI } from './constants.js';
|
|
12
13
|
import { getRoleAudienceContextId, getRuleSetAtPath, getTypeName, parseCrossProtocolRef } from '../utils/protocols.js';
|
|
13
14
|
import { ProtocolAction, ProtocolRecordLimitStrategy } from '../types/protocols-types.js';
|
|
14
15
|
|
|
@@ -275,6 +276,13 @@ export function verifyType(
|
|
|
275
276
|
);
|
|
276
277
|
}
|
|
277
278
|
|
|
279
|
+
if (protocolType.encryptionRequired !== true && inboundMessage.encryption !== undefined) {
|
|
280
|
+
throw new DwnError(
|
|
281
|
+
DwnErrorCode.ProtocolAuthorizationEncryptionNotAllowed,
|
|
282
|
+
`type '${declaredTypeName}' requires plaintext but message has encryption metadata`
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
|
|
278
286
|
return protocolType;
|
|
279
287
|
}
|
|
280
288
|
|
|
@@ -291,6 +299,12 @@ async function verifyProtocolPathEncryptionIfNeeded(
|
|
|
291
299
|
|
|
292
300
|
const ruleSet = getRuleSetAtPath(inboundMessage.descriptor.protocolPath, protocolDefinition.structure);
|
|
293
301
|
if (ruleSet?.$keyAgreement?.publicKeyJwk === undefined) {
|
|
302
|
+
const usesDynamicCoreRecipientKey = protocolDefinition.protocol === ENCRYPTION_PROTOCOL_URI &&
|
|
303
|
+
inboundMessage.descriptor.protocolPath === ENCRYPTION_PROTOCOL_GRANT_KEY_PATH;
|
|
304
|
+
if (usesDynamicCoreRecipientKey) {
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
|
|
294
308
|
throw new DwnError(
|
|
295
309
|
DwnErrorCode.ProtocolAuthorizationEncryptionKeyAgreementMissing,
|
|
296
310
|
`encrypted protocol path '${inboundMessage.descriptor.protocolPath}' has no $keyAgreement`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EventLogEntry, ProgressGapInfo
|
|
1
|
+
import type { EventLogEntry, ProgressGapInfo } from '../types/subscriptions.js';
|
|
2
2
|
import type { Filter, KeyValues } from '../types/query-types.js';
|
|
3
3
|
import type { HandlerDependencies, MethodHandler } from '../types/method-handler.js';
|
|
4
4
|
import type { MessagesFilter, MessagesQueryMessage, MessagesQueryReply, MessagesQueryReplyEntry } from '../types/messages-types.js';
|
|
@@ -31,7 +31,7 @@ export class MessagesQueryHandler implements MethodHandler {
|
|
|
31
31
|
return messageReplyFromError(e, 401);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
const replicationFeedReader =
|
|
34
|
+
const replicationFeedReader = Replication.asFeedReader(this.deps.messageStore);
|
|
35
35
|
if (replicationFeedReader === undefined) {
|
|
36
36
|
return {
|
|
37
37
|
status: {
|
|
@@ -56,7 +56,7 @@ export class MessagesQueryHandler implements MethodHandler {
|
|
|
56
56
|
drained : result.drained,
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
-
const fingerprintScopes =
|
|
59
|
+
const fingerprintScopes = Messages.computeFingerprintScopes(message.descriptor.filters);
|
|
60
60
|
if (fingerprintScopes !== undefined) {
|
|
61
61
|
reply.fingerprint = await replicationFeedReader.fingerprint(tenant, fingerprintScopes);
|
|
62
62
|
}
|
|
@@ -87,18 +87,6 @@ export class MessagesQueryHandler implements MethodHandler {
|
|
|
87
87
|
});
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
private static asReplicationFeedReader(candidate: unknown): ReplicationFeedReader | undefined {
|
|
91
|
-
const partial = candidate as Partial<ReplicationFeedReader>;
|
|
92
|
-
if (
|
|
93
|
-
typeof partial.logRead === 'function' &&
|
|
94
|
-
typeof partial.logBounds === 'function' &&
|
|
95
|
-
typeof partial.fingerprint === 'function' &&
|
|
96
|
-
typeof partial.epoch === 'function'
|
|
97
|
-
) {
|
|
98
|
-
return partial as ReplicationFeedReader;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
90
|
private static convertFilters(filters: MessagesFilter[], deps: HandlerDependencies): Filter[] | undefined {
|
|
103
91
|
if (filters.length === 0) {
|
|
104
92
|
return undefined;
|
|
@@ -155,32 +143,6 @@ export class MessagesQueryHandler implements MethodHandler {
|
|
|
155
143
|
return indexes.isLatestBaseState === true || indexes.isLatestBaseState === 'true';
|
|
156
144
|
}
|
|
157
145
|
|
|
158
|
-
private static computeFingerprintScopes(filters: MessagesFilter[]): string[] | undefined {
|
|
159
|
-
if (filters.length === 0) {
|
|
160
|
-
return [Replication.globalDomain];
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const protocols = new Set<string>();
|
|
164
|
-
for (const filter of filters) {
|
|
165
|
-
const keys = Object.keys(filter);
|
|
166
|
-
if (keys.length !== 1 || typeof filter.protocol !== 'string') {
|
|
167
|
-
return undefined;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
protocols.add(filter.protocol);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const scopes: string[] = [];
|
|
174
|
-
for (const protocol of protocols) {
|
|
175
|
-
scopes.push(
|
|
176
|
-
Replication.protocolDomain(protocol),
|
|
177
|
-
...Replication.taggedCoreProtocolDomains(protocol, protocols),
|
|
178
|
-
);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return scopes;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
146
|
private static getProgressGapInfo(error: DwnError): ProgressGapInfo | undefined {
|
|
185
147
|
const gapInfo = (error as DwnError & { gapInfo?: ProgressGapInfo }).gapInfo;
|
|
186
148
|
return gapInfo;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { PermissionGrant } from '../protocols/permission-grant.js';
|
|
2
|
-
import type { EventSubscription, ProgressGapInfo, SubscriptionEvent, SubscriptionListener, SubscriptionMessage } from '../types/subscriptions.js';
|
|
2
|
+
import type { EventSubscription, ProgressGapInfo, ProgressToken, ReplicationFeedReader, SubscriptionEvent, SubscriptionListener, SubscriptionMessage } from '../types/subscriptions.js';
|
|
3
3
|
import type { HandlerDependencies, MethodHandler } from '../types/method-handler.js';
|
|
4
|
-
import type { MessagesSubscribeMessage, MessagesSubscribeReply } from '../types/messages-types.js';
|
|
4
|
+
import type { MessagesFilter, MessagesSubscribeMessage, MessagesSubscribeReply } from '../types/messages-types.js';
|
|
5
5
|
|
|
6
6
|
import { authenticate } from '../core/auth.js';
|
|
7
7
|
import { Message } from '../core/message.js';
|
|
@@ -9,6 +9,7 @@ import { messageReplyFromError } from '../core/message-reply.js';
|
|
|
9
9
|
import { Messages } from '../utils/messages.js';
|
|
10
10
|
import { MessagesGrantAuthorization } from '../core/messages-grant-authorization.js';
|
|
11
11
|
import { MessagesSubscribe } from '../interfaces/messages-subscribe.js';
|
|
12
|
+
import { Replication } from '../utils/replication.js';
|
|
12
13
|
import { Time } from '../utils/time.js';
|
|
13
14
|
import { DwnError, DwnErrorCode } from '../core/dwn-error.js';
|
|
14
15
|
|
|
@@ -79,10 +80,20 @@ export class MessagesSubscribeHandler implements MethodHandler {
|
|
|
79
80
|
});
|
|
80
81
|
await guardedHandler.setSubscription(subscription);
|
|
81
82
|
|
|
82
|
-
|
|
83
|
+
const reply: MessagesSubscribeReply = {
|
|
83
84
|
status: { code: 200, detail: 'OK' },
|
|
84
85
|
subscription,
|
|
85
86
|
};
|
|
87
|
+
try {
|
|
88
|
+
await MessagesSubscribeHandler.attachFeedSnapshot(reply, tenant, filters, this.deps);
|
|
89
|
+
} catch {
|
|
90
|
+
// Best-effort enrichment: the subscription is live and correct
|
|
91
|
+
// without the snapshot — consumers feature-detect the fields. A
|
|
92
|
+
// failure reply here would orphan the just-installed listener, since
|
|
93
|
+
// close handles are registered only from successful replies.
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return reply;
|
|
86
97
|
} catch (error) {
|
|
87
98
|
if (error instanceof DwnError && error.code === DwnErrorCode.EventLogProgressGap) {
|
|
88
99
|
const gapInfo = (error as any).gapInfo as ProgressGapInfo | undefined;
|
|
@@ -95,6 +106,59 @@ export class MessagesSubscribeHandler implements MethodHandler {
|
|
|
95
106
|
}
|
|
96
107
|
}
|
|
97
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Attaches the replication feed's `head` token and scope `fingerprint` to a
|
|
111
|
+
* successful subscribe reply, when the message store exposes the feed.
|
|
112
|
+
*
|
|
113
|
+
* Ordering is load-bearing: both values are observed AFTER the subscription
|
|
114
|
+
* became active, so every event past `head` is either replayable from it or
|
|
115
|
+
* already flowing on the live stream — a caller that verifies `fingerprint`
|
|
116
|
+
* against its local feed may adopt `head` as a checkpoint without a delivery
|
|
117
|
+
* gap. The head is captured before the fingerprint, mirroring MessagesQuery's
|
|
118
|
+
* cursor-then-fingerprint order: an event landing between the two captures
|
|
119
|
+
* makes the fingerprint read ahead of the head, which a consumer observes as
|
|
120
|
+
* a mismatch (one redundant reconcile), never as a silently skipped event.
|
|
121
|
+
*/
|
|
122
|
+
private static async attachFeedSnapshot(
|
|
123
|
+
reply: MessagesSubscribeReply,
|
|
124
|
+
tenant: string,
|
|
125
|
+
filters: MessagesFilter[],
|
|
126
|
+
deps: HandlerDependencies,
|
|
127
|
+
): Promise<void> {
|
|
128
|
+
const feedReader = Replication.asFeedReader(deps.messageStore);
|
|
129
|
+
if (feedReader === undefined) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Build the complete snapshot before attaching anything: a partial
|
|
134
|
+
// snapshot (a head without its fingerprint) would read to consumers as
|
|
135
|
+
// a fingerprint-less server rather than as a failed capture.
|
|
136
|
+
const bounds = await feedReader.logBounds(tenant);
|
|
137
|
+
const head = bounds?.latest ?? await MessagesSubscribeHandler.buildAnchorToken(tenant, feedReader);
|
|
138
|
+
|
|
139
|
+
const fingerprintScopes = Messages.computeFingerprintScopes(filters);
|
|
140
|
+
const fingerprint = fingerprintScopes === undefined
|
|
141
|
+
? undefined
|
|
142
|
+
: await feedReader.fingerprint(tenant, fingerprintScopes);
|
|
143
|
+
|
|
144
|
+
reply.head = head;
|
|
145
|
+
if (fingerprint !== undefined) {
|
|
146
|
+
reply.fingerprint = fingerprint;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** Builds the position-zero anchor token for a tenant log with no events. */
|
|
151
|
+
private static async buildAnchorToken(
|
|
152
|
+
tenant: string,
|
|
153
|
+
feedReader: ReplicationFeedReader,
|
|
154
|
+
): Promise<ProgressToken> {
|
|
155
|
+
return {
|
|
156
|
+
streamId : await Replication.deriveStreamId(tenant),
|
|
157
|
+
epoch : await feedReader.epoch(),
|
|
158
|
+
position : '0',
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
98
162
|
private static async authorizeMessagesSubscribe(
|
|
99
163
|
tenant: string,
|
|
100
164
|
messagesSubscribe: MessagesSubscribe,
|