@enbox/dwn-sdk-js 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.mjs +8 -8
- package/dist/browser.mjs.map +4 -4
- package/dist/esm/generated/precompiled-validators.js +762 -911
- package/dist/esm/generated/precompiled-validators.js.map +1 -1
- package/dist/esm/src/core/abstract-message.js +4 -0
- package/dist/esm/src/core/abstract-message.js.map +1 -1
- package/dist/esm/src/core/auth.js +22 -33
- package/dist/esm/src/core/auth.js.map +1 -1
- package/dist/esm/src/core/constants.js +11 -0
- package/dist/esm/src/core/constants.js.map +1 -0
- package/dist/esm/src/core/core-protocol.js +44 -0
- package/dist/esm/src/core/core-protocol.js.map +1 -0
- package/dist/esm/src/core/dwn-constant.js +7 -7
- package/dist/esm/src/core/dwn-constant.js.map +1 -1
- package/dist/esm/src/core/dwn-error.js +10 -12
- package/dist/esm/src/core/dwn-error.js.map +1 -1
- package/dist/esm/src/core/grant-authorization.js +50 -52
- package/dist/esm/src/core/grant-authorization.js.map +1 -1
- package/dist/esm/src/core/message.js +85 -116
- package/dist/esm/src/core/message.js.map +1 -1
- package/dist/esm/src/core/messages-grant-authorization.js +63 -78
- package/dist/esm/src/core/messages-grant-authorization.js.map +1 -1
- package/dist/esm/src/core/protocol-authorization-action.js +266 -0
- package/dist/esm/src/core/protocol-authorization-action.js.map +1 -0
- package/dist/esm/src/core/protocol-authorization-validation.js +321 -0
- package/dist/esm/src/core/protocol-authorization-validation.js.map +1 -0
- package/dist/esm/src/core/protocol-authorization.js +144 -741
- package/dist/esm/src/core/protocol-authorization.js.map +1 -1
- package/dist/esm/src/core/protocols-grant-authorization.js +24 -38
- package/dist/esm/src/core/protocols-grant-authorization.js.map +1 -1
- package/dist/esm/src/core/record-chain.js +64 -0
- package/dist/esm/src/core/record-chain.js.map +1 -0
- package/dist/esm/src/core/records-grant-authorization.js +53 -72
- package/dist/esm/src/core/records-grant-authorization.js.map +1 -1
- package/dist/esm/src/core/resumable-task-manager.js +50 -65
- package/dist/esm/src/core/resumable-task-manager.js.map +1 -1
- package/dist/esm/src/core/tenant-gate.js +2 -13
- package/dist/esm/src/core/tenant-gate.js.map +1 -1
- package/dist/esm/src/dwn.js +108 -101
- package/dist/esm/src/dwn.js.map +1 -1
- package/dist/esm/src/event-stream/event-emitter-event-log.js +204 -0
- package/dist/esm/src/event-stream/event-emitter-event-log.js.map +1 -0
- package/dist/esm/src/handlers/messages-read.js +67 -81
- package/dist/esm/src/handlers/messages-read.js.map +1 -1
- package/dist/esm/src/handlers/messages-subscribe.js +51 -63
- package/dist/esm/src/handlers/messages-subscribe.js.map +1 -1
- package/dist/esm/src/handlers/messages-sync.js +75 -89
- package/dist/esm/src/handlers/messages-sync.js.map +1 -1
- package/dist/esm/src/handlers/protocols-configure.js +153 -163
- package/dist/esm/src/handlers/protocols-configure.js.map +1 -1
- package/dist/esm/src/handlers/protocols-query.js +52 -55
- package/dist/esm/src/handlers/protocols-query.js.map +1 -1
- package/dist/esm/src/handlers/records-count.js +97 -85
- package/dist/esm/src/handlers/records-count.js.map +1 -1
- package/dist/esm/src/handlers/records-delete.js +75 -93
- package/dist/esm/src/handlers/records-delete.js.map +1 -1
- package/dist/esm/src/handlers/records-query.js +116 -105
- package/dist/esm/src/handlers/records-query.js.map +1 -1
- package/dist/esm/src/handlers/records-read.js +130 -132
- package/dist/esm/src/handlers/records-read.js.map +1 -1
- package/dist/esm/src/handlers/records-subscribe.js +164 -104
- package/dist/esm/src/handlers/records-subscribe.js.map +1 -1
- package/dist/esm/src/handlers/records-write.js +213 -280
- package/dist/esm/src/handlers/records-write.js.map +1 -1
- package/dist/esm/src/index.js +5 -2
- package/dist/esm/src/index.js.map +1 -1
- package/dist/esm/src/interfaces/messages-read.js +24 -32
- package/dist/esm/src/interfaces/messages-read.js.map +1 -1
- package/dist/esm/src/interfaces/messages-subscribe.js +28 -41
- package/dist/esm/src/interfaces/messages-subscribe.js.map +1 -1
- package/dist/esm/src/interfaces/messages-sync.js +26 -40
- package/dist/esm/src/interfaces/messages-sync.js.map +1 -1
- package/dist/esm/src/interfaces/protocols-configure.js +87 -65
- package/dist/esm/src/interfaces/protocols-configure.js.map +1 -1
- package/dist/esm/src/interfaces/protocols-query.js +55 -68
- package/dist/esm/src/interfaces/protocols-query.js.map +1 -1
- package/dist/esm/src/interfaces/records-count.js +50 -66
- package/dist/esm/src/interfaces/records-count.js.map +1 -1
- package/dist/esm/src/interfaces/records-delete.js +45 -55
- package/dist/esm/src/interfaces/records-delete.js.map +1 -1
- package/dist/esm/src/interfaces/records-query.js +60 -76
- package/dist/esm/src/interfaces/records-query.js.map +1 -1
- package/dist/esm/src/interfaces/records-read.js +51 -67
- package/dist/esm/src/interfaces/records-read.js.map +1 -1
- package/dist/esm/src/interfaces/records-subscribe.js +53 -68
- package/dist/esm/src/interfaces/records-subscribe.js.map +1 -1
- package/dist/esm/src/interfaces/records-write-query.js +102 -0
- package/dist/esm/src/interfaces/records-write-query.js.map +1 -0
- package/dist/esm/src/interfaces/records-write-signing.js +81 -0
- package/dist/esm/src/interfaces/records-write-signing.js.map +1 -0
- package/dist/esm/src/interfaces/records-write.js +396 -610
- package/dist/esm/src/interfaces/records-write.js.map +1 -1
- package/dist/esm/src/jose/algorithms/signing/ed25519.js +10 -19
- package/dist/esm/src/jose/algorithms/signing/ed25519.js.map +1 -1
- package/dist/esm/src/jose/jws/general/builder.js +23 -35
- package/dist/esm/src/jose/jws/general/builder.js.map +1 -1
- package/dist/esm/src/jose/jws/general/verifier.js +56 -69
- package/dist/esm/src/jose/jws/general/verifier.js.map +1 -1
- package/dist/esm/src/protocols/permission-grant.js +43 -14
- package/dist/esm/src/protocols/permission-grant.js.map +1 -1
- package/dist/esm/src/protocols/permission-request.js +28 -14
- package/dist/esm/src/protocols/permission-request.js.map +1 -1
- package/dist/esm/src/protocols/permissions.js +325 -227
- package/dist/esm/src/protocols/permissions.js.map +1 -1
- package/dist/esm/src/smt/smt-store-level.js +42 -64
- package/dist/esm/src/smt/smt-store-level.js.map +1 -1
- package/dist/esm/src/smt/smt-store-memory.js +19 -45
- package/dist/esm/src/smt/smt-store-memory.js.map +1 -1
- package/dist/esm/src/smt/smt-utils.js +28 -45
- package/dist/esm/src/smt/smt-utils.js.map +1 -1
- package/dist/esm/src/smt/sparse-merkle-tree.js +426 -471
- package/dist/esm/src/smt/sparse-merkle-tree.js.map +1 -1
- package/dist/esm/src/state-index/state-index-level.js +113 -150
- package/dist/esm/src/state-index/state-index-level.js.map +1 -1
- package/dist/esm/src/store/blockstore-level.js +54 -156
- package/dist/esm/src/store/blockstore-level.js.map +1 -1
- package/dist/esm/src/store/blockstore-mock.js +48 -153
- package/dist/esm/src/store/blockstore-mock.js.map +1 -1
- package/dist/esm/src/store/data-store-level.js +137 -100
- package/dist/esm/src/store/data-store-level.js.map +1 -1
- package/dist/esm/src/store/index-level-compound.js +246 -0
- package/dist/esm/src/store/index-level-compound.js.map +1 -0
- package/dist/esm/src/store/index-level.js +307 -715
- package/dist/esm/src/store/index-level.js.map +1 -1
- package/dist/esm/src/store/level-wrapper.js +143 -244
- package/dist/esm/src/store/level-wrapper.js.map +1 -1
- package/dist/esm/src/store/message-store-level.js +71 -94
- package/dist/esm/src/store/message-store-level.js.map +1 -1
- package/dist/esm/src/store/resumable-task-store-level.js +62 -101
- package/dist/esm/src/store/resumable-task-store-level.js.map +1 -1
- package/dist/esm/src/store/storage-controller.js +131 -146
- package/dist/esm/src/store/storage-controller.js.map +1 -1
- package/dist/esm/src/types/permission-types.js.map +1 -1
- package/dist/esm/src/types/protocols-types.js +10 -0
- package/dist/esm/src/types/protocols-types.js.map +1 -1
- package/dist/esm/src/types/records-types.js.map +1 -1
- package/dist/esm/src/utils/abort.js +8 -19
- package/dist/esm/src/utils/abort.js.map +1 -1
- package/dist/esm/src/utils/array.js +15 -49
- package/dist/esm/src/utils/array.js.map +1 -1
- package/dist/esm/src/utils/cid.js +29 -77
- package/dist/esm/src/utils/cid.js.map +1 -1
- package/dist/esm/src/utils/data-stream.js +37 -65
- package/dist/esm/src/utils/data-stream.js.map +1 -1
- package/dist/esm/src/utils/encryption.js +136 -162
- package/dist/esm/src/utils/encryption.js.map +1 -1
- package/dist/esm/src/utils/filter.js +1 -12
- package/dist/esm/src/utils/filter.js.map +1 -1
- package/dist/esm/src/utils/hd-key.js +45 -71
- package/dist/esm/src/utils/hd-key.js.map +1 -1
- package/dist/esm/src/utils/jws.js +9 -20
- package/dist/esm/src/utils/jws.js.map +1 -1
- package/dist/esm/src/utils/memory-cache.js +12 -23
- package/dist/esm/src/utils/memory-cache.js.map +1 -1
- package/dist/esm/src/utils/messages.js +21 -33
- package/dist/esm/src/utils/messages.js.map +1 -1
- package/dist/esm/src/utils/private-key-signer.js +9 -17
- package/dist/esm/src/utils/private-key-signer.js.map +1 -1
- package/dist/esm/src/utils/protocols.js +62 -70
- package/dist/esm/src/utils/protocols.js.map +1 -1
- package/dist/esm/src/utils/records.js +103 -166
- package/dist/esm/src/utils/records.js.map +1 -1
- package/dist/esm/src/utils/secp256k1.js +60 -96
- package/dist/esm/src/utils/secp256k1.js.map +1 -1
- package/dist/esm/src/utils/secp256r1.js +54 -71
- package/dist/esm/src/utils/secp256r1.js.map +1 -1
- package/dist/esm/src/utils/time.js +5 -18
- package/dist/esm/src/utils/time.js.map +1 -1
- package/dist/esm/src/utils/url.js +3 -3
- package/dist/esm/src/utils/url.js.map +1 -1
- package/dist/esm/tests/core/auth.spec.js +3 -12
- package/dist/esm/tests/core/auth.spec.js.map +1 -1
- package/dist/esm/tests/core/message.spec.js +50 -59
- package/dist/esm/tests/core/message.spec.js.map +1 -1
- package/dist/esm/tests/core/protocol-authorization.spec.js +10 -18
- package/dist/esm/tests/core/protocol-authorization.spec.js.map +1 -1
- package/dist/esm/tests/dwn.spec.js +65 -89
- package/dist/esm/tests/dwn.spec.js.map +1 -1
- package/dist/esm/tests/event-emitter-event-log.spec.js +305 -0
- package/dist/esm/tests/event-emitter-event-log.spec.js.map +1 -0
- package/dist/esm/tests/features/author-delegated-grant.spec.js +337 -347
- package/dist/esm/tests/features/author-delegated-grant.spec.js.map +1 -1
- package/dist/esm/tests/features/owner-delegated-grant.spec.js +160 -172
- package/dist/esm/tests/features/owner-delegated-grant.spec.js.map +1 -1
- package/dist/esm/tests/features/owner-signature.spec.js +78 -82
- package/dist/esm/tests/features/owner-signature.spec.js.map +1 -1
- package/dist/esm/tests/features/permissions.spec.js +449 -184
- package/dist/esm/tests/features/permissions.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-composition.spec.js +981 -360
- package/dist/esm/tests/features/protocol-composition.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-create-action.spec.js +45 -54
- package/dist/esm/tests/features/protocol-create-action.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-delete-action.spec.js +99 -108
- package/dist/esm/tests/features/protocol-delete-action.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-update-action.spec.js +108 -117
- package/dist/esm/tests/features/protocol-update-action.spec.js.map +1 -1
- package/dist/esm/tests/features/records-immutable.spec.js +315 -0
- package/dist/esm/tests/features/records-immutable.spec.js.map +1 -0
- package/dist/esm/tests/features/records-prune.spec.js +178 -194
- package/dist/esm/tests/features/records-prune.spec.js.map +1 -1
- package/dist/esm/tests/features/records-record-limit.spec.js +542 -0
- package/dist/esm/tests/features/records-record-limit.spec.js.map +1 -0
- package/dist/esm/tests/features/records-tags.spec.js +456 -463
- package/dist/esm/tests/features/records-tags.spec.js.map +1 -1
- package/dist/esm/tests/features/resumable-tasks.spec.js +88 -98
- package/dist/esm/tests/features/resumable-tasks.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-read.spec.js +215 -210
- package/dist/esm/tests/handlers/messages-read.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-subscribe.spec.js +309 -171
- package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-sync.spec.js +272 -199
- package/dist/esm/tests/handlers/messages-sync.spec.js.map +1 -1
- package/dist/esm/tests/handlers/protocols-configure.spec.js +247 -241
- package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -1
- package/dist/esm/tests/handlers/protocols-query.spec.js +159 -172
- package/dist/esm/tests/handlers/protocols-query.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-count.spec.js +101 -105
- package/dist/esm/tests/handlers/records-count.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-delete.spec.js +266 -279
- package/dist/esm/tests/handlers/records-delete.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-query.spec.js +984 -996
- package/dist/esm/tests/handlers/records-query.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-read.spec.js +542 -671
- package/dist/esm/tests/handlers/records-read.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-subscribe.spec.js +433 -302
- package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-write.spec.js +1216 -1140
- package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/messages-get.spec.js +39 -48
- package/dist/esm/tests/interfaces/messages-get.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/messages-subscribe.spec.js +4 -13
- package/dist/esm/tests/interfaces/messages-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/protocols-configure.spec.js +212 -88
- package/dist/esm/tests/interfaces/protocols-configure.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/protocols-query.spec.js +8 -17
- package/dist/esm/tests/interfaces/protocols-query.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-delete.spec.js +8 -17
- package/dist/esm/tests/interfaces/records-delete.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-query.spec.js +20 -29
- package/dist/esm/tests/interfaces/records-query.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-read.spec.js +42 -51
- package/dist/esm/tests/interfaces/records-read.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-subscribe.spec.js +16 -25
- package/dist/esm/tests/interfaces/records-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-write.spec.js +190 -219
- package/dist/esm/tests/interfaces/records-write.spec.js.map +1 -1
- package/dist/esm/tests/jose/jws/general.spec.js +36 -45
- package/dist/esm/tests/jose/jws/general.spec.js.map +1 -1
- package/dist/esm/tests/protocols/permission-grant.spec.js +44 -50
- package/dist/esm/tests/protocols/permission-grant.spec.js.map +1 -1
- package/dist/esm/tests/protocols/permission-request.spec.js +23 -32
- package/dist/esm/tests/protocols/permission-request.spec.js.map +1 -1
- package/dist/esm/tests/protocols/permissions.spec.js +49 -55
- package/dist/esm/tests/protocols/permissions.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/aggregator.spec.js +127 -138
- package/dist/esm/tests/scenarios/aggregator.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/deleted-record.spec.js +372 -36
- package/dist/esm/tests/scenarios/deleted-record.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js +55 -64
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/nested-roles.spec.js +66 -76
- package/dist/esm/tests/scenarios/nested-roles.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/subscriptions.spec.js +451 -354
- package/dist/esm/tests/scenarios/subscriptions.spec.js.map +1 -1
- package/dist/esm/tests/smt/smt-store-level.spec.js +76 -87
- package/dist/esm/tests/smt/smt-store-level.spec.js.map +1 -1
- package/dist/esm/tests/smt/sparse-merkle-tree.spec.js +344 -353
- package/dist/esm/tests/smt/sparse-merkle-tree.spec.js.map +1 -1
- package/dist/esm/tests/state-index/state-index-level.spec.js +117 -126
- package/dist/esm/tests/state-index/state-index-level.spec.js.map +1 -1
- package/dist/esm/tests/store/blockstore-level.spec.js +44 -99
- package/dist/esm/tests/store/blockstore-level.spec.js.map +1 -1
- package/dist/esm/tests/store/blockstore-mock.spec.js +40 -120
- package/dist/esm/tests/store/blockstore-mock.spec.js.map +1 -1
- package/dist/esm/tests/store/data-store-level.spec.js +160 -108
- package/dist/esm/tests/store/data-store-level.spec.js.map +1 -1
- package/dist/esm/tests/store/index-level.spec.js +404 -414
- package/dist/esm/tests/store/index-level.spec.js.map +1 -1
- package/dist/esm/tests/store/message-store-level.spec.js +13 -22
- package/dist/esm/tests/store/message-store-level.spec.js.map +1 -1
- package/dist/esm/tests/store/message-store.spec.js +229 -238
- package/dist/esm/tests/store/message-store.spec.js.map +1 -1
- package/dist/esm/tests/test-event-stream.js +12 -13
- package/dist/esm/tests/test-event-stream.js.map +1 -1
- package/dist/esm/tests/test-stores.js +16 -13
- package/dist/esm/tests/test-stores.js.map +1 -1
- package/dist/esm/tests/test-suite.js +8 -15
- package/dist/esm/tests/test-suite.js.map +1 -1
- package/dist/esm/tests/utils/cid.spec.js +24 -33
- package/dist/esm/tests/utils/cid.spec.js.map +1 -1
- package/dist/esm/tests/utils/data-stream.spec.js +48 -57
- package/dist/esm/tests/utils/data-stream.spec.js.map +1 -1
- package/dist/esm/tests/utils/encryption-callbacks.spec.js +45 -54
- package/dist/esm/tests/utils/encryption-callbacks.spec.js.map +1 -1
- package/dist/esm/tests/utils/encryption.spec.js +229 -82
- package/dist/esm/tests/utils/encryption.spec.js.map +1 -1
- package/dist/esm/tests/utils/filters.spec.js +46 -55
- package/dist/esm/tests/utils/filters.spec.js.map +1 -1
- package/dist/esm/tests/utils/hd-key.spec.js +10 -19
- package/dist/esm/tests/utils/hd-key.spec.js.map +1 -1
- package/dist/esm/tests/utils/jws.spec.js +3 -12
- package/dist/esm/tests/utils/jws.spec.js.map +1 -1
- package/dist/esm/tests/utils/memory-cache.spec.js +9 -18
- package/dist/esm/tests/utils/memory-cache.spec.js.map +1 -1
- package/dist/esm/tests/utils/messages.spec.js +18 -20
- package/dist/esm/tests/utils/messages.spec.js.map +1 -1
- package/dist/esm/tests/utils/poller.js +22 -33
- package/dist/esm/tests/utils/poller.js.map +1 -1
- package/dist/esm/tests/utils/private-key-signer.spec.js +15 -24
- package/dist/esm/tests/utils/private-key-signer.spec.js.map +1 -1
- package/dist/esm/tests/utils/records.spec.js +14 -27
- package/dist/esm/tests/utils/records.spec.js.map +1 -1
- package/dist/esm/tests/utils/secp256k1.spec.js +16 -25
- package/dist/esm/tests/utils/secp256k1.spec.js.map +1 -1
- package/dist/esm/tests/utils/secp256r1.spec.js +18 -27
- package/dist/esm/tests/utils/secp256r1.spec.js.map +1 -1
- package/dist/esm/tests/utils/test-data-generator.js +446 -467
- package/dist/esm/tests/utils/test-data-generator.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/definitions.spec.js +2 -11
- package/dist/esm/tests/validation/json-schemas/definitions.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/jwk/general-jwk.spec.js +4 -13
- package/dist/esm/tests/validation/json-schemas/jwk/general-jwk.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/jwk/public-jwk.spec.js +8 -17
- package/dist/esm/tests/validation/json-schemas/jwk/public-jwk.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/jwk-verification-method.spec.js +3 -12
- package/dist/esm/tests/validation/json-schemas/jwk-verification-method.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js +4 -13
- package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/records/records-query.spec.js +2 -11
- package/dist/esm/tests/validation/json-schemas/records/records-query.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/records/records-read.spec.js +2 -11
- package/dist/esm/tests/validation/json-schemas/records/records-read.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js +44 -24
- package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js.map +1 -1
- package/dist/types/generated/precompiled-validators.d.ts +49 -40
- package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
- package/dist/types/src/core/constants.d.ts +11 -0
- package/dist/types/src/core/constants.d.ts.map +1 -0
- package/dist/types/src/core/core-protocol.d.ts +89 -0
- package/dist/types/src/core/core-protocol.d.ts.map +1 -0
- package/dist/types/src/core/dwn-error.d.ts +9 -12
- package/dist/types/src/core/dwn-error.d.ts.map +1 -1
- package/dist/types/src/core/grant-authorization.d.ts +6 -2
- package/dist/types/src/core/grant-authorization.d.ts.map +1 -1
- package/dist/types/src/core/protocol-authorization-action.d.ts +42 -0
- package/dist/types/src/core/protocol-authorization-action.d.ts.map +1 -0
- package/dist/types/src/core/protocol-authorization-validation.d.ts +81 -0
- package/dist/types/src/core/protocol-authorization-validation.d.ts.map +1 -0
- package/dist/types/src/core/protocol-authorization.d.ts +24 -106
- package/dist/types/src/core/protocol-authorization.d.ts.map +1 -1
- package/dist/types/src/core/record-chain.d.ts +24 -0
- package/dist/types/src/core/record-chain.d.ts.map +1 -0
- package/dist/types/src/core/records-grant-authorization.d.ts.map +1 -1
- package/dist/types/src/dwn.d.ts +19 -7
- package/dist/types/src/dwn.d.ts.map +1 -1
- package/dist/types/src/event-stream/event-emitter-event-log.d.ts +50 -0
- package/dist/types/src/event-stream/event-emitter-event-log.d.ts.map +1 -0
- package/dist/types/src/handlers/messages-read.d.ts +3 -8
- package/dist/types/src/handlers/messages-read.d.ts.map +1 -1
- package/dist/types/src/handlers/messages-subscribe.d.ts +6 -10
- package/dist/types/src/handlers/messages-subscribe.d.ts.map +1 -1
- package/dist/types/src/handlers/messages-sync.d.ts +3 -8
- package/dist/types/src/handlers/messages-sync.d.ts.map +1 -1
- package/dist/types/src/handlers/protocols-configure.d.ts +3 -10
- package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -1
- package/dist/types/src/handlers/protocols-query.d.ts +3 -8
- package/dist/types/src/handlers/protocols-query.d.ts.map +1 -1
- package/dist/types/src/handlers/records-count.d.ts +3 -6
- package/dist/types/src/handlers/records-count.d.ts.map +1 -1
- package/dist/types/src/handlers/records-delete.d.ts +3 -8
- package/dist/types/src/handlers/records-delete.d.ts.map +1 -1
- package/dist/types/src/handlers/records-query.d.ts +3 -8
- package/dist/types/src/handlers/records-query.d.ts.map +1 -1
- package/dist/types/src/handlers/records-read.d.ts +3 -8
- package/dist/types/src/handlers/records-read.d.ts.map +1 -1
- package/dist/types/src/handlers/records-subscribe.d.ts +8 -10
- package/dist/types/src/handlers/records-subscribe.d.ts.map +1 -1
- package/dist/types/src/handlers/records-write.d.ts +4 -24
- package/dist/types/src/handlers/records-write.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +8 -4
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/interfaces/messages-subscribe.d.ts +5 -0
- package/dist/types/src/interfaces/messages-subscribe.d.ts.map +1 -1
- package/dist/types/src/interfaces/protocols-configure.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-subscribe.d.ts +5 -0
- package/dist/types/src/interfaces/records-subscribe.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-write-query.d.ts +33 -0
- package/dist/types/src/interfaces/records-write-query.d.ts.map +1 -0
- package/dist/types/src/interfaces/records-write-signing.d.ts +34 -0
- package/dist/types/src/interfaces/records-write-signing.d.ts.map +1 -0
- package/dist/types/src/interfaces/records-write.d.ts +13 -53
- package/dist/types/src/interfaces/records-write.d.ts.map +1 -1
- package/dist/types/src/protocols/permission-grant.d.ts +1 -1
- package/dist/types/src/protocols/permission-grant.d.ts.map +1 -1
- package/dist/types/src/protocols/permission-request.d.ts +1 -1
- package/dist/types/src/protocols/permission-request.d.ts.map +1 -1
- package/dist/types/src/protocols/permissions.d.ts +40 -3
- package/dist/types/src/protocols/permissions.d.ts.map +1 -1
- package/dist/types/src/state-index/state-index-level.d.ts.map +1 -1
- package/dist/types/src/store/data-store-level.d.ts +20 -4
- package/dist/types/src/store/data-store-level.d.ts.map +1 -1
- package/dist/types/src/store/index-level-compound.d.ts +70 -0
- package/dist/types/src/store/index-level-compound.d.ts.map +1 -0
- package/dist/types/src/store/index-level.d.ts +4 -58
- package/dist/types/src/store/index-level.d.ts.map +1 -1
- package/dist/types/src/store/storage-controller.d.ts +4 -4
- package/dist/types/src/store/storage-controller.d.ts.map +1 -1
- package/dist/types/src/types/message-types.d.ts +3 -3
- package/dist/types/src/types/message-types.d.ts.map +1 -1
- package/dist/types/src/types/messages-types.d.ts +12 -3
- package/dist/types/src/types/messages-types.d.ts.map +1 -1
- package/dist/types/src/types/method-handler.d.ts +24 -3
- package/dist/types/src/types/method-handler.d.ts.map +1 -1
- package/dist/types/src/types/permission-types.d.ts +7 -0
- package/dist/types/src/types/permission-types.d.ts.map +1 -1
- package/dist/types/src/types/protocols-types.d.ts +41 -1
- package/dist/types/src/types/protocols-types.d.ts.map +1 -1
- package/dist/types/src/types/records-types.d.ts +16 -6
- package/dist/types/src/types/records-types.d.ts.map +1 -1
- package/dist/types/src/types/subscriptions.d.ts +151 -13
- package/dist/types/src/types/subscriptions.d.ts.map +1 -1
- package/dist/types/src/utils/hd-key.d.ts +1 -9
- package/dist/types/src/utils/hd-key.d.ts.map +1 -1
- package/dist/types/src/utils/messages.d.ts +7 -5
- package/dist/types/src/utils/messages.d.ts.map +1 -1
- package/dist/types/src/utils/protocols.d.ts +5 -0
- package/dist/types/src/utils/protocols.d.ts.map +1 -1
- package/dist/types/src/utils/records.d.ts +1 -11
- package/dist/types/src/utils/records.d.ts.map +1 -1
- package/dist/types/tests/dwn.spec.d.ts.map +1 -1
- package/dist/types/tests/event-emitter-event-log.spec.d.ts +2 -0
- package/dist/types/tests/event-emitter-event-log.spec.d.ts.map +1 -0
- package/dist/types/tests/features/author-delegated-grant.spec.d.ts.map +1 -1
- package/dist/types/tests/features/owner-delegated-grant.spec.d.ts.map +1 -1
- package/dist/types/tests/features/owner-signature.spec.d.ts.map +1 -1
- package/dist/types/tests/features/permissions.spec.d.ts.map +1 -1
- package/dist/types/tests/features/protocol-composition.spec.d.ts.map +1 -1
- package/dist/types/tests/features/records-immutable.spec.d.ts +2 -0
- package/dist/types/tests/features/records-immutable.spec.d.ts.map +1 -0
- package/dist/types/tests/features/records-record-limit.spec.d.ts +2 -0
- package/dist/types/tests/features/records-record-limit.spec.d.ts.map +1 -0
- package/dist/types/tests/features/records-tags.spec.d.ts.map +1 -1
- package/dist/types/tests/features/resumable-tasks.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/messages-read.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/messages-subscribe.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/messages-sync.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/records-count.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/records-delete.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/records-query.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/records-read.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/records-subscribe.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/records-write.spec.d.ts.map +1 -1
- package/dist/types/tests/scenarios/deleted-record.spec.d.ts.map +1 -1
- package/dist/types/tests/scenarios/subscriptions.spec.d.ts.map +1 -1
- package/dist/types/tests/test-event-stream.d.ts +11 -12
- package/dist/types/tests/test-event-stream.d.ts.map +1 -1
- package/dist/types/tests/test-suite.d.ts +2 -2
- package/dist/types/tests/test-suite.d.ts.map +1 -1
- package/dist/types/tests/utils/test-data-generator.d.ts +18 -0
- package/dist/types/tests/utils/test-data-generator.d.ts.map +1 -1
- package/package.json +5 -4
- package/src/core/constants.ts +11 -0
- package/src/core/core-protocol.ts +129 -0
- package/src/core/dwn-error.ts +15 -12
- package/src/core/grant-authorization.ts +20 -3
- package/src/core/protocol-authorization-action.ts +377 -0
- package/src/core/protocol-authorization-validation.ts +487 -0
- package/src/core/protocol-authorization.ts +111 -856
- package/src/core/record-chain.ts +99 -0
- package/src/core/records-grant-authorization.ts +6 -8
- package/src/dwn.ts +58 -73
- package/src/event-stream/event-emitter-event-log.ts +283 -0
- package/src/handlers/messages-read.ts +8 -9
- package/src/handlers/messages-subscribe.ts +24 -28
- package/src/handlers/messages-sync.ts +10 -16
- package/src/handlers/protocols-configure.ts +47 -32
- package/src/handlers/protocols-query.ts +6 -9
- package/src/handlers/records-count.ts +11 -10
- package/src/handlers/records-delete.ts +12 -21
- package/src/handlers/records-query.ts +12 -12
- package/src/handlers/records-read.ts +34 -22
- package/src/handlers/records-subscribe.ts +47 -26
- package/src/handlers/records-write.ts +47 -104
- package/src/index.ts +9 -5
- package/src/interfaces/messages-subscribe.ts +7 -1
- package/src/interfaces/protocols-configure.ts +73 -8
- package/src/interfaces/records-count.ts +1 -1
- package/src/interfaces/records-delete.ts +1 -1
- package/src/interfaces/records-query.ts +1 -1
- package/src/interfaces/records-read.ts +1 -1
- package/src/interfaces/records-subscribe.ts +8 -1
- package/src/interfaces/records-write-query.ts +139 -0
- package/src/interfaces/records-write-signing.ts +123 -0
- package/src/interfaces/records-write.ts +66 -261
- package/src/protocols/permission-grant.ts +1 -1
- package/src/protocols/permission-request.ts +1 -1
- package/src/protocols/permissions.ts +148 -6
- package/src/state-index/state-index-level.ts +5 -7
- package/src/store/data-store-level.ts +124 -34
- package/src/store/index-level-compound.ts +324 -0
- package/src/store/index-level.ts +68 -341
- package/src/store/storage-controller.ts +11 -11
- package/src/types/message-types.ts +3 -3
- package/src/types/messages-types.ts +12 -3
- package/src/types/method-handler.ts +26 -4
- package/src/types/mitt.d.ts +28 -0
- package/src/types/permission-types.ts +7 -0
- package/src/types/protocols-types.ts +46 -0
- package/src/types/records-types.ts +16 -6
- package/src/types/subscriptions.ts +178 -14
- package/src/utils/hd-key.ts +0 -9
- package/src/utils/messages.ts +17 -37
- package/src/utils/protocols.ts +8 -0
- package/src/utils/records.ts +8 -59
- package/dist/esm/src/event-stream/event-emitter-stream.js +0 -60
- package/dist/esm/src/event-stream/event-emitter-stream.js.map +0 -1
- package/dist/esm/tests/event-stream/event-emitter-stream.spec.js +0 -77
- package/dist/esm/tests/event-stream/event-emitter-stream.spec.js.map +0 -1
- package/dist/esm/tests/event-stream/event-stream.spec.js +0 -123
- package/dist/esm/tests/event-stream/event-stream.spec.js.map +0 -1
- package/dist/types/src/event-stream/event-emitter-stream.d.ts +0 -23
- package/dist/types/src/event-stream/event-emitter-stream.d.ts.map +0 -1
- package/dist/types/tests/event-stream/event-emitter-stream.spec.d.ts +0 -2
- package/dist/types/tests/event-stream/event-emitter-stream.spec.d.ts.map +0 -1
- package/dist/types/tests/event-stream/event-stream.spec.d.ts +0 -2
- package/dist/types/tests/event-stream/event-stream.spec.d.ts.map +0 -1
- package/src/event-stream/event-emitter-stream.ts +0 -69
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
|
|
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
|
-
};
|
|
1
|
+
import minimalProtocolDefinition from '../vectors/protocol-definitions/minimal.json' with { type: 'json' };
|
|
10
2
|
import sinon from 'sinon';
|
|
11
3
|
import { DataStream } from '../../src/utils/data-stream.js';
|
|
12
4
|
import { Dwn } from '../../src/dwn.js';
|
|
@@ -16,7 +8,7 @@ import { PermissionsProtocol } from '../../src/protocols/permissions.js';
|
|
|
16
8
|
import { RecordsRead } from '../../src/interfaces/records-read.js';
|
|
17
9
|
import { RecordsWrite } from '../../src/interfaces/records-write.js';
|
|
18
10
|
import { TestDataGenerator } from '../utils/test-data-generator.js';
|
|
19
|
-
import {
|
|
11
|
+
import { TestEventLog } from '../test-event-stream.js';
|
|
20
12
|
import { TestStores } from '../test-stores.js';
|
|
21
13
|
import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'bun:test';
|
|
22
14
|
import { DidKey, UniversalResolver } from '@enbox/dids';
|
|
@@ -28,37 +20,37 @@ export function testPermissions() {
|
|
|
28
20
|
let dataStore;
|
|
29
21
|
let resumableTaskStore;
|
|
30
22
|
let stateIndex;
|
|
31
|
-
let
|
|
23
|
+
let eventLog;
|
|
32
24
|
let dwn;
|
|
33
25
|
// important to follow the `before` and `after` pattern to initialize and clean the stores in tests
|
|
34
26
|
// so that different test suites can reuse the same backend store for testing
|
|
35
|
-
beforeAll(() =>
|
|
27
|
+
beforeAll(async () => {
|
|
36
28
|
didResolver = new UniversalResolver({ didResolvers: [DidKey] });
|
|
37
29
|
const stores = TestStores.get();
|
|
38
30
|
messageStore = stores.messageStore;
|
|
39
31
|
dataStore = stores.dataStore;
|
|
40
32
|
resumableTaskStore = stores.resumableTaskStore;
|
|
41
33
|
stateIndex = stores.stateIndex;
|
|
42
|
-
|
|
43
|
-
dwn =
|
|
44
|
-
})
|
|
45
|
-
beforeEach(() =>
|
|
34
|
+
eventLog = TestEventLog.get();
|
|
35
|
+
dwn = await Dwn.create({ didResolver, messageStore, dataStore, stateIndex, eventLog, resumableTaskStore });
|
|
36
|
+
});
|
|
37
|
+
beforeEach(async () => {
|
|
46
38
|
sinon.restore(); // wipe all previous stubs/spies/mocks/fakes
|
|
47
39
|
// clean up before each test rather than after so that a test does not depend on other tests to do the clean up
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
})
|
|
53
|
-
afterAll(() =>
|
|
40
|
+
await messageStore.clear();
|
|
41
|
+
await dataStore.clear();
|
|
42
|
+
await resumableTaskStore.clear();
|
|
43
|
+
await stateIndex.clear();
|
|
44
|
+
});
|
|
45
|
+
afterAll(async () => {
|
|
54
46
|
sinon.restore();
|
|
55
|
-
|
|
56
|
-
})
|
|
57
|
-
it('should include record tags using the createRequest, createGrant and createRevocation if provided', () =>
|
|
58
|
-
const alice =
|
|
47
|
+
await dwn.close();
|
|
48
|
+
});
|
|
49
|
+
it('should include record tags using the createRequest, createGrant and createRevocation if provided', async () => {
|
|
50
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
59
51
|
const testProtocol = 'https://example.com/protocol/test';
|
|
60
52
|
// createRequest with a protocol
|
|
61
|
-
const requestWrite =
|
|
53
|
+
const requestWrite = await PermissionsProtocol.createRequest({
|
|
62
54
|
signer: Jws.createSigner(alice),
|
|
63
55
|
description: 'Requesting to write',
|
|
64
56
|
delegated: false,
|
|
@@ -70,7 +62,7 @@ export function testPermissions() {
|
|
|
70
62
|
});
|
|
71
63
|
expect(requestWrite.recordsWrite.message.descriptor.tags).toEqual({ protocol: testProtocol });
|
|
72
64
|
// createGrant with a protocol
|
|
73
|
-
const grantWrite =
|
|
65
|
+
const grantWrite = await PermissionsProtocol.createGrant({
|
|
74
66
|
signer: Jws.createSigner(alice),
|
|
75
67
|
dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
|
|
76
68
|
description: 'Allow Bob to write',
|
|
@@ -83,18 +75,18 @@ export function testPermissions() {
|
|
|
83
75
|
});
|
|
84
76
|
expect(grantWrite.recordsWrite.message.descriptor.tags).toEqual({ protocol: testProtocol });
|
|
85
77
|
// createRevocation with a protocol derived from the grant
|
|
86
|
-
const revokeWrite =
|
|
78
|
+
const revokeWrite = await PermissionsProtocol.createRevocation({
|
|
87
79
|
signer: Jws.createSigner(alice),
|
|
88
|
-
grant:
|
|
80
|
+
grant: PermissionGrant.parse(grantWrite.dataEncodedMessage),
|
|
89
81
|
dateRevoked: Time.getCurrentTimestamp()
|
|
90
82
|
});
|
|
91
83
|
expect(revokeWrite.recordsWrite.message.descriptor.tags).toEqual({ protocol: testProtocol });
|
|
92
|
-
})
|
|
93
|
-
it('should normalize the protocol URL in the scope of a Request, Grant, and Revocation', () =>
|
|
94
|
-
const alice =
|
|
95
|
-
const bob =
|
|
84
|
+
});
|
|
85
|
+
it('should normalize the protocol URL in the scope of a Request, Grant, and Revocation', async () => {
|
|
86
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
87
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
96
88
|
// createRequest with a protocol that will be normalized to `http://any-protocol`
|
|
97
|
-
const requestWrite =
|
|
89
|
+
const requestWrite = await PermissionsProtocol.createRequest({
|
|
98
90
|
signer: Jws.createSigner(bob),
|
|
99
91
|
description: 'Requesting to write',
|
|
100
92
|
delegated: false,
|
|
@@ -106,7 +98,7 @@ export function testPermissions() {
|
|
|
106
98
|
});
|
|
107
99
|
expect(requestWrite.recordsWrite.message.descriptor.tags).toEqual({ protocol: 'http://any-protocol' });
|
|
108
100
|
// createRequest with a protocol that is already normalized to `https://any-protocol`
|
|
109
|
-
const requestWrite2 =
|
|
101
|
+
const requestWrite2 = await PermissionsProtocol.createRequest({
|
|
110
102
|
signer: Jws.createSigner(bob),
|
|
111
103
|
description: 'Requesting to write',
|
|
112
104
|
delegated: false,
|
|
@@ -118,7 +110,7 @@ export function testPermissions() {
|
|
|
118
110
|
});
|
|
119
111
|
expect(requestWrite2.recordsWrite.message.descriptor.tags).toEqual({ protocol: 'https://any-protocol' });
|
|
120
112
|
// createGrant with a protocol that will be normalized to `http://any-protocol`
|
|
121
|
-
const grantWrite =
|
|
113
|
+
const grantWrite = await PermissionsProtocol.createGrant({
|
|
122
114
|
signer: Jws.createSigner(alice),
|
|
123
115
|
dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
|
|
124
116
|
description: 'Allow Bob to write',
|
|
@@ -131,7 +123,7 @@ export function testPermissions() {
|
|
|
131
123
|
});
|
|
132
124
|
expect(grantWrite.recordsWrite.message.descriptor.tags).toEqual({ protocol: 'http://any-protocol' });
|
|
133
125
|
// createGrant with a protocol that is already normalized to `https://any-protocol`
|
|
134
|
-
const grantWrite2 =
|
|
126
|
+
const grantWrite2 = await PermissionsProtocol.createGrant({
|
|
135
127
|
signer: Jws.createSigner(alice),
|
|
136
128
|
dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
|
|
137
129
|
description: 'Allow Bob to write',
|
|
@@ -143,13 +135,13 @@ export function testPermissions() {
|
|
|
143
135
|
}
|
|
144
136
|
});
|
|
145
137
|
expect(grantWrite2.recordsWrite.message.descriptor.tags).toEqual({ protocol: 'https://any-protocol' });
|
|
146
|
-
})
|
|
147
|
-
it('should derive the grantId and protocol from the grant record when creating a revocation', () =>
|
|
148
|
-
const alice =
|
|
149
|
-
const bob =
|
|
138
|
+
});
|
|
139
|
+
it('should derive the grantId and protocol from the grant record when creating a revocation', async () => {
|
|
140
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
141
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
150
142
|
const grantProtocol = 'https://example.com/protocol/test';
|
|
151
143
|
// alice creates a grant for bob
|
|
152
|
-
const grantWrite =
|
|
144
|
+
const grantWrite = await PermissionsProtocol.createGrant({
|
|
153
145
|
signer: Jws.createSigner(alice),
|
|
154
146
|
dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
|
|
155
147
|
description: 'Allow Bob to write',
|
|
@@ -160,22 +152,22 @@ export function testPermissions() {
|
|
|
160
152
|
protocol: grantProtocol,
|
|
161
153
|
}
|
|
162
154
|
});
|
|
163
|
-
const grantWriteReply =
|
|
155
|
+
const grantWriteReply = await dwn.processMessage(alice.did, grantWrite.recordsWrite.message, {
|
|
164
156
|
dataStream: DataStream.fromBytes(grantWrite.permissionGrantBytes)
|
|
165
157
|
});
|
|
166
158
|
expect(grantWriteReply.status.code).toBe(202);
|
|
167
159
|
// derive the grantId and protocol from the grant record
|
|
168
|
-
const revokeWrite =
|
|
160
|
+
const revokeWrite = await PermissionsProtocol.createRevocation({
|
|
169
161
|
signer: Jws.createSigner(alice),
|
|
170
|
-
grant:
|
|
162
|
+
grant: PermissionGrant.parse(grantWrite.dataEncodedMessage),
|
|
171
163
|
dateRevoked: Time.getCurrentTimestamp()
|
|
172
164
|
});
|
|
173
165
|
// check that the protocol is in the revocation record's tags
|
|
174
166
|
expect(revokeWrite.recordsWrite.message.descriptor.tags).toEqual({ protocol: grantProtocol });
|
|
175
167
|
// check that the revocation's parentId is the grant's recordId
|
|
176
168
|
expect(revokeWrite.recordsWrite.message.descriptor.parentId).toBe(grantWrite.recordsWrite.message.recordId);
|
|
177
|
-
})
|
|
178
|
-
it('should support permission management through use of Request, Grants, and Revocations', () =>
|
|
169
|
+
});
|
|
170
|
+
it('should support permission management through use of Request, Grants, and Revocations', async () => {
|
|
179
171
|
// scenario:
|
|
180
172
|
// 1. Verify anyone (Bob) can send a permission request to Alice
|
|
181
173
|
// 2. Alice queries her DWN for new permission requests
|
|
@@ -186,25 +178,24 @@ export function testPermissions() {
|
|
|
186
178
|
// 7. Verify that non-owner cannot revoke the grant
|
|
187
179
|
// 8. Alice revokes the permission grant for Bob
|
|
188
180
|
// 9. Verify that any third-party can fetch the revocation status of the permission grant
|
|
189
|
-
|
|
190
|
-
const
|
|
191
|
-
const bob = yield TestDataGenerator.generateDidKeyPersona();
|
|
181
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
182
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
192
183
|
// 1. Verify anyone (Bob) can send a permission request to Alice
|
|
193
184
|
const permissionScope = {
|
|
194
185
|
interface: DwnInterfaceName.Records,
|
|
195
186
|
method: DwnMethodName.Write,
|
|
196
187
|
protocol: `any-protocol`
|
|
197
188
|
};
|
|
198
|
-
const requestToAlice =
|
|
189
|
+
const requestToAlice = await PermissionsProtocol.createRequest({
|
|
199
190
|
signer: Jws.createSigner(bob),
|
|
200
191
|
description: `Requesting to write to Alice's DWN`,
|
|
201
192
|
delegated: false,
|
|
202
193
|
scope: permissionScope
|
|
203
194
|
});
|
|
204
|
-
const requestWriteReply =
|
|
195
|
+
const requestWriteReply = await dwn.processMessage(alice.did, requestToAlice.recordsWrite.message, { dataStream: DataStream.fromBytes(requestToAlice.permissionRequestBytes) });
|
|
205
196
|
expect(requestWriteReply.status.code).toBe(202);
|
|
206
197
|
// 2. Alice queries her DWN for new permission requests
|
|
207
|
-
const requestQuery =
|
|
198
|
+
const requestQuery = await RecordsQuery.create({
|
|
208
199
|
signer: Jws.createSigner(alice),
|
|
209
200
|
filter: {
|
|
210
201
|
protocolPath: PermissionsProtocol.requestPath,
|
|
@@ -212,35 +203,35 @@ export function testPermissions() {
|
|
|
212
203
|
dateUpdated: { from: Time.createOffsetTimestamp({ seconds: -1 * 60 * 60 * 24 }) } // last 24 hours
|
|
213
204
|
}
|
|
214
205
|
});
|
|
215
|
-
const requestQueryReply =
|
|
216
|
-
const requestFromBob =
|
|
206
|
+
const requestQueryReply = await dwn.processMessage(alice.did, requestQuery.message);
|
|
207
|
+
const requestFromBob = requestQueryReply.entries?.[0];
|
|
217
208
|
expect(requestQueryReply.status.code).toBe(200);
|
|
218
|
-
expect(
|
|
209
|
+
expect(requestQueryReply.entries?.length).toBe(1);
|
|
219
210
|
expect(requestFromBob.recordId).toBe(requestToAlice.recordsWrite.message.recordId);
|
|
220
211
|
// 3. Verify a non-owner cannot create a grant for Bob in Alice's DWN
|
|
221
212
|
const decodedRequest = PermissionsProtocol.parseRequest(requestFromBob.encodedData);
|
|
222
|
-
const unauthorizedGrantWrite =
|
|
213
|
+
const unauthorizedGrantWrite = await PermissionsProtocol.createGrant({
|
|
223
214
|
signer: Jws.createSigner(bob),
|
|
224
215
|
dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
|
|
225
216
|
description: 'Allow Bob to write',
|
|
226
217
|
grantedTo: bob.did,
|
|
227
218
|
scope: decodedRequest.scope
|
|
228
219
|
});
|
|
229
|
-
const unauthorizedGrantWriteReply =
|
|
220
|
+
const unauthorizedGrantWriteReply = await dwn.processMessage(alice.did, unauthorizedGrantWrite.recordsWrite.message, { dataStream: DataStream.fromBytes(unauthorizedGrantWrite.permissionGrantBytes) });
|
|
230
221
|
expect(unauthorizedGrantWriteReply.status.code).toBe(401);
|
|
231
222
|
expect(unauthorizedGrantWriteReply.status.detail).toContain(DwnErrorCode.ProtocolAuthorizationActionNotAllowed);
|
|
232
223
|
// 4. Alice creates a permission grant for Bob in her DWN
|
|
233
|
-
const grantWrite =
|
|
224
|
+
const grantWrite = await PermissionsProtocol.createGrant({
|
|
234
225
|
signer: Jws.createSigner(alice),
|
|
235
226
|
dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
|
|
236
227
|
description: 'Allow Bob to write',
|
|
237
228
|
grantedTo: bob.did,
|
|
238
229
|
scope: decodedRequest.scope
|
|
239
230
|
});
|
|
240
|
-
const grantWriteReply =
|
|
231
|
+
const grantWriteReply = await dwn.processMessage(alice.did, grantWrite.recordsWrite.message, { dataStream: DataStream.fromBytes(grantWrite.permissionGrantBytes) });
|
|
241
232
|
expect(grantWriteReply.status.code).toBe(202);
|
|
242
233
|
// 5. Verify that Bob can query the permission grant from Alice's DWN (even though Alice can also send it directly to Bob)
|
|
243
|
-
const grantQuery =
|
|
234
|
+
const grantQuery = await RecordsQuery.create({
|
|
244
235
|
signer: Jws.createSigner(bob),
|
|
245
236
|
filter: {
|
|
246
237
|
protocolPath: PermissionsProtocol.grantPath,
|
|
@@ -248,46 +239,46 @@ export function testPermissions() {
|
|
|
248
239
|
dateUpdated: { from: Time.createOffsetTimestamp({ seconds: -1 * 60 * 60 * 24 }) } // last 24 hours
|
|
249
240
|
}
|
|
250
241
|
});
|
|
251
|
-
const grantQueryReply =
|
|
252
|
-
const grantFromBob =
|
|
242
|
+
const grantQueryReply = await dwn.processMessage(alice.did, grantQuery.message);
|
|
243
|
+
const grantFromBob = grantQueryReply.entries?.[0];
|
|
253
244
|
expect(grantQueryReply.status.code).toBe(200);
|
|
254
|
-
expect(
|
|
245
|
+
expect(grantQueryReply.entries?.length).toBe(1);
|
|
255
246
|
expect(grantFromBob.recordId).toBe(grantWrite.recordsWrite.message.recordId);
|
|
256
247
|
// 6. Verify that any third-party can fetch revocation of the grant and find it is still active (not revoked)
|
|
257
|
-
const revocationRead =
|
|
248
|
+
const revocationRead = await RecordsRead.create({
|
|
258
249
|
signer: Jws.createSigner(bob),
|
|
259
250
|
filter: {
|
|
260
251
|
contextId: grantWrite.recordsWrite.message.contextId,
|
|
261
252
|
protocolPath: PermissionsProtocol.revocationPath
|
|
262
253
|
}
|
|
263
254
|
});
|
|
264
|
-
const revocationReadReply =
|
|
255
|
+
const revocationReadReply = await dwn.processMessage(alice.did, revocationRead.message);
|
|
265
256
|
expect(revocationReadReply.status.code).toBe(404);
|
|
266
257
|
// 7. Verify that non-owner cannot revoke the grant
|
|
267
|
-
const unauthorizedRevokeWrite =
|
|
258
|
+
const unauthorizedRevokeWrite = await PermissionsProtocol.createRevocation({
|
|
268
259
|
signer: Jws.createSigner(bob),
|
|
269
|
-
grant:
|
|
260
|
+
grant: PermissionGrant.parse(grantWrite.dataEncodedMessage),
|
|
270
261
|
dateRevoked: Time.getCurrentTimestamp(),
|
|
271
262
|
});
|
|
272
|
-
const unauthorizedRevokeWriteReply =
|
|
263
|
+
const unauthorizedRevokeWriteReply = await dwn.processMessage(alice.did, unauthorizedRevokeWrite.recordsWrite.message, { dataStream: DataStream.fromBytes(unauthorizedRevokeWrite.permissionRevocationBytes) });
|
|
273
264
|
expect(unauthorizedRevokeWriteReply.status.code).toBe(401);
|
|
274
265
|
expect(unauthorizedGrantWriteReply.status.detail).toContain(DwnErrorCode.ProtocolAuthorizationActionNotAllowed);
|
|
275
266
|
// 8. Alice revokes the permission grant for Bob
|
|
276
|
-
const revokeWrite =
|
|
267
|
+
const revokeWrite = await PermissionsProtocol.createRevocation({
|
|
277
268
|
signer: Jws.createSigner(alice),
|
|
278
|
-
grant:
|
|
269
|
+
grant: PermissionGrant.parse(grantWrite.dataEncodedMessage),
|
|
279
270
|
dateRevoked: Time.getCurrentTimestamp(),
|
|
280
271
|
});
|
|
281
|
-
const revokeWriteReply =
|
|
272
|
+
const revokeWriteReply = await dwn.processMessage(alice.did, revokeWrite.recordsWrite.message, { dataStream: DataStream.fromBytes(revokeWrite.permissionRevocationBytes) });
|
|
282
273
|
expect(revokeWriteReply.status.code).toBe(202);
|
|
283
274
|
// 9. Verify that any third-party can fetch the revocation status of the permission grant
|
|
284
|
-
const revocationReadReply2 =
|
|
275
|
+
const revocationReadReply2 = await dwn.processMessage(alice.did, revocationRead.message);
|
|
285
276
|
expect(revocationReadReply2.status.code).toBe(200);
|
|
286
|
-
expect(
|
|
287
|
-
})
|
|
288
|
-
it('should fail if a RecordsPermissionScope in a Request or Grant record is created without a protocol', () =>
|
|
289
|
-
const alice =
|
|
290
|
-
const bob =
|
|
277
|
+
expect(revocationReadReply2.entry.recordsWrite?.recordId).toBe(revokeWrite.recordsWrite.message.recordId);
|
|
278
|
+
});
|
|
279
|
+
it('should fail if a RecordsPermissionScope in a Request or Grant record is created without a protocol', async () => {
|
|
280
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
281
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
291
282
|
const permissionScope = {
|
|
292
283
|
interface: DwnInterfaceName.Records,
|
|
293
284
|
method: DwnMethodName.Write
|
|
@@ -298,7 +289,7 @@ export function testPermissions() {
|
|
|
298
289
|
delegated: false,
|
|
299
290
|
scope: permissionScope // explicity as any to test the validation
|
|
300
291
|
});
|
|
301
|
-
|
|
292
|
+
await expect(requestWrite).rejects.toThrow(DwnErrorCode.PermissionsProtocolCreateRequestRecordsScopeMissingProtocol);
|
|
302
293
|
const grantWrite = PermissionsProtocol.createGrant({
|
|
303
294
|
signer: Jws.createSigner(alice),
|
|
304
295
|
dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
|
|
@@ -306,30 +297,30 @@ export function testPermissions() {
|
|
|
306
297
|
grantedTo: bob.did,
|
|
307
298
|
scope: permissionScope // explicity as any to test the validation
|
|
308
299
|
});
|
|
309
|
-
|
|
310
|
-
})
|
|
311
|
-
it('should fail if an invalid protocolPath is used during Permissions schema validation', () =>
|
|
312
|
-
const alice =
|
|
313
|
-
const { message, dataBytes } =
|
|
300
|
+
await expect(grantWrite).rejects.toThrow(DwnErrorCode.PermissionsProtocolCreateGrantRecordsScopeMissingProtocol);
|
|
301
|
+
});
|
|
302
|
+
it('should fail if an invalid protocolPath is used during Permissions schema validation', async () => {
|
|
303
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
304
|
+
const { message, dataBytes } = await TestDataGenerator.generateRecordsWrite({
|
|
314
305
|
author: alice,
|
|
315
306
|
protocol: PermissionsProtocol.uri,
|
|
316
307
|
protocolPath: 'invalid/path',
|
|
317
308
|
data: Encoder.stringToBytes(JSON.stringify({}))
|
|
318
309
|
});
|
|
319
310
|
expect(() => PermissionsProtocol.validateSchema(message, dataBytes)).toThrow(DwnErrorCode.PermissionsProtocolValidateSchemaUnexpectedRecord);
|
|
320
|
-
})
|
|
321
|
-
it('performs additional validation to the tagged protocol in a Revocation message ensuring it matches the Grant it is revoking', () =>
|
|
311
|
+
});
|
|
312
|
+
it('performs additional validation to the tagged protocol in a Revocation message ensuring it matches the Grant it is revoking', async () => {
|
|
322
313
|
// scenario:
|
|
323
314
|
// Alice creates a grant scoped to a protocol.
|
|
324
315
|
// Alice then tries to revoke the grant without a protocol set, it should fail.
|
|
325
316
|
// Alice then tries to revoke the grant with an invalid protocol, it should fail.
|
|
326
317
|
// Alice finally tries to revoke the grant with a valid protocol, it should succeed.
|
|
327
|
-
const alice =
|
|
328
|
-
const bob =
|
|
318
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
319
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
329
320
|
const grantProtocol = 'https://example.com/protocol/test';
|
|
330
321
|
const invalidProtocol = 'https://example.com/protocol/invalid';
|
|
331
322
|
// alice creates a grant for bob
|
|
332
|
-
const grantWrite =
|
|
323
|
+
const grantWrite = await PermissionsProtocol.createGrant({
|
|
333
324
|
signer: Jws.createSigner(alice),
|
|
334
325
|
dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
|
|
335
326
|
description: 'Allow Bob to write',
|
|
@@ -340,13 +331,13 @@ export function testPermissions() {
|
|
|
340
331
|
protocol: grantProtocol,
|
|
341
332
|
}
|
|
342
333
|
});
|
|
343
|
-
const grantWriteReply =
|
|
334
|
+
const grantWriteReply = await dwn.processMessage(alice.did, grantWrite.recordsWrite.message, {
|
|
344
335
|
dataStream: DataStream.fromBytes(grantWrite.permissionGrantBytes)
|
|
345
336
|
});
|
|
346
337
|
expect(grantWriteReply.status.code).toBe(202);
|
|
347
338
|
// attempt to revoke the grant without a protocol set
|
|
348
339
|
const permissionRevocationBytes = Encoder.objectToBytes({ description: 'Revoking the grant' });
|
|
349
|
-
const revokeWithoutProtocolRecordsWrite =
|
|
340
|
+
const revokeWithoutProtocolRecordsWrite = await RecordsWrite.create({
|
|
350
341
|
signer: Jws.createSigner(alice),
|
|
351
342
|
parentContextId: grantWrite.dataEncodedMessage.recordId,
|
|
352
343
|
protocol: PermissionsProtocol.uri,
|
|
@@ -354,14 +345,14 @@ export function testPermissions() {
|
|
|
354
345
|
dataFormat: 'application/json',
|
|
355
346
|
data: permissionRevocationBytes,
|
|
356
347
|
});
|
|
357
|
-
const revokeWriteWithoutProtocolReply =
|
|
348
|
+
const revokeWriteWithoutProtocolReply = await dwn.processMessage(alice.did, revokeWithoutProtocolRecordsWrite.message, {
|
|
358
349
|
dataStream: DataStream.fromBytes(permissionRevocationBytes)
|
|
359
350
|
});
|
|
360
351
|
expect(revokeWriteWithoutProtocolReply.status.code).toBe(400);
|
|
361
352
|
expect(revokeWriteWithoutProtocolReply.status.detail).toContain(DwnErrorCode.PermissionsProtocolValidateRevocationProtocolTagMismatch);
|
|
362
353
|
expect(revokeWriteWithoutProtocolReply.status.detail).toContain(`Revocation protocol undefined does not match grant protocol ${grantProtocol}`);
|
|
363
354
|
// revoke the grant with an invalid protocol
|
|
364
|
-
const revokeWriteWithMissMatchedProtocol =
|
|
355
|
+
const revokeWriteWithMissMatchedProtocol = await RecordsWrite.create({
|
|
365
356
|
signer: Jws.createSigner(alice),
|
|
366
357
|
parentContextId: grantWrite.dataEncodedMessage.recordId,
|
|
367
358
|
protocol: PermissionsProtocol.uri,
|
|
@@ -370,14 +361,14 @@ export function testPermissions() {
|
|
|
370
361
|
data: permissionRevocationBytes,
|
|
371
362
|
tags: { protocol: invalidProtocol }
|
|
372
363
|
});
|
|
373
|
-
const revokeWriteWithMissMatchedProtocolReply =
|
|
364
|
+
const revokeWriteWithMissMatchedProtocolReply = await dwn.processMessage(alice.did, revokeWriteWithMissMatchedProtocol.message, {
|
|
374
365
|
dataStream: DataStream.fromBytes(permissionRevocationBytes)
|
|
375
366
|
});
|
|
376
367
|
expect(revokeWriteWithMissMatchedProtocolReply.status.code).toBe(400);
|
|
377
368
|
expect(revokeWriteWithMissMatchedProtocolReply.status.detail).toContain(DwnErrorCode.PermissionsProtocolValidateRevocationProtocolTagMismatch);
|
|
378
369
|
expect(revokeWriteWithMissMatchedProtocolReply.status.detail).toContain(`Revocation protocol ${invalidProtocol} does not match grant protocol ${grantProtocol}`);
|
|
379
370
|
// revoke the grant with a valid protocol
|
|
380
|
-
const revokeWrite =
|
|
371
|
+
const revokeWrite = await RecordsWrite.create({
|
|
381
372
|
signer: Jws.createSigner(alice),
|
|
382
373
|
parentContextId: grantWrite.dataEncodedMessage.recordId,
|
|
383
374
|
protocol: PermissionsProtocol.uri,
|
|
@@ -386,18 +377,18 @@ export function testPermissions() {
|
|
|
386
377
|
data: permissionRevocationBytes,
|
|
387
378
|
tags: { protocol: grantProtocol }
|
|
388
379
|
});
|
|
389
|
-
const revokeWriteReply =
|
|
380
|
+
const revokeWriteReply = await dwn.processMessage(alice.did, revokeWrite.message, {
|
|
390
381
|
dataStream: DataStream.fromBytes(permissionRevocationBytes)
|
|
391
382
|
});
|
|
392
383
|
expect(revokeWriteReply.status.code).toBe(202);
|
|
393
|
-
})
|
|
384
|
+
});
|
|
394
385
|
// These set of tets are primarily to ensure SchemaValidation passes for the various permission request and grant messages and their scopes
|
|
395
386
|
describe('ensure loaded scope properties for permission requests are processed', () => {
|
|
396
|
-
it('MessagesRead', () =>
|
|
397
|
-
const alice =
|
|
398
|
-
const bob =
|
|
387
|
+
it('MessagesRead', async () => {
|
|
388
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
389
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
399
390
|
// create a permission grant with protocol
|
|
400
|
-
const messagesReadPermissions =
|
|
391
|
+
const messagesReadPermissions = await PermissionsProtocol.createGrant({
|
|
401
392
|
signer: Jws.createSigner(alice),
|
|
402
393
|
grantedTo: bob.did,
|
|
403
394
|
dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
|
|
@@ -408,16 +399,16 @@ export function testPermissions() {
|
|
|
408
399
|
protocol: 'https://example.com/protocol/test',
|
|
409
400
|
}
|
|
410
401
|
});
|
|
411
|
-
const messagesReadPermissionsReply =
|
|
402
|
+
const messagesReadPermissionsReply = await dwn.processMessage(alice.did, messagesReadPermissions.recordsWrite.message, {
|
|
412
403
|
dataStream: DataStream.fromBytes(messagesReadPermissions.permissionGrantBytes)
|
|
413
404
|
});
|
|
414
405
|
expect(messagesReadPermissionsReply.status.code).toBe(202);
|
|
415
|
-
})
|
|
416
|
-
it('MessagesSubscribe', () =>
|
|
417
|
-
const alice =
|
|
418
|
-
const bob =
|
|
406
|
+
});
|
|
407
|
+
it('MessagesSubscribe', async () => {
|
|
408
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
409
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
419
410
|
// create a permission grant with protocol
|
|
420
|
-
const messagesSubscribePermissions =
|
|
411
|
+
const messagesSubscribePermissions = await PermissionsProtocol.createGrant({
|
|
421
412
|
signer: Jws.createSigner(alice),
|
|
422
413
|
grantedTo: bob.did,
|
|
423
414
|
dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
|
|
@@ -428,16 +419,16 @@ export function testPermissions() {
|
|
|
428
419
|
protocol: 'https://example.com/protocol/test',
|
|
429
420
|
}
|
|
430
421
|
});
|
|
431
|
-
const messagesSubscribePermissionsReply =
|
|
422
|
+
const messagesSubscribePermissionsReply = await dwn.processMessage(alice.did, messagesSubscribePermissions.recordsWrite.message, {
|
|
432
423
|
dataStream: DataStream.fromBytes(messagesSubscribePermissions.permissionGrantBytes)
|
|
433
424
|
});
|
|
434
425
|
expect(messagesSubscribePermissionsReply.status.code).toBe(202);
|
|
435
|
-
})
|
|
436
|
-
it('RecordsDelete', () =>
|
|
437
|
-
const alice =
|
|
438
|
-
const bob =
|
|
426
|
+
});
|
|
427
|
+
it('RecordsDelete', async () => {
|
|
428
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
429
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
439
430
|
// create a permission grant with protocol and contextId
|
|
440
|
-
const withContextId =
|
|
431
|
+
const withContextId = await PermissionsProtocol.createGrant({
|
|
441
432
|
signer: Jws.createSigner(alice),
|
|
442
433
|
grantedTo: bob.did,
|
|
443
434
|
dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
|
|
@@ -449,12 +440,12 @@ export function testPermissions() {
|
|
|
449
440
|
contextId: 'test-context'
|
|
450
441
|
}
|
|
451
442
|
});
|
|
452
|
-
const withContextIdReply =
|
|
443
|
+
const withContextIdReply = await dwn.processMessage(alice.did, withContextId.recordsWrite.message, {
|
|
453
444
|
dataStream: DataStream.fromBytes(withContextId.permissionGrantBytes)
|
|
454
445
|
});
|
|
455
446
|
expect(withContextIdReply.status.code).toBe(202);
|
|
456
447
|
// create a permission request with protocol and protocolPath
|
|
457
|
-
const withProtocolPath =
|
|
448
|
+
const withProtocolPath = await PermissionsProtocol.createGrant({
|
|
458
449
|
signer: Jws.createSigner(alice),
|
|
459
450
|
grantedTo: bob.did,
|
|
460
451
|
dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
|
|
@@ -466,16 +457,16 @@ export function testPermissions() {
|
|
|
466
457
|
protocolPath: 'foo/bar'
|
|
467
458
|
}
|
|
468
459
|
});
|
|
469
|
-
const withProtocolPathReply =
|
|
460
|
+
const withProtocolPathReply = await dwn.processMessage(alice.did, withProtocolPath.recordsWrite.message, {
|
|
470
461
|
dataStream: DataStream.fromBytes(withProtocolPath.permissionGrantBytes)
|
|
471
462
|
});
|
|
472
463
|
expect(withProtocolPathReply.status.code).toBe(202);
|
|
473
|
-
})
|
|
474
|
-
it('RecordsQuery', () =>
|
|
475
|
-
const alice =
|
|
476
|
-
const bob =
|
|
464
|
+
});
|
|
465
|
+
it('RecordsQuery', async () => {
|
|
466
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
467
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
477
468
|
// create a permission grant with protocol and contextId scope
|
|
478
|
-
const withContextId =
|
|
469
|
+
const withContextId = await PermissionsProtocol.createGrant({
|
|
479
470
|
signer: Jws.createSigner(alice),
|
|
480
471
|
grantedTo: bob.did,
|
|
481
472
|
dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
|
|
@@ -488,12 +479,12 @@ export function testPermissions() {
|
|
|
488
479
|
contextId: 'test-context'
|
|
489
480
|
}
|
|
490
481
|
});
|
|
491
|
-
const withContextIdReply =
|
|
482
|
+
const withContextIdReply = await dwn.processMessage(alice.did, withContextId.recordsWrite.message, {
|
|
492
483
|
dataStream: DataStream.fromBytes(withContextId.permissionGrantBytes)
|
|
493
484
|
});
|
|
494
485
|
expect(withContextIdReply.status.code).toBe(202);
|
|
495
486
|
// create a permission request with protocol and protocolPath scope
|
|
496
|
-
const withProtocolPath =
|
|
487
|
+
const withProtocolPath = await PermissionsProtocol.createRequest({
|
|
497
488
|
signer: Jws.createSigner(bob),
|
|
498
489
|
description: 'Requesting to query from Alice foo/bar',
|
|
499
490
|
delegated: true,
|
|
@@ -504,16 +495,16 @@ export function testPermissions() {
|
|
|
504
495
|
protocolPath: 'foo/bar'
|
|
505
496
|
}
|
|
506
497
|
});
|
|
507
|
-
const withProtocolPathReply =
|
|
498
|
+
const withProtocolPathReply = await dwn.processMessage(bob.did, withProtocolPath.recordsWrite.message, {
|
|
508
499
|
dataStream: DataStream.fromBytes(withProtocolPath.permissionRequestBytes)
|
|
509
500
|
});
|
|
510
501
|
expect(withProtocolPathReply.status.code).toBe(202);
|
|
511
|
-
})
|
|
512
|
-
it('RecordsRead', () =>
|
|
513
|
-
const alice =
|
|
514
|
-
const bob =
|
|
502
|
+
});
|
|
503
|
+
it('RecordsRead', async () => {
|
|
504
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
505
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
515
506
|
// create a permission grant with protocol and contextId scope
|
|
516
|
-
const withContextId =
|
|
507
|
+
const withContextId = await PermissionsProtocol.createGrant({
|
|
517
508
|
signer: Jws.createSigner(alice),
|
|
518
509
|
grantedTo: bob.did,
|
|
519
510
|
dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
|
|
@@ -526,12 +517,12 @@ export function testPermissions() {
|
|
|
526
517
|
contextId: 'test-context'
|
|
527
518
|
}
|
|
528
519
|
});
|
|
529
|
-
const withContextIdReply =
|
|
520
|
+
const withContextIdReply = await dwn.processMessage(alice.did, withContextId.recordsWrite.message, {
|
|
530
521
|
dataStream: DataStream.fromBytes(withContextId.permissionGrantBytes)
|
|
531
522
|
});
|
|
532
523
|
expect(withContextIdReply.status.code).toBe(202);
|
|
533
524
|
// create a permission request with protocol and protocolPath scope
|
|
534
|
-
const withProtocolPath =
|
|
525
|
+
const withProtocolPath = await PermissionsProtocol.createGrant({
|
|
535
526
|
signer: Jws.createSigner(alice),
|
|
536
527
|
grantedTo: bob.did,
|
|
537
528
|
dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
|
|
@@ -544,16 +535,16 @@ export function testPermissions() {
|
|
|
544
535
|
protocolPath: 'foo/bar'
|
|
545
536
|
}
|
|
546
537
|
});
|
|
547
|
-
const withProtocolPathReply =
|
|
538
|
+
const withProtocolPathReply = await dwn.processMessage(alice.did, withProtocolPath.recordsWrite.message, {
|
|
548
539
|
dataStream: DataStream.fromBytes(withProtocolPath.permissionGrantBytes)
|
|
549
540
|
});
|
|
550
541
|
expect(withProtocolPathReply.status.code).toBe(202);
|
|
551
|
-
})
|
|
552
|
-
it('RecordsSubscribe', () =>
|
|
553
|
-
const alice =
|
|
554
|
-
const bob =
|
|
542
|
+
});
|
|
543
|
+
it('RecordsSubscribe', async () => {
|
|
544
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
545
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
555
546
|
// create a permission grant with protocol and contextId scope
|
|
556
|
-
const withContextId =
|
|
547
|
+
const withContextId = await PermissionsProtocol.createGrant({
|
|
557
548
|
signer: Jws.createSigner(alice),
|
|
558
549
|
grantedTo: bob.did,
|
|
559
550
|
dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
|
|
@@ -566,12 +557,12 @@ export function testPermissions() {
|
|
|
566
557
|
contextId: 'test-context'
|
|
567
558
|
}
|
|
568
559
|
});
|
|
569
|
-
const withContextIdReply =
|
|
560
|
+
const withContextIdReply = await dwn.processMessage(alice.did, withContextId.recordsWrite.message, {
|
|
570
561
|
dataStream: DataStream.fromBytes(withContextId.permissionGrantBytes)
|
|
571
562
|
});
|
|
572
563
|
expect(withContextIdReply.status.code).toBe(202);
|
|
573
564
|
// create a permission request with protocol and protocolPath scope
|
|
574
|
-
const withProtocolPath =
|
|
565
|
+
const withProtocolPath = await PermissionsProtocol.createGrant({
|
|
575
566
|
signer: Jws.createSigner(alice),
|
|
576
567
|
grantedTo: bob.did,
|
|
577
568
|
dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
|
|
@@ -584,16 +575,16 @@ export function testPermissions() {
|
|
|
584
575
|
protocolPath: 'foo/bar'
|
|
585
576
|
}
|
|
586
577
|
});
|
|
587
|
-
const withProtocolPathReply =
|
|
578
|
+
const withProtocolPathReply = await dwn.processMessage(alice.did, withProtocolPath.recordsWrite.message, {
|
|
588
579
|
dataStream: DataStream.fromBytes(withProtocolPath.permissionGrantBytes)
|
|
589
580
|
});
|
|
590
581
|
expect(withProtocolPathReply.status.code).toBe(202);
|
|
591
|
-
})
|
|
592
|
-
it('RecordsWrite', () =>
|
|
593
|
-
const alice =
|
|
594
|
-
const bob =
|
|
582
|
+
});
|
|
583
|
+
it('RecordsWrite', async () => {
|
|
584
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
585
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
595
586
|
// create a permission grant with protocol and contextId scope
|
|
596
|
-
const withContextId =
|
|
587
|
+
const withContextId = await PermissionsProtocol.createGrant({
|
|
597
588
|
signer: Jws.createSigner(alice),
|
|
598
589
|
grantedTo: bob.did,
|
|
599
590
|
dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
|
|
@@ -606,12 +597,12 @@ export function testPermissions() {
|
|
|
606
597
|
contextId: 'test-context'
|
|
607
598
|
}
|
|
608
599
|
});
|
|
609
|
-
const withContextIdReply =
|
|
600
|
+
const withContextIdReply = await dwn.processMessage(alice.did, withContextId.recordsWrite.message, {
|
|
610
601
|
dataStream: DataStream.fromBytes(withContextId.permissionGrantBytes)
|
|
611
602
|
});
|
|
612
603
|
expect(withContextIdReply.status.code).toBe(202);
|
|
613
604
|
// create a permission request with protocol and protocolPath scope
|
|
614
|
-
const withProtocolPath =
|
|
605
|
+
const withProtocolPath = await PermissionsProtocol.createGrant({
|
|
615
606
|
signer: Jws.createSigner(alice),
|
|
616
607
|
grantedTo: bob.did,
|
|
617
608
|
dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
|
|
@@ -624,16 +615,16 @@ export function testPermissions() {
|
|
|
624
615
|
protocolPath: 'foo/bar'
|
|
625
616
|
}
|
|
626
617
|
});
|
|
627
|
-
const withProtocolPathReply =
|
|
618
|
+
const withProtocolPathReply = await dwn.processMessage(alice.did, withProtocolPath.recordsWrite.message, {
|
|
628
619
|
dataStream: DataStream.fromBytes(withProtocolPath.permissionGrantBytes)
|
|
629
620
|
});
|
|
630
621
|
expect(withProtocolPathReply.status.code).toBe(202);
|
|
631
|
-
})
|
|
632
|
-
it('ProtocolsQuery', () =>
|
|
633
|
-
const alice =
|
|
634
|
-
const bob =
|
|
622
|
+
});
|
|
623
|
+
it('ProtocolsQuery', async () => {
|
|
624
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
625
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
635
626
|
// create a permission grant with protocol query that is unrestricted
|
|
636
|
-
const protocolQueryPermissions =
|
|
627
|
+
const protocolQueryPermissions = await PermissionsProtocol.createGrant({
|
|
637
628
|
signer: Jws.createSigner(alice),
|
|
638
629
|
grantedTo: bob.did,
|
|
639
630
|
dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
|
|
@@ -643,54 +634,54 @@ export function testPermissions() {
|
|
|
643
634
|
method: DwnMethodName.Query,
|
|
644
635
|
}
|
|
645
636
|
});
|
|
646
|
-
const protocolQueryPermissionsReply =
|
|
637
|
+
const protocolQueryPermissionsReply = await dwn.processMessage(alice.did, protocolQueryPermissions.recordsWrite.message, {
|
|
647
638
|
dataStream: DataStream.fromBytes(protocolQueryPermissions.permissionGrantBytes)
|
|
648
639
|
});
|
|
649
640
|
expect(protocolQueryPermissionsReply.status.code).toBe(202);
|
|
650
|
-
})
|
|
641
|
+
});
|
|
651
642
|
});
|
|
652
643
|
describe('validateScopeAndTags', () => {
|
|
653
|
-
it('should be called for a Request or Grant record', () =>
|
|
644
|
+
it('should be called for a Request or Grant record', async () => {
|
|
654
645
|
// spy on `validateScope`
|
|
655
646
|
const validateScopeSpy = sinon.spy(PermissionsProtocol, 'validateScopeAndTags');
|
|
656
|
-
const alice =
|
|
657
|
-
const bob =
|
|
647
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
648
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
658
649
|
const permissionScope = {
|
|
659
650
|
interface: DwnInterfaceName.Records,
|
|
660
651
|
method: DwnMethodName.Write,
|
|
661
652
|
protocol: 'https://example.com/protocol/test'
|
|
662
653
|
};
|
|
663
654
|
// create a request
|
|
664
|
-
const requestToAlice =
|
|
655
|
+
const requestToAlice = await PermissionsProtocol.createRequest({
|
|
665
656
|
signer: Jws.createSigner(bob),
|
|
666
657
|
description: `Requesting to write to Alice's DWN`,
|
|
667
658
|
delegated: false,
|
|
668
659
|
scope: permissionScope
|
|
669
660
|
});
|
|
670
|
-
const requestToAliceReply =
|
|
661
|
+
const requestToAliceReply = await dwn.processMessage(alice.did, requestToAlice.recordsWrite.message, { dataStream: DataStream.fromBytes(requestToAlice.permissionRequestBytes) });
|
|
671
662
|
expect(requestToAliceReply.status.code).toBe(202);
|
|
672
663
|
expect(validateScopeSpy.calledOnce).toBe(true);
|
|
673
664
|
// create a grant
|
|
674
|
-
const grantedToBob =
|
|
665
|
+
const grantedToBob = await PermissionsProtocol.createGrant({
|
|
675
666
|
signer: Jws.createSigner(alice),
|
|
676
667
|
dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
|
|
677
668
|
description: 'Allow Bob to write',
|
|
678
669
|
grantedTo: bob.did,
|
|
679
670
|
scope: permissionScope
|
|
680
671
|
});
|
|
681
|
-
const grantWriteReply =
|
|
672
|
+
const grantWriteReply = await dwn.processMessage(alice.did, grantedToBob.recordsWrite.message, { dataStream: DataStream.fromBytes(grantedToBob.permissionGrantBytes) });
|
|
682
673
|
expect(grantWriteReply.status.code).toBe(202);
|
|
683
674
|
expect(validateScopeSpy.calledTwice).toBe(true); // called twice, once for the request and once for the grant
|
|
684
|
-
})
|
|
685
|
-
it('should throw if the scope is a RecordsPermissionScope and a protocol tag is not defined on the Request and Grant record', () =>
|
|
686
|
-
const alice =
|
|
675
|
+
});
|
|
676
|
+
it('should throw if the scope is a RecordsPermissionScope and a protocol tag is not defined on the Request and Grant record', async () => {
|
|
677
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
687
678
|
const permissionScope = {
|
|
688
679
|
interface: DwnInterfaceName.Records,
|
|
689
680
|
method: DwnMethodName.Write,
|
|
690
681
|
protocol: 'https://example.com/protocol/test'
|
|
691
682
|
};
|
|
692
683
|
// create a permission request without a protocol tag
|
|
693
|
-
const requestWrite =
|
|
684
|
+
const requestWrite = await TestDataGenerator.generateRecordsWrite({
|
|
694
685
|
author: alice,
|
|
695
686
|
protocol: PermissionsProtocol.uri,
|
|
696
687
|
protocolPath: PermissionsProtocol.requestPath,
|
|
@@ -699,7 +690,7 @@ export function testPermissions() {
|
|
|
699
690
|
});
|
|
700
691
|
expect(() => PermissionsProtocol['validateScopeAndTags'](permissionScope, requestWrite.message)).toThrow(DwnErrorCode.PermissionsProtocolValidateScopeMissingProtocolTag);
|
|
701
692
|
// create a permission grant without a protocol tag
|
|
702
|
-
const grantRecordsWrite =
|
|
693
|
+
const grantRecordsWrite = await TestDataGenerator.generateRecordsWrite({
|
|
703
694
|
author: alice,
|
|
704
695
|
protocol: PermissionsProtocol.uri,
|
|
705
696
|
protocolPath: PermissionsProtocol.grantPath,
|
|
@@ -707,16 +698,16 @@ export function testPermissions() {
|
|
|
707
698
|
tags: { someTag: 'someValue' } // not a protocol tag
|
|
708
699
|
});
|
|
709
700
|
expect(() => PermissionsProtocol['validateScopeAndTags'](permissionScope, grantRecordsWrite.message)).toThrow(DwnErrorCode.PermissionsProtocolValidateScopeMissingProtocolTag);
|
|
710
|
-
})
|
|
711
|
-
it('should throw if the scope is a RecordsPermissionScope and the Request and Grant record has no tags', () =>
|
|
712
|
-
const alice =
|
|
701
|
+
});
|
|
702
|
+
it('should throw if the scope is a RecordsPermissionScope and the Request and Grant record has no tags', async () => {
|
|
703
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
713
704
|
const permissionScope = {
|
|
714
705
|
interface: DwnInterfaceName.Records,
|
|
715
706
|
method: DwnMethodName.Write,
|
|
716
707
|
protocol: 'https://example.com/protocol/test'
|
|
717
708
|
};
|
|
718
709
|
// create a permission request without a protocol tag
|
|
719
|
-
const requestWrite =
|
|
710
|
+
const requestWrite = await TestDataGenerator.generateRecordsWrite({
|
|
720
711
|
author: alice,
|
|
721
712
|
protocol: PermissionsProtocol.uri,
|
|
722
713
|
protocolPath: PermissionsProtocol.requestPath,
|
|
@@ -724,16 +715,16 @@ export function testPermissions() {
|
|
|
724
715
|
});
|
|
725
716
|
expect(() => PermissionsProtocol['validateScopeAndTags'](permissionScope, requestWrite.message)).toThrow(DwnErrorCode.PermissionsProtocolValidateScopeMissingProtocolTag);
|
|
726
717
|
// create a permission grant without a protocol tag
|
|
727
|
-
const grantRecordsWrite =
|
|
718
|
+
const grantRecordsWrite = await TestDataGenerator.generateRecordsWrite({
|
|
728
719
|
author: alice,
|
|
729
720
|
protocol: PermissionsProtocol.uri,
|
|
730
721
|
protocolPath: PermissionsProtocol.grantPath,
|
|
731
722
|
data: Encoder.stringToBytes(JSON.stringify({})),
|
|
732
723
|
});
|
|
733
724
|
expect(() => PermissionsProtocol['validateScopeAndTags'](permissionScope, grantRecordsWrite.message)).toThrow(DwnErrorCode.PermissionsProtocolValidateScopeMissingProtocolTag);
|
|
734
|
-
})
|
|
735
|
-
it('should throw if the protocol tag in the Request and Grant record does not match the protocol defined in the scope', () =>
|
|
736
|
-
const alice =
|
|
725
|
+
});
|
|
726
|
+
it('should throw if the protocol tag in the Request and Grant record does not match the protocol defined in the scope', async () => {
|
|
727
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
737
728
|
// create a permission scope to test against
|
|
738
729
|
const permissionScope = {
|
|
739
730
|
interface: DwnInterfaceName.Records,
|
|
@@ -741,7 +732,7 @@ export function testPermissions() {
|
|
|
741
732
|
protocol: 'https://example.com/protocol/test'
|
|
742
733
|
};
|
|
743
734
|
// create a permission request with a protocol tag that does not match the scope
|
|
744
|
-
const requestWrite =
|
|
735
|
+
const requestWrite = await TestDataGenerator.generateRecordsWrite({
|
|
745
736
|
author: alice,
|
|
746
737
|
protocol: PermissionsProtocol.uri,
|
|
747
738
|
protocolPath: PermissionsProtocol.requestPath,
|
|
@@ -750,7 +741,7 @@ export function testPermissions() {
|
|
|
750
741
|
});
|
|
751
742
|
expect(() => PermissionsProtocol['validateScopeAndTags'](permissionScope, requestWrite.message)).toThrow(DwnErrorCode.PermissionsProtocolValidateScopeProtocolMismatch);
|
|
752
743
|
// create a permission grant with a protocol tag that does not match the scope
|
|
753
|
-
const grantRecordsWrite =
|
|
744
|
+
const grantRecordsWrite = await TestDataGenerator.generateRecordsWrite({
|
|
754
745
|
author: alice,
|
|
755
746
|
protocol: PermissionsProtocol.uri,
|
|
756
747
|
protocolPath: PermissionsProtocol.grantPath,
|
|
@@ -758,9 +749,9 @@ export function testPermissions() {
|
|
|
758
749
|
tags: { protocol: 'https://example.com/protocol/invalid' }
|
|
759
750
|
});
|
|
760
751
|
expect(() => PermissionsProtocol['validateScopeAndTags'](permissionScope, grantRecordsWrite.message)).toThrow(DwnErrorCode.PermissionsProtocolValidateScopeProtocolMismatch);
|
|
761
|
-
})
|
|
762
|
-
it('should throw if protocolPath and contextId are both defined in the scope for a Request and Grant record', () =>
|
|
763
|
-
const alice =
|
|
752
|
+
});
|
|
753
|
+
it('should throw if protocolPath and contextId are both defined in the scope for a Request and Grant record', async () => {
|
|
754
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
764
755
|
const permissionScope = {
|
|
765
756
|
interface: DwnInterfaceName.Records,
|
|
766
757
|
method: DwnMethodName.Write,
|
|
@@ -769,7 +760,7 @@ export function testPermissions() {
|
|
|
769
760
|
contextId: 'test-context'
|
|
770
761
|
};
|
|
771
762
|
// create a permission request with a scope that has both protocolPath and contextId
|
|
772
|
-
const requestRecordsWrite =
|
|
763
|
+
const requestRecordsWrite = await TestDataGenerator.generateRecordsWrite({
|
|
773
764
|
author: alice,
|
|
774
765
|
protocol: PermissionsProtocol.uri,
|
|
775
766
|
protocolPath: PermissionsProtocol.requestPath,
|
|
@@ -778,7 +769,7 @@ export function testPermissions() {
|
|
|
778
769
|
});
|
|
779
770
|
expect(() => PermissionsProtocol['validateScopeAndTags'](permissionScope, requestRecordsWrite.message)).toThrow(DwnErrorCode.PermissionsProtocolValidateScopeContextIdProhibitedProperties);
|
|
780
771
|
// create a permission grant with a scope that has both protocolPath and contextId
|
|
781
|
-
const grantRecordsWrite =
|
|
772
|
+
const grantRecordsWrite = await TestDataGenerator.generateRecordsWrite({
|
|
782
773
|
author: alice,
|
|
783
774
|
protocol: PermissionsProtocol.uri,
|
|
784
775
|
protocolPath: PermissionsProtocol.grantPath,
|
|
@@ -786,7 +777,281 @@ export function testPermissions() {
|
|
|
786
777
|
tags: { protocol: 'https://example.com/protocol/test' }
|
|
787
778
|
});
|
|
788
779
|
expect(() => PermissionsProtocol['validateScopeAndTags'](permissionScope, grantRecordsWrite.message)).toThrow(DwnErrorCode.PermissionsProtocolValidateScopeContextIdProhibitedProperties);
|
|
789
|
-
})
|
|
780
|
+
});
|
|
781
|
+
});
|
|
782
|
+
describe('revocation cleanup', () => {
|
|
783
|
+
it('should delete grant-authorized messages created at or after the revocation timestamp', async () => {
|
|
784
|
+
// scenario:
|
|
785
|
+
// 1. Alice installs a protocol and grants Bob write access
|
|
786
|
+
// 2. Bob writes a record using the grant with a future timestamp
|
|
787
|
+
// 3. Alice revokes the grant (the revocation's messageTimestamp is auto-set to "now")
|
|
788
|
+
// 4. The record Bob wrote with a future dateCreated (>= revocation messageTimestamp) should be deleted
|
|
789
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
790
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
791
|
+
const protocolDefinition = minimalProtocolDefinition;
|
|
792
|
+
// Alice installs the protocol
|
|
793
|
+
const protocolsConfig = await TestDataGenerator.generateProtocolsConfigure({
|
|
794
|
+
author: alice,
|
|
795
|
+
protocolDefinition,
|
|
796
|
+
});
|
|
797
|
+
const protocolsConfigureReply = await dwn.processMessage(alice.did, protocolsConfig.message);
|
|
798
|
+
expect(protocolsConfigureReply.status.code).toBe(202);
|
|
799
|
+
// Alice grants Bob write permission
|
|
800
|
+
const permissionGrant = await PermissionsProtocol.createGrant({
|
|
801
|
+
signer: Jws.createSigner(alice),
|
|
802
|
+
grantedTo: bob.did,
|
|
803
|
+
dateExpires: Time.createOffsetTimestamp({ seconds: 60 * 60 * 24 }),
|
|
804
|
+
scope: {
|
|
805
|
+
interface: DwnInterfaceName.Records,
|
|
806
|
+
method: DwnMethodName.Write,
|
|
807
|
+
protocol: protocolDefinition.protocol,
|
|
808
|
+
}
|
|
809
|
+
});
|
|
810
|
+
const grantWriteReply = await dwn.processMessage(alice.did, permissionGrant.recordsWrite.message, { dataStream: DataStream.fromBytes(permissionGrant.permissionGrantBytes) });
|
|
811
|
+
expect(grantWriteReply.status.code).toBe(202);
|
|
812
|
+
// Bob writes a record using the grant with a future timestamp (guaranteed >= any revocation messageTimestamp)
|
|
813
|
+
const futureTimestamp = Time.createOffsetTimestamp({ seconds: 60 });
|
|
814
|
+
const { recordsWrite, dataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
815
|
+
author: bob,
|
|
816
|
+
protocol: protocolDefinition.protocol,
|
|
817
|
+
protocolPath: 'foo',
|
|
818
|
+
permissionGrantId: permissionGrant.recordsWrite.message.recordId,
|
|
819
|
+
dateCreated: futureTimestamp,
|
|
820
|
+
messageTimestamp: futureTimestamp,
|
|
821
|
+
});
|
|
822
|
+
const writeReply = await dwn.processMessage(alice.did, recordsWrite.message, { dataStream });
|
|
823
|
+
expect(writeReply.status.code).toBe(202);
|
|
824
|
+
// Verify the record exists before revocation
|
|
825
|
+
const queryBefore = await RecordsQuery.create({
|
|
826
|
+
signer: Jws.createSigner(alice),
|
|
827
|
+
filter: { protocol: protocolDefinition.protocol },
|
|
828
|
+
});
|
|
829
|
+
const queryBeforeReply = await dwn.processMessage(alice.did, queryBefore.message);
|
|
830
|
+
expect(queryBeforeReply.status.code).toBe(200);
|
|
831
|
+
expect(queryBeforeReply.entries.length).toBe(1);
|
|
832
|
+
// Alice revokes the grant (messageTimestamp is auto-set to current time, which is before futureTimestamp)
|
|
833
|
+
const revokeWrite = await PermissionsProtocol.createRevocation({
|
|
834
|
+
signer: Jws.createSigner(alice),
|
|
835
|
+
grant: PermissionGrant.parse(permissionGrant.dataEncodedMessage),
|
|
836
|
+
});
|
|
837
|
+
const revokeReply = await dwn.processMessage(alice.did, revokeWrite.recordsWrite.message, { dataStream: DataStream.fromBytes(revokeWrite.permissionRevocationBytes) });
|
|
838
|
+
expect(revokeReply.status.code).toBe(202);
|
|
839
|
+
// The grant-authorized record should have been deleted by revocation cleanup
|
|
840
|
+
const queryAfter = await RecordsQuery.create({
|
|
841
|
+
signer: Jws.createSigner(alice),
|
|
842
|
+
filter: { protocol: protocolDefinition.protocol },
|
|
843
|
+
});
|
|
844
|
+
const queryAfterReply = await dwn.processMessage(alice.did, queryAfter.message);
|
|
845
|
+
expect(queryAfterReply.status.code).toBe(200);
|
|
846
|
+
expect(queryAfterReply.entries.length).toBe(0);
|
|
847
|
+
});
|
|
848
|
+
it('should not delete grant-authorized messages created before the revocation timestamp', async () => {
|
|
849
|
+
// scenario:
|
|
850
|
+
// 1. Alice installs a protocol and grants Bob write access
|
|
851
|
+
// 2. Bob writes a record using the grant (dateCreated is "now")
|
|
852
|
+
// 3. Alice revokes the grant (messageTimestamp is auto-set to a slightly later "now")
|
|
853
|
+
// 4. The record Bob wrote before the revocation should NOT be deleted
|
|
854
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
855
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
856
|
+
const protocolDefinition = minimalProtocolDefinition;
|
|
857
|
+
// Alice installs the protocol
|
|
858
|
+
const protocolsConfig = await TestDataGenerator.generateProtocolsConfigure({
|
|
859
|
+
author: alice,
|
|
860
|
+
protocolDefinition,
|
|
861
|
+
});
|
|
862
|
+
const protocolsConfigureReply = await dwn.processMessage(alice.did, protocolsConfig.message);
|
|
863
|
+
expect(protocolsConfigureReply.status.code).toBe(202);
|
|
864
|
+
// Alice grants Bob write permission
|
|
865
|
+
const permissionGrant = await PermissionsProtocol.createGrant({
|
|
866
|
+
signer: Jws.createSigner(alice),
|
|
867
|
+
grantedTo: bob.did,
|
|
868
|
+
dateExpires: Time.createOffsetTimestamp({ seconds: 60 * 60 * 24 }),
|
|
869
|
+
scope: {
|
|
870
|
+
interface: DwnInterfaceName.Records,
|
|
871
|
+
method: DwnMethodName.Write,
|
|
872
|
+
protocol: protocolDefinition.protocol,
|
|
873
|
+
}
|
|
874
|
+
});
|
|
875
|
+
const grantWriteReply = await dwn.processMessage(alice.did, permissionGrant.recordsWrite.message, { dataStream: DataStream.fromBytes(permissionGrant.permissionGrantBytes) });
|
|
876
|
+
expect(grantWriteReply.status.code).toBe(202);
|
|
877
|
+
// Bob writes a record using the grant (dateCreated defaults to current time)
|
|
878
|
+
const { recordsWrite, dataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
879
|
+
author: bob,
|
|
880
|
+
protocol: protocolDefinition.protocol,
|
|
881
|
+
protocolPath: 'foo',
|
|
882
|
+
permissionGrantId: permissionGrant.recordsWrite.message.recordId,
|
|
883
|
+
});
|
|
884
|
+
const writeReply = await dwn.processMessage(alice.did, recordsWrite.message, { dataStream });
|
|
885
|
+
expect(writeReply.status.code).toBe(202);
|
|
886
|
+
// Alice revokes the grant (messageTimestamp is auto-set slightly after the record's dateCreated)
|
|
887
|
+
const revokeWrite = await PermissionsProtocol.createRevocation({
|
|
888
|
+
signer: Jws.createSigner(alice),
|
|
889
|
+
grant: PermissionGrant.parse(permissionGrant.dataEncodedMessage),
|
|
890
|
+
});
|
|
891
|
+
const revokeReply = await dwn.processMessage(alice.did, revokeWrite.recordsWrite.message, { dataStream: DataStream.fromBytes(revokeWrite.permissionRevocationBytes) });
|
|
892
|
+
expect(revokeReply.status.code).toBe(202);
|
|
893
|
+
// The record Bob wrote before the revocation should still exist
|
|
894
|
+
const queryAfter = await RecordsQuery.create({
|
|
895
|
+
signer: Jws.createSigner(alice),
|
|
896
|
+
filter: { protocol: protocolDefinition.protocol },
|
|
897
|
+
});
|
|
898
|
+
const queryAfterReply = await dwn.processMessage(alice.did, queryAfter.message);
|
|
899
|
+
expect(queryAfterReply.status.code).toBe(200);
|
|
900
|
+
expect(queryAfterReply.entries.length).toBe(1);
|
|
901
|
+
});
|
|
902
|
+
it('should delete data from the data store for large records when revoking a grant', async () => {
|
|
903
|
+
// scenario:
|
|
904
|
+
// 1. Alice installs a protocol and grants Bob write access
|
|
905
|
+
// 2. Bob writes a record with data larger than maxDataSizeAllowedToBeEncoded (30KB)
|
|
906
|
+
// 3. Alice revokes the grant
|
|
907
|
+
// 4. Both the message and the data blob should be deleted
|
|
908
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
909
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
910
|
+
const protocolDefinition = minimalProtocolDefinition;
|
|
911
|
+
// Alice installs the protocol
|
|
912
|
+
const protocolsConfig = await TestDataGenerator.generateProtocolsConfigure({
|
|
913
|
+
author: alice,
|
|
914
|
+
protocolDefinition,
|
|
915
|
+
});
|
|
916
|
+
const protocolsConfigureReply = await dwn.processMessage(alice.did, protocolsConfig.message);
|
|
917
|
+
expect(protocolsConfigureReply.status.code).toBe(202);
|
|
918
|
+
// Alice grants Bob write permission
|
|
919
|
+
const permissionGrant = await PermissionsProtocol.createGrant({
|
|
920
|
+
signer: Jws.createSigner(alice),
|
|
921
|
+
grantedTo: bob.did,
|
|
922
|
+
dateExpires: Time.createOffsetTimestamp({ seconds: 60 * 60 * 24 }),
|
|
923
|
+
scope: {
|
|
924
|
+
interface: DwnInterfaceName.Records,
|
|
925
|
+
method: DwnMethodName.Write,
|
|
926
|
+
protocol: protocolDefinition.protocol,
|
|
927
|
+
}
|
|
928
|
+
});
|
|
929
|
+
const grantWriteReply = await dwn.processMessage(alice.did, permissionGrant.recordsWrite.message, { dataStream: DataStream.fromBytes(permissionGrant.permissionGrantBytes) });
|
|
930
|
+
expect(grantWriteReply.status.code).toBe(202);
|
|
931
|
+
// Bob writes a record with large data (> 30KB) using the grant, with a future timestamp
|
|
932
|
+
const futureTimestamp = Time.createOffsetTimestamp({ seconds: 60 });
|
|
933
|
+
const largeData = TestDataGenerator.randomBytes(40_000);
|
|
934
|
+
const { recordsWrite, dataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
935
|
+
author: bob,
|
|
936
|
+
protocol: protocolDefinition.protocol,
|
|
937
|
+
protocolPath: 'foo',
|
|
938
|
+
data: largeData,
|
|
939
|
+
permissionGrantId: permissionGrant.recordsWrite.message.recordId,
|
|
940
|
+
dateCreated: futureTimestamp,
|
|
941
|
+
messageTimestamp: futureTimestamp,
|
|
942
|
+
});
|
|
943
|
+
const writeReply = await dwn.processMessage(alice.did, recordsWrite.message, { dataStream });
|
|
944
|
+
expect(writeReply.status.code).toBe(202);
|
|
945
|
+
// Verify the data exists in the data store before revocation
|
|
946
|
+
const dataResult = await dataStore.get(alice.did, recordsWrite.message.recordId, recordsWrite.message.descriptor.dataCid);
|
|
947
|
+
expect(dataResult).toBeDefined();
|
|
948
|
+
// Alice revokes the grant
|
|
949
|
+
const revokeWrite = await PermissionsProtocol.createRevocation({
|
|
950
|
+
signer: Jws.createSigner(alice),
|
|
951
|
+
grant: PermissionGrant.parse(permissionGrant.dataEncodedMessage),
|
|
952
|
+
});
|
|
953
|
+
const revokeReply = await dwn.processMessage(alice.did, revokeWrite.recordsWrite.message, { dataStream: DataStream.fromBytes(revokeWrite.permissionRevocationBytes) });
|
|
954
|
+
expect(revokeReply.status.code).toBe(202);
|
|
955
|
+
// The record should be deleted from the message store
|
|
956
|
+
const queryAfter = await RecordsQuery.create({
|
|
957
|
+
signer: Jws.createSigner(alice),
|
|
958
|
+
filter: { protocol: protocolDefinition.protocol },
|
|
959
|
+
});
|
|
960
|
+
const queryAfterReply = await dwn.processMessage(alice.did, queryAfter.message);
|
|
961
|
+
expect(queryAfterReply.status.code).toBe(200);
|
|
962
|
+
expect(queryAfterReply.entries.length).toBe(0);
|
|
963
|
+
// The data blob should also be deleted from the data store
|
|
964
|
+
const dataResultAfter = await dataStore.get(alice.did, recordsWrite.message.recordId, recordsWrite.message.descriptor.dataCid);
|
|
965
|
+
expect(dataResultAfter).toBeUndefined();
|
|
966
|
+
});
|
|
967
|
+
it('should delete multiple grant-authorized messages when revoking a grant', async () => {
|
|
968
|
+
// scenario:
|
|
969
|
+
// 1. Alice installs a protocol and grants Bob write access
|
|
970
|
+
// 2. Bob writes three records: one at current time, two with future timestamps
|
|
971
|
+
// 3. Alice revokes the grant (at current time, between the first and future records)
|
|
972
|
+
// 4. The current-time record survives; the two future records are deleted
|
|
973
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
974
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
975
|
+
const protocolDefinition = minimalProtocolDefinition;
|
|
976
|
+
// Alice installs the protocol
|
|
977
|
+
const protocolsConfig = await TestDataGenerator.generateProtocolsConfigure({
|
|
978
|
+
author: alice,
|
|
979
|
+
protocolDefinition,
|
|
980
|
+
});
|
|
981
|
+
const protocolsConfigureReply = await dwn.processMessage(alice.did, protocolsConfig.message);
|
|
982
|
+
expect(protocolsConfigureReply.status.code).toBe(202);
|
|
983
|
+
// Alice grants Bob write permission
|
|
984
|
+
const permissionGrant = await PermissionsProtocol.createGrant({
|
|
985
|
+
signer: Jws.createSigner(alice),
|
|
986
|
+
grantedTo: bob.did,
|
|
987
|
+
dateExpires: Time.createOffsetTimestamp({ seconds: 60 * 60 * 24 }),
|
|
988
|
+
scope: {
|
|
989
|
+
interface: DwnInterfaceName.Records,
|
|
990
|
+
method: DwnMethodName.Write,
|
|
991
|
+
protocol: protocolDefinition.protocol,
|
|
992
|
+
}
|
|
993
|
+
});
|
|
994
|
+
const grantWriteReply = await dwn.processMessage(alice.did, permissionGrant.recordsWrite.message, { dataStream: DataStream.fromBytes(permissionGrant.permissionGrantBytes) });
|
|
995
|
+
expect(grantWriteReply.status.code).toBe(202);
|
|
996
|
+
// Timestamps: future records will be deleted, current-time record will survive
|
|
997
|
+
const futureTimestamp = Time.createOffsetTimestamp({ seconds: 60 });
|
|
998
|
+
const farFutureTimestamp = Time.createOffsetTimestamp({ seconds: 120 });
|
|
999
|
+
// Bob writes record 1 (current time — should survive)
|
|
1000
|
+
const write1 = await TestDataGenerator.generateRecordsWrite({
|
|
1001
|
+
author: bob,
|
|
1002
|
+
protocol: protocolDefinition.protocol,
|
|
1003
|
+
protocolPath: 'foo',
|
|
1004
|
+
permissionGrantId: permissionGrant.recordsWrite.message.recordId,
|
|
1005
|
+
});
|
|
1006
|
+
const write1Reply = await dwn.processMessage(alice.did, write1.recordsWrite.message, { dataStream: write1.dataStream });
|
|
1007
|
+
expect(write1Reply.status.code).toBe(202);
|
|
1008
|
+
// Bob writes record 2 (future — should be deleted)
|
|
1009
|
+
const write2 = await TestDataGenerator.generateRecordsWrite({
|
|
1010
|
+
author: bob,
|
|
1011
|
+
protocol: protocolDefinition.protocol,
|
|
1012
|
+
protocolPath: 'foo',
|
|
1013
|
+
permissionGrantId: permissionGrant.recordsWrite.message.recordId,
|
|
1014
|
+
dateCreated: futureTimestamp,
|
|
1015
|
+
messageTimestamp: futureTimestamp,
|
|
1016
|
+
});
|
|
1017
|
+
const write2Reply = await dwn.processMessage(alice.did, write2.recordsWrite.message, { dataStream: write2.dataStream });
|
|
1018
|
+
expect(write2Reply.status.code).toBe(202);
|
|
1019
|
+
// Bob writes record 3 (far future — should be deleted)
|
|
1020
|
+
const write3 = await TestDataGenerator.generateRecordsWrite({
|
|
1021
|
+
author: bob,
|
|
1022
|
+
protocol: protocolDefinition.protocol,
|
|
1023
|
+
protocolPath: 'foo',
|
|
1024
|
+
permissionGrantId: permissionGrant.recordsWrite.message.recordId,
|
|
1025
|
+
dateCreated: farFutureTimestamp,
|
|
1026
|
+
messageTimestamp: farFutureTimestamp,
|
|
1027
|
+
});
|
|
1028
|
+
const write3Reply = await dwn.processMessage(alice.did, write3.recordsWrite.message, { dataStream: write3.dataStream });
|
|
1029
|
+
expect(write3Reply.status.code).toBe(202);
|
|
1030
|
+
// Verify all 3 records exist before revocation
|
|
1031
|
+
const queryBefore = await RecordsQuery.create({
|
|
1032
|
+
signer: Jws.createSigner(alice),
|
|
1033
|
+
filter: { protocol: protocolDefinition.protocol },
|
|
1034
|
+
});
|
|
1035
|
+
const queryBeforeReply = await dwn.processMessage(alice.did, queryBefore.message);
|
|
1036
|
+
expect(queryBeforeReply.status.code).toBe(200);
|
|
1037
|
+
expect(queryBeforeReply.entries.length).toBe(3);
|
|
1038
|
+
// Alice revokes the grant (messageTimestamp is "now", between record 1 and records 2/3)
|
|
1039
|
+
const revokeWrite = await PermissionsProtocol.createRevocation({
|
|
1040
|
+
signer: Jws.createSigner(alice),
|
|
1041
|
+
grant: PermissionGrant.parse(permissionGrant.dataEncodedMessage),
|
|
1042
|
+
});
|
|
1043
|
+
const revokeReply = await dwn.processMessage(alice.did, revokeWrite.recordsWrite.message, { dataStream: DataStream.fromBytes(revokeWrite.permissionRevocationBytes) });
|
|
1044
|
+
expect(revokeReply.status.code).toBe(202);
|
|
1045
|
+
// Only the record written at current time should remain
|
|
1046
|
+
const queryAfter = await RecordsQuery.create({
|
|
1047
|
+
signer: Jws.createSigner(alice),
|
|
1048
|
+
filter: { protocol: protocolDefinition.protocol },
|
|
1049
|
+
});
|
|
1050
|
+
const queryAfterReply = await dwn.processMessage(alice.did, queryAfter.message);
|
|
1051
|
+
expect(queryAfterReply.status.code).toBe(200);
|
|
1052
|
+
expect(queryAfterReply.entries.length).toBe(1);
|
|
1053
|
+
expect(queryAfterReply.entries[0].recordId).toBe(write1.recordsWrite.message.recordId);
|
|
1054
|
+
});
|
|
790
1055
|
});
|
|
791
1056
|
});
|
|
792
1057
|
}
|