@toa.io/extensions.exposition 1.0.0-alpha.291 → 1.0.0-alpha.293
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/identity.basic/package.json +8 -0
- package/components/identity.federation/package.json +8 -0
- package/components/identity.passkeys/package.json +8 -0
- package/components/identity.tokens/package.json +10 -0
- package/package.json +25 -13
- package/transpiled/Discovery/Explorer.js +1 -1
- package/transpiled/Discovery/Explorer.js.map +1 -1
- package/transpiled/Discovery/Site.js +1 -1
- package/transpiled/Discovery/Site.js.map +1 -1
- package/transpiled/Discovery/trunk.js +1 -1
- package/transpiled/Discovery/trunk.js.map +1 -1
- package/transpiled/Endpoint.js +3 -0
- package/transpiled/Endpoint.js.map +1 -1
- package/transpiled/Factory.js +1 -1
- package/transpiled/Factory.js.map +1 -1
- package/transpiled/Gateway.js +1 -1
- package/transpiled/Gateway.js.map +1 -1
- package/transpiled/HTTP/Server.d.ts +1 -1
- package/transpiled/HTTP/Server.js +1 -1
- package/transpiled/HTTP/Server.js.map +1 -1
- package/transpiled/Introspection.d.ts +6 -0
- package/transpiled/Introspection.js +1 -0
- package/transpiled/Introspection.js.map +1 -1
- package/transpiled/MCP/Server.d.ts +1 -1
- package/transpiled/MCP/Server.js +1 -1
- package/transpiled/MCP/Server.js.map +1 -1
- package/transpiled/MCP/discover.d.ts +1 -1
- package/transpiled/MCP/schema.js +2 -2
- package/transpiled/Query.d.ts +2 -12
- package/transpiled/Query.js +3 -13
- package/transpiled/Query.js.map +1 -1
- package/transpiled/RPC/Dispatcher.d.ts +1 -1
- package/transpiled/RPC/Dispatcher.js +2 -2
- package/transpiled/RPC/Dispatcher.js.map +1 -1
- package/transpiled/RTD/Endpoint.d.ts +2 -3
- package/transpiled/RTD/Tree.js +1 -1
- package/transpiled/RTD/Tree.js.map +1 -1
- package/transpiled/RTD/factory.js +1 -1
- package/transpiled/RTD/factory.js.map +1 -1
- package/transpiled/RTD/syntax/index.d.ts +1 -2
- package/transpiled/RTD/syntax/index.js +1 -2
- package/transpiled/RTD/syntax/index.js.map +1 -1
- package/transpiled/Tenant.js +1 -1
- package/transpiled/Tenant.js.map +1 -1
- package/transpiled/directives/auth/Authorization.js +1 -1
- package/transpiled/directives/auth/Authorization.js.map +1 -1
- package/transpiled/directives/io/IO.js +1 -1
- package/transpiled/directives/io/IO.js.map +1 -1
- package/transpiled/directives/oauth/documents.d.ts +1 -1
- package/transpiled/index.d.ts +0 -2
- package/transpiled/index.js +0 -2
- package/transpiled/index.js.map +1 -1
- package/transpiled/service.js +1 -1
- package/transpiled/service.js.map +1 -1
- package/ui/dist/_app/immutable/assets/0.Cu0AnR_8.css +2 -0
- package/ui/dist/_app/immutable/assets/2.BghF56l_.css +1 -0
- package/ui/dist/_app/immutable/assets/ui.C8aD6zzF.css +1 -0
- package/ui/dist/_app/immutable/chunks/B8GvXrmq.js +1 -0
- package/ui/dist/_app/immutable/chunks/BVDJTrf4.js +3 -0
- package/ui/dist/_app/immutable/chunks/D6q28_Ok.js +86 -0
- package/ui/dist/_app/immutable/chunks/{D9tE1yyO.js → DVlaUfVU.js} +1 -1
- package/ui/dist/_app/immutable/chunks/DpB73ZB6.js +6 -0
- package/ui/dist/_app/immutable/entry/app.CTava8yn.js +2 -0
- package/ui/dist/_app/immutable/entry/start.yWN0gSLA.js +1 -0
- package/ui/dist/_app/immutable/nodes/0.HKRDBYrC.js +1 -0
- package/ui/dist/_app/immutable/nodes/1.CLa0ydOi.js +1 -0
- package/ui/dist/_app/immutable/nodes/2.C9Kaym8C.js +8 -0
- package/ui/dist/_app/immutable/nodes/3.C1X4_rXZ.js +1 -0
- package/ui/dist/_app/immutable/nodes/4.DdzDIi9E.js +1 -0
- package/ui/dist/_app/immutable/nodes/5.DpbmCMdw.js +1 -0
- package/ui/dist/_app/version.json +1 -1
- package/ui/dist/index.html +12 -12
- package/CHANGELOG.md +0 -35
- package/components/identity.bans/tsconfig.tsbuildinfo +0 -1
- package/components/identity.basic/source/lib/credentials.test.ts +0 -18
- package/components/identity.basic/tsconfig.tsbuildinfo +0 -1
- package/components/identity.clients/source/lib/canonical.test.ts +0 -43
- package/components/identity.clients/source/lib/cimd.test.ts +0 -122
- package/components/identity.clients/source/lib/redirect.test.ts +0 -47
- package/components/identity.clients/tsconfig.tsbuildinfo +0 -1
- package/components/identity.credentials/source/list.test.ts +0 -70
- package/components/identity.credentials/tsconfig.tsbuildinfo +0 -1
- package/components/identity.federation/source/lib/discovery.test.ts +0 -60
- package/components/identity.federation/source/list.test.ts +0 -41
- package/components/identity.federation/tsconfig.tsbuildinfo +0 -1
- package/components/identity.grants/tsconfig.tsbuildinfo +0 -1
- package/components/identity.keys/tsconfig.tsbuildinfo +0 -1
- package/components/identity.otp/tsconfig.tsbuildinfo +0 -1
- package/components/identity.passkeys/source/errors.test.ts +0 -34
- package/components/identity.passkeys/source/webauthn.test.ts +0 -26
- package/components/identity.passkeys/tsconfig.tsbuildinfo +0 -1
- package/components/identity.roles/tsconfig.tsbuildinfo +0 -1
- package/components/identity.tokens/source/authenticate.test.ts +0 -112
- package/components/identity.tokens/source/decrypt.test.ts +0 -216
- package/components/identity.tokens/source/encrypt.test.ts +0 -150
- package/components/identity.tokens/source/issue.test.ts +0 -73
- package/components/identity.tokens/source/lib/form.test.ts +0 -25
- package/components/identity.tokens/source/lib/paseto.test.ts +0 -62
- package/components/identity.tokens/tsconfig.tsbuildinfo +0 -1
- package/context.toa.yaml +0 -31
- package/cucumber.mjs +0 -7
- package/documentation/.assets/ia3-dark.jpg +0 -0
- package/documentation/.assets/ia3-light.jpg +0 -0
- package/documentation/.assets/overview-dark.jpg +0 -0
- package/documentation/.assets/overview-light.jpg +0 -0
- package/documentation/.assets/role-scopes-dark.jpg +0 -0
- package/documentation/.assets/role-scopes-light.jpg +0 -0
- package/documentation/.assets/rtd-dark.jpg +0 -0
- package/documentation/.assets/rtd-light.jpg +0 -0
- package/documentation/access.md +0 -350
- package/documentation/authorities.md +0 -51
- package/documentation/cache.md +0 -72
- package/documentation/components.md +0 -472
- package/documentation/consent.md +0 -101
- package/documentation/credentials.md +0 -88
- package/documentation/dev.md +0 -30
- package/documentation/discovery.md +0 -81
- package/documentation/flow.md +0 -44
- package/documentation/help.md +0 -122
- package/documentation/identity.md +0 -304
- package/documentation/introspection.md +0 -123
- package/documentation/io.md +0 -167
- package/documentation/ip.md +0 -24
- package/documentation/map.md +0 -123
- package/documentation/mcp.md +0 -183
- package/documentation/notes/desync.jpg +0 -0
- package/documentation/notes/peers.md +0 -59
- package/documentation/notes/sse.md +0 -71
- package/documentation/notes/throttling.md +0 -122
- package/documentation/oauth.md +0 -180
- package/documentation/octets.md +0 -334
- package/documentation/passkeys.md +0 -11
- package/documentation/protocol.md +0 -120
- package/documentation/query.md +0 -324
- package/documentation/require.md +0 -15
- package/documentation/rpc.md +0 -154
- package/documentation/tracing.md +0 -70
- package/documentation/tree.md +0 -199
- package/features/access.feature +0 -596
- package/features/annotation.feature +0 -32
- package/features/auth.assert.feature +0 -55
- package/features/auth.bearer.feature +0 -120
- package/features/auth.claims.feature +0 -171
- package/features/auth.incept.feature +0 -166
- package/features/auth.input.feature +0 -59
- package/features/authorities.basic.feature +0 -141
- package/features/authorities.feature +0 -71
- package/features/authorities.federation.feature +0 -100
- package/features/authorities.tokens.feature +0 -117
- package/features/body.feature +0 -76
- package/features/cache.feature +0 -368
- package/features/configuration.feature +0 -206
- package/features/cors.feature +0 -127
- package/features/credentials.feature +0 -106
- package/features/debug.feature +0 -34
- package/features/dev.feature +0 -90
- package/features/directives.feature +0 -61
- package/features/discovery.feature +0 -213
- package/features/discovery.ui.feature +0 -213
- package/features/dynamic.feature +0 -192
- package/features/errors.feature +0 -258
- package/features/etag.feature +0 -239
- package/features/flow.feature +0 -148
- package/features/help.feature +0 -512
- package/features/identity.bans.feature +0 -200
- package/features/identity.basic.feature +0 -666
- package/features/identity.feature +0 -240
- package/features/identity.federation.feature +0 -396
- package/features/identity.otp.feature +0 -142
- package/features/identity.roles.feature +0 -568
- package/features/identity.tokens.custom.feature +0 -430
- package/features/identity.tokens.feature +0 -131
- package/features/interruptions.feature +0 -20
- package/features/introspection.feature +0 -565
- package/features/introspection.map.feature +0 -108
- package/features/io.feature +0 -204
- package/features/io.throttle.feature +0 -166
- package/features/map.feature +0 -360
- package/features/mcp.feature +0 -753
- package/features/methods.feature +0 -48
- package/features/oauth.clients.feature +0 -195
- package/features/oauth.discovery.feature +0 -164
- package/features/oauth.grants.feature +0 -301
- package/features/octets.cloudinary.feature +0 -233
- package/features/octets.download.feature +0 -194
- package/features/octets.entries.feature +0 -83
- package/features/octets.feature +0 -306
- package/features/octets.head.feature +0 -40
- package/features/octets.location.feature +0 -83
- package/features/octets.meta.feature +0 -117
- package/features/octets.workflows.feature +0 -565
- package/features/passkeys.feature +0 -66
- package/features/probes.feature +0 -18
- package/features/query.feature +0 -389
- package/features/realtime.feature +0 -34
- package/features/require.feature +0 -66
- package/features/response.feature +0 -103
- package/features/routes.feature +0 -224
- package/features/rpc.feature +0 -429
- package/features/server.feature +0 -21
- package/features/site/_app/immutable/asset.js +0 -1
- package/features/site/favicon.ico +0 -0
- package/features/site/index.html +0 -10
- package/features/steps/.env.example +0 -5
- package/features/steps/Captures.ts +0 -20
- package/features/steps/Cloudinary.ts +0 -12
- package/features/steps/Common.ts +0 -38
- package/features/steps/Components.ts +0 -115
- package/features/steps/Database.ts +0 -106
- package/features/steps/Gateway.ts +0 -240
- package/features/steps/HTTP.ts +0 -96
- package/features/steps/IDP.ts +0 -361
- package/features/steps/Identity.ts +0 -54
- package/features/steps/OTP.ts +0 -42
- package/features/steps/Parameters.ts +0 -162
- package/features/steps/Probe.ts +0 -38
- package/features/steps/Realtime.ts +0 -175
- package/features/steps/Workspace.ts +0 -48
- package/features/steps/components/audit/manifest.toa.yaml +0 -20
- package/features/steps/components/audit/operations/record.js +0 -5
- package/features/steps/components/echo/manifest.toa.yaml +0 -59
- package/features/steps/components/echo/operations/affect.js +0 -3
- package/features/steps/components/echo/operations/compute.js +0 -3
- package/features/steps/components/echo/operations/echo.js +0 -3
- package/features/steps/components/echo/operations/error.js +0 -7
- package/features/steps/components/echo/operations/identity.js +0 -3
- package/features/steps/components/echo/operations/parameters.js +0 -3
- package/features/steps/components/echo/operations/ping.js +0 -3
- package/features/steps/components/echo/operations/unwrap.js +0 -3
- package/features/steps/components/echo.beacon/manifest.toa.yaml +0 -2
- package/features/steps/components/echo.beacon/operations/hello.js +0 -3
- package/features/steps/components/greeter/manifest.toa.yaml +0 -5
- package/features/steps/components/greeter/operations/greet.js +0 -3
- package/features/steps/components/notify/manifest.toa.yaml +0 -20
- package/features/steps/components/notify/operations/send.js +0 -5
- package/features/steps/components/octets.tester/manifest.toa.yaml +0 -73
- package/features/steps/components/octets.tester/operations/authority.js +0 -3
- package/features/steps/components/octets.tester/operations/bar.js +0 -9
- package/features/steps/components/octets.tester/operations/baz.js +0 -9
- package/features/steps/components/octets.tester/operations/concat.js +0 -5
- package/features/steps/components/octets.tester/operations/echo.js +0 -5
- package/features/steps/components/octets.tester/operations/err.js +0 -14
- package/features/steps/components/octets.tester/operations/foo.js +0 -5
- package/features/steps/components/octets.tester/operations/id.js +0 -5
- package/features/steps/components/octets.tester/operations/identity.js +0 -5
- package/features/steps/components/octets.tester/operations/lenna.png +0 -0
- package/features/steps/components/octets.tester/operations/redirect.js +0 -17
- package/features/steps/components/octets.tester/operations/yex.js +0 -14
- package/features/steps/components/octets.tester/operations/yield.js +0 -11
- package/features/steps/components/orders/manifest.toa.yaml +0 -30
- package/features/steps/components/orders/operations/create.js +0 -7
- package/features/steps/components/pots/manifest.toa.yaml +0 -91
- package/features/steps/components/pots/migrations/0002-indexes.yaml +0 -4
- package/features/steps/components/pricing/manifest.toa.yaml +0 -13
- package/features/steps/components/pricing/operations/quote.js +0 -3
- package/features/steps/components/sequences/manifest.toa.yaml +0 -11
- package/features/steps/components/sequences/operations/numbers.js +0 -5
- package/features/steps/components/sequences/operations/tokens.js +0 -14
- package/features/steps/components/users/manifest.toa.yaml +0 -30
- package/features/steps/components/users/operations/create.js +0 -11
- package/features/steps/components/users.properties/manifest.toa.yaml +0 -22
- package/features/steps/map.ts +0 -30
- package/features/steps/tsconfig.json +0 -9
- package/features/streams.feature +0 -35
- package/features/timestamps.feature +0 -41
- package/features/timing.feature +0 -49
- package/features/tracing.feature +0 -123
- package/schemas/annotation.cos.yaml +0 -125
- package/schemas/call.cos.yaml +0 -18
- package/schemas/directive.cos.yaml +0 -7
- package/schemas/method.cos.yaml +0 -23
- package/schemas/node.cos.yaml +0 -22
- package/schemas/query.cos.yaml +0 -31
- package/schemas/querystring.cos.yaml +0 -19
- package/schemas/range.cos.yaml +0 -10
- package/schemas/route.cos.yaml +0 -6
- package/source/Annotation.ts +0 -89
- package/source/Branch.test.ts +0 -40
- package/source/Branch.ts +0 -44
- package/source/Composition.ts +0 -51
- package/source/Context.ts +0 -11
- package/source/Directive.test.ts +0 -199
- package/source/Directive.ts +0 -248
- package/source/Discovery/Explorer.ts +0 -34
- package/source/Discovery/Site.test.ts +0 -147
- package/source/Discovery/Site.ts +0 -202
- package/source/Discovery/index.ts +0 -3
- package/source/Discovery/tree.test.ts +0 -175
- package/source/Discovery/tree.ts +0 -77
- package/source/Discovery/trunk.ts +0 -33
- package/source/Endpoint.test.ts +0 -67
- package/source/Endpoint.ts +0 -157
- package/source/Factory.ts +0 -42
- package/source/Gateway.ts +0 -390
- package/source/HTTP/Context.ts +0 -143
- package/source/HTTP/Probe.ts +0 -99
- package/source/HTTP/Server.ts +0 -430
- package/source/HTTP/Timing.ts +0 -14
- package/source/HTTP/address.test.ts +0 -28
- package/source/HTTP/address.ts +0 -16
- package/source/HTTP/exceptions.ts +0 -99
- package/source/HTTP/formats/form.ts +0 -21
- package/source/HTTP/formats/index.ts +0 -36
- package/source/HTTP/formats/json.ts +0 -14
- package/source/HTTP/formats/msgpack.ts +0 -14
- package/source/HTTP/formats/text.ts +0 -10
- package/source/HTTP/formats/yaml.test.ts +0 -22
- package/source/HTTP/formats/yaml.ts +0 -40
- package/source/HTTP/index.ts +0 -6
- package/source/HTTP/messages.test.ts +0 -196
- package/source/HTTP/messages.ts +0 -186
- package/source/HTTP/types.ts +0 -39
- package/source/Interception.ts +0 -37
- package/source/Introspection.ts +0 -179
- package/source/MCP/Server.ts +0 -335
- package/source/MCP/discover.ts +0 -51
- package/source/MCP/errors.ts +0 -80
- package/source/MCP/index.ts +0 -1
- package/source/MCP/schema.test.ts +0 -91
- package/source/MCP/schema.ts +0 -94
- package/source/MCP/tools.ts +0 -144
- package/source/MCP/types.ts +0 -84
- package/source/Mapping.ts +0 -101
- package/source/Query.test.ts +0 -54
- package/source/Query.ts +0 -277
- package/source/RPC/Context.ts +0 -75
- package/source/RPC/Dispatcher.ts +0 -150
- package/source/RPC/errors.test.ts +0 -77
- package/source/RPC/errors.ts +0 -82
- package/source/RPC/index.ts +0 -1
- package/source/RPC/names.test.ts +0 -141
- package/source/RPC/names.ts +0 -176
- package/source/RPC/types.ts +0 -34
- package/source/RTD/Context.ts +0 -16
- package/source/RTD/Directives.ts +0 -126
- package/source/RTD/Endpoint.ts +0 -27
- package/source/RTD/Match.ts +0 -11
- package/source/RTD/Method.ts +0 -39
- package/source/RTD/Node.ts +0 -169
- package/source/RTD/Route.ts +0 -93
- package/source/RTD/Tree.ts +0 -137
- package/source/RTD/expiration.test.ts +0 -81
- package/source/RTD/factory.ts +0 -105
- package/source/RTD/index.ts +0 -8
- package/source/RTD/segment.test.ts +0 -35
- package/source/RTD/segment.ts +0 -51
- package/source/RTD/syntax/index.ts +0 -2
- package/source/RTD/syntax/parse.test.ts +0 -196
- package/source/RTD/syntax/parse.ts +0 -171
- package/source/RTD/syntax/types.ts +0 -69
- package/source/RTD/walk.test.ts +0 -147
- package/source/Remotes.test.ts +0 -79
- package/source/Remotes.ts +0 -39
- package/source/Tenant.ts +0 -73
- package/source/const.ts +0 -45
- package/source/deployment.ts +0 -96
- package/source/directives/auth/Anonymous.test.ts +0 -70
- package/source/directives/auth/Anonymous.ts +0 -36
- package/source/directives/auth/Anyone.ts +0 -23
- package/source/directives/auth/Assert.ts +0 -43
- package/source/directives/auth/Authorization.test.ts +0 -24
- package/source/directives/auth/Authorization.ts +0 -388
- package/source/directives/auth/Delegate.test.ts +0 -36
- package/source/directives/auth/Delegate.ts +0 -54
- package/source/directives/auth/Echo.ts +0 -24
- package/source/directives/auth/Federation.ts +0 -104
- package/source/directives/auth/Id.ts +0 -37
- package/source/directives/auth/Incept.ts +0 -117
- package/source/directives/auth/Input.ts +0 -92
- package/source/directives/auth/Role.test.ts +0 -147
- package/source/directives/auth/Role.ts +0 -99
- package/source/directives/auth/Rule.ts +0 -59
- package/source/directives/auth/Scheme.ts +0 -31
- package/source/directives/auth/create.ts +0 -11
- package/source/directives/auth/index.ts +0 -3
- package/source/directives/auth/schemes.test.ts +0 -18
- package/source/directives/auth/schemes.ts +0 -39
- package/source/directives/auth/split.ts +0 -14
- package/source/directives/auth/types.ts +0 -75
- package/source/directives/cache/Cache.ts +0 -92
- package/source/directives/cache/Control.ts +0 -81
- package/source/directives/cache/Exact.ts +0 -7
- package/source/directives/cache/etag.ts +0 -38
- package/source/directives/cache/index.ts +0 -3
- package/source/directives/cache/types.ts +0 -9
- package/source/directives/cors/CORS.test.ts +0 -75
- package/source/directives/cors/CORS.ts +0 -88
- package/source/directives/cors/index.ts +0 -3
- package/source/directives/dev/Development.ts +0 -41
- package/source/directives/dev/Faulty.ts +0 -31
- package/source/directives/dev/Sleep.ts +0 -53
- package/source/directives/dev/Stub.ts +0 -14
- package/source/directives/dev/Throw.ts +0 -14
- package/source/directives/dev/index.ts +0 -3
- package/source/directives/dev/types.ts +0 -5
- package/source/directives/flow/Compose.ts +0 -98
- package/source/directives/flow/Fetch.ts +0 -86
- package/source/directives/flow/Flow.ts +0 -43
- package/source/directives/flow/index.ts +0 -3
- package/source/directives/flow/types.ts +0 -7
- package/source/directives/help/Family.ts +0 -122
- package/source/directives/help/Help.test.ts +0 -227
- package/source/directives/help/Help.ts +0 -47
- package/source/directives/help/Parameters.ts +0 -47
- package/source/directives/help/described.ts +0 -57
- package/source/directives/help/index.ts +0 -45
- package/source/directives/index.ts +0 -33
- package/source/directives/io/Directive.ts +0 -17
- package/source/directives/io/IO.ts +0 -118
- package/source/directives/io/Input.ts +0 -55
- package/source/directives/io/Message.ts +0 -1
- package/source/directives/io/Output.ts +0 -81
- package/source/directives/io/Status.test.ts +0 -88
- package/source/directives/io/Status.ts +0 -47
- package/source/directives/io/Throttle.ts +0 -30
- package/source/directives/io/index.ts +0 -3
- package/source/directives/io/lib/throttle/Configuration.test.ts +0 -72
- package/source/directives/io/lib/throttle/Configuration.ts +0 -68
- package/source/directives/io/lib/throttle/Keys.ts +0 -53
- package/source/directives/io/lib/throttle/Quotas.test.ts +0 -411
- package/source/directives/io/lib/throttle/Quotas.ts +0 -190
- package/source/directives/io/lib/throttle/Sync.test.ts +0 -163
- package/source/directives/io/lib/throttle/Sync.ts +0 -93
- package/source/directives/io/lib/throttle/Warning.test.ts +0 -32
- package/source/directives/io/lib/throttle/Warning.ts +0 -29
- package/source/directives/io/lib/throttle/components/Component.ts +0 -7
- package/source/directives/io/lib/throttle/components/IP.ts +0 -30
- package/source/directives/io/lib/throttle/components/Identity.ts +0 -19
- package/source/directives/io/lib/throttle/components/Path.ts +0 -8
- package/source/directives/io/lib/throttle/components/Route.ts +0 -19
- package/source/directives/io/lib/throttle/components/Segment.ts +0 -19
- package/source/directives/io/lib/throttle/components/index.ts +0 -19
- package/source/directives/io/lib/throttle/conditions/Condition.ts +0 -5
- package/source/directives/io/lib/throttle/conditions/Status.ts +0 -17
- package/source/directives/io/lib/throttle/conditions/index.ts +0 -11
- package/source/directives/io/lib/throttle/index.ts +0 -4
- package/source/directives/io/schemas.test.ts +0 -40
- package/source/directives/io/schemas.ts +0 -16
- package/source/directives/map/Authority.ts +0 -15
- package/source/directives/map/Buffer.ts +0 -15
- package/source/directives/map/Claims.ts +0 -63
- package/source/directives/map/Directive.ts +0 -4
- package/source/directives/map/Headers.ts +0 -60
- package/source/directives/map/Language.ts +0 -45
- package/source/directives/map/Languages.ts +0 -17
- package/source/directives/map/Map.ts +0 -85
- package/source/directives/map/Mapping.ts +0 -45
- package/source/directives/map/Properties.ts +0 -15
- package/source/directives/map/Segments.ts +0 -52
- package/source/directives/map/index.ts +0 -3
- package/source/directives/mcp/MCP.ts +0 -33
- package/source/directives/mcp/Tool.test.ts +0 -56
- package/source/directives/mcp/Tool.ts +0 -32
- package/source/directives/mcp/index.ts +0 -6
- package/source/directives/oauth/Discovery.ts +0 -66
- package/source/directives/oauth/documents.ts +0 -110
- package/source/directives/oauth/index.ts +0 -3
- package/source/directives/octets/Context.ts +0 -23
- package/source/directives/octets/Delete.ts +0 -96
- package/source/directives/octets/Directive.ts +0 -21
- package/source/directives/octets/Get.ts +0 -88
- package/source/directives/octets/Octets.ts +0 -82
- package/source/directives/octets/Put.ts +0 -186
- package/source/directives/octets/Workflow.ts +0 -60
- package/source/directives/octets/bytes.test.ts +0 -33
- package/source/directives/octets/bytes.ts +0 -18
- package/source/directives/octets/index.ts +0 -3
- package/source/directives/octets/schemas.test.ts +0 -20
- package/source/directives/octets/schemas.ts +0 -15
- package/source/directives/octets/types.ts +0 -9
- package/source/directives/octets/workflows/Execution.ts +0 -130
- package/source/directives/octets/workflows/Workflow.ts +0 -51
- package/source/directives/octets/workflows/index.ts +0 -1
- package/source/directives/require/Directive.ts +0 -5
- package/source/directives/require/Headers.ts +0 -19
- package/source/directives/require/Require.ts +0 -27
- package/source/directives/require/index.ts +0 -3
- package/source/discovery.ts +0 -1
- package/source/exceptions.ts +0 -47
- package/source/index.ts +0 -12
- package/source/io.ts +0 -4
- package/source/manifest.test.ts +0 -56
- package/source/manifest.ts +0 -56
- package/source/octets.d.ts +0 -17
- package/source/root.ts +0 -59
- package/source/schemas.test.ts +0 -31
- package/source/schemas.ts +0 -15
- package/source/service.ts +0 -94
- package/source/shortcuts.ts +0 -14
- package/source/userland.ts +0 -47
- package/transpiled/Annotation.d.ts +0 -70
- package/transpiled/Annotation.js +0 -2
- package/transpiled/Annotation.js.map +0 -1
- package/transpiled/RTD/syntax/parse.d.ts +0 -4
- package/transpiled/RTD/syntax/parse.js +0 -112
- package/transpiled/RTD/syntax/parse.js.map +0 -1
- package/transpiled/RTD/syntax/types.d.ts +0 -52
- package/transpiled/RTD/syntax/types.js +0 -11
- package/transpiled/RTD/syntax/types.js.map +0 -1
- package/transpiled/const.d.ts +0 -36
- package/transpiled/const.js +0 -37
- package/transpiled/const.js.map +0 -1
- package/transpiled/deployment.d.ts +0 -6
- package/transpiled/deployment.js +0 -76
- package/transpiled/deployment.js.map +0 -1
- package/transpiled/manifest.d.ts +0 -3
- package/transpiled/manifest.js +0 -39
- package/transpiled/manifest.js.map +0 -1
- package/transpiled/schemas.d.ts +0 -9
- package/transpiled/schemas.js +0 -9
- package/transpiled/schemas.js.map +0 -1
- package/transpiled/shortcuts.d.ts +0 -3
- package/transpiled/shortcuts.js +0 -13
- package/transpiled/shortcuts.js.map +0 -1
- package/tsconfig.json +0 -13
- package/tsconfig.tsbuildinfo +0 -1
- package/ui/dist/_app/immutable/assets/0.Bl7vLmIK.css +0 -2
- package/ui/dist/_app/immutable/assets/2.BC0-Jhqu.css +0 -1
- package/ui/dist/_app/immutable/chunks/B_pK3U1C.js +0 -6
- package/ui/dist/_app/immutable/chunks/CiKbPLyY.js +0 -1
- package/ui/dist/_app/immutable/chunks/DjIYL2zC.js +0 -3
- package/ui/dist/_app/immutable/entry/app.DMqmL4NY.js +0 -2
- package/ui/dist/_app/immutable/entry/start.CRe7HWBI.js +0 -1
- package/ui/dist/_app/immutable/nodes/0.D9m-6cbM.js +0 -1
- package/ui/dist/_app/immutable/nodes/1.Cgi_RcSO.js +0 -1
- package/ui/dist/_app/immutable/nodes/2.D_Cbxgz4.js +0 -14
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert'
|
|
2
|
-
import { console } from 'openspan'
|
|
3
|
-
import * as http from '../../HTTP/index.js'
|
|
4
|
-
import { split } from './split.js'
|
|
5
|
-
import { create } from './create.js'
|
|
6
|
-
import { INCEPTION, UNKNOWN, providers as providersOf } from './schemes.js'
|
|
7
|
-
import { Role } from './Role.js'
|
|
8
|
-
import type { Component } from '@toa.io/core'
|
|
9
|
-
import type { Maybe } from '@toa.io/core/types'
|
|
10
|
-
import type { Directive, Discovery, Identity, Context, Components, Ban } from './types.js'
|
|
11
|
-
|
|
12
|
-
export class Incept implements Directive {
|
|
13
|
-
private static readonly components: Components = {}
|
|
14
|
-
private static discovery: Discovery
|
|
15
|
-
private static bans: Component | null = null
|
|
16
|
-
|
|
17
|
-
private readonly property: string | null
|
|
18
|
-
|
|
19
|
-
public constructor(property: string, discovery: Discovery) {
|
|
20
|
-
assert.ok(
|
|
21
|
-
property === null || typeof property === 'string',
|
|
22
|
-
'`auth:incept` value must be a string or null'
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
this.property = property
|
|
26
|
-
Incept.discovery ??= discovery
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
public static async incept(context: Context, id: string): Promise<Identity> {
|
|
30
|
-
const [scheme, credentials] = split(context.request.headers.authorization!)
|
|
31
|
-
const candidates = providersOf(scheme)
|
|
32
|
-
|
|
33
|
-
if (candidates === undefined)
|
|
34
|
-
throw new http.BadRequest('Authentication scheme is not supported')
|
|
35
|
-
|
|
36
|
-
// a scheme several providers claim is incepted by the one that incepts; `Bearer`
|
|
37
|
-
// carries an access token this gateway issued, and an identity cannot be incepted
|
|
38
|
-
// from a credential it would itself have to exist to hold
|
|
39
|
-
const provider = candidates.find((candidate) => INCEPTION.includes(candidate))
|
|
40
|
-
|
|
41
|
-
if (provider === undefined) throw new http.Unauthorized()
|
|
42
|
-
|
|
43
|
-
Incept.bans ??= await Incept.discovery.bans
|
|
44
|
-
|
|
45
|
-
const ban = await Incept.bans.invoke<Ban>('observe', { query: { id } })
|
|
46
|
-
|
|
47
|
-
if (ban.banned) throw new http.Unauthorized()
|
|
48
|
-
|
|
49
|
-
Incept.components[provider] ??= await Incept.discovery[provider]
|
|
50
|
-
|
|
51
|
-
const identity = await Incept.components[provider]!.invoke<Maybe<Identity>>(
|
|
52
|
-
'incept',
|
|
53
|
-
{
|
|
54
|
-
input: {
|
|
55
|
-
scheme,
|
|
56
|
-
authority: context.authority,
|
|
57
|
-
id,
|
|
58
|
-
credentials
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
if (identity instanceof Error) throw new http.UnprocessableEntity(identity)
|
|
64
|
-
|
|
65
|
-
identity.scheme = scheme
|
|
66
|
-
|
|
67
|
-
// the roles are read where the token is minted: an Identity incepted as the principal
|
|
68
|
-
// has one already
|
|
69
|
-
return identity
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/** Credentials that were rejected for any reason but being unknown are not incepted. */
|
|
73
|
-
public static acceptable(context: Context): boolean {
|
|
74
|
-
return (
|
|
75
|
-
context.request.headers.authorization === undefined || context.rejection === UNKNOWN
|
|
76
|
-
)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
public authorize(identity: Identity | null, context: Context): boolean {
|
|
80
|
-
return identity === null && Incept.acceptable(context)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
public reply(context: Context): http.OutgoingMessage | null {
|
|
84
|
-
if (this.property !== null) return null
|
|
85
|
-
|
|
86
|
-
const body = create(context.request.headers.authorization)
|
|
87
|
-
|
|
88
|
-
return { body }
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
public async settle(context: Context, response: http.OutgoingMessage): Promise<void> {
|
|
92
|
-
const id = response.body?.[this.property ?? 'id']
|
|
93
|
-
|
|
94
|
-
if (id === undefined) {
|
|
95
|
-
console.debug('Inception skipped: response does not contain expected property', {
|
|
96
|
-
property: this.property,
|
|
97
|
-
response
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
return
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
assert(
|
|
104
|
-
typeof id === 'string',
|
|
105
|
-
`Response body property "${this.property}" expected to be a string`
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
if (context.request.headers.authorization !== undefined)
|
|
109
|
-
context.identity = await Incept.incept(context, id)
|
|
110
|
-
else {
|
|
111
|
-
const identity = { id, scheme: null, refresh: true }
|
|
112
|
-
const roles = await Role.get(identity, Incept.discovery.roles)
|
|
113
|
-
|
|
114
|
-
context.identity = { ...identity, roles }
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import { Forbidden } from '../../HTTP/index.js'
|
|
2
|
-
import type { Parameter } from '../../RTD/index.js'
|
|
3
|
-
import type { Context, Directive, Identity, Create } from './types.js'
|
|
4
|
-
|
|
5
|
-
export class Input implements Directive {
|
|
6
|
-
public priority = 0
|
|
7
|
-
private readonly statements: Statement[] = []
|
|
8
|
-
|
|
9
|
-
public constructor(declarations: Declaration[], create: Create) {
|
|
10
|
-
this.statements = declarations.map(
|
|
11
|
-
(declaration) => new Statement(declaration, create)
|
|
12
|
-
)
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/** It admits nobody: it says what a body may carry, not who may send one. */
|
|
16
|
-
public admits(): boolean {
|
|
17
|
-
return false
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
public async authorize(
|
|
21
|
-
identity: Identity | null,
|
|
22
|
-
context: Context,
|
|
23
|
-
parameters: Parameter[]
|
|
24
|
-
): Promise<boolean> {
|
|
25
|
-
context.pipelines.body.push(async (body) =>
|
|
26
|
-
this.check(identity, context, parameters, body)
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
return false
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// eslint-disable-next-line max-params
|
|
33
|
-
private async check(
|
|
34
|
-
identity: Identity | null,
|
|
35
|
-
context: Context,
|
|
36
|
-
parameters: Parameter[],
|
|
37
|
-
body: unknown
|
|
38
|
-
): Promise<unknown> {
|
|
39
|
-
if (body === undefined || body === null || body.constructor !== Object) return body
|
|
40
|
-
|
|
41
|
-
const settled = await Promise.allSettled(
|
|
42
|
-
this.statements.map(async (statement) =>
|
|
43
|
-
statement.check(identity, context, parameters, body as Body)
|
|
44
|
-
)
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
for (const result of settled) if (result.status === 'rejected') throw result.reason
|
|
48
|
-
|
|
49
|
-
return body
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
class Statement {
|
|
54
|
-
private readonly properties: string[]
|
|
55
|
-
private readonly directives: Directive[] = []
|
|
56
|
-
|
|
57
|
-
public constructor({ prop, ...directives }: Declaration, create: Create) {
|
|
58
|
-
this.properties = typeof prop === 'string' ? [prop] : prop
|
|
59
|
-
|
|
60
|
-
for (const [name, value] of Object.entries(directives)) {
|
|
61
|
-
const directive = create(name, value)
|
|
62
|
-
|
|
63
|
-
this.directives.push(directive)
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// eslint-disable-next-line max-params
|
|
68
|
-
public async check(
|
|
69
|
-
identity: Identity | null,
|
|
70
|
-
context: Context,
|
|
71
|
-
parameters: Parameter[],
|
|
72
|
-
body: Body
|
|
73
|
-
): Promise<void> {
|
|
74
|
-
const match = this.properties.some((property) => property in body)
|
|
75
|
-
|
|
76
|
-
if (!match) return
|
|
77
|
-
|
|
78
|
-
for (const directive of this.directives) {
|
|
79
|
-
const authorized = await directive.authorize(identity, context, parameters)
|
|
80
|
-
|
|
81
|
-
if (!authorized) throw new Forbidden('Input property is not authorized')
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export interface Declaration {
|
|
87
|
-
[key: Exclude<string, 'prop'>]: unknown
|
|
88
|
-
|
|
89
|
-
prop: string | string[]
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
type Body = Record<string, unknown>
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import { it, beforeEach, mock } from 'node:test'
|
|
2
|
-
import assert from 'node:assert/strict'
|
|
3
|
-
import { isDeepStrictEqual } from 'node:util'
|
|
4
|
-
|
|
5
|
-
import { type Component } from '@toa.io/core'
|
|
6
|
-
import { generate } from 'randomstring'
|
|
7
|
-
import { Role } from './Role.js'
|
|
8
|
-
import { type Identity } from './types.js'
|
|
9
|
-
import type { Parameter } from '../../RTD/index.js'
|
|
10
|
-
|
|
11
|
-
const remote = {
|
|
12
|
-
invoke: mock.fn()
|
|
13
|
-
} as unknown as Component
|
|
14
|
-
|
|
15
|
-
const discovery = Promise.resolve(remote)
|
|
16
|
-
|
|
17
|
-
beforeEach(() => {
|
|
18
|
-
resetCalls()
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
it('should return false if not matched', async () => {
|
|
22
|
-
const roles = ['admin', 'user']
|
|
23
|
-
const directive = new Role(roles, discovery)
|
|
24
|
-
|
|
25
|
-
const identity: Identity = {
|
|
26
|
-
id: generate(),
|
|
27
|
-
scheme: '',
|
|
28
|
-
refresh: false
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
remote.invoke.mock.mockImplementationOnce(async () => ['guest'])
|
|
32
|
-
|
|
33
|
-
const result = await directive.authorize(identity, undefined, [])
|
|
34
|
-
|
|
35
|
-
assert.strictEqual(result, false)
|
|
36
|
-
|
|
37
|
-
assert.ok(
|
|
38
|
-
remote.invoke.mock.calls.some(
|
|
39
|
-
(call: any) =>
|
|
40
|
-
call.arguments.length === 2 &&
|
|
41
|
-
isDeepStrictEqual(call.arguments[0], 'list') &&
|
|
42
|
-
isDeepStrictEqual(call.arguments[1], {
|
|
43
|
-
query: {
|
|
44
|
-
criteria: `identity=="${identity.id}"`,
|
|
45
|
-
limit: 1024
|
|
46
|
-
}
|
|
47
|
-
})
|
|
48
|
-
)
|
|
49
|
-
)
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
it('should return true on exact match', async () => {
|
|
53
|
-
const result = await match(['admin', 'user'], ['user'])
|
|
54
|
-
|
|
55
|
-
assert.strictEqual(result, true)
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
it('should return true on scope match', async () => {
|
|
59
|
-
const result = await match(['system:identity:roles'], ['system'])
|
|
60
|
-
|
|
61
|
-
assert.strictEqual(result, true)
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
it('should return false on scope mismatch', async () => {
|
|
65
|
-
const result = await match(['system:identity'], ['system:identity:roles'])
|
|
66
|
-
|
|
67
|
-
assert.strictEqual(result, false)
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
it('should return false on non-scope substring match', async () => {
|
|
71
|
-
const result = await match(['system:identity'], ['system:iden'])
|
|
72
|
-
|
|
73
|
-
assert.strictEqual(result, false)
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
it('should return true on match with parameters', async () => {
|
|
77
|
-
const result = await match(
|
|
78
|
-
['app:{org}:reviews'],
|
|
79
|
-
['app:29e54ae1:reviews'],
|
|
80
|
-
[
|
|
81
|
-
{
|
|
82
|
-
name: 'org',
|
|
83
|
-
value: '29e54ae1'
|
|
84
|
-
}
|
|
85
|
-
]
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
assert.strictEqual(result, true)
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
it('should return true on match with parameters', async () => {
|
|
92
|
-
const result = await match(
|
|
93
|
-
['app:{org}:reviews'],
|
|
94
|
-
['app:29e54ae1:reviews'],
|
|
95
|
-
[
|
|
96
|
-
{
|
|
97
|
-
name: 'org',
|
|
98
|
-
value: '29e54ae1'
|
|
99
|
-
}
|
|
100
|
-
]
|
|
101
|
-
)
|
|
102
|
-
|
|
103
|
-
assert.strictEqual(result, true)
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
it('should return false on mismatch with parameters', async () => {
|
|
107
|
-
const result = await match(
|
|
108
|
-
['app:{org}:reviews'],
|
|
109
|
-
['app:29e54ae1:reviews'],
|
|
110
|
-
[
|
|
111
|
-
{
|
|
112
|
-
name: 'org',
|
|
113
|
-
value: '88584c9b'
|
|
114
|
-
}
|
|
115
|
-
]
|
|
116
|
-
)
|
|
117
|
-
|
|
118
|
-
assert.strictEqual(result, false)
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
async function match(
|
|
122
|
-
expected: string[],
|
|
123
|
-
actual: string[],
|
|
124
|
-
parameters: Parameter[] = []
|
|
125
|
-
): Promise<boolean> {
|
|
126
|
-
const directive = new Role(expected, discovery)
|
|
127
|
-
|
|
128
|
-
const identity: Identity = {
|
|
129
|
-
id: generate(),
|
|
130
|
-
scheme: '',
|
|
131
|
-
refresh: false
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
remote.invoke.mock.mockImplementationOnce(async () => actual)
|
|
135
|
-
|
|
136
|
-
return await directive.authorize(identity, undefined, parameters)
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function resetCalls(target = [remote, discovery], seen = new Set()) {
|
|
140
|
-
if (target === null || typeof target !== 'object' || seen.has(target)) return
|
|
141
|
-
|
|
142
|
-
seen.add(target)
|
|
143
|
-
|
|
144
|
-
for (const value of Object.values(target))
|
|
145
|
-
if (typeof value === 'function' && value.mock !== undefined) value.mock.resetCalls()
|
|
146
|
-
else resetCalls(value, seen)
|
|
147
|
-
}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert'
|
|
2
|
-
import { quote } from '@toa.io/generic'
|
|
3
|
-
import { type Component } from '@toa.io/core'
|
|
4
|
-
import type { Query } from '@toa.io/core/types'
|
|
5
|
-
import { type Directive, type Identity } from './types.js'
|
|
6
|
-
import type { Parameter } from '../../RTD/index.js'
|
|
7
|
-
import type { Introspection } from '../../Introspection.js'
|
|
8
|
-
|
|
9
|
-
export class Role implements Directive {
|
|
10
|
-
public static remote: Component | null = null
|
|
11
|
-
private readonly roles: string[]
|
|
12
|
-
private readonly discovery: Promise<Component>
|
|
13
|
-
private readonly dynamic: boolean
|
|
14
|
-
|
|
15
|
-
public constructor(roles: string | string[], discovery: Promise<Component>) {
|
|
16
|
-
this.roles = typeof roles === 'string' ? [roles] : roles
|
|
17
|
-
this.discovery = discovery
|
|
18
|
-
this.dynamic = this.roles.some((role) => role.includes('{'))
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
public static async get(
|
|
22
|
-
identity: Identity,
|
|
23
|
-
discovery: Promise<Component>
|
|
24
|
-
): Promise<string[]> {
|
|
25
|
-
this.remote ??= await discovery
|
|
26
|
-
|
|
27
|
-
const query: Query = {
|
|
28
|
-
criteria: `identity==${quote(identity.id)}`,
|
|
29
|
-
limit: 1024
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return await this.remote.invoke('list', { query })
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Reaching it takes a role, which is what `protected` says. A role of the `system` scope
|
|
37
|
-
* says so besides: what it guards is the machinery an application runs on rather than
|
|
38
|
-
* anything it serves, and a reader has no business being offered it as one.
|
|
39
|
-
*/
|
|
40
|
-
public describe(introspection: Introspection): Introspection {
|
|
41
|
-
const system = this.roles.some(
|
|
42
|
-
(role) => role === SYSTEM || role.startsWith(SYSTEM + ':')
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
return { ...introspection, protected: true, ...(system ? { system: true } : {}) }
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
public async authorize(
|
|
49
|
-
identity: Identity | null,
|
|
50
|
-
_: unknown,
|
|
51
|
-
parameters: Parameter[]
|
|
52
|
-
): Promise<boolean> {
|
|
53
|
-
if (identity === null) return false
|
|
54
|
-
|
|
55
|
-
identity.roles ??= await Role.get(identity, this.discovery)
|
|
56
|
-
|
|
57
|
-
return this.match(identity.roles, parameters)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/** A role naming a route variable cannot be told from a description, which has no values. */
|
|
61
|
-
public async admits(identity: Identity | null): Promise<boolean | undefined> {
|
|
62
|
-
if (this.dynamic) return undefined
|
|
63
|
-
|
|
64
|
-
if (identity === null) return false
|
|
65
|
-
|
|
66
|
-
identity.roles ??= await Role.get(identity, this.discovery)
|
|
67
|
-
|
|
68
|
-
return this.match(identity.roles, [])
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
private match(roles: string[], parameters: Parameter[]): boolean {
|
|
72
|
-
const required = this.dynamic ? this.substitute(parameters) : this.roles
|
|
73
|
-
|
|
74
|
-
for (const role of roles) {
|
|
75
|
-
const ok = required.some(
|
|
76
|
-
(expected) => expected === role || expected.startsWith(role + ':')
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
if (ok) return true
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return false
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
private substitute(parameters: Parameter[]): string[] {
|
|
86
|
-
return this.roles.map((role) =>
|
|
87
|
-
role.replaceAll(/{(\w+)}/g, (_, key) => {
|
|
88
|
-
const value = parameters.find((parameter) => parameter.name === key)?.value
|
|
89
|
-
|
|
90
|
-
assert.ok(value !== undefined, `Role '${role}' requires '${key}' route parameter`)
|
|
91
|
-
|
|
92
|
-
return value
|
|
93
|
-
})
|
|
94
|
-
)
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/** The scope of what an application runs on, as opposed to what it serves. */
|
|
99
|
-
const SYSTEM = 'system'
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { type Parameter } from '../../RTD/index.js'
|
|
2
|
-
import type { Introspection } from '../../Introspection.js'
|
|
3
|
-
import type { Context, Directive, Identity, Create } from './types.js'
|
|
4
|
-
|
|
5
|
-
export class Rule implements Directive {
|
|
6
|
-
private readonly directives: Directive[] = []
|
|
7
|
-
|
|
8
|
-
public constructor(directives: Record<string, any>, create: Create) {
|
|
9
|
-
for (const [name, value] of Object.entries(directives)) {
|
|
10
|
-
const directive = create(name, value)
|
|
11
|
-
|
|
12
|
-
this.directives.push(directive)
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
public async authorize(
|
|
17
|
-
identity: Identity | null,
|
|
18
|
-
context: Context,
|
|
19
|
-
parameters: Parameter[]
|
|
20
|
-
): Promise<boolean> {
|
|
21
|
-
for (const directive of this.directives) {
|
|
22
|
-
const authorized = await directive.authorize(identity, context, parameters)
|
|
23
|
-
|
|
24
|
-
if (!authorized) return false
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return true
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/** Whatever each of them makes of it, in the order they were declared. */
|
|
31
|
-
public describe(introspection: Introspection): Introspection {
|
|
32
|
-
for (const directive of this.directives)
|
|
33
|
-
introspection = directive.describe?.(introspection) ?? introspection
|
|
34
|
-
|
|
35
|
-
return introspection
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** All of them, so one that refuses ends it and one that cannot tell leaves it untold. */
|
|
39
|
-
public async admits(
|
|
40
|
-
identity: Identity | null,
|
|
41
|
-
context: Context
|
|
42
|
-
): Promise<boolean | undefined> {
|
|
43
|
-
let untold = false
|
|
44
|
-
|
|
45
|
-
for (const directive of this.directives) {
|
|
46
|
-
const admits = await directive.admits?.(identity, context)
|
|
47
|
-
|
|
48
|
-
if (admits === undefined) {
|
|
49
|
-
untold = true
|
|
50
|
-
|
|
51
|
-
continue
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (!admits) return false
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return untold ? undefined : true
|
|
58
|
-
}
|
|
59
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import * as http from '../../HTTP/index.js'
|
|
2
|
-
import { type Directive, type Identity, type Context } from './types.js'
|
|
3
|
-
import { split } from './split.js'
|
|
4
|
-
|
|
5
|
-
export class Scheme implements Directive {
|
|
6
|
-
private readonly scheme: string
|
|
7
|
-
private readonly Scheme: string
|
|
8
|
-
|
|
9
|
-
public constructor(scheme: string) {
|
|
10
|
-
this.scheme = scheme.toLowerCase()
|
|
11
|
-
this.Scheme = scheme[0].toUpperCase() + scheme.substring(1)
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
public authorize(_: Identity | null, context: Context): boolean {
|
|
15
|
-
if (context.request.headers.authorization === undefined) return false
|
|
16
|
-
|
|
17
|
-
const [scheme] = split(context.request.headers.authorization)
|
|
18
|
-
|
|
19
|
-
if (scheme !== this.scheme)
|
|
20
|
-
throw new http.Forbidden(
|
|
21
|
-
this.Scheme + ' authentication scheme is required to access this resource'
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
return false
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/** It admits nobody: it is there to refuse a scheme, not to authorize one. */
|
|
28
|
-
public admits(): boolean {
|
|
29
|
-
return false
|
|
30
|
-
}
|
|
31
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { it } from 'node:test'
|
|
2
|
-
import assert from 'node:assert/strict'
|
|
3
|
-
|
|
4
|
-
import { providers } from './schemes.js'
|
|
5
|
-
|
|
6
|
-
it('should resolve a known scheme', () => {
|
|
7
|
-
assert.deepEqual(providers('basic'), ['basic'])
|
|
8
|
-
assert.deepEqual(providers('code'), ['federation'])
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
it('should resolve every provider claiming a scheme, in order', () => {
|
|
12
|
-
assert.deepEqual(providers('bearer'), ['tokens', 'federation'])
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
it('should not resolve a property of Object.prototype', () => {
|
|
16
|
-
for (const name of ['constructor', '__proto__', 'toString', 'hasOwnProperty'])
|
|
17
|
-
assert.equal(providers(name), undefined)
|
|
18
|
-
})
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type { Remote, Scheme } from './types.js'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* The providers of a scheme, in the order they are asked. More than one claims `Bearer`:
|
|
5
|
-
* an OpenID `id_token` is federated, and a token this gateway issued is presented that way
|
|
6
|
-
* by an OAuth client. Which of them a credential belongs to is each provider's own to say,
|
|
7
|
-
* so the order here is only which is asked first.
|
|
8
|
-
*/
|
|
9
|
-
export const PROVIDERS: Record<Scheme, Remote[]> = {
|
|
10
|
-
basic: ['basic'],
|
|
11
|
-
token: ['tokens'],
|
|
12
|
-
bearer: ['tokens', 'federation'],
|
|
13
|
-
code: ['federation'],
|
|
14
|
-
otp: ['otp']
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export const INCEPTION: Remote[] = ['basic', 'federation']
|
|
18
|
-
export const PRIMARY: Remote = 'tokens'
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* The providers of a scheme, or nothing for a scheme that is not one — including a name a
|
|
22
|
-
* plain object answers on its own, like `constructor`.
|
|
23
|
-
*/
|
|
24
|
-
export function providers(scheme: string): Remote[] | undefined {
|
|
25
|
-
return Object.hasOwn(PROVIDERS, scheme) ? PROVIDERS[scheme as Scheme] : undefined
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* What a provider answers when the credentials are not of its kind. The next provider of
|
|
30
|
-
* the scheme is asked; a provider that declines has done nothing, so asking is free of
|
|
31
|
-
* effect — which asking one that rejects would not be.
|
|
32
|
-
*/
|
|
33
|
-
export const UNRECOGNIZED = 'UNRECOGNIZED'
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* The rejection of credentials that are verifiable and owned by no identity: the one
|
|
37
|
-
* inception goes ahead with.
|
|
38
|
-
*/
|
|
39
|
-
export const UNKNOWN = 'NOT_FOUND'
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import * as http from '../../HTTP/index.js'
|
|
2
|
-
import { type Scheme } from './types.js'
|
|
3
|
-
|
|
4
|
-
export function split(authorization: string): [Scheme, string] {
|
|
5
|
-
const space = authorization.indexOf(' ')
|
|
6
|
-
|
|
7
|
-
if (space === -1) throw new http.Unauthorized('Malformed authorization header')
|
|
8
|
-
|
|
9
|
-
const Scheme = authorization.slice(0, space)
|
|
10
|
-
const scheme = Scheme.toLowerCase() as Scheme
|
|
11
|
-
const value = authorization.slice(space + 1)
|
|
12
|
-
|
|
13
|
-
return [scheme, value]
|
|
14
|
-
}
|