@toa.io/extensions.exposition 1.0.0-alpha.285 → 1.0.0-alpha.287
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 +1 -545
- package/components/exposition.octets/operations/delete.js +1 -1
- package/components/exposition.octets/operations/get.js +5 -2
- package/components/exposition.octets/operations/head.js +1 -1
- package/components/exposition.octets/operations/put.js +29 -37
- package/components/exposition.octets/types/toa.d.ts +1 -1
- package/components/identity.bans/manifest.toa.yaml +12 -13
- package/components/identity.bans/migrations/0001-system-properties.yaml +14 -0
- package/components/identity.bans/operations/transit.js +1 -1
- package/components/identity.bans/source/transit.ts +1 -1
- package/components/identity.bans/tsconfig.tsbuildinfo +1 -1
- package/components/identity.bans/types/toa.d.ts +5 -5
- package/components/identity.basic/events/principal.js +3 -1
- package/components/identity.basic/manifest.toa.yaml +17 -23
- package/components/identity.basic/migrations/0001-system-properties.yaml +14 -0
- package/components/identity.basic/migrations/0002-indexes.yaml +13 -0
- package/components/identity.basic/operations/add.js +1 -1
- package/components/identity.basic/operations/authenticate.js +2 -2
- package/components/identity.basic/operations/check.js +4 -2
- package/components/identity.basic/operations/delete.js +1 -1
- package/components/identity.basic/operations/incept.js +1 -1
- package/components/identity.basic/operations/info.js +1 -1
- package/components/identity.basic/operations/lib/credentials.js +1 -1
- package/components/identity.basic/operations/transit.js +7 -8
- package/components/identity.basic/source/add.ts +5 -2
- package/components/identity.basic/source/authenticate.ts +11 -13
- package/components/identity.basic/source/check.ts +9 -6
- package/components/identity.basic/source/delete.ts +4 -1
- package/components/identity.basic/source/incept.ts +13 -10
- package/components/identity.basic/source/info.ts +4 -1
- package/components/identity.basic/source/lib/credentials.ts +2 -3
- package/components/identity.basic/source/transit.ts +27 -21
- package/components/identity.basic/tsconfig.tsbuildinfo +1 -1
- package/components/identity.basic/types/index.d.ts +7 -3
- package/components/identity.basic/types/toa.d.ts +5 -5
- package/components/identity.clients/manifest.toa.yaml +36 -40
- package/components/identity.clients/migrations/0001-system-properties.yaml +14 -0
- package/components/identity.clients/migrations/0002-indexes.yaml +4 -0
- package/components/identity.clients/operations/describe.js +1 -1
- package/components/identity.clients/operations/lib/canonical.js +1 -1
- package/components/identity.clients/operations/lib/cimd.js +3 -2
- package/components/identity.clients/operations/lib/redirect.js +7 -4
- package/components/identity.clients/operations/register.js +2 -2
- package/components/identity.clients/source/describe.ts +6 -8
- package/components/identity.clients/source/lib/Context.ts +6 -3
- package/components/identity.clients/source/lib/Entity.ts +1 -1
- package/components/identity.clients/source/lib/canonical.ts +1 -1
- package/components/identity.clients/source/lib/cimd.test.ts +8 -6
- package/components/identity.clients/source/lib/cimd.ts +24 -19
- package/components/identity.clients/source/lib/redirect.test.ts +8 -2
- package/components/identity.clients/source/lib/redirect.ts +12 -8
- package/components/identity.clients/source/register.ts +18 -18
- package/components/identity.clients/tsconfig.tsbuildinfo +1 -1
- package/components/identity.clients/types/toa.d.ts +5 -5
- package/components/identity.credentials/manifest.toa.yaml +4 -4
- package/components/identity.credentials/operations/list.js +8 -4
- package/components/identity.credentials/source/list.test.ts +39 -20
- package/components/identity.credentials/source/list.ts +12 -8
- package/components/identity.credentials/tsconfig.tsbuildinfo +1 -1
- package/components/identity.credentials/types/toa.d.ts +2 -2
- package/components/identity.federation/manifest.toa.yaml +23 -32
- package/components/identity.federation/migrations/0001-system-properties.yaml +14 -0
- package/components/identity.federation/migrations/0002-indexes.yaml +25 -0
- package/components/identity.federation/operations/authenticate.js +4 -2
- package/components/identity.federation/operations/create.js +2 -2
- package/components/identity.federation/operations/decode.js +1 -1
- package/components/identity.federation/operations/delete.js +1 -1
- package/components/identity.federation/operations/incept.js +1 -1
- package/components/identity.federation/operations/lib/decode.js +1 -1
- package/components/identity.federation/operations/lib/discovery.js +2 -2
- package/components/identity.federation/operations/lib/exchange.js +8 -4
- package/components/identity.federation/operations/lib/principal.js +1 -1
- package/components/identity.federation/operations/lib/resolve.js +1 -1
- package/components/identity.federation/operations/list.js +2 -2
- package/components/identity.federation/source/authenticate.ts +19 -17
- package/components/identity.federation/source/create.ts +6 -7
- package/components/identity.federation/source/decode.ts +4 -1
- package/components/identity.federation/source/delete.ts +4 -1
- package/components/identity.federation/source/incept.ts +2 -3
- package/components/identity.federation/source/lib/decode.ts +4 -7
- package/components/identity.federation/source/lib/discovery.test.ts +15 -5
- package/components/identity.federation/source/lib/discovery.ts +10 -9
- package/components/identity.federation/source/lib/exchange.ts +18 -15
- package/components/identity.federation/source/lib/jose.d.ts +1 -1
- package/components/identity.federation/source/lib/principal.ts +5 -3
- package/components/identity.federation/source/lib/resolve.ts +5 -1
- package/components/identity.federation/source/list.test.ts +26 -10
- package/components/identity.federation/source/list.ts +5 -2
- package/components/identity.federation/source/types/context.ts +5 -2
- package/components/identity.federation/source/types/entity.ts +2 -2
- package/components/identity.federation/tsconfig.tsbuildinfo +1 -1
- package/components/identity.federation/types/toa.d.ts +5 -5
- package/components/identity.grants/manifest.toa.yaml +27 -31
- package/components/identity.grants/migrations/0001-system-properties.yaml +14 -0
- package/components/identity.grants/migrations/0002-indexes.yaml +5 -0
- package/components/identity.grants/operations/authorize.js +1 -1
- package/components/identity.grants/operations/exchange.js +5 -2
- package/components/identity.grants/operations/lib/code.js +1 -1
- package/components/identity.grants/operations/lib/identify.js +1 -1
- package/components/identity.grants/operations/list.js +1 -1
- package/components/identity.grants/operations/revoke.js +3 -2
- package/components/identity.grants/source/authorize.ts +27 -19
- package/components/identity.grants/source/exchange.ts +15 -11
- package/components/identity.grants/source/lib/code.ts +20 -8
- package/components/identity.grants/source/lib/identify.ts +1 -1
- package/components/identity.grants/source/list.ts +2 -2
- package/components/identity.grants/source/revoke.ts +9 -7
- package/components/identity.grants/tsconfig.tsbuildinfo +1 -1
- package/components/identity.grants/types/index.d.ts +3 -3
- package/components/identity.grants/types/toa.d.ts +5 -5
- package/components/identity.keys/manifest.toa.yaml +18 -23
- package/components/identity.keys/migrations/0001-system-properties.yaml +14 -0
- package/components/identity.keys/migrations/0002-indexes.yaml +4 -0
- package/components/identity.keys/operations/create.js +1 -1
- package/components/identity.keys/operations/disable.js +1 -1
- package/components/identity.keys/operations/revoke.js +1 -1
- package/components/identity.keys/source/create.ts +2 -3
- package/components/identity.keys/source/disable.ts +1 -1
- package/components/identity.keys/source/revoke.ts +2 -2
- package/components/identity.keys/tsconfig.tsbuildinfo +1 -1
- package/components/identity.keys/types/toa.d.ts +5 -5
- package/components/identity.otp/manifest.toa.yaml +16 -24
- package/components/identity.otp/migrations/0001-system-properties.yaml +14 -0
- package/components/identity.otp/migrations/0002-indexes.yaml +5 -0
- package/components/identity.otp/operations/authenticate.js +1 -1
- package/components/identity.otp/operations/issue.js +1 -1
- package/components/identity.otp/source/authenticate.ts +4 -7
- package/components/identity.otp/source/issue.ts +1 -1
- package/components/identity.otp/source/lib/Context.ts +1 -1
- package/components/identity.otp/tsconfig.tsbuildinfo +1 -1
- package/components/identity.otp/types/toa.d.ts +5 -5
- package/components/identity.passkeys/manifest.toa.yaml +45 -53
- package/components/identity.passkeys/migrations/0001-system-properties.yaml +14 -0
- package/components/identity.passkeys/migrations/0002-indexes.yaml +11 -0
- package/components/identity.passkeys/operations/authenticate.js +1 -1
- package/components/identity.passkeys/operations/challenge.js +6 -3
- package/components/identity.passkeys/operations/create.js +1 -1
- package/components/identity.passkeys/operations/delete.js +1 -1
- package/components/identity.passkeys/operations/list.js +1 -1
- package/components/identity.passkeys/operations/use.js +1 -1
- package/components/identity.passkeys/source/authenticate.ts +3 -4
- package/components/identity.passkeys/source/challenge.ts +29 -25
- package/components/identity.passkeys/source/create.ts +8 -6
- package/components/identity.passkeys/source/delete.ts +4 -1
- package/components/identity.passkeys/source/list.ts +4 -1
- package/components/identity.passkeys/source/types/Context.ts +1 -1
- package/components/identity.passkeys/source/use.ts +12 -10
- package/components/identity.passkeys/tsconfig.tsbuildinfo +1 -1
- package/components/identity.passkeys/types/toa.d.ts +5 -5
- package/components/identity.roles/manifest.toa.yaml +12 -16
- package/components/identity.roles/migrations/0001-system-properties.yaml +14 -0
- package/components/identity.roles/migrations/0002-indexes.yaml +8 -0
- package/components/identity.roles/operations/grant.js +1 -1
- package/components/identity.roles/operations/list.js +1 -1
- package/components/identity.roles/operations/principal.js +2 -2
- package/components/identity.roles/source/grant.ts +7 -6
- package/components/identity.roles/source/list.ts +1 -1
- package/components/identity.roles/source/principal.ts +5 -7
- package/components/identity.roles/tsconfig.tsbuildinfo +1 -1
- package/components/identity.roles/types/toa.d.ts +5 -5
- package/components/identity.tokens/manifest.toa.yaml +17 -15
- package/components/identity.tokens/migrations/0001-system-properties.yaml +14 -0
- package/components/identity.tokens/operations/authenticate.js +2 -2
- package/components/identity.tokens/operations/decrypt.js +11 -5
- package/components/identity.tokens/operations/encrypt.js +2 -2
- package/components/identity.tokens/operations/issue.js +2 -4
- package/components/identity.tokens/operations/lib/form.js +1 -1
- package/components/identity.tokens/operations/lib/key.js +1 -1
- package/components/identity.tokens/operations/revoke.js +1 -1
- package/components/identity.tokens/source/authenticate.test.ts +22 -16
- package/components/identity.tokens/source/authenticate.ts +7 -10
- package/components/identity.tokens/source/decrypt.test.ts +62 -29
- package/components/identity.tokens/source/decrypt.ts +30 -27
- package/components/identity.tokens/source/encrypt.test.ts +21 -16
- package/components/identity.tokens/source/encrypt.ts +8 -11
- package/components/identity.tokens/source/issue.test.ts +4 -2
- package/components/identity.tokens/source/issue.ts +6 -8
- package/components/identity.tokens/source/lib/form.ts +5 -9
- package/components/identity.tokens/source/lib/jose.d.ts +1 -1
- package/components/identity.tokens/source/lib/key.ts +1 -1
- package/components/identity.tokens/source/lib/paseto.test.ts +17 -6
- package/components/identity.tokens/source/revoke.ts +1 -1
- package/components/identity.tokens/tsconfig.tsbuildinfo +1 -1
- package/components/identity.tokens/types/index.d.ts +13 -4
- package/components/identity.tokens/types/toa.d.ts +5 -5
- package/context.toa.yaml +2 -2
- package/cucumber.mjs +3 -0
- package/documentation/access.md +4 -3
- package/documentation/cache.md +17 -3
- package/documentation/components.md +2 -2
- package/documentation/credentials.md +2 -2
- package/documentation/identity.md +7 -9
- package/documentation/map.md +2 -2
- package/documentation/mcp.md +16 -16
- package/documentation/notes/peers.md +1 -1
- package/documentation/notes/throttling.md +1 -1
- package/documentation/octets.md +4 -4
- package/documentation/protocol.md +3 -3
- package/documentation/query.md +14 -8
- package/documentation/rpc.md +31 -21
- package/documentation/tracing.md +3 -3
- package/documentation/tree.md +1 -1
- package/features/auth.assert.feature +2 -2
- package/features/auth.bearer.feature +1 -1
- package/features/auth.claims.feature +5 -5
- package/features/auth.incept.feature +2 -2
- package/features/authorities.federation.feature +1 -1
- package/features/configuration.feature +3 -4
- package/features/credentials.feature +9 -9
- package/features/dev.feature +1 -0
- package/features/dynamic.feature +1 -0
- package/features/errors.feature +21 -0
- package/features/etag.feature +0 -86
- package/features/identity.bans.feature +3 -3
- package/features/identity.basic.feature +9 -9
- package/features/identity.federation.feature +11 -11
- package/features/identity.tokens.custom.feature +5 -5
- package/features/identity.tokens.feature +2 -2
- package/features/interruptions.feature +1 -0
- package/features/introspection.map.feature +4 -4
- package/features/io.throttle.feature +1 -0
- package/features/map.feature +2 -2
- package/features/octets.cloudinary.feature +1 -1
- package/features/octets.download.feature +1 -0
- package/features/require.feature +1 -2
- package/features/steps/Captures.ts +1 -1
- package/features/steps/Cloudinary.ts +1 -2
- package/features/steps/Common.ts +4 -5
- package/features/steps/Components.ts +17 -12
- package/features/steps/Database.ts +42 -23
- package/features/steps/Gateway.ts +55 -72
- package/features/steps/HTTP.ts +12 -15
- package/features/steps/IDP.ts +118 -94
- package/features/steps/Identity.ts +3 -3
- package/features/steps/OTP.ts +3 -3
- package/features/steps/Parameters.ts +20 -10
- package/features/steps/Probe.ts +9 -7
- package/features/steps/Realtime.ts +40 -22
- package/features/steps/Workspace.ts +10 -7
- package/features/steps/components/audit/operations/record.js +1 -1
- package/features/steps/components/echo/operations/affect.js +1 -1
- package/features/steps/components/echo/operations/compute.js +1 -1
- package/features/steps/components/echo/operations/echo.js +1 -1
- package/features/steps/components/echo/operations/error.js +1 -1
- package/features/steps/components/echo/operations/identity.js +1 -1
- package/features/steps/components/echo/operations/parameters.js +1 -1
- package/features/steps/components/echo/operations/ping.js +1 -1
- package/features/steps/components/echo/operations/unwrap.js +1 -1
- package/features/steps/components/greeter/operations/greet.js +1 -1
- package/features/steps/components/notify/operations/send.js +1 -1
- package/features/steps/components/octets.tester/operations/authority.js +1 -1
- package/features/steps/components/octets.tester/operations/bar.js +1 -1
- package/features/steps/components/octets.tester/operations/baz.js +1 -1
- package/features/steps/components/octets.tester/operations/concat.js +1 -1
- package/features/steps/components/octets.tester/operations/echo.js +1 -1
- package/features/steps/components/octets.tester/operations/err.js +1 -1
- package/features/steps/components/octets.tester/operations/foo.js +1 -1
- package/features/steps/components/octets.tester/operations/id.js +1 -1
- package/features/steps/components/octets.tester/operations/identity.js +1 -1
- package/features/steps/components/octets.tester/operations/redirect.js +6 -4
- package/features/steps/components/octets.tester/operations/yex.js +1 -1
- package/features/steps/components/octets.tester/operations/yield.js +1 -1
- package/features/steps/components/orders/manifest.toa.yaml +10 -12
- package/features/steps/components/orders/operations/create.js +4 -2
- package/features/steps/components/pots/manifest.toa.yaml +15 -20
- package/features/steps/components/pots/migrations/0002-indexes.yaml +4 -0
- package/features/steps/components/pricing/operations/quote.js +1 -1
- package/features/steps/components/sequences/manifest.toa.yaml +0 -1
- package/features/steps/components/sequences/operations/numbers.js +1 -1
- package/features/steps/components/sequences/operations/tokens.js +3 -3
- package/features/steps/components/users/manifest.toa.yaml +3 -5
- package/features/steps/components/users/operations/create.js +1 -1
- package/features/steps/components/users.properties/manifest.toa.yaml +5 -6
- package/features/steps/map.ts +2 -2
- package/features/timestamps.feature +1 -1
- package/package.json +7 -7
- package/readme.md +11 -11
- package/schemas/annotation.cos.yaml +1 -3
- package/schemas/method.cos.yaml +2 -0
- package/source/Branch.test.ts +2 -2
- package/source/Branch.ts +3 -5
- package/source/Composition.ts +5 -5
- package/source/Directive.test.ts +38 -20
- package/source/Directive.ts +61 -47
- package/source/Endpoint.test.ts +1 -1
- package/source/Endpoint.ts +27 -92
- package/source/Factory.ts +26 -12
- package/source/Gateway.ts +87 -76
- package/source/HTTP/Context.ts +23 -30
- package/source/HTTP/Probe.ts +7 -9
- package/source/HTTP/Server.ts +88 -69
- package/source/HTTP/Timing.ts +6 -21
- package/source/HTTP/address.test.ts +8 -2
- package/source/HTTP/address.ts +2 -3
- package/source/HTTP/exceptions.ts +20 -18
- package/source/HTTP/formats/form.ts +1 -1
- package/source/HTTP/formats/json.ts +2 -2
- package/source/HTTP/formats/msgpack.ts +3 -4
- package/source/HTTP/formats/text.ts +2 -2
- package/source/HTTP/formats/yaml.test.ts +4 -1
- package/source/HTTP/formats/yaml.ts +14 -11
- package/source/HTTP/messages.test.ts +38 -28
- package/source/HTTP/messages.ts +44 -98
- package/source/Interception.ts +3 -4
- package/source/Introspection.ts +26 -14
- package/source/MCP/Server.ts +114 -54
- package/source/MCP/discover.ts +6 -7
- package/source/MCP/errors.ts +7 -8
- package/source/MCP/schema.test.ts +9 -3
- package/source/MCP/schema.ts +12 -16
- package/source/MCP/tools.ts +33 -28
- package/source/Mapping.ts +25 -27
- package/source/Query.ts +58 -44
- package/source/RPC/Context.ts +8 -11
- package/source/RPC/Dispatcher.ts +46 -26
- package/source/RPC/errors.test.ts +41 -16
- package/source/RPC/errors.ts +9 -10
- package/source/RPC/names.test.ts +35 -16
- package/source/RPC/names.ts +22 -29
- package/source/RTD/Directives.ts +21 -10
- package/source/RTD/Endpoint.ts +4 -1
- package/source/RTD/Method.ts +8 -6
- package/source/RTD/Node.ts +32 -34
- package/source/RTD/Route.ts +18 -21
- package/source/RTD/Tree.ts +18 -18
- package/source/RTD/factory.ts +13 -16
- package/source/RTD/segment.ts +12 -10
- package/source/RTD/syntax/parse.test.ts +12 -6
- package/source/RTD/syntax/parse.ts +30 -26
- package/source/RTD/syntax/types.ts +17 -1
- package/source/RTD/walk.test.ts +59 -22
- package/source/Remotes.test.ts +25 -4
- package/source/Remotes.ts +9 -4
- package/source/Tenant.ts +12 -12
- package/source/deployment.ts +20 -20
- package/source/directives/auth/Anonymous.test.ts +8 -2
- package/source/directives/auth/Anonymous.ts +5 -8
- package/source/directives/auth/Anyone.ts +3 -3
- package/source/directives/auth/Assert.ts +10 -10
- package/source/directives/auth/Authorization.ts +83 -69
- package/source/directives/auth/Delegate.test.ts +2 -2
- package/source/directives/auth/Delegate.ts +8 -10
- package/source/directives/auth/Echo.ts +5 -8
- package/source/directives/auth/Federation.ts +30 -21
- package/source/directives/auth/Id.ts +7 -4
- package/source/directives/auth/Incept.ts +32 -26
- package/source/directives/auth/Input.ts +36 -20
- package/source/directives/auth/Role.test.ts +49 -23
- package/source/directives/auth/Role.ts +29 -22
- package/source/directives/auth/Rule.ts +13 -8
- package/source/directives/auth/Scheme.ts +7 -7
- package/source/directives/auth/create.ts +1 -1
- package/source/directives/auth/schemes.ts +1 -1
- package/source/directives/auth/split.ts +2 -3
- package/source/directives/auth/types.ts +5 -2
- package/source/directives/cache/Cache.ts +44 -9
- package/source/directives/cache/Control.ts +25 -26
- package/source/directives/cache/Exact.ts +1 -1
- package/source/directives/cache/etag.ts +38 -0
- package/source/directives/cors/CORS.ts +9 -7
- package/source/directives/dev/Development.ts +3 -4
- package/source/directives/dev/Faulty.ts +11 -6
- package/source/directives/dev/Sleep.ts +5 -7
- package/source/directives/dev/Stub.ts +2 -2
- package/source/directives/dev/Throw.ts +2 -2
- package/source/directives/flow/Compose.ts +26 -20
- package/source/directives/flow/Fetch.ts +15 -15
- package/source/directives/flow/Flow.ts +9 -8
- package/source/directives/index.ts +11 -2
- package/source/directives/io/IO.ts +29 -20
- package/source/directives/io/Input.ts +9 -12
- package/source/directives/io/Output.ts +20 -23
- package/source/directives/io/Status.test.ts +12 -8
- package/source/directives/io/Status.ts +9 -8
- package/source/directives/io/Throttle.ts +6 -7
- package/source/directives/io/lib/throttle/Configuration.test.ts +32 -23
- package/source/directives/io/lib/throttle/Configuration.ts +14 -9
- package/source/directives/io/lib/throttle/Keys.ts +15 -10
- package/source/directives/io/lib/throttle/Quotas.test.ts +33 -17
- package/source/directives/io/lib/throttle/Quotas.ts +20 -26
- package/source/directives/io/lib/throttle/Sync.test.ts +14 -10
- package/source/directives/io/lib/throttle/Sync.ts +9 -12
- package/source/directives/io/lib/throttle/Warning.ts +3 -4
- package/source/directives/io/lib/throttle/components/IP.ts +4 -5
- package/source/directives/io/lib/throttle/components/Identity.ts +1 -1
- package/source/directives/io/lib/throttle/components/Path.ts +1 -1
- package/source/directives/io/lib/throttle/components/Route.ts +2 -2
- package/source/directives/io/lib/throttle/components/Segment.ts +2 -2
- package/source/directives/io/lib/throttle/conditions/Status.ts +2 -2
- package/source/directives/io/schemas.test.ts +12 -6
- package/source/directives/map/Authority.ts +2 -2
- package/source/directives/map/Buffer.ts +2 -2
- package/source/directives/map/Claims.ts +25 -20
- package/source/directives/map/Headers.ts +17 -13
- package/source/directives/map/Language.ts +8 -5
- package/source/directives/map/Languages.ts +9 -3
- package/source/directives/map/Map.ts +25 -12
- package/source/directives/map/Mapping.ts +9 -6
- package/source/directives/map/Properties.ts +1 -1
- package/source/directives/map/Segments.ts +22 -15
- package/source/directives/mcp/MCP.ts +9 -7
- package/source/directives/mcp/Tool.test.ts +21 -9
- package/source/directives/mcp/Tool.ts +23 -11
- package/source/directives/oauth/Discovery.ts +7 -11
- package/source/directives/oauth/documents.ts +11 -14
- package/source/directives/octets/Context.ts +6 -3
- package/source/directives/octets/Delete.ts +33 -25
- package/source/directives/octets/Directive.ts +5 -1
- package/source/directives/octets/Get.ts +13 -21
- package/source/directives/octets/Octets.ts +20 -15
- package/source/directives/octets/Put.ts +62 -27
- package/source/directives/octets/Workflow.ts +18 -12
- package/source/directives/octets/bytes.ts +1 -1
- package/source/directives/octets/schemas.test.ts +8 -14
- package/source/directives/octets/workflows/Execution.ts +19 -21
- package/source/directives/octets/workflows/Workflow.ts +10 -7
- package/source/directives/require/Headers.ts +3 -4
- package/source/directives/require/Require.ts +3 -4
- package/source/exceptions.ts +19 -12
- package/source/index.ts +1 -1
- package/source/manifest.test.ts +4 -1
- package/source/manifest.ts +19 -13
- package/source/octets.d.ts +1 -1
- package/source/root.ts +3 -2
- package/source/schemas.test.ts +17 -3
- package/transpiled/Branch.js.map +1 -1
- package/transpiled/Composition.js.map +1 -1
- package/transpiled/Directive.js +6 -2
- package/transpiled/Directive.js.map +1 -1
- package/transpiled/Endpoint.d.ts +0 -2
- package/transpiled/Endpoint.js +11 -52
- package/transpiled/Endpoint.js.map +1 -1
- package/transpiled/Factory.d.ts +2 -1
- package/transpiled/Factory.js +1 -0
- package/transpiled/Factory.js.map +1 -1
- package/transpiled/Gateway.d.ts +2 -1
- package/transpiled/Gateway.js +24 -15
- package/transpiled/Gateway.js.map +1 -1
- package/transpiled/HTTP/Context.d.ts +0 -3
- package/transpiled/HTTP/Context.js +7 -9
- package/transpiled/HTTP/Context.js.map +1 -1
- package/transpiled/HTTP/Probe.js.map +1 -1
- package/transpiled/HTTP/Server.js +19 -4
- package/transpiled/HTTP/Server.js.map +1 -1
- package/transpiled/HTTP/Timing.d.ts +1 -2
- package/transpiled/HTTP/Timing.js +2 -10
- package/transpiled/HTTP/Timing.js.map +1 -1
- package/transpiled/HTTP/address.js.map +1 -1
- package/transpiled/HTTP/exceptions.js.map +1 -1
- package/transpiled/HTTP/formats/form.js.map +1 -1
- package/transpiled/HTTP/formats/json.js.map +1 -1
- package/transpiled/HTTP/formats/msgpack.js.map +1 -1
- package/transpiled/HTTP/formats/text.js.map +1 -1
- package/transpiled/HTTP/formats/yaml.js +4 -1
- package/transpiled/HTTP/formats/yaml.js.map +1 -1
- package/transpiled/HTTP/messages.d.ts +3 -2
- package/transpiled/HTTP/messages.js +1 -43
- package/transpiled/HTTP/messages.js.map +1 -1
- package/transpiled/Interception.js.map +1 -1
- package/transpiled/Introspection.js +13 -2
- package/transpiled/Introspection.js.map +1 -1
- package/transpiled/MCP/Server.js +15 -4
- package/transpiled/MCP/Server.js.map +1 -1
- package/transpiled/MCP/discover.js.map +1 -1
- package/transpiled/MCP/errors.js.map +1 -1
- package/transpiled/MCP/schema.js +1 -1
- package/transpiled/MCP/schema.js.map +1 -1
- package/transpiled/MCP/tools.js +10 -7
- package/transpiled/MCP/tools.js.map +1 -1
- package/transpiled/Mapping.d.ts +2 -2
- package/transpiled/Mapping.js +3 -5
- package/transpiled/Mapping.js.map +1 -1
- package/transpiled/Query.d.ts +6 -2
- package/transpiled/Query.js +23 -8
- package/transpiled/Query.js.map +1 -1
- package/transpiled/RPC/Context.js +0 -7
- package/transpiled/RPC/Context.js.map +1 -1
- package/transpiled/RPC/Dispatcher.js +4 -1
- package/transpiled/RPC/Dispatcher.js.map +1 -1
- package/transpiled/RPC/errors.js.map +1 -1
- package/transpiled/RPC/names.js.map +1 -1
- package/transpiled/RTD/Directives.d.ts +1 -1
- package/transpiled/RTD/Method.js +1 -3
- package/transpiled/RTD/Method.js.map +1 -1
- package/transpiled/RTD/Node.js +5 -4
- package/transpiled/RTD/Node.js.map +1 -1
- package/transpiled/RTD/Route.js +4 -1
- package/transpiled/RTD/Route.js.map +1 -1
- package/transpiled/RTD/Tree.js +1 -1
- package/transpiled/RTD/Tree.js.map +1 -1
- package/transpiled/RTD/factory.js.map +1 -1
- package/transpiled/RTD/segment.js.map +1 -1
- package/transpiled/RTD/syntax/parse.js.map +1 -1
- package/transpiled/RTD/syntax/types.d.ts +6 -0
- package/transpiled/RTD/syntax/types.js +10 -1
- package/transpiled/RTD/syntax/types.js.map +1 -1
- package/transpiled/Remotes.js.map +1 -1
- package/transpiled/Tenant.d.ts +1 -1
- package/transpiled/Tenant.js.map +1 -1
- package/transpiled/deployment.d.ts +3 -0
- package/transpiled/deployment.js +6 -1
- package/transpiled/deployment.js.map +1 -1
- package/transpiled/directives/auth/Anonymous.js +1 -3
- package/transpiled/directives/auth/Anonymous.js.map +1 -1
- package/transpiled/directives/auth/Anyone.js.map +1 -1
- package/transpiled/directives/auth/Assert.js.map +1 -1
- package/transpiled/directives/auth/Authorization.js +7 -3
- package/transpiled/directives/auth/Authorization.js.map +1 -1
- package/transpiled/directives/auth/Delegate.js.map +1 -1
- package/transpiled/directives/auth/Echo.js +1 -3
- package/transpiled/directives/auth/Echo.js.map +1 -1
- package/transpiled/directives/auth/Federation.js +3 -7
- package/transpiled/directives/auth/Federation.js.map +1 -1
- package/transpiled/directives/auth/Id.js.map +1 -1
- package/transpiled/directives/auth/Incept.js +1 -1
- package/transpiled/directives/auth/Incept.js.map +1 -1
- package/transpiled/directives/auth/Input.js.map +1 -1
- package/transpiled/directives/auth/Role.js.map +1 -1
- package/transpiled/directives/auth/Rule.js.map +1 -1
- package/transpiled/directives/auth/Scheme.js +1 -2
- package/transpiled/directives/auth/Scheme.js.map +1 -1
- package/transpiled/directives/auth/create.js.map +1 -1
- package/transpiled/directives/auth/schemes.js.map +1 -1
- package/transpiled/directives/auth/split.js.map +1 -1
- package/transpiled/directives/auth/types.d.ts +3 -1
- package/transpiled/directives/cache/Cache.js +28 -2
- package/transpiled/directives/cache/Cache.js.map +1 -1
- package/transpiled/directives/cache/Control.js +1 -1
- package/transpiled/directives/cache/Control.js.map +1 -1
- package/transpiled/directives/cache/etag.d.ts +10 -0
- package/transpiled/directives/cache/etag.js +30 -0
- package/transpiled/directives/cache/etag.js.map +1 -0
- package/transpiled/directives/cors/CORS.js.map +1 -1
- package/transpiled/directives/dev/Development.js.map +1 -1
- package/transpiled/directives/dev/Faulty.js.map +1 -1
- package/transpiled/directives/dev/Sleep.js.map +1 -1
- package/transpiled/directives/dev/Stub.js.map +1 -1
- package/transpiled/directives/dev/Throw.js.map +1 -1
- package/transpiled/directives/flow/Compose.js +7 -3
- package/transpiled/directives/flow/Compose.js.map +1 -1
- package/transpiled/directives/flow/Fetch.js.map +1 -1
- package/transpiled/directives/flow/Flow.js.map +1 -1
- package/transpiled/directives/index.js +11 -1
- package/transpiled/directives/index.js.map +1 -1
- package/transpiled/directives/io/IO.d.ts +1 -1
- package/transpiled/directives/io/IO.js.map +1 -1
- package/transpiled/directives/io/Input.js +1 -1
- package/transpiled/directives/io/Input.js.map +1 -1
- package/transpiled/directives/io/Output.js +3 -3
- package/transpiled/directives/io/Output.js.map +1 -1
- package/transpiled/directives/io/Status.js.map +1 -1
- package/transpiled/directives/io/Throttle.js +1 -1
- package/transpiled/directives/io/Throttle.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/Configuration.js +8 -2
- package/transpiled/directives/io/lib/throttle/Configuration.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/Keys.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/Quotas.js +4 -3
- package/transpiled/directives/io/lib/throttle/Quotas.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/Sync.d.ts +1 -1
- package/transpiled/directives/io/lib/throttle/Sync.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/Warning.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/components/IP.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/components/Identity.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/components/Path.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/components/Route.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/components/Segment.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/conditions/Status.js.map +1 -1
- package/transpiled/directives/map/Authority.js.map +1 -1
- package/transpiled/directives/map/Buffer.js.map +1 -1
- package/transpiled/directives/map/Claims.js.map +1 -1
- package/transpiled/directives/map/Headers.js.map +1 -1
- package/transpiled/directives/map/Language.js.map +1 -1
- package/transpiled/directives/map/Languages.js.map +1 -1
- package/transpiled/directives/map/Map.js.map +1 -1
- package/transpiled/directives/map/Mapping.js.map +1 -1
- package/transpiled/directives/map/Properties.js.map +1 -1
- package/transpiled/directives/map/Segments.js.map +1 -1
- package/transpiled/directives/mcp/MCP.js +1 -1
- package/transpiled/directives/mcp/MCP.js.map +1 -1
- package/transpiled/directives/mcp/Tool.js +3 -1
- package/transpiled/directives/mcp/Tool.js.map +1 -1
- package/transpiled/directives/oauth/Discovery.js.map +1 -1
- package/transpiled/directives/oauth/documents.js.map +1 -1
- package/transpiled/directives/octets/Context.js +1 -1
- package/transpiled/directives/octets/Context.js.map +1 -1
- package/transpiled/directives/octets/Delete.js.map +1 -1
- package/transpiled/directives/octets/Directive.js.map +1 -1
- package/transpiled/directives/octets/Get.js.map +1 -1
- package/transpiled/directives/octets/Octets.js +1 -1
- package/transpiled/directives/octets/Octets.js.map +1 -1
- package/transpiled/directives/octets/Put.js.map +1 -1
- package/transpiled/directives/octets/Workflow.js.map +1 -1
- package/transpiled/directives/octets/bytes.js.map +1 -1
- package/transpiled/directives/octets/workflows/Execution.js +1 -2
- package/transpiled/directives/octets/workflows/Execution.js.map +1 -1
- package/transpiled/directives/octets/workflows/Workflow.js.map +1 -1
- package/transpiled/directives/require/Headers.js.map +1 -1
- package/transpiled/directives/require/Require.js.map +1 -1
- package/transpiled/exceptions.js.map +1 -1
- package/transpiled/index.d.ts +1 -1
- package/transpiled/index.js +1 -1
- package/transpiled/index.js.map +1 -1
- package/transpiled/manifest.js +5 -1
- package/transpiled/manifest.js.map +1 -1
- package/transpiled/root.js.map +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/source/redact.test.ts +0 -27
- package/source/redact.ts +0 -21
- package/transpiled/redact.d.ts +0 -5
- package/transpiled/redact.js +0 -17
- package/transpiled/redact.js.map +0 -1
|
@@ -3,24 +3,24 @@ import tsflow from 'cucumber-tsflow'
|
|
|
3
3
|
import * as boot from '@toa.io/boot'
|
|
4
4
|
import { type Connector } from '@toa.io/core'
|
|
5
5
|
import { load as parse } from 'js-yaml'
|
|
6
|
-
import { timeout } from '@toa.io/generic'
|
|
7
6
|
import { Factory } from '../../source/index.js'
|
|
8
7
|
import * as syntax from '../../source/RTD/syntax/index.js'
|
|
9
8
|
import { shortcuts } from '../../source/Directive.js'
|
|
10
9
|
import { manifests } from './map.js'
|
|
10
|
+
import { PORT, PROBE } from './Parameters.js'
|
|
11
11
|
import type * as http from '../../source/HTTP/index.js'
|
|
12
12
|
|
|
13
13
|
const { after, afterAll, binding, given } = tsflow
|
|
14
14
|
|
|
15
15
|
let instance: Connector | null = null
|
|
16
|
+
let deployment: string | null = null
|
|
16
17
|
|
|
17
18
|
@binding()
|
|
18
19
|
export class Gateway {
|
|
19
|
-
private default: boolean = true
|
|
20
20
|
private written: string[] = []
|
|
21
21
|
|
|
22
22
|
@given('the annotation:')
|
|
23
|
-
public async annotate
|
|
23
|
+
public async annotate(yaml: string): Promise<void> {
|
|
24
24
|
const annotation = parse(yaml) as Partial<http.Options> & { '/'?: object }
|
|
25
25
|
|
|
26
26
|
if (annotation['/'] !== undefined) {
|
|
@@ -32,32 +32,21 @@ export class Gateway {
|
|
|
32
32
|
const { debug, authorities, bouncer, ip, oauth, rpc, mcp } = annotation
|
|
33
33
|
const properties = Object.assign({}, DEFAULT_PROPERTIES)
|
|
34
34
|
|
|
35
|
-
if (debug !== undefined)
|
|
36
|
-
properties.debug = debug
|
|
35
|
+
if (debug !== undefined) properties.debug = debug
|
|
37
36
|
|
|
38
|
-
if (bouncer !== undefined)
|
|
39
|
-
properties.bouncer = bouncer
|
|
37
|
+
if (bouncer !== undefined) properties.bouncer = bouncer
|
|
40
38
|
|
|
41
|
-
if (ip !== undefined)
|
|
42
|
-
properties.ip = ip
|
|
39
|
+
if (ip !== undefined) properties.ip = ip
|
|
43
40
|
|
|
44
|
-
if (authorities !== undefined)
|
|
45
|
-
properties.authorities = authorities
|
|
41
|
+
if (authorities !== undefined) properties.authorities = authorities
|
|
46
42
|
|
|
47
|
-
if (oauth !== undefined)
|
|
48
|
-
properties.oauth = oauth
|
|
43
|
+
if (oauth !== undefined) properties.oauth = oauth
|
|
49
44
|
|
|
50
|
-
if (rpc !== undefined)
|
|
51
|
-
properties.rpc = rpc
|
|
45
|
+
if (rpc !== undefined) properties.rpc = rpc
|
|
52
46
|
|
|
53
|
-
if (mcp !== undefined)
|
|
54
|
-
properties.mcp = mcp
|
|
47
|
+
if (mcp !== undefined) properties.mcp = mcp
|
|
55
48
|
|
|
56
49
|
process.env.TOA_EXPOSITION_PROPERTIES = JSON.stringify(properties)
|
|
57
|
-
|
|
58
|
-
await Gateway.stop()
|
|
59
|
-
|
|
60
|
-
this.default = false
|
|
61
50
|
}
|
|
62
51
|
|
|
63
52
|
/**
|
|
@@ -65,16 +54,17 @@ export class Gateway {
|
|
|
65
54
|
* exposition extension over them, so what lands here is what a deployment would carry.
|
|
66
55
|
*/
|
|
67
56
|
@given('the annotation of the introspection map')
|
|
68
|
-
public async annotateMap
|
|
57
|
+
public async annotateMap(): Promise<void> {
|
|
69
58
|
await this.annotateMapUnder()
|
|
70
59
|
}
|
|
71
60
|
|
|
72
61
|
/** The same routes under a root of the scenario's own: what an application declares around the map. */
|
|
73
62
|
@given('the annotation of the introspection map under:')
|
|
74
|
-
public async annotateMapUnder
|
|
75
|
-
const tree: syntax.Node =
|
|
76
|
-
|
|
77
|
-
|
|
63
|
+
public async annotateMapUnder(yaml?: string): Promise<void> {
|
|
64
|
+
const tree: syntax.Node =
|
|
65
|
+
yaml === undefined
|
|
66
|
+
? { routes: [], methods: [], directives: [] }
|
|
67
|
+
: syntax.parse((parse(yaml) as { '/': object })['/'], shortcuts)
|
|
78
68
|
|
|
79
69
|
for (const manifest of await manifests()) {
|
|
80
70
|
const node = manifest.extensions?.[EXPOSITION] as syntax.Node | undefined
|
|
@@ -87,14 +77,10 @@ export class Gateway {
|
|
|
87
77
|
|
|
88
78
|
process.env.TOA_EXPOSITION = JSON.stringify(tree)
|
|
89
79
|
process.env.TOA_EXPOSITION_PROPERTIES = JSON.stringify(DEFAULT_PROPERTIES)
|
|
90
|
-
|
|
91
|
-
await Gateway.stop()
|
|
92
|
-
|
|
93
|
-
this.default = false
|
|
94
80
|
}
|
|
95
81
|
|
|
96
82
|
@given('the `{word}` configuration:')
|
|
97
|
-
public async configure
|
|
83
|
+
public async configure(id: string, yaml: string): Promise<void> {
|
|
98
84
|
const [name, namespace = 'default'] = id.split('.').reverse()
|
|
99
85
|
const key = `TOA_CONFIGURATION_${namespace.toUpperCase()}_${name.toUpperCase()}`
|
|
100
86
|
const def = DEFAULT_CONFIGURATION[id] ?? {}
|
|
@@ -105,91 +91,89 @@ export class Gateway {
|
|
|
105
91
|
// outlives the secrets it points at, and the next scenario cannot resolve them
|
|
106
92
|
this.written.push(key)
|
|
107
93
|
process.env[key] = JSON.stringify(configuration)
|
|
108
|
-
|
|
109
|
-
await Gateway.stop()
|
|
110
|
-
|
|
111
|
-
this.default = false
|
|
112
94
|
}
|
|
113
95
|
|
|
114
96
|
/** The secrets a scenario's configuration refers to. */
|
|
115
97
|
@given('the configuration secrets:')
|
|
116
|
-
public async secrets
|
|
98
|
+
public async secrets(yaml: string): Promise<void> {
|
|
117
99
|
const secrets = parse(yaml) as Record<string, string>
|
|
118
100
|
|
|
119
101
|
for (const [name, value] of Object.entries(secrets)) {
|
|
120
102
|
this.written.push(SECRET + name)
|
|
121
103
|
process.env[SECRET + name] = value
|
|
122
104
|
}
|
|
123
|
-
|
|
124
|
-
await Gateway.stop()
|
|
125
|
-
|
|
126
|
-
this.default = false
|
|
127
105
|
}
|
|
128
106
|
|
|
129
107
|
@given('the branch TTL is {float} second(s)')
|
|
130
|
-
public async setBranchTTL
|
|
108
|
+
public async setBranchTTL(seconds: number): Promise<void> {
|
|
131
109
|
process.env.__TESTING_EXPOSITION_BRANCH_TTL = String(seconds * 1000)
|
|
132
|
-
|
|
133
|
-
await Gateway.stop()
|
|
134
|
-
|
|
135
|
-
this.default = false
|
|
136
110
|
}
|
|
137
111
|
|
|
138
112
|
@given('the Gateway is running')
|
|
139
|
-
public async start
|
|
140
|
-
if (instance !== null)
|
|
141
|
-
return
|
|
142
|
-
|
|
113
|
+
public async start(): Promise<void> {
|
|
143
114
|
process.env.TOA_EXPOSITION ??= DEFAULT_TREE
|
|
144
115
|
process.env.TOA_EXPOSITION_PROPERTIES ??= JSON.stringify(DEFAULT_PROPERTIES)
|
|
145
116
|
|
|
146
117
|
this.writeConfiguration()
|
|
147
118
|
|
|
119
|
+
const signature = Gateway.signature()
|
|
120
|
+
|
|
121
|
+
/*
|
|
122
|
+
* A component is published without restarting the gateway, and a scenario that asks for
|
|
123
|
+
* the deployment already running gets that one. Only a different deployment is a restart,
|
|
124
|
+
* which is what an annotation, a configuration or a branch TTL of its own amounts to.
|
|
125
|
+
*/
|
|
126
|
+
if (instance !== null && signature === deployment) return
|
|
127
|
+
|
|
128
|
+
await Gateway.stop()
|
|
129
|
+
|
|
148
130
|
const factory = new Factory(boot.host())
|
|
149
131
|
const service = await factory.service()
|
|
150
132
|
|
|
151
|
-
if (service === null)
|
|
152
|
-
throw new Error('?')
|
|
133
|
+
if (service === null) throw new Error('?')
|
|
153
134
|
|
|
154
135
|
instance = service
|
|
155
136
|
|
|
156
137
|
await service.connect()
|
|
157
138
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
139
|
+
deployment = signature
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** What the running gateway was built from: a different value is a different deployment. */
|
|
143
|
+
private static signature(): string {
|
|
144
|
+
const configuration = Object.keys(process.env)
|
|
145
|
+
.filter((key) => key.startsWith('TOA_CONFIGURATION_'))
|
|
146
|
+
.sort()
|
|
147
|
+
.map((key) => [key, process.env[key]])
|
|
148
|
+
|
|
149
|
+
return JSON.stringify([
|
|
150
|
+
process.env.TOA_EXPOSITION,
|
|
151
|
+
process.env.TOA_EXPOSITION_PROPERTIES,
|
|
152
|
+
process.env.__TESTING_EXPOSITION_BRANCH_TTL,
|
|
153
|
+
configuration
|
|
154
|
+
])
|
|
166
155
|
}
|
|
167
156
|
|
|
168
157
|
@after()
|
|
169
|
-
public async cleanup
|
|
158
|
+
public async cleanup(): Promise<void> {
|
|
170
159
|
delete process.env.__TESTING_EXPOSITION_BRANCH_TTL
|
|
171
160
|
|
|
172
|
-
for (const key of this.written)
|
|
173
|
-
delete process.env[key]
|
|
161
|
+
for (const key of this.written) delete process.env[key]
|
|
174
162
|
|
|
175
163
|
this.written = []
|
|
176
164
|
|
|
177
|
-
if (this.default)
|
|
178
|
-
return
|
|
179
|
-
|
|
180
165
|
delete process.env.TOA_EXPOSITION
|
|
181
166
|
delete process.env.TOA_EXPOSITION_PROPERTIES
|
|
182
|
-
|
|
183
|
-
await Gateway.stop()
|
|
184
167
|
}
|
|
185
168
|
|
|
186
169
|
@afterAll()
|
|
187
|
-
public static async stop
|
|
170
|
+
public static async stop(): Promise<void> {
|
|
188
171
|
await instance?.disconnect()
|
|
189
172
|
instance = null
|
|
173
|
+
deployment = null
|
|
190
174
|
}
|
|
191
175
|
|
|
192
|
-
private writeConfiguration
|
|
176
|
+
private writeConfiguration(): void {
|
|
193
177
|
for (const [id, configuration] of Object.entries(DEFAULT_CONFIGURATION)) {
|
|
194
178
|
const [name, namespace = 'default'] = id.split('.').reverse()
|
|
195
179
|
const key = `TOA_CONFIGURATION_${namespace.toUpperCase()}_${name.toUpperCase()}`
|
|
@@ -217,13 +201,12 @@ const DEFAULT_TREE = JSON.stringify({
|
|
|
217
201
|
]
|
|
218
202
|
} satisfies syntax.Node)
|
|
219
203
|
|
|
220
|
-
/** Milliseconds a composition is given to finish connecting what it needs. */
|
|
221
|
-
const DISCOVERY = 500
|
|
222
|
-
|
|
223
204
|
const DEFAULT_PROPERTIES: Partial<http.Options> = {
|
|
224
205
|
authorities: {
|
|
225
206
|
nex: 'nex.toa.io'
|
|
226
207
|
},
|
|
208
|
+
port: PORT,
|
|
209
|
+
probe: PROBE,
|
|
227
210
|
// `npm run features:h2c` runs the whole suite over cleartext HTTP/2
|
|
228
211
|
protocol: process.env.TOA_EXPOSITION_PROTOCOL === 'h2c' ? 'h2c' : 'h1'
|
|
229
212
|
}
|
package/features/steps/HTTP.ts
CHANGED
|
@@ -17,25 +17,25 @@ const { binding, then, when } = tsflow
|
|
|
17
17
|
export class HTTP extends http.Agent {
|
|
18
18
|
private readonly gateway: Gateway
|
|
19
19
|
|
|
20
|
-
public constructor
|
|
20
|
+
public constructor(gateway: Gateway, parameters: Parameters, captures: Captures) {
|
|
21
21
|
super(parameters.origin, captures)
|
|
22
22
|
this.gateway = gateway
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
@when('the following request is received:')
|
|
26
|
-
public override async request
|
|
26
|
+
public override async request(input: string): Promise<any> {
|
|
27
27
|
await this.gateway.start()
|
|
28
28
|
|
|
29
29
|
await super.request(input)
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
@then('the following reply is sent:')
|
|
33
|
-
public override responseIncludes
|
|
33
|
+
public override responseIncludes(expected: string): void {
|
|
34
34
|
super.responseIncludes(expected)
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
@then('response body contains {word}-encoded value:')
|
|
38
|
-
public async bodyIs
|
|
38
|
+
public async bodyIs(format: string, yaml: string): Promise<void> {
|
|
39
39
|
assert.ok(this.bytes !== null, 'Response body is not available')
|
|
40
40
|
|
|
41
41
|
const value = encoders[format]?.(this.bytes)
|
|
@@ -45,12 +45,12 @@ export class HTTP extends http.Agent {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
@then('the reply does not contain:')
|
|
48
|
-
public override responseExcludes
|
|
48
|
+
public override responseExcludes(expected: string): void {
|
|
49
49
|
super.responseExcludes(expected)
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
@when('the stream of `{word}` is received with the following headers:')
|
|
53
|
-
public async streamRequest
|
|
53
|
+
public async streamRequest(filename: string, head: string): Promise<any> {
|
|
54
54
|
const stream = open(filename)
|
|
55
55
|
|
|
56
56
|
await this.gateway.start()
|
|
@@ -58,30 +58,27 @@ export class HTTP extends http.Agent {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
@then('the stream equals to `{word}` is sent with the following headers:')
|
|
61
|
-
public async responseStreamMatch
|
|
61
|
+
public async responseStreamMatch(filename: string, head: string): Promise<any> {
|
|
62
62
|
const stream = open(filename)
|
|
63
63
|
|
|
64
64
|
await super.streamMatch(head, stream)
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
@when('the following request is interrupted after {float} second(s):')
|
|
68
|
-
public async interrupt
|
|
68
|
+
public async interrupt(delay: number, input: string): Promise<any> {
|
|
69
69
|
const controller = new AbortController()
|
|
70
70
|
|
|
71
71
|
await this.gateway.start()
|
|
72
72
|
|
|
73
73
|
setTimeout(() => {
|
|
74
|
-
if (pending)
|
|
75
|
-
|
|
76
|
-
else
|
|
77
|
-
console.error('Request cannot be interrupted as it is already completed')
|
|
74
|
+
if (pending) controller.abort()
|
|
75
|
+
else console.error('Request cannot be interrupted as it is already completed')
|
|
78
76
|
}, delay * 1000)
|
|
79
77
|
|
|
80
78
|
let pending = true
|
|
81
79
|
|
|
82
80
|
await super.fetch(input, { signal: controller.signal }).catch((e) => {
|
|
83
|
-
if (e.name !== 'AbortError')
|
|
84
|
-
throw e
|
|
81
|
+
if (e.name !== 'AbortError') throw e
|
|
85
82
|
})
|
|
86
83
|
|
|
87
84
|
pending = false
|
|
@@ -90,7 +87,7 @@ export class HTTP extends http.Agent {
|
|
|
90
87
|
|
|
91
88
|
const FILES_DIR = path.resolve(import.meta.dirname, '../../../storages/source/test')
|
|
92
89
|
|
|
93
|
-
function open
|
|
90
|
+
function open(filename: string): Readable {
|
|
94
91
|
return fs.createReadStream(path.join(FILES_DIR, filename))
|
|
95
92
|
}
|
|
96
93
|
|
package/features/steps/IDP.ts
CHANGED
|
@@ -20,12 +20,12 @@ export class IDP {
|
|
|
20
20
|
private static authCodes = new Map<string, AuthCode>()
|
|
21
21
|
private readonly captures: Captures
|
|
22
22
|
|
|
23
|
-
public constructor
|
|
23
|
+
public constructor(captures: Captures) {
|
|
24
24
|
this.captures = captures
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
@afterAll()
|
|
28
|
-
public static async stop
|
|
28
|
+
public static async stop(): Promise<void> {
|
|
29
29
|
if (this.server instanceof http.Server) {
|
|
30
30
|
this.server.close()
|
|
31
31
|
await once(this.server, 'close')
|
|
@@ -33,25 +33,27 @@ export class IDP {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
@given(/local IDP is running/i)
|
|
36
|
-
public async start
|
|
36
|
+
public async start(): Promise<void> {
|
|
37
37
|
if (IDP.server instanceof http.Server) return
|
|
38
38
|
|
|
39
39
|
// creating the key
|
|
40
|
-
const {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
const { publicKey, privateKey } = await util.promisify(crypto.generateKeyPair)(
|
|
41
|
+
'rsa',
|
|
42
|
+
{
|
|
43
|
+
modulusLength: 2048
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
46
|
|
|
47
47
|
IDP.privateKey = privateKey
|
|
48
48
|
|
|
49
49
|
const jwk = JSON.stringify({
|
|
50
|
-
keys: [
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
keys: [
|
|
51
|
+
{
|
|
52
|
+
use: 'sig',
|
|
53
|
+
alg: 'RS256',
|
|
54
|
+
...publicKey.export({ format: 'jwk' })
|
|
55
|
+
}
|
|
56
|
+
]
|
|
55
57
|
})
|
|
56
58
|
|
|
57
59
|
const JWK_ENDPOINT = '/.well-known/jwks'
|
|
@@ -71,79 +73,83 @@ export class IDP {
|
|
|
71
73
|
response.end(jwk)
|
|
72
74
|
break
|
|
73
75
|
|
|
74
|
-
case '/.well-known/openid-configuration':
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
break
|
|
97
|
-
|
|
98
|
-
case TOKEN_ENDPOINT: {
|
|
99
|
-
if (request.method !== 'POST') {
|
|
100
|
-
response.writeHead(405, { 'Content-Type': 'text/plain' })
|
|
101
|
-
response.end('Method not allowed')
|
|
102
|
-
|
|
103
|
-
return
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const buf = await buffer(request)
|
|
107
|
-
const body = buf.toString('utf8')
|
|
108
|
-
|
|
109
|
-
const params = new URLSearchParams(body)
|
|
110
|
-
const grantType = params.get('grant_type')!
|
|
111
|
-
const code = params.get('code')!
|
|
112
|
-
const redirectUri = params.get('redirect_uri')!
|
|
113
|
-
const clientId = params.get('client_id')!
|
|
114
|
-
|
|
115
|
-
if (grantType !== 'authorization_code' || !code || !clientId) {
|
|
116
|
-
response.writeHead(400, { 'Content-Type': 'application/json' })
|
|
117
|
-
response.end(JSON.stringify({ error: 'invalid_request' }))
|
|
76
|
+
case '/.well-known/openid-configuration':
|
|
77
|
+
{
|
|
78
|
+
const openIdConfiguration = JSON.stringify({
|
|
79
|
+
issuer: IDP.issuer,
|
|
80
|
+
jwks_uri: IDP.issuer + JWK_ENDPOINT,
|
|
81
|
+
authorization_endpoint: IDP.issuer + AUTH_ENDPOINT,
|
|
82
|
+
token_endpoint: IDP.issuer + TOKEN_ENDPOINT,
|
|
83
|
+
response_types_supported: ['id_token', 'code'],
|
|
84
|
+
grant_types_supported: ['authorization_code'],
|
|
85
|
+
subject_types_supported: ['public'],
|
|
86
|
+
id_token_signing_alg_values_supported: ['RS256'],
|
|
87
|
+
scopes_supported: ['openid', 'email', 'profile']
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
response.writeHead(200, {
|
|
91
|
+
'Content-Type': 'application/json',
|
|
92
|
+
'Cache-Control': 'public, max-age=3600',
|
|
93
|
+
'Content-Length': openIdConfiguration.length
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
response.end(openIdConfiguration)
|
|
118
97
|
}
|
|
119
98
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
if (!codeData ||
|
|
123
|
-
codeData.expiresAt < Date.now() ||
|
|
124
|
-
codeData.clientId !== clientId ||
|
|
125
|
-
(redirectUri && codeData.redirectUri !== redirectUri)) {
|
|
126
|
-
response.writeHead(400, { 'Content-Type': 'application/json' })
|
|
127
|
-
response.end(JSON.stringify({ error: 'invalid_grant' }))
|
|
99
|
+
break
|
|
128
100
|
|
|
129
|
-
|
|
101
|
+
case TOKEN_ENDPOINT:
|
|
102
|
+
{
|
|
103
|
+
if (request.method !== 'POST') {
|
|
104
|
+
response.writeHead(405, { 'Content-Type': 'text/plain' })
|
|
105
|
+
response.end('Method not allowed')
|
|
106
|
+
|
|
107
|
+
return
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const buf = await buffer(request)
|
|
111
|
+
const body = buf.toString('utf8')
|
|
112
|
+
|
|
113
|
+
const params = new URLSearchParams(body)
|
|
114
|
+
const grantType = params.get('grant_type')!
|
|
115
|
+
const code = params.get('code')!
|
|
116
|
+
const redirectUri = params.get('redirect_uri')!
|
|
117
|
+
const clientId = params.get('client_id')!
|
|
118
|
+
|
|
119
|
+
if (grantType !== 'authorization_code' || !code || !clientId) {
|
|
120
|
+
response.writeHead(400, { 'Content-Type': 'application/json' })
|
|
121
|
+
response.end(JSON.stringify({ error: 'invalid_request' }))
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const codeData = IDP.authCodes.get(code)
|
|
125
|
+
|
|
126
|
+
if (
|
|
127
|
+
!codeData ||
|
|
128
|
+
codeData.expiresAt < Date.now() ||
|
|
129
|
+
codeData.clientId !== clientId ||
|
|
130
|
+
(redirectUri && codeData.redirectUri !== redirectUri)
|
|
131
|
+
) {
|
|
132
|
+
response.writeHead(400, { 'Content-Type': 'application/json' })
|
|
133
|
+
response.end(JSON.stringify({ error: 'invalid_grant' }))
|
|
134
|
+
|
|
135
|
+
return
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const accessToken = crypto.randomBytes(32).toString('hex')
|
|
139
|
+
const idToken = this.generateIdToken(codeData.sub, codeData.email, clientId)
|
|
140
|
+
|
|
141
|
+
IDP.authCodes.delete(code)
|
|
142
|
+
|
|
143
|
+
response.writeHead(200, { 'Content-Type': 'application/json' }).end(
|
|
144
|
+
JSON.stringify({
|
|
145
|
+
access_token: accessToken,
|
|
146
|
+
token_type: 'Bearer',
|
|
147
|
+
id_token: idToken,
|
|
148
|
+
expires_in: 3600
|
|
149
|
+
})
|
|
150
|
+
)
|
|
130
151
|
}
|
|
131
152
|
|
|
132
|
-
const accessToken = crypto.randomBytes(32).toString('hex')
|
|
133
|
-
const idToken = this.generateIdToken(codeData.sub, codeData.email, clientId)
|
|
134
|
-
|
|
135
|
-
IDP.authCodes.delete(code)
|
|
136
|
-
|
|
137
|
-
response
|
|
138
|
-
.writeHead(200, { 'Content-Type': 'application/json' })
|
|
139
|
-
.end(JSON.stringify({
|
|
140
|
-
access_token: accessToken,
|
|
141
|
-
token_type: 'Bearer',
|
|
142
|
-
id_token: idToken,
|
|
143
|
-
expires_in: 3600
|
|
144
|
-
}))
|
|
145
|
-
}
|
|
146
|
-
|
|
147
153
|
break
|
|
148
154
|
|
|
149
155
|
default:
|
|
@@ -152,7 +158,8 @@ export class IDP {
|
|
|
152
158
|
}
|
|
153
159
|
})
|
|
154
160
|
|
|
155
|
-
|
|
161
|
+
// in Toa's own block, and out of the ephemeral range an arbitrary port would sit in
|
|
162
|
+
server.listen(31005, 'localhost')
|
|
156
163
|
await once(server, 'listening')
|
|
157
164
|
|
|
158
165
|
const address = server.address() as AddressInfo
|
|
@@ -163,7 +170,7 @@ export class IDP {
|
|
|
163
170
|
}
|
|
164
171
|
|
|
165
172
|
@given('the IDP token for {word} is issued')
|
|
166
|
-
public async issueToken
|
|
173
|
+
public async issueToken(user: string): Promise<void> {
|
|
167
174
|
assert.ok(IDP.privateKey, 'IdP private key is not available')
|
|
168
175
|
|
|
169
176
|
const jwt = [
|
|
@@ -183,7 +190,10 @@ export class IDP {
|
|
|
183
190
|
.map((v) => Buffer.from(JSON.stringify(v)).toString('base64url'))
|
|
184
191
|
.join('.')
|
|
185
192
|
|
|
186
|
-
const signature = crypto
|
|
193
|
+
const signature = crypto
|
|
194
|
+
.createSign('RSA-SHA256')
|
|
195
|
+
.end(jwt)
|
|
196
|
+
.sign(IDP.privateKey, 'base64url')
|
|
187
197
|
|
|
188
198
|
const idToken = `${jwt}.${signature}`
|
|
189
199
|
|
|
@@ -191,7 +201,7 @@ export class IDP {
|
|
|
191
201
|
}
|
|
192
202
|
|
|
193
203
|
@given('the IDP random token is issued')
|
|
194
|
-
public async issueNewToken
|
|
204
|
+
public async issueNewToken(): Promise<void> {
|
|
195
205
|
assert.ok(IDP.privateKey, 'IdP private key is not available')
|
|
196
206
|
|
|
197
207
|
const sub = Math.random().toString(36).substring(7)
|
|
@@ -213,7 +223,10 @@ export class IDP {
|
|
|
213
223
|
.map((v) => Buffer.from(JSON.stringify(v)).toString('base64url'))
|
|
214
224
|
.join('.')
|
|
215
225
|
|
|
216
|
-
const signature = crypto
|
|
226
|
+
const signature = crypto
|
|
227
|
+
.createSign('RSA-SHA256')
|
|
228
|
+
.end(jwt)
|
|
229
|
+
.sign(IDP.privateKey, 'base64url')
|
|
217
230
|
|
|
218
231
|
const idToken = `${jwt}.${signature}`
|
|
219
232
|
|
|
@@ -223,7 +236,11 @@ export class IDP {
|
|
|
223
236
|
}
|
|
224
237
|
|
|
225
238
|
@given('the IDP {word} token for {word} is issued with following secret:')
|
|
226
|
-
public async issueSymmetricToken
|
|
239
|
+
public async issueSymmetricToken(
|
|
240
|
+
alg: string,
|
|
241
|
+
user: string,
|
|
242
|
+
secret: string
|
|
243
|
+
): Promise<void> {
|
|
227
244
|
const jwt = [
|
|
228
245
|
{
|
|
229
246
|
typ: 'JWT',
|
|
@@ -240,7 +257,8 @@ export class IDP {
|
|
|
240
257
|
.map((v) => Buffer.from(JSON.stringify(v)).toString('base64url'))
|
|
241
258
|
.join('.')
|
|
242
259
|
|
|
243
|
-
const signature = crypto
|
|
260
|
+
const signature = crypto
|
|
261
|
+
.createHmac(alg.replace(/^HS(\d{3})$/, 'sha$1'), secret)
|
|
244
262
|
.update(jwt)
|
|
245
263
|
.digest('base64url')
|
|
246
264
|
|
|
@@ -250,7 +268,7 @@ export class IDP {
|
|
|
250
268
|
}
|
|
251
269
|
|
|
252
270
|
@given('ID token with jti is issued for {word}')
|
|
253
|
-
public async issueTokenWithJti
|
|
271
|
+
public async issueTokenWithJti(user: string): Promise<void> {
|
|
254
272
|
assert.ok(IDP.privateKey, 'IdP private key is not available')
|
|
255
273
|
|
|
256
274
|
const jwt = [
|
|
@@ -271,7 +289,10 @@ export class IDP {
|
|
|
271
289
|
.map((v) => Buffer.from(JSON.stringify(v)).toString('base64url'))
|
|
272
290
|
.join('.')
|
|
273
291
|
|
|
274
|
-
const signature = crypto
|
|
292
|
+
const signature = crypto
|
|
293
|
+
.createSign('RSA-SHA256')
|
|
294
|
+
.end(jwt)
|
|
295
|
+
.sign(IDP.privateKey, 'base64url')
|
|
275
296
|
|
|
276
297
|
const idToken = `${jwt}.${signature}`
|
|
277
298
|
|
|
@@ -279,7 +300,7 @@ export class IDP {
|
|
|
279
300
|
}
|
|
280
301
|
|
|
281
302
|
@given('auth code for {word} is issued for {word}')
|
|
282
|
-
public async issueAuthCode
|
|
303
|
+
public async issueAuthCode(user: string, redirectUri: string): Promise<void> {
|
|
283
304
|
const code = crypto.randomBytes(16).toString('hex')
|
|
284
305
|
const email = user + '@test.local'
|
|
285
306
|
const clientId = 'nex'
|
|
@@ -300,7 +321,7 @@ export class IDP {
|
|
|
300
321
|
this.captures.set(`${user}.code_credentials`, base64)
|
|
301
322
|
}
|
|
302
323
|
|
|
303
|
-
private generateIdToken
|
|
324
|
+
private generateIdToken(sub: string, email: string, clientId: string): string {
|
|
304
325
|
assert.ok(IDP.privateKey, 'IdP private key is not available')
|
|
305
326
|
assert.ok(IDP.issuer, 'IdP issuer is not available')
|
|
306
327
|
|
|
@@ -321,7 +342,10 @@ export class IDP {
|
|
|
321
342
|
.map((v) => Buffer.from(JSON.stringify(v)).toString('base64url'))
|
|
322
343
|
.join('.')
|
|
323
344
|
|
|
324
|
-
const signature = crypto
|
|
345
|
+
const signature = crypto
|
|
346
|
+
.createSign('RSA-SHA256')
|
|
347
|
+
.end(jwt)
|
|
348
|
+
.sign(IDP.privateKey, 'base64url')
|
|
325
349
|
|
|
326
350
|
return `${jwt}.${signature}`
|
|
327
351
|
}
|