@enbox/dwn-sdk-js 0.0.6 → 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 +100 -125
- 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 +549 -564
- 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 +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 +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/tests/features/permissions.spec.d.ts.map +1 -1
- package/package.json +2 -2
- 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 +1 -1
|
@@ -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 { ResumableTaskManager } from '../../src/core/resumable-task-manager.js';
|
|
11
2
|
import sinon from 'sinon';
|
|
12
3
|
import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'bun:test';
|
|
@@ -46,7 +37,7 @@ export function testRecordsDeleteHandler() {
|
|
|
46
37
|
describe('functional tests', () => {
|
|
47
38
|
// important to follow the `before` and `after` pattern to initialize and clean the stores in tests
|
|
48
39
|
// so that different test suites can reuse the same backend store for testing
|
|
49
|
-
beforeAll(() =>
|
|
40
|
+
beforeAll(async () => {
|
|
50
41
|
didResolver = new UniversalResolver({ didResolvers: [DidKey] });
|
|
51
42
|
const stores = TestStores.get();
|
|
52
43
|
messageStore = stores.messageStore;
|
|
@@ -54,511 +45,508 @@ export function testRecordsDeleteHandler() {
|
|
|
54
45
|
resumableTaskStore = stores.resumableTaskStore;
|
|
55
46
|
stateIndex = stores.stateIndex;
|
|
56
47
|
eventStream = TestEventStream.get();
|
|
57
|
-
dwn =
|
|
58
|
-
})
|
|
59
|
-
beforeEach(() =>
|
|
48
|
+
dwn = await Dwn.create({ didResolver, messageStore, dataStore, stateIndex, eventStream, resumableTaskStore });
|
|
49
|
+
});
|
|
50
|
+
beforeEach(async () => {
|
|
60
51
|
// clean up before each test rather than after so that a test does not depend on other tests to do the clean up
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
})
|
|
66
|
-
afterAll(() =>
|
|
67
|
-
|
|
68
|
-
})
|
|
69
|
-
it('should handle RecordsDelete successfully and return 404 if deleting a deleted record', () =>
|
|
70
|
-
|
|
71
|
-
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
52
|
+
await messageStore.clear();
|
|
53
|
+
await dataStore.clear();
|
|
54
|
+
await resumableTaskStore.clear();
|
|
55
|
+
await stateIndex.clear();
|
|
56
|
+
});
|
|
57
|
+
afterAll(async () => {
|
|
58
|
+
await dwn.close();
|
|
59
|
+
});
|
|
60
|
+
it('should handle RecordsDelete successfully and return 404 if deleting a deleted record', async () => {
|
|
61
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
72
62
|
// insert data
|
|
73
|
-
const { message, dataStream } =
|
|
74
|
-
const writeReply =
|
|
63
|
+
const { message, dataStream } = await TestDataGenerator.generateRecordsWrite({ author: alice });
|
|
64
|
+
const writeReply = await dwn.processMessage(alice.did, message, { dataStream });
|
|
75
65
|
expect(writeReply.status.code).toBe(202);
|
|
76
66
|
// ensure data is inserted
|
|
77
|
-
const queryData =
|
|
67
|
+
const queryData = await TestDataGenerator.generateRecordsQuery({
|
|
78
68
|
author: alice,
|
|
79
69
|
filter: { recordId: message.recordId }
|
|
80
70
|
});
|
|
81
|
-
const reply =
|
|
71
|
+
const reply = await dwn.processMessage(alice.did, queryData.message);
|
|
82
72
|
expect(reply.status.code).toBe(200);
|
|
83
|
-
expect(
|
|
73
|
+
expect(reply.entries?.length).toBe(1);
|
|
84
74
|
// testing delete
|
|
85
|
-
const recordsDelete =
|
|
75
|
+
const recordsDelete = await RecordsDelete.create({
|
|
86
76
|
recordId: message.recordId,
|
|
87
77
|
signer: Jws.createSigner(alice)
|
|
88
78
|
});
|
|
89
|
-
const deleteReply =
|
|
79
|
+
const deleteReply = await dwn.processMessage(alice.did, recordsDelete.message);
|
|
90
80
|
expect(deleteReply.status.code).toBe(202);
|
|
91
81
|
// ensure a query will no longer find the deleted record
|
|
92
|
-
const reply2 =
|
|
82
|
+
const reply2 = await dwn.processMessage(alice.did, queryData.message);
|
|
93
83
|
expect(reply2.status.code).toBe(200);
|
|
94
|
-
expect(
|
|
84
|
+
expect(reply2.entries?.length).toBe(0);
|
|
95
85
|
// testing deleting a deleted record
|
|
96
|
-
const recordsDelete2 =
|
|
86
|
+
const recordsDelete2 = await RecordsDelete.create({
|
|
97
87
|
recordId: message.recordId,
|
|
98
88
|
signer: Jws.createSigner(alice)
|
|
99
89
|
});
|
|
100
|
-
const recordsDelete2Reply =
|
|
90
|
+
const recordsDelete2Reply = await dwn.processMessage(alice.did, recordsDelete2.message);
|
|
101
91
|
expect(recordsDelete2Reply.status.code).toBe(404);
|
|
102
|
-
})
|
|
103
|
-
it('should not affect other records or tenants with the same data', () =>
|
|
104
|
-
const alice =
|
|
105
|
-
const bob =
|
|
92
|
+
});
|
|
93
|
+
it('should not affect other records or tenants with the same data', async () => {
|
|
94
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
95
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
106
96
|
const data = Encoder.stringToBytes('test');
|
|
107
97
|
// alice writes a records with data
|
|
108
|
-
const aliceWriteData =
|
|
109
|
-
const aliceWriteReply =
|
|
98
|
+
const aliceWriteData = await TestDataGenerator.generateRecordsWrite({ author: alice, data });
|
|
99
|
+
const aliceWriteReply = await dwn.processMessage(alice.did, aliceWriteData.message, { dataStream: aliceWriteData.dataStream });
|
|
110
100
|
expect(aliceWriteReply.status.code).toBe(202);
|
|
111
101
|
// alice writes another record with the same data
|
|
112
|
-
const aliceWrite2Data =
|
|
113
|
-
const aliceWrite2Reply =
|
|
102
|
+
const aliceWrite2Data = await TestDataGenerator.generateRecordsWrite({ author: alice, data });
|
|
103
|
+
const aliceWrite2Reply = await dwn.processMessage(alice.did, aliceWrite2Data.message, { dataStream: aliceWrite2Data.dataStream });
|
|
114
104
|
expect(aliceWrite2Reply.status.code).toBe(202);
|
|
115
105
|
// bob writes a records with same data
|
|
116
|
-
const bobWriteData =
|
|
117
|
-
const bobWriteReply =
|
|
106
|
+
const bobWriteData = await TestDataGenerator.generateRecordsWrite({ author: bob, data });
|
|
107
|
+
const bobWriteReply = await dwn.processMessage(bob.did, bobWriteData.message, { dataStream: bobWriteData.dataStream });
|
|
118
108
|
expect(bobWriteReply.status.code).toBe(202);
|
|
119
109
|
// bob writes another record with the same data
|
|
120
|
-
const bobWrite2Data =
|
|
121
|
-
const bobWrite2Reply =
|
|
110
|
+
const bobWrite2Data = await TestDataGenerator.generateRecordsWrite({ author: bob, data });
|
|
111
|
+
const bobWrite2Reply = await dwn.processMessage(bob.did, bobWrite2Data.message, { dataStream: bobWrite2Data.dataStream });
|
|
122
112
|
expect(bobWrite2Reply.status.code).toBe(202);
|
|
123
113
|
// alice deletes one of the two records
|
|
124
|
-
const aliceDeleteWriteData =
|
|
114
|
+
const aliceDeleteWriteData = await TestDataGenerator.generateRecordsDelete({
|
|
125
115
|
author: alice,
|
|
126
116
|
recordId: aliceWriteData.message.recordId
|
|
127
117
|
});
|
|
128
|
-
const aliceDeleteWriteReply =
|
|
118
|
+
const aliceDeleteWriteReply = await dwn.processMessage(alice.did, aliceDeleteWriteData.message);
|
|
129
119
|
expect(aliceDeleteWriteReply.status.code).toBe(202);
|
|
130
120
|
// verify the other record with the same data is unaffected
|
|
131
|
-
const aliceRead1 =
|
|
121
|
+
const aliceRead1 = await RecordsRead.create({
|
|
132
122
|
filter: {
|
|
133
123
|
recordId: aliceWrite2Data.message.recordId,
|
|
134
124
|
},
|
|
135
125
|
signer: Jws.createSigner(alice)
|
|
136
126
|
});
|
|
137
|
-
const aliceRead1Reply =
|
|
127
|
+
const aliceRead1Reply = await dwn.processMessage(alice.did, aliceRead1.message);
|
|
138
128
|
expect(aliceRead1Reply.status.code).toBe(200);
|
|
139
|
-
const aliceDataFetched =
|
|
129
|
+
const aliceDataFetched = await DataStream.toBytes(aliceRead1Reply.entry.data);
|
|
140
130
|
expect(ArrayUtility.byteArraysEqual(aliceDataFetched, data)).toBe(true);
|
|
141
131
|
// alice deletes the other record
|
|
142
|
-
const aliceDeleteWrite2Data =
|
|
132
|
+
const aliceDeleteWrite2Data = await TestDataGenerator.generateRecordsDelete({
|
|
143
133
|
author: alice,
|
|
144
134
|
recordId: aliceWrite2Data.message.recordId
|
|
145
135
|
});
|
|
146
|
-
const aliceDeleteWrite2Reply =
|
|
136
|
+
const aliceDeleteWrite2Reply = await dwn.processMessage(alice.did, aliceDeleteWrite2Data.message);
|
|
147
137
|
expect(aliceDeleteWrite2Reply.status.code).toBe(202);
|
|
148
138
|
// verify that alice can no longer fetch the 2nd record
|
|
149
|
-
const aliceRead2Reply =
|
|
139
|
+
const aliceRead2Reply = await dwn.processMessage(alice.did, aliceRead1.message);
|
|
150
140
|
expect(aliceRead2Reply.status.code).toBe(404);
|
|
151
141
|
// verify that bob can still fetch record with the same data
|
|
152
|
-
const bobRead1 =
|
|
142
|
+
const bobRead1 = await RecordsRead.create({
|
|
153
143
|
filter: {
|
|
154
144
|
recordId: bobWriteData.message.recordId,
|
|
155
145
|
},
|
|
156
146
|
signer: Jws.createSigner(bob)
|
|
157
147
|
});
|
|
158
|
-
const bobRead1Reply =
|
|
148
|
+
const bobRead1Reply = await dwn.processMessage(bob.did, bobRead1.message);
|
|
159
149
|
expect(bobRead1Reply.status.code).toBe(200);
|
|
160
|
-
const bobDataFetched =
|
|
150
|
+
const bobDataFetched = await DataStream.toBytes(bobRead1Reply.entry.data);
|
|
161
151
|
expect(ArrayUtility.byteArraysEqual(bobDataFetched, data)).toBe(true);
|
|
162
|
-
})
|
|
163
|
-
it('should return 404 if deleting a non-existent record', () =>
|
|
164
|
-
const alice =
|
|
152
|
+
});
|
|
153
|
+
it('should return 404 if deleting a non-existent record', async () => {
|
|
154
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
165
155
|
// testing deleting a non-existent record
|
|
166
|
-
const recordsDelete =
|
|
156
|
+
const recordsDelete = await RecordsDelete.create({
|
|
167
157
|
recordId: 'nonExistentRecordId',
|
|
168
158
|
signer: Jws.createSigner(alice)
|
|
169
159
|
});
|
|
170
|
-
const deleteReply =
|
|
160
|
+
const deleteReply = await dwn.processMessage(alice.did, recordsDelete.message);
|
|
171
161
|
expect(deleteReply.status.code).toBe(404);
|
|
172
|
-
})
|
|
173
|
-
it('should be disallowed if there is a newer RecordsWrite already in the DWN ', () =>
|
|
174
|
-
|
|
175
|
-
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
162
|
+
});
|
|
163
|
+
it('should be disallowed if there is a newer RecordsWrite already in the DWN ', async () => {
|
|
164
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
176
165
|
// initial write
|
|
177
|
-
const initialWriteData =
|
|
178
|
-
const initialWriteReply =
|
|
166
|
+
const initialWriteData = await TestDataGenerator.generateRecordsWrite({ author: alice });
|
|
167
|
+
const initialWriteReply = await dwn.processMessage(alice.did, initialWriteData.message, { dataStream: initialWriteData.dataStream });
|
|
179
168
|
expect(initialWriteReply.status.code).toBe(202);
|
|
180
169
|
// generate subsequent write and delete with the delete having an earlier timestamp
|
|
181
170
|
// NOTE: creating RecordsDelete first ensures it has an earlier `messageTimestamp` time
|
|
182
|
-
const recordsDelete =
|
|
171
|
+
const recordsDelete = await RecordsDelete.create({
|
|
183
172
|
recordId: initialWriteData.message.recordId,
|
|
184
173
|
signer: Jws.createSigner(alice)
|
|
185
174
|
});
|
|
186
|
-
|
|
187
|
-
const subsequentWriteData =
|
|
175
|
+
await Time.minimalSleep();
|
|
176
|
+
const subsequentWriteData = await TestDataGenerator.generateFromRecordsWrite({
|
|
188
177
|
existingWrite: initialWriteData.recordsWrite,
|
|
189
178
|
author: alice
|
|
190
179
|
});
|
|
191
180
|
// subsequent write
|
|
192
|
-
const subsequentWriteReply =
|
|
181
|
+
const subsequentWriteReply = await dwn.processMessage(alice.did, subsequentWriteData.message, { dataStream: subsequentWriteData.dataStream });
|
|
193
182
|
expect(subsequentWriteReply.status.code).toBe(202);
|
|
194
183
|
// test that a delete with an earlier `messageTimestamp` results in a 409
|
|
195
|
-
const deleteReply =
|
|
184
|
+
const deleteReply = await dwn.processMessage(alice.did, recordsDelete.message);
|
|
196
185
|
expect(deleteReply.status.code).toBe(409);
|
|
197
186
|
// ensure data still exists
|
|
198
|
-
const queryData =
|
|
187
|
+
const queryData = await TestDataGenerator.generateRecordsQuery({
|
|
199
188
|
author: alice,
|
|
200
189
|
filter: { recordId: initialWriteData.message.recordId }
|
|
201
190
|
});
|
|
202
191
|
const expectedEncodedData = Encoder.bytesToBase64Url(subsequentWriteData.dataBytes);
|
|
203
|
-
const reply =
|
|
192
|
+
const reply = await dwn.processMessage(alice.did, queryData.message);
|
|
204
193
|
expect(reply.status.code).toBe(200);
|
|
205
|
-
expect(
|
|
194
|
+
expect(reply.entries?.length).toBe(1);
|
|
206
195
|
expect(reply.entries[0].encodedData).toBe(expectedEncodedData);
|
|
207
|
-
})
|
|
208
|
-
it('should be able to delete then rewrite the same data', () =>
|
|
209
|
-
|
|
210
|
-
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
196
|
+
});
|
|
197
|
+
it('should be able to delete then rewrite the same data', async () => {
|
|
198
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
211
199
|
const data = Encoder.stringToBytes('test');
|
|
212
200
|
const encodedData = Encoder.bytesToBase64Url(data);
|
|
213
201
|
// alice writes a record
|
|
214
|
-
const aliceWriteData =
|
|
202
|
+
const aliceWriteData = await TestDataGenerator.generateRecordsWrite({
|
|
215
203
|
author: alice,
|
|
216
204
|
data
|
|
217
205
|
});
|
|
218
|
-
const aliceWriteReply =
|
|
206
|
+
const aliceWriteReply = await dwn.processMessage(alice.did, aliceWriteData.message, { dataStream: aliceWriteData.dataStream });
|
|
219
207
|
expect(aliceWriteReply.status.code).toBe(202);
|
|
220
|
-
const aliceQueryWriteAfterAliceWriteData =
|
|
208
|
+
const aliceQueryWriteAfterAliceWriteData = await TestDataGenerator.generateRecordsQuery({
|
|
221
209
|
author: alice,
|
|
222
210
|
filter: { recordId: aliceWriteData.message.recordId }
|
|
223
211
|
});
|
|
224
|
-
const aliceQueryWriteAfterAliceWriteReply =
|
|
212
|
+
const aliceQueryWriteAfterAliceWriteReply = await dwn.processMessage(alice.did, aliceQueryWriteAfterAliceWriteData.message);
|
|
225
213
|
expect(aliceQueryWriteAfterAliceWriteReply.status.code).toBe(200);
|
|
226
|
-
expect(
|
|
214
|
+
expect(aliceQueryWriteAfterAliceWriteReply.entries?.length).toBe(1);
|
|
227
215
|
expect(aliceQueryWriteAfterAliceWriteReply.entries[0].encodedData).toBe(encodedData);
|
|
228
216
|
// alice deleting the record
|
|
229
|
-
const aliceDeleteWriteData =
|
|
217
|
+
const aliceDeleteWriteData = await TestDataGenerator.generateRecordsDelete({
|
|
230
218
|
author: alice,
|
|
231
219
|
recordId: aliceWriteData.message.recordId
|
|
232
220
|
});
|
|
233
|
-
const aliceDeleteWriteReply =
|
|
221
|
+
const aliceDeleteWriteReply = await dwn.processMessage(alice.did, aliceDeleteWriteData.message);
|
|
234
222
|
expect(aliceDeleteWriteReply.status.code).toBe(202);
|
|
235
|
-
const aliceQueryWriteAfterAliceDeleteData =
|
|
223
|
+
const aliceQueryWriteAfterAliceDeleteData = await TestDataGenerator.generateRecordsQuery({
|
|
236
224
|
author: alice,
|
|
237
225
|
filter: { recordId: aliceWriteData.message.recordId }
|
|
238
226
|
});
|
|
239
|
-
const aliceQueryWriteAfterAliceDeleteReply =
|
|
227
|
+
const aliceQueryWriteAfterAliceDeleteReply = await dwn.processMessage(alice.did, aliceQueryWriteAfterAliceDeleteData.message);
|
|
240
228
|
expect(aliceQueryWriteAfterAliceDeleteReply.status.code).toBe(200);
|
|
241
|
-
expect(
|
|
229
|
+
expect(aliceQueryWriteAfterAliceDeleteReply.entries?.length).toBe(0);
|
|
242
230
|
// alice writes a new record with the same data
|
|
243
|
-
const aliceRewriteData =
|
|
231
|
+
const aliceRewriteData = await TestDataGenerator.generateRecordsWrite({
|
|
244
232
|
author: alice,
|
|
245
233
|
data
|
|
246
234
|
});
|
|
247
|
-
const aliceRewriteReply =
|
|
235
|
+
const aliceRewriteReply = await dwn.processMessage(alice.did, aliceRewriteData.message, { dataStream: aliceRewriteData.dataStream });
|
|
248
236
|
expect(aliceRewriteReply.status.code).toBe(202);
|
|
249
|
-
const aliceQueryWriteAfterAliceRewriteData =
|
|
237
|
+
const aliceQueryWriteAfterAliceRewriteData = await TestDataGenerator.generateRecordsQuery({
|
|
250
238
|
author: alice,
|
|
251
239
|
filter: { recordId: aliceRewriteData.message.recordId }
|
|
252
240
|
});
|
|
253
|
-
const aliceQueryWriteAfterAliceRewriteReply =
|
|
241
|
+
const aliceQueryWriteAfterAliceRewriteReply = await dwn.processMessage(alice.did, aliceQueryWriteAfterAliceRewriteData.message);
|
|
254
242
|
expect(aliceQueryWriteAfterAliceRewriteReply.status.code).toBe(200);
|
|
255
|
-
expect(
|
|
243
|
+
expect(aliceQueryWriteAfterAliceRewriteReply.entries?.length).toBe(1);
|
|
256
244
|
expect(aliceQueryWriteAfterAliceRewriteReply.entries[0].encodedData).toBe(encodedData);
|
|
257
|
-
})
|
|
245
|
+
});
|
|
258
246
|
describe('protocol based deletes', () => {
|
|
259
|
-
it('should allow delete with allow-anyone rule', () =>
|
|
247
|
+
it('should allow delete with allow-anyone rule', async () => {
|
|
260
248
|
// scenario: Alice creates a record in her DWN. Bob (anyone) is able to delete the record.
|
|
261
249
|
const protocolDefinition = anyoneCollaborateProtocolDefinition;
|
|
262
|
-
const alice =
|
|
263
|
-
const bob =
|
|
264
|
-
const protocolsConfig =
|
|
250
|
+
const alice = await TestDataGenerator.generatePersona();
|
|
251
|
+
const bob = await TestDataGenerator.generatePersona();
|
|
252
|
+
const protocolsConfig = await TestDataGenerator.generateProtocolsConfigure({
|
|
265
253
|
author: alice,
|
|
266
254
|
protocolDefinition
|
|
267
255
|
});
|
|
268
256
|
// setting up a stub DID resolver
|
|
269
257
|
TestStubGenerator.stubDidResolver(didResolver, [alice, bob]);
|
|
270
|
-
const protocolsConfigureReply =
|
|
258
|
+
const protocolsConfigureReply = await dwn.processMessage(alice.did, protocolsConfig.message);
|
|
271
259
|
expect(protocolsConfigureReply.status.code).toBe(202);
|
|
272
260
|
// Alice writes a record
|
|
273
|
-
const recordsWrite =
|
|
261
|
+
const recordsWrite = await TestDataGenerator.generateRecordsWrite({
|
|
274
262
|
author: alice,
|
|
275
263
|
protocol: protocolDefinition.protocol,
|
|
276
264
|
protocolPath: 'doc',
|
|
277
265
|
});
|
|
278
|
-
const recordsWriteReply =
|
|
266
|
+
const recordsWriteReply = await dwn.processMessage(alice.did, recordsWrite.message, { dataStream: recordsWrite.dataStream });
|
|
279
267
|
expect(recordsWriteReply.status.code).toBe(202);
|
|
280
268
|
// Bob (anyone) is able to delete the record
|
|
281
|
-
const recordsDelete =
|
|
269
|
+
const recordsDelete = await TestDataGenerator.generateRecordsDelete({
|
|
282
270
|
author: bob,
|
|
283
271
|
recordId: recordsWrite.message.recordId,
|
|
284
272
|
});
|
|
285
|
-
const recordsDeleteReply =
|
|
273
|
+
const recordsDeleteReply = await dwn.processMessage(alice.did, recordsDelete.message);
|
|
286
274
|
expect(recordsDeleteReply.status.code).toBe(202);
|
|
287
|
-
})
|
|
275
|
+
});
|
|
288
276
|
describe('recipient rules', () => {
|
|
289
|
-
it('should allow delete with ancestor recipient rule', () =>
|
|
277
|
+
it('should allow delete with ancestor recipient rule', async () => {
|
|
290
278
|
// scenario: Alice creates a 'post' with Bob as recipient and a 'post/tag'. Bob is able to delete
|
|
291
279
|
// the 'chat/tag' because he was recipient of the 'chat'. Carol is not able to delete.
|
|
292
280
|
const protocolDefinition = recipientCanProtocolDefinition;
|
|
293
|
-
const alice =
|
|
294
|
-
const bob =
|
|
295
|
-
const carol =
|
|
296
|
-
const protocolsConfig =
|
|
281
|
+
const alice = await TestDataGenerator.generatePersona();
|
|
282
|
+
const bob = await TestDataGenerator.generatePersona();
|
|
283
|
+
const carol = await TestDataGenerator.generatePersona();
|
|
284
|
+
const protocolsConfig = await TestDataGenerator.generateProtocolsConfigure({
|
|
297
285
|
author: alice,
|
|
298
286
|
protocolDefinition
|
|
299
287
|
});
|
|
300
288
|
// setting up a stub DID resolver
|
|
301
289
|
TestStubGenerator.stubDidResolver(didResolver, [alice, bob, carol]);
|
|
302
|
-
const protocolsConfigureReply =
|
|
290
|
+
const protocolsConfigureReply = await dwn.processMessage(alice.did, protocolsConfig.message);
|
|
303
291
|
expect(protocolsConfigureReply.status.code).toBe(202);
|
|
304
292
|
// Alice writes a chat
|
|
305
|
-
const chatRecordsWrite =
|
|
293
|
+
const chatRecordsWrite = await TestDataGenerator.generateRecordsWrite({
|
|
306
294
|
author: alice,
|
|
307
295
|
recipient: bob.did,
|
|
308
296
|
protocol: protocolDefinition.protocol,
|
|
309
297
|
protocolPath: 'post',
|
|
310
298
|
});
|
|
311
|
-
const chatRecordsWriteReply =
|
|
299
|
+
const chatRecordsWriteReply = await dwn.processMessage(alice.did, chatRecordsWrite.message, { dataStream: chatRecordsWrite.dataStream });
|
|
312
300
|
expect(chatRecordsWriteReply.status.code).toBe(202);
|
|
313
301
|
// Alice writes a 'chat/tag'
|
|
314
|
-
const tagRecordsWrite =
|
|
302
|
+
const tagRecordsWrite = await TestDataGenerator.generateRecordsWrite({
|
|
315
303
|
author: alice,
|
|
316
304
|
protocol: protocolDefinition.protocol,
|
|
317
305
|
protocolPath: 'post/tag',
|
|
318
306
|
parentContextId: chatRecordsWrite.message.contextId,
|
|
319
307
|
});
|
|
320
|
-
const tagRecordsWriteReply =
|
|
308
|
+
const tagRecordsWriteReply = await dwn.processMessage(alice.did, tagRecordsWrite.message, { dataStream: tagRecordsWrite.dataStream });
|
|
321
309
|
expect(tagRecordsWriteReply.status.code).toBe(202);
|
|
322
310
|
// Carol is unable to delete the 'chat/tag'
|
|
323
|
-
const recordsDeleteCarol =
|
|
311
|
+
const recordsDeleteCarol = await TestDataGenerator.generateRecordsDelete({
|
|
324
312
|
author: carol,
|
|
325
313
|
recordId: tagRecordsWrite.message.recordId,
|
|
326
314
|
});
|
|
327
|
-
const recordsDeleteCarolReply =
|
|
315
|
+
const recordsDeleteCarolReply = await dwn.processMessage(alice.did, recordsDeleteCarol.message);
|
|
328
316
|
expect(recordsDeleteCarolReply.status.code).toBe(401);
|
|
329
317
|
expect(recordsDeleteCarolReply.status.detail).toContain(DwnErrorCode.ProtocolAuthorizationActionNotAllowed);
|
|
330
318
|
// Bob is able to delete the 'chat/tag'
|
|
331
|
-
const recordsDelete =
|
|
319
|
+
const recordsDelete = await TestDataGenerator.generateRecordsDelete({
|
|
332
320
|
author: bob,
|
|
333
321
|
recordId: tagRecordsWrite.message.recordId,
|
|
334
322
|
});
|
|
335
|
-
const recordsDeleteReply =
|
|
323
|
+
const recordsDeleteReply = await dwn.processMessage(alice.did, recordsDelete.message);
|
|
336
324
|
expect(recordsDeleteReply.status.code).toBe(202);
|
|
337
|
-
})
|
|
338
|
-
it('should allow delete with direct recipient rule', () =>
|
|
325
|
+
});
|
|
326
|
+
it('should allow delete with direct recipient rule', async () => {
|
|
339
327
|
// scenario: Alice creates a 'post' with Bob as recipient. Bob is able to delete
|
|
340
328
|
// the 'post' because he was recipient of it. Carol is not able to delete.
|
|
341
329
|
const protocolDefinition = recipientCanProtocolDefinition;
|
|
342
|
-
const alice =
|
|
343
|
-
const bob =
|
|
344
|
-
const carol =
|
|
345
|
-
const protocolsConfig =
|
|
330
|
+
const alice = await TestDataGenerator.generatePersona();
|
|
331
|
+
const bob = await TestDataGenerator.generatePersona();
|
|
332
|
+
const carol = await TestDataGenerator.generatePersona();
|
|
333
|
+
const protocolsConfig = await TestDataGenerator.generateProtocolsConfigure({
|
|
346
334
|
author: alice,
|
|
347
335
|
protocolDefinition
|
|
348
336
|
});
|
|
349
337
|
// setting up a stub DID resolver
|
|
350
338
|
TestStubGenerator.stubDidResolver(didResolver, [alice, bob, carol]);
|
|
351
|
-
const protocolsConfigureReply =
|
|
339
|
+
const protocolsConfigureReply = await dwn.processMessage(alice.did, protocolsConfig.message);
|
|
352
340
|
expect(protocolsConfigureReply.status.code).toBe(202);
|
|
353
341
|
// Alice creates a 'post' with Bob as recipient
|
|
354
|
-
const recordsWrite =
|
|
342
|
+
const recordsWrite = await TestDataGenerator.generateRecordsWrite({
|
|
355
343
|
author: alice,
|
|
356
344
|
recipient: bob.did,
|
|
357
345
|
protocol: protocolDefinition.protocol,
|
|
358
346
|
protocolPath: 'post',
|
|
359
347
|
});
|
|
360
|
-
const recordsWriteReply =
|
|
348
|
+
const recordsWriteReply = await dwn.processMessage(alice.did, recordsWrite.message, { dataStream: recordsWrite.dataStream });
|
|
361
349
|
expect(recordsWriteReply.status.code).toBe(202);
|
|
362
350
|
// Carol is unable to delete the 'post'
|
|
363
|
-
const carolRecordsDelete =
|
|
351
|
+
const carolRecordsDelete = await TestDataGenerator.generateRecordsDelete({
|
|
364
352
|
author: carol,
|
|
365
353
|
recordId: recordsWrite.message.recordId,
|
|
366
354
|
});
|
|
367
|
-
const carolRecordsDeleteReply =
|
|
355
|
+
const carolRecordsDeleteReply = await dwn.processMessage(alice.did, carolRecordsDelete.message);
|
|
368
356
|
expect(carolRecordsDeleteReply.status.code).toBe(401);
|
|
369
357
|
expect(carolRecordsDeleteReply.status.detail).toContain(DwnErrorCode.ProtocolAuthorizationActionNotAllowed);
|
|
370
358
|
// Bob is able to delete the post
|
|
371
|
-
const bobRecordsDelete =
|
|
359
|
+
const bobRecordsDelete = await TestDataGenerator.generateRecordsDelete({
|
|
372
360
|
author: bob,
|
|
373
361
|
recordId: recordsWrite.message.recordId,
|
|
374
362
|
});
|
|
375
|
-
const bobRecordsDeleteReply =
|
|
363
|
+
const bobRecordsDeleteReply = await dwn.processMessage(alice.did, bobRecordsDelete.message);
|
|
376
364
|
expect(bobRecordsDeleteReply.status.code).toBe(202);
|
|
377
|
-
})
|
|
365
|
+
});
|
|
378
366
|
});
|
|
379
367
|
describe('author action rules', () => {
|
|
380
|
-
it('allow author to delete with ancestor author rule', () =>
|
|
368
|
+
it('allow author to delete with ancestor author rule', async () => {
|
|
381
369
|
// scenario: Bob writes a 'post' and Alice writes a 'post/comment' to her DWN. Bob deletes the comment
|
|
382
370
|
// because author of post can delete. Carol is unable to delete the comment.
|
|
383
371
|
const protocolDefinition = authorCanProtocolDefinition;
|
|
384
|
-
const alice =
|
|
385
|
-
const bob =
|
|
386
|
-
const carol =
|
|
387
|
-
const protocolsConfig =
|
|
372
|
+
const alice = await TestDataGenerator.generatePersona();
|
|
373
|
+
const bob = await TestDataGenerator.generatePersona();
|
|
374
|
+
const carol = await TestDataGenerator.generatePersona();
|
|
375
|
+
const protocolsConfig = await TestDataGenerator.generateProtocolsConfigure({
|
|
388
376
|
author: alice,
|
|
389
377
|
protocolDefinition
|
|
390
378
|
});
|
|
391
379
|
// setting up a stub DID resolver
|
|
392
380
|
TestStubGenerator.stubDidResolver(didResolver, [alice, bob, carol]);
|
|
393
|
-
const protocolsConfigureReply =
|
|
381
|
+
const protocolsConfigureReply = await dwn.processMessage(alice.did, protocolsConfig.message);
|
|
394
382
|
expect(protocolsConfigureReply.status.code).toBe(202);
|
|
395
383
|
// Bob writes a post
|
|
396
|
-
const postRecordsWrite =
|
|
384
|
+
const postRecordsWrite = await TestDataGenerator.generateRecordsWrite({
|
|
397
385
|
author: bob,
|
|
398
386
|
protocol: protocolDefinition.protocol,
|
|
399
387
|
protocolPath: 'post',
|
|
400
388
|
});
|
|
401
|
-
const postRecordsWriteReply =
|
|
389
|
+
const postRecordsWriteReply = await dwn.processMessage(alice.did, postRecordsWrite.message, { dataStream: postRecordsWrite.dataStream });
|
|
402
390
|
expect(postRecordsWriteReply.status.code).toBe(202);
|
|
403
391
|
// Alice writes a 'post/comment'
|
|
404
|
-
const commentRecordsWrite =
|
|
392
|
+
const commentRecordsWrite = await TestDataGenerator.generateRecordsWrite({
|
|
405
393
|
author: alice,
|
|
406
394
|
protocol: protocolDefinition.protocol,
|
|
407
395
|
protocolPath: 'post/comment',
|
|
408
396
|
parentContextId: postRecordsWrite.message.contextId,
|
|
409
397
|
});
|
|
410
|
-
const commentRecordsWriteReply =
|
|
398
|
+
const commentRecordsWriteReply = await dwn.processMessage(alice.did, commentRecordsWrite.message, { dataStream: commentRecordsWrite.dataStream });
|
|
411
399
|
expect(commentRecordsWriteReply.status.code).toBe(202);
|
|
412
400
|
// Carol is unable to delete Alice's 'post/comment'
|
|
413
|
-
const recordsDeleteCarol =
|
|
401
|
+
const recordsDeleteCarol = await TestDataGenerator.generateRecordsDelete({
|
|
414
402
|
author: carol,
|
|
415
403
|
recordId: commentRecordsWrite.message.recordId,
|
|
416
404
|
});
|
|
417
|
-
const recordsDeleteCarolReply =
|
|
405
|
+
const recordsDeleteCarolReply = await dwn.processMessage(alice.did, recordsDeleteCarol.message);
|
|
418
406
|
expect(recordsDeleteCarolReply.status.code).toBe(401);
|
|
419
407
|
expect(recordsDeleteCarolReply.status.detail).toContain(DwnErrorCode.ProtocolAuthorizationActionNotAllowed);
|
|
420
408
|
// Bob is able to delete the Alice's 'post/comment'
|
|
421
|
-
const recordsDelete =
|
|
409
|
+
const recordsDelete = await TestDataGenerator.generateRecordsDelete({
|
|
422
410
|
author: bob,
|
|
423
411
|
recordId: commentRecordsWrite.message.recordId,
|
|
424
412
|
});
|
|
425
|
-
const recordsDeleteReply =
|
|
413
|
+
const recordsDeleteReply = await dwn.processMessage(alice.did, recordsDelete.message);
|
|
426
414
|
expect(recordsDeleteReply.status.code).toBe(202);
|
|
427
|
-
})
|
|
415
|
+
});
|
|
428
416
|
});
|
|
429
417
|
describe('role based deletes', () => {
|
|
430
|
-
it('should allow co-delete by invoking a context role', () =>
|
|
418
|
+
it('should allow co-delete by invoking a context role', async () => {
|
|
431
419
|
// scenario: Alice adds Bob as a 'thread/admin' role. She writes a 'thread/chat'.
|
|
432
420
|
// Bob invokes his admin role to delete the 'thread/chat'. Carol is unable to delete
|
|
433
421
|
// the 'thread/chat'.
|
|
434
|
-
const alice =
|
|
435
|
-
const bob =
|
|
436
|
-
const carol =
|
|
422
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
423
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
424
|
+
const carol = await TestDataGenerator.generateDidKeyPersona();
|
|
437
425
|
const protocolDefinition = threadRoleProtocolDefinition;
|
|
438
|
-
const protocolsConfig =
|
|
426
|
+
const protocolsConfig = await TestDataGenerator.generateProtocolsConfigure({
|
|
439
427
|
author: alice,
|
|
440
428
|
protocolDefinition
|
|
441
429
|
});
|
|
442
|
-
const protocolsConfigureReply =
|
|
430
|
+
const protocolsConfigureReply = await dwn.processMessage(alice.did, protocolsConfig.message);
|
|
443
431
|
expect(protocolsConfigureReply.status.code).toBe(202);
|
|
444
432
|
// Alice creates a thread
|
|
445
|
-
const threadRecord =
|
|
433
|
+
const threadRecord = await TestDataGenerator.generateRecordsWrite({
|
|
446
434
|
author: alice,
|
|
447
435
|
recipient: bob.did,
|
|
448
436
|
protocol: protocolDefinition.protocol,
|
|
449
437
|
protocolPath: 'thread'
|
|
450
438
|
});
|
|
451
|
-
const threadRecordReply =
|
|
439
|
+
const threadRecordReply = await dwn.processMessage(alice.did, threadRecord.message, { dataStream: threadRecord.dataStream });
|
|
452
440
|
expect(threadRecordReply.status.code).toBe(202);
|
|
453
441
|
// Alice adds Bob as a 'thread/admin' in that thread
|
|
454
|
-
const participantRecord =
|
|
442
|
+
const participantRecord = await TestDataGenerator.generateRecordsWrite({
|
|
455
443
|
author: alice,
|
|
456
444
|
recipient: bob.did,
|
|
457
445
|
protocol: protocolDefinition.protocol,
|
|
458
446
|
protocolPath: 'thread/admin',
|
|
459
447
|
parentContextId: threadRecord.message.contextId,
|
|
460
448
|
});
|
|
461
|
-
const participantRecordReply =
|
|
449
|
+
const participantRecordReply = await dwn.processMessage(alice.did, participantRecord.message, { dataStream: participantRecord.dataStream });
|
|
462
450
|
expect(participantRecordReply.status.code).toBe(202);
|
|
463
451
|
// Alice writes a chat message in that thread
|
|
464
|
-
const chatRecord =
|
|
452
|
+
const chatRecord = await TestDataGenerator.generateRecordsWrite({
|
|
465
453
|
author: alice,
|
|
466
454
|
recipient: alice.did,
|
|
467
455
|
protocol: protocolDefinition.protocol,
|
|
468
456
|
protocolPath: 'thread/chat',
|
|
469
457
|
parentContextId: threadRecord.message.contextId,
|
|
470
458
|
});
|
|
471
|
-
const chatRecordReply =
|
|
459
|
+
const chatRecordReply = await dwn.processMessage(alice.did, chatRecord.message, { dataStream: chatRecord.dataStream });
|
|
472
460
|
expect(chatRecordReply.status.code).toBe(202);
|
|
473
461
|
// Verifies that Carol cannot delete without appropriate role
|
|
474
|
-
const chatDeleteCarol =
|
|
462
|
+
const chatDeleteCarol = await TestDataGenerator.generateRecordsDelete({
|
|
475
463
|
author: carol,
|
|
476
464
|
recordId: chatRecord.message.recordId,
|
|
477
465
|
});
|
|
478
|
-
const chatDeleteReplyCarol =
|
|
466
|
+
const chatDeleteReplyCarol = await dwn.processMessage(alice.did, chatDeleteCarol.message);
|
|
479
467
|
expect(chatDeleteReplyCarol.status.code).toBe(401);
|
|
480
468
|
expect(chatDeleteReplyCarol.status.detail).toContain(DwnErrorCode.ProtocolAuthorizationActionNotAllowed);
|
|
481
469
|
// Bob invokes the role to delete the chat message
|
|
482
|
-
const chatDelete =
|
|
470
|
+
const chatDelete = await TestDataGenerator.generateRecordsDelete({
|
|
483
471
|
author: bob,
|
|
484
472
|
recordId: chatRecord.message.recordId,
|
|
485
473
|
protocolRole: 'thread/admin',
|
|
486
474
|
});
|
|
487
|
-
const chatDeleteReply =
|
|
475
|
+
const chatDeleteReply = await dwn.processMessage(alice.did, chatDelete.message);
|
|
488
476
|
expect(chatDeleteReply.status.code).toBe(202);
|
|
489
|
-
})
|
|
490
|
-
it('should allow co-delete invoking a root-level role', () =>
|
|
477
|
+
});
|
|
478
|
+
it('should allow co-delete invoking a root-level role', async () => {
|
|
491
479
|
// scenario: Alice adds Bob as a root-level 'admin' role. She writes a 'chat'.
|
|
492
480
|
// Bob invokes his admin role to delete the 'chat'.
|
|
493
|
-
const alice =
|
|
494
|
-
const bob =
|
|
495
|
-
const carol =
|
|
481
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
482
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
483
|
+
const carol = await TestDataGenerator.generateDidKeyPersona();
|
|
496
484
|
const protocolDefinition = friendRoleProtocolDefinition;
|
|
497
|
-
const protocolsConfig =
|
|
485
|
+
const protocolsConfig = await TestDataGenerator.generateProtocolsConfigure({
|
|
498
486
|
author: alice,
|
|
499
487
|
protocolDefinition
|
|
500
488
|
});
|
|
501
|
-
const protocolsConfigureReply =
|
|
489
|
+
const protocolsConfigureReply = await dwn.processMessage(alice.did, protocolsConfig.message);
|
|
502
490
|
expect(protocolsConfigureReply.status.code).toBe(202);
|
|
503
491
|
// Alice adds Bob as a 'thread/admin' in that thread
|
|
504
|
-
const participantRecord =
|
|
492
|
+
const participantRecord = await TestDataGenerator.generateRecordsWrite({
|
|
505
493
|
author: alice,
|
|
506
494
|
recipient: bob.did,
|
|
507
495
|
protocol: protocolDefinition.protocol,
|
|
508
496
|
protocolPath: 'admin',
|
|
509
497
|
});
|
|
510
|
-
const participantRecordReply =
|
|
498
|
+
const participantRecordReply = await dwn.processMessage(alice.did, participantRecord.message, { dataStream: participantRecord.dataStream });
|
|
511
499
|
expect(participantRecordReply.status.code).toBe(202);
|
|
512
500
|
// Alice writes a chat message in that thread
|
|
513
|
-
const chatRecord =
|
|
501
|
+
const chatRecord = await TestDataGenerator.generateRecordsWrite({
|
|
514
502
|
author: alice,
|
|
515
503
|
recipient: alice.did,
|
|
516
504
|
protocol: protocolDefinition.protocol,
|
|
517
505
|
protocolPath: 'chat',
|
|
518
506
|
});
|
|
519
|
-
const chatRecordReply =
|
|
507
|
+
const chatRecordReply = await dwn.processMessage(alice.did, chatRecord.message, { dataStream: chatRecord.dataStream });
|
|
520
508
|
expect(chatRecordReply.status.code).toBe(202);
|
|
521
509
|
// Carol is unable to delete the chat message
|
|
522
|
-
const chatDeleteCarol =
|
|
510
|
+
const chatDeleteCarol = await TestDataGenerator.generateRecordsDelete({
|
|
523
511
|
author: carol,
|
|
524
512
|
recordId: chatRecord.message.recordId,
|
|
525
513
|
});
|
|
526
|
-
const chatDeleteCarolReply =
|
|
514
|
+
const chatDeleteCarolReply = await dwn.processMessage(alice.did, chatDeleteCarol.message);
|
|
527
515
|
expect(chatDeleteCarolReply.status.code).toBe(401);
|
|
528
516
|
expect(chatDeleteCarolReply.status.detail).toContain(DwnErrorCode.ProtocolAuthorizationActionNotAllowed);
|
|
529
517
|
// Bob invokes the role to delete the chat message
|
|
530
|
-
const chatDelete =
|
|
518
|
+
const chatDelete = await TestDataGenerator.generateRecordsDelete({
|
|
531
519
|
author: bob,
|
|
532
520
|
recordId: chatRecord.message.recordId,
|
|
533
521
|
protocolRole: 'admin',
|
|
534
522
|
});
|
|
535
|
-
const chatDeleteReply =
|
|
523
|
+
const chatDeleteReply = await dwn.processMessage(alice.did, chatDelete.message);
|
|
536
524
|
expect(chatDeleteReply.status.code).toBe(202);
|
|
537
|
-
})
|
|
525
|
+
});
|
|
538
526
|
});
|
|
539
527
|
});
|
|
540
|
-
it('should return 401 if message is not authorized', () =>
|
|
528
|
+
it('should return 401 if message is not authorized', async () => {
|
|
541
529
|
// scenario: Alice creates a record and Bob is unable to delete it.
|
|
542
|
-
const alice =
|
|
543
|
-
const bob =
|
|
544
|
-
const recordsWrite =
|
|
530
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
531
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
532
|
+
const recordsWrite = await TestDataGenerator.generateRecordsWrite({
|
|
545
533
|
author: alice,
|
|
546
534
|
});
|
|
547
|
-
const recordsWriteReply =
|
|
535
|
+
const recordsWriteReply = await dwn.processMessage(alice.did, recordsWrite.message, { dataStream: recordsWrite.dataStream });
|
|
548
536
|
expect(recordsWriteReply.status.code).toBe(202);
|
|
549
|
-
const recordsDelete =
|
|
537
|
+
const recordsDelete = await TestDataGenerator.generateRecordsDelete({
|
|
550
538
|
author: bob,
|
|
551
539
|
recordId: recordsWrite.message.recordId,
|
|
552
540
|
});
|
|
553
|
-
const recordsDeleteReply =
|
|
541
|
+
const recordsDeleteReply = await dwn.processMessage(alice.did, recordsDelete.message);
|
|
554
542
|
expect(recordsDeleteReply.status.code).toBe(401);
|
|
555
543
|
expect(recordsDeleteReply.status.detail).toContain(DwnErrorCode.RecordsDeleteAuthorizationFailed);
|
|
556
|
-
})
|
|
544
|
+
});
|
|
557
545
|
describe('grant based deletes', () => {
|
|
558
|
-
it('should allow delete with a matching protocol grant scope', () =>
|
|
546
|
+
it('should allow delete with a matching protocol grant scope', async () => {
|
|
559
547
|
// scenario: Alice writes a protocol record, grants Bob delete permission, Bob deletes it.
|
|
560
|
-
const alice =
|
|
561
|
-
const bob =
|
|
548
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
549
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
562
550
|
const protocolDefinition = {
|
|
563
551
|
protocol: 'http://grant-delete-test.xyz',
|
|
564
552
|
published: false,
|
|
@@ -566,22 +554,22 @@ export function testRecordsDeleteHandler() {
|
|
|
566
554
|
structure: { foo: {} }
|
|
567
555
|
};
|
|
568
556
|
// Alice installs the protocol
|
|
569
|
-
const protocolsConfig =
|
|
557
|
+
const protocolsConfig = await TestDataGenerator.generateProtocolsConfigure({
|
|
570
558
|
author: alice,
|
|
571
559
|
protocolDefinition
|
|
572
560
|
});
|
|
573
|
-
const protocolsConfigureReply =
|
|
561
|
+
const protocolsConfigureReply = await dwn.processMessage(alice.did, protocolsConfig.message);
|
|
574
562
|
expect(protocolsConfigureReply.status.code).toBe(202);
|
|
575
563
|
// Alice writes a record
|
|
576
|
-
const { recordsWrite, dataStream } =
|
|
564
|
+
const { recordsWrite, dataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
577
565
|
author: alice,
|
|
578
566
|
protocol: protocolDefinition.protocol,
|
|
579
567
|
protocolPath: 'foo',
|
|
580
568
|
});
|
|
581
|
-
const writeReply =
|
|
569
|
+
const writeReply = await dwn.processMessage(alice.did, recordsWrite.message, { dataStream });
|
|
582
570
|
expect(writeReply.status.code).toBe(202);
|
|
583
571
|
// Alice grants Bob delete permission scoped to the protocol
|
|
584
|
-
const permissionGrant =
|
|
572
|
+
const permissionGrant = await PermissionsProtocol.createGrant({
|
|
585
573
|
signer: Jws.createSigner(alice),
|
|
586
574
|
grantedTo: bob.did,
|
|
587
575
|
dateExpires: Time.createOffsetTimestamp({ seconds: 60 * 60 * 24 }),
|
|
@@ -592,22 +580,22 @@ export function testRecordsDeleteHandler() {
|
|
|
592
580
|
}
|
|
593
581
|
});
|
|
594
582
|
const grantDataStream = DataStream.fromBytes(permissionGrant.permissionGrantBytes);
|
|
595
|
-
const grantWriteReply =
|
|
583
|
+
const grantWriteReply = await dwn.processMessage(alice.did, permissionGrant.recordsWrite.message, { dataStream: grantDataStream });
|
|
596
584
|
expect(grantWriteReply.status.code).toBe(202);
|
|
597
585
|
// Bob deletes the record using the grant
|
|
598
|
-
const recordsDelete =
|
|
586
|
+
const recordsDelete = await RecordsDelete.create({
|
|
599
587
|
recordId: recordsWrite.message.recordId,
|
|
600
588
|
signer: Jws.createSigner(bob),
|
|
601
589
|
permissionGrantId: permissionGrant.recordsWrite.message.recordId,
|
|
602
590
|
});
|
|
603
|
-
const deleteReply =
|
|
591
|
+
const deleteReply = await dwn.processMessage(alice.did, recordsDelete.message);
|
|
604
592
|
expect(deleteReply.status.code).toBe(202);
|
|
605
|
-
})
|
|
606
|
-
it('should reject delete when grant has mismatching protocol scope', () =>
|
|
593
|
+
});
|
|
594
|
+
it('should reject delete when grant has mismatching protocol scope', async () => {
|
|
607
595
|
// scenario: Alice grants Bob delete permission for protocol A,
|
|
608
596
|
// Bob tries to delete a record in protocol B.
|
|
609
|
-
const alice =
|
|
610
|
-
const bob =
|
|
597
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
598
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
611
599
|
const protocolA = {
|
|
612
600
|
protocol: 'http://protocol-a.xyz',
|
|
613
601
|
published: false,
|
|
@@ -621,20 +609,20 @@ export function testRecordsDeleteHandler() {
|
|
|
621
609
|
structure: { foo: {} }
|
|
622
610
|
};
|
|
623
611
|
// Alice installs both protocols
|
|
624
|
-
const configA =
|
|
625
|
-
expect((
|
|
626
|
-
const configB =
|
|
627
|
-
expect((
|
|
612
|
+
const configA = await TestDataGenerator.generateProtocolsConfigure({ author: alice, protocolDefinition: protocolA });
|
|
613
|
+
expect((await dwn.processMessage(alice.did, configA.message)).status.code).toBe(202);
|
|
614
|
+
const configB = await TestDataGenerator.generateProtocolsConfigure({ author: alice, protocolDefinition: protocolB });
|
|
615
|
+
expect((await dwn.processMessage(alice.did, configB.message)).status.code).toBe(202);
|
|
628
616
|
// Alice writes a record in protocol B
|
|
629
|
-
const { recordsWrite, dataStream } =
|
|
617
|
+
const { recordsWrite, dataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
630
618
|
author: alice,
|
|
631
619
|
protocol: protocolB.protocol,
|
|
632
620
|
protocolPath: 'foo',
|
|
633
621
|
});
|
|
634
|
-
const writeReply =
|
|
622
|
+
const writeReply = await dwn.processMessage(alice.did, recordsWrite.message, { dataStream });
|
|
635
623
|
expect(writeReply.status.code).toBe(202);
|
|
636
624
|
// Alice grants Bob delete permission scoped to protocol A (not B)
|
|
637
|
-
const permissionGrant =
|
|
625
|
+
const permissionGrant = await PermissionsProtocol.createGrant({
|
|
638
626
|
signer: Jws.createSigner(alice),
|
|
639
627
|
grantedTo: bob.did,
|
|
640
628
|
dateExpires: Time.createOffsetTimestamp({ seconds: 60 * 60 * 24 }),
|
|
@@ -645,123 +633,123 @@ export function testRecordsDeleteHandler() {
|
|
|
645
633
|
}
|
|
646
634
|
});
|
|
647
635
|
const grantDataStream = DataStream.fromBytes(permissionGrant.permissionGrantBytes);
|
|
648
|
-
expect((
|
|
636
|
+
expect((await dwn.processMessage(alice.did, permissionGrant.recordsWrite.message, { dataStream: grantDataStream })).status.code).toBe(202);
|
|
649
637
|
// Bob tries to delete the protocol B record with the protocol A grant — should fail
|
|
650
|
-
const recordsDelete =
|
|
638
|
+
const recordsDelete = await RecordsDelete.create({
|
|
651
639
|
recordId: recordsWrite.message.recordId,
|
|
652
640
|
signer: Jws.createSigner(bob),
|
|
653
641
|
permissionGrantId: permissionGrant.recordsWrite.message.recordId,
|
|
654
642
|
});
|
|
655
|
-
const deleteReply =
|
|
643
|
+
const deleteReply = await dwn.processMessage(alice.did, recordsDelete.message);
|
|
656
644
|
expect(deleteReply.status.code).toBe(401);
|
|
657
645
|
expect(deleteReply.status.detail).toContain(DwnErrorCode.RecordsGrantAuthorizationDeleteProtocolScopeMismatch);
|
|
658
|
-
})
|
|
659
|
-
it('should reject delete without a grant when non-owner tries to delete a non-protocol record', () =>
|
|
646
|
+
});
|
|
647
|
+
it('should reject delete without a grant when non-owner tries to delete a non-protocol record', async () => {
|
|
660
648
|
// scenario: Alice writes a non-protocol record, Bob tries to delete it without any grant.
|
|
661
649
|
// This test verifies the fallback error path is unchanged.
|
|
662
|
-
const alice =
|
|
663
|
-
const bob =
|
|
664
|
-
const { recordsWrite, dataStream } =
|
|
665
|
-
expect((
|
|
666
|
-
const recordsDelete =
|
|
650
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
651
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
652
|
+
const { recordsWrite, dataStream } = await TestDataGenerator.generateRecordsWrite({ author: alice });
|
|
653
|
+
expect((await dwn.processMessage(alice.did, recordsWrite.message, { dataStream })).status.code).toBe(202);
|
|
654
|
+
const recordsDelete = await RecordsDelete.create({
|
|
667
655
|
recordId: recordsWrite.message.recordId,
|
|
668
656
|
signer: Jws.createSigner(bob),
|
|
669
657
|
});
|
|
670
|
-
const deleteReply =
|
|
658
|
+
const deleteReply = await dwn.processMessage(alice.did, recordsDelete.message);
|
|
671
659
|
expect(deleteReply.status.code).toBe(401);
|
|
672
660
|
expect(deleteReply.status.detail).toContain(DwnErrorCode.RecordsDeleteAuthorizationFailed);
|
|
673
|
-
})
|
|
661
|
+
});
|
|
674
662
|
});
|
|
675
|
-
it('should index additional properties from the RecordsWrite being deleted', () =>
|
|
676
|
-
const alice =
|
|
663
|
+
it('should index additional properties from the RecordsWrite being deleted', async () => {
|
|
664
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
677
665
|
// initial write
|
|
678
|
-
const initialWriteData =
|
|
679
|
-
const initialWriteReply =
|
|
666
|
+
const initialWriteData = await TestDataGenerator.generateRecordsWrite({ author: alice, schema: 'testSchema' });
|
|
667
|
+
const initialWriteReply = await dwn.processMessage(alice.did, initialWriteData.message, { dataStream: initialWriteData.dataStream });
|
|
680
668
|
expect(initialWriteReply.status.code).toBe(202);
|
|
681
669
|
// generate subsequent write and delete with the delete having an earlier timestamp
|
|
682
670
|
// NOTE: creating RecordsDelete first ensures it has an earlier `messageTimestamp` time
|
|
683
|
-
const recordsDelete =
|
|
671
|
+
const recordsDelete = await RecordsDelete.create({
|
|
684
672
|
recordId: initialWriteData.message.recordId,
|
|
685
673
|
signer: Jws.createSigner(alice)
|
|
686
674
|
});
|
|
687
|
-
const deleteMessageCid =
|
|
688
|
-
const deleteReply =
|
|
675
|
+
const deleteMessageCid = await Message.getCid(recordsDelete.message);
|
|
676
|
+
const deleteReply = await dwn.processMessage(alice.did, recordsDelete.message);
|
|
689
677
|
expect(deleteReply.status.code).toBe(202);
|
|
690
678
|
// message store
|
|
691
|
-
const { messages } =
|
|
679
|
+
const { messages } = await messageStore.query(alice.did, [{ schema: normalizeSchemaUrl('testSchema'), method: DwnMethodName.Delete }]);
|
|
692
680
|
expect(messages.length).toBe(1);
|
|
693
|
-
expect(
|
|
681
|
+
expect(await Message.getCid(messages[0])).toBe(deleteMessageCid);
|
|
694
682
|
// state index
|
|
695
|
-
const events =
|
|
683
|
+
const events = await stateIndex.getLeaves(alice.did, []);
|
|
696
684
|
expect(events).toContain(deleteMessageCid);
|
|
697
|
-
})
|
|
685
|
+
});
|
|
698
686
|
describe('state index', () => {
|
|
699
|
-
it('should include RecordsDelete event and keep initial RecordsWrite event', () =>
|
|
700
|
-
const alice =
|
|
701
|
-
const { message, dataStream } =
|
|
702
|
-
const writeReply =
|
|
687
|
+
it('should include RecordsDelete event and keep initial RecordsWrite event', async () => {
|
|
688
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
689
|
+
const { message, dataStream } = await TestDataGenerator.generateRecordsWrite({ author: alice });
|
|
690
|
+
const writeReply = await dwn.processMessage(alice.did, message, { dataStream });
|
|
703
691
|
expect(writeReply.status.code).toBe(202);
|
|
704
|
-
const recordsDelete =
|
|
692
|
+
const recordsDelete = await RecordsDelete.create({
|
|
705
693
|
recordId: message.recordId,
|
|
706
694
|
signer: Jws.createSigner(alice)
|
|
707
695
|
});
|
|
708
|
-
const deleteReply =
|
|
696
|
+
const deleteReply = await dwn.processMessage(alice.did, recordsDelete.message);
|
|
709
697
|
expect(deleteReply.status.code).toBe(202);
|
|
710
|
-
const events =
|
|
698
|
+
const events = await stateIndex.getLeaves(alice.did, []);
|
|
711
699
|
expect(events.length).toBe(2);
|
|
712
|
-
const writeMessageCid =
|
|
713
|
-
const deleteMessageCid =
|
|
700
|
+
const writeMessageCid = await Message.getCid(message);
|
|
701
|
+
const deleteMessageCid = await Message.getCid(recordsDelete.message);
|
|
714
702
|
const expectedMessageCids = new Set([writeMessageCid, deleteMessageCid]);
|
|
715
703
|
for (const messageCid of events) {
|
|
716
704
|
expectedMessageCids.delete(messageCid);
|
|
717
705
|
}
|
|
718
706
|
expect(expectedMessageCids.size).toBe(0);
|
|
719
|
-
})
|
|
720
|
-
it('should only keep first write and delete when subsequent writes happen', () =>
|
|
721
|
-
const { message, author, dataStream, recordsWrite } =
|
|
707
|
+
});
|
|
708
|
+
it('should only keep first write and delete when subsequent writes happen', async () => {
|
|
709
|
+
const { message, author, dataStream, recordsWrite } = await TestDataGenerator.generateRecordsWrite();
|
|
722
710
|
TestStubGenerator.stubDidResolver(didResolver, [author]);
|
|
723
|
-
const reply =
|
|
711
|
+
const reply = await dwn.processMessage(author.did, message, { dataStream });
|
|
724
712
|
expect(reply.status.code).toBe(202);
|
|
725
|
-
const newWrite =
|
|
713
|
+
const newWrite = await RecordsWrite.createFrom({
|
|
726
714
|
recordsWriteMessage: recordsWrite.message,
|
|
727
715
|
published: true,
|
|
728
716
|
signer: Jws.createSigner(author)
|
|
729
717
|
});
|
|
730
|
-
const newWriteReply =
|
|
718
|
+
const newWriteReply = await dwn.processMessage(author.did, newWrite.message);
|
|
731
719
|
expect(newWriteReply.status.code).toBe(202);
|
|
732
|
-
const recordsDelete =
|
|
720
|
+
const recordsDelete = await RecordsDelete.create({
|
|
733
721
|
recordId: message.recordId,
|
|
734
722
|
signer: Jws.createSigner(author)
|
|
735
723
|
});
|
|
736
|
-
const deleteReply =
|
|
724
|
+
const deleteReply = await dwn.processMessage(author.did, recordsDelete.message);
|
|
737
725
|
expect(deleteReply.status.code).toBe(202);
|
|
738
|
-
const events =
|
|
726
|
+
const events = await stateIndex.getLeaves(author.did, []);
|
|
739
727
|
expect(events.length).toBe(2);
|
|
740
|
-
const deletedMessageCid =
|
|
728
|
+
const deletedMessageCid = await Message.getCid(newWrite.message);
|
|
741
729
|
for (const messageCid of events) {
|
|
742
730
|
if (messageCid === deletedMessageCid) {
|
|
743
731
|
throw new Error(`${messageCid} should not exist`);
|
|
744
732
|
}
|
|
745
733
|
}
|
|
746
|
-
})
|
|
734
|
+
});
|
|
747
735
|
});
|
|
748
736
|
});
|
|
749
|
-
it('should return 401 if signature check fails', () =>
|
|
750
|
-
const { author, message } =
|
|
737
|
+
it('should return 401 if signature check fails', async () => {
|
|
738
|
+
const { author, message } = await TestDataGenerator.generateRecordsDelete();
|
|
751
739
|
const tenant = author.did;
|
|
752
740
|
// setting up a stub did resolver & message store
|
|
753
741
|
// intentionally not supplying the public key so a different public key is generated to simulate invalid signature
|
|
754
|
-
const mismatchingPersona =
|
|
742
|
+
const mismatchingPersona = await TestDataGenerator.generatePersona({ did: author.did, keyId: author.keyId });
|
|
755
743
|
const didResolver = TestStubGenerator.createDidResolverStub(mismatchingPersona);
|
|
756
744
|
// setting up a stub method resolver & message store
|
|
757
745
|
const messageStoreStub = sinon.createStubInstance(MessageStoreLevel);
|
|
758
746
|
const resumableTaskManagerStub = sinon.createStubInstance(ResumableTaskManager);
|
|
759
747
|
const recordsDeleteHandler = new RecordsDeleteHandler(didResolver, messageStoreStub, resumableTaskManagerStub);
|
|
760
|
-
const reply =
|
|
748
|
+
const reply = await recordsDeleteHandler.handle({ tenant, message });
|
|
761
749
|
expect(reply.status.code).toBe(401);
|
|
762
|
-
})
|
|
763
|
-
it('should return 400 if fail parsing the message', () =>
|
|
764
|
-
const { author, message } =
|
|
750
|
+
});
|
|
751
|
+
it('should return 400 if fail parsing the message', async () => {
|
|
752
|
+
const { author, message } = await TestDataGenerator.generateRecordsDelete();
|
|
765
753
|
const tenant = author.did;
|
|
766
754
|
// setting up a stub method resolver & message store
|
|
767
755
|
const messageStoreStub = sinon.createStubInstance(MessageStoreLevel);
|
|
@@ -769,9 +757,9 @@ export function testRecordsDeleteHandler() {
|
|
|
769
757
|
const recordsDeleteHandler = new RecordsDeleteHandler(didResolver, messageStoreStub, resumableTaskManagerStub);
|
|
770
758
|
// stub the `parse()` function to throw an error
|
|
771
759
|
sinon.stub(RecordsDelete, 'parse').throws('anyError');
|
|
772
|
-
const reply =
|
|
760
|
+
const reply = await recordsDeleteHandler.handle({ tenant, message });
|
|
773
761
|
expect(reply.status.code).toBe(400);
|
|
774
|
-
})
|
|
762
|
+
});
|
|
775
763
|
});
|
|
776
764
|
}
|
|
777
765
|
//# sourceMappingURL=records-delete.spec.js.map
|