@abaxxtech/id 0.0.0
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/LICENSE +201 -0
- package/README.md +31 -0
- package/README.npm.md +31 -0
- package/dist/bundles/dwn.js +83 -0
- package/dist/cjs/index.js +31250 -0
- package/dist/cjs/package.json +1 -0
- package/dist/esm/generated/precompiled-validators.js +7820 -0
- package/dist/esm/generated/precompiled-validators.js.map +1 -0
- package/dist/esm/json-schemas/definitions.json +23 -0
- package/dist/esm/src/core/abstract-message.js +37 -0
- package/dist/esm/src/core/abstract-message.js.map +1 -0
- package/dist/esm/src/core/auth.js +97 -0
- package/dist/esm/src/core/auth.js.map +1 -0
- package/dist/esm/src/core/dwn-constant.js +8 -0
- package/dist/esm/src/core/dwn-constant.js.map +1 -0
- package/dist/esm/src/core/dwn-error.js +138 -0
- package/dist/esm/src/core/dwn-error.js.map +1 -0
- package/dist/esm/src/core/grant-authorization.js +108 -0
- package/dist/esm/src/core/grant-authorization.js.map +1 -0
- package/dist/esm/src/core/message-reply.js +5 -0
- package/dist/esm/src/core/message-reply.js.map +1 -0
- package/dist/esm/src/core/message.js +200 -0
- package/dist/esm/src/core/message.js.map +1 -0
- package/dist/esm/src/core/protocol-authorization.js +449 -0
- package/dist/esm/src/core/protocol-authorization.js.map +1 -0
- package/dist/esm/src/core/records-grant-authorization.js +106 -0
- package/dist/esm/src/core/records-grant-authorization.js.map +1 -0
- package/dist/esm/src/core/tenant-gate.js +20 -0
- package/dist/esm/src/core/tenant-gate.js.map +1 -0
- package/dist/esm/src/did/did-dht-resolver.js +241 -0
- package/dist/esm/src/did/did-dht-resolver.js.map +1 -0
- package/dist/esm/src/did/did-ion-resolver.js +53 -0
- package/dist/esm/src/did/did-ion-resolver.js.map +1 -0
- package/dist/esm/src/did/did-key-resolver.js +135 -0
- package/dist/esm/src/did/did-key-resolver.js.map +1 -0
- package/dist/esm/src/did/did-resolver.js +70 -0
- package/dist/esm/src/did/did-resolver.js.map +1 -0
- package/dist/esm/src/did/did.js +36 -0
- package/dist/esm/src/did/did.js.map +1 -0
- package/dist/esm/src/dwn.js +164 -0
- package/dist/esm/src/dwn.js.map +1 -0
- package/dist/esm/src/enums/dwn-interface-method.js +22 -0
- package/dist/esm/src/enums/dwn-interface-method.js.map +1 -0
- package/dist/esm/src/event-log/event-log-level.js +112 -0
- package/dist/esm/src/event-log/event-log-level.js.map +1 -0
- package/dist/esm/src/handlers/events-get.js +48 -0
- package/dist/esm/src/handlers/events-get.js.map +1 -0
- package/dist/esm/src/handlers/messages-get.js +76 -0
- package/dist/esm/src/handlers/messages-get.js.map +1 -0
- package/dist/esm/src/handlers/permissions-grant.js +62 -0
- package/dist/esm/src/handlers/permissions-grant.js.map +1 -0
- package/dist/esm/src/handlers/permissions-request.js +63 -0
- package/dist/esm/src/handlers/permissions-request.js.map +1 -0
- package/dist/esm/src/handlers/permissions-revoke.js +114 -0
- package/dist/esm/src/handlers/permissions-revoke.js.map +1 -0
- package/dist/esm/src/handlers/protocols-configure.js +102 -0
- package/dist/esm/src/handlers/protocols-configure.js.map +1 -0
- package/dist/esm/src/handlers/protocols-query.js +72 -0
- package/dist/esm/src/handlers/protocols-query.js.map +1 -0
- package/dist/esm/src/handlers/records-delete.js +119 -0
- package/dist/esm/src/handlers/records-delete.js.map +1 -0
- package/dist/esm/src/handlers/records-query.js +206 -0
- package/dist/esm/src/handlers/records-query.js.map +1 -0
- package/dist/esm/src/handlers/records-read.js +118 -0
- package/dist/esm/src/handlers/records-read.js.map +1 -0
- package/dist/esm/src/handlers/records-write.js +252 -0
- package/dist/esm/src/handlers/records-write.js.map +1 -0
- package/dist/esm/src/index.js +43 -0
- package/dist/esm/src/index.js.map +1 -0
- package/dist/esm/src/interfaces/events-get.js +41 -0
- package/dist/esm/src/interfaces/events-get.js.map +1 -0
- package/dist/esm/src/interfaces/messages-get.js +58 -0
- package/dist/esm/src/interfaces/messages-get.js.map +1 -0
- package/dist/esm/src/interfaces/permissions-grant.js +130 -0
- package/dist/esm/src/interfaces/permissions-grant.js.map +1 -0
- package/dist/esm/src/interfaces/permissions-request.js +47 -0
- package/dist/esm/src/interfaces/permissions-request.js.map +1 -0
- package/dist/esm/src/interfaces/permissions-revoke.js +47 -0
- package/dist/esm/src/interfaces/permissions-revoke.js.map +1 -0
- package/dist/esm/src/interfaces/protocols-configure.js +149 -0
- package/dist/esm/src/interfaces/protocols-configure.js.map +1 -0
- package/dist/esm/src/interfaces/protocols-query.js +80 -0
- package/dist/esm/src/interfaces/protocols-query.js.map +1 -0
- package/dist/esm/src/interfaces/records-delete.js +56 -0
- package/dist/esm/src/interfaces/records-delete.js.map +1 -0
- package/dist/esm/src/interfaces/records-query.js +81 -0
- package/dist/esm/src/interfaces/records-query.js.map +1 -0
- package/dist/esm/src/interfaces/records-read.js +65 -0
- package/dist/esm/src/interfaces/records-read.js.map +1 -0
- package/dist/esm/src/interfaces/records-write.js +677 -0
- package/dist/esm/src/interfaces/records-write.js.map +1 -0
- package/dist/esm/src/jose/algorithms/signing/ed25519.js +54 -0
- package/dist/esm/src/jose/algorithms/signing/ed25519.js.map +1 -0
- package/dist/esm/src/jose/algorithms/signing/signature-algorithms.js +13 -0
- package/dist/esm/src/jose/algorithms/signing/signature-algorithms.js.map +1 -0
- package/dist/esm/src/jose/jws/general/builder.js +47 -0
- package/dist/esm/src/jose/jws/general/builder.js.map +1 -0
- package/dist/esm/src/jose/jws/general/signer.js +36 -0
- package/dist/esm/src/jose/jws/general/signer.js.map +1 -0
- package/dist/esm/src/jose/jws/general/verifier.js +97 -0
- package/dist/esm/src/jose/jws/general/verifier.js.map +1 -0
- package/dist/esm/src/schema-validator.js +28 -0
- package/dist/esm/src/schema-validator.js.map +1 -0
- package/dist/esm/src/store/blockstore-level.js +187 -0
- package/dist/esm/src/store/blockstore-level.js.map +1 -0
- package/dist/esm/src/store/data-store-level.js +192 -0
- package/dist/esm/src/store/data-store-level.js.map +1 -0
- package/dist/esm/src/store/index-level.js +302 -0
- package/dist/esm/src/store/index-level.js.map +1 -0
- package/dist/esm/src/store/level-wrapper.js +296 -0
- package/dist/esm/src/store/level-wrapper.js.map +1 -0
- package/dist/esm/src/store/message-store-level.js +236 -0
- package/dist/esm/src/store/message-store-level.js.map +1 -0
- package/dist/esm/src/store/storage-controller.js +69 -0
- package/dist/esm/src/store/storage-controller.js.map +1 -0
- package/dist/esm/src/types/cache.js +2 -0
- package/dist/esm/src/types/cache.js.map +1 -0
- package/dist/esm/src/types/data-store.js +2 -0
- package/dist/esm/src/types/data-store.js.map +1 -0
- package/dist/esm/src/types/delegated-grant-message.js +2 -0
- package/dist/esm/src/types/delegated-grant-message.js.map +1 -0
- package/dist/esm/src/types/did-types.js +2 -0
- package/dist/esm/src/types/did-types.js.map +1 -0
- package/dist/esm/src/types/event-log.js +2 -0
- package/dist/esm/src/types/event-log.js.map +1 -0
- package/dist/esm/src/types/event-types.js +2 -0
- package/dist/esm/src/types/event-types.js.map +1 -0
- package/dist/esm/src/types/jose-types.js +2 -0
- package/dist/esm/src/types/jose-types.js.map +1 -0
- package/dist/esm/src/types/jws-types.js +2 -0
- package/dist/esm/src/types/jws-types.js.map +1 -0
- package/dist/esm/src/types/message-interface.js +2 -0
- package/dist/esm/src/types/message-interface.js.map +1 -0
- package/dist/esm/src/types/message-store.js +2 -0
- package/dist/esm/src/types/message-store.js.map +1 -0
- package/dist/esm/src/types/message-types.js +6 -0
- package/dist/esm/src/types/message-types.js.map +1 -0
- package/dist/esm/src/types/messages-types.js +2 -0
- package/dist/esm/src/types/messages-types.js.map +1 -0
- package/dist/esm/src/types/method-handler.js +2 -0
- package/dist/esm/src/types/method-handler.js.map +1 -0
- package/dist/esm/src/types/permissions-grant-descriptor.js +6 -0
- package/dist/esm/src/types/permissions-grant-descriptor.js.map +1 -0
- package/dist/esm/src/types/permissions-types.js +2 -0
- package/dist/esm/src/types/permissions-types.js.map +1 -0
- package/dist/esm/src/types/protocols-types.js +15 -0
- package/dist/esm/src/types/protocols-types.js.map +1 -0
- package/dist/esm/src/types/records-types.js +8 -0
- package/dist/esm/src/types/records-types.js.map +1 -0
- package/dist/esm/src/types/signer.js +2 -0
- package/dist/esm/src/types/signer.js.map +1 -0
- package/dist/esm/src/utils/abort.js +40 -0
- package/dist/esm/src/utils/abort.js.map +1 -0
- package/dist/esm/src/utils/array.js +72 -0
- package/dist/esm/src/utils/array.js.map +1 -0
- package/dist/esm/src/utils/cid.js +130 -0
- package/dist/esm/src/utils/cid.js.map +1 -0
- package/dist/esm/src/utils/data-stream.js +88 -0
- package/dist/esm/src/utils/data-stream.js.map +1 -0
- package/dist/esm/src/utils/encoder.js +45 -0
- package/dist/esm/src/utils/encoder.js.map +1 -0
- package/dist/esm/src/utils/encryption.js +128 -0
- package/dist/esm/src/utils/encryption.js.map +1 -0
- package/dist/esm/src/utils/hd-key.js +60 -0
- package/dist/esm/src/utils/hd-key.js.map +1 -0
- package/dist/esm/src/utils/jws.js +89 -0
- package/dist/esm/src/utils/jws.js.map +1 -0
- package/dist/esm/src/utils/memory-cache.js +41 -0
- package/dist/esm/src/utils/memory-cache.js.map +1 -0
- package/dist/esm/src/utils/object.js +50 -0
- package/dist/esm/src/utils/object.js.map +1 -0
- package/dist/esm/src/utils/private-key-signer.js +43 -0
- package/dist/esm/src/utils/private-key-signer.js.map +1 -0
- package/dist/esm/src/utils/protocols.js +51 -0
- package/dist/esm/src/utils/protocols.js.map +1 -0
- package/dist/esm/src/utils/records.js +267 -0
- package/dist/esm/src/utils/records.js.map +1 -0
- package/dist/esm/src/utils/secp256k1.js +219 -0
- package/dist/esm/src/utils/secp256k1.js.map +1 -0
- package/dist/esm/src/utils/string.js +16 -0
- package/dist/esm/src/utils/string.js.map +1 -0
- package/dist/esm/src/utils/time.js +84 -0
- package/dist/esm/src/utils/time.js.map +1 -0
- package/dist/esm/src/utils/url.js +63 -0
- package/dist/esm/src/utils/url.js.map +1 -0
- package/dist/esm/tests/core/auth.spec.js +25 -0
- package/dist/esm/tests/core/auth.spec.js.map +1 -0
- package/dist/esm/tests/core/message-reply.spec.js +19 -0
- package/dist/esm/tests/core/message-reply.spec.js.map +1 -0
- package/dist/esm/tests/core/message.spec.js +85 -0
- package/dist/esm/tests/core/message.spec.js.map +1 -0
- package/dist/esm/tests/did/did-ion-resolver.spec.js +82 -0
- package/dist/esm/tests/did/did-ion-resolver.spec.js.map +1 -0
- package/dist/esm/tests/did/did-key-resolver.spec.js +74 -0
- package/dist/esm/tests/did/did-key-resolver.spec.js.map +1 -0
- package/dist/esm/tests/did/did-resolver.spec.js +84 -0
- package/dist/esm/tests/did/did-resolver.spec.js.map +1 -0
- package/dist/esm/tests/did/did.spec.js +22 -0
- package/dist/esm/tests/did/did.spec.js.map +1 -0
- package/dist/esm/tests/dwn.spec.js +252 -0
- package/dist/esm/tests/dwn.spec.js.map +1 -0
- package/dist/esm/tests/end-to-end-tests.spec.js +218 -0
- package/dist/esm/tests/end-to-end-tests.spec.js.map +1 -0
- package/dist/esm/tests/event-log/event-log-level.spec.js +137 -0
- package/dist/esm/tests/event-log/event-log-level.spec.js.map +1 -0
- package/dist/esm/tests/handlers/events-get.spec.js +108 -0
- package/dist/esm/tests/handlers/events-get.spec.js.map +1 -0
- package/dist/esm/tests/handlers/messages-get.spec.js +209 -0
- package/dist/esm/tests/handlers/messages-get.spec.js.map +1 -0
- package/dist/esm/tests/handlers/permissions-grant.spec.js +249 -0
- package/dist/esm/tests/handlers/permissions-grant.spec.js.map +1 -0
- package/dist/esm/tests/handlers/permissions-request.spec.js +132 -0
- package/dist/esm/tests/handlers/permissions-request.spec.js.map +1 -0
- package/dist/esm/tests/handlers/permissions-revoke.spec.js +311 -0
- package/dist/esm/tests/handlers/permissions-revoke.spec.js.map +1 -0
- package/dist/esm/tests/handlers/protocols-configure.spec.js +254 -0
- package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -0
- package/dist/esm/tests/handlers/protocols-query.spec.js +373 -0
- package/dist/esm/tests/handlers/protocols-query.spec.js.map +1 -0
- package/dist/esm/tests/handlers/records-delete.spec.js +630 -0
- package/dist/esm/tests/handlers/records-delete.spec.js.map +1 -0
- package/dist/esm/tests/handlers/records-query.spec.js +1937 -0
- package/dist/esm/tests/handlers/records-query.spec.js.map +1 -0
- package/dist/esm/tests/handlers/records-read.spec.js +1729 -0
- package/dist/esm/tests/handlers/records-read.spec.js.map +1 -0
- package/dist/esm/tests/handlers/records-write.spec.js +3381 -0
- package/dist/esm/tests/handlers/records-write.spec.js.map +1 -0
- package/dist/esm/tests/interfaces/events-get.spec.js +73 -0
- package/dist/esm/tests/interfaces/events-get.spec.js.map +1 -0
- package/dist/esm/tests/interfaces/messages-get.spec.js +93 -0
- package/dist/esm/tests/interfaces/messages-get.spec.js.map +1 -0
- package/dist/esm/tests/interfaces/permissions-grant.spec.js +216 -0
- package/dist/esm/tests/interfaces/permissions-grant.spec.js.map +1 -0
- package/dist/esm/tests/interfaces/permissions-request.spec.js +45 -0
- package/dist/esm/tests/interfaces/permissions-request.spec.js.map +1 -0
- package/dist/esm/tests/interfaces/protocols-configure.spec.js +334 -0
- package/dist/esm/tests/interfaces/protocols-configure.spec.js.map +1 -0
- package/dist/esm/tests/interfaces/protocols-query.spec.js +49 -0
- package/dist/esm/tests/interfaces/protocols-query.spec.js.map +1 -0
- package/dist/esm/tests/interfaces/records-delete.spec.js +42 -0
- package/dist/esm/tests/interfaces/records-delete.spec.js.map +1 -0
- package/dist/esm/tests/interfaces/records-query.spec.js +75 -0
- package/dist/esm/tests/interfaces/records-query.spec.js.map +1 -0
- package/dist/esm/tests/interfaces/records-read.spec.js +65 -0
- package/dist/esm/tests/interfaces/records-read.spec.js.map +1 -0
- package/dist/esm/tests/interfaces/records-write.spec.js +369 -0
- package/dist/esm/tests/interfaces/records-write.spec.js.map +1 -0
- package/dist/esm/tests/jose/jws/general.spec.js +185 -0
- package/dist/esm/tests/jose/jws/general.spec.js.map +1 -0
- package/dist/esm/tests/scenarios/delegated-grant.spec.js +490 -0
- package/dist/esm/tests/scenarios/delegated-grant.spec.js.map +1 -0
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js +218 -0
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js.map +1 -0
- package/dist/esm/tests/store/data-store-level.spec.js +192 -0
- package/dist/esm/tests/store/data-store-level.spec.js.map +1 -0
- package/dist/esm/tests/store/index-level.spec.js +428 -0
- package/dist/esm/tests/store/index-level.spec.js.map +1 -0
- package/dist/esm/tests/store/message-store-level.spec.js +51 -0
- package/dist/esm/tests/store/message-store-level.spec.js.map +1 -0
- package/dist/esm/tests/store/message-store.spec.js +395 -0
- package/dist/esm/tests/store/message-store.spec.js.map +1 -0
- package/dist/esm/tests/store-dependent-tests.spec.js +8 -0
- package/dist/esm/tests/store-dependent-tests.spec.js.map +1 -0
- package/dist/esm/tests/test-stores.js +40 -0
- package/dist/esm/tests/test-stores.js.map +1 -0
- package/dist/esm/tests/test-suite.js +51 -0
- package/dist/esm/tests/test-suite.js.map +1 -0
- package/dist/esm/tests/utils/cid.spec.js +83 -0
- package/dist/esm/tests/utils/cid.spec.js.map +1 -0
- package/dist/esm/tests/utils/data-stream.spec.js +30 -0
- package/dist/esm/tests/utils/data-stream.spec.js.map +1 -0
- package/dist/esm/tests/utils/encryption.spec.js +151 -0
- package/dist/esm/tests/utils/encryption.spec.js.map +1 -0
- package/dist/esm/tests/utils/jws.spec.js +11 -0
- package/dist/esm/tests/utils/jws.spec.js.map +1 -0
- package/dist/esm/tests/utils/memory-cache.spec.js +38 -0
- package/dist/esm/tests/utils/memory-cache.spec.js.map +1 -0
- package/dist/esm/tests/utils/object.spec.js +39 -0
- package/dist/esm/tests/utils/object.spec.js.map +1 -0
- package/dist/esm/tests/utils/private-key-signer.spec.js +47 -0
- package/dist/esm/tests/utils/private-key-signer.spec.js.map +1 -0
- package/dist/esm/tests/utils/records.spec.js +56 -0
- package/dist/esm/tests/utils/records.spec.js.map +1 -0
- package/dist/esm/tests/utils/secp256k1.spec.js +77 -0
- package/dist/esm/tests/utils/secp256k1.spec.js.map +1 -0
- package/dist/esm/tests/utils/test-data-generator.js +570 -0
- package/dist/esm/tests/utils/test-data-generator.js.map +1 -0
- package/dist/esm/tests/utils/test-stub-generator.js +39 -0
- package/dist/esm/tests/utils/test-stub-generator.js.map +1 -0
- package/dist/esm/tests/utils/time.spec.js +67 -0
- package/dist/esm/tests/utils/time.spec.js.map +1 -0
- package/dist/esm/tests/utils/url.spec.js +46 -0
- package/dist/esm/tests/utils/url.spec.js.map +1 -0
- package/dist/esm/tests/validation/json-schemas/definitions.spec.js +36 -0
- package/dist/esm/tests/validation/json-schemas/definitions.spec.js.map +1 -0
- package/dist/esm/tests/validation/json-schemas/jwk/general-jwk.spec.js +53 -0
- package/dist/esm/tests/validation/json-schemas/jwk/general-jwk.spec.js.map +1 -0
- package/dist/esm/tests/validation/json-schemas/jwk/public-jwk.spec.js +39 -0
- package/dist/esm/tests/validation/json-schemas/jwk/public-jwk.spec.js.map +1 -0
- package/dist/esm/tests/validation/json-schemas/jwk-verification-method.spec.js +76 -0
- package/dist/esm/tests/validation/json-schemas/jwk-verification-method.spec.js.map +1 -0
- package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js +74 -0
- package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js.map +1 -0
- package/dist/esm/tests/validation/json-schemas/records/records-query.spec.js +151 -0
- package/dist/esm/tests/validation/json-schemas/records/records-query.spec.js.map +1 -0
- package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js +389 -0
- package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js.map +1 -0
- package/dist/esm/tests/vectors/protocol-definitions/anyone-collaborate.json +25 -0
- package/dist/esm/tests/vectors/protocol-definitions/author-can.json +32 -0
- package/dist/esm/tests/vectors/protocol-definitions/chat.json +56 -0
- package/dist/esm/tests/vectors/protocol-definitions/credential-issuance.json +37 -0
- package/dist/esm/tests/vectors/protocol-definitions/dex.json +52 -0
- package/dist/esm/tests/vectors/protocol-definitions/email.json +50 -0
- package/dist/esm/tests/vectors/protocol-definitions/free-for-all.json +30 -0
- package/dist/esm/tests/vectors/protocol-definitions/friend-role.json +48 -0
- package/dist/esm/tests/vectors/protocol-definitions/message.json +20 -0
- package/dist/esm/tests/vectors/protocol-definitions/minimal.json +10 -0
- package/dist/esm/tests/vectors/protocol-definitions/nested.json +31 -0
- package/dist/esm/tests/vectors/protocol-definitions/private-protocol.json +13 -0
- package/dist/esm/tests/vectors/protocol-definitions/recipient-can.json +36 -0
- package/dist/esm/tests/vectors/protocol-definitions/social-media.json +88 -0
- package/dist/esm/tests/vectors/protocol-definitions/thread-role.json +68 -0
- package/dist/types/generated/precompiled-validators.d.ts +113 -0
- package/dist/types/generated/precompiled-validators.d.ts.map +1 -0
- package/dist/types/src/core/abstract-message.d.ts +19 -0
- package/dist/types/src/core/abstract-message.d.ts.map +1 -0
- package/dist/types/src/core/auth.d.ts +30 -0
- package/dist/types/src/core/auth.d.ts.map +1 -0
- package/dist/types/src/core/dwn-constant.d.ts +8 -0
- package/dist/types/src/core/dwn-constant.d.ts.map +1 -0
- package/dist/types/src/core/dwn-error.d.ts +133 -0
- package/dist/types/src/core/dwn-error.d.ts.map +1 -0
- package/dist/types/src/core/grant-authorization.d.ts +35 -0
- package/dist/types/src/core/grant-authorization.d.ts.map +1 -0
- package/dist/types/src/core/message-reply.d.ts +33 -0
- package/dist/types/src/core/message-reply.d.ts.map +1 -0
- package/dist/types/src/core/message.d.ts +79 -0
- package/dist/types/src/core/message.d.ts.map +1 -0
- package/dist/types/src/core/protocol-authorization.d.ts +85 -0
- package/dist/types/src/core/protocol-authorization.d.ts.map +1 -0
- package/dist/types/src/core/records-grant-authorization.d.ts +38 -0
- package/dist/types/src/core/records-grant-authorization.d.ts.map +1 -0
- package/dist/types/src/core/tenant-gate.d.ts +16 -0
- package/dist/types/src/core/tenant-gate.d.ts.map +1 -0
- package/dist/types/src/did/did-dht-resolver.d.ts +26 -0
- package/dist/types/src/did/did-dht-resolver.d.ts.map +1 -0
- package/dist/types/src/did/did-ion-resolver.d.ts +20 -0
- package/dist/types/src/did/did-ion-resolver.d.ts.map +1 -0
- package/dist/types/src/did/did-key-resolver.d.ts +32 -0
- package/dist/types/src/did/did-key-resolver.d.ts.map +1 -0
- package/dist/types/src/did/did-resolver.d.ts +20 -0
- package/dist/types/src/did/did-resolver.d.ts.map +1 -0
- package/dist/types/src/did/did.d.ts +15 -0
- package/dist/types/src/did/did.d.ts.map +1 -0
- package/dist/types/src/dwn.d.ts +74 -0
- package/dist/types/src/dwn.d.ts.map +1 -0
- package/dist/types/src/enums/dwn-interface-method.d.ts +20 -0
- package/dist/types/src/enums/dwn-interface-method.d.ts.map +1 -0
- package/dist/types/src/event-log/event-log-level.d.ts +26 -0
- package/dist/types/src/event-log/event-log-level.d.ts.map +1 -0
- package/dist/types/src/handlers/events-get.d.ts +16 -0
- package/dist/types/src/handlers/events-get.d.ts.map +1 -0
- package/dist/types/src/handlers/messages-get.d.ts +18 -0
- package/dist/types/src/handlers/messages-get.d.ts.map +1 -0
- package/dist/types/src/handlers/permissions-grant.d.ts +17 -0
- package/dist/types/src/handlers/permissions-grant.d.ts.map +1 -0
- package/dist/types/src/handlers/permissions-request.d.ts +17 -0
- package/dist/types/src/handlers/permissions-request.d.ts.map +1 -0
- package/dist/types/src/handlers/permissions-revoke.d.ts +17 -0
- package/dist/types/src/handlers/permissions-revoke.d.ts.map +1 -0
- package/dist/types/src/handlers/protocols-configure.d.ts +21 -0
- package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -0
- package/dist/types/src/handlers/protocols-query.d.ts +20 -0
- package/dist/types/src/handlers/protocols-query.d.ts.map +1 -0
- package/dist/types/src/handlers/records-delete.d.ts +22 -0
- package/dist/types/src/handlers/records-delete.d.ts.map +1 -0
- package/dist/types/src/handlers/records-query.d.ts +78 -0
- package/dist/types/src/handlers/records-query.d.ts.map +1 -0
- package/dist/types/src/handlers/records-read.d.ts +17 -0
- package/dist/types/src/handlers/records-read.d.ts.map +1 -0
- package/dist/types/src/handlers/records-write.d.ts +61 -0
- package/dist/types/src/handlers/records-write.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +72 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/interfaces/events-get.d.ts +13 -0
- package/dist/types/src/interfaces/events-get.d.ts.map +1 -0
- package/dist/types/src/interfaces/messages-get.d.ts +19 -0
- package/dist/types/src/interfaces/messages-get.d.ts.map +1 -0
- package/dist/types/src/interfaces/permissions-grant.d.ts +59 -0
- package/dist/types/src/interfaces/permissions-grant.d.ts.map +1 -0
- package/dist/types/src/interfaces/permissions-request.d.ts +19 -0
- package/dist/types/src/interfaces/permissions-request.d.ts.map +1 -0
- package/dist/types/src/interfaces/permissions-revoke.d.ts +14 -0
- package/dist/types/src/interfaces/permissions-revoke.d.ts.map +1 -0
- package/dist/types/src/interfaces/protocols-configure.d.ts +21 -0
- package/dist/types/src/interfaces/protocols-configure.d.ts.map +1 -0
- package/dist/types/src/interfaces/protocols-query.d.ts +17 -0
- package/dist/types/src/interfaces/protocols-query.d.ts.map +1 -0
- package/dist/types/src/interfaces/records-delete.d.ts +24 -0
- package/dist/types/src/interfaces/records-delete.d.ts.map +1 -0
- package/dist/types/src/interfaces/records-query.d.ts +29 -0
- package/dist/types/src/interfaces/records-query.d.ts.map +1 -0
- package/dist/types/src/interfaces/records-read.d.ts +31 -0
- package/dist/types/src/interfaces/records-read.d.ts.map +1 -0
- package/dist/types/src/interfaces/records-write.d.ts +259 -0
- package/dist/types/src/interfaces/records-write.d.ts.map +1 -0
- package/dist/types/src/jose/algorithms/signing/ed25519.d.ts +3 -0
- package/dist/types/src/jose/algorithms/signing/ed25519.d.ts.map +1 -0
- package/dist/types/src/jose/algorithms/signing/signature-algorithms.d.ts +3 -0
- package/dist/types/src/jose/algorithms/signing/signature-algorithms.d.ts.map +1 -0
- package/dist/types/src/jose/jws/general/builder.d.ts +10 -0
- package/dist/types/src/jose/jws/general/builder.d.ts.map +1 -0
- package/dist/types/src/jose/jws/general/signer.d.ts +8 -0
- package/dist/types/src/jose/jws/general/signer.d.ts.map +1 -0
- package/dist/types/src/jose/jws/general/verifier.d.ts +32 -0
- package/dist/types/src/jose/jws/general/verifier.d.ts.map +1 -0
- package/dist/types/src/schema-validator.d.ts +8 -0
- package/dist/types/src/schema-validator.d.ts.map +1 -0
- package/dist/types/src/store/blockstore-level.d.ts +35 -0
- package/dist/types/src/store/blockstore-level.d.ts.map +1 -0
- package/dist/types/src/store/data-store-level.d.ts +44 -0
- package/dist/types/src/store/data-store-level.d.ts.map +1 -0
- package/dist/types/src/store/index-level.d.ts +69 -0
- package/dist/types/src/store/index-level.d.ts.map +1 -0
- package/dist/types/src/store/level-wrapper.d.ts +44 -0
- package/dist/types/src/store/level-wrapper.d.ts.map +1 -0
- package/dist/types/src/store/message-store-level.d.ts +70 -0
- package/dist/types/src/store/message-store-level.d.ts.map +1 -0
- package/dist/types/src/store/storage-controller.d.ts +19 -0
- package/dist/types/src/store/storage-controller.d.ts.map +1 -0
- package/dist/types/src/types/cache.d.ts +16 -0
- package/dist/types/src/types/cache.d.ts.map +1 -0
- package/dist/types/src/types/data-store.d.ts +69 -0
- package/dist/types/src/types/data-store.d.ts.map +1 -0
- package/dist/types/src/types/delegated-grant-message.d.ts +14 -0
- package/dist/types/src/types/delegated-grant-message.d.ts.map +1 -0
- package/dist/types/src/types/did-types.d.ts +68 -0
- package/dist/types/src/types/did-types.d.ts.map +1 -0
- package/dist/types/src/types/event-log.d.ts +39 -0
- package/dist/types/src/types/event-log.d.ts.map +1 -0
- package/dist/types/src/types/event-types.d.ts +18 -0
- package/dist/types/src/types/event-types.d.ts.map +1 -0
- package/dist/types/src/types/jose-types.d.ts +75 -0
- package/dist/types/src/types/jose-types.d.ts.map +1 -0
- package/dist/types/src/types/jws-types.d.ts +27 -0
- package/dist/types/src/types/jws-types.d.ts.map +1 -0
- package/dist/types/src/types/message-interface.d.ts +22 -0
- package/dist/types/src/types/message-interface.d.ts.map +1 -0
- package/dist/types/src/types/message-store.d.ts +43 -0
- package/dist/types/src/types/message-store.d.ts.map +1 -0
- package/dist/types/src/types/message-types.d.ts +113 -0
- package/dist/types/src/types/message-types.d.ts.map +1 -0
- package/dist/types/src/types/messages-types.d.ts +23 -0
- package/dist/types/src/types/messages-types.d.ts.map +1 -0
- package/dist/types/src/types/method-handler.d.ts +17 -0
- package/dist/types/src/types/method-handler.d.ts.map +1 -0
- package/dist/types/src/types/permissions-grant-descriptor.d.ts +65 -0
- package/dist/types/src/types/permissions-grant-descriptor.d.ts.map +1 -0
- package/dist/types/src/types/permissions-types.d.ts +33 -0
- package/dist/types/src/types/permissions-types.d.ts.map +1 -0
- package/dist/types/src/types/protocols-types.d.ts +138 -0
- package/dist/types/src/types/protocols-types.d.ts.map +1 -0
- package/dist/types/src/types/records-types.d.ts +164 -0
- package/dist/types/src/types/records-types.d.ts.map +1 -0
- package/dist/types/src/types/signer.d.ts +26 -0
- package/dist/types/src/types/signer.d.ts.map +1 -0
- package/dist/types/src/utils/abort.d.ts +5 -0
- package/dist/types/src/utils/abort.d.ts.map +1 -0
- package/dist/types/src/utils/array.d.ts +18 -0
- package/dist/types/src/utils/array.d.ts.map +1 -0
- package/dist/types/src/utils/cid.d.ts +30 -0
- package/dist/types/src/utils/cid.d.ts.map +1 -0
- package/dist/types/src/utils/data-stream.d.ts +27 -0
- package/dist/types/src/utils/data-stream.d.ts.map +1 -0
- package/dist/types/src/utils/encoder.d.ts +14 -0
- package/dist/types/src/utils/encoder.d.ts.map +1 -0
- package/dist/types/src/utils/encryption.d.ts +44 -0
- package/dist/types/src/utils/encryption.d.ts.map +1 -0
- package/dist/types/src/utils/hd-key.d.ts +35 -0
- package/dist/types/src/utils/hd-key.d.ts.map +1 -0
- package/dist/types/src/utils/jws.d.ts +39 -0
- package/dist/types/src/utils/jws.d.ts.map +1 -0
- package/dist/types/src/utils/memory-cache.d.ts +15 -0
- package/dist/types/src/utils/memory-cache.d.ts.map +1 -0
- package/dist/types/src/utils/object.d.ts +18 -0
- package/dist/types/src/utils/object.d.ts.map +1 -0
- package/dist/types/src/utils/private-key-signer.d.ts +34 -0
- package/dist/types/src/utils/private-key-signer.d.ts.map +1 -0
- package/dist/types/src/utils/protocols.d.ts +14 -0
- package/dist/types/src/utils/protocols.d.ts.map +1 -0
- package/dist/types/src/utils/records.d.ts +68 -0
- package/dist/types/src/utils/records.d.ts.map +1 -0
- package/dist/types/src/utils/secp256k1.d.ts +78 -0
- package/dist/types/src/utils/secp256k1.d.ts.map +1 -0
- package/dist/types/src/utils/string.d.ts +6 -0
- package/dist/types/src/utils/string.d.ts.map +1 -0
- package/dist/types/src/utils/time.d.ts +49 -0
- package/dist/types/src/utils/time.d.ts.map +1 -0
- package/dist/types/src/utils/url.d.ts +5 -0
- package/dist/types/src/utils/url.d.ts.map +1 -0
- package/dist/types/tests/core/auth.spec.d.ts +2 -0
- package/dist/types/tests/core/auth.spec.d.ts.map +1 -0
- package/dist/types/tests/core/message-reply.spec.d.ts +2 -0
- package/dist/types/tests/core/message-reply.spec.d.ts.map +1 -0
- package/dist/types/tests/core/message.spec.d.ts +2 -0
- package/dist/types/tests/core/message.spec.d.ts.map +1 -0
- package/dist/types/tests/did/did-ion-resolver.spec.d.ts +2 -0
- package/dist/types/tests/did/did-ion-resolver.spec.d.ts.map +1 -0
- package/dist/types/tests/did/did-key-resolver.spec.d.ts +2 -0
- package/dist/types/tests/did/did-key-resolver.spec.d.ts.map +1 -0
- package/dist/types/tests/did/did-resolver.spec.d.ts +2 -0
- package/dist/types/tests/did/did-resolver.spec.d.ts.map +1 -0
- package/dist/types/tests/did/did.spec.d.ts +2 -0
- package/dist/types/tests/did/did.spec.d.ts.map +1 -0
- package/dist/types/tests/dwn.spec.d.ts +2 -0
- package/dist/types/tests/dwn.spec.d.ts.map +1 -0
- package/dist/types/tests/end-to-end-tests.spec.d.ts +2 -0
- package/dist/types/tests/end-to-end-tests.spec.d.ts.map +1 -0
- package/dist/types/tests/event-log/event-log-level.spec.d.ts +2 -0
- package/dist/types/tests/event-log/event-log-level.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/events-get.spec.d.ts +2 -0
- package/dist/types/tests/handlers/events-get.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/messages-get.spec.d.ts +2 -0
- package/dist/types/tests/handlers/messages-get.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/permissions-grant.spec.d.ts +2 -0
- package/dist/types/tests/handlers/permissions-grant.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/permissions-request.spec.d.ts +2 -0
- package/dist/types/tests/handlers/permissions-request.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/permissions-revoke.spec.d.ts +2 -0
- package/dist/types/tests/handlers/permissions-revoke.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/protocols-configure.spec.d.ts +2 -0
- package/dist/types/tests/handlers/protocols-configure.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/protocols-query.spec.d.ts +2 -0
- package/dist/types/tests/handlers/protocols-query.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/records-delete.spec.d.ts +2 -0
- package/dist/types/tests/handlers/records-delete.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/records-query.spec.d.ts +2 -0
- package/dist/types/tests/handlers/records-query.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/records-read.spec.d.ts +2 -0
- package/dist/types/tests/handlers/records-read.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/records-write.spec.d.ts +2 -0
- package/dist/types/tests/handlers/records-write.spec.d.ts.map +1 -0
- package/dist/types/tests/interfaces/events-get.spec.d.ts +2 -0
- package/dist/types/tests/interfaces/events-get.spec.d.ts.map +1 -0
- package/dist/types/tests/interfaces/messages-get.spec.d.ts +2 -0
- package/dist/types/tests/interfaces/messages-get.spec.d.ts.map +1 -0
- package/dist/types/tests/interfaces/permissions-grant.spec.d.ts +2 -0
- package/dist/types/tests/interfaces/permissions-grant.spec.d.ts.map +1 -0
- package/dist/types/tests/interfaces/permissions-request.spec.d.ts +2 -0
- package/dist/types/tests/interfaces/permissions-request.spec.d.ts.map +1 -0
- package/dist/types/tests/interfaces/protocols-configure.spec.d.ts +2 -0
- package/dist/types/tests/interfaces/protocols-configure.spec.d.ts.map +1 -0
- package/dist/types/tests/interfaces/protocols-query.spec.d.ts +2 -0
- package/dist/types/tests/interfaces/protocols-query.spec.d.ts.map +1 -0
- package/dist/types/tests/interfaces/records-delete.spec.d.ts +2 -0
- package/dist/types/tests/interfaces/records-delete.spec.d.ts.map +1 -0
- package/dist/types/tests/interfaces/records-query.spec.d.ts +2 -0
- package/dist/types/tests/interfaces/records-query.spec.d.ts.map +1 -0
- package/dist/types/tests/interfaces/records-read.spec.d.ts +2 -0
- package/dist/types/tests/interfaces/records-read.spec.d.ts.map +1 -0
- package/dist/types/tests/interfaces/records-write.spec.d.ts +2 -0
- package/dist/types/tests/interfaces/records-write.spec.d.ts.map +1 -0
- package/dist/types/tests/jose/jws/general.spec.d.ts +2 -0
- package/dist/types/tests/jose/jws/general.spec.d.ts.map +1 -0
- package/dist/types/tests/scenarios/delegated-grant.spec.d.ts +2 -0
- package/dist/types/tests/scenarios/delegated-grant.spec.d.ts.map +1 -0
- package/dist/types/tests/scenarios/end-to-end-tests.spec.d.ts +2 -0
- package/dist/types/tests/scenarios/end-to-end-tests.spec.d.ts.map +1 -0
- package/dist/types/tests/store/data-store-level.spec.d.ts +2 -0
- package/dist/types/tests/store/data-store-level.spec.d.ts.map +1 -0
- package/dist/types/tests/store/index-level.spec.d.ts +2 -0
- package/dist/types/tests/store/index-level.spec.d.ts.map +1 -0
- package/dist/types/tests/store/message-store-level.spec.d.ts +2 -0
- package/dist/types/tests/store/message-store-level.spec.d.ts.map +1 -0
- package/dist/types/tests/store/message-store.spec.d.ts +2 -0
- package/dist/types/tests/store/message-store.spec.d.ts.map +1 -0
- package/dist/types/tests/store-dependent-tests.spec.d.ts +2 -0
- package/dist/types/tests/store-dependent-tests.spec.d.ts.map +1 -0
- package/dist/types/tests/test-stores.d.ts +30 -0
- package/dist/types/tests/test-stores.d.ts.map +1 -0
- package/dist/types/tests/test-suite.d.ts +16 -0
- package/dist/types/tests/test-suite.d.ts.map +1 -0
- package/dist/types/tests/utils/cid.spec.d.ts +2 -0
- package/dist/types/tests/utils/cid.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/data-stream.spec.d.ts +2 -0
- package/dist/types/tests/utils/data-stream.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/encryption.spec.d.ts +2 -0
- package/dist/types/tests/utils/encryption.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/jws.spec.d.ts +2 -0
- package/dist/types/tests/utils/jws.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/memory-cache.spec.d.ts +2 -0
- package/dist/types/tests/utils/memory-cache.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/object.spec.d.ts +2 -0
- package/dist/types/tests/utils/object.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/private-key-signer.spec.d.ts +2 -0
- package/dist/types/tests/utils/private-key-signer.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/records.spec.d.ts +2 -0
- package/dist/types/tests/utils/records.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/secp256k1.spec.d.ts +2 -0
- package/dist/types/tests/utils/secp256k1.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/test-data-generator.d.ts +323 -0
- package/dist/types/tests/utils/test-data-generator.d.ts.map +1 -0
- package/dist/types/tests/utils/test-stub-generator.d.ts +16 -0
- package/dist/types/tests/utils/test-stub-generator.d.ts.map +1 -0
- package/dist/types/tests/utils/time.spec.d.ts +2 -0
- package/dist/types/tests/utils/time.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/url.spec.d.ts +2 -0
- package/dist/types/tests/utils/url.spec.d.ts.map +1 -0
- package/dist/types/tests/validation/json-schemas/definitions.spec.d.ts +2 -0
- package/dist/types/tests/validation/json-schemas/definitions.spec.d.ts.map +1 -0
- package/dist/types/tests/validation/json-schemas/jwk/general-jwk.spec.d.ts +2 -0
- package/dist/types/tests/validation/json-schemas/jwk/general-jwk.spec.d.ts.map +1 -0
- package/dist/types/tests/validation/json-schemas/jwk/public-jwk.spec.d.ts +2 -0
- package/dist/types/tests/validation/json-schemas/jwk/public-jwk.spec.d.ts.map +1 -0
- package/dist/types/tests/validation/json-schemas/jwk-verification-method.spec.d.ts +2 -0
- package/dist/types/tests/validation/json-schemas/jwk-verification-method.spec.d.ts.map +1 -0
- package/dist/types/tests/validation/json-schemas/protocols/protocols-configure.spec.d.ts +2 -0
- package/dist/types/tests/validation/json-schemas/protocols/protocols-configure.spec.d.ts.map +1 -0
- package/dist/types/tests/validation/json-schemas/records/records-query.spec.d.ts +2 -0
- package/dist/types/tests/validation/json-schemas/records/records-query.spec.d.ts.map +1 -0
- package/dist/types/tests/validation/json-schemas/records/records-write.spec.d.ts +2 -0
- package/dist/types/tests/validation/json-schemas/records/records-write.spec.d.ts.map +1 -0
- package/package.json +156 -0
- package/src/core/abstract-message.ts +48 -0
- package/src/core/auth.ts +108 -0
- package/src/core/dwn-constant.ts +7 -0
- package/src/core/dwn-error.ts +136 -0
- package/src/core/grant-authorization.ts +163 -0
- package/src/core/message-reply.ts +42 -0
- package/src/core/message.ts +224 -0
- package/src/core/protocol-authorization.ts +691 -0
- package/src/core/records-grant-authorization.ts +167 -0
- package/src/core/tenant-gate.ts +18 -0
- package/src/did/did-dht-resolver.ts +241 -0
- package/src/did/did-ion-resolver.ts +52 -0
- package/src/did/did-key-resolver.ts +137 -0
- package/src/did/did-resolver.ts +77 -0
- package/src/did/did.ts +39 -0
- package/src/dwn.ts +213 -0
- package/src/enums/dwn-interface-method.ts +20 -0
- package/src/event-log/event-log-level.ts +116 -0
- package/src/handlers/events-get.ts +46 -0
- package/src/handlers/messages-get.ts +80 -0
- package/src/handlers/permissions-grant.ts +52 -0
- package/src/handlers/permissions-request.ts +54 -0
- package/src/handlers/permissions-revoke.ts +121 -0
- package/src/handlers/protocols-configure.ts +104 -0
- package/src/handlers/protocols-query.ts +81 -0
- package/src/handlers/records-delete.ts +139 -0
- package/src/handlers/records-query.ts +253 -0
- package/src/handlers/records-read.ts +127 -0
- package/src/handlers/records-write.ts +296 -0
- package/src/index.ts +81 -0
- package/src/interfaces/events-get.ts +43 -0
- package/src/interfaces/messages-get.ts +59 -0
- package/src/interfaces/permissions-grant.ts +175 -0
- package/src/interfaces/permissions-request.ts +55 -0
- package/src/interfaces/permissions-revoke.ts +46 -0
- package/src/interfaces/protocols-configure.ts +188 -0
- package/src/interfaces/protocols-query.ts +99 -0
- package/src/interfaces/records-delete.ts +67 -0
- package/src/interfaces/records-query.ts +100 -0
- package/src/interfaces/records-read.ts +82 -0
- package/src/interfaces/records-write.ts +924 -0
- package/src/jose/algorithms/signing/ed25519.ts +61 -0
- package/src/jose/algorithms/signing/signature-algorithms.ts +15 -0
- package/src/jose/jws/general/builder.ts +48 -0
- package/src/jose/jws/general/signer.ts +29 -0
- package/src/jose/jws/general/verifier.ts +113 -0
- package/src/schema-validator.ts +34 -0
- package/src/store/blockstore-level.ts +113 -0
- package/src/store/data-store-level.ts +188 -0
- package/src/store/index-level.ts +306 -0
- package/src/store/level-wrapper.ts +262 -0
- package/src/store/message-store-level.ts +284 -0
- package/src/store/storage-controller.ts +80 -0
- package/src/types/cache.ts +16 -0
- package/src/types/data-store.ts +78 -0
- package/src/types/delegated-grant-message.ts +15 -0
- package/src/types/did-types.ts +95 -0
- package/src/types/event-log.ts +46 -0
- package/src/types/event-types.ts +20 -0
- package/src/types/jose-types.ts +76 -0
- package/src/types/jws-types.ts +28 -0
- package/src/types/message-interface.ts +24 -0
- package/src/types/message-store.ts +56 -0
- package/src/types/message-types.ts +115 -0
- package/src/types/messages-types.ts +26 -0
- package/src/types/method-handler.ts +17 -0
- package/src/types/permissions-grant-descriptor.ts +79 -0
- package/src/types/permissions-types.ts +42 -0
- package/src/types/protocols-types.ts +154 -0
- package/src/types/records-types.ts +184 -0
- package/src/types/signer.ts +27 -0
- package/src/utils/abort.ts +31 -0
- package/src/utils/array.ts +39 -0
- package/src/utils/cid.ts +101 -0
- package/src/utils/data-stream.ts +85 -0
- package/src/utils/encoder.ts +54 -0
- package/src/utils/encryption.ts +145 -0
- package/src/utils/hd-key.ts +58 -0
- package/src/utils/jws.ts +95 -0
- package/src/utils/memory-cache.ts +31 -0
- package/src/utils/object.ts +55 -0
- package/src/utils/private-key-signer.ts +72 -0
- package/src/utils/protocols.ts +50 -0
- package/src/utils/records.ts +326 -0
- package/src/utils/secp256k1.ts +209 -0
- package/src/utils/string.ts +13 -0
- package/src/utils/time.ts +77 -0
- package/src/utils/url.ts +66 -0
|
@@ -0,0 +1,1729 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { DwnConstant, Message } from '../../src/index.js';
|
|
11
|
+
import { DwnInterfaceName, DwnMethodName } from '../../src/index.js';
|
|
12
|
+
import chaiAsPromised from 'chai-as-promised';
|
|
13
|
+
import chatProtocolDefinition from '../vectors/protocol-definitions/chat.json' with { type: 'json' };
|
|
14
|
+
import emailProtocolDefinition from '../vectors/protocol-definitions/email.json' with { type: 'json' };
|
|
15
|
+
import friendRoleProtocolDefinition from '../vectors/protocol-definitions/friend-role.json' with { type: 'json' };
|
|
16
|
+
import minimalProtocolDefinition from '../vectors/protocol-definitions/minimal.json' with { type: 'json' };
|
|
17
|
+
import nestedProtocol from '../vectors/protocol-definitions/nested.json' with { type: 'json' };
|
|
18
|
+
import sinon from 'sinon';
|
|
19
|
+
import socialMediaProtocolDefinition from '../vectors/protocol-definitions/social-media.json' with { type: 'json' };
|
|
20
|
+
import threadRoleProtocolDefinition from '../vectors/protocol-definitions/thread-role.json' with { type: 'json' };
|
|
21
|
+
import chai, { expect } from 'chai';
|
|
22
|
+
import { ArrayUtility } from '../../src/utils/array.js';
|
|
23
|
+
import { authenticate } from '../../src/core/auth.js';
|
|
24
|
+
import { DidKeyResolver } from '../../src/did/did-key-resolver.js';
|
|
25
|
+
import { DwnErrorCode } from '../../src/core/dwn-error.js';
|
|
26
|
+
import { Encryption } from '../../src/utils/encryption.js';
|
|
27
|
+
import { HdKey } from '../../src/utils/hd-key.js';
|
|
28
|
+
import { KeyDerivationScheme } from '../../src/utils/hd-key.js';
|
|
29
|
+
import { RecordsReadHandler } from '../../src/handlers/records-read.js';
|
|
30
|
+
import { stubInterface } from 'ts-sinon';
|
|
31
|
+
import { TestDataGenerator } from '../utils/test-data-generator.js';
|
|
32
|
+
import { TestStores } from '../test-stores.js';
|
|
33
|
+
import { TestStubGenerator } from '../utils/test-stub-generator.js';
|
|
34
|
+
import { DataStream, DidResolver, Dwn, Jws, Protocols, ProtocolsConfigure, ProtocolsQuery, Records, RecordsDelete, RecordsRead, RecordsWrite, Secp256k1 } from '../../src/index.js';
|
|
35
|
+
chai.use(chaiAsPromised);
|
|
36
|
+
export function testRecordsReadHandler() {
|
|
37
|
+
describe('RecordsReadHandler.handle()', () => {
|
|
38
|
+
if (process.env.TESTSOFF === 'true') {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
let didResolver;
|
|
42
|
+
let messageStore;
|
|
43
|
+
let dataStore;
|
|
44
|
+
let eventLog;
|
|
45
|
+
let dwn;
|
|
46
|
+
describe('functional tests', () => {
|
|
47
|
+
// important to follow the `before` and `after` pattern to initialize and clean the stores in tests
|
|
48
|
+
// so that different test suites can reuse the same backend store for testing
|
|
49
|
+
before(() => __awaiter(this, void 0, void 0, function* () {
|
|
50
|
+
didResolver = new DidResolver([new DidKeyResolver()]);
|
|
51
|
+
const stores = TestStores.get();
|
|
52
|
+
messageStore = stores.messageStore;
|
|
53
|
+
dataStore = stores.dataStore;
|
|
54
|
+
eventLog = stores.eventLog;
|
|
55
|
+
dwn = yield Dwn.create({ didResolver, messageStore, dataStore, eventLog });
|
|
56
|
+
}));
|
|
57
|
+
beforeEach(() => __awaiter(this, void 0, void 0, function* () {
|
|
58
|
+
sinon.restore(); // wipe all previous stubs/spies/mocks/fakes
|
|
59
|
+
// clean up before each test rather than after so that a test does not depend on other tests to do the clean up
|
|
60
|
+
yield messageStore.clear();
|
|
61
|
+
yield dataStore.clear();
|
|
62
|
+
yield eventLog.clear();
|
|
63
|
+
}));
|
|
64
|
+
after(() => __awaiter(this, void 0, void 0, function* () {
|
|
65
|
+
yield dwn.close();
|
|
66
|
+
}));
|
|
67
|
+
it('should allow tenant to RecordsRead their own record', () => __awaiter(this, void 0, void 0, function* () {
|
|
68
|
+
var _a, _b;
|
|
69
|
+
const alice = yield DidKeyResolver.generate();
|
|
70
|
+
// insert data
|
|
71
|
+
const { message, dataStream, dataBytes } = yield TestDataGenerator.generateRecordsWrite({ author: alice });
|
|
72
|
+
const writeReply = yield dwn.processMessage(alice.did, message, dataStream);
|
|
73
|
+
expect(writeReply.status.code).to.equal(202);
|
|
74
|
+
// testing RecordsRead
|
|
75
|
+
const recordsRead = yield RecordsRead.create({
|
|
76
|
+
filter: {
|
|
77
|
+
recordId: message.recordId,
|
|
78
|
+
},
|
|
79
|
+
signer: Jws.createSigner(alice)
|
|
80
|
+
});
|
|
81
|
+
const readReply = yield dwn.processMessage(alice.did, recordsRead.message);
|
|
82
|
+
expect(readReply.status.code).to.equal(200);
|
|
83
|
+
expect(readReply.record).to.exist;
|
|
84
|
+
expect((_a = readReply.record) === null || _a === void 0 ? void 0 : _a.authorization).to.deep.equal(message.authorization);
|
|
85
|
+
expect((_b = readReply.record) === null || _b === void 0 ? void 0 : _b.descriptor).to.deep.equal(message.descriptor);
|
|
86
|
+
const dataFetched = yield DataStream.toBytes(readReply.record.data);
|
|
87
|
+
expect(ArrayUtility.byteArraysEqual(dataFetched, dataBytes)).to.be.true;
|
|
88
|
+
}));
|
|
89
|
+
it('should not allow non-tenant to RecordsRead their a record data', () => __awaiter(this, void 0, void 0, function* () {
|
|
90
|
+
const alice = yield DidKeyResolver.generate();
|
|
91
|
+
// insert data
|
|
92
|
+
const { message, dataStream } = yield TestDataGenerator.generateRecordsWrite({ author: alice });
|
|
93
|
+
const writeReply = yield dwn.processMessage(alice.did, message, dataStream);
|
|
94
|
+
expect(writeReply.status.code).to.equal(202);
|
|
95
|
+
// testing RecordsRead
|
|
96
|
+
const bob = yield DidKeyResolver.generate();
|
|
97
|
+
const recordsRead = yield RecordsRead.create({
|
|
98
|
+
filter: {
|
|
99
|
+
recordId: message.recordId,
|
|
100
|
+
},
|
|
101
|
+
signer: Jws.createSigner(bob)
|
|
102
|
+
});
|
|
103
|
+
const readReply = yield dwn.processMessage(alice.did, recordsRead.message);
|
|
104
|
+
expect(readReply.status.code).to.equal(401);
|
|
105
|
+
}));
|
|
106
|
+
it('should allow reading of data that is published without `authorization`', () => __awaiter(this, void 0, void 0, function* () {
|
|
107
|
+
const alice = yield DidKeyResolver.generate();
|
|
108
|
+
// insert public data
|
|
109
|
+
const { message, dataStream, dataBytes } = yield TestDataGenerator.generateRecordsWrite({ author: alice, published: true });
|
|
110
|
+
const writeReply = yield dwn.processMessage(alice.did, message, dataStream);
|
|
111
|
+
expect(writeReply.status.code).to.equal(202);
|
|
112
|
+
// testing public RecordsRead
|
|
113
|
+
const recordsRead = yield RecordsRead.create({
|
|
114
|
+
filter: {
|
|
115
|
+
recordId: message.recordId
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
expect(recordsRead.author).to.be.undefined; // making sure no author/authorization is created
|
|
119
|
+
const readReply = yield dwn.processMessage(alice.did, recordsRead.message);
|
|
120
|
+
expect(readReply.status.code).to.equal(200);
|
|
121
|
+
const dataFetched = yield DataStream.toBytes(readReply.record.data);
|
|
122
|
+
expect(ArrayUtility.byteArraysEqual(dataFetched, dataBytes)).to.be.true;
|
|
123
|
+
}));
|
|
124
|
+
it('should allow an authenticated user to RecordRead data that is published', () => __awaiter(this, void 0, void 0, function* () {
|
|
125
|
+
const alice = yield DidKeyResolver.generate();
|
|
126
|
+
// insert public data
|
|
127
|
+
const { message, dataStream, dataBytes } = yield TestDataGenerator.generateRecordsWrite({ author: alice, published: true });
|
|
128
|
+
const writeReply = yield dwn.processMessage(alice.did, message, dataStream);
|
|
129
|
+
expect(writeReply.status.code).to.equal(202);
|
|
130
|
+
// testing public RecordsRead
|
|
131
|
+
const bob = yield DidKeyResolver.generate();
|
|
132
|
+
const recordsRead = yield RecordsRead.create({
|
|
133
|
+
filter: {
|
|
134
|
+
recordId: message.recordId,
|
|
135
|
+
},
|
|
136
|
+
signer: Jws.createSigner(bob)
|
|
137
|
+
});
|
|
138
|
+
const readReply = yield dwn.processMessage(alice.did, recordsRead.message);
|
|
139
|
+
expect(readReply.status.code).to.equal(200);
|
|
140
|
+
const dataFetched = yield DataStream.toBytes(readReply.record.data);
|
|
141
|
+
expect(ArrayUtility.byteArraysEqual(dataFetched, dataBytes)).to.be.true;
|
|
142
|
+
}));
|
|
143
|
+
it('should allow a non-tenant to read RecordsRead data they have received', () => __awaiter(this, void 0, void 0, function* () {
|
|
144
|
+
var _a;
|
|
145
|
+
const alice = yield DidKeyResolver.generate();
|
|
146
|
+
const bob = yield DidKeyResolver.generate();
|
|
147
|
+
// Alice inserts data with Bob as recipient
|
|
148
|
+
const { message, dataStream, dataBytes } = yield TestDataGenerator.generateRecordsWrite({
|
|
149
|
+
author: alice,
|
|
150
|
+
recipient: bob.did,
|
|
151
|
+
});
|
|
152
|
+
const writeReply = yield dwn.processMessage(alice.did, message, dataStream);
|
|
153
|
+
expect(writeReply.status.code).to.equal(202);
|
|
154
|
+
// Bob reads the data that Alice sent him
|
|
155
|
+
const recordsRead = yield RecordsRead.create({
|
|
156
|
+
filter: {
|
|
157
|
+
recordId: message.recordId,
|
|
158
|
+
},
|
|
159
|
+
signer: Jws.createSigner(bob)
|
|
160
|
+
});
|
|
161
|
+
const readReply = yield dwn.processMessage(alice.did, recordsRead.message);
|
|
162
|
+
expect(readReply.status.code).to.equal(200);
|
|
163
|
+
expect(readReply.record).to.exist;
|
|
164
|
+
expect((_a = readReply.record) === null || _a === void 0 ? void 0 : _a.descriptor).to.exist;
|
|
165
|
+
const dataFetched = yield DataStream.toBytes(readReply.record.data);
|
|
166
|
+
expect(ArrayUtility.byteArraysEqual(dataFetched, dataBytes)).to.be.true;
|
|
167
|
+
}));
|
|
168
|
+
describe('protocol based reads', () => {
|
|
169
|
+
it('should allow read with allow-anyone rule', () => __awaiter(this, void 0, void 0, function* () {
|
|
170
|
+
// scenario: Alice writes an image to her DWN, then Bob reads the image because he is "anyone".
|
|
171
|
+
const alice = yield DidKeyResolver.generate();
|
|
172
|
+
const bob = yield DidKeyResolver.generate();
|
|
173
|
+
const protocolDefinition = socialMediaProtocolDefinition;
|
|
174
|
+
// Install social-media protocol on Alice's DWN
|
|
175
|
+
const protocolsConfig = yield TestDataGenerator.generateProtocolsConfigure({
|
|
176
|
+
author: alice,
|
|
177
|
+
protocolDefinition
|
|
178
|
+
});
|
|
179
|
+
const protocolsConfigureReply = yield dwn.processMessage(alice.did, protocolsConfig.message);
|
|
180
|
+
expect(protocolsConfigureReply.status.code).to.equal(202);
|
|
181
|
+
// Alice writes image to her DWN
|
|
182
|
+
const encodedImage = new TextEncoder().encode('cafe-aesthetic.jpg');
|
|
183
|
+
const imageRecordsWrite = yield TestDataGenerator.generateRecordsWrite({
|
|
184
|
+
author: alice,
|
|
185
|
+
protocol: protocolDefinition.protocol,
|
|
186
|
+
protocolPath: 'image', // this comes from `types` in protocol definition
|
|
187
|
+
schema: protocolDefinition.types.image.schema,
|
|
188
|
+
dataFormat: 'image/jpeg',
|
|
189
|
+
data: encodedImage,
|
|
190
|
+
recipient: alice.did
|
|
191
|
+
});
|
|
192
|
+
const imageReply = yield dwn.processMessage(alice.did, imageRecordsWrite.message, imageRecordsWrite.dataStream);
|
|
193
|
+
expect(imageReply.status.code).to.equal(202);
|
|
194
|
+
// Bob (anyone) reads the image that Alice wrote
|
|
195
|
+
const imageRecordsRead = yield RecordsRead.create({
|
|
196
|
+
filter: {
|
|
197
|
+
recordId: imageRecordsWrite.message.recordId,
|
|
198
|
+
},
|
|
199
|
+
signer: Jws.createSigner(bob)
|
|
200
|
+
});
|
|
201
|
+
const imageReadReply = yield dwn.processMessage(alice.did, imageRecordsRead.message);
|
|
202
|
+
expect(imageReadReply.status.code).to.equal(200);
|
|
203
|
+
}));
|
|
204
|
+
it('should not allow anonymous reads when there is no allow-anyone rule', () => __awaiter(this, void 0, void 0, function* () {
|
|
205
|
+
// scenario: Alice's writes a record to a protocol. An anonymous read his Alice's DWN and is rejected
|
|
206
|
+
// because there is not an allow-anyone rule.
|
|
207
|
+
const alice = yield TestDataGenerator.generatePersona();
|
|
208
|
+
const protocolDefinition = emailProtocolDefinition;
|
|
209
|
+
TestStubGenerator.stubDidResolver(didResolver, [alice]);
|
|
210
|
+
const protocolsConfig = yield TestDataGenerator.generateProtocolsConfigure({
|
|
211
|
+
author: alice,
|
|
212
|
+
protocolDefinition
|
|
213
|
+
});
|
|
214
|
+
const protocolsConfigureReply = yield dwn.processMessage(alice.did, protocolsConfig.message);
|
|
215
|
+
expect(protocolsConfigureReply.status.code).to.equal(202);
|
|
216
|
+
// Alice writes a message to the minimal protocol
|
|
217
|
+
const recordsWrite = yield TestDataGenerator.generateRecordsWrite({
|
|
218
|
+
author: alice,
|
|
219
|
+
protocol: protocolDefinition.protocol,
|
|
220
|
+
protocolPath: 'email',
|
|
221
|
+
schema: protocolDefinition.types.email.schema,
|
|
222
|
+
dataFormat: protocolDefinition.types.email.dataFormats[0],
|
|
223
|
+
data: new TextEncoder().encode('foo')
|
|
224
|
+
});
|
|
225
|
+
const recordsWriteReply = yield dwn.processMessage(alice.did, recordsWrite.message, recordsWrite.dataStream);
|
|
226
|
+
expect(recordsWriteReply.status.code).to.equal(202);
|
|
227
|
+
// Anonymous tries and fails to read Alice's message
|
|
228
|
+
const recordsRead = yield RecordsRead.create({
|
|
229
|
+
filter: {
|
|
230
|
+
recordId: recordsWrite.message.recordId,
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
const recordsReadReply = yield dwn.processMessage(alice.did, recordsRead.message);
|
|
234
|
+
expect(recordsReadReply.status.code).to.equal(401);
|
|
235
|
+
expect(recordsReadReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationActionNotAllowed);
|
|
236
|
+
}));
|
|
237
|
+
describe('recipient rules', () => {
|
|
238
|
+
it('should allow read with ancestor recipient rule', () => __awaiter(this, void 0, void 0, function* () {
|
|
239
|
+
// scenario: Alice sends an email to Bob, then Bob reads the email.
|
|
240
|
+
// ImposterBob tries and fails to read the email.
|
|
241
|
+
const alice = yield DidKeyResolver.generate();
|
|
242
|
+
const bob = yield DidKeyResolver.generate();
|
|
243
|
+
const imposterBob = yield DidKeyResolver.generate();
|
|
244
|
+
const protocolDefinition = emailProtocolDefinition;
|
|
245
|
+
// Install email protocol on Alice's DWN
|
|
246
|
+
const protocolsConfig = yield TestDataGenerator.generateProtocolsConfigure({
|
|
247
|
+
author: alice,
|
|
248
|
+
protocolDefinition,
|
|
249
|
+
});
|
|
250
|
+
const protocolsConfigureReply = yield dwn.processMessage(alice.did, protocolsConfig.message);
|
|
251
|
+
expect(protocolsConfigureReply.status.code).to.equal(202);
|
|
252
|
+
// Alice writes an email with Bob as recipient
|
|
253
|
+
const encodedEmail = new TextEncoder().encode('Dear Bob, hello!');
|
|
254
|
+
const emailRecordsWrite = yield TestDataGenerator.generateRecordsWrite({
|
|
255
|
+
author: alice,
|
|
256
|
+
protocol: protocolDefinition.protocol,
|
|
257
|
+
protocolPath: 'email', // this comes from `types` in protocol definition
|
|
258
|
+
schema: protocolDefinition.types.email.schema,
|
|
259
|
+
dataFormat: protocolDefinition.types.email.dataFormats[0],
|
|
260
|
+
data: encodedEmail,
|
|
261
|
+
recipient: bob.did
|
|
262
|
+
});
|
|
263
|
+
const imageReply = yield dwn.processMessage(alice.did, emailRecordsWrite.message, emailRecordsWrite.dataStream);
|
|
264
|
+
expect(imageReply.status.code).to.equal(202);
|
|
265
|
+
// Bob reads Alice's email
|
|
266
|
+
const bobRecordsRead = yield RecordsRead.create({
|
|
267
|
+
filter: {
|
|
268
|
+
recordId: emailRecordsWrite.message.recordId,
|
|
269
|
+
},
|
|
270
|
+
signer: Jws.createSigner(bob)
|
|
271
|
+
});
|
|
272
|
+
const bobReadReply = yield dwn.processMessage(alice.did, bobRecordsRead.message);
|
|
273
|
+
expect(bobReadReply.status.code).to.equal(200);
|
|
274
|
+
// ImposterBob is not able to read Alice's email
|
|
275
|
+
const imposterRecordsRead = yield RecordsRead.create({
|
|
276
|
+
filter: {
|
|
277
|
+
recordId: emailRecordsWrite.message.recordId,
|
|
278
|
+
},
|
|
279
|
+
signer: Jws.createSigner(imposterBob)
|
|
280
|
+
});
|
|
281
|
+
const imposterReadReply = yield dwn.processMessage(alice.did, imposterRecordsRead.message);
|
|
282
|
+
expect(imposterReadReply.status.code).to.equal(401);
|
|
283
|
+
expect(imposterReadReply.status.detail).to.include(DwnErrorCode.ProtocolAuthorizationActionNotAllowed);
|
|
284
|
+
}));
|
|
285
|
+
});
|
|
286
|
+
describe('author action rules', () => {
|
|
287
|
+
it('should allow read with ancestor author rule', () => __awaiter(this, void 0, void 0, function* () {
|
|
288
|
+
// scenario: Bob sends an email to Alice, then Bob reads the email.
|
|
289
|
+
// ImposterBob tries and fails to read the email.
|
|
290
|
+
const alice = yield DidKeyResolver.generate();
|
|
291
|
+
const bob = yield DidKeyResolver.generate();
|
|
292
|
+
const imposterBob = yield DidKeyResolver.generate();
|
|
293
|
+
const protocolDefinition = emailProtocolDefinition;
|
|
294
|
+
// Install email protocol on Alice's DWN
|
|
295
|
+
const protocolsConfig = yield TestDataGenerator.generateProtocolsConfigure({
|
|
296
|
+
author: alice,
|
|
297
|
+
protocolDefinition
|
|
298
|
+
});
|
|
299
|
+
const protocolsConfigureReply = yield dwn.processMessage(alice.did, protocolsConfig.message);
|
|
300
|
+
expect(protocolsConfigureReply.status.code).to.equal(202);
|
|
301
|
+
// Alice writes an email with Bob as recipient
|
|
302
|
+
const encodedEmail = new TextEncoder().encode('Dear Alice, hello!');
|
|
303
|
+
const emailRecordsWrite = yield TestDataGenerator.generateRecordsWrite({
|
|
304
|
+
author: bob,
|
|
305
|
+
protocol: protocolDefinition.protocol,
|
|
306
|
+
protocolPath: 'email', // this comes from `types` in protocol definition
|
|
307
|
+
schema: protocolDefinition.types.email.schema,
|
|
308
|
+
dataFormat: protocolDefinition.types.email.dataFormats[0],
|
|
309
|
+
data: encodedEmail,
|
|
310
|
+
recipient: alice.did
|
|
311
|
+
});
|
|
312
|
+
const imageReply = yield dwn.processMessage(alice.did, emailRecordsWrite.message, emailRecordsWrite.dataStream);
|
|
313
|
+
expect(imageReply.status.code).to.equal(202);
|
|
314
|
+
// Bob reads the email he just sent
|
|
315
|
+
const bobRecordsRead = yield RecordsRead.create({
|
|
316
|
+
filter: {
|
|
317
|
+
recordId: emailRecordsWrite.message.recordId,
|
|
318
|
+
},
|
|
319
|
+
signer: Jws.createSigner(bob)
|
|
320
|
+
});
|
|
321
|
+
const bobReadReply = yield dwn.processMessage(alice.did, bobRecordsRead.message);
|
|
322
|
+
expect(bobReadReply.status.code).to.equal(200);
|
|
323
|
+
// ImposterBob is not able to read the email
|
|
324
|
+
const imposterRecordsRead = yield RecordsRead.create({
|
|
325
|
+
filter: {
|
|
326
|
+
recordId: emailRecordsWrite.message.recordId,
|
|
327
|
+
},
|
|
328
|
+
signer: Jws.createSigner(imposterBob)
|
|
329
|
+
});
|
|
330
|
+
const imposterReadReply = yield dwn.processMessage(alice.did, imposterRecordsRead.message);
|
|
331
|
+
expect(imposterReadReply.status.code).to.equal(401);
|
|
332
|
+
expect(imposterReadReply.status.detail).to.include(DwnErrorCode.ProtocolAuthorizationActionNotAllowed);
|
|
333
|
+
}));
|
|
334
|
+
});
|
|
335
|
+
describe('filter based reads', () => {
|
|
336
|
+
it('should return a filter based read if there is only a single result', () => __awaiter(this, void 0, void 0, function* () {
|
|
337
|
+
const alice = yield DidKeyResolver.generate();
|
|
338
|
+
const protocolDefinition = Object.assign({}, nestedProtocol);
|
|
339
|
+
const protocolsConfig = yield TestDataGenerator.generateProtocolsConfigure({
|
|
340
|
+
author: alice,
|
|
341
|
+
protocolDefinition
|
|
342
|
+
});
|
|
343
|
+
const protocolConfigReply = yield dwn.processMessage(alice.did, protocolsConfig.message);
|
|
344
|
+
expect(protocolConfigReply.status.code).to.equal(202);
|
|
345
|
+
const foo1Write = yield TestDataGenerator.generateRecordsWrite({
|
|
346
|
+
author: alice,
|
|
347
|
+
protocol: protocolDefinition.protocol,
|
|
348
|
+
protocolPath: 'foo',
|
|
349
|
+
schema: protocolDefinition.types.foo.schema,
|
|
350
|
+
dataFormat: protocolDefinition.types.foo.dataFormats[0],
|
|
351
|
+
data: new TextEncoder().encode('foo'),
|
|
352
|
+
recipient: alice.did
|
|
353
|
+
});
|
|
354
|
+
const foo1WriteReply = yield dwn.processMessage(alice.did, foo1Write.message, foo1Write.dataStream);
|
|
355
|
+
expect(foo1WriteReply.status.code).to.equal(202);
|
|
356
|
+
const fooPathRead = yield RecordsRead.create({
|
|
357
|
+
filter: {
|
|
358
|
+
protocol: protocolDefinition.protocol,
|
|
359
|
+
protocolPath: 'foo',
|
|
360
|
+
},
|
|
361
|
+
signer: Jws.createSigner(alice),
|
|
362
|
+
});
|
|
363
|
+
const fooPathReply = yield dwn.processMessage(alice.did, fooPathRead.message);
|
|
364
|
+
expect(fooPathReply.status.code).to.equal(200);
|
|
365
|
+
expect(fooPathReply.record.recordId).to.equal(foo1Write.message.recordId);
|
|
366
|
+
}));
|
|
367
|
+
it('should throw if requested filter has more than a single result', () => __awaiter(this, void 0, void 0, function* () {
|
|
368
|
+
const alice = yield DidKeyResolver.generate();
|
|
369
|
+
const protocolDefinition = Object.assign({}, nestedProtocol);
|
|
370
|
+
const protocolsConfig = yield TestDataGenerator.generateProtocolsConfigure({
|
|
371
|
+
author: alice,
|
|
372
|
+
protocolDefinition
|
|
373
|
+
});
|
|
374
|
+
const protocolConfigReply = yield dwn.processMessage(alice.did, protocolsConfig.message);
|
|
375
|
+
expect(protocolConfigReply.status.code).to.equal(202);
|
|
376
|
+
const foo1Write = yield TestDataGenerator.generateRecordsWrite({
|
|
377
|
+
author: alice,
|
|
378
|
+
protocol: protocolDefinition.protocol,
|
|
379
|
+
protocolPath: 'foo',
|
|
380
|
+
schema: protocolDefinition.types.foo.schema,
|
|
381
|
+
dataFormat: protocolDefinition.types.foo.dataFormats[0],
|
|
382
|
+
data: new TextEncoder().encode('foo'),
|
|
383
|
+
recipient: alice.did
|
|
384
|
+
});
|
|
385
|
+
const foo1WriteReply = yield dwn.processMessage(alice.did, foo1Write.message, foo1Write.dataStream);
|
|
386
|
+
expect(foo1WriteReply.status.code).to.equal(202);
|
|
387
|
+
const foo2Write = yield TestDataGenerator.generateRecordsWrite({
|
|
388
|
+
author: alice,
|
|
389
|
+
protocol: protocolDefinition.protocol,
|
|
390
|
+
protocolPath: 'foo',
|
|
391
|
+
schema: protocolDefinition.types.foo.schema,
|
|
392
|
+
dataFormat: protocolDefinition.types.foo.dataFormats[0],
|
|
393
|
+
data: new TextEncoder().encode('foo'),
|
|
394
|
+
recipient: alice.did
|
|
395
|
+
});
|
|
396
|
+
const foo2WriteReply = yield dwn.processMessage(alice.did, foo2Write.message, foo2Write.dataStream);
|
|
397
|
+
expect(foo2WriteReply.status.code).to.equal(202);
|
|
398
|
+
// Since there are two 'foo' records, this should fail.
|
|
399
|
+
const fooPathRead = yield RecordsRead.create({
|
|
400
|
+
filter: {
|
|
401
|
+
protocol: protocolDefinition.protocol,
|
|
402
|
+
protocolPath: 'foo',
|
|
403
|
+
},
|
|
404
|
+
signer: Jws.createSigner(alice),
|
|
405
|
+
});
|
|
406
|
+
const fooPathReply = yield dwn.processMessage(alice.did, fooPathRead.message);
|
|
407
|
+
expect(fooPathReply.status.code).to.equal(400);
|
|
408
|
+
expect(fooPathReply.status.detail).to.contain(DwnErrorCode.RecordsReadReturnedMultiple);
|
|
409
|
+
}));
|
|
410
|
+
});
|
|
411
|
+
describe('protocolRole based reads', () => {
|
|
412
|
+
it('uses a globalRole to authorize a read', () => __awaiter(this, void 0, void 0, function* () {
|
|
413
|
+
// scenario: Alice writes a chat message writes a chat message. Bob invokes his
|
|
414
|
+
// friend role in order to read the chat message.
|
|
415
|
+
const alice = yield DidKeyResolver.generate();
|
|
416
|
+
const bob = yield DidKeyResolver.generate();
|
|
417
|
+
const protocolDefinition = friendRoleProtocolDefinition;
|
|
418
|
+
const protocolsConfig = yield TestDataGenerator.generateProtocolsConfigure({
|
|
419
|
+
author: alice,
|
|
420
|
+
protocolDefinition
|
|
421
|
+
});
|
|
422
|
+
const protocolsConfigureReply = yield dwn.processMessage(alice.did, protocolsConfig.message);
|
|
423
|
+
expect(protocolsConfigureReply.status.code).to.equal(202);
|
|
424
|
+
// Alice writes a 'friend' $globalRole record with Bob as recipient
|
|
425
|
+
const friendRoleRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
426
|
+
author: alice,
|
|
427
|
+
recipient: bob.did,
|
|
428
|
+
protocol: protocolDefinition.protocol,
|
|
429
|
+
protocolPath: 'friend',
|
|
430
|
+
data: new TextEncoder().encode('Bob is my friend'),
|
|
431
|
+
});
|
|
432
|
+
const friendRoleReply = yield dwn.processMessage(alice.did, friendRoleRecord.message, friendRoleRecord.dataStream);
|
|
433
|
+
expect(friendRoleReply.status.code).to.equal(202);
|
|
434
|
+
// Alice writes a 'chat' record
|
|
435
|
+
const chatRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
436
|
+
author: alice,
|
|
437
|
+
recipient: alice.did,
|
|
438
|
+
protocol: protocolDefinition.protocol,
|
|
439
|
+
protocolPath: 'chat',
|
|
440
|
+
data: new TextEncoder().encode('Bob can read this cuz he is my friend'),
|
|
441
|
+
});
|
|
442
|
+
const chatReply = yield dwn.processMessage(alice.did, chatRecord.message, chatRecord.dataStream);
|
|
443
|
+
expect(chatReply.status.code).to.equal(202);
|
|
444
|
+
// Bob reads Alice's chat record
|
|
445
|
+
const readChatRecord = yield RecordsRead.create({
|
|
446
|
+
signer: Jws.createSigner(bob),
|
|
447
|
+
filter: {
|
|
448
|
+
recordId: chatRecord.message.recordId,
|
|
449
|
+
},
|
|
450
|
+
protocolRole: 'friend'
|
|
451
|
+
});
|
|
452
|
+
const chatReadReply = yield dwn.processMessage(alice.did, readChatRecord.message);
|
|
453
|
+
expect(chatReadReply.status.code).to.equal(200);
|
|
454
|
+
}));
|
|
455
|
+
it('rejects globalRole-authorized reads if the protocolRole is not a valid protocol path to a role record', () => __awaiter(this, void 0, void 0, function* () {
|
|
456
|
+
// scenario: Alice writes a chat message writes a chat message. Bob tries to invoke the 'chat' role,
|
|
457
|
+
// but 'chat' is not a role.
|
|
458
|
+
const alice = yield DidKeyResolver.generate();
|
|
459
|
+
const bob = yield DidKeyResolver.generate();
|
|
460
|
+
const protocolDefinition = friendRoleProtocolDefinition;
|
|
461
|
+
const protocolsConfig = yield TestDataGenerator.generateProtocolsConfigure({
|
|
462
|
+
author: alice,
|
|
463
|
+
protocolDefinition
|
|
464
|
+
});
|
|
465
|
+
const protocolsConfigureReply = yield dwn.processMessage(alice.did, protocolsConfig.message);
|
|
466
|
+
expect(protocolsConfigureReply.status.code).to.equal(202);
|
|
467
|
+
// Alice writes a 'chat' record
|
|
468
|
+
const chatRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
469
|
+
author: alice,
|
|
470
|
+
recipient: alice.did,
|
|
471
|
+
protocol: protocolDefinition.protocol,
|
|
472
|
+
protocolPath: 'chat',
|
|
473
|
+
data: new TextEncoder().encode('Blah blah blah'),
|
|
474
|
+
});
|
|
475
|
+
const chatReply = yield dwn.processMessage(alice.did, chatRecord.message, chatRecord.dataStream);
|
|
476
|
+
expect(chatReply.status.code).to.equal(202);
|
|
477
|
+
// Bob tries to invoke a 'chat' role but 'chat' is not a role
|
|
478
|
+
const readChatRecord = yield RecordsRead.create({
|
|
479
|
+
signer: Jws.createSigner(bob),
|
|
480
|
+
filter: {
|
|
481
|
+
recordId: chatRecord.message.recordId,
|
|
482
|
+
},
|
|
483
|
+
protocolRole: 'chat'
|
|
484
|
+
});
|
|
485
|
+
const chatReadReply = yield dwn.processMessage(alice.did, readChatRecord.message);
|
|
486
|
+
expect(chatReadReply.status.code).to.equal(401);
|
|
487
|
+
expect(chatReadReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationNotARole);
|
|
488
|
+
}));
|
|
489
|
+
it('rejects globalRole-authorized reads if there is no active role for the recipient', () => __awaiter(this, void 0, void 0, function* () {
|
|
490
|
+
// scenario: Alice writes a chat message writes a chat message. Bob tries to invoke a role,
|
|
491
|
+
// but he has not been given one.
|
|
492
|
+
const alice = yield DidKeyResolver.generate();
|
|
493
|
+
const bob = yield DidKeyResolver.generate();
|
|
494
|
+
const protocolDefinition = friendRoleProtocolDefinition;
|
|
495
|
+
const protocolsConfig = yield TestDataGenerator.generateProtocolsConfigure({
|
|
496
|
+
author: alice,
|
|
497
|
+
protocolDefinition
|
|
498
|
+
});
|
|
499
|
+
const protocolsConfigureReply = yield dwn.processMessage(alice.did, protocolsConfig.message);
|
|
500
|
+
expect(protocolsConfigureReply.status.code).to.equal(202);
|
|
501
|
+
// Alice writes a 'chat' record
|
|
502
|
+
const chatRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
503
|
+
author: alice,
|
|
504
|
+
recipient: alice.did,
|
|
505
|
+
protocol: protocolDefinition.protocol,
|
|
506
|
+
protocolPath: 'chat',
|
|
507
|
+
data: new TextEncoder().encode('Blah blah blah'),
|
|
508
|
+
});
|
|
509
|
+
const chatReply = yield dwn.processMessage(alice.did, chatRecord.message, chatRecord.dataStream);
|
|
510
|
+
expect(chatReply.status.code).to.equal(202);
|
|
511
|
+
// Bob tries to invoke a 'friend' role but he is not a 'friend'
|
|
512
|
+
const readChatRecord = yield RecordsRead.create({
|
|
513
|
+
signer: Jws.createSigner(bob),
|
|
514
|
+
filter: {
|
|
515
|
+
recordId: chatRecord.message.recordId,
|
|
516
|
+
},
|
|
517
|
+
protocolRole: 'friend',
|
|
518
|
+
});
|
|
519
|
+
const chatReadReply = yield dwn.processMessage(alice.did, readChatRecord.message);
|
|
520
|
+
expect(chatReadReply.status.code).to.equal(401);
|
|
521
|
+
expect(chatReadReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationMissingRole);
|
|
522
|
+
}));
|
|
523
|
+
it('uses a contextRole to authorize a read', () => __awaiter(this, void 0, void 0, function* () {
|
|
524
|
+
// scenario: Alice creates a thread and adds Bob to the 'thread/participant' role. Alice writes a chat message.
|
|
525
|
+
// Bob invokes the record to read in the chat message.
|
|
526
|
+
const alice = yield DidKeyResolver.generate();
|
|
527
|
+
const bob = yield DidKeyResolver.generate();
|
|
528
|
+
const protocolDefinition = threadRoleProtocolDefinition;
|
|
529
|
+
const protocolsConfig = yield TestDataGenerator.generateProtocolsConfigure({
|
|
530
|
+
author: alice,
|
|
531
|
+
protocolDefinition
|
|
532
|
+
});
|
|
533
|
+
const protocolsConfigureReply = yield dwn.processMessage(alice.did, protocolsConfig.message);
|
|
534
|
+
expect(protocolsConfigureReply.status.code).to.equal(202);
|
|
535
|
+
// Alice creates a thread
|
|
536
|
+
const threadRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
537
|
+
author: alice,
|
|
538
|
+
recipient: bob.did,
|
|
539
|
+
protocol: protocolDefinition.protocol,
|
|
540
|
+
protocolPath: 'thread'
|
|
541
|
+
});
|
|
542
|
+
const threadRecordReply = yield dwn.processMessage(alice.did, threadRecord.message, threadRecord.dataStream);
|
|
543
|
+
expect(threadRecordReply.status.code).to.equal(202);
|
|
544
|
+
// Alice adds Bob as a 'thread/participant' in that thread
|
|
545
|
+
const participantRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
546
|
+
author: alice,
|
|
547
|
+
recipient: bob.did,
|
|
548
|
+
protocol: protocolDefinition.protocol,
|
|
549
|
+
protocolPath: 'thread/participant',
|
|
550
|
+
contextId: threadRecord.message.contextId,
|
|
551
|
+
parentId: threadRecord.message.recordId,
|
|
552
|
+
});
|
|
553
|
+
const participantRecordReply = yield dwn.processMessage(alice.did, participantRecord.message, participantRecord.dataStream);
|
|
554
|
+
expect(participantRecordReply.status.code).to.equal(202);
|
|
555
|
+
// Alice writes a chat message in the thread
|
|
556
|
+
const chatRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
557
|
+
author: alice,
|
|
558
|
+
protocol: protocolDefinition.protocol,
|
|
559
|
+
protocolPath: 'thread/chat',
|
|
560
|
+
contextId: threadRecord.message.contextId,
|
|
561
|
+
parentId: threadRecord.message.recordId,
|
|
562
|
+
});
|
|
563
|
+
const chatRecordReply = yield dwn.processMessage(alice.did, chatRecord.message, chatRecord.dataStream);
|
|
564
|
+
expect(chatRecordReply.status.code).to.equal(202);
|
|
565
|
+
// Bob is able to read his own 'participant' role
|
|
566
|
+
// He doesn't need to invoke the role because recipients of a record are always authorized to read it
|
|
567
|
+
const participantRead = yield RecordsRead.create({
|
|
568
|
+
signer: Jws.createSigner(bob),
|
|
569
|
+
filter: {
|
|
570
|
+
protocolPath: 'thread/participant',
|
|
571
|
+
recipient: bob.did,
|
|
572
|
+
contextId: threadRecord.message.contextId
|
|
573
|
+
},
|
|
574
|
+
});
|
|
575
|
+
const participantReadReply = yield dwn.processMessage(alice.did, participantRead.message);
|
|
576
|
+
expect(participantReadReply.status.code).to.equal(200);
|
|
577
|
+
// Bob is able to read the thread root record
|
|
578
|
+
const threadRead = yield RecordsRead.create({
|
|
579
|
+
signer: Jws.createSigner(bob),
|
|
580
|
+
filter: {
|
|
581
|
+
recordId: participantReadReply.record.descriptor.parentId,
|
|
582
|
+
},
|
|
583
|
+
protocolRole: 'thread/participant'
|
|
584
|
+
});
|
|
585
|
+
const threadReadReply = yield dwn.processMessage(alice.did, threadRead.message);
|
|
586
|
+
expect(threadReadReply.status.code).to.equal(200);
|
|
587
|
+
// Bob invokes his 'participant' role to read the chat message
|
|
588
|
+
const chatRead = yield RecordsRead.create({
|
|
589
|
+
signer: Jws.createSigner(bob),
|
|
590
|
+
filter: {
|
|
591
|
+
recordId: chatRecord.message.recordId,
|
|
592
|
+
},
|
|
593
|
+
protocolRole: 'thread/participant'
|
|
594
|
+
});
|
|
595
|
+
const chatReadReply = yield dwn.processMessage(alice.did, chatRead.message);
|
|
596
|
+
expect(chatReadReply.status.code).to.equal(200);
|
|
597
|
+
}));
|
|
598
|
+
it('rejects contextRole-authorized read if there is no active role in that context for the recipient', () => __awaiter(this, void 0, void 0, function* () {
|
|
599
|
+
// scenario: Alice creates a thread and adds Bob as a participant. ALice creates another thread. Bob tries and fails to invoke his
|
|
600
|
+
// contextRole to write a chat in the second thread
|
|
601
|
+
const alice = yield DidKeyResolver.generate();
|
|
602
|
+
const bob = yield DidKeyResolver.generate();
|
|
603
|
+
const protocolDefinition = threadRoleProtocolDefinition;
|
|
604
|
+
const protocolsConfig = yield TestDataGenerator.generateProtocolsConfigure({
|
|
605
|
+
author: alice,
|
|
606
|
+
protocolDefinition
|
|
607
|
+
});
|
|
608
|
+
const protocolsConfigureReply = yield dwn.processMessage(alice.did, protocolsConfig.message);
|
|
609
|
+
expect(protocolsConfigureReply.status.code).to.equal(202);
|
|
610
|
+
// Alice creates a thread
|
|
611
|
+
const threadRecord1 = yield TestDataGenerator.generateRecordsWrite({
|
|
612
|
+
author: alice,
|
|
613
|
+
recipient: bob.did,
|
|
614
|
+
protocol: protocolDefinition.protocol,
|
|
615
|
+
protocolPath: 'thread'
|
|
616
|
+
});
|
|
617
|
+
const threadRecordReply1 = yield dwn.processMessage(alice.did, threadRecord1.message, threadRecord1.dataStream);
|
|
618
|
+
expect(threadRecordReply1.status.code).to.equal(202);
|
|
619
|
+
// Alice adds Bob as a 'thread/participant' in that thread
|
|
620
|
+
const participantRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
621
|
+
author: alice,
|
|
622
|
+
recipient: bob.did,
|
|
623
|
+
protocol: protocolDefinition.protocol,
|
|
624
|
+
protocolPath: 'thread/participant',
|
|
625
|
+
contextId: threadRecord1.message.contextId,
|
|
626
|
+
parentId: threadRecord1.message.recordId,
|
|
627
|
+
});
|
|
628
|
+
const participantRecordReply = yield dwn.processMessage(alice.did, participantRecord.message, participantRecord.dataStream);
|
|
629
|
+
expect(participantRecordReply.status.code).to.equal(202);
|
|
630
|
+
// Alice creates a second thread
|
|
631
|
+
const threadRecord2 = yield TestDataGenerator.generateRecordsWrite({
|
|
632
|
+
author: alice,
|
|
633
|
+
recipient: bob.did,
|
|
634
|
+
protocol: protocolDefinition.protocol,
|
|
635
|
+
protocolPath: 'thread'
|
|
636
|
+
});
|
|
637
|
+
const threadRecordReply2 = yield dwn.processMessage(alice.did, threadRecord2.message, threadRecord2.dataStream);
|
|
638
|
+
expect(threadRecordReply2.status.code).to.equal(202);
|
|
639
|
+
// Alice writes a chat message in the thread
|
|
640
|
+
const chatRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
641
|
+
author: alice,
|
|
642
|
+
protocol: protocolDefinition.protocol,
|
|
643
|
+
protocolPath: 'thread/chat',
|
|
644
|
+
contextId: threadRecord2.message.contextId,
|
|
645
|
+
parentId: threadRecord2.message.recordId,
|
|
646
|
+
});
|
|
647
|
+
const chatRecordReply = yield dwn.processMessage(alice.did, chatRecord.message, chatRecord.dataStream);
|
|
648
|
+
expect(chatRecordReply.status.code).to.equal(202);
|
|
649
|
+
// Bob invokes his 'participant' role to read the chat message
|
|
650
|
+
const chatRead = yield RecordsRead.create({
|
|
651
|
+
signer: Jws.createSigner(bob),
|
|
652
|
+
filter: {
|
|
653
|
+
recordId: chatRecord.message.recordId,
|
|
654
|
+
},
|
|
655
|
+
protocolRole: 'thread/participant'
|
|
656
|
+
});
|
|
657
|
+
const chatReadReply = yield dwn.processMessage(alice.did, chatRead.message);
|
|
658
|
+
expect(chatReadReply.status.code).to.equal(401);
|
|
659
|
+
expect(chatReadReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationMissingRole);
|
|
660
|
+
}));
|
|
661
|
+
});
|
|
662
|
+
});
|
|
663
|
+
describe('grant based reads', () => {
|
|
664
|
+
it('rejects with 401 an external party attempts to RecordReads if grant has different DWN method scope', () => __awaiter(this, void 0, void 0, function* () {
|
|
665
|
+
// scenario: Alice grants Bob access to RecordsWrite, then Bob tries to invoke the grant with RecordsRead
|
|
666
|
+
const alice = yield DidKeyResolver.generate();
|
|
667
|
+
const bob = yield DidKeyResolver.generate();
|
|
668
|
+
// Alice writes a record which Bob will later try to read
|
|
669
|
+
const { recordsWrite, dataStream } = yield TestDataGenerator.generateRecordsWrite({
|
|
670
|
+
author: alice,
|
|
671
|
+
});
|
|
672
|
+
const recordsWriteReply = yield dwn.processMessage(alice.did, recordsWrite.message, dataStream);
|
|
673
|
+
expect(recordsWriteReply.status.code).to.equal(202);
|
|
674
|
+
// Alice gives Bob a PermissionsGrant with scope RecordsRead
|
|
675
|
+
const permissionsGrant = yield TestDataGenerator.generatePermissionsGrant({
|
|
676
|
+
author: alice,
|
|
677
|
+
grantedBy: alice.did,
|
|
678
|
+
grantedFor: alice.did,
|
|
679
|
+
grantedTo: bob.did,
|
|
680
|
+
scope: {
|
|
681
|
+
interface: DwnInterfaceName.Records,
|
|
682
|
+
method: DwnMethodName.Write,
|
|
683
|
+
}
|
|
684
|
+
});
|
|
685
|
+
const permissionsGrantReply = yield dwn.processMessage(alice.did, permissionsGrant.message);
|
|
686
|
+
expect(permissionsGrantReply.status.code).to.equal(202);
|
|
687
|
+
// Bob tries to RecordsRead
|
|
688
|
+
const recordsRead = yield RecordsRead.create({
|
|
689
|
+
filter: {
|
|
690
|
+
recordId: recordsWrite.message.recordId,
|
|
691
|
+
},
|
|
692
|
+
signer: Jws.createSigner(bob),
|
|
693
|
+
permissionsGrantId: yield Message.getCid(permissionsGrant.message),
|
|
694
|
+
});
|
|
695
|
+
const recordsReadReply = yield dwn.processMessage(alice.did, recordsRead.message);
|
|
696
|
+
expect(recordsReadReply.status.code).to.equal(401);
|
|
697
|
+
expect(recordsReadReply.status.detail).to.contain(DwnErrorCode.GrantAuthorizationMethodMismatch);
|
|
698
|
+
}));
|
|
699
|
+
it('allows external parties to read a record using a grant with unrestricted RecordsRead scope', () => __awaiter(this, void 0, void 0, function* () {
|
|
700
|
+
// scenario: Alice gives Bob a grant allowing him to read any record in her DWN.
|
|
701
|
+
// Bob invokes that grant to read a record.
|
|
702
|
+
const alice = yield DidKeyResolver.generate();
|
|
703
|
+
const bob = yield DidKeyResolver.generate();
|
|
704
|
+
// Alice writes a record to her DWN
|
|
705
|
+
const { message, dataStream } = yield TestDataGenerator.generateRecordsWrite({
|
|
706
|
+
author: alice,
|
|
707
|
+
});
|
|
708
|
+
const writeReply = yield dwn.processMessage(alice.did, message, dataStream);
|
|
709
|
+
expect(writeReply.status.code).to.equal(202);
|
|
710
|
+
// Alice issues a PermissionsGrant allowing Bob to read any record in her DWN
|
|
711
|
+
const permissionsGrant = yield TestDataGenerator.generatePermissionsGrant({
|
|
712
|
+
author: alice,
|
|
713
|
+
grantedBy: alice.did,
|
|
714
|
+
grantedTo: bob.did,
|
|
715
|
+
grantedFor: alice.did,
|
|
716
|
+
scope: {
|
|
717
|
+
interface: DwnInterfaceName.Records,
|
|
718
|
+
method: DwnMethodName.Read,
|
|
719
|
+
// No futher restrictions on grant scope
|
|
720
|
+
}
|
|
721
|
+
});
|
|
722
|
+
const grantReply = yield dwn.processMessage(alice.did, permissionsGrant.message);
|
|
723
|
+
expect(grantReply.status.code).to.equal(202);
|
|
724
|
+
// Bob invokes that grant to read a record from Alice's DWN
|
|
725
|
+
const recordsRead = yield RecordsRead.create({
|
|
726
|
+
filter: {
|
|
727
|
+
recordId: message.recordId,
|
|
728
|
+
},
|
|
729
|
+
signer: Jws.createSigner(bob),
|
|
730
|
+
permissionsGrantId: yield Message.getCid(permissionsGrant.message),
|
|
731
|
+
});
|
|
732
|
+
const readReply = yield dwn.processMessage(alice.did, recordsRead.message);
|
|
733
|
+
expect(readReply.status.code).to.equal(200);
|
|
734
|
+
}));
|
|
735
|
+
describe('protocol records', () => {
|
|
736
|
+
it('allows reads of protocol records with unrestricted grant scopes', () => __awaiter(this, void 0, void 0, function* () {
|
|
737
|
+
// scenario: Alice writes a protocol record. Alice gives Bob a grant to read all records in her DWN
|
|
738
|
+
// Bob invokes that grant to read the protocol record.
|
|
739
|
+
const alice = yield DidKeyResolver.generate();
|
|
740
|
+
const bob = yield DidKeyResolver.generate();
|
|
741
|
+
const protocolDefinition = minimalProtocolDefinition;
|
|
742
|
+
// Alice installs the protocol
|
|
743
|
+
const protocolsConfig = yield TestDataGenerator.generateProtocolsConfigure({
|
|
744
|
+
author: alice,
|
|
745
|
+
protocolDefinition
|
|
746
|
+
});
|
|
747
|
+
const protocolsConfigureReply = yield dwn.processMessage(alice.did, protocolsConfig.message);
|
|
748
|
+
expect(protocolsConfigureReply.status.code).to.equal(202);
|
|
749
|
+
// Alice writes a record which Bob will later try to read
|
|
750
|
+
const { recordsWrite, dataStream } = yield TestDataGenerator.generateRecordsWrite({
|
|
751
|
+
author: alice,
|
|
752
|
+
protocol: protocolDefinition.protocol,
|
|
753
|
+
protocolPath: 'foo',
|
|
754
|
+
});
|
|
755
|
+
const recordsWriteReply = yield dwn.processMessage(alice.did, recordsWrite.message, dataStream);
|
|
756
|
+
expect(recordsWriteReply.status.code).to.equal(202);
|
|
757
|
+
// Alice gives Bob a PermissionsGrant with scope RecordsRead
|
|
758
|
+
const permissionsGrant = yield TestDataGenerator.generatePermissionsGrant({
|
|
759
|
+
author: alice,
|
|
760
|
+
grantedBy: alice.did,
|
|
761
|
+
grantedFor: alice.did,
|
|
762
|
+
grantedTo: bob.did,
|
|
763
|
+
scope: {
|
|
764
|
+
interface: DwnInterfaceName.Records,
|
|
765
|
+
method: DwnMethodName.Read,
|
|
766
|
+
}
|
|
767
|
+
});
|
|
768
|
+
const permissionsGrantReply = yield dwn.processMessage(alice.did, permissionsGrant.message);
|
|
769
|
+
expect(permissionsGrantReply.status.code).to.equal(202);
|
|
770
|
+
// Bob is unable to read the record without using the PermissionsGrant
|
|
771
|
+
const recordsReadWithoutGrant = yield RecordsRead.create({
|
|
772
|
+
filter: {
|
|
773
|
+
recordId: recordsWrite.message.recordId,
|
|
774
|
+
},
|
|
775
|
+
signer: Jws.createSigner(bob),
|
|
776
|
+
});
|
|
777
|
+
const recordsReadWithoutGrantReply = yield dwn.processMessage(alice.did, recordsReadWithoutGrant.message);
|
|
778
|
+
expect(recordsReadWithoutGrantReply.status.code).to.equal(401);
|
|
779
|
+
expect(recordsReadWithoutGrantReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationActionRulesNotFound);
|
|
780
|
+
// Bob is able to read the record when he uses the PermissionsGrant
|
|
781
|
+
const recordsReadWithGrant = yield RecordsRead.create({
|
|
782
|
+
filter: {
|
|
783
|
+
recordId: recordsWrite.message.recordId,
|
|
784
|
+
},
|
|
785
|
+
signer: Jws.createSigner(bob),
|
|
786
|
+
permissionsGrantId: yield Message.getCid(permissionsGrant.message),
|
|
787
|
+
});
|
|
788
|
+
const recordsReadWithGrantReply = yield dwn.processMessage(alice.did, recordsReadWithGrant.message);
|
|
789
|
+
expect(recordsReadWithGrantReply.status.code).to.equal(200);
|
|
790
|
+
}));
|
|
791
|
+
it('allows reads of protocol records with matching protocol grant scopes', () => __awaiter(this, void 0, void 0, function* () {
|
|
792
|
+
// scenario: Alice writes a protocol record. Alice gives Bob a grant to read all records in the protocol
|
|
793
|
+
// Bob invokes that grant to read the protocol record.
|
|
794
|
+
const alice = yield DidKeyResolver.generate();
|
|
795
|
+
const bob = yield DidKeyResolver.generate();
|
|
796
|
+
const protocolDefinition = minimalProtocolDefinition;
|
|
797
|
+
// Alice installs the protocol
|
|
798
|
+
const protocolsConfig = yield TestDataGenerator.generateProtocolsConfigure({
|
|
799
|
+
author: alice,
|
|
800
|
+
protocolDefinition
|
|
801
|
+
});
|
|
802
|
+
const protocolsConfigureReply = yield dwn.processMessage(alice.did, protocolsConfig.message);
|
|
803
|
+
expect(protocolsConfigureReply.status.code).to.equal(202);
|
|
804
|
+
// Alice writes a record which Bob will later try to read
|
|
805
|
+
const { recordsWrite, dataStream } = yield TestDataGenerator.generateRecordsWrite({
|
|
806
|
+
author: alice,
|
|
807
|
+
protocol: protocolDefinition.protocol,
|
|
808
|
+
protocolPath: 'foo',
|
|
809
|
+
});
|
|
810
|
+
const recordsWriteReply = yield dwn.processMessage(alice.did, recordsWrite.message, dataStream);
|
|
811
|
+
expect(recordsWriteReply.status.code).to.equal(202);
|
|
812
|
+
// Alice gives Bob a PermissionsGrant with scope RecordsRead
|
|
813
|
+
const permissionsGrant = yield TestDataGenerator.generatePermissionsGrant({
|
|
814
|
+
author: alice,
|
|
815
|
+
grantedBy: alice.did,
|
|
816
|
+
grantedFor: alice.did,
|
|
817
|
+
grantedTo: bob.did,
|
|
818
|
+
scope: {
|
|
819
|
+
interface: DwnInterfaceName.Records,
|
|
820
|
+
method: DwnMethodName.Read,
|
|
821
|
+
protocol: protocolDefinition.protocol,
|
|
822
|
+
}
|
|
823
|
+
});
|
|
824
|
+
const permissionsGrantReply = yield dwn.processMessage(alice.did, permissionsGrant.message);
|
|
825
|
+
expect(permissionsGrantReply.status.code).to.equal(202);
|
|
826
|
+
// Bob is unable to read the record without using the PermissionsGrant
|
|
827
|
+
const recordsReadWithoutGrant = yield RecordsRead.create({
|
|
828
|
+
filter: {
|
|
829
|
+
recordId: recordsWrite.message.recordId,
|
|
830
|
+
},
|
|
831
|
+
signer: Jws.createSigner(bob),
|
|
832
|
+
});
|
|
833
|
+
const recordsReadWithoutGrantReply = yield dwn.processMessage(alice.did, recordsReadWithoutGrant.message);
|
|
834
|
+
expect(recordsReadWithoutGrantReply.status.code).to.equal(401);
|
|
835
|
+
expect(recordsReadWithoutGrantReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationActionRulesNotFound);
|
|
836
|
+
// Bob is able to read the record when he uses the PermissionsGrant
|
|
837
|
+
const recordsReadWithGrant = yield RecordsRead.create({
|
|
838
|
+
filter: {
|
|
839
|
+
recordId: recordsWrite.message.recordId,
|
|
840
|
+
},
|
|
841
|
+
signer: Jws.createSigner(bob),
|
|
842
|
+
permissionsGrantId: yield Message.getCid(permissionsGrant.message),
|
|
843
|
+
});
|
|
844
|
+
const recordsReadWithGrantReply = yield dwn.processMessage(alice.did, recordsReadWithGrant.message);
|
|
845
|
+
expect(recordsReadWithGrantReply.status.code).to.equal(200);
|
|
846
|
+
}));
|
|
847
|
+
it('rejects reads of protocol records with mismatching protocol grant scopes', () => __awaiter(this, void 0, void 0, function* () {
|
|
848
|
+
// scenario: Alice writes a protocol record. Alice gives Bob a grant to read a different protocol
|
|
849
|
+
// Bob invokes that grant to read the protocol record, but fails.
|
|
850
|
+
const alice = yield DidKeyResolver.generate();
|
|
851
|
+
const bob = yield DidKeyResolver.generate();
|
|
852
|
+
const protocolDefinition = minimalProtocolDefinition;
|
|
853
|
+
// Alice installs the protocol
|
|
854
|
+
const protocolsConfig = yield TestDataGenerator.generateProtocolsConfigure({
|
|
855
|
+
author: alice,
|
|
856
|
+
protocolDefinition
|
|
857
|
+
});
|
|
858
|
+
const protocolsConfigureReply = yield dwn.processMessage(alice.did, protocolsConfig.message);
|
|
859
|
+
expect(protocolsConfigureReply.status.code).to.equal(202);
|
|
860
|
+
// Alice writes a record which Bob will later try to read
|
|
861
|
+
const { recordsWrite, dataStream } = yield TestDataGenerator.generateRecordsWrite({
|
|
862
|
+
author: alice,
|
|
863
|
+
protocol: protocolDefinition.protocol,
|
|
864
|
+
protocolPath: 'foo',
|
|
865
|
+
});
|
|
866
|
+
const recordsWriteReply = yield dwn.processMessage(alice.did, recordsWrite.message, dataStream);
|
|
867
|
+
expect(recordsWriteReply.status.code).to.equal(202);
|
|
868
|
+
// Alice gives Bob a PermissionsGrant with scope RecordsRead
|
|
869
|
+
const permissionsGrant = yield TestDataGenerator.generatePermissionsGrant({
|
|
870
|
+
author: alice,
|
|
871
|
+
grantedBy: alice.did,
|
|
872
|
+
grantedFor: alice.did,
|
|
873
|
+
grantedTo: bob.did,
|
|
874
|
+
scope: {
|
|
875
|
+
interface: DwnInterfaceName.Records,
|
|
876
|
+
method: DwnMethodName.Read,
|
|
877
|
+
protocol: 'a-different-protocol'
|
|
878
|
+
}
|
|
879
|
+
});
|
|
880
|
+
const permissionsGrantReply = yield dwn.processMessage(alice.did, permissionsGrant.message);
|
|
881
|
+
expect(permissionsGrantReply.status.code).to.equal(202);
|
|
882
|
+
// Bob is unable to read the record using the mismatched PermissionsGrant
|
|
883
|
+
const recordsReadWithoutGrant = yield RecordsRead.create({
|
|
884
|
+
filter: {
|
|
885
|
+
recordId: recordsWrite.message.recordId,
|
|
886
|
+
},
|
|
887
|
+
signer: Jws.createSigner(bob),
|
|
888
|
+
permissionsGrantId: yield Message.getCid(permissionsGrant.message),
|
|
889
|
+
});
|
|
890
|
+
const recordsReadWithoutGrantReply = yield dwn.processMessage(alice.did, recordsReadWithoutGrant.message);
|
|
891
|
+
expect(recordsReadWithoutGrantReply.status.code).to.equal(401);
|
|
892
|
+
expect(recordsReadWithoutGrantReply.status.detail).to.contain(DwnErrorCode.RecordsGrantAuthorizationScopeProtocolMismatch);
|
|
893
|
+
}));
|
|
894
|
+
it('rejects reads of protocol records with non-protocol grant scopes', () => __awaiter(this, void 0, void 0, function* () {
|
|
895
|
+
// scenario: Alice writes a protocol record. Alice gives Bob a grant to read a records of a certain schema.
|
|
896
|
+
// Bob invokes that grant to read the protocol record, but fails.
|
|
897
|
+
const alice = yield DidKeyResolver.generate();
|
|
898
|
+
const bob = yield DidKeyResolver.generate();
|
|
899
|
+
const protocolDefinition = minimalProtocolDefinition;
|
|
900
|
+
// Alice installs the protocol
|
|
901
|
+
const protocolsConfig = yield TestDataGenerator.generateProtocolsConfigure({
|
|
902
|
+
author: alice,
|
|
903
|
+
protocolDefinition
|
|
904
|
+
});
|
|
905
|
+
const protocolsConfigureReply = yield dwn.processMessage(alice.did, protocolsConfig.message);
|
|
906
|
+
expect(protocolsConfigureReply.status.code).to.equal(202);
|
|
907
|
+
// Alice writes a record which Bob will later try to read
|
|
908
|
+
const { recordsWrite, dataStream } = yield TestDataGenerator.generateRecordsWrite({
|
|
909
|
+
author: alice,
|
|
910
|
+
protocol: protocolDefinition.protocol,
|
|
911
|
+
protocolPath: 'foo',
|
|
912
|
+
});
|
|
913
|
+
const recordsWriteReply = yield dwn.processMessage(alice.did, recordsWrite.message, dataStream);
|
|
914
|
+
expect(recordsWriteReply.status.code).to.equal(202);
|
|
915
|
+
// Alice gives Bob a PermissionsGrant with scope RecordsRead
|
|
916
|
+
const permissionsGrant = yield TestDataGenerator.generatePermissionsGrant({
|
|
917
|
+
author: alice,
|
|
918
|
+
grantedBy: alice.did,
|
|
919
|
+
grantedFor: alice.did,
|
|
920
|
+
grantedTo: bob.did,
|
|
921
|
+
scope: {
|
|
922
|
+
interface: DwnInterfaceName.Records,
|
|
923
|
+
method: DwnMethodName.Read,
|
|
924
|
+
schema: 'some-schema'
|
|
925
|
+
}
|
|
926
|
+
});
|
|
927
|
+
const permissionsGrantReply = yield dwn.processMessage(alice.did, permissionsGrant.message);
|
|
928
|
+
expect(permissionsGrantReply.status.code).to.equal(202);
|
|
929
|
+
// Bob is unable to read the record using the mismatched PermissionsGrant
|
|
930
|
+
const recordsReadWithoutGrant = yield RecordsRead.create({
|
|
931
|
+
filter: {
|
|
932
|
+
recordId: recordsWrite.message.recordId,
|
|
933
|
+
},
|
|
934
|
+
signer: Jws.createSigner(bob),
|
|
935
|
+
permissionsGrantId: yield Message.getCid(permissionsGrant.message),
|
|
936
|
+
});
|
|
937
|
+
const recordsReadWithoutGrantReply = yield dwn.processMessage(alice.did, recordsReadWithoutGrant.message);
|
|
938
|
+
expect(recordsReadWithoutGrantReply.status.code).to.equal(401);
|
|
939
|
+
expect(recordsReadWithoutGrantReply.status.detail).to.contain(DwnErrorCode.RecordsGrantAuthorizationScopeNotProtocol);
|
|
940
|
+
}));
|
|
941
|
+
it('allows reads of records in the contextId specified in the grant', () => __awaiter(this, void 0, void 0, function* () {
|
|
942
|
+
// scenario: Alice grants Bob access to RecordsRead records with a specific contextId.
|
|
943
|
+
// Bob uses it to read a record in that context.
|
|
944
|
+
const alice = yield DidKeyResolver.generate();
|
|
945
|
+
const bob = yield DidKeyResolver.generate();
|
|
946
|
+
const protocolDefinition = minimalProtocolDefinition;
|
|
947
|
+
// Alice installs the protocol
|
|
948
|
+
const protocolsConfig = yield TestDataGenerator.generateProtocolsConfigure({
|
|
949
|
+
author: alice,
|
|
950
|
+
protocolDefinition
|
|
951
|
+
});
|
|
952
|
+
const protocolsConfigureReply = yield dwn.processMessage(alice.did, protocolsConfig.message);
|
|
953
|
+
expect(protocolsConfigureReply.status.code).to.equal(202);
|
|
954
|
+
// Alice writes a record which Bob will later try to read
|
|
955
|
+
const { recordsWrite, dataStream } = yield TestDataGenerator.generateRecordsWrite({
|
|
956
|
+
author: alice,
|
|
957
|
+
protocol: protocolDefinition.protocol,
|
|
958
|
+
protocolPath: 'foo',
|
|
959
|
+
});
|
|
960
|
+
const recordsWriteReply = yield dwn.processMessage(alice.did, recordsWrite.message, dataStream);
|
|
961
|
+
expect(recordsWriteReply.status.code).to.equal(202);
|
|
962
|
+
// Alice gives Bob a PermissionsGrant with scope RecordsRead
|
|
963
|
+
const permissionsGrant = yield TestDataGenerator.generatePermissionsGrant({
|
|
964
|
+
author: alice,
|
|
965
|
+
grantedBy: alice.did,
|
|
966
|
+
grantedFor: alice.did,
|
|
967
|
+
grantedTo: bob.did,
|
|
968
|
+
scope: {
|
|
969
|
+
interface: DwnInterfaceName.Records,
|
|
970
|
+
method: DwnMethodName.Read,
|
|
971
|
+
protocol: protocolDefinition.protocol,
|
|
972
|
+
contextId: recordsWrite.message.contextId,
|
|
973
|
+
}
|
|
974
|
+
});
|
|
975
|
+
const permissionsGrantReply = yield dwn.processMessage(alice.did, permissionsGrant.message);
|
|
976
|
+
expect(permissionsGrantReply.status.code).to.equal(202);
|
|
977
|
+
// Bob is unable to read the record using the mismatched PermissionsGrant
|
|
978
|
+
const recordsReadWithoutGrant = yield RecordsRead.create({
|
|
979
|
+
filter: {
|
|
980
|
+
recordId: recordsWrite.message.recordId,
|
|
981
|
+
},
|
|
982
|
+
signer: Jws.createSigner(bob),
|
|
983
|
+
permissionsGrantId: yield Message.getCid(permissionsGrant.message),
|
|
984
|
+
});
|
|
985
|
+
const recordsReadWithoutGrantReply = yield dwn.processMessage(alice.did, recordsReadWithoutGrant.message);
|
|
986
|
+
expect(recordsReadWithoutGrantReply.status.code).to.equal(200);
|
|
987
|
+
}));
|
|
988
|
+
it('rejects reads of records in a different contextId than is specified in the grant', () => __awaiter(this, void 0, void 0, function* () {
|
|
989
|
+
// scenario: Alice grants Bob access to RecordsRead records with a specific contextId.
|
|
990
|
+
// Bob tries and fails to invoke the grant in order to read a record outside of the context.
|
|
991
|
+
const alice = yield DidKeyResolver.generate();
|
|
992
|
+
const bob = yield DidKeyResolver.generate();
|
|
993
|
+
const protocolDefinition = minimalProtocolDefinition;
|
|
994
|
+
// Alice installs the protocol
|
|
995
|
+
const protocolsConfig = yield TestDataGenerator.generateProtocolsConfigure({
|
|
996
|
+
author: alice,
|
|
997
|
+
protocolDefinition
|
|
998
|
+
});
|
|
999
|
+
const protocolsConfigureReply = yield dwn.processMessage(alice.did, protocolsConfig.message);
|
|
1000
|
+
expect(protocolsConfigureReply.status.code).to.equal(202);
|
|
1001
|
+
// Alice writes a record which Bob will later try to read
|
|
1002
|
+
const { recordsWrite, dataStream } = yield TestDataGenerator.generateRecordsWrite({
|
|
1003
|
+
author: alice,
|
|
1004
|
+
protocol: protocolDefinition.protocol,
|
|
1005
|
+
protocolPath: 'foo',
|
|
1006
|
+
});
|
|
1007
|
+
const recordsWriteReply = yield dwn.processMessage(alice.did, recordsWrite.message, dataStream);
|
|
1008
|
+
expect(recordsWriteReply.status.code).to.equal(202);
|
|
1009
|
+
// Alice gives Bob a PermissionsGrant with scope RecordsRead
|
|
1010
|
+
const permissionsGrant = yield TestDataGenerator.generatePermissionsGrant({
|
|
1011
|
+
author: alice,
|
|
1012
|
+
grantedBy: alice.did,
|
|
1013
|
+
grantedFor: alice.did,
|
|
1014
|
+
grantedTo: bob.did,
|
|
1015
|
+
scope: {
|
|
1016
|
+
interface: DwnInterfaceName.Records,
|
|
1017
|
+
method: DwnMethodName.Read,
|
|
1018
|
+
protocol: protocolDefinition.protocol,
|
|
1019
|
+
contextId: yield TestDataGenerator.randomCborSha256Cid(), // different contextId than what Bob will try to read
|
|
1020
|
+
}
|
|
1021
|
+
});
|
|
1022
|
+
const permissionsGrantReply = yield dwn.processMessage(alice.did, permissionsGrant.message);
|
|
1023
|
+
expect(permissionsGrantReply.status.code).to.equal(202);
|
|
1024
|
+
// Bob is unable to read the record using the mismatched PermissionsGrant
|
|
1025
|
+
const recordsReadWithoutGrant = yield RecordsRead.create({
|
|
1026
|
+
filter: {
|
|
1027
|
+
recordId: recordsWrite.message.recordId,
|
|
1028
|
+
},
|
|
1029
|
+
signer: Jws.createSigner(bob),
|
|
1030
|
+
permissionsGrantId: yield Message.getCid(permissionsGrant.message),
|
|
1031
|
+
});
|
|
1032
|
+
const recordsReadWithoutGrantReply = yield dwn.processMessage(alice.did, recordsReadWithoutGrant.message);
|
|
1033
|
+
expect(recordsReadWithoutGrantReply.status.code).to.equal(401);
|
|
1034
|
+
expect(recordsReadWithoutGrantReply.status.detail).to.contain(DwnErrorCode.RecordsGrantAuthorizationScopeContextIdMismatch);
|
|
1035
|
+
}));
|
|
1036
|
+
it('allows reads of records in the protocolPath specified in the grant', () => __awaiter(this, void 0, void 0, function* () {
|
|
1037
|
+
// scenario: Alice grants Bob access to RecordsRead records with a specific protocolPath.
|
|
1038
|
+
// Bob uses it to read a record in that protocolPath.
|
|
1039
|
+
const alice = yield DidKeyResolver.generate();
|
|
1040
|
+
const bob = yield DidKeyResolver.generate();
|
|
1041
|
+
const protocolDefinition = minimalProtocolDefinition;
|
|
1042
|
+
// Alice installs the protocol
|
|
1043
|
+
const protocolsConfig = yield TestDataGenerator.generateProtocolsConfigure({
|
|
1044
|
+
author: alice,
|
|
1045
|
+
protocolDefinition
|
|
1046
|
+
});
|
|
1047
|
+
const protocolsConfigureReply = yield dwn.processMessage(alice.did, protocolsConfig.message);
|
|
1048
|
+
expect(protocolsConfigureReply.status.code).to.equal(202);
|
|
1049
|
+
// Alice writes a record which Bob will later try to read
|
|
1050
|
+
const { recordsWrite, dataStream } = yield TestDataGenerator.generateRecordsWrite({
|
|
1051
|
+
author: alice,
|
|
1052
|
+
protocol: protocolDefinition.protocol,
|
|
1053
|
+
protocolPath: 'foo',
|
|
1054
|
+
});
|
|
1055
|
+
const recordsWriteReply = yield dwn.processMessage(alice.did, recordsWrite.message, dataStream);
|
|
1056
|
+
expect(recordsWriteReply.status.code).to.equal(202);
|
|
1057
|
+
// Alice gives Bob a PermissionsGrant with scope RecordsRead
|
|
1058
|
+
const permissionsGrant = yield TestDataGenerator.generatePermissionsGrant({
|
|
1059
|
+
author: alice,
|
|
1060
|
+
grantedBy: alice.did,
|
|
1061
|
+
grantedFor: alice.did,
|
|
1062
|
+
grantedTo: bob.did,
|
|
1063
|
+
scope: {
|
|
1064
|
+
interface: DwnInterfaceName.Records,
|
|
1065
|
+
method: DwnMethodName.Read,
|
|
1066
|
+
protocol: protocolDefinition.protocol,
|
|
1067
|
+
protocolPath: recordsWrite.message.descriptor.protocolPath,
|
|
1068
|
+
}
|
|
1069
|
+
});
|
|
1070
|
+
const permissionsGrantReply = yield dwn.processMessage(alice.did, permissionsGrant.message);
|
|
1071
|
+
expect(permissionsGrantReply.status.code).to.equal(202);
|
|
1072
|
+
// Bob is unable to read the record using the mismatched PermissionsGrant
|
|
1073
|
+
const recordsReadWithoutGrant = yield RecordsRead.create({
|
|
1074
|
+
filter: {
|
|
1075
|
+
recordId: recordsWrite.message.recordId,
|
|
1076
|
+
},
|
|
1077
|
+
signer: Jws.createSigner(bob),
|
|
1078
|
+
permissionsGrantId: yield Message.getCid(permissionsGrant.message),
|
|
1079
|
+
});
|
|
1080
|
+
const recordsReadWithoutGrantReply = yield dwn.processMessage(alice.did, recordsReadWithoutGrant.message);
|
|
1081
|
+
expect(recordsReadWithoutGrantReply.status.code).to.equal(200);
|
|
1082
|
+
}));
|
|
1083
|
+
it('rejects reads of records in a different protocolPath than is specified in the grant', () => __awaiter(this, void 0, void 0, function* () {
|
|
1084
|
+
// scenario: Alice grants Bob access to RecordsRead records with a specific protocolPath.
|
|
1085
|
+
// Bob tries and fails to invoke the grant in order to read a record outside of the protocolPath.
|
|
1086
|
+
const alice = yield DidKeyResolver.generate();
|
|
1087
|
+
const bob = yield DidKeyResolver.generate();
|
|
1088
|
+
const protocolDefinition = minimalProtocolDefinition;
|
|
1089
|
+
// Alice installs the protocol
|
|
1090
|
+
const protocolsConfig = yield TestDataGenerator.generateProtocolsConfigure({
|
|
1091
|
+
author: alice,
|
|
1092
|
+
protocolDefinition
|
|
1093
|
+
});
|
|
1094
|
+
const protocolsConfigureReply = yield dwn.processMessage(alice.did, protocolsConfig.message);
|
|
1095
|
+
expect(protocolsConfigureReply.status.code).to.equal(202);
|
|
1096
|
+
// Alice writes a record which Bob will later try to read
|
|
1097
|
+
const { recordsWrite, dataStream } = yield TestDataGenerator.generateRecordsWrite({
|
|
1098
|
+
author: alice,
|
|
1099
|
+
protocol: protocolDefinition.protocol,
|
|
1100
|
+
protocolPath: 'foo',
|
|
1101
|
+
});
|
|
1102
|
+
const recordsWriteReply = yield dwn.processMessage(alice.did, recordsWrite.message, dataStream);
|
|
1103
|
+
expect(recordsWriteReply.status.code).to.equal(202);
|
|
1104
|
+
// Alice gives Bob a PermissionsGrant with scope RecordsRead
|
|
1105
|
+
const permissionsGrant = yield TestDataGenerator.generatePermissionsGrant({
|
|
1106
|
+
author: alice,
|
|
1107
|
+
grantedBy: alice.did,
|
|
1108
|
+
grantedFor: alice.did,
|
|
1109
|
+
grantedTo: bob.did,
|
|
1110
|
+
scope: {
|
|
1111
|
+
interface: DwnInterfaceName.Records,
|
|
1112
|
+
method: DwnMethodName.Read,
|
|
1113
|
+
protocol: protocolDefinition.protocol,
|
|
1114
|
+
protocolPath: 'different-protocol-path', // different protocol path than what Bob will try to read
|
|
1115
|
+
}
|
|
1116
|
+
});
|
|
1117
|
+
const permissionsGrantReply = yield dwn.processMessage(alice.did, permissionsGrant.message);
|
|
1118
|
+
expect(permissionsGrantReply.status.code).to.equal(202);
|
|
1119
|
+
// Bob is unable to read the record using the mismatched PermissionsGrant
|
|
1120
|
+
const recordsReadWithoutGrant = yield RecordsRead.create({
|
|
1121
|
+
filter: {
|
|
1122
|
+
recordId: recordsWrite.message.recordId,
|
|
1123
|
+
},
|
|
1124
|
+
signer: Jws.createSigner(bob),
|
|
1125
|
+
permissionsGrantId: yield Message.getCid(permissionsGrant.message),
|
|
1126
|
+
});
|
|
1127
|
+
const recordsReadWithoutGrantReply = yield dwn.processMessage(alice.did, recordsReadWithoutGrant.message);
|
|
1128
|
+
expect(recordsReadWithoutGrantReply.status.code).to.equal(401);
|
|
1129
|
+
expect(recordsReadWithoutGrantReply.status.detail).to.contain(DwnErrorCode.RecordsGrantAuthorizationScopeProtocolPathMismatch);
|
|
1130
|
+
}));
|
|
1131
|
+
});
|
|
1132
|
+
describe('grant scope schema', () => {
|
|
1133
|
+
it('allows access if the RecordsRead grant scope schema includes the schema of the record', () => __awaiter(this, void 0, void 0, function* () {
|
|
1134
|
+
// scenario: Alice gives Bob a grant allowing him to read records with matching schema in her DWN.
|
|
1135
|
+
// Bob invokes that grant to read a record.
|
|
1136
|
+
const alice = yield DidKeyResolver.generate();
|
|
1137
|
+
const bob = yield DidKeyResolver.generate();
|
|
1138
|
+
// Alice writes a record to her DWN
|
|
1139
|
+
const { message, dataStream } = yield TestDataGenerator.generateRecordsWrite({
|
|
1140
|
+
author: alice,
|
|
1141
|
+
schema: 'some-schema',
|
|
1142
|
+
});
|
|
1143
|
+
const writeReply = yield dwn.processMessage(alice.did, message, dataStream);
|
|
1144
|
+
expect(writeReply.status.code).to.equal(202);
|
|
1145
|
+
// Alice issues a PermissionsGrant allowing Bob to read a specific recordId
|
|
1146
|
+
const permissionsGrant = yield TestDataGenerator.generatePermissionsGrant({
|
|
1147
|
+
author: alice,
|
|
1148
|
+
grantedBy: alice.did,
|
|
1149
|
+
grantedTo: bob.did,
|
|
1150
|
+
grantedFor: alice.did,
|
|
1151
|
+
scope: {
|
|
1152
|
+
interface: DwnInterfaceName.Records,
|
|
1153
|
+
method: DwnMethodName.Read,
|
|
1154
|
+
schema: message.descriptor.schema
|
|
1155
|
+
}
|
|
1156
|
+
});
|
|
1157
|
+
const grantReply = yield dwn.processMessage(alice.did, permissionsGrant.message);
|
|
1158
|
+
expect(grantReply.status.code).to.equal(202);
|
|
1159
|
+
// Bob invokes that grant to read a record from Alice's DWN
|
|
1160
|
+
const recordsRead = yield RecordsRead.create({
|
|
1161
|
+
filter: {
|
|
1162
|
+
recordId: message.recordId,
|
|
1163
|
+
},
|
|
1164
|
+
signer: Jws.createSigner(bob),
|
|
1165
|
+
permissionsGrantId: yield Message.getCid(permissionsGrant.message),
|
|
1166
|
+
});
|
|
1167
|
+
const readReply = yield dwn.processMessage(alice.did, recordsRead.message);
|
|
1168
|
+
expect(readReply.status.code).to.equal(200);
|
|
1169
|
+
}));
|
|
1170
|
+
it('rejects with 401 if the RecordsRead grant scope schema does not have the same schema as the record', () => __awaiter(this, void 0, void 0, function* () {
|
|
1171
|
+
// scenario: Alice gives Bob a grant allowing him to read records with matching schema in her DWN.
|
|
1172
|
+
// Bob invokes that grant to read a different record and is rejected.
|
|
1173
|
+
const alice = yield DidKeyResolver.generate();
|
|
1174
|
+
const bob = yield DidKeyResolver.generate();
|
|
1175
|
+
// Alice writes a record to her DWN
|
|
1176
|
+
const recordSchema = 'record-schema';
|
|
1177
|
+
const { message, dataStream } = yield TestDataGenerator.generateRecordsWrite({
|
|
1178
|
+
author: alice,
|
|
1179
|
+
schema: recordSchema,
|
|
1180
|
+
});
|
|
1181
|
+
const writeReply = yield dwn.processMessage(alice.did, message, dataStream);
|
|
1182
|
+
expect(writeReply.status.code).to.equal(202);
|
|
1183
|
+
// Alice issues a PermissionsGrant allowing Bob to read a specific recordId
|
|
1184
|
+
const scopeSchema = 'scope-schema';
|
|
1185
|
+
const permissionsGrant = yield TestDataGenerator.generatePermissionsGrant({
|
|
1186
|
+
author: alice,
|
|
1187
|
+
grantedBy: alice.did,
|
|
1188
|
+
grantedTo: bob.did,
|
|
1189
|
+
grantedFor: alice.did,
|
|
1190
|
+
scope: {
|
|
1191
|
+
interface: DwnInterfaceName.Records,
|
|
1192
|
+
method: DwnMethodName.Read,
|
|
1193
|
+
schema: scopeSchema // different schema than the record Bob will try to read
|
|
1194
|
+
}
|
|
1195
|
+
});
|
|
1196
|
+
const grantReply = yield dwn.processMessage(alice.did, permissionsGrant.message);
|
|
1197
|
+
expect(grantReply.status.code).to.equal(202);
|
|
1198
|
+
// Bob invokes that grant to read a record from Alice's DWN
|
|
1199
|
+
const recordsRead = yield RecordsRead.create({
|
|
1200
|
+
filter: {
|
|
1201
|
+
recordId: message.recordId,
|
|
1202
|
+
},
|
|
1203
|
+
signer: Jws.createSigner(bob),
|
|
1204
|
+
permissionsGrantId: yield Message.getCid(permissionsGrant.message),
|
|
1205
|
+
});
|
|
1206
|
+
const readReply = yield dwn.processMessage(alice.did, recordsRead.message);
|
|
1207
|
+
expect(readReply.status.code).to.equal(401);
|
|
1208
|
+
expect(readReply.status.detail).to.include(DwnErrorCode.RecordsGrantAuthorizationScopeSchema);
|
|
1209
|
+
}));
|
|
1210
|
+
});
|
|
1211
|
+
});
|
|
1212
|
+
it('should return 404 RecordRead if data does not exist', () => __awaiter(this, void 0, void 0, function* () {
|
|
1213
|
+
const alice = yield DidKeyResolver.generate();
|
|
1214
|
+
const recordsRead = yield RecordsRead.create({
|
|
1215
|
+
filter: {
|
|
1216
|
+
recordId: `non-existent-record-id`,
|
|
1217
|
+
},
|
|
1218
|
+
signer: Jws.createSigner(alice)
|
|
1219
|
+
});
|
|
1220
|
+
const readReply = yield dwn.processMessage(alice.did, recordsRead.message);
|
|
1221
|
+
expect(readReply.status.code).to.equal(404);
|
|
1222
|
+
}));
|
|
1223
|
+
it('should return 404 RecordRead if data has been deleted', () => __awaiter(this, void 0, void 0, function* () {
|
|
1224
|
+
var _a;
|
|
1225
|
+
const alice = yield DidKeyResolver.generate();
|
|
1226
|
+
// insert public data
|
|
1227
|
+
const { message, dataStream } = yield TestDataGenerator.generateRecordsWrite({ author: alice, published: true });
|
|
1228
|
+
const writeReply = yield dwn.processMessage(alice.did, message, dataStream);
|
|
1229
|
+
expect(writeReply.status.code).to.equal(202);
|
|
1230
|
+
// ensure data is inserted
|
|
1231
|
+
const queryData = yield TestDataGenerator.generateRecordsQuery({
|
|
1232
|
+
author: alice,
|
|
1233
|
+
filter: { recordId: message.recordId }
|
|
1234
|
+
});
|
|
1235
|
+
const reply = yield dwn.processMessage(alice.did, queryData.message);
|
|
1236
|
+
expect(reply.status.code).to.equal(200);
|
|
1237
|
+
expect((_a = reply.entries) === null || _a === void 0 ? void 0 : _a.length).to.equal(1);
|
|
1238
|
+
// RecordsDelete
|
|
1239
|
+
const recordsDelete = yield RecordsDelete.create({
|
|
1240
|
+
recordId: message.recordId,
|
|
1241
|
+
signer: Jws.createSigner(alice)
|
|
1242
|
+
});
|
|
1243
|
+
const deleteReply = yield dwn.processMessage(alice.did, recordsDelete.message);
|
|
1244
|
+
expect(deleteReply.status.code).to.equal(202);
|
|
1245
|
+
// RecordsRead
|
|
1246
|
+
const recordsRead = yield RecordsRead.create({
|
|
1247
|
+
filter: {
|
|
1248
|
+
recordId: message.recordId,
|
|
1249
|
+
},
|
|
1250
|
+
signer: Jws.createSigner(alice)
|
|
1251
|
+
});
|
|
1252
|
+
const readReply = yield dwn.processMessage(alice.did, recordsRead.message);
|
|
1253
|
+
expect(readReply.status.code).to.equal(404);
|
|
1254
|
+
}));
|
|
1255
|
+
it('should return 404 underlying data store cannot locate the data when data is above threshold', () => __awaiter(this, void 0, void 0, function* () {
|
|
1256
|
+
const alice = yield DidKeyResolver.generate();
|
|
1257
|
+
sinon.stub(dataStore, 'get').resolves(undefined);
|
|
1258
|
+
// insert data larger than the allowed amount in encodedData
|
|
1259
|
+
const { message, dataStream } = yield TestDataGenerator.generateRecordsWrite({
|
|
1260
|
+
author: alice,
|
|
1261
|
+
data: TestDataGenerator.randomBytes(DwnConstant.maxDataSizeAllowedToBeEncoded + 1)
|
|
1262
|
+
});
|
|
1263
|
+
const writeReply = yield dwn.processMessage(alice.did, message, dataStream);
|
|
1264
|
+
expect(writeReply.status.code).to.equal(202);
|
|
1265
|
+
// testing RecordsRead
|
|
1266
|
+
const recordsRead = yield RecordsRead.create({
|
|
1267
|
+
filter: {
|
|
1268
|
+
recordId: message.recordId,
|
|
1269
|
+
},
|
|
1270
|
+
signer: Jws.createSigner(alice)
|
|
1271
|
+
});
|
|
1272
|
+
const readReply = yield dwn.processMessage(alice.did, recordsRead.message);
|
|
1273
|
+
expect(readReply.status.code).to.equal(404);
|
|
1274
|
+
}));
|
|
1275
|
+
describe('data from encodedData', () => {
|
|
1276
|
+
it('should not get data from DataStore if encodedData exists', () => __awaiter(this, void 0, void 0, function* () {
|
|
1277
|
+
const alice = yield DidKeyResolver.generate();
|
|
1278
|
+
//since the data is at the threshold it will be returned from the messageStore in the `encodedData` field.
|
|
1279
|
+
const { message, dataStream, dataBytes } = yield TestDataGenerator.generateRecordsWrite({
|
|
1280
|
+
author: alice,
|
|
1281
|
+
data: TestDataGenerator.randomBytes(DwnConstant.maxDataSizeAllowedToBeEncoded)
|
|
1282
|
+
});
|
|
1283
|
+
const writeReply = yield dwn.processMessage(alice.did, message, dataStream);
|
|
1284
|
+
expect(writeReply.status.code).to.equal(202);
|
|
1285
|
+
const recordRead = yield RecordsRead.create({
|
|
1286
|
+
filter: {
|
|
1287
|
+
recordId: message.recordId,
|
|
1288
|
+
},
|
|
1289
|
+
signer: Jws.createSigner(alice)
|
|
1290
|
+
});
|
|
1291
|
+
const dataStoreGet = sinon.spy(dataStore, 'get');
|
|
1292
|
+
const recordsReadResponse = yield dwn.processMessage(alice.did, recordRead.message);
|
|
1293
|
+
expect(recordsReadResponse.status.code).to.equal(200);
|
|
1294
|
+
expect(recordsReadResponse.record).to.exist;
|
|
1295
|
+
expect(recordsReadResponse.record.data).to.exist;
|
|
1296
|
+
sinon.assert.notCalled(dataStoreGet);
|
|
1297
|
+
const readData = yield DataStream.toBytes(recordsReadResponse.record.data);
|
|
1298
|
+
expect(readData).to.eql(dataBytes);
|
|
1299
|
+
}));
|
|
1300
|
+
it('should get data from DataStore if encodedData does not exist', () => __awaiter(this, void 0, void 0, function* () {
|
|
1301
|
+
const alice = yield DidKeyResolver.generate();
|
|
1302
|
+
//since the data is over the threshold it will not be returned from the messageStore in the `encodedData` field.
|
|
1303
|
+
const { message, dataStream, dataBytes } = yield TestDataGenerator.generateRecordsWrite({
|
|
1304
|
+
author: alice,
|
|
1305
|
+
data: TestDataGenerator.randomBytes(DwnConstant.maxDataSizeAllowedToBeEncoded + 1)
|
|
1306
|
+
});
|
|
1307
|
+
const writeReply = yield dwn.processMessage(alice.did, message, dataStream);
|
|
1308
|
+
expect(writeReply.status.code).to.equal(202);
|
|
1309
|
+
const recordRead = yield RecordsRead.create({
|
|
1310
|
+
filter: {
|
|
1311
|
+
recordId: message.recordId,
|
|
1312
|
+
},
|
|
1313
|
+
signer: Jws.createSigner(alice)
|
|
1314
|
+
});
|
|
1315
|
+
const dataStoreGet = sinon.spy(dataStore, 'get');
|
|
1316
|
+
const recordsReadResponse = yield dwn.processMessage(alice.did, recordRead.message);
|
|
1317
|
+
expect(recordsReadResponse.status.code).to.equal(200);
|
|
1318
|
+
expect(recordsReadResponse.record).to.exist;
|
|
1319
|
+
expect(recordsReadResponse.record.data).to.exist;
|
|
1320
|
+
sinon.assert.calledOnce(dataStoreGet);
|
|
1321
|
+
const readData = yield DataStream.toBytes(recordsReadResponse.record.data);
|
|
1322
|
+
expect(readData).to.eql(dataBytes);
|
|
1323
|
+
}));
|
|
1324
|
+
});
|
|
1325
|
+
describe('encryption scenarios', () => {
|
|
1326
|
+
it('should be able to decrypt flat-space schema-contained record with a correct derived key', () => __awaiter(this, void 0, void 0, function* () {
|
|
1327
|
+
// scenario: Alice writes into her own DWN an encrypted record and she is able to decrypt it
|
|
1328
|
+
const alice = yield TestDataGenerator.generatePersona();
|
|
1329
|
+
TestStubGenerator.stubDidResolver(didResolver, [alice]);
|
|
1330
|
+
// encrypt Alice's record
|
|
1331
|
+
const originalData = TestDataGenerator.randomBytes(1000);
|
|
1332
|
+
const originalDataStream = DataStream.fromBytes(originalData);
|
|
1333
|
+
const dataEncryptionInitializationVector = TestDataGenerator.randomBytes(16);
|
|
1334
|
+
const dataEncryptionKey = TestDataGenerator.randomBytes(32);
|
|
1335
|
+
const encryptedDataStream = yield Encryption.aes256CtrEncrypt(dataEncryptionKey, dataEncryptionInitializationVector, originalDataStream);
|
|
1336
|
+
const encryptedDataBytes = yield DataStream.toBytes(encryptedDataStream);
|
|
1337
|
+
const rootPrivateKeyWithSchemasScheme = {
|
|
1338
|
+
rootKeyId: alice.keyId,
|
|
1339
|
+
derivationScheme: KeyDerivationScheme.Schemas,
|
|
1340
|
+
derivedPrivateKey: alice.keyPair.privateJwk
|
|
1341
|
+
};
|
|
1342
|
+
const schema = 'https://some-schema.com';
|
|
1343
|
+
const schemaDerivationPath = Records.constructKeyDerivationPathUsingSchemasScheme(schema);
|
|
1344
|
+
const schemaDerivedPrivateKey = yield HdKey.derivePrivateKey(rootPrivateKeyWithSchemasScheme, schemaDerivationPath);
|
|
1345
|
+
const schemaDerivedPublicKey = yield Secp256k1.getPublicJwk(schemaDerivedPrivateKey.derivedPrivateKey);
|
|
1346
|
+
const rootPrivateKeyWithDataFormatsScheme = {
|
|
1347
|
+
rootKeyId: alice.keyId,
|
|
1348
|
+
derivationScheme: KeyDerivationScheme.DataFormats,
|
|
1349
|
+
derivedPrivateKey: alice.keyPair.privateJwk
|
|
1350
|
+
};
|
|
1351
|
+
const dataFormat = 'some/format';
|
|
1352
|
+
const dataFormatDerivationPath = Records.constructKeyDerivationPathUsingDataFormatsScheme(schema, dataFormat);
|
|
1353
|
+
const dataFormatDerivedPublicKey = yield HdKey.derivePublicKey(rootPrivateKeyWithDataFormatsScheme, dataFormatDerivationPath);
|
|
1354
|
+
const encryptionInput = {
|
|
1355
|
+
initializationVector: dataEncryptionInitializationVector,
|
|
1356
|
+
key: dataEncryptionKey,
|
|
1357
|
+
keyEncryptionInputs: [{
|
|
1358
|
+
publicKeyId: alice.keyId, // reusing signing key for encryption purely as a convenience
|
|
1359
|
+
publicKey: schemaDerivedPublicKey,
|
|
1360
|
+
derivationScheme: KeyDerivationScheme.Schemas
|
|
1361
|
+
},
|
|
1362
|
+
{
|
|
1363
|
+
publicKeyId: alice.keyId, // reusing signing key for encryption purely as a convenience
|
|
1364
|
+
publicKey: dataFormatDerivedPublicKey,
|
|
1365
|
+
derivationScheme: KeyDerivationScheme.DataFormats
|
|
1366
|
+
}]
|
|
1367
|
+
};
|
|
1368
|
+
const { message, dataStream } = yield TestDataGenerator.generateRecordsWrite({
|
|
1369
|
+
author: alice,
|
|
1370
|
+
schema,
|
|
1371
|
+
dataFormat,
|
|
1372
|
+
data: encryptedDataBytes,
|
|
1373
|
+
encryptionInput
|
|
1374
|
+
});
|
|
1375
|
+
const writeReply = yield dwn.processMessage(alice.did, message, dataStream);
|
|
1376
|
+
expect(writeReply.status.code).to.equal(202);
|
|
1377
|
+
const recordsRead = yield RecordsRead.create({
|
|
1378
|
+
filter: {
|
|
1379
|
+
recordId: message.recordId,
|
|
1380
|
+
},
|
|
1381
|
+
signer: Jws.createSigner(alice)
|
|
1382
|
+
});
|
|
1383
|
+
// test able to derive correct key using `schemas` scheme from root key to decrypt the message
|
|
1384
|
+
const readReply = yield dwn.processMessage(alice.did, recordsRead.message);
|
|
1385
|
+
expect(readReply.status.code).to.equal(200);
|
|
1386
|
+
const recordsWriteMessage = readReply.record;
|
|
1387
|
+
const cipherStream = readReply.record.data;
|
|
1388
|
+
const plaintextDataStream = yield Records.decrypt(recordsWriteMessage, schemaDerivedPrivateKey, cipherStream);
|
|
1389
|
+
const plaintextBytes = yield DataStream.toBytes(plaintextDataStream);
|
|
1390
|
+
expect(ArrayUtility.byteArraysEqual(plaintextBytes, originalData)).to.be.true;
|
|
1391
|
+
// test able to derive correct key using `dataFormat` scheme from root key to decrypt the message
|
|
1392
|
+
const readReply2 = yield dwn.processMessage(alice.did, recordsRead.message); // send the same read message to get a new cipher stream
|
|
1393
|
+
expect(readReply2.status.code).to.equal(200);
|
|
1394
|
+
const cipherStream2 = readReply2.record.data;
|
|
1395
|
+
const plaintextDataStream2 = yield Records.decrypt(recordsWriteMessage, rootPrivateKeyWithDataFormatsScheme, cipherStream2);
|
|
1396
|
+
const plaintextBytes2 = yield DataStream.toBytes(plaintextDataStream2);
|
|
1397
|
+
expect(ArrayUtility.byteArraysEqual(plaintextBytes2, originalData)).to.be.true;
|
|
1398
|
+
// test unable to decrypt the message if dataFormat-derived key is derived without taking `schema` as input to derivation path
|
|
1399
|
+
const readReply3 = yield dwn.processMessage(alice.did, recordsRead.message); // process the same read message to get a new cipher stream
|
|
1400
|
+
expect(readReply3.status.code).to.equal(200);
|
|
1401
|
+
const cipherStream3 = readReply3.record.data;
|
|
1402
|
+
const invalidDerivationPath = [KeyDerivationScheme.DataFormats, message.descriptor.dataFormat];
|
|
1403
|
+
const inValidDescendantPrivateKey = yield HdKey.derivePrivateKey(rootPrivateKeyWithDataFormatsScheme, invalidDerivationPath);
|
|
1404
|
+
yield expect(Records.decrypt(recordsWriteMessage, inValidDescendantPrivateKey, cipherStream3)).to.be.rejectedWith(DwnErrorCode.RecordsInvalidAncestorKeyDerivationSegment);
|
|
1405
|
+
}));
|
|
1406
|
+
it('should be able to decrypt flat-space schema-less record with the correct derived key', () => __awaiter(this, void 0, void 0, function* () {
|
|
1407
|
+
// scenario: Alice writes into her own DWN an encrypted record and she is able to decrypt it
|
|
1408
|
+
const alice = yield TestDataGenerator.generatePersona();
|
|
1409
|
+
TestStubGenerator.stubDidResolver(didResolver, [alice]);
|
|
1410
|
+
// encrypt Alice's record
|
|
1411
|
+
const originalData = TestDataGenerator.randomBytes(1000);
|
|
1412
|
+
const originalDataStream = DataStream.fromBytes(originalData);
|
|
1413
|
+
const dataEncryptionInitializationVector = TestDataGenerator.randomBytes(16);
|
|
1414
|
+
const dataEncryptionKey = TestDataGenerator.randomBytes(32);
|
|
1415
|
+
const encryptedDataStream = yield Encryption.aes256CtrEncrypt(dataEncryptionKey, dataEncryptionInitializationVector, originalDataStream);
|
|
1416
|
+
const encryptedDataBytes = yield DataStream.toBytes(encryptedDataStream);
|
|
1417
|
+
const rootPrivateKeyWithDataFormatsScheme = {
|
|
1418
|
+
rootKeyId: alice.keyId,
|
|
1419
|
+
derivationScheme: KeyDerivationScheme.DataFormats,
|
|
1420
|
+
derivedPrivateKey: alice.keyPair.privateJwk
|
|
1421
|
+
};
|
|
1422
|
+
const dataFormat = `image/jpg`;
|
|
1423
|
+
const dataFormatDerivationPath = Records.constructKeyDerivationPathUsingDataFormatsScheme(undefined, dataFormat);
|
|
1424
|
+
const dataFormatDerivedPublicKey = yield HdKey.derivePublicKey(rootPrivateKeyWithDataFormatsScheme, dataFormatDerivationPath);
|
|
1425
|
+
const encryptionInput = {
|
|
1426
|
+
initializationVector: dataEncryptionInitializationVector,
|
|
1427
|
+
key: dataEncryptionKey,
|
|
1428
|
+
keyEncryptionInputs: [{
|
|
1429
|
+
publicKeyId: alice.keyId, // reusing signing key for encryption purely as a convenience
|
|
1430
|
+
publicKey: dataFormatDerivedPublicKey,
|
|
1431
|
+
derivationScheme: KeyDerivationScheme.DataFormats
|
|
1432
|
+
}]
|
|
1433
|
+
};
|
|
1434
|
+
const recordsWrite = yield RecordsWrite.create({
|
|
1435
|
+
signer: Jws.createSigner(alice),
|
|
1436
|
+
dataFormat,
|
|
1437
|
+
data: encryptedDataBytes,
|
|
1438
|
+
encryptionInput
|
|
1439
|
+
});
|
|
1440
|
+
const dataStream = DataStream.fromBytes(encryptedDataBytes);
|
|
1441
|
+
const writeReply = yield dwn.processMessage(alice.did, recordsWrite.message, dataStream);
|
|
1442
|
+
expect(writeReply.status.code).to.equal(202);
|
|
1443
|
+
const recordsRead = yield RecordsRead.create({
|
|
1444
|
+
filter: {
|
|
1445
|
+
recordId: recordsWrite.message.recordId,
|
|
1446
|
+
},
|
|
1447
|
+
signer: Jws.createSigner(alice)
|
|
1448
|
+
});
|
|
1449
|
+
// test able to derive correct key using `dataFormat` scheme from root key to decrypt the message
|
|
1450
|
+
const readReply = yield dwn.processMessage(alice.did, recordsRead.message); // send the same read message to get a new cipher stream
|
|
1451
|
+
expect(readReply.status.code).to.equal(200);
|
|
1452
|
+
const cipherStream = readReply.record.data;
|
|
1453
|
+
const recordsWriteMessage = readReply.record;
|
|
1454
|
+
const plaintextDataStream = yield Records.decrypt(recordsWriteMessage, rootPrivateKeyWithDataFormatsScheme, cipherStream);
|
|
1455
|
+
const plaintextBytes = yield DataStream.toBytes(plaintextDataStream);
|
|
1456
|
+
expect(ArrayUtility.byteArraysEqual(plaintextBytes, originalData)).to.be.true;
|
|
1457
|
+
}));
|
|
1458
|
+
it('should only be able to decrypt record with a correct derived private key - `protocol-context` derivation scheme', () => __awaiter(this, void 0, void 0, function* () {
|
|
1459
|
+
// scenario: Bob initiated an encrypted chat thread with Alice,
|
|
1460
|
+
// bob is able to decrypt subsequent messages from Alice using the `protocol-context` derived private key
|
|
1461
|
+
// creating Alice and Bob persona and setting up a stub DID resolver
|
|
1462
|
+
const alice = yield TestDataGenerator.generatePersona();
|
|
1463
|
+
const bob = yield TestDataGenerator.generatePersona();
|
|
1464
|
+
TestStubGenerator.stubDidResolver(didResolver, [alice, bob]);
|
|
1465
|
+
// Alice configures chat protocol with encryption
|
|
1466
|
+
const protocolDefinition = chatProtocolDefinition;
|
|
1467
|
+
const protocolDefinitionForAlice = yield Protocols.deriveAndInjectPublicEncryptionKeys(protocolDefinition, alice.keyId, alice.keyPair.privateJwk);
|
|
1468
|
+
const protocolsConfigureForAlice = yield TestDataGenerator.generateProtocolsConfigure({
|
|
1469
|
+
author: alice,
|
|
1470
|
+
protocolDefinition: protocolDefinitionForAlice
|
|
1471
|
+
});
|
|
1472
|
+
const protocolsConfigureForAliceReply = yield dwn.processMessage(alice.did, protocolsConfigureForAlice.message);
|
|
1473
|
+
expect(protocolsConfigureForAliceReply.status.code).to.equal(202);
|
|
1474
|
+
// Bob configures chat protocol with encryption
|
|
1475
|
+
const protocolDefinitionForBob = yield Protocols.deriveAndInjectPublicEncryptionKeys(protocolDefinition, bob.keyId, bob.keyPair.privateJwk);
|
|
1476
|
+
const protocolsConfigureForBob = yield TestDataGenerator.generateProtocolsConfigure({
|
|
1477
|
+
author: bob,
|
|
1478
|
+
protocolDefinition: protocolDefinitionForBob
|
|
1479
|
+
});
|
|
1480
|
+
const protocolsConfigureReply = yield dwn.processMessage(bob.did, protocolsConfigureForBob.message);
|
|
1481
|
+
expect(protocolsConfigureReply.status.code).to.equal(202);
|
|
1482
|
+
// Bob queries for Alice's chat protocol definition
|
|
1483
|
+
const protocolsQuery = yield ProtocolsQuery.create({
|
|
1484
|
+
filter: { protocol: chatProtocolDefinition.protocol }
|
|
1485
|
+
});
|
|
1486
|
+
const protocolsQueryReply = yield dwn.processMessage(alice.did, protocolsQuery.message);
|
|
1487
|
+
const protocolsConfigureMessageReceived = protocolsQueryReply.entries[0];
|
|
1488
|
+
// Bob verifies that the chat protocol definition is authored by Alice
|
|
1489
|
+
yield authenticate(protocolsConfigureMessageReceived.authorization, didResolver);
|
|
1490
|
+
const protocolsConfigureFetched = yield ProtocolsConfigure.parse(protocolsConfigureMessageReceived);
|
|
1491
|
+
expect(protocolsConfigureFetched.author).to.equal(alice.did);
|
|
1492
|
+
// Bob creates an initiating a chat thread RecordsWrite
|
|
1493
|
+
const plaintextMessageToAlice = TestDataGenerator.randomBytes(100);
|
|
1494
|
+
const { message, dataStream, recordsWrite, encryptedDataBytes, encryptionInput } = yield TestDataGenerator.generateProtocolEncryptedRecordsWrite({
|
|
1495
|
+
plaintextBytes: plaintextMessageToAlice,
|
|
1496
|
+
author: bob,
|
|
1497
|
+
protocolDefinition: protocolsConfigureForAlice.message.descriptor.definition,
|
|
1498
|
+
protocolPath: 'thread',
|
|
1499
|
+
encryptSymmetricKeyWithProtocolPathDerivedKey: true,
|
|
1500
|
+
encryptSymmetricKeyWithProtocolContextDerivedKey: true
|
|
1501
|
+
});
|
|
1502
|
+
// Bob writes the encrypted chat thread to Alice's DWN
|
|
1503
|
+
const bobToAliceWriteReply = yield dwn.processMessage(alice.did, message, dataStream);
|
|
1504
|
+
expect(bobToAliceWriteReply.status.code).to.equal(202);
|
|
1505
|
+
// Bob also needs to write the same encrypted chat thread to his own DWN
|
|
1506
|
+
// Opportunity here to create a much nicer utility method for this entire block
|
|
1507
|
+
const bobToBobRecordsWrite = yield RecordsWrite.createFrom({
|
|
1508
|
+
recordsWriteMessage: recordsWrite.message,
|
|
1509
|
+
messageTimestamp: recordsWrite.message.descriptor.messageTimestamp
|
|
1510
|
+
});
|
|
1511
|
+
const bobRootPrivateKey = {
|
|
1512
|
+
rootKeyId: bob.keyId,
|
|
1513
|
+
derivationScheme: KeyDerivationScheme.ProtocolContext,
|
|
1514
|
+
derivedPrivateKey: bob.keyPair.privateJwk
|
|
1515
|
+
};
|
|
1516
|
+
const protocolPathDerivationPath = Records.constructKeyDerivationPathUsingProtocolPathScheme(recordsWrite.message.descriptor);
|
|
1517
|
+
const protocolPathDerivedPublicJwkForBobsDwn = yield HdKey.derivePublicKey(bobRootPrivateKey, protocolPathDerivationPath);
|
|
1518
|
+
const protocolPathDerivedKeyEncryptionInputForBobsDwn = {
|
|
1519
|
+
publicKeyId: bob.keyId, // reusing signing key for encryption purely as a convenience
|
|
1520
|
+
publicKey: protocolPathDerivedPublicJwkForBobsDwn,
|
|
1521
|
+
derivationScheme: KeyDerivationScheme.ProtocolPath
|
|
1522
|
+
};
|
|
1523
|
+
const encryptionInputForBobsDwn = encryptionInput;
|
|
1524
|
+
const indexOfKeyEncryptionInputToReplace = encryptionInputForBobsDwn.keyEncryptionInputs.findIndex(input => input.derivationScheme === KeyDerivationScheme.ProtocolPath);
|
|
1525
|
+
encryptionInputForBobsDwn.keyEncryptionInputs[indexOfKeyEncryptionInputToReplace] = protocolPathDerivedKeyEncryptionInputForBobsDwn;
|
|
1526
|
+
yield bobToBobRecordsWrite.encryptSymmetricEncryptionKey(encryptionInputForBobsDwn);
|
|
1527
|
+
yield bobToBobRecordsWrite.sign({ signer: Jws.createSigner(bob) });
|
|
1528
|
+
const dataStreamForBobsDwn = DataStream.fromBytes(encryptedDataBytes);
|
|
1529
|
+
const bobToBobWriteReply = yield dwn.processMessage(bob.did, bobToBobRecordsWrite.message, dataStreamForBobsDwn);
|
|
1530
|
+
expect(bobToBobWriteReply.status.code).to.equal(202);
|
|
1531
|
+
// NOTE: we know Alice is able to decrypt the message using protocol-path derived key through other tests, so we won't verify it again
|
|
1532
|
+
// test that anyone with the protocol-context derived private key is able to decrypt the message
|
|
1533
|
+
const recordsRead = yield RecordsRead.create({
|
|
1534
|
+
filter: {
|
|
1535
|
+
recordId: message.recordId,
|
|
1536
|
+
},
|
|
1537
|
+
signer: Jws.createSigner(alice)
|
|
1538
|
+
});
|
|
1539
|
+
const readReply = yield dwn.processMessage(alice.did, recordsRead.message);
|
|
1540
|
+
expect(readReply.status.code).to.equal(200);
|
|
1541
|
+
const fetchedRecordsWrite = readReply.record;
|
|
1542
|
+
const cipherStream = readReply.record.data;
|
|
1543
|
+
const derivationPathFromReadContext = Records.constructKeyDerivationPathUsingProtocolContextScheme(fetchedRecordsWrite.contextId);
|
|
1544
|
+
const protocolContextDerivedPrivateJwk = yield HdKey.derivePrivateKey(bobRootPrivateKey, derivationPathFromReadContext);
|
|
1545
|
+
const plaintextDataStream = yield Records.decrypt(fetchedRecordsWrite, protocolContextDerivedPrivateJwk, cipherStream);
|
|
1546
|
+
const plaintextBytes = yield DataStream.toBytes(plaintextDataStream);
|
|
1547
|
+
expect(ArrayUtility.byteArraysEqual(plaintextBytes, plaintextMessageToAlice)).to.be.true;
|
|
1548
|
+
// verify that Alice is able to send an encrypted message using the protocol-context derived public key and Bob is able to decrypt it
|
|
1549
|
+
// NOTE: we will skip verification of Bob's protocol configuration because we have test the such scenario above as well as in other tests
|
|
1550
|
+
const { derivedPublicKey: protocolContextDerivedPublicJwkReturned, rootKeyId: protocolContextDerivingRootKeyIdReturned } = fetchedRecordsWrite.encryption.keyEncryption.find(encryptedKey => encryptedKey.derivationScheme === KeyDerivationScheme.ProtocolContext);
|
|
1551
|
+
const plaintextMessageToBob = TestDataGenerator.randomBytes(100);
|
|
1552
|
+
const recordsWriteToBob = yield TestDataGenerator.generateProtocolEncryptedRecordsWrite({
|
|
1553
|
+
plaintextBytes: plaintextMessageToBob,
|
|
1554
|
+
author: alice,
|
|
1555
|
+
protocolDefinition: protocolsConfigureForBob.message.descriptor.definition,
|
|
1556
|
+
protocolPath: 'thread/message',
|
|
1557
|
+
protocolContextId: fetchedRecordsWrite.contextId,
|
|
1558
|
+
protocolContextDerivingRootKeyId: protocolContextDerivingRootKeyIdReturned,
|
|
1559
|
+
protocolContextDerivedPublicJwk: protocolContextDerivedPublicJwkReturned,
|
|
1560
|
+
protocolParentId: fetchedRecordsWrite.recordId,
|
|
1561
|
+
encryptSymmetricKeyWithProtocolPathDerivedKey: true,
|
|
1562
|
+
encryptSymmetricKeyWithProtocolContextDerivedKey: true
|
|
1563
|
+
});
|
|
1564
|
+
// Alice sends the message to Bob
|
|
1565
|
+
const aliceWriteReply = yield dwn.processMessage(bob.did, recordsWriteToBob.message, recordsWriteToBob.dataStream);
|
|
1566
|
+
expect(aliceWriteReply.status.code).to.equal(202);
|
|
1567
|
+
// test that Bob is able to read and decrypt Alice's message
|
|
1568
|
+
const recordsReadByBob = yield RecordsRead.create({
|
|
1569
|
+
filter: {
|
|
1570
|
+
recordId: recordsWriteToBob.message.recordId,
|
|
1571
|
+
},
|
|
1572
|
+
signer: Jws.createSigner(bob)
|
|
1573
|
+
});
|
|
1574
|
+
const readByBobReply = yield dwn.processMessage(bob.did, recordsReadByBob.message);
|
|
1575
|
+
expect(readByBobReply.status.code).to.equal(200);
|
|
1576
|
+
const fetchedRecordsWrite2 = readByBobReply.record;
|
|
1577
|
+
const cipherStream2 = readByBobReply.record.data;
|
|
1578
|
+
const plaintextDataStream2 = yield Records.decrypt(fetchedRecordsWrite2, protocolContextDerivedPrivateJwk, cipherStream2);
|
|
1579
|
+
const plaintextBytes2 = yield DataStream.toBytes(plaintextDataStream2);
|
|
1580
|
+
expect(ArrayUtility.byteArraysEqual(plaintextBytes2, plaintextMessageToBob)).to.be.true;
|
|
1581
|
+
}));
|
|
1582
|
+
it('should only be able to decrypt record with a correct derived private key - `protocols` derivation scheme', () => __awaiter(this, void 0, void 0, function* () {
|
|
1583
|
+
// scenario: Bob writes into Alice's DWN an encrypted "email", alice is able to decrypt it
|
|
1584
|
+
var _a;
|
|
1585
|
+
// creating Alice and Bob persona and setting up a stub DID resolver
|
|
1586
|
+
const alice = yield TestDataGenerator.generatePersona();
|
|
1587
|
+
const bob = yield TestDataGenerator.generatePersona();
|
|
1588
|
+
TestStubGenerator.stubDidResolver(didResolver, [alice, bob]);
|
|
1589
|
+
// Alice configures email protocol with encryption
|
|
1590
|
+
const protocolDefinition = emailProtocolDefinition;
|
|
1591
|
+
const encryptedProtocolDefinition = yield Protocols.deriveAndInjectPublicEncryptionKeys(protocolDefinition, alice.keyId, alice.keyPair.privateJwk);
|
|
1592
|
+
const protocolsConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
1593
|
+
author: alice,
|
|
1594
|
+
protocolDefinition: encryptedProtocolDefinition
|
|
1595
|
+
});
|
|
1596
|
+
const protocolsConfigureReply = yield dwn.processMessage(alice.did, protocolsConfigure.message);
|
|
1597
|
+
expect(protocolsConfigureReply.status.code).to.equal(202);
|
|
1598
|
+
// Bob queries for Alice's email protocol definition
|
|
1599
|
+
const protocolsQuery = yield ProtocolsQuery.create({
|
|
1600
|
+
filter: { protocol: emailProtocolDefinition.protocol }
|
|
1601
|
+
});
|
|
1602
|
+
const protocolsQueryReply = yield dwn.processMessage(alice.did, protocolsQuery.message);
|
|
1603
|
+
const protocolsConfigureMessageReceived = protocolsQueryReply.entries[0];
|
|
1604
|
+
// Bob verifies that the email protocol definition is authored by Alice
|
|
1605
|
+
yield authenticate(protocolsConfigureMessageReceived.authorization, didResolver);
|
|
1606
|
+
const protocolsConfigureFetched = yield ProtocolsConfigure.parse(protocolsConfigureMessageReceived);
|
|
1607
|
+
expect(protocolsConfigureFetched.author).to.equal(alice.did);
|
|
1608
|
+
// Bob encrypts his email to Alice with a randomly generated symmetric key
|
|
1609
|
+
const bobMessageBytes = TestDataGenerator.randomBytes(100);
|
|
1610
|
+
const bobMessageStream = DataStream.fromBytes(bobMessageBytes);
|
|
1611
|
+
const dataEncryptionInitializationVector = TestDataGenerator.randomBytes(16);
|
|
1612
|
+
const dataEncryptionKey = TestDataGenerator.randomBytes(32);
|
|
1613
|
+
const bobMessageEncryptedStream = yield Encryption.aes256CtrEncrypt(dataEncryptionKey, dataEncryptionInitializationVector, bobMessageStream);
|
|
1614
|
+
const bobMessageEncryptedBytes = yield DataStream.toBytes(bobMessageEncryptedStream);
|
|
1615
|
+
// Bob generates an encrypted RecordsWrite,
|
|
1616
|
+
// the public encryption key designated by Alice is used to encrypt the symmetric key Bob generated above
|
|
1617
|
+
const publicJwk = (_a = protocolsConfigureFetched.message.descriptor.definition.structure.email.$encryption) === null || _a === void 0 ? void 0 : _a.publicKeyJwk;
|
|
1618
|
+
expect(publicJwk).to.not.be.undefined;
|
|
1619
|
+
const encryptionInput = {
|
|
1620
|
+
initializationVector: dataEncryptionInitializationVector,
|
|
1621
|
+
key: dataEncryptionKey,
|
|
1622
|
+
keyEncryptionInputs: [{
|
|
1623
|
+
publicKeyId: alice.keyId, // reusing signing key for encryption purely as a convenience
|
|
1624
|
+
publicKey: publicJwk,
|
|
1625
|
+
derivationScheme: KeyDerivationScheme.ProtocolPath
|
|
1626
|
+
}]
|
|
1627
|
+
};
|
|
1628
|
+
const { message, dataStream } = yield TestDataGenerator.generateRecordsWrite({
|
|
1629
|
+
author: bob,
|
|
1630
|
+
protocol: protocolDefinition.protocol,
|
|
1631
|
+
protocolPath: 'email', // this comes from `types` in protocol definition
|
|
1632
|
+
schema: protocolDefinition.types.email.schema,
|
|
1633
|
+
dataFormat: protocolDefinition.types.email.dataFormats[0],
|
|
1634
|
+
data: bobMessageEncryptedBytes,
|
|
1635
|
+
encryptionInput
|
|
1636
|
+
});
|
|
1637
|
+
// Bob writes the encrypted email to Alice's DWN
|
|
1638
|
+
const bobWriteReply = yield dwn.processMessage(alice.did, message, dataStream);
|
|
1639
|
+
expect(bobWriteReply.status.code).to.equal(202);
|
|
1640
|
+
// Alice reads the encrypted email
|
|
1641
|
+
// assume Alice already made query to get the `recordId` of the email
|
|
1642
|
+
const recordsRead = yield RecordsRead.create({
|
|
1643
|
+
filter: {
|
|
1644
|
+
recordId: message.recordId,
|
|
1645
|
+
},
|
|
1646
|
+
signer: Jws.createSigner(alice)
|
|
1647
|
+
});
|
|
1648
|
+
const readReply = yield dwn.processMessage(alice.did, recordsRead.message);
|
|
1649
|
+
expect(readReply.status.code).to.equal(200);
|
|
1650
|
+
// test that Alice is able decrypt the encrypted email from Bob using the root key
|
|
1651
|
+
const rootPrivateKey = {
|
|
1652
|
+
rootKeyId: alice.keyId,
|
|
1653
|
+
derivationScheme: KeyDerivationScheme.ProtocolPath,
|
|
1654
|
+
derivedPrivateKey: alice.keyPair.privateJwk
|
|
1655
|
+
};
|
|
1656
|
+
const fetchedRecordsWrite = readReply.record;
|
|
1657
|
+
const cipherStream = readReply.record.data;
|
|
1658
|
+
const plaintextDataStream = yield Records.decrypt(fetchedRecordsWrite, rootPrivateKey, cipherStream);
|
|
1659
|
+
const plaintextBytes = yield DataStream.toBytes(plaintextDataStream);
|
|
1660
|
+
expect(ArrayUtility.byteArraysEqual(plaintextBytes, bobMessageBytes)).to.be.true;
|
|
1661
|
+
// test that a correct derived key is able decrypt the encrypted email from Bob
|
|
1662
|
+
const readReply2 = yield dwn.processMessage(alice.did, recordsRead.message);
|
|
1663
|
+
expect(readReply2.status.code).to.equal(200);
|
|
1664
|
+
const relativeDescendantDerivationPath = Records.constructKeyDerivationPath(KeyDerivationScheme.ProtocolPath, fetchedRecordsWrite);
|
|
1665
|
+
const derivedPrivateKey = yield HdKey.derivePrivateKey(rootPrivateKey, relativeDescendantDerivationPath);
|
|
1666
|
+
const fetchedRecordsWrite2 = readReply2.record;
|
|
1667
|
+
const cipherStream2 = readReply2.record.data;
|
|
1668
|
+
const plaintextDataStream2 = yield Records.decrypt(fetchedRecordsWrite2, derivedPrivateKey, cipherStream2);
|
|
1669
|
+
const plaintextBytes2 = yield DataStream.toBytes(plaintextDataStream2);
|
|
1670
|
+
expect(ArrayUtility.byteArraysEqual(plaintextBytes2, bobMessageBytes)).to.be.true;
|
|
1671
|
+
// test unable to decrypt the message if derived key has an unexpected path
|
|
1672
|
+
const invalidDerivationPath = [KeyDerivationScheme.ProtocolPath, protocolDefinition.protocol, 'invalidContextId'];
|
|
1673
|
+
const inValidDescendantPrivateKey = yield HdKey.derivePrivateKey(rootPrivateKey, invalidDerivationPath);
|
|
1674
|
+
yield expect(Records.decrypt(fetchedRecordsWrite, inValidDescendantPrivateKey, cipherStream)).to.be.rejectedWith(DwnErrorCode.RecordsInvalidAncestorKeyDerivationSegment);
|
|
1675
|
+
// test unable to decrypt the message if no derivation scheme used by the message matches the scheme used by the given private key
|
|
1676
|
+
const privateKeyWithMismatchingDerivationScheme = {
|
|
1677
|
+
rootKeyId: alice.keyId,
|
|
1678
|
+
derivationScheme: 'scheme-that-is-not-protocol-context',
|
|
1679
|
+
derivedPrivateKey: alice.keyPair.privateJwk
|
|
1680
|
+
};
|
|
1681
|
+
yield expect(Records.decrypt(fetchedRecordsWrite, privateKeyWithMismatchingDerivationScheme, cipherStream)).to.be.rejectedWith(DwnErrorCode.RecordsDecryptNoMatchingKeyEncryptedFound);
|
|
1682
|
+
// test unable to decrypt the message if public key ID does not match the derived private key
|
|
1683
|
+
const privateKeyWithMismatchingKeyId = {
|
|
1684
|
+
rootKeyId: 'mismatchingKeyId',
|
|
1685
|
+
derivationScheme: KeyDerivationScheme.ProtocolPath,
|
|
1686
|
+
derivedPrivateKey: alice.keyPair.privateJwk
|
|
1687
|
+
};
|
|
1688
|
+
yield expect(Records.decrypt(fetchedRecordsWrite, privateKeyWithMismatchingKeyId, cipherStream)).to.be.rejectedWith(DwnErrorCode.RecordsDecryptNoMatchingKeyEncryptedFound);
|
|
1689
|
+
}));
|
|
1690
|
+
});
|
|
1691
|
+
});
|
|
1692
|
+
it('should return 401 if signature check fails', () => __awaiter(this, void 0, void 0, function* () {
|
|
1693
|
+
const alice = yield DidKeyResolver.generate();
|
|
1694
|
+
const recordsRead = yield RecordsRead.create({
|
|
1695
|
+
filter: {
|
|
1696
|
+
recordId: 'any-id',
|
|
1697
|
+
},
|
|
1698
|
+
signer: Jws.createSigner(alice)
|
|
1699
|
+
});
|
|
1700
|
+
// setting up a stub did resolver & message store
|
|
1701
|
+
// intentionally not supplying the public key so a different public key is generated to simulate invalid signature
|
|
1702
|
+
const mismatchingPersona = yield TestDataGenerator.generatePersona({ did: alice.did, keyId: alice.keyId });
|
|
1703
|
+
const didResolver = TestStubGenerator.createDidResolverStub(mismatchingPersona);
|
|
1704
|
+
const messageStore = stubInterface();
|
|
1705
|
+
const dataStore = stubInterface();
|
|
1706
|
+
const recordsReadHandler = new RecordsReadHandler(didResolver, messageStore, dataStore);
|
|
1707
|
+
const reply = yield recordsReadHandler.handle({ tenant: alice.did, message: recordsRead.message });
|
|
1708
|
+
expect(reply.status.code).to.equal(401);
|
|
1709
|
+
}));
|
|
1710
|
+
it('should return 400 if fail parsing the message', () => __awaiter(this, void 0, void 0, function* () {
|
|
1711
|
+
const alice = yield DidKeyResolver.generate();
|
|
1712
|
+
const recordsRead = yield RecordsRead.create({
|
|
1713
|
+
filter: {
|
|
1714
|
+
recordId: 'any-id',
|
|
1715
|
+
},
|
|
1716
|
+
signer: Jws.createSigner(alice)
|
|
1717
|
+
});
|
|
1718
|
+
// setting up a stub method resolver & message store
|
|
1719
|
+
const messageStore = stubInterface();
|
|
1720
|
+
const dataStore = stubInterface();
|
|
1721
|
+
const recordsReadHandler = new RecordsReadHandler(didResolver, messageStore, dataStore);
|
|
1722
|
+
// stub the `parse()` function to throw an error
|
|
1723
|
+
sinon.stub(RecordsRead, 'parse').throws('anyError');
|
|
1724
|
+
const reply = yield recordsReadHandler.handle({ tenant: alice.did, message: recordsRead.message });
|
|
1725
|
+
expect(reply.status.code).to.equal(400);
|
|
1726
|
+
}));
|
|
1727
|
+
});
|
|
1728
|
+
}
|
|
1729
|
+
//# sourceMappingURL=records-read.spec.js.map
|