@enbox/agent 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.js +2215 -0
- package/dist/browser.js.map +7 -0
- package/dist/browser.mjs +2215 -0
- package/dist/browser.mjs.map +7 -0
- package/dist/cjs/index.js +8530 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/package.json +1 -0
- package/dist/esm/agent-did-resolver-cache.js +87 -0
- package/dist/esm/agent-did-resolver-cache.js.map +1 -0
- package/dist/esm/bearer-identity.js +41 -0
- package/dist/esm/bearer-identity.js.map +1 -0
- package/dist/esm/connect.js +191 -0
- package/dist/esm/connect.js.map +1 -0
- package/dist/esm/crypto-api.js +346 -0
- package/dist/esm/crypto-api.js.map +1 -0
- package/dist/esm/did-api.js +278 -0
- package/dist/esm/did-api.js.map +1 -0
- package/dist/esm/dwn-api.js +336 -0
- package/dist/esm/dwn-api.js.map +1 -0
- package/dist/esm/dwn-registrar.js +120 -0
- package/dist/esm/dwn-registrar.js.map +1 -0
- package/dist/esm/hd-identity-vault.js +729 -0
- package/dist/esm/hd-identity-vault.js.map +1 -0
- package/dist/esm/identity-api.js +262 -0
- package/dist/esm/identity-api.js.map +1 -0
- package/dist/esm/index.js +23 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/local-key-manager.js +498 -0
- package/dist/esm/local-key-manager.js.map +1 -0
- package/dist/esm/oidc.js +507 -0
- package/dist/esm/oidc.js.map +1 -0
- package/dist/esm/permissions-api.js +322 -0
- package/dist/esm/permissions-api.js.map +1 -0
- package/dist/esm/prototyping/clients/dwn-rpc-types.js +2 -0
- package/dist/esm/prototyping/clients/dwn-rpc-types.js.map +1 -0
- package/dist/esm/prototyping/clients/dwn-server-info-cache-memory.js +74 -0
- package/dist/esm/prototyping/clients/dwn-server-info-cache-memory.js.map +1 -0
- package/dist/esm/prototyping/clients/http-dwn-rpc-client.js +105 -0
- package/dist/esm/prototyping/clients/http-dwn-rpc-client.js.map +1 -0
- package/dist/esm/prototyping/clients/json-rpc-socket.js +150 -0
- package/dist/esm/prototyping/clients/json-rpc-socket.js.map +1 -0
- package/dist/esm/prototyping/clients/json-rpc.js +58 -0
- package/dist/esm/prototyping/clients/json-rpc.js.map +1 -0
- package/dist/esm/prototyping/clients/server-info-types.js +2 -0
- package/dist/esm/prototyping/clients/server-info-types.js.map +1 -0
- package/dist/esm/prototyping/clients/web-socket-clients.js +90 -0
- package/dist/esm/prototyping/clients/web-socket-clients.js.map +1 -0
- package/dist/esm/prototyping/common/object.js +14 -0
- package/dist/esm/prototyping/common/object.js.map +1 -0
- package/dist/esm/prototyping/common/type-utils.js +2 -0
- package/dist/esm/prototyping/common/type-utils.js.map +1 -0
- package/dist/esm/prototyping/crypto/algorithms/aes-gcm.js +147 -0
- package/dist/esm/prototyping/crypto/algorithms/aes-gcm.js.map +1 -0
- package/dist/esm/prototyping/crypto/algorithms/aes-kw.js +137 -0
- package/dist/esm/prototyping/crypto/algorithms/aes-kw.js.map +1 -0
- package/dist/esm/prototyping/crypto/algorithms/ecdsa.js +307 -0
- package/dist/esm/prototyping/crypto/algorithms/ecdsa.js.map +1 -0
- package/dist/esm/prototyping/crypto/algorithms/eddsa.js +264 -0
- package/dist/esm/prototyping/crypto/algorithms/eddsa.js.map +1 -0
- package/dist/esm/prototyping/crypto/algorithms/hkdf.js +39 -0
- package/dist/esm/prototyping/crypto/algorithms/hkdf.js.map +1 -0
- package/dist/esm/prototyping/crypto/algorithms/pbkdf2.js +41 -0
- package/dist/esm/prototyping/crypto/algorithms/pbkdf2.js.map +1 -0
- package/dist/esm/prototyping/crypto/crypto-error.js +41 -0
- package/dist/esm/prototyping/crypto/crypto-error.js.map +1 -0
- package/dist/esm/prototyping/crypto/dsa.js +236 -0
- package/dist/esm/prototyping/crypto/dsa.js.map +1 -0
- package/dist/esm/prototyping/crypto/jose/jwe-compact.js +130 -0
- package/dist/esm/prototyping/crypto/jose/jwe-compact.js.map +1 -0
- package/dist/esm/prototyping/crypto/jose/jwe-flattened.js +294 -0
- package/dist/esm/prototyping/crypto/jose/jwe-flattened.js.map +1 -0
- package/dist/esm/prototyping/crypto/jose/jwe.js +308 -0
- package/dist/esm/prototyping/crypto/jose/jwe.js.map +1 -0
- package/dist/esm/prototyping/crypto/primitives/aes-gcm.js +352 -0
- package/dist/esm/prototyping/crypto/primitives/aes-gcm.js.map +1 -0
- package/dist/esm/prototyping/crypto/primitives/aes-kw.js +247 -0
- package/dist/esm/prototyping/crypto/primitives/aes-kw.js.map +1 -0
- package/dist/esm/prototyping/crypto/primitives/hkdf.js +80 -0
- package/dist/esm/prototyping/crypto/primitives/hkdf.js.map +1 -0
- package/dist/esm/prototyping/crypto/primitives/pbkdf2.js +85 -0
- package/dist/esm/prototyping/crypto/primitives/pbkdf2.js.map +1 -0
- package/dist/esm/prototyping/crypto/types/cipher.js +2 -0
- package/dist/esm/prototyping/crypto/types/cipher.js.map +1 -0
- package/dist/esm/prototyping/crypto/types/crypto-api.js +2 -0
- package/dist/esm/prototyping/crypto/types/crypto-api.js.map +1 -0
- package/dist/esm/prototyping/crypto/types/key-converter.js +2 -0
- package/dist/esm/prototyping/crypto/types/key-converter.js.map +1 -0
- package/dist/esm/prototyping/crypto/types/key-deriver.js +2 -0
- package/dist/esm/prototyping/crypto/types/key-deriver.js.map +1 -0
- package/dist/esm/prototyping/crypto/types/key-io.js +2 -0
- package/dist/esm/prototyping/crypto/types/key-io.js.map +1 -0
- package/dist/esm/prototyping/crypto/types/key-manager.js +2 -0
- package/dist/esm/prototyping/crypto/types/key-manager.js.map +1 -0
- package/dist/esm/prototyping/crypto/types/key-wrapper.js +2 -0
- package/dist/esm/prototyping/crypto/types/key-wrapper.js.map +1 -0
- package/dist/esm/prototyping/crypto/types/params-direct.js +2 -0
- package/dist/esm/prototyping/crypto/types/params-direct.js.map +1 -0
- package/dist/esm/prototyping/crypto/types/params-kms.js +2 -0
- package/dist/esm/prototyping/crypto/types/params-kms.js.map +1 -0
- package/dist/esm/prototyping/crypto/utils.js +19 -0
- package/dist/esm/prototyping/crypto/utils.js.map +1 -0
- package/dist/esm/prototyping/dids/resolver-cache-memory.js +77 -0
- package/dist/esm/prototyping/dids/resolver-cache-memory.js.map +1 -0
- package/dist/esm/prototyping/dids/utils.js +9 -0
- package/dist/esm/prototyping/dids/utils.js.map +1 -0
- package/dist/esm/rpc-client.js +123 -0
- package/dist/esm/rpc-client.js.map +1 -0
- package/dist/esm/store-data-protocols.js +38 -0
- package/dist/esm/store-data-protocols.js.map +1 -0
- package/dist/esm/store-data.js +320 -0
- package/dist/esm/store-data.js.map +1 -0
- package/dist/esm/store-did.js +136 -0
- package/dist/esm/store-did.js.map +1 -0
- package/dist/esm/store-identity.js +140 -0
- package/dist/esm/store-identity.js.map +1 -0
- package/dist/esm/store-key.js +136 -0
- package/dist/esm/store-key.js.map +1 -0
- package/dist/esm/sync-api.js +61 -0
- package/dist/esm/sync-api.js.map +1 -0
- package/dist/esm/sync-engine-level.js +618 -0
- package/dist/esm/sync-engine-level.js.map +1 -0
- package/dist/esm/test-harness.js +239 -0
- package/dist/esm/test-harness.js.map +1 -0
- package/dist/esm/types/agent.js +2 -0
- package/dist/esm/types/agent.js.map +1 -0
- package/dist/esm/types/dwn.js +31 -0
- package/dist/esm/types/dwn.js.map +1 -0
- package/dist/esm/types/identity-vault.js +2 -0
- package/dist/esm/types/identity-vault.js.map +1 -0
- package/dist/esm/types/identity.js +2 -0
- package/dist/esm/types/identity.js.map +1 -0
- package/dist/esm/types/key-manager.js +2 -0
- package/dist/esm/types/key-manager.js.map +1 -0
- package/dist/esm/types/permissions.js +2 -0
- package/dist/esm/types/permissions.js.map +1 -0
- package/dist/esm/types/sync.js +2 -0
- package/dist/esm/types/sync.js.map +1 -0
- package/dist/esm/types/vc.js +5 -0
- package/dist/esm/types/vc.js.map +1 -0
- package/dist/esm/utils-internal.js +147 -0
- package/dist/esm/utils-internal.js.map +1 -0
- package/dist/esm/utils.js +161 -0
- package/dist/esm/utils.js.map +1 -0
- package/dist/types/agent-did-resolver-cache.d.ts +30 -0
- package/dist/types/agent-did-resolver-cache.d.ts.map +1 -0
- package/dist/types/bearer-identity.d.ts +31 -0
- package/dist/types/bearer-identity.d.ts.map +1 -0
- package/dist/types/connect.d.ts +88 -0
- package/dist/types/connect.d.ts.map +1 -0
- package/dist/types/crypto-api.d.ts +286 -0
- package/dist/types/crypto-api.d.ts.map +1 -0
- package/dist/types/did-api.d.ts +119 -0
- package/dist/types/did-api.d.ts.map +1 -0
- package/dist/types/dwn-api.d.ts +66 -0
- package/dist/types/dwn-api.d.ts.map +1 -0
- package/dist/types/dwn-registrar.d.ts +29 -0
- package/dist/types/dwn-registrar.d.ts.map +1 -0
- package/dist/types/hd-identity-vault.d.ts +306 -0
- package/dist/types/hd-identity-vault.d.ts.map +1 -0
- package/dist/types/identity-api.d.ts +107 -0
- package/dist/types/identity-api.d.ts.map +1 -0
- package/dist/types/index.d.ts +30 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/local-key-manager.d.ts +311 -0
- package/dist/types/local-key-manager.d.ts.map +1 -0
- package/dist/types/oidc.d.ts +247 -0
- package/dist/types/oidc.d.ts.map +1 -0
- package/dist/types/permissions-api.d.ts +35 -0
- package/dist/types/permissions-api.d.ts.map +1 -0
- package/dist/types/prototyping/clients/dwn-rpc-types.d.ts +45 -0
- package/dist/types/prototyping/clients/dwn-rpc-types.d.ts.map +1 -0
- package/dist/types/prototyping/clients/dwn-server-info-cache-memory.d.ts +57 -0
- package/dist/types/prototyping/clients/dwn-server-info-cache-memory.d.ts.map +1 -0
- package/dist/types/prototyping/clients/http-dwn-rpc-client.d.ts +13 -0
- package/dist/types/prototyping/clients/http-dwn-rpc-client.d.ts.map +1 -0
- package/dist/types/prototyping/clients/json-rpc-socket.d.ts +43 -0
- package/dist/types/prototyping/clients/json-rpc-socket.d.ts.map +1 -0
- package/dist/types/prototyping/clients/json-rpc.d.ts +49 -0
- package/dist/types/prototyping/clients/json-rpc.d.ts.map +1 -0
- package/dist/types/prototyping/clients/server-info-types.d.ts +20 -0
- package/dist/types/prototyping/clients/server-info-types.d.ts.map +1 -0
- package/dist/types/prototyping/clients/web-socket-clients.d.ts +10 -0
- package/dist/types/prototyping/clients/web-socket-clients.d.ts.map +1 -0
- package/dist/types/prototyping/common/object.d.ts +2 -0
- package/dist/types/prototyping/common/object.d.ts.map +1 -0
- package/dist/types/prototyping/common/type-utils.d.ts +7 -0
- package/dist/types/prototyping/common/type-utils.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/algorithms/aes-gcm.d.ts +151 -0
- package/dist/types/prototyping/crypto/algorithms/aes-gcm.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/algorithms/aes-kw.d.ts +109 -0
- package/dist/types/prototyping/crypto/algorithms/aes-kw.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/algorithms/ecdsa.d.ts +160 -0
- package/dist/types/prototyping/crypto/algorithms/ecdsa.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/algorithms/eddsa.d.ts +157 -0
- package/dist/types/prototyping/crypto/algorithms/eddsa.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/algorithms/hkdf.d.ts +21 -0
- package/dist/types/prototyping/crypto/algorithms/hkdf.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/algorithms/pbkdf2.d.ts +21 -0
- package/dist/types/prototyping/crypto/algorithms/pbkdf2.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/crypto-error.d.ts +29 -0
- package/dist/types/prototyping/crypto/crypto-error.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/dsa.d.ts +169 -0
- package/dist/types/prototyping/crypto/dsa.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/jose/jwe-compact.d.ts +135 -0
- package/dist/types/prototyping/crypto/jose/jwe-compact.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/jose/jwe-flattened.d.ts +134 -0
- package/dist/types/prototyping/crypto/jose/jwe-flattened.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/jose/jwe.d.ts +378 -0
- package/dist/types/prototyping/crypto/jose/jwe.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/primitives/aes-gcm.d.ts +245 -0
- package/dist/types/prototyping/crypto/primitives/aes-gcm.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/primitives/aes-kw.d.ts +103 -0
- package/dist/types/prototyping/crypto/primitives/aes-kw.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/primitives/hkdf.d.ts +90 -0
- package/dist/types/prototyping/crypto/primitives/hkdf.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/primitives/pbkdf2.d.ts +84 -0
- package/dist/types/prototyping/crypto/primitives/pbkdf2.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/types/cipher.d.ts +14 -0
- package/dist/types/prototyping/crypto/types/cipher.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/types/crypto-api.d.ts +35 -0
- package/dist/types/prototyping/crypto/types/crypto-api.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/types/key-converter.d.ts +49 -0
- package/dist/types/prototyping/crypto/types/key-converter.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/types/key-deriver.d.ts +50 -0
- package/dist/types/prototyping/crypto/types/key-deriver.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/types/key-io.d.ts +49 -0
- package/dist/types/prototyping/crypto/types/key-io.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/types/key-manager.d.ts +69 -0
- package/dist/types/prototyping/crypto/types/key-manager.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/types/key-wrapper.d.ts +14 -0
- package/dist/types/prototyping/crypto/types/key-wrapper.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/types/params-direct.d.ts +75 -0
- package/dist/types/prototyping/crypto/types/params-direct.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/types/params-kms.d.ts +63 -0
- package/dist/types/prototyping/crypto/types/params-kms.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/utils.d.ts +7 -0
- package/dist/types/prototyping/crypto/utils.d.ts.map +1 -0
- package/dist/types/prototyping/dids/resolver-cache-memory.d.ts +57 -0
- package/dist/types/prototyping/dids/resolver-cache-memory.d.ts.map +1 -0
- package/dist/types/prototyping/dids/utils.d.ts +3 -0
- package/dist/types/prototyping/dids/utils.d.ts.map +1 -0
- package/dist/types/rpc-client.d.ts +51 -0
- package/dist/types/rpc-client.d.ts.map +1 -0
- package/dist/types/store-data-protocols.d.ts +4 -0
- package/dist/types/store-data-protocols.d.ts.map +1 -0
- package/dist/types/store-data.d.ts +95 -0
- package/dist/types/store-data.d.ts.map +1 -0
- package/dist/types/store-did.d.ts +33 -0
- package/dist/types/store-did.d.ts.map +1 -0
- package/dist/types/store-identity.d.ts +34 -0
- package/dist/types/store-identity.d.ts.map +1 -0
- package/dist/types/store-key.d.ts +32 -0
- package/dist/types/store-key.d.ts.map +1 -0
- package/dist/types/sync-api.d.ts +41 -0
- package/dist/types/sync-api.d.ts.map +1 -0
- package/dist/types/sync-engine-level.d.ts +85 -0
- package/dist/types/sync-engine-level.d.ts.map +1 -0
- package/dist/types/test-harness.d.ts +69 -0
- package/dist/types/test-harness.d.ts.map +1 -0
- package/dist/types/types/agent.d.ts +172 -0
- package/dist/types/types/agent.d.ts.map +1 -0
- package/dist/types/types/dwn.d.ts +178 -0
- package/dist/types/types/dwn.d.ts.map +1 -0
- package/dist/types/types/identity-vault.d.ts +129 -0
- package/dist/types/types/identity-vault.d.ts.map +1 -0
- package/dist/types/types/identity.d.ts +16 -0
- package/dist/types/types/identity.d.ts.map +1 -0
- package/dist/types/types/key-manager.d.ts +9 -0
- package/dist/types/types/key-manager.d.ts.map +1 -0
- package/dist/types/types/permissions.d.ts +98 -0
- package/dist/types/types/permissions.d.ts.map +1 -0
- package/dist/types/types/sync.d.ts +66 -0
- package/dist/types/types/sync.d.ts.map +1 -0
- package/dist/types/types/vc.d.ts +7 -0
- package/dist/types/types/vc.d.ts.map +1 -0
- package/dist/types/utils-internal.d.ts +50 -0
- package/dist/types/utils-internal.d.ts.map +1 -0
- package/dist/types/utils.d.ts +37 -0
- package/dist/types/utils.d.ts.map +1 -0
- package/package.json +112 -0
- package/src/agent-did-resolver-cache.ts +95 -0
- package/src/bearer-identity.ts +42 -0
- package/src/connect.ts +296 -0
- package/src/crypto-api.ts +593 -0
- package/src/did-api.ts +429 -0
- package/src/dwn-api.ts +462 -0
- package/src/dwn-registrar.ts +127 -0
- package/src/hd-identity-vault.ts +853 -0
- package/src/identity-api.ts +324 -0
- package/src/index.ts +30 -0
- package/src/local-key-manager.ts +672 -0
- package/src/oidc.ts +857 -0
- package/src/permissions-api.ts +408 -0
- package/src/prototyping/clients/dwn-rpc-types.ts +55 -0
- package/src/prototyping/clients/dwn-server-info-cache-memory.ts +79 -0
- package/src/prototyping/clients/http-dwn-rpc-client.ts +110 -0
- package/src/prototyping/clients/json-rpc-socket.ts +169 -0
- package/src/prototyping/clients/json-rpc.ts +113 -0
- package/src/prototyping/clients/server-info-types.ts +21 -0
- package/src/prototyping/clients/web-socket-clients.ts +100 -0
- package/src/prototyping/common/object.ts +15 -0
- package/src/prototyping/common/type-utils.ts +6 -0
- package/src/prototyping/crypto/algorithms/aes-gcm.ts +211 -0
- package/src/prototyping/crypto/algorithms/aes-kw.ts +164 -0
- package/src/prototyping/crypto/algorithms/ecdsa.ts +365 -0
- package/src/prototyping/crypto/algorithms/eddsa.ts +310 -0
- package/src/prototyping/crypto/algorithms/hkdf.ts +40 -0
- package/src/prototyping/crypto/algorithms/pbkdf2.ts +44 -0
- package/src/prototyping/crypto/crypto-error.ts +45 -0
- package/src/prototyping/crypto/dsa.ts +367 -0
- package/src/prototyping/crypto/jose/jwe-compact.ts +225 -0
- package/src/prototyping/crypto/jose/jwe-flattened.ts +459 -0
- package/src/prototyping/crypto/jose/jwe.ts +653 -0
- package/src/prototyping/crypto/primitives/aes-gcm.ts +374 -0
- package/src/prototyping/crypto/primitives/aes-kw.ts +271 -0
- package/src/prototyping/crypto/primitives/hkdf.ts +121 -0
- package/src/prototyping/crypto/primitives/pbkdf2.ts +116 -0
- package/src/prototyping/crypto/types/cipher.ts +17 -0
- package/src/prototyping/crypto/types/crypto-api.ts +78 -0
- package/src/prototyping/crypto/types/key-converter.ts +53 -0
- package/src/prototyping/crypto/types/key-deriver.ts +56 -0
- package/src/prototyping/crypto/types/key-io.ts +51 -0
- package/src/prototyping/crypto/types/key-manager.ts +83 -0
- package/src/prototyping/crypto/types/key-wrapper.ts +17 -0
- package/src/prototyping/crypto/types/params-direct.ts +95 -0
- package/src/prototyping/crypto/types/params-kms.ts +76 -0
- package/src/prototyping/crypto/utils.ts +41 -0
- package/src/prototyping/dids/resolver-cache-memory.ts +83 -0
- package/src/prototyping/dids/utils.ts +10 -0
- package/src/rpc-client.ts +162 -0
- package/src/store-data-protocols.ts +40 -0
- package/src/store-data.ts +400 -0
- package/src/store-did.ts +105 -0
- package/src/store-identity.ts +109 -0
- package/src/store-key.ts +104 -0
- package/src/sync-api.ts +71 -0
- package/src/sync-engine-level.ts +714 -0
- package/src/test-harness.ts +330 -0
- package/src/types/agent.ts +195 -0
- package/src/types/dwn.ts +278 -0
- package/src/types/identity-vault.ts +137 -0
- package/src/types/identity.ts +18 -0
- package/src/types/key-manager.ts +15 -0
- package/src/types/permissions.ts +115 -0
- package/src/types/sync.ts +58 -0
- package/src/types/vc.ts +7 -0
- package/src/utils-internal.ts +157 -0
- package/src/utils.ts +181 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { CryptoUtils } from '@enbox/crypto';
|
|
2
|
+
import IsomorphicWebSocket from 'isomorphic-ws';
|
|
3
|
+
import { JsonRpcId, JsonRpcRequest, JsonRpcResponse, createJsonRpcSubscriptionRequest, parseJson } from './json-rpc.js';
|
|
4
|
+
|
|
5
|
+
// These were arbitrarily chosen, but can be modified via connect options
|
|
6
|
+
const CONNECT_TIMEOUT = 3_000;
|
|
7
|
+
const RESPONSE_TIMEOUT = 30_000;
|
|
8
|
+
|
|
9
|
+
export interface JsonRpcSocketOptions {
|
|
10
|
+
/** socket connection timeout in milliseconds */
|
|
11
|
+
connectTimeout?: number;
|
|
12
|
+
/** response timeout for rpc requests in milliseconds */
|
|
13
|
+
responseTimeout?: number;
|
|
14
|
+
/** optional connection close handler */
|
|
15
|
+
onclose?: () => void;
|
|
16
|
+
/** optional socket error handler */
|
|
17
|
+
onerror?: (error?: any) => void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* JSON RPC Socket Client for WebSocket request/response and long-running subscriptions.
|
|
22
|
+
*
|
|
23
|
+
* NOTE: This is temporarily copied over from https://github.com/TBD54566975/dwn-server/blob/main/src/json-rpc-socket.ts
|
|
24
|
+
* This was done in order to avoid taking a dependency on the `dwn-server`, until a future time when there will be a `clients` package.
|
|
25
|
+
*/
|
|
26
|
+
export class JsonRpcSocket {
|
|
27
|
+
private messageHandlers: Map<JsonRpcId, (event: { data: any }) => void> = new Map();
|
|
28
|
+
|
|
29
|
+
private constructor(private socket: IsomorphicWebSocket, private responseTimeout: number) {}
|
|
30
|
+
|
|
31
|
+
static async connect(url: string, options: JsonRpcSocketOptions = {}): Promise<JsonRpcSocket> {
|
|
32
|
+
const { connectTimeout = CONNECT_TIMEOUT, responseTimeout = RESPONSE_TIMEOUT, onclose, onerror } = options;
|
|
33
|
+
|
|
34
|
+
const socket = new IsomorphicWebSocket(url);
|
|
35
|
+
|
|
36
|
+
if (!onclose) {
|
|
37
|
+
socket.onclose = ():void => {
|
|
38
|
+
console.info(`JSON RPC Socket close ${url}`);
|
|
39
|
+
};
|
|
40
|
+
} else {
|
|
41
|
+
socket.onclose = onclose;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (!onerror) {
|
|
45
|
+
socket.onerror = (error?: any):void => {
|
|
46
|
+
console.error(`JSON RPC Socket error ${url}`, error);
|
|
47
|
+
};
|
|
48
|
+
} else {
|
|
49
|
+
socket.onerror = onerror;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return new Promise<JsonRpcSocket>((resolve, reject) => {
|
|
53
|
+
socket.addEventListener('open', () => {
|
|
54
|
+
const jsonRpcSocket = new JsonRpcSocket(socket, responseTimeout);
|
|
55
|
+
|
|
56
|
+
socket.addEventListener('message', (event: { data: any }) => {
|
|
57
|
+
const jsonRpcResponse = parseJson(event.data) as JsonRpcResponse;
|
|
58
|
+
const handler = jsonRpcSocket.messageHandlers.get(jsonRpcResponse.id);
|
|
59
|
+
if (handler) {
|
|
60
|
+
handler(event);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
resolve(jsonRpcSocket);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
socket.addEventListener('error', (error: any) => {
|
|
68
|
+
reject(error);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
setTimeout(() => reject, connectTimeout);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
close(): void {
|
|
76
|
+
this.socket.close();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Sends a JSON-RPC request through the socket and waits for a single response.
|
|
81
|
+
*/
|
|
82
|
+
async request(request: JsonRpcRequest): Promise<JsonRpcResponse> {
|
|
83
|
+
return new Promise((resolve, reject) => {
|
|
84
|
+
request.id ??= CryptoUtils.randomUuid();
|
|
85
|
+
|
|
86
|
+
const handleResponse = (event: { data: any }):void => {
|
|
87
|
+
const jsonRpsResponse = parseJson(event.data) as JsonRpcResponse;
|
|
88
|
+
if (jsonRpsResponse.id === request.id) {
|
|
89
|
+
// if the incoming response id matches the request id, we will remove the listener and resolve the response
|
|
90
|
+
this.messageHandlers.delete(request.id);
|
|
91
|
+
return resolve(jsonRpsResponse);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// add the listener to the map of message handlers
|
|
96
|
+
this.messageHandlers.set(request.id, handleResponse);
|
|
97
|
+
this.send(request);
|
|
98
|
+
|
|
99
|
+
// reject this promise if we don't receive any response back within the timeout period
|
|
100
|
+
setTimeout(() => {
|
|
101
|
+
this.messageHandlers.delete(request.id!);
|
|
102
|
+
reject(new Error('request timed out'));
|
|
103
|
+
}, this.responseTimeout);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Sends a JSON-RPC request through the socket and keeps a listener open to read associated responses as they arrive.
|
|
109
|
+
* Returns a close method to clean up the listener.
|
|
110
|
+
*/
|
|
111
|
+
async subscribe(request: JsonRpcRequest, listener: (response: JsonRpcResponse) => void): Promise<{
|
|
112
|
+
response: JsonRpcResponse;
|
|
113
|
+
close?: () => Promise<void>;
|
|
114
|
+
}> {
|
|
115
|
+
|
|
116
|
+
if (!request.method.startsWith('rpc.subscribe.')) {
|
|
117
|
+
throw new Error('subscribe rpc requests must include the `rpc.subscribe` prefix');
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (!request.subscription) {
|
|
121
|
+
throw new Error('subscribe rpc requests must include subscribe options');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const subscriptionId = request.subscription.id;
|
|
125
|
+
const socketEventListener = (event: { data: any }):void => {
|
|
126
|
+
const jsonRpcResponse = parseJson(event.data.toString()) as JsonRpcResponse;
|
|
127
|
+
if (jsonRpcResponse.id === subscriptionId) {
|
|
128
|
+
if (jsonRpcResponse.error !== undefined) {
|
|
129
|
+
// remove the event listener upon receipt of a JSON RPC Error.
|
|
130
|
+
this.messageHandlers.delete(subscriptionId);
|
|
131
|
+
this.closeSubscription(subscriptionId);
|
|
132
|
+
}
|
|
133
|
+
listener(jsonRpcResponse);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
this.messageHandlers.set(subscriptionId, socketEventListener);
|
|
138
|
+
|
|
139
|
+
const response = await this.request(request);
|
|
140
|
+
if (response.error) {
|
|
141
|
+
this.messageHandlers.delete(subscriptionId);
|
|
142
|
+
return { response };
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// clean up listener and create a `rpc.subscribe.close` message to use when closing this JSON RPC subscription
|
|
146
|
+
const close = async (): Promise<void> => {
|
|
147
|
+
this.messageHandlers.delete(subscriptionId);
|
|
148
|
+
await this.closeSubscription(subscriptionId);
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
response,
|
|
153
|
+
close
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
private closeSubscription(id: JsonRpcId): Promise<JsonRpcResponse> {
|
|
158
|
+
const requestId = CryptoUtils.randomUuid();
|
|
159
|
+
const request = createJsonRpcSubscriptionRequest(requestId, 'close', id, {});
|
|
160
|
+
return this.request(request);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Sends a JSON-RPC request through the socket. You must subscribe to a message listener separately to capture the response.
|
|
165
|
+
*/
|
|
166
|
+
send(request: JsonRpcRequest):void {
|
|
167
|
+
this.socket.send(JSON.stringify(request));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
export type JsonRpcId = string | number | null;
|
|
2
|
+
export type JsonRpcParams = any;
|
|
3
|
+
export type JsonRpcVersion = '2.0';
|
|
4
|
+
|
|
5
|
+
export interface JsonRpcRequest {
|
|
6
|
+
jsonrpc: JsonRpcVersion;
|
|
7
|
+
id?: JsonRpcId;
|
|
8
|
+
/** JSON RPC Subscription Extension Parameters */
|
|
9
|
+
subscription?: { id: JsonRpcId }
|
|
10
|
+
method: string;
|
|
11
|
+
params?: any;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface JsonRpcError {
|
|
15
|
+
code: JsonRpcErrorCodes;
|
|
16
|
+
message: string;
|
|
17
|
+
data?: any;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export enum JsonRpcErrorCodes {
|
|
21
|
+
// JSON-RPC 2.0 pre-defined errors
|
|
22
|
+
InvalidRequest = -32600,
|
|
23
|
+
MethodNotFound = -32601,
|
|
24
|
+
InvalidParams = -32602,
|
|
25
|
+
InternalError = -32603,
|
|
26
|
+
ParseError = -32700,
|
|
27
|
+
TransportError = -32300,
|
|
28
|
+
|
|
29
|
+
// App defined errors
|
|
30
|
+
BadRequest = -50400, // equivalent to HTTP Status 400
|
|
31
|
+
Unauthorized = -50401, // equivalent to HTTP Status 401
|
|
32
|
+
Forbidden = -50403, // equivalent to HTTP Status 403,
|
|
33
|
+
Conflict = -50409, // equivalent to HTTP Status 409
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type JsonRpcResponse = JsonRpcSuccessResponse | JsonRpcErrorResponse;
|
|
37
|
+
|
|
38
|
+
export interface JsonRpcSuccessResponse {
|
|
39
|
+
jsonrpc: JsonRpcVersion;
|
|
40
|
+
id: JsonRpcId;
|
|
41
|
+
result: any;
|
|
42
|
+
error?: never;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface JsonRpcErrorResponse {
|
|
46
|
+
jsonrpc: JsonRpcVersion;
|
|
47
|
+
id: JsonRpcId;
|
|
48
|
+
result?: never;
|
|
49
|
+
error: JsonRpcError;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const createJsonRpcErrorResponse = (
|
|
53
|
+
id: JsonRpcId,
|
|
54
|
+
code: JsonRpcErrorCodes,
|
|
55
|
+
message: string,
|
|
56
|
+
data?: any,
|
|
57
|
+
): JsonRpcErrorResponse => {
|
|
58
|
+
const error: JsonRpcError = { code, message, data };
|
|
59
|
+
return {
|
|
60
|
+
jsonrpc: '2.0',
|
|
61
|
+
id,
|
|
62
|
+
error,
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const createJsonRpcRequest = (
|
|
67
|
+
id: JsonRpcId,
|
|
68
|
+
method: string,
|
|
69
|
+
params?: JsonRpcParams,
|
|
70
|
+
): JsonRpcRequest => {
|
|
71
|
+
return {
|
|
72
|
+
jsonrpc: '2.0',
|
|
73
|
+
id,
|
|
74
|
+
method,
|
|
75
|
+
params,
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export const createJsonRpcSubscriptionRequest = (
|
|
80
|
+
id: JsonRpcId,
|
|
81
|
+
method: string,
|
|
82
|
+
subscriptionId: JsonRpcId,
|
|
83
|
+
params?: any
|
|
84
|
+
): JsonRpcRequest => {
|
|
85
|
+
return {
|
|
86
|
+
jsonrpc : '2.0',
|
|
87
|
+
id,
|
|
88
|
+
method : `rpc.subscribe.${method}`,
|
|
89
|
+
params,
|
|
90
|
+
subscription : {
|
|
91
|
+
id: subscriptionId,
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export const createJsonRpcSuccessResponse = (
|
|
97
|
+
id: JsonRpcId,
|
|
98
|
+
result: any,
|
|
99
|
+
): JsonRpcSuccessResponse => {
|
|
100
|
+
return {
|
|
101
|
+
jsonrpc: '2.0',
|
|
102
|
+
id,
|
|
103
|
+
result,
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export function parseJson(text: string): object | null {
|
|
108
|
+
try {
|
|
109
|
+
return JSON.parse(text);
|
|
110
|
+
} catch {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { KeyValueStore } from '@enbox/common';
|
|
2
|
+
|
|
3
|
+
export type ServerInfo = {
|
|
4
|
+
/** the maximum file size the user can request to store */
|
|
5
|
+
maxFileSize: number,
|
|
6
|
+
/**
|
|
7
|
+
* an array of strings representing the server's registration requirements.
|
|
8
|
+
*
|
|
9
|
+
* ie. ['proof-of-work-sha256-v0', 'terms-of-service']
|
|
10
|
+
* */
|
|
11
|
+
registrationRequirements: string[],
|
|
12
|
+
/** whether web socket support is enabled on this server */
|
|
13
|
+
webSocketSupport: boolean,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface DwnServerInfoCache extends KeyValueStore<string, ServerInfo| undefined> {}
|
|
17
|
+
|
|
18
|
+
export interface DwnServerInfoRpc {
|
|
19
|
+
/** retrieves the DWN Sever info, used to detect features such as WebSocket Subscriptions */
|
|
20
|
+
getServerInfo(url: string): Promise<ServerInfo>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { DwnRpc, DwnRpcRequest, DwnRpcResponse, DwnSubscriptionHandler } from './dwn-rpc-types.js';
|
|
2
|
+
import type { GenericMessage, MessageSubscription, UnionMessageReply } from '@enbox/dwn-sdk-js';
|
|
3
|
+
|
|
4
|
+
import { CryptoUtils } from '@enbox/crypto';
|
|
5
|
+
import { createJsonRpcRequest, createJsonRpcSubscriptionRequest } from './json-rpc.js';
|
|
6
|
+
import { JsonRpcSocket, JsonRpcSocketOptions } from './json-rpc-socket.js';
|
|
7
|
+
|
|
8
|
+
interface SocketConnection {
|
|
9
|
+
socket: JsonRpcSocket;
|
|
10
|
+
subscriptions: Map<string, MessageSubscription>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export class WebSocketDwnRpcClient implements DwnRpc {
|
|
14
|
+
public get transportProtocols() { return ['ws:', 'wss:']; }
|
|
15
|
+
// a map of dwn host to WebSocket connection
|
|
16
|
+
private static connections = new Map<string, SocketConnection>();
|
|
17
|
+
|
|
18
|
+
async sendDwnRequest(request: DwnRpcRequest, jsonRpcSocketOptions?: JsonRpcSocketOptions): Promise<DwnRpcResponse> {
|
|
19
|
+
|
|
20
|
+
// validate that the dwn URL provided is a valid WebSocket URL
|
|
21
|
+
const url = new URL(request.dwnUrl);
|
|
22
|
+
if (url.protocol !== 'ws:' && url.protocol !== 'wss:') {
|
|
23
|
+
throw new Error(`Invalid websocket protocol ${url.protocol}`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// check if there is already a connection to this host, if it does not exist, initiate a new connection
|
|
27
|
+
const hasConnection = WebSocketDwnRpcClient.connections.has(url.host);
|
|
28
|
+
if (!hasConnection) {
|
|
29
|
+
try {
|
|
30
|
+
const socket = await JsonRpcSocket.connect(url.toString(), jsonRpcSocketOptions);
|
|
31
|
+
const subscriptions = new Map();
|
|
32
|
+
WebSocketDwnRpcClient.connections.set(url.host, { socket, subscriptions });
|
|
33
|
+
} catch(error) {
|
|
34
|
+
throw new Error(`Error connecting to ${url.host}: ${(error as Error).message}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const connection = WebSocketDwnRpcClient.connections.get(url.host)!;
|
|
39
|
+
const { targetDid, message, subscriptionHandler } = request;
|
|
40
|
+
|
|
41
|
+
if (subscriptionHandler) {
|
|
42
|
+
return WebSocketDwnRpcClient.subscriptionRequest(connection, targetDid, message, subscriptionHandler);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return WebSocketDwnRpcClient.processMessage(connection, targetDid, message);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private static async processMessage(connection: SocketConnection, target: string, message: GenericMessage): Promise<DwnRpcResponse> {
|
|
49
|
+
const requestId = CryptoUtils.randomUuid();
|
|
50
|
+
const request = createJsonRpcRequest(requestId, 'dwn.processMessage', { target, message });
|
|
51
|
+
|
|
52
|
+
const { socket } = connection;
|
|
53
|
+
const response = await socket.request(request);
|
|
54
|
+
|
|
55
|
+
const { error, result } = response;
|
|
56
|
+
if (error !== undefined) {
|
|
57
|
+
throw new Error(`error sending DWN request: ${error.message}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return result.reply as DwnRpcResponse;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private static async subscriptionRequest(connection: SocketConnection, target:string, message: GenericMessage, messageHandler: DwnSubscriptionHandler): Promise<DwnRpcResponse> {
|
|
64
|
+
const requestId = CryptoUtils.randomUuid();
|
|
65
|
+
const subscriptionId = CryptoUtils.randomUuid();
|
|
66
|
+
const request = createJsonRpcSubscriptionRequest(requestId, 'dwn.processMessage', subscriptionId, { target, message });
|
|
67
|
+
|
|
68
|
+
const { socket, subscriptions } = connection;
|
|
69
|
+
const { response, close } = await socket.subscribe(request, (response) => {
|
|
70
|
+
const { result, error } = response;
|
|
71
|
+
if (error) {
|
|
72
|
+
|
|
73
|
+
// if there is an error, close the subscription and delete it from the connection
|
|
74
|
+
const subscription = subscriptions.get(subscriptionId);
|
|
75
|
+
if (subscription) {
|
|
76
|
+
subscription.close();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
subscriptions.delete(subscriptionId);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const { event } = result;
|
|
84
|
+
messageHandler(event);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const { error, result } = response;
|
|
88
|
+
if (error) {
|
|
89
|
+
throw new Error(`could not subscribe via jsonrpc socket: ${error.message}`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const { reply } = result as { reply: UnionMessageReply };
|
|
93
|
+
if (reply.subscription && close) {
|
|
94
|
+
subscriptions.set(subscriptionId, { ...reply.subscription, close });
|
|
95
|
+
reply.subscription.close = close;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return reply;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function hasDuplicateProperties(...objects: Array<Record<string, any> | undefined>): boolean {
|
|
2
|
+
const propertySet = new Set<string>();
|
|
3
|
+
const objectsWithoutUndefined = objects.filter(Boolean); // Remove any undefined values
|
|
4
|
+
|
|
5
|
+
for (const obj of objectsWithoutUndefined) {
|
|
6
|
+
for (const key in obj) {
|
|
7
|
+
if (propertySet.has(key)) {
|
|
8
|
+
return true; // Return true if a duplicate property is found
|
|
9
|
+
}
|
|
10
|
+
propertySet.add(key);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return false; // Return false if no duplicates are found
|
|
15
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Jwk,
|
|
3
|
+
Cipher,
|
|
4
|
+
KeyConverter,
|
|
5
|
+
KeyGenerator,
|
|
6
|
+
DecryptParams,
|
|
7
|
+
EncryptParams,
|
|
8
|
+
GenerateKeyParams,
|
|
9
|
+
} from '@enbox/crypto';
|
|
10
|
+
|
|
11
|
+
import { AesGcm, AES_GCM_TAG_LENGTHS, CryptoAlgorithm } from '@enbox/crypto';
|
|
12
|
+
|
|
13
|
+
import type { BytesToPrivateKeyParams, PrivateKeyToBytesParams } from '../types/params-direct.js';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The `AesGcmGenerateKeyParams` interface defines the algorithm-specific parameters that should be
|
|
17
|
+
* passed into the `generateKey()` method when using the AES-GCM algorithm.
|
|
18
|
+
*/
|
|
19
|
+
export interface AesGcmGenerateKeyParams extends GenerateKeyParams {
|
|
20
|
+
/** Specifies the algorithm variant for key generation in AES-GCM mode.
|
|
21
|
+
* The value determines the length of the key to be generated and must be one of the following:
|
|
22
|
+
* - `"A128GCM"`: Generates a 128-bit key.
|
|
23
|
+
* - `"A192GCM"`: Generates a 192-bit key.
|
|
24
|
+
* - `"A256GCM"`: Generates a 256-bit key.
|
|
25
|
+
*/
|
|
26
|
+
algorithm: 'A128GCM' | 'A192GCM' | 'A256GCM';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The `AesGcmParams` interface defines the algorithm-specific parameters that should be passed
|
|
31
|
+
* into the `encrypt()` and `decrypt()` methods when using the AES-GCM algorithm.
|
|
32
|
+
*/
|
|
33
|
+
export interface AesGcmParams {
|
|
34
|
+
/**
|
|
35
|
+
* The `additionalData` property is used for authentication alongside encrypted data but isn't
|
|
36
|
+
* encrypted itself. It must match in both encryption and decryption; a mismatch will cause
|
|
37
|
+
* decryption to fail. This feature allows for the authentication of data without encrypting it.
|
|
38
|
+
*
|
|
39
|
+
* The `additionalData` property is optional and omitting it does not compromise encryption
|
|
40
|
+
* security.
|
|
41
|
+
*/
|
|
42
|
+
additionalData?: Uint8Array;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The initialization vector (IV) must be unique for every encryption operation carried out with a
|
|
46
|
+
* given key. The IV need not be secret, but it must be unpredictable: that is, the IV must not be
|
|
47
|
+
* reused with the same key. The IV must be 12 bytes (96 bits) in length in accordance with the
|
|
48
|
+
* AES-GCM specification recommendedation to promote interoperability and efficiency.
|
|
49
|
+
*
|
|
50
|
+
* Note: It is OK to transmit the IV in the clear with the encrypted message.
|
|
51
|
+
*/
|
|
52
|
+
iv: Uint8Array;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* This property determines the size in bits of the authentication tag generated in the encryption
|
|
56
|
+
* operation and used for authentication in the corresponding decryption. In accordance with the
|
|
57
|
+
* AES-GCM specification, the tag length must be 96, 104, 112, 120 or 128.
|
|
58
|
+
*
|
|
59
|
+
* The `tagLength` property is optional and defaults to 128 bits if omitted.
|
|
60
|
+
*/
|
|
61
|
+
tagLength?: typeof AES_GCM_TAG_LENGTHS[number];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The `AesGcmAlgorithm` class provides a concrete implementation for cryptographic operations using
|
|
66
|
+
* the AES algorithm in Galois/Counter Mode (GCM). This class implements both
|
|
67
|
+
* {@link Cipher | `Cipher`} and { @link KeyGenerator | `KeyGenerator`} interfaces, providing
|
|
68
|
+
* key generation, encryption, and decryption features.
|
|
69
|
+
*
|
|
70
|
+
* This class is typically accessed through implementations that extend the
|
|
71
|
+
* {@link CryptoApi | `CryptoApi`} interface.
|
|
72
|
+
*/
|
|
73
|
+
export class AesGcmAlgorithm extends CryptoAlgorithm
|
|
74
|
+
implements Cipher<AesGcmParams, AesGcmParams>,
|
|
75
|
+
KeyConverter,
|
|
76
|
+
KeyGenerator<AesGcmGenerateKeyParams, Jwk> {
|
|
77
|
+
|
|
78
|
+
public async bytesToPrivateKey({ privateKeyBytes }: BytesToPrivateKeyParams): Promise<Jwk> {
|
|
79
|
+
// Convert the byte array to a JWK.
|
|
80
|
+
const privateKey = await AesGcm.bytesToPrivateKey({ privateKeyBytes });
|
|
81
|
+
|
|
82
|
+
// Set the `alg` property based on the key length.
|
|
83
|
+
privateKey.alg = { 16: 'A128GCM', 24: 'A192GCM', 32: 'A256GCM' }[privateKeyBytes.length];
|
|
84
|
+
|
|
85
|
+
return privateKey;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Decrypts the provided data using AES-GCM.
|
|
90
|
+
*
|
|
91
|
+
* @remarks
|
|
92
|
+
* This method performs AES-GCM decryption on the given encrypted data using the specified key.
|
|
93
|
+
* It requires an initialization vector (IV), the encrypted data along with the decryption key,
|
|
94
|
+
* and optionally, additional authenticated data (AAD). The method returns the decrypted data as a
|
|
95
|
+
* Uint8Array. The optional `tagLength` parameter specifies the size in bits of the authentication
|
|
96
|
+
* tag used when encrypting the data. If not specified, the default tag length of 128 bits is
|
|
97
|
+
* used.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
101
|
+
* const aesGcm = new AesGcmAlgorithm();
|
|
102
|
+
* const encryptedData = new Uint8Array([...]); // Encrypted data
|
|
103
|
+
* const iv = new Uint8Array([...]); // Initialization vector used during encryption
|
|
104
|
+
* const additionalData = new Uint8Array([...]); // Optional additional authenticated data
|
|
105
|
+
* const key = { ... }; // A Jwk object representing the AES key
|
|
106
|
+
* const decryptedData = await aesGcm.decrypt({
|
|
107
|
+
* data: encryptedData,
|
|
108
|
+
* iv,
|
|
109
|
+
* additionalData,
|
|
110
|
+
* key,
|
|
111
|
+
* tagLength: 128 // Optional tag length in bits
|
|
112
|
+
* });
|
|
113
|
+
* ```
|
|
114
|
+
*
|
|
115
|
+
* @param params - The parameters for the decryption operation.
|
|
116
|
+
*
|
|
117
|
+
* @returns A Promise that resolves to the decrypted data as a Uint8Array.
|
|
118
|
+
*/
|
|
119
|
+
public async decrypt(params:
|
|
120
|
+
DecryptParams & AesGcmParams
|
|
121
|
+
): Promise<Uint8Array> {
|
|
122
|
+
const plaintext = AesGcm.decrypt(params);
|
|
123
|
+
|
|
124
|
+
return plaintext;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Encrypts the provided data using AES-GCM.
|
|
129
|
+
*
|
|
130
|
+
* @remarks
|
|
131
|
+
* This method performs AES-GCM encryption on the given data using the specified key.
|
|
132
|
+
* It requires an initialization vector (IV), the encrypted data along with the decryption key,
|
|
133
|
+
* and optionally, additional authenticated data (AAD). The method returns the encrypted data as a
|
|
134
|
+
* Uint8Array. The optional `tagLength` parameter specifies the size in bits of the authentication
|
|
135
|
+
* tag generated in the encryption operation and used for authentication in the corresponding
|
|
136
|
+
* decryption. If not specified, the default tag length of 128 bits is used.
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```ts
|
|
140
|
+
* const aesGcm = new AesGcmAlgorithm();
|
|
141
|
+
* const data = new TextEncoder().encode('Messsage');
|
|
142
|
+
* const iv = new Uint8Array([...]); // Initialization vector
|
|
143
|
+
* const additionalData = new Uint8Array([...]); // Optional additional authenticated data
|
|
144
|
+
* const key = { ... }; // A Jwk object representing an AES key
|
|
145
|
+
* const encryptedData = await aesGcm.encrypt({
|
|
146
|
+
* data,
|
|
147
|
+
* iv,
|
|
148
|
+
* additionalData,
|
|
149
|
+
* key,
|
|
150
|
+
* tagLength: 128 // Optional tag length in bits
|
|
151
|
+
* });
|
|
152
|
+
* ```
|
|
153
|
+
*
|
|
154
|
+
* @param params - The parameters for the encryption operation.
|
|
155
|
+
*
|
|
156
|
+
* @returns A Promise that resolves to the encrypted data as a Uint8Array.
|
|
157
|
+
*/
|
|
158
|
+
public async encrypt(params:
|
|
159
|
+
EncryptParams & AesGcmParams
|
|
160
|
+
): Promise<Uint8Array> {
|
|
161
|
+
const ciphertext = AesGcm.encrypt(params);
|
|
162
|
+
|
|
163
|
+
return ciphertext;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Generates a symmetric key for AES in Galois/Counter Mode (GCM) in JSON Web Key (JWK) format.
|
|
168
|
+
*
|
|
169
|
+
* @remarks
|
|
170
|
+
* This method generates a symmetric AES key for use in GCM mode, based on the specified
|
|
171
|
+
* `algorithm` parameter which determines the key length. It uses cryptographically secure random
|
|
172
|
+
* number generation to ensure the uniqueness and security of the key. The key is returned in JWK
|
|
173
|
+
* format.
|
|
174
|
+
*
|
|
175
|
+
* The generated key includes the following components:
|
|
176
|
+
* - `kty`: Key Type, set to 'oct' for Octet Sequence.
|
|
177
|
+
* - `k`: The symmetric key component, base64url-encoded.
|
|
178
|
+
* - `kid`: Key ID, generated based on the JWK thumbprint.
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```ts
|
|
182
|
+
* const aesGcm = new AesGcmAlgorithm();
|
|
183
|
+
* const privateKey = await aesGcm.generateKey({ algorithm: 'A256GCM' });
|
|
184
|
+
* ```
|
|
185
|
+
*
|
|
186
|
+
* @param params - The parameters for the key generation.
|
|
187
|
+
*
|
|
188
|
+
* @returns A Promise that resolves to the generated symmetric key in JWK format.
|
|
189
|
+
*/
|
|
190
|
+
public async generateKey({ algorithm }:
|
|
191
|
+
AesGcmGenerateKeyParams
|
|
192
|
+
): Promise<Jwk> {
|
|
193
|
+
// Map algorithm name to key length.
|
|
194
|
+
const length = { A128GCM: 128, A192GCM: 192, A256GCM: 256 }[algorithm] as 128 | 192 | 256;
|
|
195
|
+
|
|
196
|
+
// Generate a random private key.
|
|
197
|
+
const privateKey = await AesGcm.generateKey({ length });
|
|
198
|
+
|
|
199
|
+
// Set the `alg` property based on the specified algorithm.
|
|
200
|
+
privateKey.alg = algorithm;
|
|
201
|
+
|
|
202
|
+
return privateKey;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
public async privateKeyToBytes({ privateKey }: PrivateKeyToBytesParams): Promise<Uint8Array> {
|
|
206
|
+
// Convert the JWK to a byte array.
|
|
207
|
+
const privateKeyBytes = await AesGcm.privateKeyToBytes({ privateKey });
|
|
208
|
+
|
|
209
|
+
return privateKeyBytes;
|
|
210
|
+
}
|
|
211
|
+
}
|