@enbox/dwn-sdk-js 0.0.5 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.mjs +8 -8
- package/dist/browser.mjs.map +4 -4
- package/dist/esm/generated/precompiled-validators.js +1 -2
- package/dist/esm/generated/precompiled-validators.js.map +1 -1
- package/dist/esm/src/core/abstract-message.js +4 -0
- package/dist/esm/src/core/abstract-message.js.map +1 -1
- package/dist/esm/src/core/auth.js +22 -33
- package/dist/esm/src/core/auth.js.map +1 -1
- package/dist/esm/src/core/dwn-constant.js +7 -7
- package/dist/esm/src/core/dwn-constant.js.map +1 -1
- package/dist/esm/src/core/dwn-error.js +1 -0
- package/dist/esm/src/core/dwn-error.js.map +1 -1
- package/dist/esm/src/core/grant-authorization.js +37 -52
- package/dist/esm/src/core/grant-authorization.js.map +1 -1
- package/dist/esm/src/core/message.js +85 -116
- package/dist/esm/src/core/message.js.map +1 -1
- package/dist/esm/src/core/messages-grant-authorization.js +63 -78
- package/dist/esm/src/core/messages-grant-authorization.js.map +1 -1
- package/dist/esm/src/core/protocol-authorization-action.js +266 -0
- package/dist/esm/src/core/protocol-authorization-action.js.map +1 -0
- package/dist/esm/src/core/protocol-authorization-validation.js +254 -0
- package/dist/esm/src/core/protocol-authorization-validation.js.map +1 -0
- package/dist/esm/src/core/protocol-authorization.js +122 -740
- package/dist/esm/src/core/protocol-authorization.js.map +1 -1
- package/dist/esm/src/core/protocols-grant-authorization.js +24 -38
- package/dist/esm/src/core/protocols-grant-authorization.js.map +1 -1
- package/dist/esm/src/core/record-chain.js +64 -0
- package/dist/esm/src/core/record-chain.js.map +1 -0
- package/dist/esm/src/core/records-grant-authorization.js +55 -72
- package/dist/esm/src/core/records-grant-authorization.js.map +1 -1
- package/dist/esm/src/core/resumable-task-manager.js +50 -65
- package/dist/esm/src/core/resumable-task-manager.js.map +1 -1
- package/dist/esm/src/core/tenant-gate.js +2 -13
- package/dist/esm/src/core/tenant-gate.js.map +1 -1
- package/dist/esm/src/dwn.js +69 -86
- package/dist/esm/src/dwn.js.map +1 -1
- package/dist/esm/src/event-stream/event-emitter-stream.js +17 -31
- package/dist/esm/src/event-stream/event-emitter-stream.js.map +1 -1
- package/dist/esm/src/handlers/messages-read.js +67 -77
- package/dist/esm/src/handlers/messages-read.js.map +1 -1
- package/dist/esm/src/handlers/messages-subscribe.js +51 -61
- package/dist/esm/src/handlers/messages-subscribe.js.map +1 -1
- package/dist/esm/src/handlers/messages-sync.js +75 -85
- package/dist/esm/src/handlers/messages-sync.js.map +1 -1
- package/dist/esm/src/handlers/protocols-configure.js +135 -155
- package/dist/esm/src/handlers/protocols-configure.js.map +1 -1
- package/dist/esm/src/handlers/protocols-query.js +52 -51
- package/dist/esm/src/handlers/protocols-query.js.map +1 -1
- package/dist/esm/src/handlers/records-count.js +96 -82
- package/dist/esm/src/handlers/records-count.js.map +1 -1
- package/dist/esm/src/handlers/records-delete.js +78 -88
- package/dist/esm/src/handlers/records-delete.js.map +1 -1
- package/dist/esm/src/handlers/records-query.js +116 -101
- package/dist/esm/src/handlers/records-query.js.map +1 -1
- package/dist/esm/src/handlers/records-read.js +124 -131
- package/dist/esm/src/handlers/records-read.js.map +1 -1
- package/dist/esm/src/handlers/records-subscribe.js +150 -103
- package/dist/esm/src/handlers/records-subscribe.js.map +1 -1
- package/dist/esm/src/handlers/records-write.js +250 -259
- package/dist/esm/src/handlers/records-write.js.map +1 -1
- package/dist/esm/src/interfaces/messages-read.js +24 -32
- package/dist/esm/src/interfaces/messages-read.js.map +1 -1
- package/dist/esm/src/interfaces/messages-subscribe.js +27 -41
- package/dist/esm/src/interfaces/messages-subscribe.js.map +1 -1
- package/dist/esm/src/interfaces/messages-sync.js +26 -40
- package/dist/esm/src/interfaces/messages-sync.js.map +1 -1
- package/dist/esm/src/interfaces/protocols-configure.js +63 -63
- package/dist/esm/src/interfaces/protocols-configure.js.map +1 -1
- package/dist/esm/src/interfaces/protocols-query.js +55 -68
- package/dist/esm/src/interfaces/protocols-query.js.map +1 -1
- package/dist/esm/src/interfaces/records-count.js +50 -66
- package/dist/esm/src/interfaces/records-count.js.map +1 -1
- package/dist/esm/src/interfaces/records-delete.js +45 -55
- package/dist/esm/src/interfaces/records-delete.js.map +1 -1
- package/dist/esm/src/interfaces/records-query.js +60 -76
- package/dist/esm/src/interfaces/records-query.js.map +1 -1
- package/dist/esm/src/interfaces/records-read.js +51 -67
- package/dist/esm/src/interfaces/records-read.js.map +1 -1
- package/dist/esm/src/interfaces/records-subscribe.js +52 -68
- package/dist/esm/src/interfaces/records-subscribe.js.map +1 -1
- package/dist/esm/src/interfaces/records-write-query.js +102 -0
- package/dist/esm/src/interfaces/records-write-query.js.map +1 -0
- package/dist/esm/src/interfaces/records-write-signing.js +92 -0
- package/dist/esm/src/interfaces/records-write-signing.js.map +1 -0
- package/dist/esm/src/interfaces/records-write.js +407 -602
- package/dist/esm/src/interfaces/records-write.js.map +1 -1
- package/dist/esm/src/jose/algorithms/signing/ed25519.js +10 -19
- package/dist/esm/src/jose/algorithms/signing/ed25519.js.map +1 -1
- package/dist/esm/src/jose/jws/general/builder.js +23 -35
- package/dist/esm/src/jose/jws/general/builder.js.map +1 -1
- package/dist/esm/src/jose/jws/general/verifier.js +56 -69
- package/dist/esm/src/jose/jws/general/verifier.js.map +1 -1
- package/dist/esm/src/protocols/permission-grant.js +44 -15
- package/dist/esm/src/protocols/permission-grant.js.map +1 -1
- package/dist/esm/src/protocols/permission-request.js +29 -15
- package/dist/esm/src/protocols/permission-request.js.map +1 -1
- package/dist/esm/src/protocols/permissions.js +216 -226
- package/dist/esm/src/protocols/permissions.js.map +1 -1
- package/dist/esm/src/smt/smt-store-level.js +42 -64
- package/dist/esm/src/smt/smt-store-level.js.map +1 -1
- package/dist/esm/src/smt/smt-store-memory.js +19 -45
- package/dist/esm/src/smt/smt-store-memory.js.map +1 -1
- package/dist/esm/src/smt/smt-utils.js +28 -45
- package/dist/esm/src/smt/smt-utils.js.map +1 -1
- package/dist/esm/src/smt/sparse-merkle-tree.js +426 -471
- package/dist/esm/src/smt/sparse-merkle-tree.js.map +1 -1
- package/dist/esm/src/state-index/state-index-level.js +115 -150
- package/dist/esm/src/state-index/state-index-level.js.map +1 -1
- package/dist/esm/src/store/blockstore-level.js +54 -156
- package/dist/esm/src/store/blockstore-level.js.map +1 -1
- package/dist/esm/src/store/blockstore-mock.js +48 -153
- package/dist/esm/src/store/blockstore-mock.js.map +1 -1
- package/dist/esm/src/store/data-store-level.js +59 -99
- package/dist/esm/src/store/data-store-level.js.map +1 -1
- package/dist/esm/src/store/index-level-compound.js +246 -0
- package/dist/esm/src/store/index-level-compound.js.map +1 -0
- package/dist/esm/src/store/index-level.js +295 -713
- package/dist/esm/src/store/index-level.js.map +1 -1
- package/dist/esm/src/store/level-wrapper.js +143 -244
- package/dist/esm/src/store/level-wrapper.js.map +1 -1
- package/dist/esm/src/store/message-store-level.js +71 -94
- package/dist/esm/src/store/message-store-level.js.map +1 -1
- package/dist/esm/src/store/resumable-task-store-level.js +62 -101
- package/dist/esm/src/store/resumable-task-store-level.js.map +1 -1
- package/dist/esm/src/store/storage-controller.js +129 -144
- package/dist/esm/src/store/storage-controller.js.map +1 -1
- package/dist/esm/src/utils/abort.js +8 -19
- package/dist/esm/src/utils/abort.js.map +1 -1
- package/dist/esm/src/utils/array.js +15 -49
- package/dist/esm/src/utils/array.js.map +1 -1
- package/dist/esm/src/utils/cid.js +29 -77
- package/dist/esm/src/utils/cid.js.map +1 -1
- package/dist/esm/src/utils/data-stream.js +37 -65
- package/dist/esm/src/utils/data-stream.js.map +1 -1
- package/dist/esm/src/utils/encryption.js +136 -162
- package/dist/esm/src/utils/encryption.js.map +1 -1
- package/dist/esm/src/utils/filter.js +1 -12
- package/dist/esm/src/utils/filter.js.map +1 -1
- package/dist/esm/src/utils/hd-key.js +45 -63
- package/dist/esm/src/utils/hd-key.js.map +1 -1
- package/dist/esm/src/utils/jws.js +9 -20
- package/dist/esm/src/utils/jws.js.map +1 -1
- package/dist/esm/src/utils/memory-cache.js +12 -23
- package/dist/esm/src/utils/memory-cache.js.map +1 -1
- package/dist/esm/src/utils/messages.js +9 -3
- package/dist/esm/src/utils/messages.js.map +1 -1
- package/dist/esm/src/utils/private-key-signer.js +9 -17
- package/dist/esm/src/utils/private-key-signer.js.map +1 -1
- package/dist/esm/src/utils/protocols.js +62 -70
- package/dist/esm/src/utils/protocols.js.map +1 -1
- package/dist/esm/src/utils/records.js +108 -140
- package/dist/esm/src/utils/records.js.map +1 -1
- package/dist/esm/src/utils/secp256k1.js +60 -96
- package/dist/esm/src/utils/secp256k1.js.map +1 -1
- package/dist/esm/src/utils/secp256r1.js +54 -71
- package/dist/esm/src/utils/secp256r1.js.map +1 -1
- package/dist/esm/src/utils/time.js +5 -18
- package/dist/esm/src/utils/time.js.map +1 -1
- package/dist/esm/src/utils/url.js +3 -3
- package/dist/esm/src/utils/url.js.map +1 -1
- package/dist/esm/tests/core/auth.spec.js +3 -12
- package/dist/esm/tests/core/auth.spec.js.map +1 -1
- package/dist/esm/tests/core/message.spec.js +50 -59
- package/dist/esm/tests/core/message.spec.js.map +1 -1
- package/dist/esm/tests/core/protocol-authorization.spec.js +9 -18
- package/dist/esm/tests/core/protocol-authorization.spec.js.map +1 -1
- package/dist/esm/tests/dwn.spec.js +45 -58
- package/dist/esm/tests/dwn.spec.js.map +1 -1
- package/dist/esm/tests/event-stream/event-emitter-stream.spec.js +24 -33
- package/dist/esm/tests/event-stream/event-emitter-stream.spec.js.map +1 -1
- package/dist/esm/tests/event-stream/event-stream.spec.js +46 -55
- package/dist/esm/tests/event-stream/event-stream.spec.js.map +1 -1
- package/dist/esm/tests/features/author-delegated-grant.spec.js +326 -343
- package/dist/esm/tests/features/author-delegated-grant.spec.js.map +1 -1
- package/dist/esm/tests/features/owner-delegated-grant.spec.js +153 -169
- package/dist/esm/tests/features/owner-delegated-grant.spec.js.map +1 -1
- package/dist/esm/tests/features/owner-signature.spec.js +67 -78
- package/dist/esm/tests/features/owner-signature.spec.js.map +1 -1
- package/dist/esm/tests/features/permissions.spec.js +446 -181
- package/dist/esm/tests/features/permissions.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-composition.spec.js +346 -356
- package/dist/esm/tests/features/protocol-composition.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-create-action.spec.js +42 -51
- package/dist/esm/tests/features/protocol-create-action.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-delete-action.spec.js +94 -103
- package/dist/esm/tests/features/protocol-delete-action.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-update-action.spec.js +105 -114
- package/dist/esm/tests/features/protocol-update-action.spec.js.map +1 -1
- package/dist/esm/tests/features/records-prune.spec.js +175 -191
- package/dist/esm/tests/features/records-prune.spec.js.map +1 -1
- package/dist/esm/tests/features/records-tags.spec.js +441 -460
- package/dist/esm/tests/features/records-tags.spec.js.map +1 -1
- package/dist/esm/tests/features/resumable-tasks.spec.js +82 -91
- package/dist/esm/tests/features/resumable-tasks.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-read.spec.js +206 -207
- package/dist/esm/tests/handlers/messages-read.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-subscribe.spec.js +145 -154
- package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-sync.spec.js +174 -183
- package/dist/esm/tests/handlers/messages-sync.spec.js.map +1 -1
- package/dist/esm/tests/handlers/protocols-configure.spec.js +244 -238
- package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -1
- package/dist/esm/tests/handlers/protocols-query.spec.js +156 -169
- package/dist/esm/tests/handlers/protocols-query.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-count.spec.js +93 -102
- package/dist/esm/tests/handlers/records-count.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-delete.spec.js +252 -264
- package/dist/esm/tests/handlers/records-delete.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-query.spec.js +917 -988
- package/dist/esm/tests/handlers/records-query.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-read.spec.js +553 -568
- package/dist/esm/tests/handlers/records-read.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-subscribe.spec.js +269 -278
- package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-write.spec.js +1057 -1082
- package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/messages-get.spec.js +39 -48
- package/dist/esm/tests/interfaces/messages-get.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/messages-subscribe.spec.js +4 -13
- package/dist/esm/tests/interfaces/messages-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/protocols-configure.spec.js +212 -88
- package/dist/esm/tests/interfaces/protocols-configure.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/protocols-query.spec.js +8 -17
- package/dist/esm/tests/interfaces/protocols-query.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-delete.spec.js +8 -17
- package/dist/esm/tests/interfaces/records-delete.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-query.spec.js +20 -29
- package/dist/esm/tests/interfaces/records-query.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-read.spec.js +42 -51
- package/dist/esm/tests/interfaces/records-read.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-subscribe.spec.js +16 -25
- package/dist/esm/tests/interfaces/records-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-write.spec.js +152 -165
- package/dist/esm/tests/interfaces/records-write.spec.js.map +1 -1
- package/dist/esm/tests/jose/jws/general.spec.js +36 -45
- package/dist/esm/tests/jose/jws/general.spec.js.map +1 -1
- package/dist/esm/tests/protocols/permission-grant.spec.js +44 -50
- package/dist/esm/tests/protocols/permission-grant.spec.js.map +1 -1
- package/dist/esm/tests/protocols/permission-request.spec.js +23 -32
- package/dist/esm/tests/protocols/permission-request.spec.js.map +1 -1
- package/dist/esm/tests/protocols/permissions.spec.js +49 -55
- package/dist/esm/tests/protocols/permissions.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/aggregator.spec.js +124 -135
- package/dist/esm/tests/scenarios/aggregator.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/deleted-record.spec.js +23 -32
- package/dist/esm/tests/scenarios/deleted-record.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js +52 -61
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/nested-roles.spec.js +63 -73
- package/dist/esm/tests/scenarios/nested-roles.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/subscriptions.spec.js +377 -333
- package/dist/esm/tests/scenarios/subscriptions.spec.js.map +1 -1
- package/dist/esm/tests/smt/smt-store-level.spec.js +76 -87
- package/dist/esm/tests/smt/smt-store-level.spec.js.map +1 -1
- package/dist/esm/tests/smt/sparse-merkle-tree.spec.js +344 -353
- package/dist/esm/tests/smt/sparse-merkle-tree.spec.js.map +1 -1
- package/dist/esm/tests/state-index/state-index-level.spec.js +117 -126
- package/dist/esm/tests/state-index/state-index-level.spec.js.map +1 -1
- package/dist/esm/tests/store/blockstore-level.spec.js +44 -99
- package/dist/esm/tests/store/blockstore-level.spec.js.map +1 -1
- package/dist/esm/tests/store/blockstore-mock.spec.js +40 -120
- package/dist/esm/tests/store/blockstore-mock.spec.js.map +1 -1
- package/dist/esm/tests/store/data-store-level.spec.js +86 -95
- package/dist/esm/tests/store/data-store-level.spec.js.map +1 -1
- package/dist/esm/tests/store/index-level.spec.js +404 -414
- package/dist/esm/tests/store/index-level.spec.js.map +1 -1
- package/dist/esm/tests/store/message-store-level.spec.js +13 -22
- package/dist/esm/tests/store/message-store-level.spec.js.map +1 -1
- package/dist/esm/tests/store/message-store.spec.js +229 -238
- package/dist/esm/tests/store/message-store.spec.js.map +1 -1
- package/dist/esm/tests/test-event-stream.js +3 -3
- package/dist/esm/tests/test-event-stream.js.map +1 -1
- package/dist/esm/tests/test-stores.js +16 -13
- package/dist/esm/tests/test-stores.js.map +1 -1
- package/dist/esm/tests/test-suite.js +2 -11
- package/dist/esm/tests/test-suite.js.map +1 -1
- package/dist/esm/tests/utils/cid.spec.js +24 -33
- package/dist/esm/tests/utils/cid.spec.js.map +1 -1
- package/dist/esm/tests/utils/data-stream.spec.js +48 -57
- package/dist/esm/tests/utils/data-stream.spec.js.map +1 -1
- package/dist/esm/tests/utils/encryption-callbacks.spec.js +45 -54
- package/dist/esm/tests/utils/encryption-callbacks.spec.js.map +1 -1
- package/dist/esm/tests/utils/encryption.spec.js +291 -44
- package/dist/esm/tests/utils/encryption.spec.js.map +1 -1
- package/dist/esm/tests/utils/filters.spec.js +46 -55
- package/dist/esm/tests/utils/filters.spec.js.map +1 -1
- package/dist/esm/tests/utils/hd-key.spec.js +10 -19
- package/dist/esm/tests/utils/hd-key.spec.js.map +1 -1
- package/dist/esm/tests/utils/jws.spec.js +3 -12
- package/dist/esm/tests/utils/jws.spec.js.map +1 -1
- package/dist/esm/tests/utils/memory-cache.spec.js +9 -18
- package/dist/esm/tests/utils/memory-cache.spec.js.map +1 -1
- package/dist/esm/tests/utils/messages.spec.js +6 -15
- package/dist/esm/tests/utils/messages.spec.js.map +1 -1
- package/dist/esm/tests/utils/poller.js +22 -33
- package/dist/esm/tests/utils/poller.js.map +1 -1
- package/dist/esm/tests/utils/private-key-signer.spec.js +15 -24
- package/dist/esm/tests/utils/private-key-signer.spec.js.map +1 -1
- package/dist/esm/tests/utils/records.spec.js +10 -19
- package/dist/esm/tests/utils/records.spec.js.map +1 -1
- package/dist/esm/tests/utils/secp256k1.spec.js +16 -25
- package/dist/esm/tests/utils/secp256k1.spec.js.map +1 -1
- package/dist/esm/tests/utils/secp256r1.spec.js +18 -27
- package/dist/esm/tests/utils/secp256r1.spec.js.map +1 -1
- package/dist/esm/tests/utils/test-data-generator.js +414 -468
- package/dist/esm/tests/utils/test-data-generator.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/definitions.spec.js +2 -11
- package/dist/esm/tests/validation/json-schemas/definitions.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/jwk/general-jwk.spec.js +4 -13
- package/dist/esm/tests/validation/json-schemas/jwk/general-jwk.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/jwk/public-jwk.spec.js +8 -17
- package/dist/esm/tests/validation/json-schemas/jwk/public-jwk.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/jwk-verification-method.spec.js +3 -12
- package/dist/esm/tests/validation/json-schemas/jwk-verification-method.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js +4 -13
- package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/records/records-query.spec.js +2 -11
- package/dist/esm/tests/validation/json-schemas/records/records-query.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/records/records-read.spec.js +2 -11
- package/dist/esm/tests/validation/json-schemas/records/records-read.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js +7 -16
- package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js.map +1 -1
- package/dist/types/src/core/protocol-authorization-action.d.ts +42 -0
- package/dist/types/src/core/protocol-authorization-action.d.ts.map +1 -0
- package/dist/types/src/core/protocol-authorization-validation.d.ts +60 -0
- package/dist/types/src/core/protocol-authorization-validation.d.ts.map +1 -0
- package/dist/types/src/core/protocol-authorization.d.ts +10 -100
- package/dist/types/src/core/protocol-authorization.d.ts.map +1 -1
- package/dist/types/src/core/record-chain.d.ts +24 -0
- package/dist/types/src/core/record-chain.d.ts.map +1 -0
- package/dist/types/src/handlers/records-write.d.ts +2 -1
- package/dist/types/src/handlers/records-write.d.ts.map +1 -1
- package/dist/types/src/interfaces/protocols-configure.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-write-query.d.ts +33 -0
- package/dist/types/src/interfaces/records-write-query.d.ts.map +1 -0
- package/dist/types/src/interfaces/records-write-signing.d.ts +35 -0
- package/dist/types/src/interfaces/records-write-signing.d.ts.map +1 -0
- package/dist/types/src/interfaces/records-write.d.ts +10 -44
- package/dist/types/src/interfaces/records-write.d.ts.map +1 -1
- package/dist/types/src/store/index-level-compound.d.ts +70 -0
- package/dist/types/src/store/index-level-compound.d.ts.map +1 -0
- package/dist/types/src/store/index-level.d.ts +0 -58
- package/dist/types/src/store/index-level.d.ts.map +1 -1
- package/dist/types/src/utils/protocols.d.ts +5 -0
- package/dist/types/src/utils/protocols.d.ts.map +1 -1
- package/dist/types/src/utils/records.d.ts +3 -1
- package/dist/types/src/utils/records.d.ts.map +1 -1
- package/dist/types/tests/features/permissions.spec.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/core/protocol-authorization-action.ts +377 -0
- package/src/core/protocol-authorization-validation.ts +391 -0
- package/src/core/protocol-authorization.ts +60 -849
- package/src/core/record-chain.ts +99 -0
- package/src/handlers/records-read.ts +1 -1
- package/src/handlers/records-write.ts +37 -21
- package/src/interfaces/protocols-configure.ts +33 -5
- package/src/interfaces/records-write-query.ts +139 -0
- package/src/interfaces/records-write-signing.ts +143 -0
- package/src/interfaces/records-write.ts +49 -221
- package/src/store/index-level-compound.ts +324 -0
- package/src/store/index-level.ts +24 -306
- package/src/utils/protocols.ts +8 -0
- package/src/utils/records.ts +9 -15
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import { authenticate } from '../core/auth.js';
|
|
11
2
|
import { Cid } from '../utils/cid.js';
|
|
12
3
|
import { DataStream } from '../utils/data-stream.js';
|
|
@@ -22,6 +13,11 @@ import { StorageController } from '../store/storage-controller.js';
|
|
|
22
13
|
import { DwnError, DwnErrorCode } from '../core/dwn-error.js';
|
|
23
14
|
import { DwnInterfaceName, DwnMethodName } from '../enums/dwn-interface-method.js';
|
|
24
15
|
export class RecordsWriteHandler {
|
|
16
|
+
didResolver;
|
|
17
|
+
messageStore;
|
|
18
|
+
dataStore;
|
|
19
|
+
stateIndex;
|
|
20
|
+
eventStream;
|
|
25
21
|
constructor(didResolver, messageStore, dataStore, stateIndex, eventStream) {
|
|
26
22
|
this.didResolver = didResolver;
|
|
27
23
|
this.messageStore = messageStore;
|
|
@@ -29,154 +25,149 @@ export class RecordsWriteHandler {
|
|
|
29
25
|
this.stateIndex = stateIndex;
|
|
30
26
|
this.eventStream = eventStream;
|
|
31
27
|
}
|
|
32
|
-
handle(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
yield ProtocolAuthorization.validateReferentialIntegrity(tenant, recordsWrite, this.messageStore);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
catch (e) {
|
|
43
|
-
return messageReplyFromError(e, 400);
|
|
28
|
+
async handle({ tenant, message, dataStream }) {
|
|
29
|
+
let recordsWrite;
|
|
30
|
+
try {
|
|
31
|
+
recordsWrite = await RecordsWrite.parse(message);
|
|
32
|
+
// Protocol-authorized record specific validation
|
|
33
|
+
if (message.descriptor.protocol !== undefined) {
|
|
34
|
+
await ProtocolAuthorization.validateReferentialIntegrity(tenant, recordsWrite, this.messageStore);
|
|
44
35
|
}
|
|
45
|
-
|
|
36
|
+
}
|
|
37
|
+
catch (e) {
|
|
38
|
+
return messageReplyFromError(e, 400);
|
|
39
|
+
}
|
|
40
|
+
// authentication & authorization
|
|
41
|
+
try {
|
|
42
|
+
await authenticate(message.authorization, this.didResolver, message.attestation);
|
|
43
|
+
await RecordsWriteHandler.authorizeRecordsWrite(tenant, recordsWrite, this.messageStore);
|
|
44
|
+
}
|
|
45
|
+
catch (e) {
|
|
46
|
+
return messageReplyFromError(e, 401);
|
|
47
|
+
}
|
|
48
|
+
// get existing messages matching the `recordId`
|
|
49
|
+
const query = {
|
|
50
|
+
interface: DwnInterfaceName.Records,
|
|
51
|
+
recordId: message.recordId
|
|
52
|
+
};
|
|
53
|
+
const { messages: existingMessages } = await this.messageStore.query(tenant, [query]);
|
|
54
|
+
// if the incoming write is not the initial write, then it must not modify any immutable properties defined by the initial write
|
|
55
|
+
const newMessageIsInitialWrite = await recordsWrite.isInitialWrite();
|
|
56
|
+
let initialWrite;
|
|
57
|
+
if (!newMessageIsInitialWrite) {
|
|
46
58
|
try {
|
|
47
|
-
|
|
48
|
-
|
|
59
|
+
initialWrite = await RecordsWrite.getInitialWrite(existingMessages);
|
|
60
|
+
RecordsWrite.verifyEqualityOfImmutableProperties(initialWrite, message);
|
|
49
61
|
}
|
|
50
62
|
catch (e) {
|
|
51
|
-
return messageReplyFromError(e,
|
|
63
|
+
return messageReplyFromError(e, 400);
|
|
52
64
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
65
|
+
}
|
|
66
|
+
const newestExistingMessage = await Message.getNewestMessage(existingMessages);
|
|
67
|
+
let incomingMessageIsNewest = false;
|
|
68
|
+
let newestMessage; // keep reference of newest message for pruning later
|
|
69
|
+
if (newestExistingMessage === undefined || await Message.isNewer(message, newestExistingMessage)) {
|
|
70
|
+
incomingMessageIsNewest = true;
|
|
71
|
+
newestMessage = message;
|
|
72
|
+
}
|
|
73
|
+
else { // existing message is the same age or newer than the incoming message
|
|
74
|
+
newestMessage = newestExistingMessage;
|
|
75
|
+
}
|
|
76
|
+
if (!incomingMessageIsNewest) {
|
|
77
|
+
return {
|
|
78
|
+
status: { code: 409, detail: 'Conflict' }
|
|
57
79
|
};
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (!newMessageIsInitialWrite) {
|
|
63
|
-
try {
|
|
64
|
-
initialWrite = yield RecordsWrite.getInitialWrite(existingMessages);
|
|
65
|
-
RecordsWrite.verifyEqualityOfImmutableProperties(initialWrite, message);
|
|
66
|
-
}
|
|
67
|
-
catch (e) {
|
|
68
|
-
return messageReplyFromError(e, 400);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
const newestExistingMessage = yield Message.getNewestMessage(existingMessages);
|
|
72
|
-
let incomingMessageIsNewest = false;
|
|
73
|
-
let newestMessage; // keep reference of newest message for pruning later
|
|
74
|
-
if (newestExistingMessage === undefined || (yield Message.isNewer(message, newestExistingMessage))) {
|
|
75
|
-
incomingMessageIsNewest = true;
|
|
76
|
-
newestMessage = message;
|
|
77
|
-
}
|
|
78
|
-
else { // existing message is the same age or newer than the incoming message
|
|
79
|
-
newestMessage = newestExistingMessage;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
if (newestExistingMessage?.descriptor.method === DwnMethodName.Delete) {
|
|
83
|
+
throw new DwnError(DwnErrorCode.RecordsWriteNotAllowedAfterDelete, 'RecordsWrite is not allowed after a RecordsDelete.');
|
|
80
84
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
+
// NOTE: We want to perform additional validation before storing the RecordsWrite.
|
|
86
|
+
// This is necessary for core DWN RecordsWrite that needs additional processing and allows us to fail before the storing and post processing.
|
|
87
|
+
//
|
|
88
|
+
// Example: Ensures that the protocol tag of a permission revocation RecordsWrite and the parent grant's scoped protocol match.
|
|
89
|
+
await this.preProcessingForCoreRecordsWrite(tenant, message);
|
|
90
|
+
// NOTE: We allow isLatestBaseState to be true ONLY if the incoming message comes with data, or if the incoming message is NOT an initial write
|
|
91
|
+
// This would allow an initial write to be written to the DB without data, but having it not queryable,
|
|
92
|
+
// because query implementation filters on `isLatestBaseState` being `true`
|
|
93
|
+
// thus preventing a user's attempt to gain authorized access to data by referencing the dataCid of a private data in their initial writes,
|
|
94
|
+
// See: https://github.com/enboxorg/enbox/issues/359 for more info
|
|
95
|
+
let isLatestBaseState = false;
|
|
96
|
+
let messageWithOptionalEncodedData = message;
|
|
97
|
+
if (dataStream !== undefined) {
|
|
98
|
+
messageWithOptionalEncodedData = await this.processMessageWithDataStream(tenant, message, dataStream);
|
|
99
|
+
isLatestBaseState = true;
|
|
85
100
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
// Example: Ensures that the protocol tag of a permission revocation RecordsWrite and the parent grant's scoped protocol match.
|
|
94
|
-
yield this.preProcessingForCoreRecordsWrite(tenant, message);
|
|
95
|
-
// NOTE: We allow isLatestBaseState to be true ONLY if the incoming message comes with data, or if the incoming message is NOT an initial write
|
|
96
|
-
// This would allow an initial write to be written to the DB without data, but having it not queryable,
|
|
97
|
-
// because query implementation filters on `isLatestBaseState` being `true`
|
|
98
|
-
// thus preventing a user's attempt to gain authorized access to data by referencing the dataCid of a private data in their initial writes,
|
|
99
|
-
// See: https://github.com/enboxorg/enbox/issues/359 for more info
|
|
100
|
-
let isLatestBaseState = false;
|
|
101
|
-
let messageWithOptionalEncodedData = message;
|
|
102
|
-
if (dataStream !== undefined) {
|
|
103
|
-
messageWithOptionalEncodedData = yield this.processMessageWithDataStream(tenant, message, dataStream);
|
|
101
|
+
else {
|
|
102
|
+
// else data stream is NOT provided
|
|
103
|
+
// if the incoming message is not an initial write, and no dataStream is provided, we would allow it provided it passes validation
|
|
104
|
+
// processMessageWithoutDataStream() abstracts that logic
|
|
105
|
+
if (!newMessageIsInitialWrite) {
|
|
106
|
+
const newestExistingWrite = newestExistingMessage;
|
|
107
|
+
messageWithOptionalEncodedData = await this.processMessageWithoutDataStream(tenant, message, newestExistingWrite);
|
|
104
108
|
isLatestBaseState = true;
|
|
105
109
|
}
|
|
106
|
-
else {
|
|
107
|
-
// else data stream is NOT provided
|
|
108
|
-
// if the incoming message is not an initial write, and no dataStream is provided, we would allow it provided it passes validation
|
|
109
|
-
// processMessageWithoutDataStream() abstracts that logic
|
|
110
|
-
if (!newMessageIsInitialWrite) {
|
|
111
|
-
const newestExistingWrite = newestExistingMessage;
|
|
112
|
-
messageWithOptionalEncodedData = yield this.processMessageWithoutDataStream(tenant, message, newestExistingWrite);
|
|
113
|
-
isLatestBaseState = true;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
const indexes = yield recordsWrite.constructIndexes(isLatestBaseState);
|
|
117
|
-
yield this.messageStore.put(tenant, messageWithOptionalEncodedData, indexes);
|
|
118
|
-
yield this.stateIndex.insert(tenant, yield Message.getCid(message), indexes);
|
|
119
|
-
// NOTE: We only emit a `RecordsWrite` when the message is the latest base state.
|
|
120
|
-
// Because we allow a `RecordsWrite` which is not the latest state to be written, but not queried, we shouldn't emit it either.
|
|
121
|
-
// It will be emitted as a part of a subsequent next write, if it is the latest base state.
|
|
122
|
-
if (this.eventStream !== undefined && isLatestBaseState) {
|
|
123
|
-
this.eventStream.emit(tenant, { message, initialWrite }, indexes);
|
|
124
|
-
}
|
|
125
110
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
111
|
+
const indexes = await recordsWrite.constructIndexes(isLatestBaseState);
|
|
112
|
+
await this.messageStore.put(tenant, messageWithOptionalEncodedData, indexes);
|
|
113
|
+
await this.stateIndex.insert(tenant, await Message.getCid(message), indexes);
|
|
114
|
+
// NOTE: We only emit a `RecordsWrite` when the message is the latest base state.
|
|
115
|
+
// Because we allow a `RecordsWrite` which is not the latest state to be written, but not queried, we shouldn't emit it either.
|
|
116
|
+
// It will be emitted as a part of a subsequent next write, if it is the latest base state.
|
|
117
|
+
if (this.eventStream !== undefined && isLatestBaseState) {
|
|
118
|
+
this.eventStream.emit(tenant, { message, initialWrite }, indexes);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
if (error instanceof DwnError) {
|
|
123
|
+
if (error.code === DwnErrorCode.RecordsWriteMissingEncodedDataInPrevious ||
|
|
124
|
+
error.code === DwnErrorCode.RecordsWriteMissingDataInPrevious ||
|
|
125
|
+
error.code === DwnErrorCode.RecordsWriteNotAllowedAfterDelete ||
|
|
126
|
+
error.code === DwnErrorCode.RecordsWriteDataCidMismatch ||
|
|
127
|
+
error.code === DwnErrorCode.RecordsWriteDataSizeMismatch ||
|
|
128
|
+
error.code.startsWith('PermissionsProtocolValidate') ||
|
|
129
|
+
error.code.startsWith('SchemaValidator')) {
|
|
130
|
+
return messageReplyFromError(error, 400);
|
|
137
131
|
}
|
|
138
|
-
// else throw
|
|
139
|
-
throw error;
|
|
140
132
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
133
|
+
// else throw
|
|
134
|
+
throw error;
|
|
135
|
+
}
|
|
136
|
+
const messageReply = {
|
|
137
|
+
// In order to discern between something that was accepted as a queryable write and something that was accepted
|
|
138
|
+
// as an initial state we use separate response codes. See https://github.com/enboxorg/enbox/issues/695
|
|
139
|
+
// for more details.
|
|
140
|
+
status: (newMessageIsInitialWrite && dataStream === undefined) ?
|
|
141
|
+
{ code: 204, detail: 'No Content' } :
|
|
142
|
+
{ code: 202, detail: 'Accepted' }
|
|
143
|
+
};
|
|
144
|
+
// delete all existing messages of the same record that are not newest, except for the initial write
|
|
145
|
+
await StorageController.deleteAllOlderMessagesButKeepInitialWrite(tenant, existingMessages, newestMessage, this.messageStore, this.dataStore, this.stateIndex);
|
|
146
|
+
await this.postProcessingForCoreRecordsWrite(tenant, recordsWrite);
|
|
147
|
+
return messageReply;
|
|
154
148
|
}
|
|
155
149
|
;
|
|
156
150
|
/**
|
|
157
151
|
* Performs additional necessary validation before storing the RecordsWrite if it is a core DWN RecordsWrite that needs additional processing.
|
|
158
152
|
* For instance: a Permission revocation RecordsWrite.
|
|
159
153
|
*/
|
|
160
|
-
preProcessingForCoreRecordsWrite(tenant, recordsWriteMessage) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
if (grantProtocol !== revokeTagProtocol) {
|
|
176
|
-
throw new DwnError(DwnErrorCode.PermissionsProtocolValidateRevocationProtocolTagMismatch, `Revocation protocol ${revokeTagProtocol} does not match grant protocol ${grantProtocol}`);
|
|
177
|
-
}
|
|
154
|
+
async preProcessingForCoreRecordsWrite(tenant, recordsWriteMessage) {
|
|
155
|
+
// we validate the protocol tag of the revocation message against the grant's scoped protocol
|
|
156
|
+
// to do this we will fetch the grant, and compare the the scoped protocol value to the protocol tag of the revocation message
|
|
157
|
+
if (recordsWriteMessage.descriptor.protocol === PermissionsProtocol.uri &&
|
|
158
|
+
recordsWriteMessage.descriptor.protocolPath === PermissionsProtocol.revocationPath) {
|
|
159
|
+
// get the parentId of the revocation message, which is the permissionGrantId
|
|
160
|
+
// fetch the grant in order to get the grant's protocol
|
|
161
|
+
const permissionGrantId = recordsWriteMessage.descriptor.parentId;
|
|
162
|
+
const grant = await PermissionsProtocol.fetchGrant(tenant, this.messageStore, permissionGrantId);
|
|
163
|
+
// get the protocol values of the revocation message from the protocol tag and the protocol from the grant scope if they are defined
|
|
164
|
+
// compare the two values ensuring they must match
|
|
165
|
+
const revokeTagProtocol = recordsWriteMessage.descriptor.tags?.protocol;
|
|
166
|
+
const grantProtocol = 'protocol' in grant.scope ? grant.scope.protocol : undefined;
|
|
167
|
+
if (grantProtocol !== revokeTagProtocol) {
|
|
168
|
+
throw new DwnError(DwnErrorCode.PermissionsProtocolValidateRevocationProtocolTagMismatch, `Revocation protocol ${revokeTagProtocol} does not match grant protocol ${grantProtocol}`);
|
|
178
169
|
}
|
|
179
|
-
}
|
|
170
|
+
}
|
|
180
171
|
}
|
|
181
172
|
static validateSchemaForCoreRecordsWrite(recordsWriteMessage, dataBytes) {
|
|
182
173
|
if (recordsWriteMessage.descriptor.protocol === PermissionsProtocol.uri) {
|
|
@@ -185,104 +176,106 @@ export class RecordsWriteHandler {
|
|
|
185
176
|
}
|
|
186
177
|
/**
|
|
187
178
|
* Performs additional necessary tasks if the RecordsWrite handled is a core DWN RecordsWrite that need additional processing.
|
|
188
|
-
* For instance: a Permission revocation
|
|
179
|
+
* For instance: when a Permission revocation is written, all messages authorized by the revoked grant
|
|
180
|
+
* that were created after the revocation timestamp are deleted from all stores.
|
|
189
181
|
*/
|
|
190
|
-
postProcessingForCoreRecordsWrite(tenant, recordsWrite) {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
182
|
+
async postProcessingForCoreRecordsWrite(tenant, recordsWrite) {
|
|
183
|
+
if (recordsWrite.message.descriptor.protocol !== PermissionsProtocol.uri ||
|
|
184
|
+
recordsWrite.message.descriptor.protocolPath !== PermissionsProtocol.revocationPath) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
// Delete all messages authorized by the revoked grant that were created after the revocation.
|
|
188
|
+
// `permissionGrantId` is indexed via the RecordsWriteDescriptor spread in constructIndexes().
|
|
189
|
+
const permissionGrantId = recordsWrite.message.descriptor.parentId;
|
|
190
|
+
const grantAuthorizedMessagesQuery = {
|
|
191
|
+
permissionGrantId,
|
|
192
|
+
dateCreated: { gte: recordsWrite.message.descriptor.messageTimestamp },
|
|
193
|
+
};
|
|
194
|
+
const { messages: grantAuthorizedMessages } = await this.messageStore.query(tenant, [grantAuthorizedMessagesQuery]);
|
|
195
|
+
if (grantAuthorizedMessages.length === 0) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
// Delete data from the data store first to avoid orphaned data blobs in case of crash.
|
|
199
|
+
// Only RecordsWrite messages with data larger than maxDataSizeAllowedToBeEncoded have data in the data store.
|
|
200
|
+
for (const message of grantAuthorizedMessages) {
|
|
201
|
+
if (message.descriptor.method === DwnMethodName.Write) {
|
|
202
|
+
const recordsWriteMessage = message;
|
|
203
|
+
if (recordsWriteMessage.descriptor.dataSize > DwnConstant.maxDataSizeAllowedToBeEncoded) {
|
|
204
|
+
await this.dataStore.delete(tenant, recordsWriteMessage.recordId, recordsWriteMessage.descriptor.dataCid);
|
|
211
205
|
}
|
|
212
|
-
this.stateIndex.delete(tenant, grantAuthorizedMessageCidsAfterRevoke);
|
|
213
206
|
}
|
|
214
|
-
}
|
|
207
|
+
}
|
|
208
|
+
// Compute CIDs for all messages to delete.
|
|
209
|
+
const messageCids = await Promise.all(grantAuthorizedMessages.map((message) => Message.getCid(message)));
|
|
210
|
+
// Delete from state index before message store so we don't have orphaned state entries.
|
|
211
|
+
await this.stateIndex.delete(tenant, messageCids);
|
|
212
|
+
// Finally delete all messages from the message store.
|
|
213
|
+
await Promise.all(messageCids.map((cid) => this.messageStore.delete(tenant, cid)));
|
|
215
214
|
}
|
|
216
215
|
/**
|
|
217
216
|
* Returns a `RecordsQueryReplyEntry` with a copy of the incoming message and the incoming data encoded to `Base64URL`.
|
|
218
217
|
*/
|
|
219
|
-
cloneAndAddEncodedData(message, dataBytes) {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
return recordsWrite;
|
|
224
|
-
});
|
|
218
|
+
async cloneAndAddEncodedData(message, dataBytes) {
|
|
219
|
+
const recordsWrite = { ...message };
|
|
220
|
+
recordsWrite.encodedData = Encoder.bytesToBase64Url(dataBytes);
|
|
221
|
+
return recordsWrite;
|
|
225
222
|
}
|
|
226
|
-
processMessageWithDataStream(tenant, message, dataStream) {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
223
|
+
async processMessageWithDataStream(tenant, message, dataStream) {
|
|
224
|
+
let messageWithOptionalEncodedData = message;
|
|
225
|
+
// if data is below the threshold, we store it within MessageStore
|
|
226
|
+
if (message.descriptor.dataSize <= DwnConstant.maxDataSizeAllowedToBeEncoded) {
|
|
227
|
+
// validate data integrity before setting.
|
|
228
|
+
const dataBytes = await DataStream.toBytes(dataStream);
|
|
229
|
+
const dataCid = await Cid.computeDagPbCidFromBytes(dataBytes);
|
|
230
|
+
RecordsWriteHandler.validateDataIntegrity(message.descriptor.dataCid, message.descriptor.dataSize, dataCid, dataBytes.length);
|
|
231
|
+
RecordsWriteHandler.validateSchemaForCoreRecordsWrite(message, dataBytes);
|
|
232
|
+
messageWithOptionalEncodedData = await this.cloneAndAddEncodedData(message, dataBytes);
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
// split the dataStream into two: one for CID computation and one for storage
|
|
236
|
+
const [dataStreamCopy1, dataStreamCopy2] = DataStream.duplicateDataStream(dataStream, 2);
|
|
237
|
+
try {
|
|
238
|
+
// perform storage and CID computation in parallel
|
|
239
|
+
const [dataCid, DataStorePutResult] = await Promise.all([
|
|
240
|
+
Cid.computeDagPbCidFromStream(dataStreamCopy1),
|
|
241
|
+
this.dataStore.put(tenant, message.recordId, message.descriptor.dataCid, dataStreamCopy2)
|
|
242
|
+
]);
|
|
243
|
+
RecordsWriteHandler.validateDataIntegrity(message.descriptor.dataCid, message.descriptor.dataSize, dataCid, DataStorePutResult.dataSize);
|
|
237
244
|
}
|
|
238
|
-
|
|
239
|
-
//
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
// perform storage and CID computation in parallel
|
|
243
|
-
const [dataCid, DataStorePutResult] = yield Promise.all([
|
|
244
|
-
Cid.computeDagPbCidFromStream(dataStreamCopy1),
|
|
245
|
-
this.dataStore.put(tenant, message.recordId, message.descriptor.dataCid, dataStreamCopy2)
|
|
246
|
-
]);
|
|
247
|
-
RecordsWriteHandler.validateDataIntegrity(message.descriptor.dataCid, message.descriptor.dataSize, dataCid, DataStorePutResult.dataSize);
|
|
248
|
-
}
|
|
249
|
-
catch (error) {
|
|
250
|
-
// unwind/delete data if we have issue with storage or the data failed integrity validation
|
|
251
|
-
yield this.dataStore.delete(tenant, message.recordId, message.descriptor.dataCid);
|
|
252
|
-
throw error;
|
|
253
|
-
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
// unwind/delete data if we have issue with storage or the data failed integrity validation
|
|
247
|
+
await this.dataStore.delete(tenant, message.recordId, message.descriptor.dataCid);
|
|
248
|
+
throw error;
|
|
254
249
|
}
|
|
255
|
-
|
|
256
|
-
|
|
250
|
+
}
|
|
251
|
+
return messageWithOptionalEncodedData;
|
|
257
252
|
}
|
|
258
|
-
processMessageWithoutDataStream(tenant, message, newestExistingWrite) {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
if
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
messageWithOptionalEncodedData.encodedData = newestExistingWrite.encodedData;
|
|
271
|
-
}
|
|
272
|
-
else {
|
|
273
|
-
throw new DwnError(DwnErrorCode.RecordsWriteMissingEncodedDataInPrevious, `No dataStream was provided and unable to get data from previous message`);
|
|
274
|
-
}
|
|
253
|
+
async processMessageWithoutDataStream(tenant, message, newestExistingWrite) {
|
|
254
|
+
const messageWithOptionalEncodedData = { ...message }; // clone
|
|
255
|
+
const { dataCid, dataSize } = message.descriptor;
|
|
256
|
+
// Since incoming message is not an initial write, and no dataStream is provided, we first check integrity against newest existing write.
|
|
257
|
+
// we preform the dataCid check in case a user attempts to gain access to data by referencing a different known dataCid,
|
|
258
|
+
// so we insure that the data is already associated with the existing newest message
|
|
259
|
+
// See: https://github.com/enboxorg/enbox/issues/359 for more info
|
|
260
|
+
RecordsWriteHandler.validateDataIntegrity(dataCid, dataSize, newestExistingWrite.descriptor.dataCid, newestExistingWrite.descriptor.dataSize);
|
|
261
|
+
if (dataSize <= DwnConstant.maxDataSizeAllowedToBeEncoded) {
|
|
262
|
+
// we encode the data from the original write if it is smaller than the data-store threshold
|
|
263
|
+
if (newestExistingWrite.encodedData !== undefined) {
|
|
264
|
+
messageWithOptionalEncodedData.encodedData = newestExistingWrite.encodedData;
|
|
275
265
|
}
|
|
276
266
|
else {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
267
|
+
throw new DwnError(DwnErrorCode.RecordsWriteMissingEncodedDataInPrevious, `No dataStream was provided and unable to get data from previous message`);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
// else just make sure the data is in the data store
|
|
272
|
+
// attempt to retrieve the data from the previous message
|
|
273
|
+
const DataStoreGetResult = await this.dataStore.get(tenant, newestExistingWrite.recordId, message.descriptor.dataCid);
|
|
274
|
+
if (DataStoreGetResult === undefined) {
|
|
275
|
+
throw new DwnError(DwnErrorCode.RecordsWriteMissingDataInPrevious, `No dataStream was provided and unable to get data from previous message`);
|
|
283
276
|
}
|
|
284
|
-
|
|
285
|
-
|
|
277
|
+
}
|
|
278
|
+
return messageWithOptionalEncodedData;
|
|
286
279
|
}
|
|
287
280
|
/**
|
|
288
281
|
* Validates the expected `dataCid` and `dataSize` in the descriptor vs the received data.
|
|
@@ -300,44 +293,42 @@ export class RecordsWriteHandler {
|
|
|
300
293
|
throw new DwnError(DwnErrorCode.RecordsWriteDataSizeMismatch, `actual data size ${actualDataSize} bytes does not match dataSize in descriptor: ${expectedDataSize}`);
|
|
301
294
|
}
|
|
302
295
|
}
|
|
303
|
-
static authorizeRecordsWrite(tenant, recordsWrite, messageStore) {
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
if
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
}
|
|
340
|
-
});
|
|
296
|
+
static async authorizeRecordsWrite(tenant, recordsWrite, messageStore) {
|
|
297
|
+
// if owner signature is given (`owner` is not `undefined`), it must be the same as the tenant DID
|
|
298
|
+
if (recordsWrite.owner !== undefined && recordsWrite.owner !== tenant) {
|
|
299
|
+
throw new DwnError(DwnErrorCode.RecordsWriteOwnerAndTenantMismatch, `Owner ${recordsWrite.owner} must be the same as tenant ${tenant} when specified.`);
|
|
300
|
+
}
|
|
301
|
+
if (recordsWrite.isSignedByAuthorDelegate) {
|
|
302
|
+
await recordsWrite.authorizeAuthorDelegate(messageStore);
|
|
303
|
+
}
|
|
304
|
+
if (recordsWrite.isSignedByOwnerDelegate) {
|
|
305
|
+
await recordsWrite.authorizeOwnerDelegate(messageStore);
|
|
306
|
+
}
|
|
307
|
+
if (recordsWrite.owner !== undefined) {
|
|
308
|
+
// if incoming message is a write retained by this tenant, we by-design always allow
|
|
309
|
+
// NOTE: the "owner === tenant" check is already done earlier in this method
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
else if (recordsWrite.author === tenant) {
|
|
313
|
+
// if author is the same as the target tenant, we can directly grant access
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
else if (recordsWrite.author !== undefined && recordsWrite.signaturePayload.permissionGrantId !== undefined) {
|
|
317
|
+
const permissionGrant = await PermissionsProtocol.fetchGrant(tenant, messageStore, recordsWrite.signaturePayload.permissionGrantId);
|
|
318
|
+
await RecordsGrantAuthorization.authorizeWrite({
|
|
319
|
+
recordsWriteMessage: recordsWrite.message,
|
|
320
|
+
expectedGrantor: tenant,
|
|
321
|
+
expectedGrantee: recordsWrite.author,
|
|
322
|
+
permissionGrant,
|
|
323
|
+
messageStore
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
else if (recordsWrite.message.descriptor.protocol !== undefined) {
|
|
327
|
+
await ProtocolAuthorization.authorizeWrite(tenant, recordsWrite, messageStore);
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
throw new DwnError(DwnErrorCode.RecordsWriteAuthorizationFailed, 'message failed authorization');
|
|
331
|
+
}
|
|
341
332
|
}
|
|
342
333
|
}
|
|
343
334
|
//# sourceMappingURL=records-write.js.map
|