@enbox/dwn-sdk-js 0.4.5 → 0.4.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/README.md +3 -1
- package/dist/browser.mjs +19 -78
- package/dist/browser.mjs.map +4 -4
- package/dist/esm/generated/precompiled-validators.js +4465 -3861
- package/dist/esm/generated/precompiled-validators.js.map +1 -1
- package/dist/esm/src/core/constants.js +50 -0
- package/dist/esm/src/core/constants.js.map +1 -1
- package/dist/esm/src/core/dwn-error.js +28 -11
- package/dist/esm/src/core/dwn-error.js.map +1 -1
- package/dist/esm/src/core/encryption-control.js +785 -0
- package/dist/esm/src/core/encryption-control.js.map +1 -0
- package/dist/esm/src/core/message.js +6 -0
- package/dist/esm/src/core/message.js.map +1 -1
- package/dist/esm/src/core/messages-grant-authorization.js +36 -5
- package/dist/esm/src/core/messages-grant-authorization.js.map +1 -1
- package/dist/esm/src/core/protocol-authorization-action.js +3 -12
- package/dist/esm/src/core/protocol-authorization-action.js.map +1 -1
- package/dist/esm/src/core/protocol-authorization-validation.js +31 -30
- package/dist/esm/src/core/protocol-authorization-validation.js.map +1 -1
- package/dist/esm/src/core/protocol-authorization.js +6 -0
- package/dist/esm/src/core/protocol-authorization.js.map +1 -1
- package/dist/esm/src/core/recording-validation-state-reader.js +3 -3
- package/dist/esm/src/core/recording-validation-state-reader.js.map +1 -1
- package/dist/esm/src/core/replication-apply.js +62 -108
- package/dist/esm/src/core/replication-apply.js.map +1 -1
- package/dist/esm/src/core/validation-state-reader.js +5 -6
- package/dist/esm/src/core/validation-state-reader.js.map +1 -1
- package/dist/esm/src/dwn.js +1 -2
- package/dist/esm/src/dwn.js.map +1 -1
- package/dist/esm/src/event-stream/event-emitter-wake-publisher.js +11 -11
- package/dist/esm/src/event-stream/event-emitter-wake-publisher.js.map +1 -1
- package/dist/esm/src/handlers/messages-query.js +6 -16
- package/dist/esm/src/handlers/messages-query.js.map +1 -1
- package/dist/esm/src/handlers/messages-read.js +4 -3
- package/dist/esm/src/handlers/messages-read.js.map +1 -1
- package/dist/esm/src/handlers/messages-subscribe.js +26 -30
- package/dist/esm/src/handlers/messages-subscribe.js.map +1 -1
- package/dist/esm/src/handlers/protocols-configure.js +6 -4
- package/dist/esm/src/handlers/protocols-configure.js.map +1 -1
- package/dist/esm/src/handlers/records-count.js +85 -10
- package/dist/esm/src/handlers/records-count.js.map +1 -1
- package/dist/esm/src/handlers/records-delete.js +11 -0
- package/dist/esm/src/handlers/records-delete.js.map +1 -1
- package/dist/esm/src/handlers/records-query.js +140 -18
- package/dist/esm/src/handlers/records-query.js.map +1 -1
- package/dist/esm/src/handlers/records-read.js +20 -4
- package/dist/esm/src/handlers/records-read.js.map +1 -1
- package/dist/esm/src/handlers/records-subscribe.js +127 -11
- package/dist/esm/src/handlers/records-subscribe.js.map +1 -1
- package/dist/esm/src/handlers/records-write.js +15 -0
- package/dist/esm/src/handlers/records-write.js.map +1 -1
- package/dist/esm/src/index.js +7 -10
- package/dist/esm/src/index.js.map +1 -1
- package/dist/esm/src/interfaces/protocols-configure.js +66 -9
- package/dist/esm/src/interfaces/protocols-configure.js.map +1 -1
- package/dist/esm/src/interfaces/records-write.js +43 -36
- package/dist/esm/src/interfaces/records-write.js.map +1 -1
- package/dist/esm/src/jose/algorithms/signing/ed25519.js +5 -5
- package/dist/esm/src/jose/algorithms/signing/ed25519.js.map +1 -1
- package/dist/esm/src/jose/jws/general/verifier.js +1 -1
- package/dist/esm/src/jose/jws/general/verifier.js.map +1 -1
- package/dist/esm/src/protocols/encryption.js +32 -274
- package/dist/esm/src/protocols/encryption.js.map +1 -1
- package/dist/esm/src/store/blockstore-level.js +14 -23
- package/dist/esm/src/store/blockstore-level.js.map +1 -1
- package/dist/esm/src/store/blockstore-mock.js +10 -27
- package/dist/esm/src/store/blockstore-mock.js.map +1 -1
- package/dist/esm/src/store/blockstore-utils.js +45 -0
- package/dist/esm/src/store/blockstore-utils.js.map +1 -0
- package/dist/esm/src/store/blockstore.js +2 -0
- package/dist/esm/src/store/blockstore.js.map +1 -0
- package/dist/esm/src/store/data-store-level.js +4 -12
- package/dist/esm/src/store/data-store-level.js.map +1 -1
- package/dist/esm/src/store/level.js +7 -0
- package/dist/esm/src/store/level.js.map +1 -0
- package/dist/esm/src/types/encryption-types.js +4 -1
- package/dist/esm/src/types/encryption-types.js.map +1 -1
- package/dist/esm/src/utils/data-stream.js +25 -0
- package/dist/esm/src/utils/data-stream.js.map +1 -1
- package/dist/esm/src/utils/encryption.js +142 -34
- package/dist/esm/src/utils/encryption.js.map +1 -1
- package/dist/esm/src/utils/grant-key-coverage.js +180 -0
- package/dist/esm/src/utils/grant-key-coverage.js.map +1 -0
- package/dist/esm/src/utils/hd-key.js +1 -2
- package/dist/esm/src/utils/hd-key.js.map +1 -1
- package/dist/esm/src/utils/jws.js +7 -1
- package/dist/esm/src/utils/jws.js.map +1 -1
- package/dist/esm/src/utils/memory-cache.js +29 -8
- package/dist/esm/src/utils/memory-cache.js.map +1 -1
- package/dist/esm/src/utils/protocols.js +27 -0
- package/dist/esm/src/utils/protocols.js.map +1 -1
- package/dist/esm/src/utils/record-limit-occupancy.js +23 -3
- package/dist/esm/src/utils/record-limit-occupancy.js.map +1 -1
- package/dist/esm/src/utils/records.js +29 -0
- package/dist/esm/src/utils/records.js.map +1 -1
- package/dist/esm/src/utils/secp256k1.js +12 -11
- package/dist/esm/src/utils/secp256k1.js.map +1 -1
- package/dist/esm/src/utils/secp256r1.js +12 -20
- package/dist/esm/src/utils/secp256r1.js.map +1 -1
- package/dist/esm/src/utils/time.js +103 -25
- package/dist/esm/src/utils/time.js.map +1 -1
- package/dist/esm/tests/core/constants.spec.js +35 -0
- package/dist/esm/tests/core/constants.spec.js.map +1 -0
- package/dist/esm/tests/core/encryption-control.spec.js +100 -0
- package/dist/esm/tests/core/encryption-control.spec.js.map +1 -0
- package/dist/esm/tests/core/message.spec.js +35 -0
- package/dist/esm/tests/core/message.spec.js.map +1 -1
- package/dist/esm/tests/core/protocol-authorization.spec.js +1 -1
- package/dist/esm/tests/core/protocol-authorization.spec.js.map +1 -1
- package/dist/esm/tests/core/replication-apply.spec.js +157 -74
- package/dist/esm/tests/core/replication-apply.spec.js.map +1 -1
- package/dist/esm/tests/core/replication-replay-property.spec.js +2 -1
- package/dist/esm/tests/core/replication-replay-property.spec.js.map +1 -1
- package/dist/esm/tests/core/validation-read-closure.spec.js +14 -28
- package/dist/esm/tests/core/validation-read-closure.spec.js.map +1 -1
- package/dist/esm/tests/core/validation-state-reader.spec.js +19 -23
- package/dist/esm/tests/core/validation-state-reader.spec.js.map +1 -1
- package/dist/esm/tests/dwn.spec.js +2 -1
- package/dist/esm/tests/dwn.spec.js.map +1 -1
- package/dist/esm/tests/event-emitter-wake-publisher.spec.js +51 -0
- package/dist/esm/tests/event-emitter-wake-publisher.spec.js.map +1 -0
- package/dist/esm/tests/features/protocol-composition.spec.js +1 -1
- package/dist/esm/tests/features/protocol-composition.spec.js.map +1 -1
- package/dist/esm/tests/features/records-record-limit.spec.js +1 -1
- package/dist/esm/tests/features/records-record-limit.spec.js.map +1 -1
- package/dist/esm/tests/fuzz/encryption.fuzz.spec.js +9 -1
- package/dist/esm/tests/fuzz/encryption.fuzz.spec.js.map +1 -1
- package/dist/esm/tests/fuzz/process-message.fuzz.spec.js +1 -1
- package/dist/esm/tests/fuzz/process-message.fuzz.spec.js.map +1 -1
- package/dist/esm/tests/fuzz/protocols-utils.fuzz.spec.js +29 -1
- package/dist/esm/tests/fuzz/protocols-utils.fuzz.spec.js.map +1 -1
- package/dist/esm/tests/fuzz/secp256k1.fuzz.spec.js +2 -2
- package/dist/esm/tests/fuzz/secp256k1.fuzz.spec.js.map +1 -1
- package/dist/esm/tests/fuzz/time.fuzz.spec.js +7 -1
- package/dist/esm/tests/fuzz/time.fuzz.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-query.spec.js +123 -11
- package/dist/esm/tests/handlers/messages-query.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-read.spec.js +95 -0
- package/dist/esm/tests/handlers/messages-read.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-subscribe.spec.js +90 -0
- package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/handlers/protocols-configure.spec.js +66 -0
- package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-count.spec.js +370 -0
- package/dist/esm/tests/handlers/records-count.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-delete.spec.js +70 -1
- package/dist/esm/tests/handlers/records-delete.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-query.spec.js +562 -1
- package/dist/esm/tests/handlers/records-query.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-read.spec.js +140 -2
- package/dist/esm/tests/handlers/records-read.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-subscribe.spec.js +241 -1
- package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-write.spec.js +1187 -29
- package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/protocols-configure.spec.js +290 -2
- package/dist/esm/tests/interfaces/protocols-configure.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-write.spec.js +47 -5
- package/dist/esm/tests/interfaces/records-write.spec.js.map +1 -1
- package/dist/esm/tests/protocols/encryption.spec.js +116 -472
- package/dist/esm/tests/protocols/encryption.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js +13 -27
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js.map +1 -1
- package/dist/esm/tests/store/blockstore-level.spec.js +33 -10
- package/dist/esm/tests/store/blockstore-level.spec.js.map +1 -1
- package/dist/esm/tests/store/blockstore-mock.spec.js +31 -7
- package/dist/esm/tests/store/blockstore-mock.spec.js.map +1 -1
- package/dist/esm/tests/store/blockstore-utils.spec.js +115 -0
- package/dist/esm/tests/store/blockstore-utils.spec.js.map +1 -0
- package/dist/esm/tests/store/index-level.spec.js +3 -3
- package/dist/esm/tests/store/index-level.spec.js.map +1 -1
- package/dist/esm/tests/test-stores.js +2 -1
- package/dist/esm/tests/test-stores.js.map +1 -1
- package/dist/esm/tests/utils/cid.spec.js +15 -0
- package/dist/esm/tests/utils/cid.spec.js.map +1 -1
- package/dist/esm/tests/utils/data-stream.spec.js +30 -0
- package/dist/esm/tests/utils/data-stream.spec.js.map +1 -1
- package/dist/esm/tests/utils/encryption-control-test-utils.js +111 -0
- package/dist/esm/tests/utils/encryption-control-test-utils.js.map +1 -0
- package/dist/esm/tests/utils/encryption.spec.js +240 -67
- package/dist/esm/tests/utils/encryption.spec.js.map +1 -1
- package/dist/esm/tests/utils/grant-key-coverage.spec.js +262 -0
- package/dist/esm/tests/utils/grant-key-coverage.spec.js.map +1 -0
- package/dist/esm/tests/utils/memory-cache.spec.js +12 -0
- package/dist/esm/tests/utils/memory-cache.spec.js.map +1 -1
- package/dist/esm/tests/utils/secp256r1.spec.js +2 -2
- package/dist/esm/tests/utils/secp256r1.spec.js.map +1 -1
- package/dist/esm/tests/utils/test-data-generator.js +2 -1
- package/dist/esm/tests/utils/test-data-generator.js.map +1 -1
- package/dist/esm/tests/utils/test-validation-state-reader.js +1 -1
- package/dist/esm/tests/utils/test-validation-state-reader.js.map +1 -1
- package/dist/esm/tests/utils/time.spec.js +26 -0
- package/dist/esm/tests/utils/time.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/encryption/audience.spec.js +45 -0
- package/dist/esm/tests/validation/json-schemas/encryption/audience.spec.js.map +1 -0
- package/dist/esm/tests/validation/json-schemas/encryption/delivery.spec.js +47 -0
- package/dist/esm/tests/validation/json-schemas/encryption/delivery.spec.js.map +1 -0
- package/dist/esm/tests/validation/json-schemas/encryption/grant-key.spec.js +25 -16
- package/dist/esm/tests/validation/json-schemas/encryption/grant-key.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js +152 -0
- package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js +46 -1
- package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js.map +1 -1
- package/dist/types/generated/precompiled-validators.d.ts +4 -4
- package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
- package/dist/types/src/core/constants.d.ts +39 -0
- package/dist/types/src/core/constants.d.ts.map +1 -1
- package/dist/types/src/core/dwn-error.d.ts +28 -11
- package/dist/types/src/core/dwn-error.d.ts.map +1 -1
- package/dist/types/src/core/encryption-control.d.ts +128 -0
- package/dist/types/src/core/encryption-control.d.ts.map +1 -0
- package/dist/types/src/core/message.d.ts +4 -0
- package/dist/types/src/core/message.d.ts.map +1 -1
- package/dist/types/src/core/messages-grant-authorization.d.ts +11 -0
- package/dist/types/src/core/messages-grant-authorization.d.ts.map +1 -1
- package/dist/types/src/core/protocol-authorization-action.d.ts.map +1 -1
- package/dist/types/src/core/protocol-authorization-validation.d.ts.map +1 -1
- package/dist/types/src/core/protocol-authorization.d.ts.map +1 -1
- package/dist/types/src/core/recording-validation-state-reader.d.ts +2 -3
- package/dist/types/src/core/recording-validation-state-reader.d.ts.map +1 -1
- package/dist/types/src/core/replication-apply.d.ts +10 -1
- package/dist/types/src/core/replication-apply.d.ts.map +1 -1
- package/dist/types/src/core/validation-state-reader.d.ts +2 -3
- package/dist/types/src/core/validation-state-reader.d.ts.map +1 -1
- package/dist/types/src/dwn.d.ts.map +1 -1
- package/dist/types/src/event-stream/event-emitter-wake-publisher.d.ts +1 -1
- package/dist/types/src/event-stream/event-emitter-wake-publisher.d.ts.map +1 -1
- package/dist/types/src/handlers/messages-query.d.ts.map +1 -1
- package/dist/types/src/handlers/messages-read.d.ts.map +1 -1
- package/dist/types/src/handlers/messages-subscribe.d.ts.map +1 -1
- package/dist/types/src/handlers/protocols-configure.d.ts +1 -0
- package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -1
- package/dist/types/src/handlers/records-count.d.ts +2 -0
- package/dist/types/src/handlers/records-count.d.ts.map +1 -1
- package/dist/types/src/handlers/records-delete.d.ts.map +1 -1
- package/dist/types/src/handlers/records-query.d.ts +3 -0
- package/dist/types/src/handlers/records-query.d.ts.map +1 -1
- package/dist/types/src/handlers/records-read.d.ts.map +1 -1
- package/dist/types/src/handlers/records-subscribe.d.ts +2 -0
- package/dist/types/src/handlers/records-subscribe.d.ts.map +1 -1
- package/dist/types/src/handlers/records-write.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +10 -17
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/interfaces/protocols-configure.d.ts +13 -1
- package/dist/types/src/interfaces/protocols-configure.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-write.d.ts +5 -1
- package/dist/types/src/interfaces/records-write.d.ts.map +1 -1
- package/dist/types/src/jose/algorithms/signing/ed25519.d.ts.map +1 -1
- package/dist/types/src/protocols/encryption.d.ts +2 -19
- package/dist/types/src/protocols/encryption.d.ts.map +1 -1
- package/dist/types/src/store/blockstore-level.d.ts +11 -11
- package/dist/types/src/store/blockstore-level.d.ts.map +1 -1
- package/dist/types/src/store/blockstore-mock.d.ts +12 -12
- package/dist/types/src/store/blockstore-mock.d.ts.map +1 -1
- package/dist/types/src/store/blockstore-utils.d.ts +23 -0
- package/dist/types/src/store/blockstore-utils.d.ts.map +1 -0
- package/dist/types/src/store/blockstore.d.ts +3 -0
- package/dist/types/src/store/blockstore.d.ts.map +1 -0
- package/dist/types/src/store/data-store-level.d.ts.map +1 -1
- package/dist/types/src/store/level.d.ts +13 -0
- package/dist/types/src/store/level.d.ts.map +1 -0
- package/dist/types/src/types/cache.d.ts +2 -2
- package/dist/types/src/types/cache.d.ts.map +1 -1
- package/dist/types/src/types/encryption-types.d.ts +31 -2
- package/dist/types/src/types/encryption-types.d.ts.map +1 -1
- package/dist/types/src/types/validation-state-reader.d.ts +3 -5
- package/dist/types/src/types/validation-state-reader.d.ts.map +1 -1
- package/dist/types/src/utils/data-stream.d.ts +5 -0
- package/dist/types/src/utils/data-stream.d.ts.map +1 -1
- package/dist/types/src/utils/encryption.d.ts +58 -22
- package/dist/types/src/utils/encryption.d.ts.map +1 -1
- package/dist/types/src/utils/grant-key-coverage.d.ts +36 -0
- package/dist/types/src/utils/grant-key-coverage.d.ts.map +1 -0
- package/dist/types/src/utils/hd-key.d.ts.map +1 -1
- package/dist/types/src/utils/jws.d.ts.map +1 -1
- package/dist/types/src/utils/memory-cache.d.ts +4 -2
- package/dist/types/src/utils/memory-cache.d.ts.map +1 -1
- package/dist/types/src/utils/protocols.d.ts +11 -0
- package/dist/types/src/utils/protocols.d.ts.map +1 -1
- package/dist/types/src/utils/record-limit-occupancy.d.ts +7 -0
- package/dist/types/src/utils/record-limit-occupancy.d.ts.map +1 -1
- package/dist/types/src/utils/records.d.ts +2 -0
- package/dist/types/src/utils/records.d.ts.map +1 -1
- package/dist/types/src/utils/secp256k1.d.ts.map +1 -1
- package/dist/types/src/utils/secp256r1.d.ts.map +1 -1
- package/dist/types/src/utils/time.d.ts +21 -13
- package/dist/types/src/utils/time.d.ts.map +1 -1
- package/dist/types/tests/core/constants.spec.d.ts +2 -0
- package/dist/types/tests/core/constants.spec.d.ts.map +1 -0
- package/dist/types/tests/core/encryption-control.spec.d.ts +2 -0
- package/dist/types/tests/core/encryption-control.spec.d.ts.map +1 -0
- package/dist/types/tests/dwn.spec.d.ts.map +1 -1
- package/dist/types/tests/event-emitter-wake-publisher.spec.d.ts +2 -0
- package/dist/types/tests/event-emitter-wake-publisher.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/messages-query.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/protocols-configure.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/end-to-end-tests.spec.d.ts.map +1 -1
- package/dist/types/tests/store/blockstore-utils.spec.d.ts +2 -0
- package/dist/types/tests/store/blockstore-utils.spec.d.ts.map +1 -0
- package/dist/types/tests/test-stores.d.ts.map +1 -1
- package/dist/types/tests/utils/encryption-control-test-utils.d.ts +46 -0
- package/dist/types/tests/utils/encryption-control-test-utils.d.ts.map +1 -0
- package/dist/types/tests/utils/grant-key-coverage.spec.d.ts +2 -0
- package/dist/types/tests/utils/grant-key-coverage.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/test-data-generator.d.ts.map +1 -1
- package/dist/types/tests/validation/json-schemas/encryption/audience.spec.d.ts +2 -0
- package/dist/types/tests/validation/json-schemas/encryption/audience.spec.d.ts.map +1 -0
- package/dist/types/tests/validation/json-schemas/encryption/delivery.spec.d.ts +2 -0
- package/dist/types/tests/validation/json-schemas/encryption/delivery.spec.d.ts.map +1 -0
- package/package.json +47 -28
- package/src/core/constants.ts +61 -0
- package/src/core/dwn-error.ts +28 -11
- package/src/core/encryption-control.ts +1249 -0
- package/src/core/message.ts +7 -0
- package/src/core/messages-grant-authorization.ts +60 -9
- package/src/core/protocol-authorization-action.ts +3 -13
- package/src/core/protocol-authorization-validation.ts +66 -46
- package/src/core/protocol-authorization.ts +7 -0
- package/src/core/recording-validation-state-reader.ts +4 -5
- package/src/core/replication-apply.ts +77 -133
- package/src/core/validation-state-reader.ts +6 -8
- package/src/dwn.ts +1 -2
- package/src/event-stream/event-emitter-wake-publisher.ts +10 -14
- package/src/handlers/messages-query.ts +6 -22
- package/src/handlers/messages-read.ts +4 -3
- package/src/handlers/messages-subscribe.ts +34 -30
- package/src/handlers/protocols-configure.ts +7 -4
- package/src/handlers/records-count.ts +111 -10
- package/src/handlers/records-delete.ts +15 -0
- package/src/handlers/records-query.ts +176 -20
- package/src/handlers/records-read.ts +19 -6
- package/src/handlers/records-subscribe.ts +158 -8
- package/src/handlers/records-write.ts +19 -0
- package/src/index.ts +48 -21
- package/src/interfaces/protocols-configure.ts +102 -11
- package/src/interfaces/records-write.ts +49 -43
- package/src/jose/algorithms/signing/ed25519.ts +7 -6
- package/src/jose/jws/general/verifier.ts +3 -3
- package/src/protocols/encryption.ts +50 -420
- package/src/store/blockstore-level.ts +33 -37
- package/src/store/blockstore-mock.ts +24 -38
- package/src/store/blockstore-utils.ts +85 -0
- package/src/store/blockstore.ts +8 -0
- package/src/store/data-store-level.ts +5 -12
- package/src/store/level.ts +19 -0
- package/src/types/cache.ts +3 -3
- package/src/types/encryption-types.ts +39 -2
- package/src/types/validation-state-reader.ts +3 -5
- package/src/utils/data-stream.ts +29 -1
- package/src/utils/encryption.ts +247 -69
- package/src/utils/grant-key-coverage.ts +303 -0
- package/src/utils/hd-key.ts +1 -2
- package/src/utils/jws.ts +8 -2
- package/src/utils/memory-cache.ts +42 -11
- package/src/utils/protocols.ts +32 -0
- package/src/utils/record-limit-occupancy.ts +34 -5
- package/src/utils/records.ts +36 -2
- package/src/utils/secp256k1.ts +12 -12
- package/src/utils/secp256r1.ts +12 -22
- package/src/utils/time.ts +145 -27
- package/src/types/mitt.d.ts +0 -28
|
@@ -1,95 +1,33 @@
|
|
|
1
1
|
import type { CoreProtocol } from '../core/core-protocol.js';
|
|
2
2
|
import type { Filter } from '../types/query-types.js';
|
|
3
|
-
import type { GenericSignaturePayload } from '../types/message-types.js';
|
|
4
3
|
import type { MessagesFilter } from '../types/messages-types.js';
|
|
5
4
|
import type { PermissionGrant } from './permission-grant.js';
|
|
6
5
|
import type { PermissionScope } from '../types/permission-types.js';
|
|
7
|
-
import type {
|
|
6
|
+
import type { ProtocolDefinition } from '../types/protocols-types.js';
|
|
8
7
|
import type { RecordsWriteMessage } from '../types/records-types.js';
|
|
9
8
|
import type { ValidationStateReader } from '../types/validation-state-reader.js';
|
|
10
|
-
import type { ProtocolActionRule, ProtocolDefinition, ProtocolRuleSet } from '../types/protocols-types.js';
|
|
11
9
|
|
|
12
|
-
import { checkActor } from '../core/protocol-authorization-action.js';
|
|
13
|
-
import { Encoder } from '../utils/encoder.js';
|
|
14
|
-
import { Encryption } from '../utils/encryption.js';
|
|
15
10
|
import { ENCRYPTION_PROTOCOL_URI } from '../core/constants.js';
|
|
16
11
|
import { FilterUtility } from '../utils/filter.js';
|
|
17
|
-
import { Jws } from '../utils/jws.js';
|
|
18
12
|
import { Message } from '../core/message.js';
|
|
19
13
|
import { Records } from '../utils/records.js';
|
|
20
|
-
import { validateJsonSchema } from '../schema-validator.js';
|
|
21
14
|
import { DwnError, DwnErrorCode } from '../core/dwn-error.js';
|
|
22
|
-
import {
|
|
23
|
-
import { getRuleSetAtPath, isCrossProtocolRef, parseCrossProtocolRef } from '../utils/protocols.js';
|
|
24
|
-
import { ProtocolAction, ProtocolActor } from '../types/protocols-types.js';
|
|
25
|
-
|
|
26
|
-
type AudienceTags = {
|
|
27
|
-
protocol: string;
|
|
28
|
-
contextId: string;
|
|
29
|
-
role: string;
|
|
30
|
-
epoch: number;
|
|
31
|
-
keyId: string;
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
type AudienceEpochData = AudienceTags & {
|
|
35
|
-
publicKeyJwk: PublicKeyJwk;
|
|
36
|
-
};
|
|
15
|
+
import { grantKeyScopeCoversDeliveredScope, isGrantKeyEligibleRecordsScope, isGrantKeyRecordsScope } from '../utils/grant-key-coverage.js';
|
|
37
16
|
|
|
38
17
|
export class EncryptionProtocol implements CoreProtocol {
|
|
39
18
|
public static readonly uri = ENCRYPTION_PROTOCOL_URI;
|
|
40
|
-
public static readonly audienceEpochPath = 'audienceEpoch';
|
|
41
|
-
public static readonly audienceKeyPath = 'audienceKey';
|
|
42
19
|
public static readonly grantKeyPath = 'grantKey';
|
|
43
20
|
|
|
44
21
|
public static readonly definition: ProtocolDefinition = {
|
|
45
22
|
published : true,
|
|
46
23
|
protocol : EncryptionProtocol.uri,
|
|
47
24
|
types : {
|
|
48
|
-
audienceEpoch: {
|
|
49
|
-
dataFormats : ['application/json'],
|
|
50
|
-
schema : 'https://identity.foundation/dwn/json-schemas/encryption/audience-epoch.json',
|
|
51
|
-
},
|
|
52
|
-
audienceKey: {
|
|
53
|
-
dataFormats : ['application/json'],
|
|
54
|
-
schema : 'https://identity.foundation/dwn/json-schemas/encryption/audience-key.json',
|
|
55
|
-
},
|
|
56
25
|
grantKey: {
|
|
57
26
|
dataFormats : ['application/json'],
|
|
58
27
|
schema : 'https://identity.foundation/dwn/json-schemas/encryption/grant-key.json',
|
|
59
28
|
},
|
|
60
29
|
},
|
|
61
30
|
structure: {
|
|
62
|
-
audienceEpoch: {
|
|
63
|
-
$actions: [
|
|
64
|
-
{ can: ['create', 'read'], who: 'anyone' },
|
|
65
|
-
],
|
|
66
|
-
$immutable : true,
|
|
67
|
-
$tags : {
|
|
68
|
-
$allowUndefinedTags : false,
|
|
69
|
-
$requiredTags : ['protocol', 'contextId', 'role', 'epoch', 'keyId'],
|
|
70
|
-
contextId : { type: 'string' },
|
|
71
|
-
epoch : { minimum: 1, type: 'integer' },
|
|
72
|
-
keyId : { pattern: '^[A-Za-z0-9_-]{43}$', type: 'string' },
|
|
73
|
-
protocol : { type: 'string' },
|
|
74
|
-
role : { type: 'string' },
|
|
75
|
-
},
|
|
76
|
-
},
|
|
77
|
-
audienceKey: {
|
|
78
|
-
$actions: [
|
|
79
|
-
{ can: ['create'], who: 'anyone' },
|
|
80
|
-
{ can: ['read'], of: 'audienceKey', who: 'recipient' },
|
|
81
|
-
],
|
|
82
|
-
$immutable : true,
|
|
83
|
-
$tags : {
|
|
84
|
-
$allowUndefinedTags : false,
|
|
85
|
-
$requiredTags : ['protocol', 'contextId', 'role', 'epoch', 'keyId'],
|
|
86
|
-
contextId : { type: 'string' },
|
|
87
|
-
epoch : { minimum: 1, type: 'integer' },
|
|
88
|
-
keyId : { pattern: '^[A-Za-z0-9_-]{43}$', type: 'string' },
|
|
89
|
-
protocol : { type: 'string' },
|
|
90
|
-
role : { type: 'string' },
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
31
|
grantKey: {
|
|
94
32
|
$actions: [
|
|
95
33
|
{ can: ['create'], who: 'anyone' },
|
|
@@ -121,119 +59,21 @@ export class EncryptionProtocol implements CoreProtocol {
|
|
|
121
59
|
message: RecordsWriteMessage,
|
|
122
60
|
validationStateReader: ValidationStateReader,
|
|
123
61
|
): Promise<void> {
|
|
124
|
-
|
|
125
|
-
case EncryptionProtocol.audienceEpochPath:
|
|
126
|
-
await EncryptionProtocol.preProcessAudienceEpoch(tenant, message, validationStateReader);
|
|
127
|
-
return;
|
|
128
|
-
case EncryptionProtocol.audienceKeyPath:
|
|
129
|
-
await EncryptionProtocol.preProcessAudienceKey(tenant, message, validationStateReader);
|
|
130
|
-
return;
|
|
131
|
-
case EncryptionProtocol.grantKeyPath:
|
|
62
|
+
if (message.descriptor.protocolPath === EncryptionProtocol.grantKeyPath) {
|
|
132
63
|
await EncryptionProtocol.preProcessGrantKey(tenant, message, validationStateReader);
|
|
133
|
-
return;
|
|
134
|
-
default:
|
|
135
|
-
return;
|
|
136
64
|
}
|
|
137
65
|
}
|
|
138
66
|
|
|
139
|
-
public async validateRecord(message: RecordsWriteMessage,
|
|
140
|
-
|
|
141
|
-
case EncryptionProtocol.audienceEpochPath:
|
|
142
|
-
await EncryptionProtocol.validateAudienceEpoch(message, dataBytes);
|
|
143
|
-
return;
|
|
144
|
-
case EncryptionProtocol.audienceKeyPath:
|
|
145
|
-
case EncryptionProtocol.grantKeyPath:
|
|
67
|
+
public async validateRecord(message: RecordsWriteMessage, _dataBytes: Uint8Array): Promise<void> {
|
|
68
|
+
if (message.descriptor.protocolPath === EncryptionProtocol.grantKeyPath) {
|
|
146
69
|
EncryptionProtocol.verifyEncryptedDelivery(message);
|
|
147
70
|
return;
|
|
148
|
-
default:
|
|
149
|
-
throw new DwnError(
|
|
150
|
-
DwnErrorCode.EncryptionProtocolValidateSchemaUnexpectedRecord,
|
|
151
|
-
`Unexpected encryption record: ${message.descriptor.protocolPath}`
|
|
152
|
-
);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
private static async preProcessAudienceEpoch(
|
|
157
|
-
tenant: string,
|
|
158
|
-
message: RecordsWriteMessage,
|
|
159
|
-
validationStateReader: ValidationStateReader,
|
|
160
|
-
): Promise<void> {
|
|
161
|
-
if (message.encryption !== undefined) {
|
|
162
|
-
throw new DwnError(
|
|
163
|
-
DwnErrorCode.EncryptionProtocolValidateAudienceEpochEncrypted,
|
|
164
|
-
'audienceEpoch records must be plaintext.'
|
|
165
|
-
);
|
|
166
71
|
}
|
|
167
72
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
message,
|
|
173
|
-
tags,
|
|
174
|
-
ruleSet,
|
|
175
|
-
protocolDefinition,
|
|
176
|
-
validationStateReader,
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
private static async preProcessAudienceKey(
|
|
182
|
-
tenant: string,
|
|
183
|
-
message: RecordsWriteMessage,
|
|
184
|
-
validationStateReader: ValidationStateReader,
|
|
185
|
-
): Promise<void> {
|
|
186
|
-
EncryptionProtocol.verifyEncryptedDelivery(message);
|
|
187
|
-
|
|
188
|
-
const recipient = message.descriptor.recipient;
|
|
189
|
-
if (recipient === undefined) {
|
|
190
|
-
throw new DwnError(
|
|
191
|
-
DwnErrorCode.EncryptionProtocolValidateAudienceKeyRecipientMissing,
|
|
192
|
-
'audienceKey records must have a recipient.'
|
|
193
|
-
);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
const tags = EncryptionProtocol.getAudienceTags(message, 'audienceKey');
|
|
197
|
-
const { ruleSet, protocolDefinition } = await EncryptionProtocol.verifyRoleAudienceDefinition(tenant, tags, message, validationStateReader);
|
|
198
|
-
await EncryptionProtocol.verifyWriterCanCreateRole({
|
|
199
|
-
tenant,
|
|
200
|
-
message,
|
|
201
|
-
tags,
|
|
202
|
-
ruleSet,
|
|
203
|
-
protocolDefinition,
|
|
204
|
-
validationStateReader,
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
const matchingEpochs = await validationStateReader.queryAudienceEpochs({
|
|
208
|
-
tenant,
|
|
209
|
-
protocol : tags.protocol,
|
|
210
|
-
contextId : tags.contextId,
|
|
211
|
-
role : tags.role,
|
|
212
|
-
epoch : tags.epoch,
|
|
213
|
-
keyId : tags.keyId,
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
if (matchingEpochs.length === 0) {
|
|
217
|
-
throw new DwnError(
|
|
218
|
-
DwnErrorCode.EncryptionProtocolValidateAudienceEpochMissing,
|
|
219
|
-
'audienceKey references a missing audienceEpoch.'
|
|
220
|
-
);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
const hasRoleRecord = await validationStateReader.hasMatchingRoleRecord({
|
|
224
|
-
tenant,
|
|
225
|
-
protocol : tags.protocol,
|
|
226
|
-
protocolPath : tags.role,
|
|
227
|
-
recipient,
|
|
228
|
-
contextIdPrefix : tags.contextId === '' ? undefined : tags.contextId,
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
if (!hasRoleRecord) {
|
|
232
|
-
throw new DwnError(
|
|
233
|
-
DwnErrorCode.EncryptionProtocolValidateAudienceKeyRoleRecordMissing,
|
|
234
|
-
'audienceKey recipient is not an active holder of the referenced role.'
|
|
235
|
-
);
|
|
236
|
-
}
|
|
73
|
+
throw new DwnError(
|
|
74
|
+
DwnErrorCode.EncryptionProtocolValidateSchemaUnexpectedRecord,
|
|
75
|
+
`Unexpected encryption record: ${message.descriptor.protocolPath}`
|
|
76
|
+
);
|
|
237
77
|
}
|
|
238
78
|
|
|
239
79
|
private static async preProcessGrantKey(
|
|
@@ -252,7 +92,14 @@ export class EncryptionProtocol implements CoreProtocol {
|
|
|
252
92
|
await EncryptionProtocol.verifyGrantActive(tenant, message, grant, validationStateReader);
|
|
253
93
|
EncryptionProtocol.verifyGrantKeyAuthor(message, grant);
|
|
254
94
|
EncryptionProtocol.verifyGrantKeyRecipient(message, grant);
|
|
255
|
-
EncryptionProtocol.verifyGrantKeyScope(
|
|
95
|
+
await EncryptionProtocol.verifyGrantKeyScope({
|
|
96
|
+
tenant,
|
|
97
|
+
message,
|
|
98
|
+
grantScope: grant.scope,
|
|
99
|
+
protocol,
|
|
100
|
+
protocolPath,
|
|
101
|
+
validationStateReader,
|
|
102
|
+
});
|
|
256
103
|
}
|
|
257
104
|
|
|
258
105
|
private static verifyEncryptedDelivery(message: RecordsWriteMessage): void {
|
|
@@ -264,79 +111,18 @@ export class EncryptionProtocol implements CoreProtocol {
|
|
|
264
111
|
}
|
|
265
112
|
}
|
|
266
113
|
|
|
267
|
-
private static
|
|
268
|
-
if (message.encryption !== undefined) {
|
|
269
|
-
throw new DwnError(
|
|
270
|
-
DwnErrorCode.EncryptionProtocolValidateAudienceEpochEncrypted,
|
|
271
|
-
'audienceEpoch records must be plaintext.'
|
|
272
|
-
);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
const dataObject = JSON.parse(Encoder.bytesToString(dataBytes)) as AudienceEpochData;
|
|
276
|
-
validateJsonSchema('AudienceEpoch', dataObject);
|
|
277
|
-
|
|
278
|
-
const tags = EncryptionProtocol.getAudienceTags(message, 'audienceEpoch');
|
|
279
|
-
EncryptionProtocol.verifyAudiencePayloadMatchesTags(dataObject, tags);
|
|
280
|
-
|
|
281
|
-
const keyId = await Encryption.getKeyId(dataObject.publicKeyJwk);
|
|
282
|
-
if (keyId !== dataObject.keyId) {
|
|
283
|
-
throw new DwnError(
|
|
284
|
-
DwnErrorCode.EncryptionProtocolValidateAudienceEpochKeyIdMismatch,
|
|
285
|
-
'audienceEpoch keyId must match publicKeyJwk thumbprint.'
|
|
286
|
-
);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
private static verifyAudiencePayloadMatchesTags(payload: AudienceTags, tags: AudienceTags): void {
|
|
291
|
-
if (payload.protocol !== tags.protocol ||
|
|
292
|
-
payload.contextId !== tags.contextId ||
|
|
293
|
-
payload.role !== tags.role ||
|
|
294
|
-
payload.epoch !== tags.epoch ||
|
|
295
|
-
payload.keyId !== tags.keyId) {
|
|
296
|
-
throw new DwnError(
|
|
297
|
-
DwnErrorCode.EncryptionProtocolValidateAudienceTagsMismatch,
|
|
298
|
-
'audienceEpoch tags must match payload fields.'
|
|
299
|
-
);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
private static getRequiredStringTag(message: RecordsWriteMessage, tag: string, recordType = 'grantKey'): string {
|
|
114
|
+
private static getRequiredStringTag(message: RecordsWriteMessage, tag: string): string {
|
|
304
115
|
const value = message.descriptor.tags?.[tag];
|
|
305
116
|
if (typeof value !== 'string') {
|
|
306
|
-
const errorCode = recordType === 'grantKey'
|
|
307
|
-
? DwnErrorCode.EncryptionProtocolValidateGrantKeyMissingRequiredTag
|
|
308
|
-
: DwnErrorCode.EncryptionProtocolValidateAudienceMissingRequiredTag;
|
|
309
117
|
throw new DwnError(
|
|
310
|
-
|
|
311
|
-
|
|
118
|
+
DwnErrorCode.EncryptionProtocolValidateGrantKeyMissingRequiredTag,
|
|
119
|
+
`grantKey records must include string tag '${tag}'.`
|
|
312
120
|
);
|
|
313
121
|
}
|
|
314
122
|
|
|
315
123
|
return value;
|
|
316
124
|
}
|
|
317
125
|
|
|
318
|
-
private static getRequiredIntegerTag(message: RecordsWriteMessage, tag: string, recordType: string): number {
|
|
319
|
-
const value = message.descriptor.tags?.[tag];
|
|
320
|
-
if (!Number.isInteger(value)) {
|
|
321
|
-
throw new DwnError(
|
|
322
|
-
DwnErrorCode.EncryptionProtocolValidateAudienceMissingRequiredTag,
|
|
323
|
-
`${recordType} records must include integer tag '${tag}'.`
|
|
324
|
-
);
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
return value as number;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
private static getAudienceTags(message: RecordsWriteMessage, recordType: string): AudienceTags {
|
|
331
|
-
return {
|
|
332
|
-
protocol : EncryptionProtocol.getRequiredStringTag(message, 'protocol', recordType),
|
|
333
|
-
contextId : EncryptionProtocol.getRequiredStringTag(message, 'contextId', recordType),
|
|
334
|
-
role : EncryptionProtocol.getRequiredStringTag(message, 'role', recordType),
|
|
335
|
-
epoch : EncryptionProtocol.getRequiredIntegerTag(message, 'epoch', recordType),
|
|
336
|
-
keyId : EncryptionProtocol.getRequiredStringTag(message, 'keyId', recordType),
|
|
337
|
-
};
|
|
338
|
-
}
|
|
339
|
-
|
|
340
126
|
private static getOptionalStringTag(message: RecordsWriteMessage, tag: string): string | undefined {
|
|
341
127
|
const value = message.descriptor.tags?.[tag];
|
|
342
128
|
if (value === undefined) {
|
|
@@ -405,220 +191,64 @@ export class EncryptionProtocol implements CoreProtocol {
|
|
|
405
191
|
);
|
|
406
192
|
}
|
|
407
193
|
|
|
408
|
-
private static verifyGrantKeyScope(
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
194
|
+
private static async verifyGrantKeyScope(params: {
|
|
195
|
+
tenant: string;
|
|
196
|
+
message: RecordsWriteMessage;
|
|
197
|
+
grantScope: PermissionScope;
|
|
198
|
+
protocol: string;
|
|
199
|
+
protocolPath: string | undefined;
|
|
200
|
+
validationStateReader: ValidationStateReader;
|
|
201
|
+
}): Promise<void> {
|
|
202
|
+
const { grantScope, protocol, protocolPath } = params;
|
|
415
203
|
|
|
416
|
-
if (
|
|
204
|
+
if (!isGrantKeyRecordsScope(grantScope)) {
|
|
417
205
|
throw new DwnError(
|
|
418
206
|
DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch,
|
|
419
|
-
|
|
207
|
+
'grantKey must reference a Records.Read or Records.Write permission grant.'
|
|
420
208
|
);
|
|
421
209
|
}
|
|
422
210
|
|
|
423
|
-
if (!(
|
|
424
|
-
return;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
if (protocolPath === undefined || !EncryptionProtocol.isBoundaryAwareSubtree(grantScope.protocolPath, protocolPath)) {
|
|
211
|
+
if (!isGrantKeyEligibleRecordsScope(grantScope)) {
|
|
428
212
|
throw new DwnError(
|
|
429
213
|
DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch,
|
|
430
|
-
|
|
431
|
-
);
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
private static isReadScope(scope: PermissionScope): boolean {
|
|
436
|
-
return (scope.interface === DwnInterfaceName.Records || scope.interface === DwnInterfaceName.Messages) &&
|
|
437
|
-
scope.method === DwnMethodName.Read;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
private static isBoundaryAwareSubtree(scopePath: string, candidatePath: string): boolean {
|
|
441
|
-
return candidatePath === scopePath || candidatePath.startsWith(scopePath + '/');
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
private static async verifyRoleAudienceDefinition(
|
|
445
|
-
tenant: string,
|
|
446
|
-
tags: AudienceTags,
|
|
447
|
-
message: RecordsWriteMessage,
|
|
448
|
-
validationStateReader: ValidationStateReader,
|
|
449
|
-
): Promise<{ protocolDefinition: ProtocolDefinition; ruleSet: ProtocolRuleSet }> {
|
|
450
|
-
EncryptionProtocol.verifyRoleAudienceContext(tags.role, tags.contextId);
|
|
451
|
-
|
|
452
|
-
const protocolDefinition = await validationStateReader.fetchProtocolDefinition(
|
|
453
|
-
tenant,
|
|
454
|
-
tags.protocol,
|
|
455
|
-
message.descriptor.messageTimestamp,
|
|
456
|
-
);
|
|
457
|
-
const ruleSet = getRuleSetAtPath(tags.role, protocolDefinition.structure);
|
|
458
|
-
|
|
459
|
-
if (ruleSet?.$role !== true || ruleSet.$keyAgreement === undefined) {
|
|
460
|
-
throw new DwnError(
|
|
461
|
-
DwnErrorCode.EncryptionProtocolValidateRoleAudienceInvalid,
|
|
462
|
-
`role audience path '${tags.role}' must be a role path with $keyAgreement.`
|
|
214
|
+
'grantKey must not reference a context-scoped permission grant.'
|
|
463
215
|
);
|
|
464
216
|
}
|
|
465
217
|
|
|
466
|
-
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
private static verifyRoleAudienceContext(rolePath: string, contextId: string): void {
|
|
470
|
-
const parentDepth = rolePath.split('/').length - 1;
|
|
471
|
-
if ((parentDepth === 0 && contextId !== '') || (parentDepth > 0 && contextId === '')) {
|
|
218
|
+
if (grantScope.protocol !== protocol) {
|
|
472
219
|
throw new DwnError(
|
|
473
|
-
DwnErrorCode.
|
|
474
|
-
|
|
220
|
+
DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch,
|
|
221
|
+
`grantKey protocol ${protocol} is outside the permission grant scope.`
|
|
475
222
|
);
|
|
476
223
|
}
|
|
477
|
-
}
|
|
478
224
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
message: RecordsWriteMessage;
|
|
482
|
-
tags: AudienceTags;
|
|
483
|
-
ruleSet: ProtocolRuleSet;
|
|
484
|
-
protocolDefinition: ProtocolDefinition;
|
|
485
|
-
validationStateReader: ValidationStateReader;
|
|
486
|
-
}): Promise<void> {
|
|
487
|
-
const author = Message.getAuthor(input.message);
|
|
488
|
-
if (author === input.tenant) {
|
|
225
|
+
const deliveredScope = { protocol, protocolPath };
|
|
226
|
+
if (grantKeyScopeCoversDeliveredScope({ grantScope, deliveredScope })) {
|
|
489
227
|
return;
|
|
490
228
|
}
|
|
491
229
|
|
|
492
|
-
if (
|
|
230
|
+
if (protocolPath === undefined) {
|
|
493
231
|
throw new DwnError(
|
|
494
|
-
DwnErrorCode.
|
|
495
|
-
|
|
232
|
+
DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch,
|
|
233
|
+
`grantKey protocolPath ${protocolPath ?? '<protocol>'} is outside the permission grant scope.`
|
|
496
234
|
);
|
|
497
235
|
}
|
|
498
236
|
|
|
499
|
-
const
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
if (actionRule.who === ProtocolActor.Anyone) {
|
|
509
|
-
return;
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
if (await EncryptionProtocol.roleRuleAllowsAuthor(
|
|
513
|
-
input.tenant,
|
|
514
|
-
author,
|
|
515
|
-
actionRule,
|
|
516
|
-
input.tags,
|
|
517
|
-
input.protocolDefinition,
|
|
518
|
-
input.validationStateReader,
|
|
519
|
-
signaturePayload.protocolRole,
|
|
520
|
-
)) {
|
|
521
|
-
return;
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
if (await checkActor(author, actionRule, recordChain, input.protocolDefinition)) {
|
|
525
|
-
return;
|
|
526
|
-
}
|
|
237
|
+
const protocolDefinition = await params.validationStateReader.fetchProtocolDefinition(
|
|
238
|
+
params.tenant,
|
|
239
|
+
params.protocol,
|
|
240
|
+
params.message.descriptor.messageTimestamp,
|
|
241
|
+
);
|
|
242
|
+
if (grantKeyScopeCoversDeliveredScope({ grantScope, deliveredScope, protocolDefinition })) {
|
|
243
|
+
return;
|
|
527
244
|
}
|
|
528
245
|
|
|
529
246
|
throw new DwnError(
|
|
530
|
-
DwnErrorCode.
|
|
531
|
-
|
|
247
|
+
DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch,
|
|
248
|
+
`grantKey protocolPath ${protocolPath ?? '<protocol>'} is outside the permission grant scope.`
|
|
532
249
|
);
|
|
533
250
|
}
|
|
534
251
|
|
|
535
|
-
private static async constructRoleParentChain(
|
|
536
|
-
tenant: string,
|
|
537
|
-
tags: AudienceTags,
|
|
538
|
-
validationStateReader: ValidationStateReader,
|
|
539
|
-
): Promise<RecordsWriteMessage[]> {
|
|
540
|
-
if (tags.contextId === '') {
|
|
541
|
-
return [];
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
const parentRecordId = tags.contextId.split('/').pop();
|
|
545
|
-
if (parentRecordId === undefined || parentRecordId === '') {
|
|
546
|
-
return [];
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
return validationStateReader.constructRecordChain(tenant, parentRecordId);
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
private static async roleRuleAllowsAuthor(
|
|
553
|
-
tenant: string,
|
|
554
|
-
author: string,
|
|
555
|
-
actionRule: ProtocolActionRule,
|
|
556
|
-
tags: AudienceTags,
|
|
557
|
-
protocolDefinition: ProtocolDefinition,
|
|
558
|
-
validationStateReader: ValidationStateReader,
|
|
559
|
-
invokedRole: string | undefined,
|
|
560
|
-
): Promise<boolean> {
|
|
561
|
-
if (actionRule.role === undefined || invokedRole !== actionRule.role) {
|
|
562
|
-
return false;
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
const roleRef = actionRule.role;
|
|
566
|
-
return EncryptionProtocol.hasInvokedRole(tenant, author, roleRef, tags, protocolDefinition, validationStateReader);
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
private static async hasInvokedRole(
|
|
570
|
-
tenant: string,
|
|
571
|
-
author: string,
|
|
572
|
-
roleRef: string,
|
|
573
|
-
tags: AudienceTags,
|
|
574
|
-
protocolDefinition: ProtocolDefinition,
|
|
575
|
-
validationStateReader: ValidationStateReader,
|
|
576
|
-
): Promise<boolean> {
|
|
577
|
-
const resolved = EncryptionProtocol.resolveRoleReference(roleRef, tags.protocol, protocolDefinition);
|
|
578
|
-
if (resolved === undefined) {
|
|
579
|
-
return false;
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
const ancestorDepth = resolved.protocolPath.split('/').length - 1;
|
|
583
|
-
let contextIdPrefix: string | undefined;
|
|
584
|
-
if (ancestorDepth > 0) {
|
|
585
|
-
contextIdPrefix = tags.contextId.split('/').slice(0, ancestorDepth).join('/');
|
|
586
|
-
if (contextIdPrefix === '') {
|
|
587
|
-
return false;
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
return validationStateReader.hasMatchingRoleRecord({
|
|
592
|
-
tenant,
|
|
593
|
-
protocol : resolved.protocol,
|
|
594
|
-
protocolPath : resolved.protocolPath,
|
|
595
|
-
recipient : author,
|
|
596
|
-
contextIdPrefix,
|
|
597
|
-
});
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
private static resolveRoleReference(
|
|
601
|
-
roleRef: string,
|
|
602
|
-
currentProtocol: string,
|
|
603
|
-
protocolDefinition: ProtocolDefinition,
|
|
604
|
-
): { protocol: string; protocolPath: string } | undefined {
|
|
605
|
-
if (!isCrossProtocolRef(roleRef)) {
|
|
606
|
-
return { protocol: currentProtocol, protocolPath: roleRef };
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
const parsed = parseCrossProtocolRef(roleRef);
|
|
610
|
-
if (parsed === undefined) {
|
|
611
|
-
return undefined;
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
const protocol = protocolDefinition.uses?.[parsed.alias];
|
|
615
|
-
if (protocol === undefined) {
|
|
616
|
-
return undefined;
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
return { protocol, protocolPath: parsed.protocolPath };
|
|
620
|
-
}
|
|
621
|
-
|
|
622
252
|
public mapErrorToStatusCode(errorCode: string): number | undefined {
|
|
623
253
|
if (errorCode.startsWith('EncryptionProtocolValidate')) {
|
|
624
254
|
return 400;
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type {
|
|
3
|
-
import type { Blockstore, Pair } from 'interface-blockstore';
|
|
1
|
+
import type { Blockstore, InputPair, Pair } from 'interface-blockstore';
|
|
2
|
+
import type { BlockstoreAbortOptions, BlockstoreInput, BlockstoreSource } from './blockstore-utils.js';
|
|
4
3
|
|
|
4
|
+
import { CID } from 'multiformats';
|
|
5
|
+
import { NotFoundError } from 'interface-store';
|
|
6
|
+
import {
|
|
7
|
+
collectBlockstoreBytes,
|
|
8
|
+
deleteManyBlockstoreItems,
|
|
9
|
+
getManyBlockstoreItems,
|
|
10
|
+
putManyBlockstoreItems,
|
|
11
|
+
yieldBlockstoreBytes,
|
|
12
|
+
} from './blockstore-utils.js';
|
|
5
13
|
import { createLevelDatabase, LevelWrapper } from './level-wrapper.js';
|
|
6
14
|
|
|
7
15
|
// `level` works in Node.js 12+ and Electron 5+ on Linux, Mac OS, Windows and
|
|
@@ -40,63 +48,51 @@ export class BlockstoreLevel implements Blockstore {
|
|
|
40
48
|
return new BlockstoreLevel({ ...this.config, location: '' }, db);
|
|
41
49
|
}
|
|
42
50
|
|
|
43
|
-
async put(key: CID | string, val:
|
|
44
|
-
await
|
|
51
|
+
async put(key: CID | string, val: BlockstoreInput, options?: BlockstoreAbortOptions): Promise<CID> {
|
|
52
|
+
const bytes = await collectBlockstoreBytes(val);
|
|
53
|
+
await this.db.put(String(key), bytes, options);
|
|
45
54
|
return CID.parse(key.toString());
|
|
46
55
|
}
|
|
47
56
|
|
|
48
|
-
async get(key: CID | string, options?:
|
|
57
|
+
async * get(key: CID | string, options?: BlockstoreAbortOptions): AsyncGenerator<Uint8Array> {
|
|
49
58
|
const result = await this.db.get(String(key), options);
|
|
50
|
-
|
|
59
|
+
if (result === undefined) {
|
|
60
|
+
throw new NotFoundError();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
yield result;
|
|
51
64
|
}
|
|
52
65
|
|
|
53
|
-
async has(key: CID | string, options?:
|
|
66
|
+
async has(key: CID | string, options?: BlockstoreAbortOptions): Promise<boolean> {
|
|
54
67
|
return this.db.has(String(key), options);
|
|
55
68
|
}
|
|
56
69
|
|
|
57
|
-
async delete(key: CID | string, options?:
|
|
70
|
+
async delete(key: CID | string, options?: BlockstoreAbortOptions): Promise<void> {
|
|
58
71
|
return this.db.delete(String(key), options);
|
|
59
72
|
}
|
|
60
73
|
|
|
61
|
-
async isEmpty(options?:
|
|
74
|
+
async isEmpty(options?: BlockstoreAbortOptions): Promise<boolean> {
|
|
62
75
|
return this.db.isEmpty(options);
|
|
63
76
|
}
|
|
64
77
|
|
|
65
|
-
async * putMany(source:
|
|
66
|
-
|
|
67
|
-
await this.put(entry.cid, entry.block, options);
|
|
68
|
-
|
|
69
|
-
yield entry.cid;
|
|
70
|
-
}
|
|
78
|
+
async * putMany(source: BlockstoreSource<InputPair>, options?: BlockstoreAbortOptions): AsyncGenerator<CID> {
|
|
79
|
+
yield * putManyBlockstoreItems(this, source, options);
|
|
71
80
|
}
|
|
72
81
|
|
|
73
|
-
async * getMany(source:
|
|
74
|
-
|
|
75
|
-
yield {
|
|
76
|
-
cid : key,
|
|
77
|
-
block : await this.get(key, options)
|
|
78
|
-
};
|
|
79
|
-
}
|
|
82
|
+
async * getMany(source: BlockstoreSource<CID>, options?: BlockstoreAbortOptions): AsyncGenerator<Pair> {
|
|
83
|
+
yield * getManyBlockstoreItems(this, source, options);
|
|
80
84
|
}
|
|
81
85
|
|
|
82
|
-
async * getAll(options?:
|
|
83
|
-
|
|
84
|
-
const li: AsyncGenerator<[Uint8Array, Uint8Array]> = this.db.iterator({
|
|
85
|
-
keys : true,
|
|
86
|
-
keyEncoding : 'buffer'
|
|
87
|
-
}, options);
|
|
86
|
+
async * getAll(options?: BlockstoreAbortOptions): AsyncGenerator<Pair> {
|
|
87
|
+
const li: AsyncGenerator<[string, Uint8Array]> = this.db.iterator({ keys: true }, options);
|
|
88
88
|
|
|
89
89
|
for await (const [key, value] of li) {
|
|
90
|
-
yield { cid: CID.
|
|
90
|
+
yield { cid: CID.parse(key), bytes: yieldBlockstoreBytes(value) };
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
async * deleteMany(source:
|
|
95
|
-
|
|
96
|
-
await this.delete(key, options);
|
|
97
|
-
|
|
98
|
-
yield key;
|
|
99
|
-
}
|
|
94
|
+
async * deleteMany(source: BlockstoreSource<CID>, options?: BlockstoreAbortOptions): AsyncGenerator<CID> {
|
|
95
|
+
yield * deleteManyBlockstoreItems(this, source, options);
|
|
100
96
|
}
|
|
101
97
|
|
|
102
98
|
/**
|
|
@@ -110,4 +106,4 @@ export class BlockstoreLevel implements Blockstore {
|
|
|
110
106
|
export type BlockstoreLevelConfig = {
|
|
111
107
|
location: string,
|
|
112
108
|
createLevelDatabase?: typeof createLevelDatabase,
|
|
113
|
-
};
|
|
109
|
+
};
|