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