@enbox/dwn-sdk-js 0.0.6 → 0.0.8
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 +8 -8
- package/dist/browser.mjs.map +4 -4
- package/dist/esm/generated/precompiled-validators.js +762 -911
- package/dist/esm/generated/precompiled-validators.js.map +1 -1
- package/dist/esm/src/core/abstract-message.js +4 -0
- package/dist/esm/src/core/abstract-message.js.map +1 -1
- package/dist/esm/src/core/auth.js +22 -33
- package/dist/esm/src/core/auth.js.map +1 -1
- package/dist/esm/src/core/constants.js +11 -0
- package/dist/esm/src/core/constants.js.map +1 -0
- package/dist/esm/src/core/core-protocol.js +44 -0
- package/dist/esm/src/core/core-protocol.js.map +1 -0
- package/dist/esm/src/core/dwn-constant.js +7 -7
- package/dist/esm/src/core/dwn-constant.js.map +1 -1
- package/dist/esm/src/core/dwn-error.js +10 -12
- package/dist/esm/src/core/dwn-error.js.map +1 -1
- package/dist/esm/src/core/grant-authorization.js +50 -52
- package/dist/esm/src/core/grant-authorization.js.map +1 -1
- package/dist/esm/src/core/message.js +85 -116
- package/dist/esm/src/core/message.js.map +1 -1
- package/dist/esm/src/core/messages-grant-authorization.js +63 -78
- package/dist/esm/src/core/messages-grant-authorization.js.map +1 -1
- package/dist/esm/src/core/protocol-authorization-action.js +266 -0
- package/dist/esm/src/core/protocol-authorization-action.js.map +1 -0
- package/dist/esm/src/core/protocol-authorization-validation.js +321 -0
- package/dist/esm/src/core/protocol-authorization-validation.js.map +1 -0
- package/dist/esm/src/core/protocol-authorization.js +144 -741
- package/dist/esm/src/core/protocol-authorization.js.map +1 -1
- package/dist/esm/src/core/protocols-grant-authorization.js +24 -38
- package/dist/esm/src/core/protocols-grant-authorization.js.map +1 -1
- package/dist/esm/src/core/record-chain.js +64 -0
- package/dist/esm/src/core/record-chain.js.map +1 -0
- package/dist/esm/src/core/records-grant-authorization.js +53 -72
- package/dist/esm/src/core/records-grant-authorization.js.map +1 -1
- package/dist/esm/src/core/resumable-task-manager.js +50 -65
- package/dist/esm/src/core/resumable-task-manager.js.map +1 -1
- package/dist/esm/src/core/tenant-gate.js +2 -13
- package/dist/esm/src/core/tenant-gate.js.map +1 -1
- package/dist/esm/src/dwn.js +108 -101
- package/dist/esm/src/dwn.js.map +1 -1
- package/dist/esm/src/event-stream/event-emitter-event-log.js +204 -0
- package/dist/esm/src/event-stream/event-emitter-event-log.js.map +1 -0
- package/dist/esm/src/handlers/messages-read.js +67 -81
- package/dist/esm/src/handlers/messages-read.js.map +1 -1
- package/dist/esm/src/handlers/messages-subscribe.js +51 -63
- package/dist/esm/src/handlers/messages-subscribe.js.map +1 -1
- package/dist/esm/src/handlers/messages-sync.js +75 -89
- package/dist/esm/src/handlers/messages-sync.js.map +1 -1
- package/dist/esm/src/handlers/protocols-configure.js +153 -163
- package/dist/esm/src/handlers/protocols-configure.js.map +1 -1
- package/dist/esm/src/handlers/protocols-query.js +52 -55
- package/dist/esm/src/handlers/protocols-query.js.map +1 -1
- package/dist/esm/src/handlers/records-count.js +97 -85
- package/dist/esm/src/handlers/records-count.js.map +1 -1
- package/dist/esm/src/handlers/records-delete.js +75 -93
- package/dist/esm/src/handlers/records-delete.js.map +1 -1
- package/dist/esm/src/handlers/records-query.js +116 -105
- package/dist/esm/src/handlers/records-query.js.map +1 -1
- package/dist/esm/src/handlers/records-read.js +130 -132
- package/dist/esm/src/handlers/records-read.js.map +1 -1
- package/dist/esm/src/handlers/records-subscribe.js +164 -104
- package/dist/esm/src/handlers/records-subscribe.js.map +1 -1
- package/dist/esm/src/handlers/records-write.js +213 -280
- package/dist/esm/src/handlers/records-write.js.map +1 -1
- package/dist/esm/src/index.js +5 -2
- package/dist/esm/src/index.js.map +1 -1
- package/dist/esm/src/interfaces/messages-read.js +24 -32
- package/dist/esm/src/interfaces/messages-read.js.map +1 -1
- package/dist/esm/src/interfaces/messages-subscribe.js +28 -41
- package/dist/esm/src/interfaces/messages-subscribe.js.map +1 -1
- package/dist/esm/src/interfaces/messages-sync.js +26 -40
- package/dist/esm/src/interfaces/messages-sync.js.map +1 -1
- package/dist/esm/src/interfaces/protocols-configure.js +87 -65
- package/dist/esm/src/interfaces/protocols-configure.js.map +1 -1
- package/dist/esm/src/interfaces/protocols-query.js +55 -68
- package/dist/esm/src/interfaces/protocols-query.js.map +1 -1
- package/dist/esm/src/interfaces/records-count.js +50 -66
- package/dist/esm/src/interfaces/records-count.js.map +1 -1
- package/dist/esm/src/interfaces/records-delete.js +45 -55
- package/dist/esm/src/interfaces/records-delete.js.map +1 -1
- package/dist/esm/src/interfaces/records-query.js +60 -76
- package/dist/esm/src/interfaces/records-query.js.map +1 -1
- package/dist/esm/src/interfaces/records-read.js +51 -67
- package/dist/esm/src/interfaces/records-read.js.map +1 -1
- package/dist/esm/src/interfaces/records-subscribe.js +53 -68
- package/dist/esm/src/interfaces/records-subscribe.js.map +1 -1
- package/dist/esm/src/interfaces/records-write-query.js +102 -0
- package/dist/esm/src/interfaces/records-write-query.js.map +1 -0
- package/dist/esm/src/interfaces/records-write-signing.js +81 -0
- package/dist/esm/src/interfaces/records-write-signing.js.map +1 -0
- package/dist/esm/src/interfaces/records-write.js +396 -610
- package/dist/esm/src/interfaces/records-write.js.map +1 -1
- package/dist/esm/src/jose/algorithms/signing/ed25519.js +10 -19
- package/dist/esm/src/jose/algorithms/signing/ed25519.js.map +1 -1
- package/dist/esm/src/jose/jws/general/builder.js +23 -35
- package/dist/esm/src/jose/jws/general/builder.js.map +1 -1
- package/dist/esm/src/jose/jws/general/verifier.js +56 -69
- package/dist/esm/src/jose/jws/general/verifier.js.map +1 -1
- package/dist/esm/src/protocols/permission-grant.js +43 -14
- package/dist/esm/src/protocols/permission-grant.js.map +1 -1
- package/dist/esm/src/protocols/permission-request.js +28 -14
- package/dist/esm/src/protocols/permission-request.js.map +1 -1
- package/dist/esm/src/protocols/permissions.js +325 -227
- package/dist/esm/src/protocols/permissions.js.map +1 -1
- package/dist/esm/src/smt/smt-store-level.js +42 -64
- package/dist/esm/src/smt/smt-store-level.js.map +1 -1
- package/dist/esm/src/smt/smt-store-memory.js +19 -45
- package/dist/esm/src/smt/smt-store-memory.js.map +1 -1
- package/dist/esm/src/smt/smt-utils.js +28 -45
- package/dist/esm/src/smt/smt-utils.js.map +1 -1
- package/dist/esm/src/smt/sparse-merkle-tree.js +426 -471
- package/dist/esm/src/smt/sparse-merkle-tree.js.map +1 -1
- package/dist/esm/src/state-index/state-index-level.js +113 -150
- package/dist/esm/src/state-index/state-index-level.js.map +1 -1
- package/dist/esm/src/store/blockstore-level.js +54 -156
- package/dist/esm/src/store/blockstore-level.js.map +1 -1
- package/dist/esm/src/store/blockstore-mock.js +48 -153
- package/dist/esm/src/store/blockstore-mock.js.map +1 -1
- package/dist/esm/src/store/data-store-level.js +137 -100
- package/dist/esm/src/store/data-store-level.js.map +1 -1
- package/dist/esm/src/store/index-level-compound.js +246 -0
- package/dist/esm/src/store/index-level-compound.js.map +1 -0
- package/dist/esm/src/store/index-level.js +307 -715
- package/dist/esm/src/store/index-level.js.map +1 -1
- package/dist/esm/src/store/level-wrapper.js +143 -244
- package/dist/esm/src/store/level-wrapper.js.map +1 -1
- package/dist/esm/src/store/message-store-level.js +71 -94
- package/dist/esm/src/store/message-store-level.js.map +1 -1
- package/dist/esm/src/store/resumable-task-store-level.js +62 -101
- package/dist/esm/src/store/resumable-task-store-level.js.map +1 -1
- package/dist/esm/src/store/storage-controller.js +131 -146
- package/dist/esm/src/store/storage-controller.js.map +1 -1
- package/dist/esm/src/types/permission-types.js.map +1 -1
- package/dist/esm/src/types/protocols-types.js +10 -0
- package/dist/esm/src/types/protocols-types.js.map +1 -1
- package/dist/esm/src/types/records-types.js.map +1 -1
- package/dist/esm/src/utils/abort.js +8 -19
- package/dist/esm/src/utils/abort.js.map +1 -1
- package/dist/esm/src/utils/array.js +15 -49
- package/dist/esm/src/utils/array.js.map +1 -1
- package/dist/esm/src/utils/cid.js +29 -77
- package/dist/esm/src/utils/cid.js.map +1 -1
- package/dist/esm/src/utils/data-stream.js +37 -65
- package/dist/esm/src/utils/data-stream.js.map +1 -1
- package/dist/esm/src/utils/encryption.js +136 -162
- package/dist/esm/src/utils/encryption.js.map +1 -1
- package/dist/esm/src/utils/filter.js +1 -12
- package/dist/esm/src/utils/filter.js.map +1 -1
- package/dist/esm/src/utils/hd-key.js +45 -71
- package/dist/esm/src/utils/hd-key.js.map +1 -1
- package/dist/esm/src/utils/jws.js +9 -20
- package/dist/esm/src/utils/jws.js.map +1 -1
- package/dist/esm/src/utils/memory-cache.js +12 -23
- package/dist/esm/src/utils/memory-cache.js.map +1 -1
- package/dist/esm/src/utils/messages.js +21 -33
- package/dist/esm/src/utils/messages.js.map +1 -1
- package/dist/esm/src/utils/private-key-signer.js +9 -17
- package/dist/esm/src/utils/private-key-signer.js.map +1 -1
- package/dist/esm/src/utils/protocols.js +62 -70
- package/dist/esm/src/utils/protocols.js.map +1 -1
- package/dist/esm/src/utils/records.js +103 -166
- package/dist/esm/src/utils/records.js.map +1 -1
- package/dist/esm/src/utils/secp256k1.js +60 -96
- package/dist/esm/src/utils/secp256k1.js.map +1 -1
- package/dist/esm/src/utils/secp256r1.js +54 -71
- package/dist/esm/src/utils/secp256r1.js.map +1 -1
- package/dist/esm/src/utils/time.js +5 -18
- package/dist/esm/src/utils/time.js.map +1 -1
- package/dist/esm/src/utils/url.js +3 -3
- package/dist/esm/src/utils/url.js.map +1 -1
- package/dist/esm/tests/core/auth.spec.js +3 -12
- package/dist/esm/tests/core/auth.spec.js.map +1 -1
- package/dist/esm/tests/core/message.spec.js +50 -59
- package/dist/esm/tests/core/message.spec.js.map +1 -1
- package/dist/esm/tests/core/protocol-authorization.spec.js +10 -18
- package/dist/esm/tests/core/protocol-authorization.spec.js.map +1 -1
- package/dist/esm/tests/dwn.spec.js +65 -89
- package/dist/esm/tests/dwn.spec.js.map +1 -1
- package/dist/esm/tests/event-emitter-event-log.spec.js +305 -0
- package/dist/esm/tests/event-emitter-event-log.spec.js.map +1 -0
- package/dist/esm/tests/features/author-delegated-grant.spec.js +337 -347
- package/dist/esm/tests/features/author-delegated-grant.spec.js.map +1 -1
- package/dist/esm/tests/features/owner-delegated-grant.spec.js +160 -172
- package/dist/esm/tests/features/owner-delegated-grant.spec.js.map +1 -1
- package/dist/esm/tests/features/owner-signature.spec.js +78 -82
- package/dist/esm/tests/features/owner-signature.spec.js.map +1 -1
- package/dist/esm/tests/features/permissions.spec.js +449 -184
- package/dist/esm/tests/features/permissions.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-composition.spec.js +981 -360
- package/dist/esm/tests/features/protocol-composition.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-create-action.spec.js +45 -54
- package/dist/esm/tests/features/protocol-create-action.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-delete-action.spec.js +99 -108
- package/dist/esm/tests/features/protocol-delete-action.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-update-action.spec.js +108 -117
- package/dist/esm/tests/features/protocol-update-action.spec.js.map +1 -1
- package/dist/esm/tests/features/records-immutable.spec.js +315 -0
- package/dist/esm/tests/features/records-immutable.spec.js.map +1 -0
- package/dist/esm/tests/features/records-prune.spec.js +178 -194
- package/dist/esm/tests/features/records-prune.spec.js.map +1 -1
- package/dist/esm/tests/features/records-record-limit.spec.js +542 -0
- package/dist/esm/tests/features/records-record-limit.spec.js.map +1 -0
- package/dist/esm/tests/features/records-tags.spec.js +456 -463
- package/dist/esm/tests/features/records-tags.spec.js.map +1 -1
- package/dist/esm/tests/features/resumable-tasks.spec.js +88 -98
- package/dist/esm/tests/features/resumable-tasks.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-read.spec.js +215 -210
- package/dist/esm/tests/handlers/messages-read.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-subscribe.spec.js +309 -171
- package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-sync.spec.js +272 -199
- package/dist/esm/tests/handlers/messages-sync.spec.js.map +1 -1
- package/dist/esm/tests/handlers/protocols-configure.spec.js +247 -241
- package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -1
- package/dist/esm/tests/handlers/protocols-query.spec.js +159 -172
- package/dist/esm/tests/handlers/protocols-query.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-count.spec.js +101 -105
- package/dist/esm/tests/handlers/records-count.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-delete.spec.js +266 -279
- package/dist/esm/tests/handlers/records-delete.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-query.spec.js +984 -996
- package/dist/esm/tests/handlers/records-query.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-read.spec.js +542 -671
- package/dist/esm/tests/handlers/records-read.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-subscribe.spec.js +433 -302
- package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-write.spec.js +1216 -1140
- package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/messages-get.spec.js +39 -48
- package/dist/esm/tests/interfaces/messages-get.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/messages-subscribe.spec.js +4 -13
- package/dist/esm/tests/interfaces/messages-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/protocols-configure.spec.js +212 -88
- package/dist/esm/tests/interfaces/protocols-configure.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/protocols-query.spec.js +8 -17
- package/dist/esm/tests/interfaces/protocols-query.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-delete.spec.js +8 -17
- package/dist/esm/tests/interfaces/records-delete.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-query.spec.js +20 -29
- package/dist/esm/tests/interfaces/records-query.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-read.spec.js +42 -51
- package/dist/esm/tests/interfaces/records-read.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-subscribe.spec.js +16 -25
- package/dist/esm/tests/interfaces/records-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-write.spec.js +190 -219
- package/dist/esm/tests/interfaces/records-write.spec.js.map +1 -1
- package/dist/esm/tests/jose/jws/general.spec.js +36 -45
- package/dist/esm/tests/jose/jws/general.spec.js.map +1 -1
- package/dist/esm/tests/protocols/permission-grant.spec.js +44 -50
- package/dist/esm/tests/protocols/permission-grant.spec.js.map +1 -1
- package/dist/esm/tests/protocols/permission-request.spec.js +23 -32
- package/dist/esm/tests/protocols/permission-request.spec.js.map +1 -1
- package/dist/esm/tests/protocols/permissions.spec.js +49 -55
- package/dist/esm/tests/protocols/permissions.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/aggregator.spec.js +127 -138
- package/dist/esm/tests/scenarios/aggregator.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/deleted-record.spec.js +372 -36
- package/dist/esm/tests/scenarios/deleted-record.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js +55 -64
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/nested-roles.spec.js +66 -76
- package/dist/esm/tests/scenarios/nested-roles.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/subscriptions.spec.js +451 -354
- package/dist/esm/tests/scenarios/subscriptions.spec.js.map +1 -1
- package/dist/esm/tests/smt/smt-store-level.spec.js +76 -87
- package/dist/esm/tests/smt/smt-store-level.spec.js.map +1 -1
- package/dist/esm/tests/smt/sparse-merkle-tree.spec.js +344 -353
- package/dist/esm/tests/smt/sparse-merkle-tree.spec.js.map +1 -1
- package/dist/esm/tests/state-index/state-index-level.spec.js +117 -126
- package/dist/esm/tests/state-index/state-index-level.spec.js.map +1 -1
- package/dist/esm/tests/store/blockstore-level.spec.js +44 -99
- package/dist/esm/tests/store/blockstore-level.spec.js.map +1 -1
- package/dist/esm/tests/store/blockstore-mock.spec.js +40 -120
- package/dist/esm/tests/store/blockstore-mock.spec.js.map +1 -1
- package/dist/esm/tests/store/data-store-level.spec.js +160 -108
- package/dist/esm/tests/store/data-store-level.spec.js.map +1 -1
- package/dist/esm/tests/store/index-level.spec.js +404 -414
- package/dist/esm/tests/store/index-level.spec.js.map +1 -1
- package/dist/esm/tests/store/message-store-level.spec.js +13 -22
- package/dist/esm/tests/store/message-store-level.spec.js.map +1 -1
- package/dist/esm/tests/store/message-store.spec.js +229 -238
- package/dist/esm/tests/store/message-store.spec.js.map +1 -1
- package/dist/esm/tests/test-event-stream.js +12 -13
- package/dist/esm/tests/test-event-stream.js.map +1 -1
- package/dist/esm/tests/test-stores.js +16 -13
- package/dist/esm/tests/test-stores.js.map +1 -1
- package/dist/esm/tests/test-suite.js +8 -15
- package/dist/esm/tests/test-suite.js.map +1 -1
- package/dist/esm/tests/utils/cid.spec.js +24 -33
- package/dist/esm/tests/utils/cid.spec.js.map +1 -1
- package/dist/esm/tests/utils/data-stream.spec.js +48 -57
- package/dist/esm/tests/utils/data-stream.spec.js.map +1 -1
- package/dist/esm/tests/utils/encryption-callbacks.spec.js +45 -54
- package/dist/esm/tests/utils/encryption-callbacks.spec.js.map +1 -1
- package/dist/esm/tests/utils/encryption.spec.js +229 -82
- package/dist/esm/tests/utils/encryption.spec.js.map +1 -1
- package/dist/esm/tests/utils/filters.spec.js +46 -55
- package/dist/esm/tests/utils/filters.spec.js.map +1 -1
- package/dist/esm/tests/utils/hd-key.spec.js +10 -19
- package/dist/esm/tests/utils/hd-key.spec.js.map +1 -1
- package/dist/esm/tests/utils/jws.spec.js +3 -12
- package/dist/esm/tests/utils/jws.spec.js.map +1 -1
- package/dist/esm/tests/utils/memory-cache.spec.js +9 -18
- package/dist/esm/tests/utils/memory-cache.spec.js.map +1 -1
- package/dist/esm/tests/utils/messages.spec.js +18 -20
- package/dist/esm/tests/utils/messages.spec.js.map +1 -1
- package/dist/esm/tests/utils/poller.js +22 -33
- package/dist/esm/tests/utils/poller.js.map +1 -1
- package/dist/esm/tests/utils/private-key-signer.spec.js +15 -24
- package/dist/esm/tests/utils/private-key-signer.spec.js.map +1 -1
- package/dist/esm/tests/utils/records.spec.js +14 -27
- package/dist/esm/tests/utils/records.spec.js.map +1 -1
- package/dist/esm/tests/utils/secp256k1.spec.js +16 -25
- package/dist/esm/tests/utils/secp256k1.spec.js.map +1 -1
- package/dist/esm/tests/utils/secp256r1.spec.js +18 -27
- package/dist/esm/tests/utils/secp256r1.spec.js.map +1 -1
- package/dist/esm/tests/utils/test-data-generator.js +446 -467
- package/dist/esm/tests/utils/test-data-generator.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/definitions.spec.js +2 -11
- package/dist/esm/tests/validation/json-schemas/definitions.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/jwk/general-jwk.spec.js +4 -13
- package/dist/esm/tests/validation/json-schemas/jwk/general-jwk.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/jwk/public-jwk.spec.js +8 -17
- package/dist/esm/tests/validation/json-schemas/jwk/public-jwk.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/jwk-verification-method.spec.js +3 -12
- package/dist/esm/tests/validation/json-schemas/jwk-verification-method.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js +4 -13
- package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/records/records-query.spec.js +2 -11
- package/dist/esm/tests/validation/json-schemas/records/records-query.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/records/records-read.spec.js +2 -11
- package/dist/esm/tests/validation/json-schemas/records/records-read.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js +44 -24
- package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js.map +1 -1
- package/dist/types/generated/precompiled-validators.d.ts +49 -40
- package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
- package/dist/types/src/core/constants.d.ts +11 -0
- package/dist/types/src/core/constants.d.ts.map +1 -0
- package/dist/types/src/core/core-protocol.d.ts +89 -0
- package/dist/types/src/core/core-protocol.d.ts.map +1 -0
- package/dist/types/src/core/dwn-error.d.ts +9 -12
- package/dist/types/src/core/dwn-error.d.ts.map +1 -1
- package/dist/types/src/core/grant-authorization.d.ts +6 -2
- package/dist/types/src/core/grant-authorization.d.ts.map +1 -1
- package/dist/types/src/core/protocol-authorization-action.d.ts +42 -0
- package/dist/types/src/core/protocol-authorization-action.d.ts.map +1 -0
- package/dist/types/src/core/protocol-authorization-validation.d.ts +81 -0
- package/dist/types/src/core/protocol-authorization-validation.d.ts.map +1 -0
- package/dist/types/src/core/protocol-authorization.d.ts +24 -106
- package/dist/types/src/core/protocol-authorization.d.ts.map +1 -1
- package/dist/types/src/core/record-chain.d.ts +24 -0
- package/dist/types/src/core/record-chain.d.ts.map +1 -0
- package/dist/types/src/core/records-grant-authorization.d.ts.map +1 -1
- package/dist/types/src/dwn.d.ts +19 -7
- package/dist/types/src/dwn.d.ts.map +1 -1
- package/dist/types/src/event-stream/event-emitter-event-log.d.ts +50 -0
- package/dist/types/src/event-stream/event-emitter-event-log.d.ts.map +1 -0
- package/dist/types/src/handlers/messages-read.d.ts +3 -8
- package/dist/types/src/handlers/messages-read.d.ts.map +1 -1
- package/dist/types/src/handlers/messages-subscribe.d.ts +6 -10
- package/dist/types/src/handlers/messages-subscribe.d.ts.map +1 -1
- package/dist/types/src/handlers/messages-sync.d.ts +3 -8
- package/dist/types/src/handlers/messages-sync.d.ts.map +1 -1
- package/dist/types/src/handlers/protocols-configure.d.ts +3 -10
- package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -1
- package/dist/types/src/handlers/protocols-query.d.ts +3 -8
- package/dist/types/src/handlers/protocols-query.d.ts.map +1 -1
- package/dist/types/src/handlers/records-count.d.ts +3 -6
- package/dist/types/src/handlers/records-count.d.ts.map +1 -1
- package/dist/types/src/handlers/records-delete.d.ts +3 -8
- package/dist/types/src/handlers/records-delete.d.ts.map +1 -1
- package/dist/types/src/handlers/records-query.d.ts +3 -8
- package/dist/types/src/handlers/records-query.d.ts.map +1 -1
- package/dist/types/src/handlers/records-read.d.ts +3 -8
- package/dist/types/src/handlers/records-read.d.ts.map +1 -1
- package/dist/types/src/handlers/records-subscribe.d.ts +8 -10
- package/dist/types/src/handlers/records-subscribe.d.ts.map +1 -1
- package/dist/types/src/handlers/records-write.d.ts +4 -24
- package/dist/types/src/handlers/records-write.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +8 -4
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/interfaces/messages-subscribe.d.ts +5 -0
- package/dist/types/src/interfaces/messages-subscribe.d.ts.map +1 -1
- package/dist/types/src/interfaces/protocols-configure.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-subscribe.d.ts +5 -0
- package/dist/types/src/interfaces/records-subscribe.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-write-query.d.ts +33 -0
- package/dist/types/src/interfaces/records-write-query.d.ts.map +1 -0
- package/dist/types/src/interfaces/records-write-signing.d.ts +34 -0
- package/dist/types/src/interfaces/records-write-signing.d.ts.map +1 -0
- package/dist/types/src/interfaces/records-write.d.ts +13 -53
- package/dist/types/src/interfaces/records-write.d.ts.map +1 -1
- package/dist/types/src/protocols/permission-grant.d.ts +1 -1
- package/dist/types/src/protocols/permission-grant.d.ts.map +1 -1
- package/dist/types/src/protocols/permission-request.d.ts +1 -1
- package/dist/types/src/protocols/permission-request.d.ts.map +1 -1
- package/dist/types/src/protocols/permissions.d.ts +40 -3
- package/dist/types/src/protocols/permissions.d.ts.map +1 -1
- package/dist/types/src/state-index/state-index-level.d.ts.map +1 -1
- package/dist/types/src/store/data-store-level.d.ts +20 -4
- package/dist/types/src/store/data-store-level.d.ts.map +1 -1
- package/dist/types/src/store/index-level-compound.d.ts +70 -0
- package/dist/types/src/store/index-level-compound.d.ts.map +1 -0
- package/dist/types/src/store/index-level.d.ts +4 -58
- package/dist/types/src/store/index-level.d.ts.map +1 -1
- package/dist/types/src/store/storage-controller.d.ts +4 -4
- package/dist/types/src/store/storage-controller.d.ts.map +1 -1
- package/dist/types/src/types/message-types.d.ts +3 -3
- package/dist/types/src/types/message-types.d.ts.map +1 -1
- package/dist/types/src/types/messages-types.d.ts +12 -3
- package/dist/types/src/types/messages-types.d.ts.map +1 -1
- package/dist/types/src/types/method-handler.d.ts +24 -3
- package/dist/types/src/types/method-handler.d.ts.map +1 -1
- package/dist/types/src/types/permission-types.d.ts +7 -0
- package/dist/types/src/types/permission-types.d.ts.map +1 -1
- package/dist/types/src/types/protocols-types.d.ts +41 -1
- package/dist/types/src/types/protocols-types.d.ts.map +1 -1
- package/dist/types/src/types/records-types.d.ts +16 -6
- package/dist/types/src/types/records-types.d.ts.map +1 -1
- package/dist/types/src/types/subscriptions.d.ts +151 -13
- package/dist/types/src/types/subscriptions.d.ts.map +1 -1
- package/dist/types/src/utils/hd-key.d.ts +1 -9
- package/dist/types/src/utils/hd-key.d.ts.map +1 -1
- package/dist/types/src/utils/messages.d.ts +7 -5
- package/dist/types/src/utils/messages.d.ts.map +1 -1
- package/dist/types/src/utils/protocols.d.ts +5 -0
- package/dist/types/src/utils/protocols.d.ts.map +1 -1
- package/dist/types/src/utils/records.d.ts +1 -11
- package/dist/types/src/utils/records.d.ts.map +1 -1
- package/dist/types/tests/dwn.spec.d.ts.map +1 -1
- package/dist/types/tests/event-emitter-event-log.spec.d.ts +2 -0
- package/dist/types/tests/event-emitter-event-log.spec.d.ts.map +1 -0
- package/dist/types/tests/features/author-delegated-grant.spec.d.ts.map +1 -1
- package/dist/types/tests/features/owner-delegated-grant.spec.d.ts.map +1 -1
- package/dist/types/tests/features/owner-signature.spec.d.ts.map +1 -1
- package/dist/types/tests/features/permissions.spec.d.ts.map +1 -1
- package/dist/types/tests/features/protocol-composition.spec.d.ts.map +1 -1
- package/dist/types/tests/features/records-immutable.spec.d.ts +2 -0
- package/dist/types/tests/features/records-immutable.spec.d.ts.map +1 -0
- package/dist/types/tests/features/records-record-limit.spec.d.ts +2 -0
- package/dist/types/tests/features/records-record-limit.spec.d.ts.map +1 -0
- package/dist/types/tests/features/records-tags.spec.d.ts.map +1 -1
- package/dist/types/tests/features/resumable-tasks.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/messages-read.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/messages-subscribe.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/messages-sync.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/records-count.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/records-delete.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/records-query.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-subscribe.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/records-write.spec.d.ts.map +1 -1
- package/dist/types/tests/scenarios/deleted-record.spec.d.ts.map +1 -1
- package/dist/types/tests/scenarios/subscriptions.spec.d.ts.map +1 -1
- package/dist/types/tests/test-event-stream.d.ts +11 -12
- package/dist/types/tests/test-event-stream.d.ts.map +1 -1
- package/dist/types/tests/test-suite.d.ts +2 -2
- package/dist/types/tests/test-suite.d.ts.map +1 -1
- package/dist/types/tests/utils/test-data-generator.d.ts +18 -0
- package/dist/types/tests/utils/test-data-generator.d.ts.map +1 -1
- package/package.json +5 -4
- package/src/core/constants.ts +11 -0
- package/src/core/core-protocol.ts +129 -0
- package/src/core/dwn-error.ts +15 -12
- package/src/core/grant-authorization.ts +20 -3
- package/src/core/protocol-authorization-action.ts +377 -0
- package/src/core/protocol-authorization-validation.ts +487 -0
- package/src/core/protocol-authorization.ts +111 -856
- package/src/core/record-chain.ts +99 -0
- package/src/core/records-grant-authorization.ts +6 -8
- package/src/dwn.ts +58 -73
- package/src/event-stream/event-emitter-event-log.ts +283 -0
- package/src/handlers/messages-read.ts +8 -9
- package/src/handlers/messages-subscribe.ts +24 -28
- package/src/handlers/messages-sync.ts +10 -16
- package/src/handlers/protocols-configure.ts +47 -32
- package/src/handlers/protocols-query.ts +6 -9
- package/src/handlers/records-count.ts +11 -10
- package/src/handlers/records-delete.ts +12 -21
- package/src/handlers/records-query.ts +12 -12
- package/src/handlers/records-read.ts +34 -22
- package/src/handlers/records-subscribe.ts +47 -26
- package/src/handlers/records-write.ts +47 -104
- package/src/index.ts +9 -5
- package/src/interfaces/messages-subscribe.ts +7 -1
- package/src/interfaces/protocols-configure.ts +73 -8
- package/src/interfaces/records-count.ts +1 -1
- package/src/interfaces/records-delete.ts +1 -1
- package/src/interfaces/records-query.ts +1 -1
- package/src/interfaces/records-read.ts +1 -1
- package/src/interfaces/records-subscribe.ts +8 -1
- package/src/interfaces/records-write-query.ts +139 -0
- package/src/interfaces/records-write-signing.ts +123 -0
- package/src/interfaces/records-write.ts +66 -261
- package/src/protocols/permission-grant.ts +1 -1
- package/src/protocols/permission-request.ts +1 -1
- package/src/protocols/permissions.ts +148 -6
- package/src/state-index/state-index-level.ts +5 -7
- package/src/store/data-store-level.ts +124 -34
- package/src/store/index-level-compound.ts +324 -0
- package/src/store/index-level.ts +68 -341
- package/src/store/storage-controller.ts +11 -11
- package/src/types/message-types.ts +3 -3
- package/src/types/messages-types.ts +12 -3
- package/src/types/method-handler.ts +26 -4
- package/src/types/mitt.d.ts +28 -0
- package/src/types/permission-types.ts +7 -0
- package/src/types/protocols-types.ts +46 -0
- package/src/types/records-types.ts +16 -6
- package/src/types/subscriptions.ts +178 -14
- package/src/utils/hd-key.ts +0 -9
- package/src/utils/messages.ts +17 -37
- package/src/utils/protocols.ts +8 -0
- package/src/utils/records.ts +8 -59
- package/dist/esm/src/event-stream/event-emitter-stream.js +0 -60
- package/dist/esm/src/event-stream/event-emitter-stream.js.map +0 -1
- package/dist/esm/tests/event-stream/event-emitter-stream.spec.js +0 -77
- package/dist/esm/tests/event-stream/event-emitter-stream.spec.js.map +0 -1
- package/dist/esm/tests/event-stream/event-stream.spec.js +0 -123
- package/dist/esm/tests/event-stream/event-stream.spec.js.map +0 -1
- package/dist/types/src/event-stream/event-emitter-stream.d.ts +0 -23
- package/dist/types/src/event-stream/event-emitter-stream.d.ts.map +0 -1
- package/dist/types/tests/event-stream/event-emitter-stream.spec.d.ts +0 -2
- package/dist/types/tests/event-stream/event-emitter-stream.spec.d.ts.map +0 -1
- package/dist/types/tests/event-stream/event-stream.spec.d.ts +0 -2
- package/dist/types/tests/event-stream/event-stream.spec.d.ts.map +0 -1
- package/src/event-stream/event-emitter-stream.ts +0 -69
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import sinon from 'sinon';
|
|
11
2
|
import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'bun:test';
|
|
12
3
|
import friendRoleProtocolDefinition from '../vectors/protocol-definitions/friend-role.json' with { type: 'json' };
|
|
@@ -17,14 +8,14 @@ import { Poller } from '../utils/poller.js';
|
|
|
17
8
|
import { RecordsSubscribe } from '../../src/interfaces/records-subscribe.js';
|
|
18
9
|
import { RecordsSubscribeHandler } from '../../src/handlers/records-subscribe.js';
|
|
19
10
|
import { TestDataGenerator } from '../utils/test-data-generator.js';
|
|
20
|
-
import {
|
|
11
|
+
import { TestEventLog } from '../test-event-stream.js';
|
|
21
12
|
import { TestStores } from '../test-stores.js';
|
|
22
13
|
import { TestStubGenerator } from '../utils/test-stub-generator.js';
|
|
23
14
|
import { DidKey, UniversalResolver } from '@enbox/dids';
|
|
24
|
-
import { Dwn, DwnErrorCode, DwnMethodName,
|
|
15
|
+
import { Dwn, DwnErrorCode, DwnMethodName, EventEmitterEventLog, MessageStoreLevel, Time } from '../../src/index.js';
|
|
25
16
|
export function testRecordsSubscribeHandler() {
|
|
26
17
|
describe('RecordsSubscribeHandler.handle()', () => {
|
|
27
|
-
describe('
|
|
18
|
+
describe('EventLog disabled', () => {
|
|
28
19
|
let didResolver;
|
|
29
20
|
let messageStore;
|
|
30
21
|
let resumableTaskStore;
|
|
@@ -33,44 +24,44 @@ export function testRecordsSubscribeHandler() {
|
|
|
33
24
|
let dwn;
|
|
34
25
|
// important to follow the `before` and `after` pattern to initialize and clean the stores in tests
|
|
35
26
|
// so that different test suites can reuse the same backend store for testing
|
|
36
|
-
beforeAll(() =>
|
|
27
|
+
beforeAll(async () => {
|
|
37
28
|
didResolver = new UniversalResolver({ didResolvers: [DidKey] });
|
|
38
29
|
const stores = TestStores.get();
|
|
39
30
|
messageStore = stores.messageStore;
|
|
40
31
|
dataStore = stores.dataStore;
|
|
41
32
|
resumableTaskStore = stores.resumableTaskStore;
|
|
42
33
|
stateIndex = stores.stateIndex;
|
|
43
|
-
dwn =
|
|
34
|
+
dwn = await Dwn.create({
|
|
44
35
|
didResolver,
|
|
45
36
|
messageStore,
|
|
46
37
|
dataStore,
|
|
47
38
|
resumableTaskStore,
|
|
48
39
|
stateIndex,
|
|
49
40
|
});
|
|
50
|
-
})
|
|
51
|
-
beforeEach(() =>
|
|
41
|
+
});
|
|
42
|
+
beforeEach(async () => {
|
|
52
43
|
sinon.restore(); // wipe all previous stubs/spies/mocks/fakes
|
|
53
44
|
// clean up before each test rather than after so that a test does not depend on other tests to do the clean up
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
})
|
|
59
|
-
afterAll(() =>
|
|
60
|
-
|
|
61
|
-
})
|
|
62
|
-
it('should respond with a 501 if subscriptions are not supported', () =>
|
|
63
|
-
|
|
64
|
-
dwn =
|
|
65
|
-
const alice =
|
|
45
|
+
await messageStore.clear();
|
|
46
|
+
await dataStore.clear();
|
|
47
|
+
await resumableTaskStore.clear();
|
|
48
|
+
await stateIndex.clear();
|
|
49
|
+
});
|
|
50
|
+
afterAll(async () => {
|
|
51
|
+
await dwn.close();
|
|
52
|
+
});
|
|
53
|
+
it('should respond with a 501 if subscriptions are not supported', async () => {
|
|
54
|
+
await dwn.close(); // close the original dwn instance
|
|
55
|
+
dwn = await Dwn.create({ didResolver, messageStore, dataStore, stateIndex, resumableTaskStore }); // leave out eventLog
|
|
56
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
66
57
|
// attempt to subscribe
|
|
67
|
-
const { message } =
|
|
58
|
+
const { message } = await TestDataGenerator.generateRecordsSubscribe({
|
|
68
59
|
author: alice,
|
|
69
60
|
});
|
|
70
|
-
const subscriptionMessageReply =
|
|
61
|
+
const subscriptionMessageReply = await dwn.processMessage(alice.did, message, { subscriptionHandler: (_) => { } });
|
|
71
62
|
expect(subscriptionMessageReply.status.code).toBe(501, subscriptionMessageReply.status.detail);
|
|
72
|
-
expect(subscriptionMessageReply.status.detail).toContain(DwnErrorCode.
|
|
73
|
-
})
|
|
63
|
+
expect(subscriptionMessageReply.status.detail).toContain(DwnErrorCode.RecordsSubscribeEventLogUnimplemented);
|
|
64
|
+
});
|
|
74
65
|
});
|
|
75
66
|
describe('functional tests', () => {
|
|
76
67
|
let didResolver;
|
|
@@ -78,63 +69,64 @@ export function testRecordsSubscribeHandler() {
|
|
|
78
69
|
let dataStore;
|
|
79
70
|
let resumableTaskStore;
|
|
80
71
|
let stateIndex;
|
|
81
|
-
let
|
|
72
|
+
let eventLog;
|
|
82
73
|
let dwn;
|
|
83
74
|
// important to follow the `before` and `after` pattern to initialize and clean the stores in tests
|
|
84
75
|
// so that different test suites can reuse the same backend store for testing
|
|
85
|
-
beforeAll(() =>
|
|
76
|
+
beforeAll(async () => {
|
|
86
77
|
didResolver = new UniversalResolver({ didResolvers: [DidKey] });
|
|
87
78
|
const stores = TestStores.get();
|
|
88
79
|
messageStore = stores.messageStore;
|
|
89
80
|
dataStore = stores.dataStore;
|
|
90
81
|
resumableTaskStore = stores.resumableTaskStore;
|
|
91
82
|
stateIndex = stores.stateIndex;
|
|
92
|
-
|
|
93
|
-
dwn =
|
|
94
|
-
})
|
|
95
|
-
beforeEach(() =>
|
|
83
|
+
eventLog = TestEventLog.get();
|
|
84
|
+
dwn = await Dwn.create({ didResolver, messageStore, dataStore, stateIndex, eventLog, resumableTaskStore });
|
|
85
|
+
});
|
|
86
|
+
beforeEach(async () => {
|
|
96
87
|
sinon.restore(); // wipe all previous stubs/spies/mocks/fakes
|
|
97
88
|
// clean up before each test rather than after so that a test does not depend on other tests to do the clean up
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
})
|
|
103
|
-
afterAll(() =>
|
|
104
|
-
|
|
105
|
-
})
|
|
106
|
-
it('should return a subscription object', () =>
|
|
107
|
-
const alice =
|
|
108
|
-
const recordsSubscribe =
|
|
89
|
+
await messageStore.clear();
|
|
90
|
+
await dataStore.clear();
|
|
91
|
+
await resumableTaskStore.clear();
|
|
92
|
+
await stateIndex.clear();
|
|
93
|
+
});
|
|
94
|
+
afterAll(async () => {
|
|
95
|
+
await dwn.close();
|
|
96
|
+
});
|
|
97
|
+
it('should return a subscription object', async () => {
|
|
98
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
99
|
+
const recordsSubscribe = await TestDataGenerator.generateRecordsSubscribe({
|
|
109
100
|
author: alice,
|
|
110
101
|
filter: { schema: 'some-schema' },
|
|
111
102
|
});
|
|
112
103
|
// Send records subscribe message
|
|
113
|
-
const reply =
|
|
104
|
+
const reply = await dwn.processMessage(alice.did, recordsSubscribe.message, { subscriptionHandler: () => { } });
|
|
114
105
|
expect(reply.status.code).toBe(200);
|
|
115
106
|
expect(reply.subscription).toBeDefined();
|
|
116
107
|
expect(reply.entries).toBeDefined();
|
|
117
108
|
expect(reply.entries.length).toBe(0); // no matching records exist yet
|
|
118
|
-
})
|
|
119
|
-
it('should return initial entries matching the filter', () =>
|
|
120
|
-
const alice =
|
|
109
|
+
});
|
|
110
|
+
it('should return initial entries matching the filter', async () => {
|
|
111
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
112
|
+
await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
|
|
121
113
|
// write some records before subscribing
|
|
122
|
-
const write1 =
|
|
123
|
-
const write1Reply =
|
|
114
|
+
const write1 = await TestDataGenerator.generateRecordsWrite({ author: alice, schema: 'http://test-schema' });
|
|
115
|
+
const write1Reply = await dwn.processMessage(alice.did, write1.message, { dataStream: write1.dataStream });
|
|
124
116
|
expect(write1Reply.status.code).toBe(202);
|
|
125
|
-
const write2 =
|
|
126
|
-
const write2Reply =
|
|
117
|
+
const write2 = await TestDataGenerator.generateRecordsWrite({ author: alice, schema: 'http://test-schema' });
|
|
118
|
+
const write2Reply = await dwn.processMessage(alice.did, write2.message, { dataStream: write2.dataStream });
|
|
127
119
|
expect(write2Reply.status.code).toBe(202);
|
|
128
120
|
// write a record with a different schema that should NOT be in the entries
|
|
129
|
-
const write3 =
|
|
130
|
-
const write3Reply =
|
|
121
|
+
const write3 = await TestDataGenerator.generateRecordsWrite({ author: alice, schema: 'http://other-schema' });
|
|
122
|
+
const write3Reply = await dwn.processMessage(alice.did, write3.message, { dataStream: write3.dataStream });
|
|
131
123
|
expect(write3Reply.status.code).toBe(202);
|
|
132
124
|
// subscribe with a filter that matches only the first two writes
|
|
133
|
-
const recordsSubscribe =
|
|
125
|
+
const recordsSubscribe = await TestDataGenerator.generateRecordsSubscribe({
|
|
134
126
|
author: alice,
|
|
135
127
|
filter: { schema: 'http://test-schema' },
|
|
136
128
|
});
|
|
137
|
-
const subReply =
|
|
129
|
+
const subReply = await dwn.processMessage(alice.did, recordsSubscribe.message, { subscriptionHandler: () => { } });
|
|
138
130
|
expect(subReply.status.code).toBe(200);
|
|
139
131
|
expect(subReply.subscription).toBeDefined();
|
|
140
132
|
expect(subReply.entries).toBeDefined();
|
|
@@ -142,47 +134,49 @@ export function testRecordsSubscribeHandler() {
|
|
|
142
134
|
const returnedRecordIds = subReply.entries.map(e => e.recordId);
|
|
143
135
|
expect(returnedRecordIds).toContain(write1.message.recordId);
|
|
144
136
|
expect(returnedRecordIds).toContain(write2.message.recordId);
|
|
145
|
-
})
|
|
146
|
-
it('should support pagination on initial entries', () =>
|
|
147
|
-
const alice =
|
|
137
|
+
});
|
|
138
|
+
it('should support pagination on initial entries', async () => {
|
|
139
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
140
|
+
await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
|
|
148
141
|
// write 5 records
|
|
149
142
|
for (let i = 0; i < 5; i++) {
|
|
150
|
-
const write =
|
|
151
|
-
const writeReply =
|
|
143
|
+
const write = await TestDataGenerator.generateRecordsWrite({ author: alice, schema: 'http://paginated' });
|
|
144
|
+
const writeReply = await dwn.processMessage(alice.did, write.message, { dataStream: write.dataStream });
|
|
152
145
|
expect(writeReply.status.code).toBe(202);
|
|
153
146
|
}
|
|
154
147
|
// subscribe with a limit of 2
|
|
155
|
-
const recordsSubscribe =
|
|
148
|
+
const recordsSubscribe = await TestDataGenerator.generateRecordsSubscribe({
|
|
156
149
|
author: alice,
|
|
157
150
|
filter: { schema: 'http://paginated' },
|
|
158
151
|
pagination: { limit: 2 },
|
|
159
152
|
});
|
|
160
|
-
const subReply =
|
|
153
|
+
const subReply = await dwn.processMessage(alice.did, recordsSubscribe.message, { subscriptionHandler: () => { } });
|
|
161
154
|
expect(subReply.status.code).toBe(200);
|
|
162
155
|
expect(subReply.subscription).toBeDefined();
|
|
163
156
|
expect(subReply.entries).toBeDefined();
|
|
164
157
|
expect(subReply.entries.length).toBe(2);
|
|
165
158
|
expect(subReply.cursor).toBeDefined();
|
|
166
|
-
})
|
|
167
|
-
it('should include initialWrite for updated records in entries', () =>
|
|
168
|
-
const alice =
|
|
159
|
+
});
|
|
160
|
+
it('should include initialWrite for updated records in entries', async () => {
|
|
161
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
162
|
+
await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
|
|
169
163
|
// create a record
|
|
170
|
-
const write =
|
|
171
|
-
const writeReply =
|
|
164
|
+
const write = await TestDataGenerator.generateRecordsWrite({ author: alice, schema: 'http://update-test' });
|
|
165
|
+
const writeReply = await dwn.processMessage(alice.did, write.message, { dataStream: write.dataStream });
|
|
172
166
|
expect(writeReply.status.code).toBe(202);
|
|
173
167
|
// update the record
|
|
174
|
-
const update =
|
|
168
|
+
const update = await TestDataGenerator.generateFromRecordsWrite({
|
|
175
169
|
author: alice,
|
|
176
170
|
existingWrite: write.recordsWrite,
|
|
177
171
|
});
|
|
178
|
-
const updateReply =
|
|
172
|
+
const updateReply = await dwn.processMessage(alice.did, update.message, { dataStream: update.dataStream });
|
|
179
173
|
expect(updateReply.status.code).toBe(202);
|
|
180
174
|
// subscribe and check the entries
|
|
181
|
-
const recordsSubscribe =
|
|
175
|
+
const recordsSubscribe = await TestDataGenerator.generateRecordsSubscribe({
|
|
182
176
|
author: alice,
|
|
183
177
|
filter: { schema: 'http://update-test' },
|
|
184
178
|
});
|
|
185
|
-
const subReply =
|
|
179
|
+
const subReply = await dwn.processMessage(alice.did, recordsSubscribe.message, { subscriptionHandler: () => { } });
|
|
186
180
|
expect(subReply.status.code).toBe(200);
|
|
187
181
|
expect(subReply.entries).toBeDefined();
|
|
188
182
|
expect(subReply.entries.length).toBe(1);
|
|
@@ -190,188 +184,306 @@ export function testRecordsSubscribeHandler() {
|
|
|
190
184
|
expect(subReply.entries[0].recordId).toBe(write.message.recordId);
|
|
191
185
|
expect(subReply.entries[0].initialWrite).toBeDefined();
|
|
192
186
|
expect(subReply.entries[0].initialWrite.descriptor.dateCreated).toBe(write.message.descriptor.dateCreated);
|
|
193
|
-
})
|
|
194
|
-
it('should still receive live events after initial entries', () =>
|
|
195
|
-
const alice =
|
|
187
|
+
});
|
|
188
|
+
it('should still receive live events after initial entries', async () => {
|
|
189
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
190
|
+
await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
|
|
196
191
|
// write a record before subscribing
|
|
197
|
-
const write1 =
|
|
198
|
-
const write1Reply =
|
|
192
|
+
const write1 = await TestDataGenerator.generateRecordsWrite({ author: alice, schema: 'http://live-test' });
|
|
193
|
+
const write1Reply = await dwn.processMessage(alice.did, write1.message, { dataStream: write1.dataStream });
|
|
199
194
|
expect(write1Reply.status.code).toBe(202);
|
|
200
195
|
// subscribe
|
|
201
196
|
const receivedEvents = [];
|
|
202
|
-
const subscriptionHandler = (
|
|
203
|
-
|
|
197
|
+
const subscriptionHandler = (msg) => { if (msg.type === 'event') {
|
|
198
|
+
receivedEvents.push(msg.event);
|
|
199
|
+
} };
|
|
200
|
+
const recordsSubscribe = await TestDataGenerator.generateRecordsSubscribe({
|
|
204
201
|
author: alice,
|
|
205
202
|
filter: { schema: 'http://live-test' },
|
|
206
203
|
});
|
|
207
|
-
const subReply =
|
|
204
|
+
const subReply = await dwn.processMessage(alice.did, recordsSubscribe.message, { subscriptionHandler });
|
|
208
205
|
expect(subReply.status.code).toBe(200);
|
|
209
206
|
expect(subReply.entries.length).toBe(1); // initial entries has write1
|
|
210
207
|
// write another record after subscribing
|
|
211
|
-
const write2 =
|
|
212
|
-
const write2Reply =
|
|
208
|
+
const write2 = await TestDataGenerator.generateRecordsWrite({ author: alice, schema: 'http://live-test' });
|
|
209
|
+
const write2Reply = await dwn.processMessage(alice.did, write2.message, { dataStream: write2.dataStream });
|
|
213
210
|
expect(write2Reply.status.code).toBe(202);
|
|
214
211
|
// wait for the event to arrive
|
|
215
|
-
|
|
212
|
+
await Poller.pollUntilSuccessOrTimeout(async () => {
|
|
216
213
|
expect(receivedEvents.length).toBe(1);
|
|
217
214
|
expect(receivedEvents[0].message.recordId).toBe(write2.message.recordId);
|
|
218
|
-
})
|
|
219
|
-
})
|
|
220
|
-
|
|
221
|
-
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
describe('cursor-based subscriptions', () => {
|
|
218
|
+
it('should use EventLog catch-up when cursor is provided (no initial MessageStore query)', async () => {
|
|
219
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
220
|
+
await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
|
|
221
|
+
// Read the EventLog to get the current cursor position before writing records.
|
|
222
|
+
const { cursor: cursorBefore } = await eventLog.read(alice.did);
|
|
223
|
+
// Write records before subscribing.
|
|
224
|
+
const write1 = await TestDataGenerator.generateRecordsWrite({ author: alice, schema: 'http://cursor-test' });
|
|
225
|
+
const write1Reply = await dwn.processMessage(alice.did, write1.message, { dataStream: write1.dataStream });
|
|
226
|
+
expect(write1Reply.status.code).toBe(202);
|
|
227
|
+
const write2 = await TestDataGenerator.generateRecordsWrite({ author: alice, schema: 'http://cursor-test' });
|
|
228
|
+
const write2Reply = await dwn.processMessage(alice.did, write2.message, { dataStream: write2.dataStream });
|
|
229
|
+
expect(write2Reply.status.code).toBe(202);
|
|
230
|
+
// Subscribe with the cursor from before the writes. The handler takes the
|
|
231
|
+
// EventLog catch-up path, replaying events through the subscription handler.
|
|
232
|
+
const receivedEvents = [];
|
|
233
|
+
const subscriptionHandler = (msg) => { if (msg.type === 'event') {
|
|
234
|
+
receivedEvents.push(msg.event);
|
|
235
|
+
} };
|
|
236
|
+
const recordsSubscribe = await TestDataGenerator.generateRecordsSubscribe({
|
|
237
|
+
author: alice,
|
|
238
|
+
filter: { schema: 'http://cursor-test' },
|
|
239
|
+
cursor: cursorBefore,
|
|
240
|
+
});
|
|
241
|
+
const subReply = await dwn.processMessage(alice.did, recordsSubscribe.message, { subscriptionHandler });
|
|
242
|
+
expect(subReply.status.code).toBe(200);
|
|
243
|
+
expect(subReply.subscription).toBeDefined();
|
|
244
|
+
// In cursor mode, initial entries are NOT returned via the reply —
|
|
245
|
+
// they come through the subscription handler as catch-up events.
|
|
246
|
+
// The handler wraps SubscriptionListener→RecordSubscriptionHandler,
|
|
247
|
+
// so we get plain RecordEvents (EOSE is silently consumed).
|
|
248
|
+
await Poller.pollUntilSuccessOrTimeout(async () => {
|
|
249
|
+
expect(receivedEvents.length).toBeGreaterThanOrEqual(2);
|
|
250
|
+
});
|
|
251
|
+
// Verify the catch-up events are our records.
|
|
252
|
+
const recordIds = receivedEvents.map(e => e.message.recordId);
|
|
253
|
+
expect(recordIds).toContain(write1.message.recordId);
|
|
254
|
+
expect(recordIds).toContain(write2.message.recordId);
|
|
255
|
+
});
|
|
256
|
+
it('should receive live events after cursor catch-up', async () => {
|
|
257
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
258
|
+
await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
|
|
259
|
+
// Write a record before subscribing.
|
|
260
|
+
const write1 = await TestDataGenerator.generateRecordsWrite({ author: alice, schema: 'http://cursor-live' });
|
|
261
|
+
await dwn.processMessage(alice.did, write1.message, { dataStream: write1.dataStream });
|
|
262
|
+
// Read to get a cursor that includes write1's protocol config + the record.
|
|
263
|
+
const { cursor: cursorAfterWrite1 } = await eventLog.read(alice.did);
|
|
264
|
+
// Write another record that we'll want to catch up on.
|
|
265
|
+
const write2 = await TestDataGenerator.generateRecordsWrite({ author: alice, schema: 'http://cursor-live' });
|
|
266
|
+
await dwn.processMessage(alice.did, write2.message, { dataStream: write2.dataStream });
|
|
267
|
+
const receivedEvents = [];
|
|
268
|
+
const subscriptionHandler = (msg) => { if (msg.type === 'event') {
|
|
269
|
+
receivedEvents.push(msg.event);
|
|
270
|
+
} };
|
|
271
|
+
const recordsSubscribe = await TestDataGenerator.generateRecordsSubscribe({
|
|
272
|
+
author: alice,
|
|
273
|
+
filter: { schema: 'http://cursor-live' },
|
|
274
|
+
cursor: cursorAfterWrite1,
|
|
275
|
+
});
|
|
276
|
+
const subReply = await dwn.processMessage(alice.did, recordsSubscribe.message, { subscriptionHandler });
|
|
277
|
+
expect(subReply.status.code).toBe(200);
|
|
278
|
+
// Wait for catch-up event (write2).
|
|
279
|
+
await Poller.pollUntilSuccessOrTimeout(async () => {
|
|
280
|
+
expect(receivedEvents.length).toBeGreaterThanOrEqual(1);
|
|
281
|
+
});
|
|
282
|
+
// Write a live record after subscribing.
|
|
283
|
+
const write3 = await TestDataGenerator.generateRecordsWrite({ author: alice, schema: 'http://cursor-live' });
|
|
284
|
+
await dwn.processMessage(alice.did, write3.message, { dataStream: write3.dataStream });
|
|
285
|
+
// Wait for the live event.
|
|
286
|
+
await Poller.pollUntilSuccessOrTimeout(async () => {
|
|
287
|
+
expect(receivedEvents.length).toBeGreaterThanOrEqual(2);
|
|
288
|
+
});
|
|
289
|
+
const recordIds = receivedEvents.map(e => e.message.recordId);
|
|
290
|
+
expect(recordIds).toContain(write2.message.recordId);
|
|
291
|
+
expect(recordIds).toContain(write3.message.recordId);
|
|
292
|
+
});
|
|
293
|
+
it('should filter catch-up events when cursor and filter are provided', async () => {
|
|
294
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
295
|
+
await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
|
|
296
|
+
// Get cursor before writing.
|
|
297
|
+
const { cursor: cursorBefore } = await eventLog.read(alice.did);
|
|
298
|
+
// Write records with different schemas.
|
|
299
|
+
const matchWrite = await TestDataGenerator.generateRecordsWrite({ author: alice, schema: 'http://filter-match' });
|
|
300
|
+
await dwn.processMessage(alice.did, matchWrite.message, { dataStream: matchWrite.dataStream });
|
|
301
|
+
const noMatchWrite = await TestDataGenerator.generateRecordsWrite({ author: alice, schema: 'http://filter-other' });
|
|
302
|
+
await dwn.processMessage(alice.did, noMatchWrite.message, { dataStream: noMatchWrite.dataStream });
|
|
303
|
+
const receivedEvents = [];
|
|
304
|
+
const subscriptionHandler = (msg) => { if (msg.type === 'event') {
|
|
305
|
+
receivedEvents.push(msg.event);
|
|
306
|
+
} };
|
|
307
|
+
const recordsSubscribe = await TestDataGenerator.generateRecordsSubscribe({
|
|
308
|
+
author: alice,
|
|
309
|
+
filter: { schema: 'http://filter-match' },
|
|
310
|
+
cursor: cursorBefore,
|
|
311
|
+
});
|
|
312
|
+
const subReply = await dwn.processMessage(alice.did, recordsSubscribe.message, { subscriptionHandler });
|
|
313
|
+
expect(subReply.status.code).toBe(200);
|
|
314
|
+
// Wait for catch-up events. Should only get the matching one.
|
|
315
|
+
await Poller.pollUntilSuccessOrTimeout(async () => {
|
|
316
|
+
expect(receivedEvents.length).toBe(1);
|
|
317
|
+
expect(receivedEvents[0].message.recordId).toBe(matchWrite.message.recordId);
|
|
318
|
+
});
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
it('should return 400 if protocol is not normalized', async () => {
|
|
322
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
222
323
|
// subscribe for non-normalized protocol
|
|
223
|
-
const recordsSubscribe =
|
|
324
|
+
const recordsSubscribe = await TestDataGenerator.generateRecordsSubscribe({
|
|
224
325
|
author: alice,
|
|
225
326
|
filter: { protocol: 'example.com/' },
|
|
226
327
|
});
|
|
227
328
|
// overwrite protocol because #create auto-normalizes protocol
|
|
228
329
|
recordsSubscribe.message.descriptor.filter.protocol = 'example.com/';
|
|
229
330
|
// Re-create auth because we altered the descriptor after signing
|
|
230
|
-
recordsSubscribe.message.authorization =
|
|
331
|
+
recordsSubscribe.message.authorization = await Message.createAuthorization({
|
|
231
332
|
descriptor: recordsSubscribe.message.descriptor,
|
|
232
333
|
signer: Jws.createSigner(alice)
|
|
233
334
|
});
|
|
234
335
|
// Send records subscribe message
|
|
235
|
-
const reply =
|
|
336
|
+
const reply = await dwn.processMessage(alice.did, recordsSubscribe.message);
|
|
236
337
|
expect(reply.status.code).toBe(400);
|
|
237
338
|
expect(reply.status.detail).toContain(DwnErrorCode.UrlProtocolNotNormalized);
|
|
238
|
-
})
|
|
239
|
-
it('should return 400 if schema is not normalized', () =>
|
|
240
|
-
const alice =
|
|
339
|
+
});
|
|
340
|
+
it('should return 400 if schema is not normalized', async () => {
|
|
341
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
241
342
|
// subscribe for non-normalized schema
|
|
242
|
-
const recordsSubscribe =
|
|
343
|
+
const recordsSubscribe = await TestDataGenerator.generateRecordsSubscribe({
|
|
243
344
|
author: alice,
|
|
244
345
|
filter: { schema: 'example.com/' },
|
|
245
346
|
});
|
|
246
347
|
// overwrite schema because #create auto-normalizes schema
|
|
247
348
|
recordsSubscribe.message.descriptor.filter.schema = 'example.com/';
|
|
248
349
|
// Re-create auth because we altered the descriptor after signing
|
|
249
|
-
recordsSubscribe.message.authorization =
|
|
350
|
+
recordsSubscribe.message.authorization = await Message.createAuthorization({
|
|
250
351
|
descriptor: recordsSubscribe.message.descriptor,
|
|
251
352
|
signer: Jws.createSigner(alice)
|
|
252
353
|
});
|
|
253
354
|
// Send records subscribe message
|
|
254
|
-
const reply =
|
|
355
|
+
const reply = await dwn.processMessage(alice.did, recordsSubscribe.message);
|
|
255
356
|
expect(reply.status.code).toBe(400);
|
|
256
357
|
expect(reply.status.detail).toContain(DwnErrorCode.UrlSchemaNotNormalized);
|
|
257
|
-
})
|
|
258
|
-
it('should return 400 if published is set to false and a datePublished range is provided', () =>
|
|
358
|
+
});
|
|
359
|
+
it('should return 400 if published is set to false and a datePublished range is provided', async () => {
|
|
259
360
|
const fromDatePublished = Time.getCurrentTimestamp();
|
|
260
|
-
const alice =
|
|
361
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
261
362
|
// set to true so create does not fail
|
|
262
|
-
const recordSubscribe =
|
|
363
|
+
const recordSubscribe = await TestDataGenerator.generateRecordsSubscribe({
|
|
263
364
|
author: alice,
|
|
264
365
|
filter: { datePublished: { from: fromDatePublished }, published: true }
|
|
265
366
|
});
|
|
266
367
|
// set to false
|
|
267
368
|
recordSubscribe.message.descriptor.filter.published = false;
|
|
268
|
-
const subscribeResponse =
|
|
369
|
+
const subscribeResponse = await dwn.processMessage(alice.did, recordSubscribe.message);
|
|
269
370
|
expect(subscribeResponse.status.code).toBe(400);
|
|
270
371
|
expect(subscribeResponse.status.detail).toContain('descriptor/filter/published: must be equal to one of the allowed values');
|
|
271
|
-
})
|
|
272
|
-
it('should return 401 for anonymous subscriptions that filter explicitly for unpublished records', () =>
|
|
273
|
-
const alice =
|
|
372
|
+
});
|
|
373
|
+
it('should return 401 for anonymous subscriptions that filter explicitly for unpublished records', async () => {
|
|
374
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
375
|
+
await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
|
|
274
376
|
// create an unpublished record
|
|
275
|
-
const draftWrite =
|
|
276
|
-
const draftWriteReply =
|
|
377
|
+
const draftWrite = await TestDataGenerator.generateRecordsWrite({ author: alice, schema: 'post' });
|
|
378
|
+
const draftWriteReply = await dwn.processMessage(alice.did, draftWrite.message, { dataStream: draftWrite.dataStream });
|
|
277
379
|
expect(draftWriteReply.status.code).toBe(202);
|
|
278
380
|
// validate that alice can subscribe
|
|
279
|
-
const unpublishedPostSubscribe =
|
|
280
|
-
const unpublishedPostReply =
|
|
381
|
+
const unpublishedPostSubscribe = await TestDataGenerator.generateRecordsSubscribe({ author: alice, filter: { schema: 'post', published: false } });
|
|
382
|
+
const unpublishedPostReply = await dwn.processMessage(alice.did, unpublishedPostSubscribe.message, { subscriptionHandler: () => { } });
|
|
281
383
|
expect(unpublishedPostReply.status.code).toBe(200);
|
|
282
384
|
expect(unpublishedPostReply.subscription).toBeDefined();
|
|
283
385
|
// anonymous subscribe for unpublished records
|
|
284
|
-
const unpublishedAnonymous =
|
|
285
|
-
const anonymousPostReply =
|
|
386
|
+
const unpublishedAnonymous = await RecordsSubscribe.create({ filter: { schema: 'post', published: false } });
|
|
387
|
+
const anonymousPostReply = await dwn.processMessage(alice.did, unpublishedAnonymous.message);
|
|
286
388
|
expect(anonymousPostReply.status.code).toBe(401);
|
|
287
389
|
expect(anonymousPostReply.status.detail).toContain('Missing JWS');
|
|
288
390
|
expect(anonymousPostReply.subscription).toBeUndefined();
|
|
289
|
-
})
|
|
290
|
-
it('should return 401 if signature check fails', () =>
|
|
291
|
-
const { author, message } =
|
|
391
|
+
});
|
|
392
|
+
it('should return 401 if signature check fails', async () => {
|
|
393
|
+
const { author, message } = await TestDataGenerator.generateRecordsSubscribe();
|
|
292
394
|
const tenant = author.did;
|
|
293
395
|
// setting up a stub did resolver & message store
|
|
294
396
|
// intentionally not supplying the public key so a different public key is generated to simulate invalid signature
|
|
295
|
-
const mismatchingPersona =
|
|
397
|
+
const mismatchingPersona = await TestDataGenerator.generatePersona({ did: author.did, keyId: author.keyId });
|
|
296
398
|
const didResolver = TestStubGenerator.createDidResolverStub(mismatchingPersona);
|
|
297
399
|
const messageStoreStub = sinon.createStubInstance(MessageStoreLevel);
|
|
298
|
-
const
|
|
299
|
-
const recordsSubscribeHandler = new RecordsSubscribeHandler(
|
|
300
|
-
|
|
400
|
+
const eventLogStub = sinon.createStubInstance(EventEmitterEventLog);
|
|
401
|
+
const recordsSubscribeHandler = new RecordsSubscribeHandler({
|
|
402
|
+
didResolver, messageStore: messageStoreStub, eventLog: eventLogStub,
|
|
403
|
+
});
|
|
404
|
+
const reply = await recordsSubscribeHandler.handle({ tenant, message, subscriptionHandler: () => { } });
|
|
301
405
|
expect(reply.status.code).toBe(401);
|
|
302
|
-
})
|
|
303
|
-
it('should return 400 if fail parsing the message', () =>
|
|
304
|
-
const { author, message } =
|
|
406
|
+
});
|
|
407
|
+
it('should return 400 if fail parsing the message', async () => {
|
|
408
|
+
const { author, message } = await TestDataGenerator.generateRecordsSubscribe();
|
|
305
409
|
const tenant = author.did;
|
|
306
410
|
// setting up a stub method resolver & message store
|
|
307
411
|
const didResolver = TestStubGenerator.createDidResolverStub(author);
|
|
308
412
|
const messageStoreStub = sinon.createStubInstance(MessageStoreLevel);
|
|
309
|
-
const
|
|
310
|
-
const recordsSubscribeHandler = new RecordsSubscribeHandler(
|
|
413
|
+
const eventLogStub = sinon.createStubInstance(EventEmitterEventLog);
|
|
414
|
+
const recordsSubscribeHandler = new RecordsSubscribeHandler({
|
|
415
|
+
didResolver, messageStore: messageStoreStub, eventLog: eventLogStub,
|
|
416
|
+
});
|
|
311
417
|
// stub the `parse()` function to throw an error
|
|
312
418
|
sinon.stub(RecordsSubscribe, 'parse').throws('anyError');
|
|
313
|
-
const reply =
|
|
419
|
+
const reply = await recordsSubscribeHandler.handle({ tenant, message, subscriptionHandler: () => { } });
|
|
314
420
|
expect(reply.status.code).toBe(400);
|
|
315
|
-
})
|
|
421
|
+
});
|
|
316
422
|
describe('protocol based subscriptions', () => {
|
|
317
|
-
it('does not try protocol authorization if protocolRole is not invoked', () =>
|
|
423
|
+
it('does not try protocol authorization if protocolRole is not invoked', async () => {
|
|
318
424
|
// scenario:
|
|
319
425
|
// Bob and Carol subscribe to a chat protocol without invoking a protocolRole,
|
|
320
426
|
// they should receive chat messages addressed to them, respectively.
|
|
321
427
|
// Alice creates a thread and writes some chat messages to Bob and Carol.
|
|
322
428
|
// Bob receives only the chat messages addressed to him, Carol receives only the chat messages addressed to her.
|
|
323
|
-
const alice =
|
|
324
|
-
const bob =
|
|
325
|
-
const carol =
|
|
429
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
430
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
431
|
+
const carol = await TestDataGenerator.generateDidKeyPersona();
|
|
326
432
|
const protocolDefinition = threadRoleProtocolDefinition;
|
|
327
|
-
const protocolsConfig =
|
|
433
|
+
const protocolsConfig = await TestDataGenerator.generateProtocolsConfigure({
|
|
328
434
|
author: alice,
|
|
329
435
|
protocolDefinition
|
|
330
436
|
});
|
|
331
|
-
const protocolsConfigureReply =
|
|
437
|
+
const protocolsConfigureReply = await dwn.processMessage(alice.did, protocolsConfig.message);
|
|
332
438
|
expect(protocolsConfigureReply.status.code).toBe(202);
|
|
333
439
|
const bobMessages = [];
|
|
334
|
-
const handleForBob = (
|
|
335
|
-
|
|
336
|
-
|
|
440
|
+
const handleForBob = async (msg) => {
|
|
441
|
+
if (msg.type !== 'event') {
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
const { message } = msg.event;
|
|
445
|
+
const messageCid = await Message.getCid(message);
|
|
337
446
|
bobMessages.push(messageCid);
|
|
338
|
-
}
|
|
339
|
-
const bobSubscription =
|
|
447
|
+
};
|
|
448
|
+
const bobSubscription = await TestDataGenerator.generateRecordsSubscribe({
|
|
340
449
|
author: bob,
|
|
341
450
|
filter: {
|
|
342
451
|
published: false,
|
|
343
452
|
protocol: protocolDefinition.protocol,
|
|
344
453
|
}
|
|
345
454
|
});
|
|
346
|
-
const subscriptionReply =
|
|
455
|
+
const subscriptionReply = await dwn.processMessage(alice.did, bobSubscription.message, { subscriptionHandler: handleForBob });
|
|
347
456
|
expect(subscriptionReply.status.code).toBe(200);
|
|
348
457
|
expect(subscriptionReply.subscription).toBeDefined();
|
|
349
458
|
const carolMessages = [];
|
|
350
|
-
const handleForCarol = (
|
|
351
|
-
|
|
352
|
-
|
|
459
|
+
const handleForCarol = async (msg) => {
|
|
460
|
+
if (msg.type !== 'event') {
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
const { message } = msg.event;
|
|
464
|
+
const messageCid = await Message.getCid(message);
|
|
353
465
|
carolMessages.push(messageCid);
|
|
354
|
-
}
|
|
355
|
-
const carolSubscription =
|
|
466
|
+
};
|
|
467
|
+
const carolSubscription = await TestDataGenerator.generateRecordsSubscribe({
|
|
356
468
|
author: carol,
|
|
357
469
|
filter: {
|
|
358
470
|
published: false,
|
|
359
471
|
protocol: protocolDefinition.protocol,
|
|
360
472
|
}
|
|
361
473
|
});
|
|
362
|
-
const carolSubscriptionReply =
|
|
474
|
+
const carolSubscriptionReply = await dwn.processMessage(alice.did, carolSubscription.message, { subscriptionHandler: handleForCarol });
|
|
363
475
|
expect(carolSubscriptionReply.status.code).toBe(200);
|
|
364
476
|
expect(carolSubscriptionReply.subscription).toBeDefined();
|
|
365
477
|
// Alice writes a 'thread' record
|
|
366
|
-
const threadRecord =
|
|
478
|
+
const threadRecord = await TestDataGenerator.generateRecordsWrite({
|
|
367
479
|
author: alice,
|
|
368
480
|
protocol: protocolDefinition.protocol,
|
|
369
481
|
protocolPath: 'thread',
|
|
370
482
|
});
|
|
371
|
-
const threadRoleReply =
|
|
483
|
+
const threadRoleReply = await dwn.processMessage(alice.did, threadRecord.message, { dataStream: threadRecord.dataStream });
|
|
372
484
|
expect(threadRoleReply.status.code).toBe(202);
|
|
373
485
|
// Alice writes one 'chat' record addressed to Bob
|
|
374
|
-
const chatRecordForBob =
|
|
486
|
+
const chatRecordForBob = await TestDataGenerator.generateRecordsWrite({
|
|
375
487
|
author: alice,
|
|
376
488
|
recipient: bob.did,
|
|
377
489
|
protocol: protocolDefinition.protocol,
|
|
@@ -380,11 +492,11 @@ export function testRecordsSubscribeHandler() {
|
|
|
380
492
|
parentContextId: threadRecord.message.contextId,
|
|
381
493
|
data: new TextEncoder().encode('Bob can read this cuz he is my friend'),
|
|
382
494
|
});
|
|
383
|
-
const chatRecordForBobReply =
|
|
495
|
+
const chatRecordForBobReply = await dwn.processMessage(alice.did, chatRecordForBob.message, { dataStream: chatRecordForBob.dataStream });
|
|
384
496
|
expect(chatRecordForBobReply.status.code).toBe(202);
|
|
385
|
-
const chatRecordForBobCid =
|
|
497
|
+
const chatRecordForBobCid = await Message.getCid(chatRecordForBob.message);
|
|
386
498
|
// Alice writes two 'chat' records addressed to Carol
|
|
387
|
-
const chatRecordForCarol1 =
|
|
499
|
+
const chatRecordForCarol1 = await TestDataGenerator.generateRecordsWrite({
|
|
388
500
|
author: alice,
|
|
389
501
|
recipient: carol.did,
|
|
390
502
|
protocol: protocolDefinition.protocol,
|
|
@@ -393,10 +505,10 @@ export function testRecordsSubscribeHandler() {
|
|
|
393
505
|
parentContextId: threadRecord.message.contextId,
|
|
394
506
|
data: new TextEncoder().encode('Bob cannot read this'),
|
|
395
507
|
});
|
|
396
|
-
const chatRecordForCarol1Reply =
|
|
508
|
+
const chatRecordForCarol1Reply = await dwn.processMessage(alice.did, chatRecordForCarol1.message, { dataStream: chatRecordForCarol1.dataStream });
|
|
397
509
|
expect(chatRecordForCarol1Reply.status.code).toBe(202);
|
|
398
|
-
const chatRecordForCarol1Cid =
|
|
399
|
-
const chatRecordForCarol2 =
|
|
510
|
+
const chatRecordForCarol1Cid = await Message.getCid(chatRecordForCarol1.message);
|
|
511
|
+
const chatRecordForCarol2 = await TestDataGenerator.generateRecordsWrite({
|
|
400
512
|
author: alice,
|
|
401
513
|
recipient: carol.did,
|
|
402
514
|
protocol: protocolDefinition.protocol,
|
|
@@ -405,86 +517,90 @@ export function testRecordsSubscribeHandler() {
|
|
|
405
517
|
parentContextId: threadRecord.message.contextId,
|
|
406
518
|
data: new TextEncoder().encode('Bob cannot read this either'),
|
|
407
519
|
});
|
|
408
|
-
const chatRecordForCarol2Reply =
|
|
520
|
+
const chatRecordForCarol2Reply = await dwn.processMessage(alice.did, chatRecordForCarol2.message, { dataStream: chatRecordForCarol2.dataStream });
|
|
409
521
|
expect(chatRecordForCarol2Reply.status.code).toBe(202);
|
|
410
|
-
const chatRecordForCarol2Cid =
|
|
411
|
-
|
|
522
|
+
const chatRecordForCarol2Cid = await Message.getCid(chatRecordForCarol2.message);
|
|
523
|
+
await Poller.pollUntilSuccessOrTimeout(async () => {
|
|
412
524
|
expect(bobMessages.length).toBe(1);
|
|
413
525
|
expect(bobMessages).toEqual(expect.arrayContaining([chatRecordForBobCid]));
|
|
414
|
-
})
|
|
415
|
-
|
|
526
|
+
});
|
|
527
|
+
await Poller.pollUntilSuccessOrTimeout(async () => {
|
|
416
528
|
expect(carolMessages.length).toBe(2);
|
|
417
529
|
expect(carolMessages).toEqual(expect.arrayContaining([chatRecordForCarol1Cid, chatRecordForCarol2Cid]));
|
|
418
|
-
})
|
|
419
|
-
})
|
|
420
|
-
it('allows root-level role authorized subscriptions', () =>
|
|
530
|
+
});
|
|
531
|
+
});
|
|
532
|
+
it('allows root-level role authorized subscriptions', async () => {
|
|
421
533
|
// scenario: Alice creates a thread and writes some chat messages writes a chat message. Bob invokes his
|
|
422
534
|
// thread member role in order to subscribe to the chat messages.
|
|
423
|
-
const alice =
|
|
424
|
-
const bob =
|
|
425
|
-
const carol =
|
|
535
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
536
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
537
|
+
const carol = await TestDataGenerator.generateDidKeyPersona();
|
|
426
538
|
const protocolDefinition = friendRoleProtocolDefinition;
|
|
427
|
-
const protocolsConfig =
|
|
539
|
+
const protocolsConfig = await TestDataGenerator.generateProtocolsConfigure({
|
|
428
540
|
author: alice,
|
|
429
541
|
protocolDefinition
|
|
430
542
|
});
|
|
431
|
-
const protocolsConfigureReply =
|
|
543
|
+
const protocolsConfigureReply = await dwn.processMessage(alice.did, protocolsConfig.message);
|
|
432
544
|
expect(protocolsConfigureReply.status.code).toBe(202);
|
|
433
545
|
const filter = {
|
|
434
546
|
protocol: protocolDefinition.protocol,
|
|
435
547
|
protocolPath: 'chat'
|
|
436
548
|
};
|
|
437
549
|
const noRoleRecords = new Set();
|
|
438
|
-
const addNoRole = (
|
|
439
|
-
|
|
550
|
+
const addNoRole = async (msg) => {
|
|
551
|
+
if (msg.type !== 'event') {
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
554
|
+
const { message } = msg.event;
|
|
440
555
|
if (message.descriptor.method === DwnMethodName.Write) {
|
|
441
|
-
|
|
442
|
-
noRoleRecords.add(recordsWriteMessage.recordId);
|
|
556
|
+
noRoleRecords.add(message.recordId);
|
|
443
557
|
}
|
|
444
558
|
else {
|
|
445
559
|
noRoleRecords.delete(message.descriptor.recordId);
|
|
446
560
|
}
|
|
447
|
-
}
|
|
561
|
+
};
|
|
448
562
|
// subscribe without role, expect no messages
|
|
449
|
-
const noRoleSubscription =
|
|
563
|
+
const noRoleSubscription = await TestDataGenerator.generateRecordsSubscribe({
|
|
450
564
|
author: bob,
|
|
451
565
|
filter
|
|
452
566
|
});
|
|
453
|
-
const subscriptionReply =
|
|
567
|
+
const subscriptionReply = await dwn.processMessage(alice.did, noRoleSubscription.message, { subscriptionHandler: addNoRole });
|
|
454
568
|
expect(subscriptionReply.status.code).toBe(200);
|
|
455
569
|
expect(subscriptionReply.subscription).toBeDefined();
|
|
456
570
|
// Alice writes a 'friend' root-level role record with Bob as recipient
|
|
457
|
-
const friendRoleRecord =
|
|
571
|
+
const friendRoleRecord = await TestDataGenerator.generateRecordsWrite({
|
|
458
572
|
author: alice,
|
|
459
573
|
recipient: bob.did,
|
|
460
574
|
protocol: protocolDefinition.protocol,
|
|
461
575
|
protocolPath: 'friend',
|
|
462
576
|
data: new TextEncoder().encode('Bob is my friend'),
|
|
463
577
|
});
|
|
464
|
-
const friendRoleReply =
|
|
578
|
+
const friendRoleReply = await dwn.processMessage(alice.did, friendRoleRecord.message, { dataStream: friendRoleRecord.dataStream });
|
|
465
579
|
expect(friendRoleReply.status.code).toBe(202);
|
|
466
580
|
const recordIds = new Set();
|
|
467
|
-
const addRecord = (
|
|
468
|
-
|
|
581
|
+
const addRecord = async (msg) => {
|
|
582
|
+
if (msg.type !== 'event') {
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
const { message } = msg.event;
|
|
469
586
|
if (message.descriptor.method === DwnMethodName.Write) {
|
|
470
|
-
|
|
471
|
-
recordIds.add(recordsWriteMessage.recordId);
|
|
587
|
+
recordIds.add(message.recordId);
|
|
472
588
|
}
|
|
473
589
|
else {
|
|
474
590
|
recordIds.delete(message.descriptor.recordId);
|
|
475
591
|
}
|
|
476
|
-
}
|
|
592
|
+
};
|
|
477
593
|
// subscribe with friend role
|
|
478
|
-
const bobSubscriptionWithRole =
|
|
594
|
+
const bobSubscriptionWithRole = await TestDataGenerator.generateRecordsSubscribe({
|
|
479
595
|
filter,
|
|
480
596
|
author: bob,
|
|
481
597
|
protocolRole: 'friend',
|
|
482
598
|
});
|
|
483
|
-
const subscriptionWithRoleReply =
|
|
599
|
+
const subscriptionWithRoleReply = await dwn.processMessage(alice.did, bobSubscriptionWithRole.message, { subscriptionHandler: addRecord });
|
|
484
600
|
expect(subscriptionWithRoleReply.status.code).toBe(200);
|
|
485
601
|
expect(subscriptionWithRoleReply.subscription).toBeDefined();
|
|
486
602
|
// Create one chat message for Bob as a control to show up in the `noRoleRecords` array
|
|
487
|
-
const chatRecordForBob =
|
|
603
|
+
const chatRecordForBob = await TestDataGenerator.generateRecordsWrite({
|
|
488
604
|
author: alice,
|
|
489
605
|
recipient: bob.did,
|
|
490
606
|
protocol: protocolDefinition.protocol,
|
|
@@ -492,12 +608,12 @@ export function testRecordsSubscribeHandler() {
|
|
|
492
608
|
published: false,
|
|
493
609
|
data: new TextEncoder().encode('Bob can read this cuz he is my friend'),
|
|
494
610
|
});
|
|
495
|
-
const chatRecordForBobReply =
|
|
611
|
+
const chatRecordForBobReply = await dwn.processMessage(alice.did, chatRecordForBob.message, { dataStream: chatRecordForBob.dataStream });
|
|
496
612
|
expect(chatRecordForBobReply.status.code).toBe(202);
|
|
497
613
|
// Alice writes three more 'chat' records for carol, Bob's friend role should allow him to see these messages.
|
|
498
614
|
const chatRecordIds = [];
|
|
499
615
|
for (let i = 0; i < 3; i++) {
|
|
500
|
-
const chatRecord =
|
|
616
|
+
const chatRecord = await TestDataGenerator.generateRecordsWrite({
|
|
501
617
|
author: alice,
|
|
502
618
|
recipient: carol.did,
|
|
503
619
|
protocol: protocolDefinition.protocol,
|
|
@@ -505,20 +621,20 @@ export function testRecordsSubscribeHandler() {
|
|
|
505
621
|
published: false,
|
|
506
622
|
data: new TextEncoder().encode('Bob can read this cuz he is my friend'),
|
|
507
623
|
});
|
|
508
|
-
const chatReply =
|
|
624
|
+
const chatReply = await dwn.processMessage(alice.did, chatRecord.message, { dataStream: chatRecord.dataStream });
|
|
509
625
|
expect(chatReply.status.code).toBe(202);
|
|
510
626
|
chatRecordIds.push(chatRecord.message.recordId);
|
|
511
627
|
}
|
|
512
628
|
// there should only be the control message for bob in the subscription without a friend role.
|
|
513
|
-
|
|
629
|
+
await Poller.pollUntilSuccessOrTimeout(async () => {
|
|
514
630
|
expect(noRoleRecords.size).toBe(1);
|
|
515
631
|
expect([...noRoleRecords]).toEqual(expect.arrayContaining([chatRecordForBob.message.recordId]));
|
|
516
|
-
})
|
|
632
|
+
});
|
|
517
633
|
// All chats should be in the subscription with the friend role.
|
|
518
|
-
|
|
634
|
+
await Poller.pollUntilSuccessOrTimeout(async () => {
|
|
519
635
|
expect(recordIds.size).toBe(4);
|
|
520
636
|
expect([...recordIds]).toEqual(expect.arrayContaining([chatRecordForBob.message.recordId, ...chatRecordIds]));
|
|
521
|
-
})
|
|
637
|
+
});
|
|
522
638
|
// TODO: https://github.com/enboxorg/enbox/issues/759
|
|
523
639
|
// When `RecordsSubscribeHandler` builds up the matchFilters there are no matching filters for a delete within a context
|
|
524
640
|
// so the delete event is not being captured by the subscription handler. This is likely due to some of the filters including
|
|
@@ -544,26 +660,26 @@ export function testRecordsSubscribeHandler() {
|
|
|
544
660
|
// expect(recordIds.size).toBe(2); // both chat records were removed from the set
|
|
545
661
|
// expect([ ...recordIds ]).toEqual(expect.arrayContaining([ ...chatRecordIds.slice(1) ])); // only the last two chat records remain
|
|
546
662
|
// });
|
|
547
|
-
})
|
|
548
|
-
it('can authorize subscriptions using a context role', () =>
|
|
663
|
+
});
|
|
664
|
+
it('can authorize subscriptions using a context role', async () => {
|
|
549
665
|
// scenario: Alice writes some chat messages.
|
|
550
666
|
// Bob, having a thread/participant record, can subscribe to the chat.
|
|
551
|
-
const alice =
|
|
552
|
-
const bob =
|
|
667
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
668
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
553
669
|
const protocolDefinition = threadRoleProtocolDefinition;
|
|
554
|
-
const protocolsConfig =
|
|
670
|
+
const protocolsConfig = await TestDataGenerator.generateProtocolsConfigure({
|
|
555
671
|
author: alice,
|
|
556
672
|
protocolDefinition
|
|
557
673
|
});
|
|
558
|
-
const protocolsConfigureReply =
|
|
674
|
+
const protocolsConfigureReply = await dwn.processMessage(alice.did, protocolsConfig.message);
|
|
559
675
|
expect(protocolsConfigureReply.status.code).toBe(202);
|
|
560
676
|
// Alice writes a 'thread' record
|
|
561
|
-
const threadRecord =
|
|
677
|
+
const threadRecord = await TestDataGenerator.generateRecordsWrite({
|
|
562
678
|
author: alice,
|
|
563
679
|
protocol: protocolDefinition.protocol,
|
|
564
680
|
protocolPath: 'thread',
|
|
565
681
|
});
|
|
566
|
-
const threadRoleReply =
|
|
682
|
+
const threadRoleReply = await dwn.processMessage(alice.did, threadRecord.message, { dataStream: threadRecord.dataStream });
|
|
567
683
|
expect(threadRoleReply.status.code).toBe(202);
|
|
568
684
|
const filter = {
|
|
569
685
|
protocol: protocolDefinition.protocol,
|
|
@@ -571,23 +687,26 @@ export function testRecordsSubscribeHandler() {
|
|
|
571
687
|
contextId: threadRecord.message.contextId,
|
|
572
688
|
};
|
|
573
689
|
const noRoleRecords = [];
|
|
574
|
-
const addNoRole = (
|
|
575
|
-
|
|
690
|
+
const addNoRole = async (msg) => {
|
|
691
|
+
if (msg.type !== 'event') {
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
const { message } = msg.event;
|
|
576
695
|
if (message.descriptor.method === DwnMethodName.Write) {
|
|
577
696
|
const recordsWriteMessage = message;
|
|
578
697
|
noRoleRecords.push(recordsWriteMessage.recordId);
|
|
579
698
|
}
|
|
580
|
-
}
|
|
699
|
+
};
|
|
581
700
|
// subscribe without role, expect no messages
|
|
582
|
-
const noRoleSubscription =
|
|
701
|
+
const noRoleSubscription = await TestDataGenerator.generateRecordsSubscribe({
|
|
583
702
|
author: bob,
|
|
584
703
|
filter
|
|
585
704
|
});
|
|
586
|
-
const subscriptionReply =
|
|
705
|
+
const subscriptionReply = await dwn.processMessage(alice.did, noRoleSubscription.message, { subscriptionHandler: addNoRole });
|
|
587
706
|
expect(subscriptionReply.status.code).toBe(200);
|
|
588
707
|
expect(subscriptionReply.subscription).toBeDefined();
|
|
589
708
|
// Alice writes a 'participant' role record with Bob as recipient
|
|
590
|
-
const participantRoleRecord =
|
|
709
|
+
const participantRoleRecord = await TestDataGenerator.generateRecordsWrite({
|
|
591
710
|
author: alice,
|
|
592
711
|
recipient: bob.did,
|
|
593
712
|
protocol: protocolDefinition.protocol,
|
|
@@ -595,29 +714,32 @@ export function testRecordsSubscribeHandler() {
|
|
|
595
714
|
parentContextId: threadRecord.message.contextId,
|
|
596
715
|
data: new TextEncoder().encode('Bob is my friend'),
|
|
597
716
|
});
|
|
598
|
-
const participantRoleReply =
|
|
717
|
+
const participantRoleReply = await dwn.processMessage(alice.did, participantRoleRecord.message, { dataStream: participantRoleRecord.dataStream });
|
|
599
718
|
expect(participantRoleReply.status.code).toBe(202);
|
|
600
719
|
const recordIds = [];
|
|
601
|
-
const addRecord = (
|
|
602
|
-
|
|
720
|
+
const addRecord = async (msg) => {
|
|
721
|
+
if (msg.type !== 'event') {
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
const { message } = msg.event;
|
|
603
725
|
if (message.descriptor.method === DwnMethodName.Write) {
|
|
604
726
|
const recordsWriteMessage = message;
|
|
605
727
|
recordIds.push(recordsWriteMessage.recordId);
|
|
606
728
|
}
|
|
607
|
-
}
|
|
729
|
+
};
|
|
608
730
|
// subscribe with the participant role
|
|
609
|
-
const bobSubscriptionWithRole =
|
|
731
|
+
const bobSubscriptionWithRole = await TestDataGenerator.generateRecordsSubscribe({
|
|
610
732
|
filter,
|
|
611
733
|
author: bob,
|
|
612
734
|
protocolRole: 'thread/participant',
|
|
613
735
|
});
|
|
614
|
-
const subscriptionWithRoleReply =
|
|
736
|
+
const subscriptionWithRoleReply = await dwn.processMessage(alice.did, bobSubscriptionWithRole.message, { subscriptionHandler: addRecord });
|
|
615
737
|
expect(subscriptionWithRoleReply.status.code).toBe(200);
|
|
616
738
|
expect(subscriptionWithRoleReply.subscription).toBeDefined();
|
|
617
739
|
// Alice writes three 'chat' records
|
|
618
740
|
const chatRecordIds = [];
|
|
619
741
|
for (let i = 0; i < 3; i++) {
|
|
620
|
-
const chatRecord =
|
|
742
|
+
const chatRecord = await TestDataGenerator.generateRecordsWrite({
|
|
621
743
|
author: alice,
|
|
622
744
|
recipient: alice.did,
|
|
623
745
|
protocol: protocolDefinition.protocol,
|
|
@@ -626,41 +748,41 @@ export function testRecordsSubscribeHandler() {
|
|
|
626
748
|
parentContextId: threadRecord.message.contextId,
|
|
627
749
|
data: new TextEncoder().encode('Bob can read this cuz he is my friend'),
|
|
628
750
|
});
|
|
629
|
-
const chatReply =
|
|
751
|
+
const chatReply = await dwn.processMessage(alice.did, chatRecord.message, { dataStream: chatRecord.dataStream });
|
|
630
752
|
expect(chatReply.status.code).toBe(202);
|
|
631
753
|
chatRecordIds.push(chatRecord.message.recordId);
|
|
632
754
|
}
|
|
633
|
-
|
|
755
|
+
await Poller.pollUntilSuccessOrTimeout(async () => {
|
|
634
756
|
// should have all chat messages.
|
|
635
757
|
expect(recordIds).toEqual(expect.arrayContaining(chatRecordIds));
|
|
636
758
|
// there should not be any messages in the subscription without a participant role.
|
|
637
759
|
expect(noRoleRecords.length).toBe(0);
|
|
638
|
-
})
|
|
639
|
-
})
|
|
640
|
-
it('does not execute protocol subscriptions where protocolPath is missing from the filter', () =>
|
|
760
|
+
});
|
|
761
|
+
});
|
|
762
|
+
it('does not execute protocol subscriptions where protocolPath is missing from the filter', async () => {
|
|
641
763
|
// scenario: Alice assigns Bob a friend role and writes some chat messages. Bob invokes his role to subscribe those messages,
|
|
642
764
|
// but his subscription filter does not include protocolPath.
|
|
643
|
-
const alice =
|
|
644
|
-
const bob =
|
|
765
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
766
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
645
767
|
const protocolDefinition = friendRoleProtocolDefinition;
|
|
646
|
-
const protocolsConfig =
|
|
768
|
+
const protocolsConfig = await TestDataGenerator.generateProtocolsConfigure({
|
|
647
769
|
author: alice,
|
|
648
770
|
protocolDefinition
|
|
649
771
|
});
|
|
650
|
-
const protocolsConfigureReply =
|
|
772
|
+
const protocolsConfigureReply = await dwn.processMessage(alice.did, protocolsConfig.message);
|
|
651
773
|
expect(protocolsConfigureReply.status.code).toBe(202);
|
|
652
774
|
// Alice writes a 'friend' root-level role record with Bob as recipient
|
|
653
|
-
const friendRoleRecord =
|
|
775
|
+
const friendRoleRecord = await TestDataGenerator.generateRecordsWrite({
|
|
654
776
|
author: alice,
|
|
655
777
|
recipient: bob.did,
|
|
656
778
|
protocol: protocolDefinition.protocol,
|
|
657
779
|
protocolPath: 'friend',
|
|
658
780
|
data: new TextEncoder().encode('Bob is my friend'),
|
|
659
781
|
});
|
|
660
|
-
const friendRoleReply =
|
|
782
|
+
const friendRoleReply = await dwn.processMessage(alice.did, friendRoleRecord.message, { dataStream: friendRoleRecord.dataStream });
|
|
661
783
|
expect(friendRoleReply.status.code).toBe(202);
|
|
662
784
|
// Bob invokes his friendRole to subscribe but does not have `protocolPath` in the filter
|
|
663
|
-
const chatSubscribe =
|
|
785
|
+
const chatSubscribe = await TestDataGenerator.generateRecordsSubscribe({
|
|
664
786
|
author: bob,
|
|
665
787
|
filter: {
|
|
666
788
|
protocol: protocolDefinition.protocol,
|
|
@@ -668,33 +790,33 @@ export function testRecordsSubscribeHandler() {
|
|
|
668
790
|
},
|
|
669
791
|
protocolRole: 'friend',
|
|
670
792
|
});
|
|
671
|
-
const chatSubscribeReply =
|
|
793
|
+
const chatSubscribeReply = await dwn.processMessage(alice.did, chatSubscribe.message);
|
|
672
794
|
expect(chatSubscribeReply.status.code).toBe(400);
|
|
673
795
|
expect(chatSubscribeReply.status.detail).toContain(DwnErrorCode.RecordsSubscribeFilterMissingRequiredProperties);
|
|
674
796
|
expect(chatSubscribeReply.subscription).toBeUndefined();
|
|
675
|
-
})
|
|
676
|
-
it('does not execute context role authorized subscriptions where contextId is missing from the filter', () =>
|
|
797
|
+
});
|
|
798
|
+
it('does not execute context role authorized subscriptions where contextId is missing from the filter', async () => {
|
|
677
799
|
// scenario: Alice gives Bob a role allowing him to access a particular chat thread.
|
|
678
800
|
// But Bob's filter does not contain a contextId so the subscription fails.
|
|
679
|
-
const alice =
|
|
680
|
-
const bob =
|
|
801
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
802
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
681
803
|
const protocolDefinition = threadRoleProtocolDefinition;
|
|
682
|
-
const protocolsConfig =
|
|
804
|
+
const protocolsConfig = await TestDataGenerator.generateProtocolsConfigure({
|
|
683
805
|
author: alice,
|
|
684
806
|
protocolDefinition
|
|
685
807
|
});
|
|
686
|
-
const protocolsConfigureReply =
|
|
808
|
+
const protocolsConfigureReply = await dwn.processMessage(alice.did, protocolsConfig.message);
|
|
687
809
|
expect(protocolsConfigureReply.status.code).toBe(202);
|
|
688
810
|
// Alice writes a 'thread' record
|
|
689
|
-
const threadRecord =
|
|
811
|
+
const threadRecord = await TestDataGenerator.generateRecordsWrite({
|
|
690
812
|
author: alice,
|
|
691
813
|
protocol: protocolDefinition.protocol,
|
|
692
814
|
protocolPath: 'thread',
|
|
693
815
|
});
|
|
694
|
-
const threadRoleReply =
|
|
816
|
+
const threadRoleReply = await dwn.processMessage(alice.did, threadRecord.message, { dataStream: threadRecord.dataStream });
|
|
695
817
|
expect(threadRoleReply.status.code).toBe(202);
|
|
696
818
|
// Alice writes a 'friend' root-level role record with Bob as recipient
|
|
697
|
-
const participantRoleRecord =
|
|
819
|
+
const participantRoleRecord = await TestDataGenerator.generateRecordsWrite({
|
|
698
820
|
author: alice,
|
|
699
821
|
recipient: bob.did,
|
|
700
822
|
protocol: protocolDefinition.protocol,
|
|
@@ -702,10 +824,10 @@ export function testRecordsSubscribeHandler() {
|
|
|
702
824
|
parentContextId: threadRecord.message.contextId,
|
|
703
825
|
data: new TextEncoder().encode('Bob is my friend'),
|
|
704
826
|
});
|
|
705
|
-
const participantRoleReply =
|
|
827
|
+
const participantRoleReply = await dwn.processMessage(alice.did, participantRoleRecord.message, { dataStream: participantRoleRecord.dataStream });
|
|
706
828
|
expect(participantRoleReply.status.code).toBe(202);
|
|
707
829
|
// Bob invokes his thread participant role to subscribe but omits the contextId
|
|
708
|
-
const chatSubscribe =
|
|
830
|
+
const chatSubscribe = await TestDataGenerator.generateRecordsSubscribe({
|
|
709
831
|
author: bob,
|
|
710
832
|
filter: {
|
|
711
833
|
protocol: protocolDefinition.protocol,
|
|
@@ -714,25 +836,25 @@ export function testRecordsSubscribeHandler() {
|
|
|
714
836
|
},
|
|
715
837
|
protocolRole: 'thread/participant',
|
|
716
838
|
});
|
|
717
|
-
const chatSubscribeReply =
|
|
839
|
+
const chatSubscribeReply = await dwn.processMessage(alice.did, chatSubscribe.message);
|
|
718
840
|
expect(chatSubscribeReply.status.code).toBe(401);
|
|
719
841
|
expect(chatSubscribeReply.status.detail).toContain(DwnErrorCode.ProtocolAuthorizationMissingContextId);
|
|
720
842
|
expect(chatSubscribeReply.subscription).toBeUndefined();
|
|
721
|
-
})
|
|
722
|
-
it('rejects role authorized subscriptions if the request author does not have a matching root-level role', () =>
|
|
843
|
+
});
|
|
844
|
+
it('rejects role authorized subscriptions if the request author does not have a matching root-level role', async () => {
|
|
723
845
|
// scenario: Alice installs a chat protocol.
|
|
724
846
|
// Bob invokes a root-level role within that protocol to subscribe but fails because he does not actually have a role.
|
|
725
|
-
const alice =
|
|
726
|
-
const bob =
|
|
847
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
848
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
727
849
|
const protocolDefinition = friendRoleProtocolDefinition;
|
|
728
|
-
const protocolsConfig =
|
|
850
|
+
const protocolsConfig = await TestDataGenerator.generateProtocolsConfigure({
|
|
729
851
|
author: alice,
|
|
730
852
|
protocolDefinition
|
|
731
853
|
});
|
|
732
|
-
const protocolsConfigureReply =
|
|
854
|
+
const protocolsConfigureReply = await dwn.processMessage(alice.did, protocolsConfig.message);
|
|
733
855
|
expect(protocolsConfigureReply.status.code).toBe(202);
|
|
734
856
|
// Bob invokes a friendRole he does not have to subscribe to the records
|
|
735
|
-
const chatSubscribe =
|
|
857
|
+
const chatSubscribe = await TestDataGenerator.generateRecordsSubscribe({
|
|
736
858
|
author: bob,
|
|
737
859
|
filter: {
|
|
738
860
|
protocol: protocolDefinition.protocol,
|
|
@@ -740,31 +862,31 @@ export function testRecordsSubscribeHandler() {
|
|
|
740
862
|
},
|
|
741
863
|
protocolRole: 'friend',
|
|
742
864
|
});
|
|
743
|
-
const chatSubscribeReply =
|
|
865
|
+
const chatSubscribeReply = await dwn.processMessage(alice.did, chatSubscribe.message);
|
|
744
866
|
expect(chatSubscribeReply.status.code).toBe(401);
|
|
745
867
|
expect(chatSubscribeReply.status.detail).toContain(DwnErrorCode.ProtocolAuthorizationMatchingRoleRecordNotFound);
|
|
746
868
|
expect(chatSubscribeReply.subscription).toBeUndefined();
|
|
747
|
-
})
|
|
748
|
-
it('rejects role authorized subscriptions where the subscription author does not have a matching context role', () =>
|
|
749
|
-
const alice =
|
|
750
|
-
const bob =
|
|
869
|
+
});
|
|
870
|
+
it('rejects role authorized subscriptions where the subscription author does not have a matching context role', async () => {
|
|
871
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
872
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
751
873
|
const protocolDefinition = threadRoleProtocolDefinition;
|
|
752
|
-
const protocolsConfig =
|
|
874
|
+
const protocolsConfig = await TestDataGenerator.generateProtocolsConfigure({
|
|
753
875
|
author: alice,
|
|
754
876
|
protocolDefinition
|
|
755
877
|
});
|
|
756
|
-
const protocolsConfigureReply =
|
|
878
|
+
const protocolsConfigureReply = await dwn.processMessage(alice.did, protocolsConfig.message);
|
|
757
879
|
expect(protocolsConfigureReply.status.code).toBe(202);
|
|
758
880
|
// Alice writes a 'thread' record
|
|
759
|
-
const threadRecord =
|
|
881
|
+
const threadRecord = await TestDataGenerator.generateRecordsWrite({
|
|
760
882
|
author: alice,
|
|
761
883
|
protocol: protocolDefinition.protocol,
|
|
762
884
|
protocolPath: 'thread',
|
|
763
885
|
});
|
|
764
|
-
const threadRoleReply =
|
|
886
|
+
const threadRoleReply = await dwn.processMessage(alice.did, threadRecord.message, { dataStream: threadRecord.dataStream });
|
|
765
887
|
expect(threadRoleReply.status.code).toBe(202);
|
|
766
888
|
// Bob invokes his a `thread/participant` role which he does not have to subscribe to the records
|
|
767
|
-
const chatSubscribe =
|
|
889
|
+
const chatSubscribe = await TestDataGenerator.generateRecordsSubscribe({
|
|
768
890
|
author: bob,
|
|
769
891
|
filter: {
|
|
770
892
|
protocol: protocolDefinition.protocol,
|
|
@@ -773,11 +895,11 @@ export function testRecordsSubscribeHandler() {
|
|
|
773
895
|
},
|
|
774
896
|
protocolRole: 'thread/participant',
|
|
775
897
|
});
|
|
776
|
-
const chatSubscribeReply =
|
|
898
|
+
const chatSubscribeReply = await dwn.processMessage(alice.did, chatSubscribe.message);
|
|
777
899
|
expect(chatSubscribeReply.status.code).toBe(401);
|
|
778
900
|
expect(chatSubscribeReply.status.detail).toContain(DwnErrorCode.ProtocolAuthorizationMatchingRoleRecordNotFound);
|
|
779
901
|
expect(chatSubscribeReply.subscription).toBeUndefined();
|
|
780
|
-
})
|
|
902
|
+
});
|
|
781
903
|
describe('who-based query/subscribe action rules', () => {
|
|
782
904
|
const whoSubscribeProtocol = {
|
|
783
905
|
published: true,
|
|
@@ -797,75 +919,84 @@ export function testRecordsSubscribeHandler() {
|
|
|
797
919
|
},
|
|
798
920
|
},
|
|
799
921
|
};
|
|
800
|
-
it('recipient receives only events for records addressed to them', () =>
|
|
922
|
+
it('recipient receives only events for records addressed to them', async () => {
|
|
801
923
|
// scenario: Bob and Carol each subscribe to Alice's DWN. Alice writes messages
|
|
802
924
|
// to Bob and Carol. Each subscriber only receives their own messages.
|
|
803
925
|
// Dave subscribes and receives nothing.
|
|
804
|
-
const alice =
|
|
805
|
-
const bob =
|
|
806
|
-
const carol =
|
|
807
|
-
const dave =
|
|
808
|
-
const protocolsConfig =
|
|
926
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
927
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
928
|
+
const carol = await TestDataGenerator.generateDidKeyPersona();
|
|
929
|
+
const dave = await TestDataGenerator.generateDidKeyPersona();
|
|
930
|
+
const protocolsConfig = await TestDataGenerator.generateProtocolsConfigure({
|
|
809
931
|
author: alice,
|
|
810
932
|
protocolDefinition: whoSubscribeProtocol,
|
|
811
933
|
});
|
|
812
|
-
const protocolsConfigureReply =
|
|
934
|
+
const protocolsConfigureReply = await dwn.processMessage(alice.did, protocolsConfig.message);
|
|
813
935
|
expect(protocolsConfigureReply.status.code).toBe(202);
|
|
814
936
|
// Bob subscribes — no role
|
|
815
937
|
const bobRecordIds = new Set();
|
|
816
|
-
const bobHandler = (
|
|
817
|
-
|
|
938
|
+
const bobHandler = async (msg) => {
|
|
939
|
+
if (msg.type !== 'event') {
|
|
940
|
+
return;
|
|
941
|
+
}
|
|
942
|
+
const { message } = msg.event;
|
|
818
943
|
if (message.descriptor.method === DwnMethodName.Write) {
|
|
819
944
|
bobRecordIds.add(message.recordId);
|
|
820
945
|
}
|
|
821
|
-
}
|
|
822
|
-
const bobSub =
|
|
946
|
+
};
|
|
947
|
+
const bobSub = await TestDataGenerator.generateRecordsSubscribe({
|
|
823
948
|
author: bob,
|
|
824
949
|
filter: {
|
|
825
950
|
published: false,
|
|
826
951
|
protocol: whoSubscribeProtocol.protocol,
|
|
827
952
|
},
|
|
828
953
|
});
|
|
829
|
-
const bobSubReply =
|
|
954
|
+
const bobSubReply = await dwn.processMessage(alice.did, bobSub.message, { subscriptionHandler: bobHandler });
|
|
830
955
|
expect(bobSubReply.status.code).toBe(200);
|
|
831
956
|
// Carol subscribes — no role
|
|
832
957
|
const carolRecordIds = new Set();
|
|
833
|
-
const carolHandler = (
|
|
834
|
-
|
|
958
|
+
const carolHandler = async (msg) => {
|
|
959
|
+
if (msg.type !== 'event') {
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
962
|
+
const { message } = msg.event;
|
|
835
963
|
if (message.descriptor.method === DwnMethodName.Write) {
|
|
836
964
|
carolRecordIds.add(message.recordId);
|
|
837
965
|
}
|
|
838
|
-
}
|
|
839
|
-
const carolSub =
|
|
966
|
+
};
|
|
967
|
+
const carolSub = await TestDataGenerator.generateRecordsSubscribe({
|
|
840
968
|
author: carol,
|
|
841
969
|
filter: {
|
|
842
970
|
published: false,
|
|
843
971
|
protocol: whoSubscribeProtocol.protocol,
|
|
844
972
|
},
|
|
845
973
|
});
|
|
846
|
-
const carolSubReply =
|
|
974
|
+
const carolSubReply = await dwn.processMessage(alice.did, carolSub.message, { subscriptionHandler: carolHandler });
|
|
847
975
|
expect(carolSubReply.status.code).toBe(200);
|
|
848
976
|
// Dave subscribes — no role, not a participant at all
|
|
849
977
|
const daveRecordIds = new Set();
|
|
850
|
-
const daveHandler = (
|
|
851
|
-
|
|
978
|
+
const daveHandler = async (msg) => {
|
|
979
|
+
if (msg.type !== 'event') {
|
|
980
|
+
return;
|
|
981
|
+
}
|
|
982
|
+
const { message } = msg.event;
|
|
852
983
|
if (message.descriptor.method === DwnMethodName.Write) {
|
|
853
984
|
daveRecordIds.add(message.recordId);
|
|
854
985
|
}
|
|
855
|
-
}
|
|
856
|
-
const daveSub =
|
|
986
|
+
};
|
|
987
|
+
const daveSub = await TestDataGenerator.generateRecordsSubscribe({
|
|
857
988
|
author: dave,
|
|
858
989
|
filter: {
|
|
859
990
|
published: false,
|
|
860
991
|
protocol: whoSubscribeProtocol.protocol,
|
|
861
992
|
},
|
|
862
993
|
});
|
|
863
|
-
const daveSubReply =
|
|
994
|
+
const daveSubReply = await dwn.processMessage(alice.did, daveSub.message, { subscriptionHandler: daveHandler });
|
|
864
995
|
expect(daveSubReply.status.code).toBe(200);
|
|
865
996
|
// Alice writes 2 messages for Bob
|
|
866
997
|
const expectedBobIds = [];
|
|
867
998
|
for (let i = 0; i < 2; i++) {
|
|
868
|
-
const msg =
|
|
999
|
+
const msg = await TestDataGenerator.generateRecordsWrite({
|
|
869
1000
|
author: alice,
|
|
870
1001
|
recipient: bob.did,
|
|
871
1002
|
protocol: whoSubscribeProtocol.protocol,
|
|
@@ -874,12 +1005,12 @@ export function testRecordsSubscribeHandler() {
|
|
|
874
1005
|
dataFormat: 'text/plain',
|
|
875
1006
|
data: new TextEncoder().encode(`for bob ${i}`),
|
|
876
1007
|
});
|
|
877
|
-
const reply =
|
|
1008
|
+
const reply = await dwn.processMessage(alice.did, msg.message, { dataStream: msg.dataStream });
|
|
878
1009
|
expect(reply.status.code).toBe(202);
|
|
879
1010
|
expectedBobIds.push(msg.message.recordId);
|
|
880
1011
|
}
|
|
881
1012
|
// Alice writes 1 message for Carol
|
|
882
|
-
const carolMsg =
|
|
1013
|
+
const carolMsg = await TestDataGenerator.generateRecordsWrite({
|
|
883
1014
|
author: alice,
|
|
884
1015
|
recipient: carol.did,
|
|
885
1016
|
protocol: whoSubscribeProtocol.protocol,
|
|
@@ -888,10 +1019,10 @@ export function testRecordsSubscribeHandler() {
|
|
|
888
1019
|
dataFormat: 'text/plain',
|
|
889
1020
|
data: new TextEncoder().encode('for carol'),
|
|
890
1021
|
});
|
|
891
|
-
const carolWriteReply =
|
|
1022
|
+
const carolWriteReply = await dwn.processMessage(alice.did, carolMsg.message, { dataStream: carolMsg.dataStream });
|
|
892
1023
|
expect(carolWriteReply.status.code).toBe(202);
|
|
893
1024
|
// Alice writes 1 message addressed to herself (nobody else should see it)
|
|
894
|
-
const aliceMsg =
|
|
1025
|
+
const aliceMsg = await TestDataGenerator.generateRecordsWrite({
|
|
895
1026
|
author: alice,
|
|
896
1027
|
recipient: alice.did,
|
|
897
1028
|
protocol: whoSubscribeProtocol.protocol,
|
|
@@ -900,28 +1031,28 @@ export function testRecordsSubscribeHandler() {
|
|
|
900
1031
|
dataFormat: 'text/plain',
|
|
901
1032
|
data: new TextEncoder().encode('private'),
|
|
902
1033
|
});
|
|
903
|
-
const aliceWriteReply =
|
|
1034
|
+
const aliceWriteReply = await dwn.processMessage(alice.did, aliceMsg.message, { dataStream: aliceMsg.dataStream });
|
|
904
1035
|
expect(aliceWriteReply.status.code).toBe(202);
|
|
905
1036
|
// Bob should receive exactly 2 events
|
|
906
|
-
|
|
1037
|
+
await Poller.pollUntilSuccessOrTimeout(async () => {
|
|
907
1038
|
expect(bobRecordIds.size).toBe(2);
|
|
908
1039
|
expect([...bobRecordIds]).toEqual(expect.arrayContaining(expectedBobIds));
|
|
909
|
-
})
|
|
1040
|
+
});
|
|
910
1041
|
// Carol should receive exactly 1 event
|
|
911
|
-
|
|
1042
|
+
await Poller.pollUntilSuccessOrTimeout(async () => {
|
|
912
1043
|
expect(carolRecordIds.size).toBe(1);
|
|
913
1044
|
expect([...carolRecordIds]).toEqual(expect.arrayContaining([carolMsg.message.recordId]));
|
|
914
|
-
})
|
|
1045
|
+
});
|
|
915
1046
|
// Dave should receive zero events
|
|
916
1047
|
// Give a small window for any stray events to arrive, then assert empty
|
|
917
|
-
|
|
1048
|
+
await Time.sleep(200);
|
|
918
1049
|
expect(daveRecordIds.size).toBe(0);
|
|
919
|
-
})
|
|
920
|
-
it('who-based subscribe rules do not grant role-like broad access', () =>
|
|
1050
|
+
});
|
|
1051
|
+
it('who-based subscribe rules do not grant role-like broad access', async () => {
|
|
921
1052
|
// scenario: Dave tries to invoke a protocolRole on a protocol with who-based
|
|
922
1053
|
// subscribe rules. Should be rejected because he has no role record.
|
|
923
|
-
const alice =
|
|
924
|
-
const dave =
|
|
1054
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
1055
|
+
const dave = await TestDataGenerator.generateDidKeyPersona();
|
|
925
1056
|
const mixedProtocol = {
|
|
926
1057
|
published: true,
|
|
927
1058
|
protocol: 'http://mixed-sub-test.xyz',
|
|
@@ -945,22 +1076,22 @@ export function testRecordsSubscribeHandler() {
|
|
|
945
1076
|
},
|
|
946
1077
|
},
|
|
947
1078
|
};
|
|
948
|
-
const protocolsConfig =
|
|
1079
|
+
const protocolsConfig = await TestDataGenerator.generateProtocolsConfigure({
|
|
949
1080
|
author: alice,
|
|
950
1081
|
protocolDefinition: mixedProtocol,
|
|
951
1082
|
});
|
|
952
|
-
const protocolsConfigureReply =
|
|
1083
|
+
const protocolsConfigureReply = await dwn.processMessage(alice.did, protocolsConfig.message);
|
|
953
1084
|
expect(protocolsConfigureReply.status.code).toBe(202);
|
|
954
1085
|
// Alice creates a thread
|
|
955
|
-
const threadRecord =
|
|
1086
|
+
const threadRecord = await TestDataGenerator.generateRecordsWrite({
|
|
956
1087
|
author: alice,
|
|
957
1088
|
protocol: mixedProtocol.protocol,
|
|
958
1089
|
protocolPath: 'thread',
|
|
959
1090
|
});
|
|
960
|
-
const threadReply =
|
|
1091
|
+
const threadReply = await dwn.processMessage(alice.did, threadRecord.message, { dataStream: threadRecord.dataStream });
|
|
961
1092
|
expect(threadReply.status.code).toBe(202);
|
|
962
1093
|
// Dave tries to subscribe with a role he doesn't have — should be rejected
|
|
963
|
-
const daveRoleSub =
|
|
1094
|
+
const daveRoleSub = await TestDataGenerator.generateRecordsSubscribe({
|
|
964
1095
|
author: dave,
|
|
965
1096
|
filter: {
|
|
966
1097
|
protocol: mixedProtocol.protocol,
|
|
@@ -969,11 +1100,11 @@ export function testRecordsSubscribeHandler() {
|
|
|
969
1100
|
},
|
|
970
1101
|
protocolRole: 'thread/participant',
|
|
971
1102
|
});
|
|
972
|
-
const daveRoleSubReply =
|
|
1103
|
+
const daveRoleSubReply = await dwn.processMessage(alice.did, daveRoleSub.message);
|
|
973
1104
|
expect(daveRoleSubReply.status.code).toBe(401);
|
|
974
1105
|
expect(daveRoleSubReply.status.detail).toContain(DwnErrorCode.ProtocolAuthorizationMatchingRoleRecordNotFound);
|
|
975
1106
|
expect(daveRoleSubReply.subscription).toBeUndefined();
|
|
976
|
-
})
|
|
1107
|
+
});
|
|
977
1108
|
});
|
|
978
1109
|
});
|
|
979
1110
|
});
|