mppx 0.8.15 → 0.8.17
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/CHANGELOG.md +36 -0
- package/dist/Challenge.d.ts.map +1 -1
- package/dist/Challenge.js +40 -35
- package/dist/Challenge.js.map +1 -1
- package/dist/Constants.d.ts +17 -17
- package/dist/Constants.d.ts.map +1 -1
- package/dist/Credential.d.ts.map +1 -1
- package/dist/Errors.d.ts +3 -3
- package/dist/Errors.d.ts.map +1 -1
- package/dist/Errors.js.map +1 -1
- package/dist/Method.d.ts +35 -5
- package/dist/Method.d.ts.map +1 -1
- package/dist/Method.js +7 -22
- package/dist/Method.js.map +1 -1
- package/dist/Store.d.ts +19 -0
- package/dist/Store.d.ts.map +1 -1
- package/dist/Store.js +43 -0
- package/dist/Store.js.map +1 -1
- package/dist/attestation/Client.d.ts +17 -0
- package/dist/attestation/Client.d.ts.map +1 -0
- package/dist/attestation/Client.js +28 -0
- package/dist/attestation/Client.js.map +1 -0
- package/dist/attestation/Constants.d.ts +15 -0
- package/dist/attestation/Constants.d.ts.map +1 -0
- package/dist/attestation/Constants.js +15 -0
- package/dist/attestation/Constants.js.map +1 -0
- package/dist/attestation/Server.d.ts +4 -0
- package/dist/attestation/Server.d.ts.map +1 -0
- package/dist/attestation/Server.js +8 -0
- package/dist/attestation/Server.js.map +1 -0
- package/dist/attestation/Types.d.ts +76 -0
- package/dist/attestation/Types.d.ts.map +1 -0
- package/dist/attestation/Types.js +2 -0
- package/dist/attestation/Types.js.map +1 -0
- package/dist/attestation/index.d.ts +6 -0
- package/dist/attestation/index.d.ts.map +1 -0
- package/dist/attestation/index.js +6 -0
- package/dist/attestation/index.js.map +1 -0
- package/dist/attestation/internal/HttpMessageSignature.d.ts +73 -0
- package/dist/attestation/internal/HttpMessageSignature.d.ts.map +1 -0
- package/dist/attestation/internal/HttpMessageSignature.js +320 -0
- package/dist/attestation/internal/HttpMessageSignature.js.map +1 -0
- package/dist/attestation/internal/SigningContext.d.ts +4 -0
- package/dist/attestation/internal/SigningContext.d.ts.map +1 -0
- package/dist/attestation/internal/SigningContext.js +11 -0
- package/dist/attestation/internal/SigningContext.js.map +1 -0
- package/dist/cli/account.d.ts +14 -14
- package/dist/cli/account.d.ts.map +1 -1
- package/dist/cli/cli.d.ts +6 -6
- package/dist/cli/cli.d.ts.map +1 -1
- package/dist/cli/cli.js +1 -0
- package/dist/cli/cli.js.map +1 -1
- package/dist/cli/plugins/tempo.js.map +1 -1
- package/dist/cli/sessions/commands.d.ts +4 -4
- package/dist/cli/sessions/commands.d.ts.map +1 -1
- package/dist/cli/sessions/commands.js.map +1 -1
- package/dist/cli/sessions/store.d.ts.map +1 -1
- package/dist/cli/sessions/store.js.map +1 -1
- package/dist/cli/utils.d.ts +1 -1
- package/dist/cli/utils.d.ts.map +1 -1
- package/dist/cli/utils.js.map +1 -1
- package/dist/cli/validate/discovery.js.map +1 -1
- package/dist/cli/validate/index.d.ts +3 -3
- package/dist/cli/validate/index.d.ts.map +1 -1
- package/dist/client/Mppx.d.ts +3 -0
- package/dist/client/Mppx.d.ts.map +1 -1
- package/dist/client/Mppx.js +13 -5
- package/dist/client/Mppx.js.map +1 -1
- package/dist/client/Transport.d.ts +3 -5
- package/dist/client/Transport.d.ts.map +1 -1
- package/dist/client/Transport.js +1 -17
- package/dist/client/Transport.js.map +1 -1
- package/dist/client/internal/Fetch.d.ts.map +1 -1
- package/dist/client/internal/Fetch.js +2 -6
- package/dist/client/internal/Fetch.js.map +1 -1
- package/dist/client/node.js.map +1 -1
- package/dist/discovery/OpenApi.d.ts +3 -5
- package/dist/discovery/OpenApi.d.ts.map +1 -1
- package/dist/discovery/OpenApi.js +13 -34
- package/dist/discovery/OpenApi.js.map +1 -1
- package/dist/discovery/internal/Metadata.d.ts +20 -0
- package/dist/discovery/internal/Metadata.d.ts.map +1 -0
- package/dist/discovery/internal/Metadata.js +36 -0
- package/dist/discovery/internal/Metadata.js.map +1 -0
- package/dist/evm/Methods.d.ts +11 -11
- package/dist/evm/Methods.d.ts.map +1 -1
- package/dist/evm/Types.d.ts +17 -17
- package/dist/evm/Types.d.ts.map +1 -1
- package/dist/evm/client/Charge.d.ts +11 -11
- package/dist/evm/client/Methods.d.ts +11 -11
- package/dist/evm/server/Charge.d.ts +1 -1
- package/dist/evm/server/Charge.d.ts.map +1 -1
- package/dist/evm/server/Charge.js +2 -0
- package/dist/evm/server/Charge.js.map +1 -1
- package/dist/evm/server/Methods.d.ts +11 -11
- package/dist/internal/HeaderCodec.d.ts +2 -2
- package/dist/internal/HeaderCodec.d.ts.map +1 -1
- package/dist/internal/types.d.ts +6 -0
- package/dist/internal/types.d.ts.map +1 -1
- package/dist/middlewares/elysia.js.map +1 -1
- package/dist/middlewares/express.js.map +1 -1
- package/dist/middlewares/hono.js.map +1 -1
- package/dist/middlewares/nextjs.js.map +1 -1
- package/dist/proxy/Proxy.d.ts +2 -0
- package/dist/proxy/Proxy.d.ts.map +1 -1
- package/dist/proxy/Proxy.js +117 -9
- package/dist/proxy/Proxy.js.map +1 -1
- package/dist/proxy/Service.d.ts +36 -1
- package/dist/proxy/Service.d.ts.map +1 -1
- package/dist/proxy/Service.js +9 -8
- package/dist/proxy/Service.js.map +1 -1
- package/dist/proxy/services/anthropic.d.ts.map +1 -1
- package/dist/proxy/services/anthropic.js +1 -0
- package/dist/proxy/services/anthropic.js.map +1 -1
- package/dist/proxy/services/openai.d.ts.map +1 -1
- package/dist/proxy/services/openai.js +1 -0
- package/dist/proxy/services/openai.js.map +1 -1
- package/dist/proxy/services/stripe.d.ts.map +1 -1
- package/dist/proxy/services/stripe.js +1 -0
- package/dist/proxy/services/stripe.js.map +1 -1
- package/dist/server/Mppx.d.ts +75 -13
- package/dist/server/Mppx.d.ts.map +1 -1
- package/dist/server/Mppx.js +201 -23
- package/dist/server/Mppx.js.map +1 -1
- package/dist/server/internal/html/config.d.ts +9 -9
- package/dist/server/internal/html/config.d.ts.map +1 -1
- package/dist/server/internal/html/constants.d.ts +17 -17
- package/dist/server/internal/html/constants.d.ts.map +1 -1
- package/dist/stripe/Methods.d.ts +10 -10
- package/dist/stripe/Methods.d.ts.map +1 -1
- package/dist/stripe/client/Charge.d.ts +10 -10
- package/dist/stripe/client/Methods.d.ts +10 -10
- package/dist/stripe/internal/constants.d.ts +1 -1
- package/dist/stripe/internal/constants.js +1 -1
- package/dist/stripe/internal/types.d.ts +1 -0
- package/dist/stripe/internal/types.d.ts.map +1 -1
- package/dist/stripe/server/Charge.d.ts +11 -11
- package/dist/stripe/server/Charge.d.ts.map +1 -1
- package/dist/stripe/server/Charge.js +49 -1
- package/dist/stripe/server/Charge.js.map +1 -1
- package/dist/stripe/server/Methods.d.ts +137 -48
- package/dist/stripe/server/Methods.d.ts.map +1 -1
- package/dist/stripe/server/Methods.js +259 -4
- package/dist/stripe/server/Methods.js.map +1 -1
- package/dist/stripe/server/internal/deposit-address.d.ts +13 -0
- package/dist/stripe/server/internal/deposit-address.d.ts.map +1 -0
- package/dist/stripe/server/internal/deposit-address.js +28 -0
- package/dist/stripe/server/internal/deposit-address.js.map +1 -0
- package/dist/stripe/server/internal/html.gen.d.ts +1 -1
- package/dist/stripe/server/internal/html.gen.d.ts.map +1 -1
- package/dist/stripe/server/internal/html.gen.js +1 -1
- package/dist/stripe/server/internal/html.gen.js.map +1 -1
- package/dist/stripe/server/internal/record-payment.d.ts +15 -0
- package/dist/stripe/server/internal/record-payment.d.ts.map +1 -0
- package/dist/stripe/server/internal/record-payment.js +42 -0
- package/dist/stripe/server/internal/record-payment.js.map +1 -0
- package/dist/stripe/server/internal/request.d.ts +25 -0
- package/dist/stripe/server/internal/request.d.ts.map +1 -0
- package/dist/stripe/server/internal/request.js +29 -0
- package/dist/stripe/server/internal/request.js.map +1 -0
- package/dist/tap/Constants.d.ts +28 -0
- package/dist/tap/Constants.d.ts.map +1 -0
- package/dist/tap/Constants.js +32 -0
- package/dist/tap/Constants.js.map +1 -0
- package/dist/tap/Types.d.ts +11 -0
- package/dist/tap/Types.d.ts.map +1 -0
- package/dist/tap/Types.js +2 -0
- package/dist/tap/Types.js.map +1 -0
- package/dist/tap/client/index.d.ts +26 -0
- package/dist/tap/client/index.d.ts.map +1 -0
- package/dist/tap/client/index.js +33 -0
- package/dist/tap/client/index.js.map +1 -0
- package/dist/tap/index.d.ts +5 -0
- package/dist/tap/index.d.ts.map +1 -0
- package/dist/tap/index.js +5 -0
- package/dist/tap/index.js.map +1 -0
- package/dist/tap/server/index.d.ts +20 -0
- package/dist/tap/server/index.d.ts.map +1 -0
- package/dist/tap/server/index.js +36 -0
- package/dist/tap/server/index.js.map +1 -0
- package/dist/tempo/Attribution.d.ts +1 -1
- package/dist/tempo/Methods.d.ts +60 -60
- package/dist/tempo/Methods.d.ts.map +1 -1
- package/dist/tempo/Proof.d.ts +16 -16
- package/dist/tempo/client/Charge.d.ts +19 -19
- package/dist/tempo/client/Charge.d.ts.map +1 -1
- package/dist/tempo/client/Charge.js +1 -7
- package/dist/tempo/client/Charge.js.map +1 -1
- package/dist/tempo/client/Methods.d.ts +38 -38
- package/dist/tempo/client/Methods.js.map +1 -1
- package/dist/tempo/client/Subscription.d.ts +23 -23
- package/dist/tempo/client/Subscription.js.map +1 -1
- package/dist/tempo/internal/address.d.ts +2 -1
- package/dist/tempo/internal/address.d.ts.map +1 -1
- package/dist/tempo/internal/address.js +3 -1
- package/dist/tempo/internal/address.js.map +1 -1
- package/dist/tempo/internal/auto-swap.d.ts.map +1 -1
- package/dist/tempo/internal/auto-swap.js +4 -19
- package/dist/tempo/internal/auto-swap.js.map +1 -1
- package/dist/tempo/internal/defaults.d.ts +6 -6
- package/dist/tempo/internal/defaults.d.ts.map +1 -1
- package/dist/tempo/internal/fee-payer.d.ts +12 -12
- package/dist/tempo/internal/fee-payer.d.ts.map +1 -1
- package/dist/tempo/internal/fee-payer.js.map +1 -1
- package/dist/tempo/internal/proof.d.ts +17 -17
- package/dist/tempo/internal/proof.d.ts.map +1 -1
- package/dist/tempo/legacy/client/Session.d.ts +20 -20
- package/dist/tempo/legacy/client/Session.js.map +1 -1
- package/dist/tempo/legacy/client/SessionManager.js.map +1 -1
- package/dist/tempo/legacy/index.d.ts +1 -3
- package/dist/tempo/legacy/index.d.ts.map +1 -1
- package/dist/tempo/legacy/index.js +1 -3
- package/dist/tempo/legacy/index.js.map +1 -1
- package/dist/tempo/legacy/session/escrow.abi.d.ts +374 -374
- package/dist/tempo/legacy/session/escrow.abi.d.ts.map +1 -1
- package/dist/tempo/server/Charge.d.ts +25 -11
- package/dist/tempo/server/Charge.d.ts.map +1 -1
- package/dist/tempo/server/Charge.js +44 -39
- package/dist/tempo/server/Charge.js.map +1 -1
- package/dist/tempo/server/Methods.d.ts +37 -52
- package/dist/tempo/server/Methods.d.ts.map +1 -1
- package/dist/tempo/server/Methods.js +0 -14
- package/dist/tempo/server/Methods.js.map +1 -1
- package/dist/tempo/server/Relay.d.ts +1 -1
- package/dist/tempo/server/Relay.d.ts.map +1 -1
- package/dist/tempo/server/Relay.js +2 -2
- package/dist/tempo/server/Relay.js.map +1 -1
- package/dist/tempo/server/Subscription.d.ts +25 -25
- package/dist/tempo/server/Subscription.d.ts.map +1 -1
- package/dist/tempo/server/Subscription.js +2 -0
- package/dist/tempo/server/Subscription.js.map +1 -1
- package/dist/tempo/server/index.d.ts +1 -1
- package/dist/tempo/server/index.d.ts.map +1 -1
- package/dist/tempo/server/index.js +1 -1
- package/dist/tempo/server/index.js.map +1 -1
- package/dist/tempo/server/internal/html.gen.d.ts +1 -1
- package/dist/tempo/server/internal/html.gen.d.ts.map +1 -1
- package/dist/tempo/server/internal/html.gen.js +1 -1
- package/dist/tempo/server/internal/html.gen.js.map +1 -1
- package/dist/tempo/server/internal/transport.d.ts +2 -0
- package/dist/tempo/server/internal/transport.d.ts.map +1 -1
- package/dist/tempo/server/internal/transport.js +9 -2
- package/dist/tempo/server/internal/transport.js.map +1 -1
- package/dist/tempo/session/client/ChannelOps.js.map +1 -1
- package/dist/tempo/session/client/CredentialState.d.ts +1 -1
- package/dist/tempo/session/client/CredentialState.js.map +1 -1
- package/dist/tempo/session/client/ReceiptCoordinator.js.map +1 -1
- package/dist/tempo/session/client/Runtime.js.map +1 -1
- package/dist/tempo/session/client/Session.d.ts +19 -19
- package/dist/tempo/session/client/Session.js.map +1 -1
- package/dist/tempo/session/client/SessionManager.js.map +1 -1
- package/dist/tempo/session/client/Transports.d.ts.map +1 -1
- package/dist/tempo/session/precompile/Chain.d.ts +27 -0
- package/dist/tempo/session/precompile/Chain.d.ts.map +1 -1
- package/dist/tempo/session/precompile/Chain.js +68 -7
- package/dist/tempo/session/precompile/Chain.js.map +1 -1
- package/dist/tempo/session/precompile/Protocol.js.map +1 -1
- package/dist/tempo/session/precompile/Voucher.d.ts +4 -4
- package/dist/tempo/session/precompile/Voucher.d.ts.map +1 -1
- package/dist/tempo/session/precompile/escrow.abi.d.ts +306 -306
- package/dist/tempo/session/precompile/escrow.abi.d.ts.map +1 -1
- package/dist/tempo/session/server/ChannelStore.d.ts +9 -0
- package/dist/tempo/session/server/ChannelStore.d.ts.map +1 -1
- package/dist/tempo/session/server/ChannelStore.js +16 -8
- package/dist/tempo/session/server/ChannelStore.js.map +1 -1
- package/dist/tempo/session/server/CredentialVerification.d.ts +30 -13
- package/dist/tempo/session/server/CredentialVerification.d.ts.map +1 -1
- package/dist/tempo/session/server/CredentialVerification.js +207 -13
- package/dist/tempo/session/server/CredentialVerification.js.map +1 -1
- package/dist/tempo/session/server/MeteredStream.d.ts +3 -0
- package/dist/tempo/session/server/MeteredStream.d.ts.map +1 -1
- package/dist/tempo/session/server/MeteredStream.js +3 -1
- package/dist/tempo/session/server/MeteredStream.js.map +1 -1
- package/dist/tempo/session/server/Session.d.ts +32 -21
- package/dist/tempo/session/server/Session.d.ts.map +1 -1
- package/dist/tempo/session/server/Session.js +116 -53
- package/dist/tempo/session/server/Session.js.map +1 -1
- package/dist/tempo/session/server/Sse.d.ts +3 -1
- package/dist/tempo/session/server/Sse.d.ts.map +1 -1
- package/dist/tempo/session/server/Sse.js +2 -1
- package/dist/tempo/session/server/Sse.js.map +1 -1
- package/dist/tempo/session/server/Transports.d.ts +1 -1
- package/dist/tempo/session/server/Transports.d.ts.map +1 -1
- package/dist/tempo/session/server/Transports.js +1 -0
- package/dist/tempo/session/server/Transports.js.map +1 -1
- package/dist/tempo/session/server/Ws.d.ts +6 -1
- package/dist/tempo/session/server/Ws.d.ts.map +1 -1
- package/dist/tempo/session/server/Ws.js +1 -0
- package/dist/tempo/session/server/Ws.js.map +1 -1
- package/dist/tempo/subscription/KeyAuthorization.d.ts +39 -39
- package/dist/tempo/subscription/KeyAuthorization.d.ts.map +1 -1
- package/dist/viem/Account.d.ts.map +1 -1
- package/dist/viem/Account.js.map +1 -1
- package/dist/web-bot-auth/Constants.d.ts +20 -0
- package/dist/web-bot-auth/Constants.d.ts.map +1 -0
- package/dist/web-bot-auth/Constants.js +24 -0
- package/dist/web-bot-auth/Constants.js.map +1 -0
- package/dist/web-bot-auth/Types.d.ts +10 -0
- package/dist/web-bot-auth/Types.d.ts.map +1 -0
- package/dist/web-bot-auth/Types.js +2 -0
- package/dist/web-bot-auth/Types.js.map +1 -0
- package/dist/web-bot-auth/client/index.d.ts +29 -0
- package/dist/web-bot-auth/client/index.d.ts.map +1 -0
- package/dist/web-bot-auth/client/index.js +64 -0
- package/dist/web-bot-auth/client/index.js.map +1 -0
- package/dist/web-bot-auth/index.d.ts +7 -0
- package/dist/web-bot-auth/index.d.ts.map +1 -0
- package/dist/web-bot-auth/index.js +7 -0
- package/dist/web-bot-auth/index.js.map +1 -0
- package/dist/web-bot-auth/internal/JwkThumbprint.d.ts +5 -0
- package/dist/web-bot-auth/internal/JwkThumbprint.d.ts.map +1 -0
- package/dist/web-bot-auth/internal/JwkThumbprint.js +20 -0
- package/dist/web-bot-auth/internal/JwkThumbprint.js.map +1 -0
- package/dist/web-bot-auth/internal/SignatureAgent.d.ts +3 -0
- package/dist/web-bot-auth/internal/SignatureAgent.d.ts.map +1 -0
- package/dist/web-bot-auth/internal/SignatureAgent.js +18 -0
- package/dist/web-bot-auth/internal/SignatureAgent.js.map +1 -0
- package/dist/web-bot-auth/server/index.d.ts +35 -0
- package/dist/web-bot-auth/server/index.d.ts.map +1 -0
- package/dist/web-bot-auth/server/index.js +88 -0
- package/dist/web-bot-auth/server/index.js.map +1 -0
- package/dist/x402/Assets.d.ts.map +1 -1
- package/dist/x402/Types.d.ts +6 -6
- package/dist/x402/Types.d.ts.map +1 -1
- package/dist/x402/server/EvmCharge.d.ts.map +1 -1
- package/dist/x402/server/EvmCharge.js +32 -20
- package/dist/x402/server/EvmCharge.js.map +1 -1
- package/package.json +19 -3
- package/src/Challenge.fuzz.test.ts +80 -47
- package/src/Challenge.test.ts +65 -0
- package/src/Challenge.ts +39 -35
- package/src/Method.ts +82 -68
- package/src/Store.test-d.ts +16 -0
- package/src/Store.test.ts +50 -0
- package/src/Store.ts +68 -0
- package/src/attestation/Attestation.integration.test.ts +208 -0
- package/src/attestation/Client.test.ts +83 -0
- package/src/attestation/Client.ts +34 -0
- package/src/attestation/Constants.ts +15 -0
- package/src/attestation/Server.test.ts +60 -0
- package/src/attestation/Server.ts +12 -0
- package/src/attestation/Types.test-d.ts +54 -0
- package/src/attestation/Types.ts +77 -0
- package/src/attestation/index.ts +5 -0
- package/src/attestation/internal/HttpMessageSignature.test.ts +101 -0
- package/src/attestation/internal/HttpMessageSignature.ts +429 -0
- package/src/attestation/internal/SigningContext.ts +13 -0
- package/src/bin.js +2 -0
- package/src/cli/cli.ts +1 -0
- package/src/client/Mppx.test-d.ts +17 -0
- package/src/client/Mppx.test.ts +14 -14
- package/src/client/Mppx.ts +25 -4
- package/src/client/Transport.test.ts +12 -45
- package/src/client/Transport.ts +3 -24
- package/src/client/internal/Fetch.ts +2 -6
- package/src/discovery/OpenApi.test.ts +170 -0
- package/src/discovery/OpenApi.ts +16 -48
- package/src/discovery/internal/Metadata.ts +51 -0
- package/src/evm/server/Charge.ts +6 -1
- package/src/internal/AcceptPayment.test.ts +12 -8
- package/src/internal/types.ts +9 -0
- package/src/mcp/client/McpClient.integration.test.ts +19 -32
- package/src/middlewares/elysia.test.ts +2 -12
- package/src/middlewares/express.test.ts +2 -12
- package/src/middlewares/hono.test.ts +6 -9
- package/src/middlewares/nextjs.test.ts +2 -12
- package/src/proxy/Proxy.test.ts +26 -19
- package/src/proxy/Proxy.ts +147 -9
- package/src/proxy/Proxy.upstreamError.test.ts +364 -0
- package/src/proxy/Service.test.ts +73 -3
- package/src/proxy/Service.ts +50 -23
- package/src/proxy/services/anthropic.ts +1 -0
- package/src/proxy/services/hooks.test-d.ts +14 -0
- package/src/proxy/services/hooks.test.ts +44 -0
- package/src/proxy/services/openai.ts +1 -0
- package/src/proxy/services/stripe.ts +1 -0
- package/src/server/Methods.test-d.ts +88 -0
- package/src/server/Methods.test.ts +69 -0
- package/src/server/Mppx.test-d.ts +141 -7
- package/src/server/Mppx.test.ts +1017 -119
- package/src/server/Mppx.ts +350 -54
- package/src/stripe/internal/constants.ts +1 -1
- package/src/stripe/internal/types.ts +1 -0
- package/src/stripe/server/Charge.test-d.ts +16 -1
- package/src/stripe/server/Charge.test.ts +79 -0
- package/src/stripe/server/Charge.ts +54 -1
- package/src/stripe/server/Methods.test-d.ts +157 -0
- package/src/stripe/server/Methods.test.ts +403 -0
- package/src/stripe/server/Methods.ts +423 -6
- package/src/stripe/server/internal/deposit-address.ts +57 -0
- package/src/stripe/server/internal/html/node_modules/.bin/mppx +3 -3
- package/src/stripe/server/internal/html/package.json +1 -1
- package/src/stripe/server/internal/html.gen.ts +1 -1
- package/src/stripe/server/internal/record-payment.ts +66 -0
- package/src/stripe/server/internal/request.ts +49 -0
- package/src/tap/Constants.ts +32 -0
- package/src/tap/Tap.test.ts +125 -0
- package/src/tap/Types.ts +11 -0
- package/src/tap/client/index.ts +54 -0
- package/src/tap/index.ts +4 -0
- package/src/tap/server/index.ts +48 -0
- package/src/tempo/PublicExports.test-d.ts +3 -3
- package/src/tempo/client/Charge.ts +1 -19
- package/src/tempo/internal/address.test.ts +42 -0
- package/src/tempo/internal/address.ts +3 -3
- package/src/tempo/internal/auto-swap.test.ts +4 -4
- package/src/tempo/internal/auto-swap.ts +7 -50
- package/src/tempo/legacy/README.md +5 -5
- package/src/tempo/legacy/index.ts +1 -3
- package/src/tempo/server/AtomicStore.test-d.ts +13 -0
- package/src/tempo/server/Charge.test.ts +19 -84
- package/src/tempo/server/Charge.ts +83 -55
- package/src/tempo/server/Methods.ts +0 -20
- package/src/tempo/server/Relay.test.ts +5 -5
- package/src/tempo/server/Relay.ts +2 -2
- package/src/tempo/server/Subscription.ts +4 -1
- package/src/tempo/server/index.ts +1 -1
- package/src/tempo/server/internal/html/node_modules/.bin/mppx +3 -3
- package/src/tempo/server/internal/html/package.json +1 -1
- package/src/tempo/server/internal/html.gen.ts +1 -1
- package/src/tempo/server/internal/transport.test.ts +22 -3
- package/src/tempo/server/internal/transport.ts +15 -3
- package/src/tempo/session/README.md +112 -0
- package/src/tempo/session/precompile/Chain.ts +131 -11
- package/src/tempo/session/server/ChannelStore.ts +33 -12
- package/src/tempo/session/server/CredentialVerification.test.ts +4 -4
- package/src/tempo/session/server/CredentialVerification.ts +340 -28
- package/src/tempo/session/server/MeteredStream.ts +5 -1
- package/src/tempo/session/server/Session.test.ts +428 -43
- package/src/tempo/session/server/Session.ts +159 -60
- package/src/tempo/session/server/Sse.test.ts +77 -0
- package/src/tempo/session/server/Sse.ts +8 -1
- package/src/tempo/session/server/Transports.ts +2 -1
- package/src/tempo/session/server/Ws.test.ts +171 -0
- package/src/tempo/session/server/Ws.ts +7 -1
- package/src/web-bot-auth/Constants.ts +24 -0
- package/src/web-bot-auth/Types.ts +9 -0
- package/src/web-bot-auth/WebBotAuth.test.ts +182 -0
- package/src/web-bot-auth/client/index.ts +84 -0
- package/src/web-bot-auth/index.ts +6 -0
- package/src/web-bot-auth/internal/JwkThumbprint.ts +21 -0
- package/src/web-bot-auth/internal/SignatureAgent.ts +18 -0
- package/src/web-bot-auth/server/index.ts +113 -0
- package/src/x402/Exact.e2e.test.ts +121 -81
- package/src/x402/Exact.localnet.test.ts +1 -1
- package/src/x402/server/EvmCharge.ts +35 -19
- package/dist/tempo/legacy/server/Session.d.ts +0 -208
- package/dist/tempo/legacy/server/Session.d.ts.map +0 -1
- package/dist/tempo/legacy/server/Session.js +0 -698
- package/dist/tempo/legacy/server/Session.js.map +0 -1
- package/dist/tempo/legacy/server/index.d.ts +0 -5
- package/dist/tempo/legacy/server/index.d.ts.map +0 -1
- package/dist/tempo/legacy/server/index.js +0 -5
- package/dist/tempo/legacy/server/index.js.map +0 -1
- package/dist/tempo/legacy/session/ChannelStore.d.ts +0 -22
- package/dist/tempo/legacy/session/ChannelStore.d.ts.map +0 -1
- package/dist/tempo/legacy/session/ChannelStore.js +0 -6
- package/dist/tempo/legacy/session/ChannelStore.js.map +0 -1
- package/src/tempo/legacy/server/Defaults.test-d.ts +0 -9
- package/src/tempo/legacy/server/Session.test.ts +0 -6370
- package/src/tempo/legacy/server/Session.ts +0 -1024
- package/src/tempo/legacy/server/index.ts +0 -4
- package/src/tempo/legacy/session/ChannelStore.test.ts +0 -58
- package/src/tempo/legacy/session/ChannelStore.ts +0 -39
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Verified Web Bot Auth HTTPS-directory profile request signature. */
|
|
2
|
+
export type VerifiedRequest = {
|
|
3
|
+
/** Public-key thumbprint advertised by the bot. */
|
|
4
|
+
keyId: string
|
|
5
|
+
/** HTTPS directory origin carried in the signed `Signature-Agent` header. */
|
|
6
|
+
signatureAgent: string
|
|
7
|
+
/** Signature nonce supplied by the bot. */
|
|
8
|
+
nonce: string
|
|
9
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import * as Attestation from 'mppx/attestation'
|
|
2
|
+
import * as WebBotAuth from 'mppx/attestation/web-bot-auth'
|
|
3
|
+
import { expect, test } from 'vp/test'
|
|
4
|
+
import { jwkThumbprint, keyPair, rsaKeyPair } from '~test/Attestation.js'
|
|
5
|
+
|
|
6
|
+
import * as HttpMessageSignature from '../attestation/internal/HttpMessageSignature.js'
|
|
7
|
+
|
|
8
|
+
test('emits and verifies a signed Signature-Agent member', async () => {
|
|
9
|
+
const keys = await keyPair()
|
|
10
|
+
const keyId = await jwkThumbprint(keys.publicKey)
|
|
11
|
+
const signatureAgent = 'https://agent.example'
|
|
12
|
+
const signed = await WebBotAuth.Client.signer({
|
|
13
|
+
expiresIn: WebBotAuth.Constants.defaultSignatureLifetime + 1,
|
|
14
|
+
key: keys.privateKey,
|
|
15
|
+
keyId,
|
|
16
|
+
signatureAgent: `${signatureAgent}/`,
|
|
17
|
+
}).sign(new Request('https://merchant.example/resource'))
|
|
18
|
+
|
|
19
|
+
expect(signed.headers.get(WebBotAuth.Constants.signatureAgentHeader)).toBe(
|
|
20
|
+
`${WebBotAuth.Constants.label}="${signatureAgent}"`,
|
|
21
|
+
)
|
|
22
|
+
expect(signed.headers.get(Attestation.Headers.signatureInput)).toContain(
|
|
23
|
+
`"signature-agent";key="${WebBotAuth.Constants.label}"`,
|
|
24
|
+
)
|
|
25
|
+
expect(
|
|
26
|
+
await WebBotAuth.Server.verifier({
|
|
27
|
+
keyResolver: () => keys.publicKey,
|
|
28
|
+
maxAge: WebBotAuth.Constants.defaultSignatureLifetime,
|
|
29
|
+
nonceStore: Attestation.Store.memory(),
|
|
30
|
+
}).verify(signed),
|
|
31
|
+
).toMatchObject({ status: 'invalid' })
|
|
32
|
+
expect(
|
|
33
|
+
await WebBotAuth.Server.verifier({
|
|
34
|
+
keyResolver: () => keys.publicKey,
|
|
35
|
+
nonceStore: Attestation.Store.memory(),
|
|
36
|
+
}).verify(signed),
|
|
37
|
+
).toMatchObject({
|
|
38
|
+
status: 'verified',
|
|
39
|
+
value: { keyId, signatureAgent },
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
test('signs and verifies RSA-PSS SHA-512', async () => {
|
|
44
|
+
const keys = await rsaKeyPair()
|
|
45
|
+
const keyId = await jwkThumbprint(keys.publicKey)
|
|
46
|
+
const algorithms: Attestation.SignatureAlgorithm[] = []
|
|
47
|
+
const signed = await WebBotAuth.Client.signer({
|
|
48
|
+
key: keys.privateKey,
|
|
49
|
+
keyId,
|
|
50
|
+
signatureAgent: 'https://agent.example',
|
|
51
|
+
}).sign(new Request('https://merchant.example/resource'))
|
|
52
|
+
const result = await WebBotAuth.Server.verifier({
|
|
53
|
+
keyResolver({ algorithm, keyId: candidate }) {
|
|
54
|
+
algorithms.push(algorithm)
|
|
55
|
+
return candidate === keyId ? keys.publicKey : undefined
|
|
56
|
+
},
|
|
57
|
+
nonceStore: Attestation.Store.memory(),
|
|
58
|
+
}).verify(signed)
|
|
59
|
+
|
|
60
|
+
expect(signed.headers.get(Attestation.Headers.signatureInput)).toContain(
|
|
61
|
+
`alg="${Attestation.Algorithms.rsaPssSha512}"`,
|
|
62
|
+
)
|
|
63
|
+
expect(algorithms).toEqual([Attestation.Algorithms.rsaPssSha512])
|
|
64
|
+
expect(result).toMatchObject({ status: 'verified' })
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
test('preserves directory lookup failures as unverified outcomes', async () => {
|
|
68
|
+
const keys = await keyPair()
|
|
69
|
+
const keyId = await jwkThumbprint(keys.publicKey)
|
|
70
|
+
const signed = await WebBotAuth.Client.signer({
|
|
71
|
+
key: keys.privateKey,
|
|
72
|
+
keyId,
|
|
73
|
+
signatureAgent: 'https://agent.example',
|
|
74
|
+
}).sign(new Request('https://merchant.example/resource'))
|
|
75
|
+
|
|
76
|
+
expect(
|
|
77
|
+
await WebBotAuth.Server.verifier({
|
|
78
|
+
keyResolver: () => undefined,
|
|
79
|
+
nonceStore: Attestation.Store.memory(),
|
|
80
|
+
}).verify(signed),
|
|
81
|
+
).toEqual({
|
|
82
|
+
reason: 'No public key is available for the signature key ID.',
|
|
83
|
+
status: 'unverified',
|
|
84
|
+
})
|
|
85
|
+
expect(
|
|
86
|
+
await WebBotAuth.Server.verifier({
|
|
87
|
+
keyResolver() {
|
|
88
|
+
throw new Error('directory unavailable')
|
|
89
|
+
},
|
|
90
|
+
nonceStore: Attestation.Store.memory(),
|
|
91
|
+
}).verify(signed),
|
|
92
|
+
).toEqual({
|
|
93
|
+
reason: 'The public key could not be resolved.',
|
|
94
|
+
status: 'unverified',
|
|
95
|
+
})
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
test('rejects mismatched keys, non-directory discovery, and header tampering', async () => {
|
|
99
|
+
const advertisedKeys = await keyPair()
|
|
100
|
+
const signingKeys = await keyPair()
|
|
101
|
+
const advertisedKeyId = await jwkThumbprint(advertisedKeys.publicKey)
|
|
102
|
+
const signatureAgent = 'https://agent.example'
|
|
103
|
+
const signed = await WebBotAuth.Client.signer({
|
|
104
|
+
key: signingKeys.privateKey,
|
|
105
|
+
keyId: advertisedKeyId,
|
|
106
|
+
signatureAgent,
|
|
107
|
+
}).sign(new Request('https://merchant.example/resource'))
|
|
108
|
+
const verifier = WebBotAuth.Server.verifier({
|
|
109
|
+
keyResolver: () => signingKeys.publicKey,
|
|
110
|
+
nonceStore: Attestation.Store.memory(),
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
expect(await verifier.verify(signed)).toMatchObject({ status: 'invalid' })
|
|
114
|
+
|
|
115
|
+
const alteredHeaders = new Headers(signed.headers)
|
|
116
|
+
alteredHeaders.set(
|
|
117
|
+
WebBotAuth.Constants.signatureAgentHeader,
|
|
118
|
+
`${WebBotAuth.Constants.label}="https://attacker.example"`,
|
|
119
|
+
)
|
|
120
|
+
expect(
|
|
121
|
+
await WebBotAuth.Server.verifier({
|
|
122
|
+
keyResolver: () => signingKeys.publicKey,
|
|
123
|
+
nonceStore: Attestation.Store.memory(),
|
|
124
|
+
}).verify(new Request(signed, { headers: alteredHeaders })),
|
|
125
|
+
).toMatchObject({ status: 'invalid' })
|
|
126
|
+
|
|
127
|
+
const discoveryHeaders = new Headers({
|
|
128
|
+
[WebBotAuth.Constants.signatureAgentHeader]:
|
|
129
|
+
'webbot="https://agent.example/keys";type=jwks_uri',
|
|
130
|
+
})
|
|
131
|
+
const unsupportedDiscovery = await HttpMessageSignature.sign(
|
|
132
|
+
new Request('https://merchant.example/resource', { headers: discoveryHeaders }),
|
|
133
|
+
{
|
|
134
|
+
components: [
|
|
135
|
+
HttpMessageSignature.Constants.components.authority,
|
|
136
|
+
{
|
|
137
|
+
id: HttpMessageSignature.Constants.components.signatureAgent,
|
|
138
|
+
parameters: new Map([['key', WebBotAuth.Constants.label]]),
|
|
139
|
+
},
|
|
140
|
+
],
|
|
141
|
+
key: advertisedKeys.privateKey,
|
|
142
|
+
keyId: advertisedKeyId,
|
|
143
|
+
label: WebBotAuth.Constants.label,
|
|
144
|
+
tag: WebBotAuth.Constants.tag,
|
|
145
|
+
},
|
|
146
|
+
)
|
|
147
|
+
expect(
|
|
148
|
+
await WebBotAuth.Server.verifier({
|
|
149
|
+
keyResolver: () => advertisedKeys.publicKey,
|
|
150
|
+
nonceStore: Attestation.Store.memory(),
|
|
151
|
+
}).verify(unsupportedDiscovery),
|
|
152
|
+
).toMatchObject({
|
|
153
|
+
reason: 'The Signature-Agent discovery type is not supported by this directory profile.',
|
|
154
|
+
status: 'invalid',
|
|
155
|
+
})
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
test('validates signer and verifier configuration', async () => {
|
|
159
|
+
const keys = await keyPair()
|
|
160
|
+
const keyId = await jwkThumbprint(keys.publicKey)
|
|
161
|
+
const config = { key: keys.privateKey, keyId, signatureAgent: 'https://agent.example' }
|
|
162
|
+
|
|
163
|
+
expect(() => WebBotAuth.Client.signer({ ...config, keyId: 'not-a-thumbprint' })).toThrow(
|
|
164
|
+
'Web Bot Auth keyId must be an RFC 7638 SHA-256 JWK thumbprint.',
|
|
165
|
+
)
|
|
166
|
+
expect(() => WebBotAuth.Client.signer({ ...config, signatureAgent: 'https://' })).toThrow(
|
|
167
|
+
'Signature-Agent must identify a valid HTTPS origin.',
|
|
168
|
+
)
|
|
169
|
+
expect(() =>
|
|
170
|
+
WebBotAuth.Client.signer({ ...config, signatureAgent: 'https://agent.example/keys' }),
|
|
171
|
+
).toThrow('Signature-Agent must identify a valid HTTPS origin.')
|
|
172
|
+
expect(() => WebBotAuth.Client.signer({ ...config, expiresIn: 0 })).toThrow(
|
|
173
|
+
'Web Bot Auth expiresIn must be a positive integer.',
|
|
174
|
+
)
|
|
175
|
+
expect(() =>
|
|
176
|
+
WebBotAuth.Server.verifier({
|
|
177
|
+
keyResolver: () => keys.publicKey,
|
|
178
|
+
maxAge: 0,
|
|
179
|
+
nonceStore: Attestation.Store.memory(),
|
|
180
|
+
}),
|
|
181
|
+
).toThrow('Web Bot Auth maxAge must be a positive integer.')
|
|
182
|
+
})
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { parseDictionary, serializeDictionary } from 'structured-headers'
|
|
2
|
+
import type { Dictionary } from 'structured-headers'
|
|
3
|
+
|
|
4
|
+
import * as HttpMessageSignature from '../../attestation/internal/HttpMessageSignature.js'
|
|
5
|
+
import type * as AttestationTypes from '../../attestation/Types.js'
|
|
6
|
+
import { Constants } from '../Constants.js'
|
|
7
|
+
import * as JwkThumbprint from '../internal/JwkThumbprint.js'
|
|
8
|
+
import * as SignatureAgent from '../internal/SignatureAgent.js'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Creates a Web Bot Auth HTTPS-directory profile request signer.
|
|
12
|
+
*
|
|
13
|
+
* The signed `Signature-Agent` header links the request to the HTTPS origin
|
|
14
|
+
* of an HTTP Message Signatures Directory. This adapter does not support
|
|
15
|
+
* direct key configuration or other Web Bot Auth discovery types. It
|
|
16
|
+
* establishes bot identity only; it does not assert consumer identity or
|
|
17
|
+
* authority to make a payment.
|
|
18
|
+
*/
|
|
19
|
+
export function signer(config: signer.Config): AttestationTypes.Signer<typeof Constants.protocol> {
|
|
20
|
+
const label = config.label ?? Constants.label
|
|
21
|
+
const signatureAgentKey = config.signatureAgentKey ?? label
|
|
22
|
+
const expiresIn = config.expiresIn ?? Constants.defaultSignatureLifetime
|
|
23
|
+
const signatureAgent = SignatureAgent.directoryOrigin(config.signatureAgent)
|
|
24
|
+
if (!JwkThumbprint.is(config.keyId))
|
|
25
|
+
throw new TypeError('Web Bot Auth keyId must be an RFC 7638 SHA-256 JWK thumbprint.')
|
|
26
|
+
if (!signatureAgent) throw new TypeError('Signature-Agent must identify a valid HTTPS origin.')
|
|
27
|
+
if (!Number.isInteger(expiresIn) || expiresIn <= 0)
|
|
28
|
+
throw new RangeError('Web Bot Auth expiresIn must be a positive integer.')
|
|
29
|
+
return {
|
|
30
|
+
protocol: Constants.protocol,
|
|
31
|
+
sign(request, context) {
|
|
32
|
+
const headers = new Headers(request.headers)
|
|
33
|
+
const signatureAgents = parseSignatureAgents(headers)
|
|
34
|
+
if (signatureAgents.has(signatureAgentKey))
|
|
35
|
+
throw new Error(`Signature-Agent member "${signatureAgentKey}" already exists.`)
|
|
36
|
+
signatureAgents.set(signatureAgentKey, [signatureAgent, new Map()])
|
|
37
|
+
headers.set(Constants.signatureAgentHeader, serializeDictionary(signatureAgents))
|
|
38
|
+
return HttpMessageSignature.sign(new Request(request, { headers }), {
|
|
39
|
+
components: [
|
|
40
|
+
HttpMessageSignature.Constants.components.authority,
|
|
41
|
+
{
|
|
42
|
+
id: HttpMessageSignature.Constants.components.signatureAgent,
|
|
43
|
+
parameters: new Map([['key', signatureAgentKey]]),
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
context,
|
|
47
|
+
expiresIn,
|
|
48
|
+
key: config.key,
|
|
49
|
+
keyId: config.keyId,
|
|
50
|
+
label,
|
|
51
|
+
tag: Constants.tag,
|
|
52
|
+
})
|
|
53
|
+
},
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export declare namespace signer {
|
|
58
|
+
type Config = {
|
|
59
|
+
/** Ed25519 or RSA-PSS SHA-512 private key registered for the bot. */
|
|
60
|
+
key: CryptoKey
|
|
61
|
+
/** RFC 7638 JWK thumbprint for the registered public key. */
|
|
62
|
+
keyId: string
|
|
63
|
+
/** Required HTTPS directory origin, sent with the default `directory` discovery type. */
|
|
64
|
+
signatureAgent: string
|
|
65
|
+
/** Dictionary member name used for `Signature-Agent`. @default signature label */
|
|
66
|
+
signatureAgentKey?: string | undefined
|
|
67
|
+
/** Signature lifetime in seconds. @default 60 */
|
|
68
|
+
expiresIn?: number | undefined
|
|
69
|
+
/** RFC 9421 dictionary label. @default 'webbot' */
|
|
70
|
+
label?: string | undefined
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function parseSignatureAgents(headers: Headers): Dictionary {
|
|
75
|
+
const value = headers.get(Constants.signatureAgentHeader)
|
|
76
|
+
if (!value) return new Map()
|
|
77
|
+
try {
|
|
78
|
+
return parseDictionary(value)
|
|
79
|
+
} catch {
|
|
80
|
+
throw new Error(
|
|
81
|
+
`HTTP header "${Constants.signatureAgentHeader}" is not a structured dictionary.`,
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Client helpers for the Web Bot Auth HTTPS-directory profile. */
|
|
2
|
+
export * as Client from './client/index.js'
|
|
3
|
+
/** Server helpers for the Web Bot Auth HTTPS-directory profile. */
|
|
4
|
+
export * as Server from './server/index.js'
|
|
5
|
+
export * from './Constants.js'
|
|
6
|
+
export * from './Types.js'
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Base64 } from 'ox'
|
|
2
|
+
|
|
3
|
+
const pattern = /^[A-Za-z0-9_-]{43}$/
|
|
4
|
+
|
|
5
|
+
/** Returns whether a value has the RFC 7638 SHA-256 thumbprint encoding. */
|
|
6
|
+
export function is(value: string): boolean {
|
|
7
|
+
return pattern.test(value)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/** Derives an RFC 7638 thumbprint from an extractable Ed25519 or RSA public key. */
|
|
11
|
+
export async function fromKey(key: CryptoKey): Promise<string> {
|
|
12
|
+
const jwk = await crypto.subtle.exportKey('jwk', key)
|
|
13
|
+
let canonical: string
|
|
14
|
+
if (jwk.kty === 'OKP' && jwk.crv === 'Ed25519' && jwk.x)
|
|
15
|
+
canonical = JSON.stringify({ crv: jwk.crv, kty: jwk.kty, x: jwk.x })
|
|
16
|
+
else if (jwk.kty === 'RSA' && jwk.e && jwk.n)
|
|
17
|
+
canonical = JSON.stringify({ e: jwk.e, kty: jwk.kty, n: jwk.n })
|
|
18
|
+
else throw new TypeError('Web Bot Auth requires an Ed25519 or RSA public key.')
|
|
19
|
+
const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(canonical))
|
|
20
|
+
return Base64.fromBytes(new Uint8Array(digest), { pad: false, url: true })
|
|
21
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Returns the canonical origin for a Web Bot Auth directory identifier. */
|
|
2
|
+
export function directoryOrigin(value: string): string | undefined {
|
|
3
|
+
try {
|
|
4
|
+
const url = new URL(value)
|
|
5
|
+
if (
|
|
6
|
+
url.protocol !== 'https:' ||
|
|
7
|
+
url.username ||
|
|
8
|
+
url.password ||
|
|
9
|
+
url.pathname !== '/' ||
|
|
10
|
+
url.search ||
|
|
11
|
+
url.hash
|
|
12
|
+
)
|
|
13
|
+
return undefined
|
|
14
|
+
return url.origin
|
|
15
|
+
} catch {
|
|
16
|
+
return undefined
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { isInnerList, parseDictionary, Token } from 'structured-headers'
|
|
2
|
+
|
|
3
|
+
import * as HttpMessageSignature from '../../attestation/internal/HttpMessageSignature.js'
|
|
4
|
+
import type * as Attestation from '../../attestation/Types.js'
|
|
5
|
+
import type * as Store from '../../Store.js'
|
|
6
|
+
import { Constants } from '../Constants.js'
|
|
7
|
+
import * as JwkThumbprint from '../internal/JwkThumbprint.js'
|
|
8
|
+
import * as SignatureAgent from '../internal/SignatureAgent.js'
|
|
9
|
+
import type * as Types from '../Types.js'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Creates a verifier for the Web Bot Auth HTTPS-directory profile.
|
|
13
|
+
*
|
|
14
|
+
* It requires an `@authority` and signed `Signature-Agent` directory member;
|
|
15
|
+
* direct key configuration and other Web Bot Auth discovery types are outside
|
|
16
|
+
* this adapter's scope. Verification confirms the cryptographic identity of an
|
|
17
|
+
* automated HTTP client. It must not be used on its own as user or payment
|
|
18
|
+
* authorization.
|
|
19
|
+
*/
|
|
20
|
+
export function verifier(config: verifier.Config): Attestation.Verifier<Types.VerifiedRequest> {
|
|
21
|
+
const maxAge = config.maxAge ?? Constants.defaultMaximumSignatureLifetime
|
|
22
|
+
if (!Number.isInteger(maxAge) || maxAge <= 0)
|
|
23
|
+
throw new RangeError('Web Bot Auth maxAge must be a positive integer.')
|
|
24
|
+
return {
|
|
25
|
+
async verify(request) {
|
|
26
|
+
let signatureAgent: string | undefined
|
|
27
|
+
const result = await HttpMessageSignature.verify(request, {
|
|
28
|
+
async keyResolver(parameters) {
|
|
29
|
+
return config.keyResolver({
|
|
30
|
+
...parameters,
|
|
31
|
+
signatureAgent: signatureAgent!,
|
|
32
|
+
})
|
|
33
|
+
},
|
|
34
|
+
async validateKey(key, input) {
|
|
35
|
+
try {
|
|
36
|
+
return (await JwkThumbprint.fromKey(key)) === input.keyId
|
|
37
|
+
? undefined
|
|
38
|
+
: 'The Web Bot Auth key does not match its RFC 7638 keyid.'
|
|
39
|
+
} catch {
|
|
40
|
+
return 'The Web Bot Auth key must be an extractable Ed25519 or RSA public key.'
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
maxAge,
|
|
44
|
+
nonceNamespace: Constants.protocol,
|
|
45
|
+
nonceStore: config.nonceStore,
|
|
46
|
+
requiredComponents: Constants.requiredComponents,
|
|
47
|
+
tag: Constants.tag,
|
|
48
|
+
validate(signature, request) {
|
|
49
|
+
if (!JwkThumbprint.is(signature.keyId))
|
|
50
|
+
return 'The Web Bot Auth keyid must be an RFC 7638 SHA-256 JWK thumbprint.'
|
|
51
|
+
const component = signature.components.find(
|
|
52
|
+
(entry) => entry.id === HttpMessageSignature.Constants.components.signatureAgent,
|
|
53
|
+
)
|
|
54
|
+
const key = component?.parameters?.get('key')
|
|
55
|
+
if (typeof key !== 'string')
|
|
56
|
+
return 'The signed Signature-Agent component must identify a dictionary member.'
|
|
57
|
+
const value = request.headers.get(Constants.signatureAgentHeader)
|
|
58
|
+
if (!value) return 'The Signature-Agent header is required.'
|
|
59
|
+
let agents
|
|
60
|
+
try {
|
|
61
|
+
agents = parseDictionary(value)
|
|
62
|
+
} catch {
|
|
63
|
+
return 'The Signature-Agent header must be a structured dictionary.'
|
|
64
|
+
}
|
|
65
|
+
const agent = agents.get(key)
|
|
66
|
+
if (!agent || isInnerList(agent) || typeof agent[0] !== 'string')
|
|
67
|
+
return 'The signed Signature-Agent member must be an HTTPS URL.'
|
|
68
|
+
const type = agent[1].get('type')
|
|
69
|
+
if (
|
|
70
|
+
type !== undefined &&
|
|
71
|
+
(!(type instanceof Token) || type.toString() !== Constants.discoveryType)
|
|
72
|
+
)
|
|
73
|
+
return 'The Signature-Agent discovery type is not supported by this directory profile.'
|
|
74
|
+
const origin = SignatureAgent.directoryOrigin(agent[0])
|
|
75
|
+
if (!origin) return 'The Signature-Agent header must identify a valid HTTPS origin.'
|
|
76
|
+
signatureAgent = origin
|
|
77
|
+
return undefined
|
|
78
|
+
},
|
|
79
|
+
})
|
|
80
|
+
if (result.status !== 'verified') return result
|
|
81
|
+
return {
|
|
82
|
+
status: 'verified',
|
|
83
|
+
value: {
|
|
84
|
+
keyId: result.input.keyId,
|
|
85
|
+
nonce: result.input.nonce,
|
|
86
|
+
signatureAgent: signatureAgent!,
|
|
87
|
+
},
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export declare namespace verifier {
|
|
94
|
+
type Config = {
|
|
95
|
+
/**
|
|
96
|
+
* Resolves a public key for the advertised directory.
|
|
97
|
+
*
|
|
98
|
+
* Apply the origin's trust policy before any network lookup; do not fetch an
|
|
99
|
+
* arbitrary caller-provided `signatureAgent` URL. Returned public keys
|
|
100
|
+
* must be extractable so their RFC 7638 thumbprints can be verified.
|
|
101
|
+
*/
|
|
102
|
+
keyResolver: (parameters: {
|
|
103
|
+
algorithm: Attestation.SignatureAlgorithm
|
|
104
|
+
keyId: string
|
|
105
|
+
request: Request
|
|
106
|
+
signatureAgent: string
|
|
107
|
+
}) => Promise<CryptoKey | undefined> | CryptoKey | undefined
|
|
108
|
+
/** Maximum accepted signature lifetime in seconds. @default 86400 */
|
|
109
|
+
maxAge?: number | undefined
|
|
110
|
+
/** Atomically consumes each nonce in shared storage for multi-instance deployments. */
|
|
111
|
+
nonceStore: Store.AtomicStore
|
|
112
|
+
}
|
|
113
|
+
}
|