@enbox/dwn-sdk-js 0.0.2 → 0.0.3
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 +52 -301
- package/dist/bundles/dwn.js +19 -21
- package/dist/esm/generated/precompiled-validators.js +2764 -1773
- package/dist/esm/generated/precompiled-validators.js.map +1 -1
- package/dist/esm/src/core/dwn-error.js +27 -3
- package/dist/esm/src/core/dwn-error.js.map +1 -1
- package/dist/esm/src/core/message.js.map +1 -1
- package/dist/esm/src/core/messages-grant-authorization.js +17 -6
- package/dist/esm/src/core/messages-grant-authorization.js.map +1 -1
- package/dist/esm/src/core/protocol-authorization.js +245 -69
- package/dist/esm/src/core/protocol-authorization.js.map +1 -1
- package/dist/esm/src/core/resumable-task-manager.js +4 -4
- package/dist/esm/src/core/resumable-task-manager.js.map +1 -1
- package/dist/esm/src/dwn.js +10 -8
- package/dist/esm/src/dwn.js.map +1 -1
- package/dist/esm/src/enums/dwn-interface-method.js +4 -2
- package/dist/esm/src/enums/dwn-interface-method.js.map +1 -1
- package/dist/esm/src/event-stream/event-emitter-stream.js.map +1 -0
- package/dist/esm/src/handlers/messages-subscribe.js +1 -1
- package/dist/esm/src/handlers/messages-subscribe.js.map +1 -1
- package/dist/esm/src/handlers/messages-sync.js +116 -0
- package/dist/esm/src/handlers/messages-sync.js.map +1 -0
- package/dist/esm/src/handlers/protocols-configure.js +149 -16
- package/dist/esm/src/handlers/protocols-configure.js.map +1 -1
- package/dist/esm/src/handlers/protocols-query.js +2 -2
- package/dist/esm/src/handlers/protocols-query.js.map +1 -1
- package/dist/esm/src/handlers/records-count.js +143 -0
- package/dist/esm/src/handlers/records-count.js.map +1 -0
- package/dist/esm/src/handlers/records-query.js +4 -0
- package/dist/esm/src/handlers/records-query.js.map +1 -1
- package/dist/esm/src/handlers/records-read.js +4 -6
- package/dist/esm/src/handlers/records-read.js.map +1 -1
- package/dist/esm/src/handlers/records-write.js +17 -18
- package/dist/esm/src/handlers/records-write.js.map +1 -1
- package/dist/esm/src/index.js +9 -5
- package/dist/esm/src/index.js.map +1 -1
- package/dist/esm/src/interfaces/messages-read.js +2 -7
- package/dist/esm/src/interfaces/messages-read.js.map +1 -1
- package/dist/esm/src/interfaces/messages-subscribe.js +1 -0
- package/dist/esm/src/interfaces/messages-subscribe.js.map +1 -1
- package/dist/esm/src/interfaces/{messages-query.js → messages-sync.js} +11 -12
- package/dist/esm/src/interfaces/messages-sync.js.map +1 -0
- package/dist/esm/src/interfaces/protocols-configure.js +153 -30
- package/dist/esm/src/interfaces/protocols-configure.js.map +1 -1
- package/dist/esm/src/interfaces/protocols-query.js +1 -0
- package/dist/esm/src/interfaces/protocols-query.js.map +1 -1
- package/dist/esm/src/interfaces/records-count.js +91 -0
- package/dist/esm/src/interfaces/records-count.js.map +1 -0
- package/dist/esm/src/interfaces/records-read.js +15 -1
- package/dist/esm/src/interfaces/records-read.js.map +1 -1
- package/dist/esm/src/interfaces/records-write.js +64 -15
- package/dist/esm/src/interfaces/records-write.js.map +1 -1
- package/dist/esm/src/jose/algorithms/signing/ed25519.js.map +1 -1
- package/dist/esm/src/jose/algorithms/signing/signature-algorithms.js.map +1 -1
- package/dist/esm/src/jose/jws/general/builder.js.map +1 -1
- package/dist/esm/src/jose/jws/general/verifier.js.map +1 -1
- package/dist/esm/src/protocols/permission-grant.js +30 -0
- package/dist/esm/src/protocols/permission-grant.js.map +1 -1
- package/dist/esm/src/protocols/permission-request.js +24 -0
- package/dist/esm/src/protocols/permission-request.js.map +1 -1
- package/dist/esm/src/protocols/permissions.js +1 -1
- package/dist/esm/src/protocols/permissions.js.map +1 -1
- package/dist/esm/src/schema-validator.js +0 -1
- package/dist/esm/src/schema-validator.js.map +1 -1
- package/dist/esm/src/smt/smt-store-level.js +125 -0
- package/dist/esm/src/smt/smt-store-level.js.map +1 -0
- package/dist/esm/src/smt/smt-store-memory.js +67 -0
- package/dist/esm/src/smt/smt-store-memory.js.map +1 -0
- package/dist/esm/src/smt/smt-utils.js +146 -0
- package/dist/esm/src/smt/smt-utils.js.map +1 -0
- package/dist/esm/src/smt/sparse-merkle-tree.js +622 -0
- package/dist/esm/src/smt/sparse-merkle-tree.js.map +1 -0
- package/dist/esm/src/state-index/state-index-level.js +228 -0
- package/dist/esm/src/state-index/state-index-level.js.map +1 -0
- package/dist/esm/src/store/data-store-level.js +6 -6
- package/dist/esm/src/store/data-store-level.js.map +1 -1
- package/dist/esm/src/store/index-level.js +375 -17
- package/dist/esm/src/store/index-level.js.map +1 -1
- package/dist/esm/src/store/message-store-level.js +56 -0
- package/dist/esm/src/store/message-store-level.js.map +1 -1
- package/dist/esm/src/store/storage-controller.js +19 -16
- package/dist/esm/src/store/storage-controller.js.map +1 -1
- package/dist/esm/src/types/encryption-types.js +2 -0
- package/dist/esm/src/types/encryption-types.js.map +1 -0
- package/dist/esm/src/types/message-types.js.map +1 -1
- package/dist/esm/src/types/protocols-types.js +0 -2
- package/dist/esm/src/types/protocols-types.js.map +1 -1
- package/dist/esm/src/types/records-types.js +2 -0
- package/dist/esm/src/types/records-types.js.map +1 -1
- package/dist/esm/src/types/smt-types.js +5 -0
- package/dist/esm/src/types/smt-types.js.map +1 -0
- package/dist/esm/src/types/state-index.js +2 -0
- package/dist/esm/src/types/state-index.js.map +1 -0
- package/dist/esm/src/utils/cid.js +2 -1
- package/dist/esm/src/utils/cid.js.map +1 -1
- package/dist/esm/src/utils/data-stream.js +84 -29
- package/dist/esm/src/utils/data-stream.js.map +1 -1
- package/dist/esm/src/utils/encryption.js +22 -31
- package/dist/esm/src/utils/encryption.js.map +1 -1
- package/dist/esm/src/utils/hd-key.js +3 -3
- package/dist/esm/src/utils/hd-key.js.map +1 -1
- package/dist/esm/src/utils/jws.js +4 -4
- package/dist/esm/src/utils/jws.js.map +1 -1
- package/dist/esm/src/utils/private-key-signer.js +4 -3
- package/dist/esm/src/utils/private-key-signer.js.map +1 -1
- package/dist/esm/src/utils/protocols.js +82 -9
- package/dist/esm/src/utils/protocols.js.map +1 -1
- package/dist/esm/src/utils/records.js +82 -26
- package/dist/esm/src/utils/records.js.map +1 -1
- package/dist/esm/src/utils/secp256k1.js +4 -3
- package/dist/esm/src/utils/secp256k1.js.map +1 -1
- package/dist/esm/src/utils/secp256r1.js +3 -2
- package/dist/esm/src/utils/secp256r1.js.map +1 -1
- package/dist/esm/src/utils/time.js +1 -1
- package/dist/esm/src/utils/url.js +1 -1
- package/dist/esm/src/utils/url.js.map +1 -1
- package/dist/esm/tests/core/auth.spec.js +2 -2
- package/dist/esm/tests/core/auth.spec.js.map +1 -1
- package/dist/esm/tests/core/message-reply.spec.js +3 -3
- package/dist/esm/tests/core/message-reply.spec.js.map +1 -1
- package/dist/esm/tests/core/message.spec.js +13 -13
- package/dist/esm/tests/core/message.spec.js.map +1 -1
- package/dist/esm/tests/core/protocol-authorization.spec.js +3 -3
- package/dist/esm/tests/core/protocol-authorization.spec.js.map +1 -1
- package/dist/esm/tests/dwn.spec.js +27 -37
- package/dist/esm/tests/dwn.spec.js.map +1 -1
- package/dist/esm/tests/{event-log → event-stream}/event-emitter-stream.spec.js +14 -15
- package/dist/esm/tests/event-stream/event-emitter-stream.spec.js.map +1 -0
- package/dist/esm/tests/{event-log → event-stream}/event-stream.spec.js +13 -15
- package/dist/esm/tests/event-stream/event-stream.spec.js.map +1 -0
- package/dist/esm/tests/features/author-delegated-grant.spec.js +281 -135
- package/dist/esm/tests/features/author-delegated-grant.spec.js.map +1 -1
- package/dist/esm/tests/features/owner-delegated-grant.spec.js +57 -59
- package/dist/esm/tests/features/owner-delegated-grant.spec.js.map +1 -1
- package/dist/esm/tests/features/owner-signature.spec.js +32 -34
- package/dist/esm/tests/features/owner-signature.spec.js.map +1 -1
- package/dist/esm/tests/features/permissions.spec.js +73 -95
- package/dist/esm/tests/features/permissions.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-composition.spec.js +1645 -0
- package/dist/esm/tests/features/protocol-composition.spec.js.map +1 -0
- package/dist/esm/tests/features/protocol-create-action.spec.js +25 -27
- package/dist/esm/tests/features/protocol-create-action.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-delete-action.spec.js +42 -44
- package/dist/esm/tests/features/protocol-delete-action.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-update-action.spec.js +53 -55
- package/dist/esm/tests/features/protocol-update-action.spec.js.map +1 -1
- package/dist/esm/tests/features/records-prune.spec.js +126 -100
- package/dist/esm/tests/features/records-prune.spec.js.map +1 -1
- package/dist/esm/tests/features/records-tags.spec.js +272 -272
- package/dist/esm/tests/features/records-tags.spec.js.map +1 -1
- package/dist/esm/tests/features/resumable-tasks.spec.js +35 -37
- package/dist/esm/tests/features/resumable-tasks.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-read.spec.js +112 -112
- package/dist/esm/tests/handlers/messages-read.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-subscribe.spec.js +78 -76
- package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-sync.spec.js +528 -0
- package/dist/esm/tests/handlers/messages-sync.spec.js.map +1 -0
- package/dist/esm/tests/handlers/protocols-configure.spec.js +545 -152
- package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -1
- package/dist/esm/tests/handlers/protocols-query.spec.js +70 -72
- package/dist/esm/tests/handlers/protocols-query.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-count.spec.js +313 -0
- package/dist/esm/tests/handlers/records-count.spec.js.map +1 -0
- package/dist/esm/tests/handlers/records-delete.spec.js +106 -109
- package/dist/esm/tests/handlers/records-delete.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-query.spec.js +863 -463
- package/dist/esm/tests/handlers/records-query.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-read.spec.js +439 -209
- package/dist/esm/tests/handlers/records-read.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-subscribe.spec.js +292 -97
- package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-write.spec.js +481 -483
- package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/messages-get.spec.js +31 -11
- package/dist/esm/tests/interfaces/messages-get.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/messages-subscribe.spec.js +5 -5
- package/dist/esm/tests/interfaces/messages-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/protocols-configure.spec.js +64 -134
- package/dist/esm/tests/interfaces/protocols-configure.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/protocols-query.spec.js +4 -6
- package/dist/esm/tests/interfaces/protocols-query.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-delete.spec.js +3 -5
- package/dist/esm/tests/interfaces/records-delete.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-query.spec.js +9 -11
- package/dist/esm/tests/interfaces/records-query.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-read.spec.js +76 -7
- package/dist/esm/tests/interfaces/records-read.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-subscribe.spec.js +7 -9
- package/dist/esm/tests/interfaces/records-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-write.spec.js +244 -48
- package/dist/esm/tests/interfaces/records-write.spec.js.map +1 -1
- package/dist/esm/tests/jose/jws/general.spec.js +15 -18
- package/dist/esm/tests/jose/jws/general.spec.js.map +1 -1
- package/dist/esm/tests/protocols/permission-grant.spec.js +114 -0
- package/dist/esm/tests/protocols/permission-grant.spec.js.map +1 -0
- package/dist/esm/tests/protocols/permission-request.spec.js +43 -7
- package/dist/esm/tests/protocols/permission-request.spec.js.map +1 -1
- package/dist/esm/tests/protocols/permissions.spec.js +9 -11
- package/dist/esm/tests/protocols/permissions.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/aggregator.spec.js +90 -92
- package/dist/esm/tests/scenarios/aggregator.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/deleted-record.spec.js +17 -19
- package/dist/esm/tests/scenarios/deleted-record.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js +27 -29
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/nested-roles.spec.js +37 -39
- package/dist/esm/tests/scenarios/nested-roles.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/subscriptions.spec.js +163 -163
- package/dist/esm/tests/scenarios/subscriptions.spec.js.map +1 -1
- package/dist/esm/tests/smt/smt-store-level.spec.js +143 -0
- package/dist/esm/tests/smt/smt-store-level.spec.js.map +1 -0
- package/dist/esm/tests/smt/sparse-merkle-tree.spec.js +741 -0
- package/dist/esm/tests/smt/sparse-merkle-tree.spec.js.map +1 -0
- package/dist/esm/tests/state-index/state-index-level.spec.js +254 -0
- package/dist/esm/tests/state-index/state-index-level.spec.js.map +1 -0
- package/dist/esm/tests/store/blockstore-level.spec.js +136 -0
- package/dist/esm/tests/store/blockstore-level.spec.js.map +1 -0
- package/dist/esm/tests/store/blockstore-mock.spec.js +29 -28
- package/dist/esm/tests/store/blockstore-mock.spec.js.map +1 -1
- package/dist/esm/tests/store/data-store-level.spec.js +23 -25
- package/dist/esm/tests/store/data-store-level.spec.js.map +1 -1
- package/dist/esm/tests/store/index-level.spec.js +544 -194
- package/dist/esm/tests/store/index-level.spec.js.map +1 -1
- package/dist/esm/tests/store/message-store-level.spec.js +4 -4
- package/dist/esm/tests/store/message-store-level.spec.js.map +1 -1
- package/dist/esm/tests/store/message-store.spec.js +147 -73
- package/dist/esm/tests/store/message-store.spec.js.map +1 -1
- package/dist/esm/tests/store-dependent-tests.spec.js +1 -0
- package/dist/esm/tests/store-dependent-tests.spec.js.map +1 -1
- package/dist/esm/tests/test-stores.js +5 -5
- package/dist/esm/tests/test-stores.js.map +1 -1
- package/dist/esm/tests/test-suite.js +9 -8
- package/dist/esm/tests/test-suite.js.map +1 -1
- package/dist/esm/tests/utils/cid.spec.js +8 -11
- package/dist/esm/tests/utils/cid.spec.js.map +1 -1
- package/dist/esm/tests/utils/data-stream.spec.js +167 -13
- package/dist/esm/tests/utils/data-stream.spec.js.map +1 -1
- package/dist/esm/tests/utils/encryption-callbacks.spec.js +233 -0
- package/dist/esm/tests/utils/encryption-callbacks.spec.js.map +1 -0
- package/dist/esm/tests/utils/encryption.spec.js +34 -85
- package/dist/esm/tests/utils/encryption.spec.js.map +1 -1
- package/dist/esm/tests/utils/filters.spec.js +67 -69
- package/dist/esm/tests/utils/filters.spec.js.map +1 -1
- package/dist/esm/tests/utils/hd-key.spec.js +3 -3
- package/dist/esm/tests/utils/hd-key.spec.js.map +1 -1
- package/dist/esm/tests/utils/jws.spec.js +54 -3
- package/dist/esm/tests/utils/jws.spec.js.map +1 -1
- package/dist/esm/tests/utils/memory-cache.spec.js +6 -9
- package/dist/esm/tests/utils/memory-cache.spec.js.map +1 -1
- package/dist/esm/tests/utils/messages.spec.js +63 -29
- package/dist/esm/tests/utils/messages.spec.js.map +1 -1
- package/dist/esm/tests/utils/object.spec.js +3 -3
- package/dist/esm/tests/utils/object.spec.js.map +1 -1
- package/dist/esm/tests/utils/poller.js +1 -1
- package/dist/esm/tests/utils/poller.js.map +1 -1
- package/dist/esm/tests/utils/private-key-signer.spec.js +6 -6
- package/dist/esm/tests/utils/private-key-signer.spec.js.map +1 -1
- package/dist/esm/tests/utils/records.spec.js +37 -5
- package/dist/esm/tests/utils/records.spec.js.map +1 -1
- package/dist/esm/tests/utils/secp256k1.spec.js +7 -7
- package/dist/esm/tests/utils/secp256k1.spec.js.map +1 -1
- package/dist/esm/tests/utils/secp256r1.spec.js +7 -7
- package/dist/esm/tests/utils/secp256r1.spec.js.map +1 -1
- package/dist/esm/tests/utils/test-data-generator.js +47 -28
- package/dist/esm/tests/utils/test-data-generator.js.map +1 -1
- package/dist/esm/tests/utils/time.spec.js +7 -7
- package/dist/esm/tests/utils/time.spec.js.map +1 -1
- package/dist/esm/tests/utils/url.spec.js +25 -27
- package/dist/esm/tests/utils/url.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/definitions.spec.js +4 -4
- 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 +15 -3
- 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 -8
- 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 +8 -18
- 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 +3 -3
- 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 +9 -9
- 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 +106 -0
- package/dist/esm/tests/validation/json-schemas/records/records-read.spec.js.map +1 -0
- package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js +18 -18
- package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js.map +1 -1
- package/dist/esm/tests/vectors/protocol-definitions/email.json +1 -1
- package/dist/esm/tests/vectors/protocol-definitions/friend-role.json +2 -4
- package/dist/esm/tests/vectors/protocol-definitions/slack.json +2 -6
- package/dist/esm/tests/vectors/protocol-definitions/thread-role.json +2 -6
- package/dist/types/generated/precompiled-validators.d.ts +82 -64
- package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
- package/dist/types/src/core/dwn-error.d.ts +27 -3
- package/dist/types/src/core/dwn-error.d.ts.map +1 -1
- package/dist/types/src/core/message-reply.d.ts +1 -1
- package/dist/types/src/core/message.d.ts +3 -3
- package/dist/types/src/core/message.d.ts.map +1 -1
- package/dist/types/src/core/messages-grant-authorization.d.ts +4 -4
- package/dist/types/src/core/messages-grant-authorization.d.ts.map +1 -1
- package/dist/types/src/core/protocol-authorization.d.ts +43 -2
- package/dist/types/src/core/protocol-authorization.d.ts.map +1 -1
- package/dist/types/src/core/records-grant-authorization.d.ts +2 -2
- package/dist/types/src/core/records-grant-authorization.d.ts.map +1 -1
- package/dist/types/src/core/resumable-task-manager.d.ts +1 -0
- package/dist/types/src/core/resumable-task-manager.d.ts.map +1 -1
- package/dist/types/src/dwn.d.ts +8 -8
- package/dist/types/src/dwn.d.ts.map +1 -1
- package/dist/types/src/enums/dwn-interface-method.d.ts +5 -3
- package/dist/types/src/enums/dwn-interface-method.d.ts.map +1 -1
- package/dist/types/src/event-stream/event-emitter-stream.d.ts.map +1 -0
- package/dist/types/src/handlers/messages-sync.d.ts +21 -0
- package/dist/types/src/handlers/messages-sync.d.ts.map +1 -0
- package/dist/types/src/handlers/protocols-configure.d.ts +24 -4
- package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -1
- package/dist/types/src/handlers/protocols-query.d.ts.map +1 -1
- package/dist/types/src/handlers/records-count.d.ts +43 -0
- package/dist/types/src/handlers/records-count.d.ts.map +1 -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-write.d.ts +5 -5
- package/dist/types/src/handlers/records-write.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +72 -37
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/interfaces/messages-read.d.ts +2 -2
- package/dist/types/src/interfaces/messages-read.d.ts.map +1 -1
- package/dist/types/src/interfaces/messages-subscribe.d.ts +2 -2
- package/dist/types/src/interfaces/messages-subscribe.d.ts.map +1 -1
- package/dist/types/src/interfaces/messages-sync.d.ts +16 -0
- package/dist/types/src/interfaces/messages-sync.d.ts.map +1 -0
- package/dist/types/src/interfaces/protocols-configure.d.ts +22 -2
- package/dist/types/src/interfaces/protocols-configure.d.ts.map +1 -1
- package/dist/types/src/interfaces/protocols-query.d.ts +2 -2
- package/dist/types/src/interfaces/protocols-query.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-count.d.ts +27 -0
- package/dist/types/src/interfaces/records-count.d.ts.map +1 -0
- package/dist/types/src/interfaces/records-delete.d.ts +2 -2
- package/dist/types/src/interfaces/records-delete.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-query.d.ts +2 -2
- package/dist/types/src/interfaces/records-query.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-read.d.ts +4 -2
- package/dist/types/src/interfaces/records-read.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-subscribe.d.ts +2 -2
- package/dist/types/src/interfaces/records-subscribe.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-write.d.ts +37 -15
- 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/jose/algorithms/signing/signature-algorithms.d.ts +5 -1
- package/dist/types/src/jose/algorithms/signing/signature-algorithms.d.ts.map +1 -1
- package/dist/types/src/jose/jws/general/builder.d.ts +3 -3
- package/dist/types/src/jose/jws/general/builder.d.ts.map +1 -1
- package/dist/types/src/protocols/permission-grant.d.ts +11 -0
- package/dist/types/src/protocols/permission-grant.d.ts.map +1 -1
- package/dist/types/src/protocols/permission-request.d.ts +11 -0
- package/dist/types/src/protocols/permission-request.d.ts.map +1 -1
- package/dist/types/src/protocols/permissions.d.ts +4 -4
- package/dist/types/src/protocols/permissions.d.ts.map +1 -1
- package/dist/types/src/schema-validator.d.ts +1 -1
- package/dist/types/src/schema-validator.d.ts.map +1 -1
- package/dist/types/src/smt/smt-store-level.d.ts +32 -0
- package/dist/types/src/smt/smt-store-level.d.ts.map +1 -0
- package/dist/types/src/smt/smt-store-memory.d.ts +22 -0
- package/dist/types/src/smt/smt-store-memory.d.ts.map +1 -0
- package/dist/types/src/smt/smt-utils.d.ts +58 -0
- package/dist/types/src/smt/smt-utils.d.ts.map +1 -0
- package/dist/types/src/smt/sparse-merkle-tree.d.ts +124 -0
- package/dist/types/src/smt/sparse-merkle-tree.d.ts.map +1 -0
- package/dist/types/src/state-index/state-index-level.d.ts +83 -0
- package/dist/types/src/state-index/state-index-level.d.ts.map +1 -0
- package/dist/types/src/store/data-store-level.d.ts +1 -2
- package/dist/types/src/store/data-store-level.d.ts.map +1 -1
- package/dist/types/src/store/index-level.d.ts +98 -2
- package/dist/types/src/store/index-level.d.ts.map +1 -1
- package/dist/types/src/store/level-wrapper.d.ts.map +1 -1
- package/dist/types/src/store/message-store-level.d.ts +5 -0
- package/dist/types/src/store/message-store-level.d.ts.map +1 -1
- package/dist/types/src/store/storage-controller.d.ts +7 -7
- package/dist/types/src/store/storage-controller.d.ts.map +1 -1
- package/dist/types/src/types/data-store.d.ts +2 -3
- package/dist/types/src/types/data-store.d.ts.map +1 -1
- package/dist/types/src/types/encryption-types.d.ts +48 -0
- package/dist/types/src/types/encryption-types.d.ts.map +1 -0
- package/dist/types/src/types/jose-types.d.ts +9 -40
- package/dist/types/src/types/jose-types.d.ts.map +1 -1
- package/dist/types/src/types/message-store.d.ts +5 -0
- package/dist/types/src/types/message-store.d.ts.map +1 -1
- package/dist/types/src/types/message-types.d.ts +19 -0
- package/dist/types/src/types/message-types.d.ts.map +1 -1
- package/dist/types/src/types/messages-types.d.ts +16 -11
- package/dist/types/src/types/messages-types.d.ts.map +1 -1
- package/dist/types/src/types/method-handler.d.ts +1 -2
- package/dist/types/src/types/method-handler.d.ts.map +1 -1
- package/dist/types/src/types/permission-types.d.ts +2 -2
- package/dist/types/src/types/permission-types.d.ts.map +1 -1
- package/dist/types/src/types/protocols-types.d.ts +49 -5
- package/dist/types/src/types/protocols-types.d.ts.map +1 -1
- package/dist/types/src/types/records-types.d.ts +23 -7
- package/dist/types/src/types/records-types.d.ts.map +1 -1
- package/dist/types/src/types/signer.d.ts +1 -1
- package/dist/types/src/types/signer.d.ts.map +1 -1
- package/dist/types/src/types/smt-types.d.ts +81 -0
- package/dist/types/src/types/smt-types.d.ts.map +1 -0
- package/dist/types/src/types/state-index.d.ts +90 -0
- package/dist/types/src/types/state-index.d.ts.map +1 -0
- package/dist/types/src/utils/cid.d.ts +1 -2
- package/dist/types/src/utils/cid.d.ts.map +1 -1
- package/dist/types/src/utils/data-stream.d.ts +14 -7
- package/dist/types/src/utils/data-stream.d.ts.map +1 -1
- package/dist/types/src/utils/encryption.d.ts +2 -3
- package/dist/types/src/utils/encryption.d.ts.map +1 -1
- package/dist/types/src/utils/hd-key.d.ts +4 -4
- package/dist/types/src/utils/hd-key.d.ts.map +1 -1
- package/dist/types/src/utils/jws.d.ts +7 -7
- package/dist/types/src/utils/jws.d.ts.map +1 -1
- package/dist/types/src/utils/private-key-signer.d.ts +4 -4
- package/dist/types/src/utils/private-key-signer.d.ts.map +1 -1
- package/dist/types/src/utils/protocols.d.ts +46 -3
- package/dist/types/src/utils/protocols.d.ts.map +1 -1
- package/dist/types/src/utils/records.d.ts +33 -6
- package/dist/types/src/utils/records.d.ts.map +1 -1
- package/dist/types/src/utils/secp256k1.d.ts +11 -11
- package/dist/types/src/utils/secp256k1.d.ts.map +1 -1
- package/dist/types/src/utils/secp256r1.d.ts +8 -8
- package/dist/types/src/utils/secp256r1.d.ts.map +1 -1
- package/dist/types/src/utils/time.d.ts +1 -1
- package/dist/types/tests/dwn.spec.d.ts.map +1 -1
- package/dist/types/tests/event-stream/event-emitter-stream.spec.d.ts.map +1 -0
- package/dist/types/tests/event-stream/event-stream.spec.d.ts.map +1 -0
- package/dist/types/tests/features/author-delegated-grant.spec.d.ts.map +1 -1
- package/dist/types/tests/features/owner-delegated-grant.spec.d.ts.map +1 -1
- package/dist/types/tests/features/owner-signature.spec.d.ts.map +1 -1
- package/dist/types/tests/features/permissions.spec.d.ts.map +1 -1
- package/dist/types/tests/features/protocol-composition.spec.d.ts +5 -0
- package/dist/types/tests/features/protocol-composition.spec.d.ts.map +1 -0
- package/dist/types/tests/features/protocol-create-action.spec.d.ts.map +1 -1
- package/dist/types/tests/features/protocol-delete-action.spec.d.ts.map +1 -1
- package/dist/types/tests/features/protocol-update-action.spec.d.ts.map +1 -1
- package/dist/types/tests/features/records-prune.spec.d.ts.map +1 -1
- package/dist/types/tests/features/records-tags.spec.d.ts.map +1 -1
- package/dist/types/tests/features/resumable-tasks.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/messages-read.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/messages-subscribe.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/messages-sync.spec.d.ts +2 -0
- package/dist/types/tests/handlers/messages-sync.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/protocols-configure.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/protocols-query.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/records-count.spec.d.ts +2 -0
- package/dist/types/tests/handlers/records-count.spec.d.ts.map +1 -0
- 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/protocols/permission-grant.spec.d.ts +2 -0
- package/dist/types/tests/protocols/permission-grant.spec.d.ts.map +1 -0
- package/dist/types/tests/scenarios/deleted-record.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/scenarios/nested-roles.spec.d.ts.map +1 -1
- package/dist/types/tests/smt/smt-store-level.spec.d.ts +2 -0
- package/dist/types/tests/smt/smt-store-level.spec.d.ts.map +1 -0
- package/dist/types/tests/smt/sparse-merkle-tree.spec.d.ts +2 -0
- package/dist/types/tests/smt/sparse-merkle-tree.spec.d.ts.map +1 -0
- package/dist/types/tests/state-index/state-index-level.spec.d.ts +2 -0
- package/dist/types/tests/state-index/state-index-level.spec.d.ts.map +1 -0
- package/dist/types/tests/store/blockstore-level.spec.d.ts +2 -0
- package/dist/types/tests/store/blockstore-level.spec.d.ts.map +1 -0
- package/dist/types/tests/store/message-store.spec.d.ts.map +1 -1
- package/dist/types/tests/test-stores.d.ts +4 -4
- package/dist/types/tests/test-stores.d.ts.map +1 -1
- package/dist/types/tests/test-suite.d.ts +2 -2
- package/dist/types/tests/test-suite.d.ts.map +1 -1
- package/dist/types/tests/utils/encryption-callbacks.spec.d.ts +2 -0
- package/dist/types/tests/utils/encryption-callbacks.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/test-data-generator.d.ts +31 -28
- package/dist/types/tests/utils/test-data-generator.d.ts.map +1 -1
- package/dist/types/tests/validation/json-schemas/records/records-read.spec.d.ts +2 -0
- package/dist/types/tests/validation/json-schemas/records/records-read.spec.d.ts.map +1 -0
- package/package.json +27 -46
- package/src/core/dwn-error.ts +27 -3
- package/src/core/message-reply.ts +1 -1
- package/src/core/message.ts +5 -5
- package/src/core/messages-grant-authorization.ts +22 -8
- package/src/core/protocol-authorization.ts +345 -68
- package/src/core/records-grant-authorization.ts +2 -2
- package/src/core/resumable-task-manager.ts +4 -5
- package/src/dwn.ts +25 -20
- package/src/enums/dwn-interface-method.ts +5 -3
- package/src/handlers/messages-subscribe.ts +1 -1
- package/src/handlers/messages-sync.ts +129 -0
- package/src/handlers/protocols-configure.ts +195 -17
- package/src/handlers/protocols-query.ts +7 -5
- package/src/handlers/records-count.ts +184 -0
- package/src/handlers/records-query.ts +4 -0
- package/src/handlers/records-read.ts +4 -8
- package/src/handlers/records-write.ts +20 -21
- package/src/index.ts +74 -37
- package/src/interfaces/messages-read.ts +6 -5
- package/src/interfaces/messages-subscribe.ts +7 -6
- package/src/interfaces/messages-sync.ts +59 -0
- package/src/interfaces/protocols-configure.ts +211 -33
- package/src/interfaces/protocols-query.ts +7 -6
- package/src/interfaces/records-count.ts +106 -0
- package/src/interfaces/records-delete.ts +2 -2
- package/src/interfaces/records-query.ts +2 -2
- package/src/interfaces/records-read.ts +26 -3
- package/src/interfaces/records-subscribe.ts +2 -2
- package/src/interfaces/records-write.ts +115 -46
- package/src/jose/algorithms/signing/ed25519.ts +13 -12
- package/src/jose/algorithms/signing/signature-algorithms.ts +6 -1
- package/src/jose/jws/general/builder.ts +3 -3
- package/src/jose/jws/general/verifier.ts +3 -3
- package/src/protocols/permission-grant.ts +51 -0
- package/src/protocols/permission-request.ts +37 -0
- package/src/protocols/permissions.ts +5 -5
- package/src/schema-validator.ts +11 -3
- package/src/smt/smt-store-level.ts +143 -0
- package/src/smt/smt-store-memory.ts +53 -0
- package/src/smt/smt-utils.ts +149 -0
- package/src/smt/sparse-merkle-tree.ts +698 -0
- package/src/state-index/state-index-level.ts +241 -0
- package/src/store/data-store-level.ts +8 -7
- package/src/store/index-level.ts +415 -19
- package/src/store/level-wrapper.ts +1 -1
- package/src/store/message-store-level.ts +62 -0
- package/src/store/storage-controller.ts +21 -19
- package/src/types/data-store.ts +2 -4
- package/src/types/encryption-types.ts +52 -0
- package/src/types/jose-types.ts +10 -42
- package/src/types/message-store.ts +11 -0
- package/src/types/message-types.ts +21 -0
- package/src/types/messages-types.ts +21 -15
- package/src/types/method-handler.ts +1 -2
- package/src/types/permission-types.ts +2 -2
- package/src/types/protocols-types.ts +55 -6
- package/src/types/records-types.ts +26 -7
- package/src/types/signer.ts +1 -1
- package/src/types/smt-types.ts +95 -0
- package/src/types/state-index.ts +100 -0
- package/src/utils/cid.ts +3 -4
- package/src/utils/data-stream.ts +75 -38
- package/src/utils/encryption.ts +24 -39
- package/src/utils/hd-key.ts +6 -6
- package/src/utils/jws.ts +9 -9
- package/src/utils/private-key-signer.ts +9 -8
- package/src/utils/protocols.ts +132 -6
- package/src/utils/records.ts +118 -29
- package/src/utils/secp256k1.ts +23 -21
- package/src/utils/secp256r1.ts +17 -15
- package/src/utils/time.ts +1 -1
- package/src/utils/url.ts +1 -1
- package/dist/cjs/index.js +0 -36749
- package/dist/cjs/package.json +0 -1
- package/dist/esm/src/event-log/event-emitter-stream.js.map +0 -1
- package/dist/esm/src/event-log/event-log-level.js +0 -63
- package/dist/esm/src/event-log/event-log-level.js.map +0 -1
- package/dist/esm/src/handlers/messages-query.js +0 -71
- package/dist/esm/src/handlers/messages-query.js.map +0 -1
- package/dist/esm/src/interfaces/messages-query.js.map +0 -1
- package/dist/esm/src/types/event-log.js +0 -2
- package/dist/esm/src/types/event-log.js.map +0 -1
- package/dist/esm/tests/event-log/event-emitter-stream.spec.js.map +0 -1
- package/dist/esm/tests/event-log/event-log-level.spec.js +0 -44
- package/dist/esm/tests/event-log/event-log-level.spec.js.map +0 -1
- package/dist/esm/tests/event-log/event-log.spec.js +0 -236
- package/dist/esm/tests/event-log/event-log.spec.js.map +0 -1
- package/dist/esm/tests/event-log/event-stream.spec.js.map +0 -1
- package/dist/esm/tests/handlers/messages-query.spec.js +0 -349
- package/dist/esm/tests/handlers/messages-query.spec.js.map +0 -1
- package/dist/esm/tests/interfaces/messagess-query.spec.js +0 -127
- package/dist/esm/tests/interfaces/messagess-query.spec.js.map +0 -1
- package/dist/esm/tests/scenarios/messages-query.spec.js +0 -395
- package/dist/esm/tests/scenarios/messages-query.spec.js.map +0 -1
- package/dist/types/src/event-log/event-emitter-stream.d.ts.map +0 -1
- package/dist/types/src/event-log/event-log-level.d.ts +0 -35
- package/dist/types/src/event-log/event-log-level.d.ts.map +0 -1
- package/dist/types/src/handlers/messages-query.d.ts +0 -17
- package/dist/types/src/handlers/messages-query.d.ts.map +0 -1
- package/dist/types/src/interfaces/messages-query.d.ts +0 -16
- package/dist/types/src/interfaces/messages-query.d.ts.map +0 -1
- package/dist/types/src/types/event-log.d.ts +0 -52
- package/dist/types/src/types/event-log.d.ts.map +0 -1
- package/dist/types/tests/event-log/event-emitter-stream.spec.d.ts.map +0 -1
- package/dist/types/tests/event-log/event-log-level.spec.d.ts +0 -2
- package/dist/types/tests/event-log/event-log-level.spec.d.ts.map +0 -1
- package/dist/types/tests/event-log/event-log.spec.d.ts +0 -2
- package/dist/types/tests/event-log/event-log.spec.d.ts.map +0 -1
- package/dist/types/tests/event-log/event-stream.spec.d.ts.map +0 -1
- package/dist/types/tests/handlers/messages-query.spec.d.ts +0 -2
- package/dist/types/tests/handlers/messages-query.spec.d.ts.map +0 -1
- package/dist/types/tests/interfaces/messagess-query.spec.d.ts +0 -2
- package/dist/types/tests/interfaces/messagess-query.spec.d.ts.map +0 -1
- package/dist/types/tests/scenarios/messages-query.spec.d.ts +0 -2
- package/dist/types/tests/scenarios/messages-query.spec.d.ts.map +0 -1
- package/src/event-log/event-log-level.ts +0 -72
- package/src/handlers/messages-query.ts +0 -67
- package/src/interfaces/messages-query.ts +0 -60
- package/src/types/event-log.ts +0 -52
- /package/dist/esm/src/{event-log → event-stream}/event-emitter-stream.js +0 -0
- /package/dist/types/src/{event-log → event-stream}/event-emitter-stream.d.ts +0 -0
- /package/dist/types/tests/{event-log → event-stream}/event-emitter-stream.spec.d.ts +0 -0
- /package/dist/types/tests/{event-log → event-stream}/event-stream.spec.d.ts +0 -0
- /package/src/{event-log → event-stream}/event-emitter-stream.ts +0 -0
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
import type { Filter } from '../types/query-types.js';
|
|
2
2
|
import type { MessageStore } from '../types/message-store.js';
|
|
3
|
+
import type { RecordsCount } from '../interfaces/records-count.js';
|
|
3
4
|
import type { RecordsDelete } from '../interfaces/records-delete.js';
|
|
4
5
|
import type { RecordsQuery } from '../interfaces/records-query.js';
|
|
5
6
|
import type { RecordsRead } from '../interfaces/records-read.js';
|
|
6
7
|
import type { RecordsSubscribe } from '../interfaces/records-subscribe.js';
|
|
7
8
|
import type { RecordsWriteMessage } from '../types/records-types.js';
|
|
8
|
-
import type {
|
|
9
|
+
import type {
|
|
10
|
+
ProtocolActionRule, ProtocolDefinition, ProtocolRuleSet, ProtocolsConfigureMessage, ProtocolType, ProtocolTypes
|
|
11
|
+
} from '../types/protocols-types.js';
|
|
9
12
|
|
|
10
13
|
import Ajv from 'ajv/dist/2020.js';
|
|
11
14
|
import { FilterUtility } from '../utils/filter.js';
|
|
12
15
|
import { PermissionsProtocol } from '../protocols/permissions.js';
|
|
13
16
|
import { Records } from '../utils/records.js';
|
|
14
17
|
import { RecordsWrite } from '../interfaces/records-write.js';
|
|
18
|
+
import { SortDirection } from '../types/query-types.js';
|
|
15
19
|
import { DwnError, DwnErrorCode } from './dwn-error.js';
|
|
16
20
|
import { DwnInterfaceName, DwnMethodName } from '../enums/dwn-interface-method.js';
|
|
21
|
+
import { getRuleSetAtPath, isCrossProtocolRef, parseCrossProtocolRef } from '../utils/protocols.js';
|
|
17
22
|
import { ProtocolAction, ProtocolActor } from '../types/protocols-types.js';
|
|
18
23
|
|
|
19
24
|
export class ProtocolAuthorization {
|
|
@@ -27,17 +32,25 @@ export class ProtocolAuthorization {
|
|
|
27
32
|
incomingMessage: RecordsWrite,
|
|
28
33
|
messageStore: MessageStore,
|
|
29
34
|
): Promise<void> {
|
|
30
|
-
//
|
|
35
|
+
// Determine the governing timestamp for protocol definition lookup.
|
|
36
|
+
// For an initial write, this is the message's own timestamp.
|
|
37
|
+
// For an update, this is the initial write's timestamp (the protocol version is locked at creation time).
|
|
38
|
+
const governingTimestamp = await ProtocolAuthorization.getGoverningTimestamp(
|
|
39
|
+
tenant, incomingMessage, messageStore
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
// fetch the protocol definition that was active at the governing timestamp
|
|
31
43
|
const protocolDefinition = await ProtocolAuthorization.fetchProtocolDefinition(
|
|
32
44
|
tenant,
|
|
33
45
|
incomingMessage.message.descriptor.protocol!,
|
|
34
46
|
messageStore,
|
|
47
|
+
governingTimestamp,
|
|
35
48
|
);
|
|
36
49
|
|
|
37
|
-
// verify declared protocol type exists in protocol and that it conforms to type specification
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
protocolDefinition
|
|
50
|
+
// verify declared protocol type exists in protocol and that it conforms to type specification.
|
|
51
|
+
// For cross-protocol composition, the type may be defined in a referenced protocol.
|
|
52
|
+
await ProtocolAuthorization.verifyTypeWithComposition(
|
|
53
|
+
tenant, incomingMessage.message, protocolDefinition, messageStore, governingTimestamp
|
|
41
54
|
);
|
|
42
55
|
|
|
43
56
|
// validate `protocolPath`
|
|
@@ -45,6 +58,7 @@ export class ProtocolAuthorization {
|
|
|
45
58
|
tenant,
|
|
46
59
|
incomingMessage,
|
|
47
60
|
messageStore,
|
|
61
|
+
governingTimestamp,
|
|
48
62
|
);
|
|
49
63
|
|
|
50
64
|
// get the rule set for the inbound message
|
|
@@ -89,11 +103,17 @@ export class ProtocolAuthorization {
|
|
|
89
103
|
recordChain = await ProtocolAuthorization.constructRecordChain(tenant, incomingMessage.message.recordId, messageStore);
|
|
90
104
|
}
|
|
91
105
|
|
|
92
|
-
//
|
|
106
|
+
// Determine the governing timestamp for protocol definition lookup.
|
|
107
|
+
const governingTimestamp = await ProtocolAuthorization.getGoverningTimestamp(
|
|
108
|
+
tenant, incomingMessage, messageStore
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
// fetch the protocol definition that was active at the governing timestamp
|
|
93
112
|
const protocolDefinition = await ProtocolAuthorization.fetchProtocolDefinition(
|
|
94
113
|
tenant,
|
|
95
114
|
incomingMessage.message.descriptor.protocol!,
|
|
96
115
|
messageStore,
|
|
116
|
+
governingTimestamp,
|
|
97
117
|
);
|
|
98
118
|
|
|
99
119
|
// get the rule set for the inbound message
|
|
@@ -110,6 +130,7 @@ export class ProtocolAuthorization {
|
|
|
110
130
|
incomingMessage.message.contextId!,
|
|
111
131
|
protocolDefinition,
|
|
112
132
|
messageStore,
|
|
133
|
+
governingTimestamp,
|
|
113
134
|
);
|
|
114
135
|
|
|
115
136
|
// verify method invoked against the allowed actions in the rule set
|
|
@@ -119,6 +140,7 @@ export class ProtocolAuthorization {
|
|
|
119
140
|
ruleSet,
|
|
120
141
|
recordChain,
|
|
121
142
|
messageStore,
|
|
143
|
+
protocolDefinition,
|
|
122
144
|
);
|
|
123
145
|
}
|
|
124
146
|
|
|
@@ -137,11 +159,21 @@ export class ProtocolAuthorization {
|
|
|
137
159
|
const recordChain: RecordsWriteMessage[] =
|
|
138
160
|
await ProtocolAuthorization.constructRecordChain(tenant, newestRecordsWrite.message.recordId, messageStore);
|
|
139
161
|
|
|
140
|
-
//
|
|
162
|
+
// Use the initial write's timestamp to determine the governing protocol definition.
|
|
163
|
+
// The protocol version is locked at the time the record was first created.
|
|
164
|
+
const initialWrite = await ProtocolAuthorization.fetchInitialWrite(
|
|
165
|
+
tenant, newestRecordsWrite.message.recordId, messageStore
|
|
166
|
+
);
|
|
167
|
+
const governingTimestamp = initialWrite !== undefined
|
|
168
|
+
? initialWrite.descriptor.messageTimestamp
|
|
169
|
+
: newestRecordsWrite.message.descriptor.messageTimestamp;
|
|
170
|
+
|
|
171
|
+
// fetch the protocol definition that was active when the record was created
|
|
141
172
|
const protocolDefinition = await ProtocolAuthorization.fetchProtocolDefinition(
|
|
142
173
|
tenant,
|
|
143
174
|
newestRecordsWrite.message.descriptor.protocol!,
|
|
144
175
|
messageStore,
|
|
176
|
+
governingTimestamp,
|
|
145
177
|
);
|
|
146
178
|
|
|
147
179
|
// get the rule set for the inbound message
|
|
@@ -158,6 +190,7 @@ export class ProtocolAuthorization {
|
|
|
158
190
|
newestRecordsWrite.message.contextId!,
|
|
159
191
|
protocolDefinition,
|
|
160
192
|
messageStore,
|
|
193
|
+
governingTimestamp,
|
|
161
194
|
);
|
|
162
195
|
|
|
163
196
|
// verify method invoked against the allowed actions in the rule set
|
|
@@ -167,12 +200,13 @@ export class ProtocolAuthorization {
|
|
|
167
200
|
ruleSet,
|
|
168
201
|
recordChain,
|
|
169
202
|
messageStore,
|
|
203
|
+
protocolDefinition,
|
|
170
204
|
);
|
|
171
205
|
}
|
|
172
206
|
|
|
173
207
|
public static async authorizeQueryOrSubscribe(
|
|
174
208
|
tenant: string,
|
|
175
|
-
incomingMessage: RecordsQuery | RecordsSubscribe,
|
|
209
|
+
incomingMessage: RecordsCount | RecordsQuery | RecordsSubscribe,
|
|
176
210
|
messageStore: MessageStore,
|
|
177
211
|
): Promise<void> {
|
|
178
212
|
const { protocol, protocolPath, contextId } = incomingMessage.message.descriptor.filter;
|
|
@@ -207,6 +241,7 @@ export class ProtocolAuthorization {
|
|
|
207
241
|
ruleSet,
|
|
208
242
|
[], // record chain is not relevant to queries or subscriptions
|
|
209
243
|
messageStore,
|
|
244
|
+
protocolDefinition,
|
|
210
245
|
);
|
|
211
246
|
}
|
|
212
247
|
|
|
@@ -225,11 +260,20 @@ export class ProtocolAuthorization {
|
|
|
225
260
|
const recordChain: RecordsWriteMessage[] =
|
|
226
261
|
await ProtocolAuthorization.constructRecordChain(tenant, incomingMessage.message.descriptor.recordId, messageStore);
|
|
227
262
|
|
|
228
|
-
//
|
|
263
|
+
// Use the initial write's timestamp to determine the governing protocol definition.
|
|
264
|
+
const initialWrite = await ProtocolAuthorization.fetchInitialWrite(
|
|
265
|
+
tenant, incomingMessage.message.descriptor.recordId, messageStore
|
|
266
|
+
);
|
|
267
|
+
const governingTimestamp = initialWrite !== undefined
|
|
268
|
+
? initialWrite.descriptor.messageTimestamp
|
|
269
|
+
: recordsWrite.message.descriptor.messageTimestamp;
|
|
270
|
+
|
|
271
|
+
// fetch the protocol definition that was active when the record was created
|
|
229
272
|
const protocolDefinition = await ProtocolAuthorization.fetchProtocolDefinition(
|
|
230
273
|
tenant,
|
|
231
274
|
recordsWrite.message.descriptor.protocol!,
|
|
232
275
|
messageStore,
|
|
276
|
+
governingTimestamp,
|
|
233
277
|
);
|
|
234
278
|
|
|
235
279
|
// get the rule set for the inbound message
|
|
@@ -246,6 +290,7 @@ export class ProtocolAuthorization {
|
|
|
246
290
|
recordsWrite.message.contextId!,
|
|
247
291
|
protocolDefinition,
|
|
248
292
|
messageStore,
|
|
293
|
+
governingTimestamp,
|
|
249
294
|
);
|
|
250
295
|
|
|
251
296
|
// verify method invoked against the allowed actions in the rule set
|
|
@@ -255,16 +300,21 @@ export class ProtocolAuthorization {
|
|
|
255
300
|
ruleSet,
|
|
256
301
|
recordChain,
|
|
257
302
|
messageStore,
|
|
303
|
+
protocolDefinition,
|
|
258
304
|
);
|
|
259
305
|
}
|
|
260
306
|
|
|
261
307
|
/**
|
|
262
308
|
* Fetches the protocol definition based on the protocol specified in the given message.
|
|
309
|
+
* When `messageTimestamp` is provided, returns the protocol definition that was active at that
|
|
310
|
+
* point in time — i.e. the ProtocolsConfigure with the greatest `messageTimestamp` that is <= the
|
|
311
|
+
* given timestamp. When not provided, returns the latest (current) protocol definition.
|
|
263
312
|
*/
|
|
264
313
|
private static async fetchProtocolDefinition(
|
|
265
314
|
tenant: string,
|
|
266
315
|
protocolUri: string,
|
|
267
|
-
messageStore: MessageStore
|
|
316
|
+
messageStore: MessageStore,
|
|
317
|
+
messageTimestamp?: string,
|
|
268
318
|
): Promise<ProtocolDefinition> {
|
|
269
319
|
// if first-class protocol, return the definition from const object directly without going to data store
|
|
270
320
|
if (protocolUri === PermissionsProtocol.uri) {
|
|
@@ -275,9 +325,23 @@ export class ProtocolAuthorization {
|
|
|
275
325
|
const query: Filter = {
|
|
276
326
|
interface : DwnInterfaceName.Protocols,
|
|
277
327
|
method : DwnMethodName.Configure,
|
|
278
|
-
protocol : protocolUri
|
|
328
|
+
protocol : protocolUri,
|
|
279
329
|
};
|
|
280
|
-
|
|
330
|
+
|
|
331
|
+
if (messageTimestamp !== undefined) {
|
|
332
|
+
// temporal lookup: find the protocol definition active at the given timestamp
|
|
333
|
+
query.messageTimestamp = { lte: messageTimestamp };
|
|
334
|
+
} else {
|
|
335
|
+
// default: return only the latest protocol definition
|
|
336
|
+
query.isLatestBaseState = true;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
const { messages: protocols } = await messageStore.query(
|
|
340
|
+
tenant,
|
|
341
|
+
[query],
|
|
342
|
+
{ messageTimestamp: SortDirection.Descending },
|
|
343
|
+
{ limit: 1 },
|
|
344
|
+
);
|
|
281
345
|
|
|
282
346
|
if (protocols.length === 0) {
|
|
283
347
|
throw new DwnError(DwnErrorCode.ProtocolAuthorizationProtocolNotFound, `unable to find protocol definition for ${protocolUri}`);
|
|
@@ -362,7 +426,7 @@ export class ProtocolAuthorization {
|
|
|
362
426
|
protocolPath: string,
|
|
363
427
|
protocolDefinition: ProtocolDefinition,
|
|
364
428
|
): ProtocolRuleSet {
|
|
365
|
-
const ruleSet =
|
|
429
|
+
const ruleSet = getRuleSetAtPath(protocolPath, protocolDefinition.structure);
|
|
366
430
|
if (ruleSet === undefined) {
|
|
367
431
|
throw new DwnError(DwnErrorCode.ProtocolAuthorizationMissingRuleSet,
|
|
368
432
|
`No rule set defined for protocolPath ${protocolPath}`);
|
|
@@ -372,12 +436,14 @@ export class ProtocolAuthorization {
|
|
|
372
436
|
|
|
373
437
|
/**
|
|
374
438
|
* Verifies the `protocolPath` declared in the given message (if it is a RecordsWrite) matches the path of actual record chain.
|
|
439
|
+
* For cross-protocol composition, the parent record may belong to a different protocol (resolved via `$ref` in the composing protocol).
|
|
375
440
|
* @throws {DwnError} if fails verification.
|
|
376
441
|
*/
|
|
377
442
|
private static async verifyProtocolPathAndContextId(
|
|
378
443
|
tenant: string,
|
|
379
444
|
inboundMessage: RecordsWrite,
|
|
380
|
-
messageStore: MessageStore
|
|
445
|
+
messageStore: MessageStore,
|
|
446
|
+
governingTimestamp?: string,
|
|
381
447
|
): Promise<void> {
|
|
382
448
|
const declaredProtocolPath = inboundMessage.message.descriptor.protocolPath!;
|
|
383
449
|
const declaredTypeName = ProtocolAuthorization.getTypeName(declaredProtocolPath);
|
|
@@ -396,20 +462,42 @@ export class ProtocolAuthorization {
|
|
|
396
462
|
|
|
397
463
|
// Else `parentId` is defined, so we need to verify both protocolPath and contextId
|
|
398
464
|
|
|
465
|
+
// Determine the protocol URI for the parent query.
|
|
466
|
+
// If the parent path segment has a `$ref` in the composing protocol, the parent lives in a different protocol.
|
|
467
|
+
const childProtocol = inboundMessage.message.descriptor.protocol!;
|
|
468
|
+
const parentProtocolUri = await ProtocolAuthorization.resolveParentProtocolUri(
|
|
469
|
+
tenant, childProtocol, declaredProtocolPath, messageStore, governingTimestamp
|
|
470
|
+
);
|
|
471
|
+
|
|
399
472
|
// fetch the parent message
|
|
400
|
-
const protocol = inboundMessage.message.descriptor.protocol!;
|
|
401
473
|
const query: Filter = {
|
|
402
474
|
isLatestBaseState : true, // NOTE: this filter is critical, to ensure are are not returning a deleted parent
|
|
403
475
|
interface : DwnInterfaceName.Records,
|
|
404
476
|
method : DwnMethodName.Write,
|
|
405
|
-
protocol,
|
|
477
|
+
protocol : parentProtocolUri,
|
|
406
478
|
recordId : parentId
|
|
407
479
|
};
|
|
408
480
|
const { messages: parentMessages } = await messageStore.query(tenant, [query]);
|
|
409
481
|
const parentMessage = (parentMessages as RecordsWriteMessage[])[0];
|
|
410
482
|
|
|
483
|
+
if (parentMessage === undefined) {
|
|
484
|
+
// if this is a cross-protocol composition lookup, use a more descriptive error
|
|
485
|
+
if (parentProtocolUri !== childProtocol) {
|
|
486
|
+
throw new DwnError(
|
|
487
|
+
DwnErrorCode.ProtocolAuthorizationCrossProtocolParentNotFound,
|
|
488
|
+
`Could not find parent record '${parentId}' in protocol '${parentProtocolUri}' ` +
|
|
489
|
+
`for cross-protocol child at path '${declaredProtocolPath}'.`
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
throw new DwnError(
|
|
494
|
+
DwnErrorCode.ProtocolAuthorizationIncorrectProtocolPath,
|
|
495
|
+
`Could not find matching parent record to verify declared protocol path '${declaredProtocolPath}'.`
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
|
|
411
499
|
// verifying protocolPath of incoming message is a child of the parent message's protocolPath
|
|
412
|
-
const parentProtocolPath = parentMessage
|
|
500
|
+
const parentProtocolPath = parentMessage.descriptor.protocolPath;
|
|
413
501
|
const expectedProtocolPath = `${parentProtocolPath}/${declaredTypeName}`;
|
|
414
502
|
if (expectedProtocolPath !== declaredProtocolPath) {
|
|
415
503
|
throw new DwnError(
|
|
@@ -430,6 +518,123 @@ export class ProtocolAuthorization {
|
|
|
430
518
|
|
|
431
519
|
}
|
|
432
520
|
|
|
521
|
+
/**
|
|
522
|
+
* Resolves the protocol URI that should be used when querying for the parent record.
|
|
523
|
+
* For standard (non-composed) records, this is the same as the child's protocol.
|
|
524
|
+
* For cross-protocol composition, the parent may live in a different protocol
|
|
525
|
+
* (resolved via `$ref` in the composing protocol's definition).
|
|
526
|
+
*
|
|
527
|
+
* Logic: Given a child at protocolPath `a/b/c`, the parent is at `a/b`.
|
|
528
|
+
* Walk up the composing protocol's structure from root to `a/b`.
|
|
529
|
+
* If any segment along the way has a `$ref`, the parent (and its ancestors up to the `$ref` boundary)
|
|
530
|
+
* live in the referenced protocol. Specifically, the `$ref` at the topmost ancestor tells us
|
|
531
|
+
* the parent's protocol URI.
|
|
532
|
+
*/
|
|
533
|
+
private static async resolveParentProtocolUri(
|
|
534
|
+
tenant: string,
|
|
535
|
+
childProtocolUri: string,
|
|
536
|
+
childProtocolPath: string,
|
|
537
|
+
messageStore: MessageStore,
|
|
538
|
+
governingTimestamp?: string,
|
|
539
|
+
): Promise<string> {
|
|
540
|
+
const segments = childProtocolPath.split('/');
|
|
541
|
+
|
|
542
|
+
// A root-level record (no `/` in path) has no parent or uses the same protocol
|
|
543
|
+
if (segments.length <= 1) {
|
|
544
|
+
return childProtocolUri;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// Fetch the composing protocol's definition at the governing timestamp
|
|
548
|
+
const composingDefinition = await ProtocolAuthorization.fetchProtocolDefinition(
|
|
549
|
+
tenant, childProtocolUri, messageStore, governingTimestamp
|
|
550
|
+
);
|
|
551
|
+
|
|
552
|
+
// Walk the structure to find the parent's path segment
|
|
553
|
+
// The parent's position in the structure is at segments[0..n-2]
|
|
554
|
+
// We check if the first segment has a `$ref`, which means the parent is in a different protocol
|
|
555
|
+
const firstSegmentRuleSet = composingDefinition.structure[segments[0]];
|
|
556
|
+
if (firstSegmentRuleSet?.$ref !== undefined) {
|
|
557
|
+
const parsed = parseCrossProtocolRef(firstSegmentRuleSet.$ref);
|
|
558
|
+
if (parsed !== undefined && composingDefinition.uses !== undefined) {
|
|
559
|
+
const resolvedUri = composingDefinition.uses[parsed.alias];
|
|
560
|
+
if (resolvedUri !== undefined) {
|
|
561
|
+
// The parent path is within the `$ref` boundary — check if the parent IS the `$ref` node
|
|
562
|
+
// or is a descendant of it (which would still be in the composing protocol).
|
|
563
|
+
// If segments.length === 2, parent is at segments[0] which IS the $ref node → parent's protocol is the referenced one.
|
|
564
|
+
// If segments.length > 2, parent is at segments[0..n-2]. If segments[0] is $ref, the parent could be:
|
|
565
|
+
// - Still the $ref node itself (segments.length === 2) → referenced protocol
|
|
566
|
+
// - A child of the $ref node defined in the composing protocol (segments.length > 2) → composing protocol
|
|
567
|
+
if (segments.length === 2) {
|
|
568
|
+
// Parent is the $ref node itself (e.g., child is "thread/comment", parent is "thread")
|
|
569
|
+
return resolvedUri;
|
|
570
|
+
}
|
|
571
|
+
// else: parent is a deeper child defined in the composing protocol
|
|
572
|
+
return childProtocolUri;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
return childProtocolUri;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Verifies the `dataFormat` and `schema` declared in the given message matches the type in the protocol.
|
|
582
|
+
* For cross-protocol composition, if the type is at a `$ref` position in the structure,
|
|
583
|
+
* the type definition is looked up in the referenced protocol's `types` map instead.
|
|
584
|
+
*/
|
|
585
|
+
private static async verifyTypeWithComposition(
|
|
586
|
+
tenant: string,
|
|
587
|
+
inboundMessage: RecordsWriteMessage,
|
|
588
|
+
protocolDefinition: ProtocolDefinition,
|
|
589
|
+
messageStore: MessageStore,
|
|
590
|
+
governingTimestamp?: string,
|
|
591
|
+
): Promise<void> {
|
|
592
|
+
const declaredProtocolPath = inboundMessage.descriptor.protocolPath!;
|
|
593
|
+
const declaredTypeName = ProtocolAuthorization.getTypeName(declaredProtocolPath);
|
|
594
|
+
|
|
595
|
+
// Resolve which protocol types map to use.
|
|
596
|
+
// If the first path segment has `$ref`, this record's type might be defined in a referenced protocol.
|
|
597
|
+
const protocolTypes = await ProtocolAuthorization.resolveProtocolTypesForPath(
|
|
598
|
+
tenant, declaredProtocolPath, protocolDefinition, messageStore, governingTimestamp
|
|
599
|
+
);
|
|
600
|
+
|
|
601
|
+
ProtocolAuthorization.verifyType(inboundMessage, protocolTypes, declaredTypeName);
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* Resolves the `ProtocolTypes` map that contains the type definition for the given protocol path.
|
|
606
|
+
* For non-composed records, this is the protocol definition's own `types` map.
|
|
607
|
+
* For records at a `$ref` position, this is the referenced protocol's `types` map.
|
|
608
|
+
*/
|
|
609
|
+
private static async resolveProtocolTypesForPath(
|
|
610
|
+
tenant: string,
|
|
611
|
+
protocolPath: string,
|
|
612
|
+
protocolDefinition: ProtocolDefinition,
|
|
613
|
+
messageStore: MessageStore,
|
|
614
|
+
governingTimestamp?: string,
|
|
615
|
+
): Promise<ProtocolTypes> {
|
|
616
|
+
const segments = protocolPath.split('/');
|
|
617
|
+
|
|
618
|
+
// Check if the first segment has a `$ref`
|
|
619
|
+
const firstSegmentRuleSet = protocolDefinition.structure[segments[0]];
|
|
620
|
+
if (firstSegmentRuleSet?.$ref !== undefined && segments.length === 1) {
|
|
621
|
+
// This record IS the $ref node itself — its type is defined in the referenced protocol
|
|
622
|
+
const parsed = parseCrossProtocolRef(firstSegmentRuleSet.$ref);
|
|
623
|
+
if (parsed !== undefined && protocolDefinition.uses !== undefined) {
|
|
624
|
+
const refProtocolUri = protocolDefinition.uses[parsed.alias];
|
|
625
|
+
if (refProtocolUri !== undefined) {
|
|
626
|
+
const refDefinition = await ProtocolAuthorization.fetchProtocolDefinition(
|
|
627
|
+
tenant, refProtocolUri, messageStore, governingTimestamp
|
|
628
|
+
);
|
|
629
|
+
return refDefinition.types;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
// Default: use the composing protocol's own types
|
|
635
|
+
return protocolDefinition.types;
|
|
636
|
+
}
|
|
637
|
+
|
|
433
638
|
/**
|
|
434
639
|
* Verifies the `dataFormat` and `schema` declared in the given message (if it is a RecordsWrite) matches dataFormat
|
|
435
640
|
* and schema of the type in the given protocol.
|
|
@@ -438,27 +643,24 @@ export class ProtocolAuthorization {
|
|
|
438
643
|
private static verifyType(
|
|
439
644
|
inboundMessage: RecordsWriteMessage,
|
|
440
645
|
protocolTypes: ProtocolTypes,
|
|
646
|
+
typeName?: string,
|
|
441
647
|
): void {
|
|
442
|
-
|
|
648
|
+
const declaredTypeName = typeName ?? ProtocolAuthorization.getTypeName(inboundMessage.descriptor.protocolPath!);
|
|
443
649
|
const typeNames = Object.keys(protocolTypes);
|
|
444
|
-
|
|
445
|
-
const declaredTypeName = ProtocolAuthorization.getTypeName(declaredProtocolPath);
|
|
650
|
+
|
|
446
651
|
if (!typeNames.includes(declaredTypeName)) {
|
|
447
652
|
throw new DwnError(DwnErrorCode.ProtocolAuthorizationInvalidType,
|
|
448
653
|
`record with type ${declaredTypeName} not allowed in protocol`);
|
|
449
654
|
}
|
|
450
655
|
|
|
451
|
-
const
|
|
452
|
-
// existence of `protocolType` has already been verified
|
|
453
|
-
const typeName = ProtocolAuthorization.getTypeName(protocolPath);
|
|
454
|
-
const protocolType: ProtocolType = protocolTypes[typeName];
|
|
656
|
+
const protocolType: ProtocolType = protocolTypes[declaredTypeName];
|
|
455
657
|
|
|
456
658
|
// no `schema` specified in protocol definition means that any schema is allowed
|
|
457
659
|
const { schema } = inboundMessage.descriptor;
|
|
458
660
|
if (protocolType.schema !== undefined && protocolType.schema !== schema) {
|
|
459
661
|
throw new DwnError(
|
|
460
662
|
DwnErrorCode.ProtocolAuthorizationInvalidSchema,
|
|
461
|
-
`type '${
|
|
663
|
+
`type '${declaredTypeName}' must have schema '${protocolType.schema}', \
|
|
462
664
|
instead has '${schema}'`
|
|
463
665
|
);
|
|
464
666
|
}
|
|
@@ -468,7 +670,7 @@ export class ProtocolAuthorization {
|
|
|
468
670
|
if (protocolType.dataFormats !== undefined && !protocolType.dataFormats.includes(dataFormat)) {
|
|
469
671
|
throw new DwnError(
|
|
470
672
|
DwnErrorCode.ProtocolAuthorizationIncorrectDataFormat,
|
|
471
|
-
`type '${
|
|
673
|
+
`type '${declaredTypeName}' must have data format in (${protocolType.dataFormats}), \
|
|
472
674
|
instead has '${dataFormat}'`
|
|
473
675
|
);
|
|
474
676
|
}
|
|
@@ -476,14 +678,17 @@ export class ProtocolAuthorization {
|
|
|
476
678
|
|
|
477
679
|
/**
|
|
478
680
|
* Check if the incoming message is invoking a role. If so, validate the invoked role.
|
|
681
|
+
* For cross-protocol role invocation, the role record may live in a different protocol
|
|
682
|
+
* (resolved via the composing protocol's `uses` map).
|
|
479
683
|
*/
|
|
480
684
|
private static async verifyInvokedRole(
|
|
481
685
|
tenant: string,
|
|
482
|
-
incomingMessage: RecordsDelete | RecordsQuery | RecordsRead | RecordsSubscribe | RecordsWrite,
|
|
686
|
+
incomingMessage: RecordsCount | RecordsDelete | RecordsQuery | RecordsRead | RecordsSubscribe | RecordsWrite,
|
|
483
687
|
protocolUri: string,
|
|
484
688
|
contextId: string | undefined,
|
|
485
689
|
protocolDefinition: ProtocolDefinition,
|
|
486
690
|
messageStore: MessageStore,
|
|
691
|
+
governingTimestamp?: string,
|
|
487
692
|
): Promise<void> {
|
|
488
693
|
const protocolRole = incomingMessage.signaturePayload?.protocolRole;
|
|
489
694
|
|
|
@@ -492,25 +697,63 @@ export class ProtocolAuthorization {
|
|
|
492
697
|
return;
|
|
493
698
|
}
|
|
494
699
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
700
|
+
// Determine the protocol URI and protocol path for the role record.
|
|
701
|
+
// For cross-protocol roles (e.g., "threads:thread/participant"), resolve the alias.
|
|
702
|
+
let roleProtocolUri = protocolUri;
|
|
703
|
+
let roleProtocolPath = protocolRole;
|
|
704
|
+
|
|
705
|
+
if (isCrossProtocolRef(protocolRole)) {
|
|
706
|
+
const parsed = parseCrossProtocolRef(protocolRole);
|
|
707
|
+
if (parsed === undefined) {
|
|
708
|
+
throw new DwnError(
|
|
709
|
+
DwnErrorCode.ProtocolAuthorizationNotARole,
|
|
710
|
+
`Cross-protocol role '${protocolRole}' could not be parsed as a valid 'alias:path' format.`
|
|
711
|
+
);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
if (protocolDefinition.uses === undefined || protocolDefinition.uses[parsed.alias] === undefined) {
|
|
715
|
+
throw new DwnError(
|
|
716
|
+
DwnErrorCode.ProtocolAuthorizationNotARole,
|
|
717
|
+
`Cross-protocol role alias '${parsed.alias}' in '${protocolRole}' does not exist in the protocol's 'uses' map.`
|
|
718
|
+
);
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
roleProtocolUri = protocolDefinition.uses[parsed.alias];
|
|
722
|
+
roleProtocolPath = parsed.protocolPath;
|
|
723
|
+
|
|
724
|
+
// Fetch the referenced protocol's definition to validate the role exists
|
|
725
|
+
const refDefinition = await ProtocolAuthorization.fetchProtocolDefinition(
|
|
726
|
+
tenant, roleProtocolUri, messageStore, governingTimestamp
|
|
500
727
|
);
|
|
728
|
+
const roleRuleSet = getRuleSetAtPath(roleProtocolPath, refDefinition.structure);
|
|
729
|
+
if (roleRuleSet === undefined || !roleRuleSet.$role) {
|
|
730
|
+
throw new DwnError(
|
|
731
|
+
DwnErrorCode.ProtocolAuthorizationNotARole,
|
|
732
|
+
`Cross-protocol role path ${protocolRole} does not match role record type.`
|
|
733
|
+
);
|
|
734
|
+
}
|
|
735
|
+
} else {
|
|
736
|
+
// Local role: validate in the composing protocol's definition
|
|
737
|
+
const roleRuleSet = getRuleSetAtPath(protocolRole, protocolDefinition.structure);
|
|
738
|
+
if (roleRuleSet === undefined || !roleRuleSet.$role) {
|
|
739
|
+
throw new DwnError(
|
|
740
|
+
DwnErrorCode.ProtocolAuthorizationNotARole,
|
|
741
|
+
`Protocol path ${protocolRole} does not match role record type.`
|
|
742
|
+
);
|
|
743
|
+
}
|
|
501
744
|
}
|
|
502
745
|
|
|
503
746
|
// Construct a filter to fetch the invoked role record
|
|
504
747
|
const roleRecordFilter: Filter = {
|
|
505
748
|
interface : DwnInterfaceName.Records,
|
|
506
749
|
method : DwnMethodName.Write,
|
|
507
|
-
protocol :
|
|
508
|
-
protocolPath :
|
|
750
|
+
protocol : roleProtocolUri,
|
|
751
|
+
protocolPath : roleProtocolPath,
|
|
509
752
|
recipient : incomingMessage.author!,
|
|
510
753
|
isLatestBaseState : true,
|
|
511
754
|
};
|
|
512
755
|
|
|
513
|
-
const ancestorSegmentCountOfRolePath =
|
|
756
|
+
const ancestorSegmentCountOfRolePath = roleProtocolPath.split('/').length - 1;
|
|
514
757
|
if (contextId === undefined && ancestorSegmentCountOfRolePath > 0) {
|
|
515
758
|
throw new DwnError(
|
|
516
759
|
DwnErrorCode.ProtocolAuthorizationMissingContextId,
|
|
@@ -536,7 +779,7 @@ export class ProtocolAuthorization {
|
|
|
536
779
|
if (matchingMessages.length === 0) {
|
|
537
780
|
throw new DwnError(
|
|
538
781
|
DwnErrorCode.ProtocolAuthorizationMatchingRoleRecordNotFound,
|
|
539
|
-
`No matching role record found for protocol path ${
|
|
782
|
+
`No matching role record found for protocol path ${roleProtocolPath}`
|
|
540
783
|
);
|
|
541
784
|
}
|
|
542
785
|
}
|
|
@@ -553,7 +796,7 @@ export class ProtocolAuthorization {
|
|
|
553
796
|
*/
|
|
554
797
|
private static async getActionsSeekingARuleMatch(
|
|
555
798
|
tenant: string,
|
|
556
|
-
incomingMessage: RecordsDelete | RecordsQuery | RecordsRead | RecordsSubscribe | RecordsWrite,
|
|
799
|
+
incomingMessage: RecordsCount | RecordsDelete | RecordsQuery | RecordsRead | RecordsSubscribe | RecordsWrite,
|
|
557
800
|
messageStore: MessageStore,
|
|
558
801
|
): Promise<ProtocolAction[]> {
|
|
559
802
|
|
|
@@ -590,14 +833,17 @@ export class ProtocolAuthorization {
|
|
|
590
833
|
|
|
591
834
|
return actionsThatWouldAuthorizeDelete;
|
|
592
835
|
|
|
836
|
+
case DwnMethodName.Count:
|
|
837
|
+
return [ProtocolAction.Read];
|
|
838
|
+
|
|
593
839
|
case DwnMethodName.Query:
|
|
594
|
-
return [ProtocolAction.
|
|
840
|
+
return [ProtocolAction.Read];
|
|
595
841
|
|
|
596
842
|
case DwnMethodName.Read:
|
|
597
843
|
return [ProtocolAction.Read];
|
|
598
844
|
|
|
599
845
|
case DwnMethodName.Subscribe:
|
|
600
|
-
return [ProtocolAction.
|
|
846
|
+
return [ProtocolAction.Read];
|
|
601
847
|
|
|
602
848
|
case DwnMethodName.Write:
|
|
603
849
|
const incomingRecordsWrite = incomingMessage as RecordsWrite;
|
|
@@ -632,14 +878,16 @@ export class ProtocolAuthorization {
|
|
|
632
878
|
|
|
633
879
|
/**
|
|
634
880
|
* Verifies the given message is authorized by one of the action rules in the given protocol rule set.
|
|
881
|
+
* @param protocolDefinition Optional protocol definition for resolving cross-protocol `of` and `role` references.
|
|
635
882
|
* @throws {Error} if action not allowed.
|
|
636
883
|
*/
|
|
637
884
|
private static async authorizeAgainstAllowedActions(
|
|
638
885
|
tenant: string,
|
|
639
|
-
incomingMessage: RecordsDelete | RecordsQuery | RecordsRead | RecordsSubscribe | RecordsWrite,
|
|
886
|
+
incomingMessage: RecordsCount | RecordsDelete | RecordsQuery | RecordsRead | RecordsSubscribe | RecordsWrite,
|
|
640
887
|
ruleSet: ProtocolRuleSet,
|
|
641
888
|
recordChain: RecordsWriteMessage[],
|
|
642
889
|
messageStore: MessageStore,
|
|
890
|
+
protocolDefinition?: ProtocolDefinition,
|
|
643
891
|
): Promise<void> {
|
|
644
892
|
const incomingMessageMethod = incomingMessage.message.descriptor.method;
|
|
645
893
|
const actionsSeekingARuleMatch = await ProtocolAuthorization.getActionsSeekingARuleMatch(tenant, incomingMessage, messageStore);
|
|
@@ -716,7 +964,7 @@ export class ProtocolAuthorization {
|
|
|
716
964
|
}
|
|
717
965
|
|
|
718
966
|
// validate the actor is allowed by the current action rule
|
|
719
|
-
const ancestorRuleSuccess: boolean = await ProtocolAuthorization.checkActor(author, actionRule, recordChain);
|
|
967
|
+
const ancestorRuleSuccess: boolean = await ProtocolAuthorization.checkActor(author, actionRule, recordChain, protocolDefinition);
|
|
720
968
|
if (ancestorRuleSuccess) {
|
|
721
969
|
return;
|
|
722
970
|
}
|
|
@@ -847,43 +1095,48 @@ export class ProtocolAuthorization {
|
|
|
847
1095
|
}
|
|
848
1096
|
}
|
|
849
1097
|
|
|
850
|
-
private static getRuleSetAtProtocolPath(protocolPath: string, protocolDefinition: ProtocolDefinition): ProtocolRuleSet | undefined {
|
|
851
|
-
const protocolPathArray = protocolPath.split('/');
|
|
852
|
-
let currentRuleSet: ProtocolRuleSet = protocolDefinition.structure;
|
|
853
|
-
let i = 0;
|
|
854
|
-
while (i < protocolPathArray.length) {
|
|
855
|
-
const currentTypeName = protocolPathArray[i];
|
|
856
|
-
const nextRuleSet: ProtocolRuleSet | undefined = currentRuleSet[currentTypeName];
|
|
857
|
-
|
|
858
|
-
if (nextRuleSet === undefined) {
|
|
859
|
-
return undefined;
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
currentRuleSet = nextRuleSet;
|
|
863
|
-
i++;
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
return currentRuleSet;
|
|
867
|
-
}
|
|
868
|
-
|
|
869
1098
|
/**
|
|
870
1099
|
* Checks if the `who: 'author' | 'recipient'` action rule has a matching record in the record chain.
|
|
1100
|
+
* For cross-protocol `of` references (e.g., `"threads:thread"`), matches against both the protocol URI
|
|
1101
|
+
* and the protocol path of the ancestor record.
|
|
871
1102
|
* @returns `true` if the action rule is satisfied; `false` otherwise.
|
|
872
1103
|
*/
|
|
873
1104
|
private static async checkActor(
|
|
874
1105
|
author: string,
|
|
875
1106
|
actionRule: ProtocolActionRule,
|
|
876
1107
|
recordChain: RecordsWriteMessage[],
|
|
1108
|
+
composingDefinition?: ProtocolDefinition,
|
|
877
1109
|
): Promise<boolean> {
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
)
|
|
1110
|
+
const ofValue = actionRule.of;
|
|
1111
|
+
|
|
1112
|
+
// `of` should always be defined when `checkActor` is called, but guard defensively
|
|
1113
|
+
if (ofValue === undefined) {
|
|
1114
|
+
return false;
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
let ancestorRecordsWrite: RecordsWriteMessage | undefined;
|
|
1118
|
+
|
|
1119
|
+
if (isCrossProtocolRef(ofValue) && composingDefinition?.uses !== undefined) {
|
|
1120
|
+
// Cross-protocol `of`: resolve alias to protocol URI and match by both protocol + protocolPath
|
|
1121
|
+
const parsed = parseCrossProtocolRef(ofValue);
|
|
1122
|
+
if (parsed !== undefined) {
|
|
1123
|
+
const refProtocolUri = composingDefinition.uses[parsed.alias];
|
|
1124
|
+
if (refProtocolUri !== undefined) {
|
|
1125
|
+
ancestorRecordsWrite = recordChain.find((msg) =>
|
|
1126
|
+
msg.descriptor.protocol === refProtocolUri && msg.descriptor.protocolPath === parsed.protocolPath
|
|
1127
|
+
);
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
} else {
|
|
1131
|
+
// Local `of`: match by protocolPath only (same protocol assumed)
|
|
1132
|
+
ancestorRecordsWrite = recordChain.find((msg) =>
|
|
1133
|
+
msg.descriptor.protocolPath === ofValue
|
|
1134
|
+
);
|
|
1135
|
+
}
|
|
882
1136
|
|
|
883
1137
|
if (ancestorRecordsWrite === undefined) {
|
|
884
|
-
//
|
|
885
|
-
//
|
|
886
|
-
// consider moving this check to ProtocolsConfigure message ingestion
|
|
1138
|
+
// No matching ancestor found in the record chain. Return false to allow the caller
|
|
1139
|
+
// to continue evaluating other action rules that might authorize the request.
|
|
887
1140
|
return false;
|
|
888
1141
|
}
|
|
889
1142
|
|
|
@@ -897,6 +1150,30 @@ export class ProtocolAuthorization {
|
|
|
897
1150
|
}
|
|
898
1151
|
}
|
|
899
1152
|
|
|
1153
|
+
/**
|
|
1154
|
+
* Determines the timestamp that governs which protocol definition version applies to the given RecordsWrite.
|
|
1155
|
+
* For an update, this is the initial write's `messageTimestamp` (the protocol version is locked at creation time).
|
|
1156
|
+
* For a new initial write, returns `undefined` — the latest protocol definition should be used because the
|
|
1157
|
+
* record is being created now and must conform to the current protocol rules.
|
|
1158
|
+
*/
|
|
1159
|
+
private static async getGoverningTimestamp(
|
|
1160
|
+
tenant: string,
|
|
1161
|
+
incomingMessage: RecordsWrite,
|
|
1162
|
+
messageStore: MessageStore,
|
|
1163
|
+
): Promise<string | undefined> {
|
|
1164
|
+
const existingInitialWrite = await ProtocolAuthorization.fetchInitialWrite(
|
|
1165
|
+
tenant, incomingMessage.message.recordId, messageStore
|
|
1166
|
+
);
|
|
1167
|
+
|
|
1168
|
+
if (existingInitialWrite !== undefined) {
|
|
1169
|
+
// update case: use the initial write's timestamp
|
|
1170
|
+
return existingInitialWrite.descriptor.messageTimestamp;
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
// initial write case: validate against the latest protocol definition
|
|
1174
|
+
return undefined;
|
|
1175
|
+
}
|
|
1176
|
+
|
|
900
1177
|
private static getTypeName(protocolPath: string): string {
|
|
901
1178
|
return protocolPath.split('/').slice(-1)[0];
|
|
902
1179
|
}
|