@toa.io/extensions.exposition 1.0.0-alpha.284 → 1.0.0-alpha.286
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/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 +23 -17
- 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 +45 -31
- 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/mcp.feature +32 -28
- package/features/oauth.grants.feature +1 -1
- package/features/octets.cloudinary.feature +1 -1
- package/features/octets.download.feature +1 -0
- package/features/require.feature +1 -2
- package/features/rpc.feature +21 -21
- 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 -71
- 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 +29 -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 -27
- package/source/MCP/types.ts +4 -1
- 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 +51 -32
- package/source/RPC/names.ts +26 -32
- 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 +64 -27
- 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 +14 -5
- package/source/directives/mcp/Tool.test.ts +42 -6
- package/source/directives/mcp/Tool.ts +38 -7
- 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.d.ts +2 -0
- 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 -6
- package/transpiled/MCP/tools.js.map +1 -1
- package/transpiled/MCP/types.d.ts +3 -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.d.ts +3 -2
- package/transpiled/RPC/names.js +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 +7 -1
- package/transpiled/directives/mcp/MCP.js.map +1 -1
- package/transpiled/directives/mcp/Tool.d.ts +6 -1
- package/transpiled/directives/mcp/Tool.js +16 -3
- 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/CHANGELOG.md +0 -541
- 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
package/source/Tenant.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { setTimeout } from 'node:timers/promises'
|
|
2
2
|
import { Connector } from '@toa.io/core'
|
|
3
3
|
import { BRANCH_TTL } from './const.js'
|
|
4
|
-
import type { bindings } from '@toa.io/core'
|
|
4
|
+
import type { bindings } from '@toa.io/core/types'
|
|
5
5
|
import type { Label } from './discovery.js'
|
|
6
6
|
import type { Branch } from './Branch.js'
|
|
7
7
|
|
|
@@ -11,7 +11,7 @@ export class Tenant extends Connector {
|
|
|
11
11
|
private started = 0
|
|
12
12
|
private stopped = false
|
|
13
13
|
|
|
14
|
-
public constructor
|
|
14
|
+
public constructor(broadcast: Broadcast, branch: Omit<Branch, 'timestamp'>) {
|
|
15
15
|
super()
|
|
16
16
|
|
|
17
17
|
this.broadcast = broadcast
|
|
@@ -20,7 +20,7 @@ export class Tenant extends Connector {
|
|
|
20
20
|
this.depends(broadcast)
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
public override async open
|
|
23
|
+
public override async open(): Promise<void> {
|
|
24
24
|
this.started = Date.now()
|
|
25
25
|
|
|
26
26
|
await this.expose()
|
|
@@ -35,35 +35,35 @@ export class Tenant extends Connector {
|
|
|
35
35
|
* announces itself once more has its routes held open by whoever is listening, and the
|
|
36
36
|
* requests that follow reach nothing.
|
|
37
37
|
*/
|
|
38
|
-
protected override async close
|
|
38
|
+
protected override async close(): Promise<void> {
|
|
39
39
|
this.stopped = true
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
private async announce
|
|
42
|
+
private async announce(): Promise<void> {
|
|
43
43
|
while (!this.stopped) {
|
|
44
44
|
const delay = exposeInterval(Date.now() - this.started)
|
|
45
45
|
|
|
46
46
|
await setTimeout(delay, undefined, { ref: false })
|
|
47
47
|
|
|
48
|
-
if (this.stopped)
|
|
49
|
-
break
|
|
48
|
+
if (this.stopped) break
|
|
50
49
|
|
|
51
50
|
await this.expose()
|
|
52
51
|
}
|
|
53
52
|
}
|
|
54
53
|
|
|
55
|
-
private async expose
|
|
54
|
+
private async expose(): Promise<void> {
|
|
56
55
|
// the ping subscription outlives the announcing loop, and answering one on the way out
|
|
57
56
|
// is the same announcement by another route
|
|
58
|
-
if (this.stopped)
|
|
59
|
-
return
|
|
57
|
+
if (this.stopped) return
|
|
60
58
|
|
|
61
59
|
await this.broadcast.transmit('expose', { ...this.branch, timestamp: this.started })
|
|
62
60
|
}
|
|
63
61
|
}
|
|
64
62
|
|
|
65
|
-
function exposeInterval
|
|
66
|
-
return Math.round(
|
|
63
|
+
function exposeInterval(uptime: number): number {
|
|
64
|
+
return Math.round(
|
|
65
|
+
EXPOSE_MAX - (EXPOSE_MAX - EXPOSE_MIN) * Math.exp(-uptime / EXPOSE_TAU)
|
|
66
|
+
)
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
const EXPOSE_MIN = 5_000
|
package/source/deployment.ts
CHANGED
|
@@ -8,7 +8,11 @@ import { components } from './Composition.js'
|
|
|
8
8
|
import { parse } from './RTD/syntax/index.js'
|
|
9
9
|
import { DELAY, PORT, PROBE } from './HTTP/index.js'
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
/** Where Toa's release publishes this service's image. An application takes it
|
|
12
|
+
* instead of building one when its context says `registry.services: published`. */
|
|
13
|
+
export const image = 'ghcr.io/toa-io/extension-exposition-gateway'
|
|
14
|
+
|
|
15
|
+
export function deployment(_: unknown, annotation?: Annotation): Dependency {
|
|
12
16
|
assert.ok(annotation !== undefined, 'Exposition context annotation is required')
|
|
13
17
|
schemas.annotation.validate(annotation)
|
|
14
18
|
|
|
@@ -17,8 +21,10 @@ export function deployment (_: unknown, annotation?: Annotation): Dependency {
|
|
|
17
21
|
const service: Service = {
|
|
18
22
|
group: 'exposition',
|
|
19
23
|
name: 'gateway',
|
|
24
|
+
image,
|
|
20
25
|
port: PORT,
|
|
21
|
-
version: JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'))
|
|
26
|
+
version: JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'))
|
|
27
|
+
.version,
|
|
22
28
|
variables: [],
|
|
23
29
|
components: labels,
|
|
24
30
|
resources: annotation.resources,
|
|
@@ -44,8 +50,7 @@ export function deployment (_: unknown, annotation?: Annotation): Dependency {
|
|
|
44
50
|
service.ingress!.hosts = Object.values(authorities)
|
|
45
51
|
|
|
46
52
|
// leaving these undefined lets the context's own ingress section supply them
|
|
47
|
-
if (annotation.class !== undefined)
|
|
48
|
-
service.ingress!.class = annotation.class
|
|
53
|
+
if (annotation.class !== undefined) service.ingress!.class = annotation.class
|
|
49
54
|
|
|
50
55
|
if (annotation.annotations !== undefined)
|
|
51
56
|
service.ingress!.annotations = annotation.annotations
|
|
@@ -55,26 +60,19 @@ export function deployment (_: unknown, annotation?: Annotation): Dependency {
|
|
|
55
60
|
|
|
56
61
|
const properties: Properties = { authorities }
|
|
57
62
|
|
|
58
|
-
if (debug === true)
|
|
59
|
-
properties.debug = true
|
|
63
|
+
if (debug === true) properties.debug = true
|
|
60
64
|
|
|
61
|
-
if (annotation.protocol !== undefined)
|
|
62
|
-
properties.protocol = annotation.protocol
|
|
65
|
+
if (annotation.protocol !== undefined) properties.protocol = annotation.protocol
|
|
63
66
|
|
|
64
|
-
if (annotation.ip !== undefined)
|
|
65
|
-
properties.ip = annotation.ip
|
|
67
|
+
if (annotation.ip !== undefined) properties.ip = annotation.ip
|
|
66
68
|
|
|
67
|
-
if (annotation.bouncer !== undefined)
|
|
68
|
-
properties.bouncer = annotation.bouncer
|
|
69
|
+
if (annotation.bouncer !== undefined) properties.bouncer = annotation.bouncer
|
|
69
70
|
|
|
70
|
-
if (annotation.oauth !== undefined)
|
|
71
|
-
properties.oauth = annotation.oauth
|
|
71
|
+
if (annotation.oauth !== undefined) properties.oauth = annotation.oauth
|
|
72
72
|
|
|
73
|
-
if (annotation.rpc !== undefined)
|
|
74
|
-
properties.rpc = annotation.rpc
|
|
73
|
+
if (annotation.rpc !== undefined) properties.rpc = annotation.rpc
|
|
75
74
|
|
|
76
|
-
if (annotation.mcp !== undefined)
|
|
77
|
-
properties.mcp = annotation.mcp
|
|
75
|
+
if (annotation.mcp !== undefined) properties.mcp = annotation.mcp
|
|
78
76
|
|
|
79
77
|
service.variables!.push({
|
|
80
78
|
name: 'TOA_EXPOSITION_PROPERTIES',
|
|
@@ -92,5 +90,7 @@ export function deployment (_: unknown, annotation?: Annotation): Dependency {
|
|
|
92
90
|
return { services: [service] }
|
|
93
91
|
}
|
|
94
92
|
|
|
95
|
-
type Properties = Pick<
|
|
96
|
-
|
|
93
|
+
type Properties = Pick<
|
|
94
|
+
Annotation,
|
|
95
|
+
'authorities' | 'debug' | 'protocol' | 'bouncer' | 'ip' | 'oauth' | 'rpc' | 'mcp'
|
|
96
|
+
>
|
|
@@ -14,7 +14,10 @@ describe('anonymous', () => {
|
|
|
14
14
|
|
|
15
15
|
it('should refuse a request that presents a credential', () => {
|
|
16
16
|
// it would make the reply uncacheable, which is the whole of the rule
|
|
17
|
-
assert.equal(
|
|
17
|
+
assert.equal(
|
|
18
|
+
new Anonymous(true).authorize(null, context({ authorization: 'Token x' })),
|
|
19
|
+
false
|
|
20
|
+
)
|
|
18
21
|
})
|
|
19
22
|
|
|
20
23
|
it('should admit a procedure whatever the request presented', () => {
|
|
@@ -33,6 +36,9 @@ describe('anonymous', () => {
|
|
|
33
36
|
const directive = new Anonymous(true)
|
|
34
37
|
|
|
35
38
|
assert.equal(directive.admits(null, context({ authorization: 'Token x' })), false)
|
|
36
|
-
assert.equal(
|
|
39
|
+
assert.equal(
|
|
40
|
+
directive.admits(null, context({ authorization: 'Token x' }, true)),
|
|
41
|
+
true
|
|
42
|
+
)
|
|
37
43
|
})
|
|
38
44
|
})
|
|
@@ -3,7 +3,7 @@ import { type Directive, type Context } from './types.js'
|
|
|
3
3
|
export class Anonymous implements Directive {
|
|
4
4
|
private readonly allow: boolean
|
|
5
5
|
|
|
6
|
-
public constructor
|
|
6
|
+
public constructor(allow: boolean) {
|
|
7
7
|
this.allow = allow
|
|
8
8
|
}
|
|
9
9
|
|
|
@@ -12,16 +12,13 @@ export class Anonymous implements Directive {
|
|
|
12
12
|
* of the rule, and none of it applies to a procedure: what a procedure answers is a value
|
|
13
13
|
* in an envelope, and the envelope is the one thing that is cached or not.
|
|
14
14
|
*/
|
|
15
|
-
public authorize
|
|
16
|
-
if (context.procedural)
|
|
17
|
-
return this.allow
|
|
15
|
+
public authorize(_: any, context: Context): boolean {
|
|
16
|
+
if (context.procedural) return this.allow
|
|
18
17
|
|
|
19
|
-
return 'authorization' in context.request.headers
|
|
20
|
-
? false
|
|
21
|
-
: this.allow
|
|
18
|
+
return 'authorization' in context.request.headers ? false : this.allow
|
|
22
19
|
}
|
|
23
20
|
|
|
24
|
-
public admits
|
|
21
|
+
public admits(_: any, context: Context): boolean {
|
|
25
22
|
return this.authorize(_, context)
|
|
26
23
|
}
|
|
27
24
|
}
|
|
@@ -3,15 +3,15 @@ import { type Directive, type Context } from './types.js'
|
|
|
3
3
|
export class Anyone implements Directive {
|
|
4
4
|
private readonly allow: boolean
|
|
5
5
|
|
|
6
|
-
public constructor
|
|
6
|
+
public constructor(allow: boolean) {
|
|
7
7
|
this.allow = allow
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
public authorize
|
|
10
|
+
public authorize(_: any, context: Context): boolean {
|
|
11
11
|
return context.identity !== null && this.allow
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
public admits
|
|
14
|
+
public admits(_: any, context: Context): boolean {
|
|
15
15
|
return this.authorize(_, context)
|
|
16
16
|
}
|
|
17
17
|
}
|
|
@@ -7,26 +7,26 @@ import type { Context, Directive, Identity } from './types.js'
|
|
|
7
7
|
export class Assert implements Directive {
|
|
8
8
|
private readonly disabled: boolean
|
|
9
9
|
|
|
10
|
-
public constructor
|
|
11
|
-
assert.ok(
|
|
10
|
+
public constructor(enabled: boolean) {
|
|
11
|
+
assert.ok(
|
|
12
|
+
typeof enabled === 'boolean',
|
|
13
|
+
'`auth:assert` directive value must be a boolean'
|
|
14
|
+
)
|
|
12
15
|
|
|
13
16
|
this.disabled = !enabled
|
|
14
17
|
}
|
|
15
18
|
|
|
16
|
-
public async authorize
|
|
17
|
-
if (!this.disabled)
|
|
18
|
-
await this.incept(context, identity)
|
|
19
|
+
public async authorize(identity: Identity | null, context: Context): Promise<boolean> {
|
|
20
|
+
if (!this.disabled) await this.incept(context, identity)
|
|
19
21
|
|
|
20
22
|
return false
|
|
21
23
|
}
|
|
22
24
|
|
|
23
|
-
private async incept
|
|
24
|
-
if (context.request.headers.authorization === undefined)
|
|
25
|
-
throw new http.Unauthorized()
|
|
25
|
+
private async incept(context: Context, identity: Identity | null): Promise<void> {
|
|
26
|
+
if (context.request.headers.authorization === undefined) throw new http.Unauthorized()
|
|
26
27
|
|
|
27
28
|
if (identity === null) {
|
|
28
|
-
if (!Incept.acceptable(context))
|
|
29
|
-
throw new http.Unauthorized()
|
|
29
|
+
if (!Incept.acceptable(context)) throw new http.Unauthorized()
|
|
30
30
|
|
|
31
31
|
context.identity = await Incept.incept(context, newid())
|
|
32
32
|
|
|
@@ -52,7 +52,7 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
|
|
|
52
52
|
private meter: Quotas | null = null
|
|
53
53
|
private sync: Sync | null = null
|
|
54
54
|
|
|
55
|
-
public mount
|
|
55
|
+
public mount(host: Host, options: http.Options): void {
|
|
56
56
|
this.sync?.dispose()
|
|
57
57
|
this.sync = null
|
|
58
58
|
this.meter = null
|
|
@@ -60,8 +60,7 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
|
|
|
60
60
|
const bouncer = options.bouncer
|
|
61
61
|
|
|
62
62
|
// keyed by address, which is the deployment's to name, so off until it is set
|
|
63
|
-
if (bouncer === undefined)
|
|
64
|
-
return
|
|
63
|
+
if (bouncer === undefined) return
|
|
65
64
|
|
|
66
65
|
this.meter = new Quotas({
|
|
67
66
|
keys: Keys.create([{ method: 'ip', options: BOUNCER }]),
|
|
@@ -75,29 +74,35 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
|
|
|
75
74
|
this.sync.register(this.meter)
|
|
76
75
|
}
|
|
77
76
|
|
|
78
|
-
public dispose
|
|
77
|
+
public dispose(): void {
|
|
79
78
|
this.sync?.dispose()
|
|
80
79
|
}
|
|
81
80
|
|
|
82
|
-
public create
|
|
83
|
-
assert.ok(name in constructors,
|
|
84
|
-
`Directive 'auth:${name}' is not implemented`)
|
|
81
|
+
public create(name: string, value: any, remotes: Remotes): Directive {
|
|
82
|
+
assert.ok(name in constructors, `Directive 'auth:${name}' is not implemented`)
|
|
85
83
|
|
|
86
84
|
const Class = constructors[name]
|
|
87
85
|
|
|
88
86
|
for (const name of REMOTES)
|
|
89
87
|
this.discovery[name] ??= remotes.discover('identity', name)
|
|
90
88
|
|
|
91
|
-
return match(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
89
|
+
return match(
|
|
90
|
+
Class,
|
|
91
|
+
Role,
|
|
92
|
+
() => new Role(value as string | string[], this.discovery.roles),
|
|
93
|
+
Rule,
|
|
94
|
+
() => new Rule(value as Record<string, string>, this.create.bind(this)),
|
|
95
|
+
Input,
|
|
96
|
+
() => new Input(value as Declaration[], this.create.bind(this)),
|
|
97
|
+
Incept,
|
|
98
|
+
() => new Incept(value as string, this.discovery),
|
|
99
|
+
Delegate,
|
|
100
|
+
() => new Delegate(value as string, this.discovery.roles),
|
|
101
|
+
() => new Class(value)
|
|
102
|
+
)
|
|
98
103
|
}
|
|
99
104
|
|
|
100
|
-
public arrange
|
|
105
|
+
public arrange(directives: Directive[]): void {
|
|
101
106
|
directives.sort((a, b) => (a.priority ?? 1) - (b.priority ?? 1))
|
|
102
107
|
}
|
|
103
108
|
|
|
@@ -105,28 +110,26 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
|
|
|
105
110
|
* Authentication: who the credential names, if one is presented. A credential belongs to
|
|
106
111
|
* the request, so it is read once however many calls the request carries.
|
|
107
112
|
*/
|
|
108
|
-
public async preflight
|
|
113
|
+
public async preflight(context: Context): Promise<void> {
|
|
109
114
|
context.identity = await this.resolve(context)
|
|
110
115
|
}
|
|
111
116
|
|
|
112
117
|
/** Authorization: whether that identity may make this call, which every call asks anew. */
|
|
113
|
-
public async precall
|
|
118
|
+
public async precall(
|
|
119
|
+
directives: Directive[],
|
|
114
120
|
context: Context,
|
|
115
|
-
parameters: Parameter[]
|
|
121
|
+
parameters: Parameter[]
|
|
122
|
+
): Promise<Output> {
|
|
116
123
|
for (const directive of directives) {
|
|
117
124
|
const allow = await directive.authorize(context.identity, context, parameters)
|
|
118
125
|
|
|
119
126
|
if (allow)
|
|
120
|
-
if (this.permitted(context))
|
|
121
|
-
|
|
122
|
-
else
|
|
123
|
-
throw new http.Forbidden()
|
|
127
|
+
if (this.permitted(context)) return directive.reply?.(context) ?? null
|
|
128
|
+
else throw new http.Forbidden()
|
|
124
129
|
}
|
|
125
130
|
|
|
126
|
-
if (context.identity === null)
|
|
127
|
-
|
|
128
|
-
else
|
|
129
|
-
throw new http.Forbidden()
|
|
131
|
+
if (context.identity === null) throw new http.Unauthorized()
|
|
132
|
+
else throw new http.Forbidden()
|
|
130
133
|
}
|
|
131
134
|
|
|
132
135
|
/**
|
|
@@ -142,8 +145,11 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
|
|
|
142
145
|
* admission is a disjunction and stops at the first that admits, while what the directives
|
|
143
146
|
* fill is not any one of them's to state alone.
|
|
144
147
|
*/
|
|
145
|
-
public async explain
|
|
146
|
-
|
|
148
|
+
public async explain(
|
|
149
|
+
directives: Directive[],
|
|
150
|
+
context: Context,
|
|
151
|
+
introspection: Introspection
|
|
152
|
+
): Promise<Introspection | null> {
|
|
147
153
|
let untold = false
|
|
148
154
|
let admitted = false
|
|
149
155
|
|
|
@@ -163,8 +169,7 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
|
|
|
163
169
|
}
|
|
164
170
|
}
|
|
165
171
|
|
|
166
|
-
if (!admitted && !untold)
|
|
167
|
-
return null
|
|
172
|
+
if (!admitted && !untold) return null
|
|
168
173
|
|
|
169
174
|
// whichever of them admitted, a property any of them fills from the identity is filled
|
|
170
175
|
// from the identity: what a caller sent there would be overwritten or forged
|
|
@@ -174,35 +179,36 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
|
|
|
174
179
|
return introspection
|
|
175
180
|
}
|
|
176
181
|
|
|
177
|
-
public async settle
|
|
182
|
+
public async settle(
|
|
183
|
+
directives: Directive[],
|
|
178
184
|
context: Context,
|
|
179
|
-
response: http.OutgoingMessage
|
|
180
|
-
|
|
181
|
-
|
|
185
|
+
response: http.OutgoingMessage
|
|
186
|
+
): Promise<void> {
|
|
187
|
+
await Promise.all(
|
|
188
|
+
directives.map(async (directive) => directive.settle?.(context, response))
|
|
189
|
+
)
|
|
182
190
|
}
|
|
183
191
|
|
|
184
192
|
/**
|
|
185
193
|
* Re-issuing a credential, and refusing a ban, are the request's business: the header
|
|
186
194
|
* carries one token however many calls were made, and a ban refuses all of them.
|
|
187
195
|
*/
|
|
188
|
-
public async depart
|
|
196
|
+
public async depart(context: Context, response: http.OutgoingMessage): Promise<void> {
|
|
189
197
|
const identity = context.identity
|
|
190
198
|
|
|
191
|
-
if (identity === null)
|
|
192
|
-
return
|
|
199
|
+
if (identity === null) return
|
|
193
200
|
|
|
194
|
-
if (identity.provider === PRIMARY && !identity.refresh)
|
|
195
|
-
return
|
|
201
|
+
if (identity.provider === PRIMARY && !identity.refresh) return
|
|
196
202
|
|
|
197
|
-
|
|
203
|
+
// resolving already asked, for any provider but the primary
|
|
204
|
+
if (context.vetted !== true && (await this.banned(identity)))
|
|
198
205
|
throw new http.Unauthorized()
|
|
199
206
|
|
|
200
207
|
// a token carries the roles it was issued with, and the refresh is where they are read again;
|
|
201
208
|
// any other scheme has just read them, unless a Role directive already did
|
|
202
209
|
if (identity.provider === PRIMARY)
|
|
203
210
|
identity.roles = await Role.get(identity, this.discovery.roles)
|
|
204
|
-
else
|
|
205
|
-
identity.roles ??= await Role.get(identity, this.discovery.roles)
|
|
211
|
+
else identity.roles ??= await Role.get(identity, this.discovery.roles)
|
|
206
212
|
this.tokens ??= await this.discovery.tokens
|
|
207
213
|
|
|
208
214
|
const token = await this.tokens.invoke<string>('encrypt', {
|
|
@@ -216,17 +222,15 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
|
|
|
216
222
|
response.headers.set('cache-control', 'no-store')
|
|
217
223
|
}
|
|
218
224
|
|
|
219
|
-
private async resolve
|
|
225
|
+
private async resolve(context: Context): Promise<Identity | null> {
|
|
220
226
|
const { authority } = context
|
|
221
227
|
const { authorization } = context.request.headers
|
|
222
228
|
|
|
223
|
-
if (authorization === undefined)
|
|
224
|
-
return null
|
|
229
|
+
if (authorization === undefined) return null
|
|
225
230
|
|
|
226
231
|
const retry = this.meter?.check(context, NONE) ?? 0
|
|
227
232
|
|
|
228
|
-
if (retry > 0)
|
|
229
|
-
throw new http.TooManyRequests(retry)
|
|
233
|
+
if (retry > 0) throw new http.TooManyRequests(retry)
|
|
230
234
|
|
|
231
235
|
const [scheme, credentials] = split(authorization)
|
|
232
236
|
const candidates = providersOf(scheme)
|
|
@@ -242,16 +246,18 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
|
|
|
242
246
|
for (const candidate of candidates) {
|
|
243
247
|
this.components[candidate] ??= await this.discovery[candidate]
|
|
244
248
|
|
|
245
|
-
const answer = await this.components[candidate]!.invoke<AuthenticationResult>(
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
249
|
+
const answer = await this.components[candidate]!.invoke<AuthenticationResult>(
|
|
250
|
+
'authenticate',
|
|
251
|
+
{
|
|
252
|
+
input: {
|
|
253
|
+
scheme,
|
|
254
|
+
authority,
|
|
255
|
+
credentials
|
|
256
|
+
}
|
|
250
257
|
}
|
|
251
|
-
|
|
258
|
+
)
|
|
252
259
|
|
|
253
|
-
if (declined(answer))
|
|
254
|
-
continue
|
|
260
|
+
if (declined(answer)) continue
|
|
255
261
|
|
|
256
262
|
provider = candidate
|
|
257
263
|
result = answer
|
|
@@ -275,7 +281,11 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
|
|
|
275
281
|
|
|
276
282
|
const identity = result.identity
|
|
277
283
|
|
|
278
|
-
if (provider !== PRIMARY
|
|
284
|
+
if (provider !== PRIMARY) {
|
|
285
|
+
if (await this.banned(identity)) throw new http.Unauthorized()
|
|
286
|
+
|
|
287
|
+
context.vetted = true
|
|
288
|
+
}
|
|
279
289
|
|
|
280
290
|
identity.scheme = scheme
|
|
281
291
|
identity.provider = provider!
|
|
@@ -284,17 +294,16 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
|
|
|
284
294
|
return identity
|
|
285
295
|
}
|
|
286
296
|
|
|
287
|
-
private permitted
|
|
297
|
+
private permitted(context: Context): boolean {
|
|
288
298
|
const permissions = context.identity?.permissions
|
|
289
299
|
|
|
290
|
-
if (permissions === undefined)
|
|
291
|
-
return true
|
|
300
|
+
if (permissions === undefined) return true
|
|
292
301
|
|
|
293
302
|
// the route is matched on the normalized path, so the permission is too
|
|
294
303
|
return permits(permissions, context.request.method, context.url.pathname)
|
|
295
304
|
}
|
|
296
305
|
|
|
297
|
-
private async banned
|
|
306
|
+
private async banned(identity: Identity): Promise<boolean> {
|
|
298
307
|
this.bans ??= await this.discovery.bans
|
|
299
308
|
|
|
300
309
|
const ban = await this.bans.invoke<Ban>('observe', { query: { id: identity.id } })
|
|
@@ -304,21 +313,27 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
|
|
|
304
313
|
}
|
|
305
314
|
|
|
306
315
|
/** Whether a provider says the credentials are not of its kind, so the next is asked. */
|
|
307
|
-
function declined
|
|
316
|
+
function declined(result: AuthenticationResult): boolean {
|
|
308
317
|
return result instanceof Error && codeOf(result) === UNRECOGNIZED
|
|
309
318
|
}
|
|
310
319
|
|
|
311
|
-
function codeOf
|
|
320
|
+
function codeOf(result: Error): string | undefined {
|
|
312
321
|
const code: string | unknown = (result as unknown as { code: string }).code
|
|
313
322
|
|
|
314
323
|
return typeof code === 'string' ? code : undefined
|
|
315
324
|
}
|
|
316
325
|
|
|
317
326
|
/** Whether the permissions admit the method on the path the request is routed by. */
|
|
318
|
-
export function permits
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
327
|
+
export function permits(
|
|
328
|
+
permissions: Record<string, string[]>,
|
|
329
|
+
method: string,
|
|
330
|
+
pathname: string
|
|
331
|
+
): boolean {
|
|
332
|
+
return Object.entries(permissions).some(
|
|
333
|
+
([pattern, methods]) =>
|
|
334
|
+
methods.some((allowed) => allowed === '*' || allowed === method) &&
|
|
335
|
+
glob(pattern).match(pathname)
|
|
336
|
+
)
|
|
322
337
|
}
|
|
323
338
|
|
|
324
339
|
/**
|
|
@@ -326,12 +341,11 @@ export function permits (permissions: Record<string, string[]>, method: string,
|
|
|
326
341
|
* matched on every request the identity makes. Patterns arrive with an identity, hence
|
|
327
342
|
* the bound.
|
|
328
343
|
*/
|
|
329
|
-
function glob
|
|
344
|
+
function glob(pattern: string): Minimatch {
|
|
330
345
|
let compiled = GLOBS.get(pattern)
|
|
331
346
|
|
|
332
347
|
if (compiled === undefined) {
|
|
333
|
-
if (GLOBS.size >= GLOBS_LIMIT)
|
|
334
|
-
GLOBS.clear()
|
|
348
|
+
if (GLOBS.size >= GLOBS_LIMIT) GLOBS.clear()
|
|
335
349
|
|
|
336
350
|
compiled = new Minimatch(pattern)
|
|
337
351
|
|
|
@@ -4,7 +4,7 @@ import { Delegate } from './Delegate.js'
|
|
|
4
4
|
import type { Introspection } from '../../Introspection.js'
|
|
5
5
|
|
|
6
6
|
describe('auth:delegate', () => {
|
|
7
|
-
function explanation
|
|
7
|
+
function explanation(): Introspection {
|
|
8
8
|
return {
|
|
9
9
|
input: {
|
|
10
10
|
type: 'object',
|
|
@@ -20,7 +20,7 @@ describe('auth:delegate', () => {
|
|
|
20
20
|
it('should take the property it embeds out of the input', () => {
|
|
21
21
|
const delegate = new Delegate('identity', null as never)
|
|
22
22
|
const described = delegate.describe(explanation())
|
|
23
|
-
const input = described.input as { properties: object
|
|
23
|
+
const input = described.input as { properties: object; required: string[] }
|
|
24
24
|
|
|
25
25
|
assert.deepStrictEqual(Object.keys(input.properties), ['title'])
|
|
26
26
|
assert.deepStrictEqual(input.required, ['title'])
|
|
@@ -9,14 +9,13 @@ export class Delegate implements Directive {
|
|
|
9
9
|
private readonly property: string
|
|
10
10
|
private readonly discovery: Promise<Component>
|
|
11
11
|
|
|
12
|
-
public constructor
|
|
12
|
+
public constructor(property: string, discovery: Promise<Component>) {
|
|
13
13
|
this.property = property
|
|
14
14
|
this.discovery = discovery
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
public async authorize
|
|
18
|
-
if (identity === null)
|
|
19
|
-
return false
|
|
17
|
+
public async authorize(identity: Identity | null, context: Context): Promise<boolean> {
|
|
18
|
+
if (identity === null) return false
|
|
20
19
|
|
|
21
20
|
identity.roles ??= await Role.get(identity, this.discovery)
|
|
22
21
|
context.pipelines.body.push((body) => this.embed(body, identity))
|
|
@@ -25,20 +24,19 @@ export class Delegate implements Directive {
|
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
/** It admits whoever there is, and embedding the identity is the request's business. */
|
|
28
|
-
public admits
|
|
27
|
+
public admits(identity: Identity | null): boolean {
|
|
29
28
|
return identity !== null
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
/** The property it embeds is the identity's, so a caller has nothing to put there. */
|
|
33
|
-
public describe
|
|
32
|
+
public describe(introspection: Introspection): Introspection {
|
|
34
33
|
take(introspection, this.property)
|
|
35
34
|
|
|
36
35
|
return introspection
|
|
37
36
|
}
|
|
38
37
|
|
|
39
|
-
private embed
|
|
40
|
-
if (body === undefined)
|
|
41
|
-
body = {}
|
|
38
|
+
private embed(body: unknown, identity: Identity): Record<string, unknown> {
|
|
39
|
+
if (body === undefined) body = {}
|
|
42
40
|
|
|
43
41
|
check(body)
|
|
44
42
|
body[this.property] = structuredClone(identity)
|
|
@@ -47,7 +45,7 @@ export class Delegate implements Directive {
|
|
|
47
45
|
}
|
|
48
46
|
}
|
|
49
47
|
|
|
50
|
-
function check
|
|
48
|
+
function check(body: unknown): asserts body is Record<string, unknown> {
|
|
51
49
|
if (typeof body !== 'object' || body === null)
|
|
52
50
|
throw new BadRequest('Invalid request body')
|
|
53
51
|
}
|
|
@@ -3,9 +3,8 @@ import type { OutgoingMessage } from '../../HTTP/index.js'
|
|
|
3
3
|
import type { Directive, Identity, Context } from './types.js'
|
|
4
4
|
|
|
5
5
|
export class Echo implements Directive {
|
|
6
|
-
public authorize
|
|
7
|
-
if (identity === null && 'authorization' in context.request.headers)
|
|
8
|
-
return false
|
|
6
|
+
public authorize(identity: Identity | null, context: Context): boolean {
|
|
7
|
+
if (identity === null && 'authorization' in context.request.headers) return false
|
|
9
8
|
|
|
10
9
|
context.identity ??= create()
|
|
11
10
|
|
|
@@ -13,15 +12,13 @@ export class Echo implements Directive {
|
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
/** What `authorize` answers, without inventing the identity it would go on to invent. */
|
|
16
|
-
public admits
|
|
15
|
+
public admits(identity: Identity | null, context: Context): boolean {
|
|
17
16
|
return !(identity === null && 'authorization' in context.request.headers)
|
|
18
17
|
}
|
|
19
18
|
|
|
20
|
-
public reply
|
|
19
|
+
public reply(context: Context): OutgoingMessage {
|
|
21
20
|
const body = context.identity!
|
|
22
21
|
|
|
23
|
-
return body.scheme === null
|
|
24
|
-
? { status: 201, body }
|
|
25
|
-
: { body }
|
|
22
|
+
return body.scheme === null ? { status: 201, body } : { body }
|
|
26
23
|
}
|
|
27
24
|
}
|