@toa.io/extensions.exposition 1.0.0-alpha.2 → 1.0.0-alpha.21
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.bans/manifest.toa.yaml +15 -6
- package/components/identity.bans/operations/transit.d.ts +14 -0
- package/components/identity.bans/operations/transit.js +11 -0
- package/components/identity.bans/operations/transit.js.map +1 -0
- package/components/identity.bans/operations/tsconfig.tsbuildinfo +1 -0
- package/components/identity.bans/source/transit.ts +21 -0
- package/components/identity.bans/tsconfig.json +9 -0
- package/components/identity.basic/manifest.toa.yaml +5 -1
- package/components/identity.basic/operations/tsconfig.tsbuildinfo +1 -1
- package/components/identity.federation/manifest.toa.yaml +13 -7
- package/components/identity.federation/operations/authenticate.js +4 -4
- package/components/identity.federation/operations/authenticate.js.map +1 -1
- package/components/identity.federation/operations/create.js +4 -4
- package/components/identity.federation/operations/create.js.map +1 -1
- package/components/identity.federation/operations/{assertions-as-values.cjs → lib/assertions-as-values.js} +1 -1
- package/components/identity.federation/operations/lib/assertions-as-values.js.map +1 -0
- package/components/identity.federation/operations/{jwt.d.cts → lib/jwt.d.ts} +5 -4
- package/components/identity.federation/operations/{jwt.cjs → lib/jwt.js} +35 -11
- package/components/identity.federation/operations/lib/jwt.js.map +1 -0
- package/components/identity.federation/operations/schemas.d.ts +16 -0
- package/components/identity.federation/operations/tsconfig.tsbuildinfo +1 -1
- package/components/identity.federation/operations/types.d.ts +1 -1
- package/components/identity.federation/source/authenticate.ts +2 -2
- package/components/identity.federation/source/create.ts +2 -2
- package/components/identity.federation/source/{assertions-as-values.cts → lib/assertions-as-values.ts} +1 -2
- package/components/identity.federation/source/lib/jwt.test.ts +56 -0
- package/components/identity.federation/source/{jwt.cts → lib/jwt.ts} +57 -29
- package/components/identity.federation/source/schemas.ts +16 -0
- package/components/identity.federation/source/types.ts +1 -1
- package/components/identity.federation/tsconfig.json +2 -2
- package/components/identity.roles/manifest.toa.yaml +18 -5
- package/components/identity.roles/operations/grant.d.ts +10 -0
- package/components/identity.roles/operations/grant.js +21 -0
- package/components/identity.roles/operations/grant.js.map +1 -0
- package/components/identity.roles/operations/lib/Entity.d.ts +5 -0
- package/components/identity.roles/operations/lib/Entity.js +3 -0
- package/components/identity.roles/operations/lib/Entity.js.map +1 -0
- package/components/identity.roles/operations/list.d.ts +1 -4
- package/components/identity.roles/operations/list.js.map +1 -1
- package/components/identity.roles/operations/principal.d.ts +4 -6
- package/components/identity.roles/operations/principal.js +6 -1
- package/components/identity.roles/operations/principal.js.map +1 -1
- package/components/identity.roles/operations/tsconfig.tsbuildinfo +1 -1
- package/components/identity.roles/source/grant.ts +32 -0
- package/components/identity.roles/source/lib/Entity.ts +5 -0
- package/components/identity.roles/source/list.ts +2 -4
- package/components/identity.roles/source/principal.ts +10 -8
- package/components/identity.tokens/manifest.toa.yaml +12 -3
- package/components/identity.tokens/operations/authenticate.js +5 -2
- package/components/identity.tokens/operations/authenticate.js.map +1 -1
- package/components/identity.tokens/operations/encrypt.js +4 -1
- package/components/identity.tokens/operations/encrypt.js.map +1 -1
- package/components/identity.tokens/operations/tsconfig.tsbuildinfo +1 -1
- package/components/identity.tokens/operations/types.d.ts +1 -2
- package/components/identity.tokens/receivers/identity.bans.created.js +3 -0
- package/components/identity.tokens/source/authenticate.ts +5 -2
- package/components/identity.tokens/source/encrypt.test.ts +22 -1
- package/components/identity.tokens/source/encrypt.ts +4 -1
- package/components/identity.tokens/source/types.ts +1 -2
- package/components/octets.storage/operations/store.js +1 -1
- package/documentation/access.md +27 -16
- package/documentation/cache.md +8 -1
- package/documentation/components.md +55 -23
- package/documentation/identity.md +7 -0
- package/documentation/io.md +56 -0
- package/documentation/octets.md +12 -0
- package/documentation/protocol.md +3 -0
- package/documentation/query.md +50 -5
- package/documentation/require.md +15 -0
- package/documentation/tree.md +22 -4
- package/documentation/vary.md +9 -3
- package/features/access.feature +28 -49
- package/features/annotation.feature +1 -0
- package/features/body.feature +3 -1
- package/features/cache.feature +39 -0
- package/features/cors.feature +2 -2
- package/features/directives.feature +2 -0
- package/features/dynamic.feature +14 -7
- package/features/errors.feature +7 -4
- package/features/etag.feature +97 -0
- package/features/identity.bans.feature +128 -0
- package/features/identity.basic.feature +68 -3
- package/features/identity.federation.feature +78 -5
- package/features/identity.roles.feature +205 -1
- package/features/identity.tokens.feature +98 -0
- package/features/io.feature +196 -0
- package/features/octets.entries.feature +3 -1
- package/features/octets.feature +32 -10
- package/features/octets.meta.feature +4 -3
- package/features/octets.workflows.feature +39 -0
- package/features/queries.feature +9 -1
- package/features/require.feature +64 -0
- package/features/response.feature +7 -1
- package/features/routes.feature +17 -10
- package/features/steps/Database.ts +17 -10
- package/features/steps/Gateway.ts +3 -0
- package/features/steps/IdP.ts +55 -21
- package/features/steps/components/echo/manifest.toa.yaml +5 -0
- package/features/steps/components/echo/operations/identity.js +7 -0
- package/features/steps/components/greeter/manifest.toa.yaml +1 -0
- package/features/steps/components/octets.tester/manifest.toa.yaml +1 -0
- package/features/steps/components/pots/manifest.toa.yaml +12 -3
- package/features/steps/components/sequences/manifest.toa.yaml +1 -0
- package/features/steps/components/users.properties/manifest.toa.yaml +2 -1
- package/features/timing.feature +66 -0
- package/features/vary.feature +56 -3
- package/package.json +13 -14
- package/readme.md +7 -6
- package/schemas/annotation.cos.yaml +1 -0
- package/schemas/io/input.cos.yaml +3 -0
- package/schemas/io/message.cos.yaml +5 -0
- package/schemas/io/output.cos.yaml +5 -0
- package/schemas/octets/workflow.cos.yaml +12 -0
- package/schemas/querystring.cos.yaml +1 -0
- package/source/Annotation.ts +1 -0
- package/source/Context.ts +6 -4
- package/source/Directive.test.ts +7 -7
- package/source/Directive.ts +19 -46
- package/source/Endpoint.ts +53 -6
- package/source/Factory.ts +17 -7
- package/source/Gateway.ts +40 -51
- package/source/HTTP/Context.ts +67 -0
- package/source/HTTP/Server.test.ts +1 -1
- package/source/HTTP/Server.ts +61 -96
- package/source/HTTP/Timing.ts +40 -0
- package/source/HTTP/exceptions.ts +1 -1
- package/source/HTTP/index.ts +1 -0
- package/source/HTTP/messages.test.ts +27 -8
- package/source/HTTP/messages.ts +32 -48
- package/source/Mapping.ts +7 -8
- package/source/RTD/Context.ts +7 -10
- package/source/RTD/Directives.ts +28 -4
- package/source/RTD/Endpoint.ts +6 -4
- package/source/RTD/Match.ts +2 -7
- package/source/RTD/Method.ts +7 -13
- package/source/RTD/Node.ts +13 -14
- package/source/RTD/Tree.ts +17 -16
- package/source/RTD/factory.ts +3 -6
- package/source/Tenant.ts +0 -8
- package/source/deployment.ts +6 -0
- package/source/directives/auth/Anonymous.ts +3 -2
- package/source/directives/auth/Authorization.ts +17 -14
- package/source/directives/auth/Delegate.ts +35 -0
- package/source/directives/auth/Incept.ts +11 -6
- package/source/directives/auth/Role.test.ts +53 -6
- package/source/directives/auth/Role.ts +27 -17
- package/source/directives/auth/Scheme.ts +2 -2
- package/source/directives/auth/types.ts +1 -1
- package/source/directives/cache/Cache.ts +5 -5
- package/source/directives/cache/Control.ts +48 -22
- package/source/directives/cache/types.ts +1 -1
- package/source/directives/cors/CORS.ts +18 -10
- package/source/directives/dev/Development.ts +4 -4
- package/source/directives/index.ts +6 -4
- package/source/directives/io/Directive.ts +11 -0
- package/source/directives/io/IO.ts +43 -0
- package/source/directives/io/Input.ts +50 -0
- package/source/directives/io/Message.ts +1 -0
- package/source/directives/io/Output.ts +69 -0
- package/source/directives/io/index.ts +3 -0
- package/source/directives/io/schemas.ts +12 -0
- package/source/directives/octets/Context.ts +5 -4
- package/source/directives/octets/Delete.ts +25 -13
- package/source/directives/octets/Directive.ts +10 -0
- package/source/directives/octets/Fetch.ts +33 -17
- package/source/directives/octets/List.ts +18 -8
- package/source/directives/octets/Octets.ts +12 -8
- package/source/directives/octets/Permute.ts +16 -9
- package/source/directives/octets/Store.ts +43 -19
- package/source/directives/octets/Workflow.ts +48 -0
- package/source/directives/octets/schemas.test.ts +21 -0
- package/source/directives/octets/schemas.ts +2 -0
- package/source/directives/octets/types.ts +0 -7
- package/source/directives/octets/{workflow → workflows}/Execution.ts +0 -2
- package/source/directives/octets/{workflow → workflows}/Workflow.ts +2 -2
- package/source/directives/require/Directive.ts +5 -0
- package/source/directives/require/Headers.ts +20 -0
- package/source/directives/require/Require.ts +28 -0
- package/source/directives/require/index.ts +3 -0
- package/source/directives/vary/Directive.ts +2 -1
- package/source/directives/vary/Embed.ts +14 -8
- package/source/directives/vary/Vary.ts +8 -6
- package/source/directives/vary/embeddings/Embedding.ts +2 -1
- package/source/directives/vary/embeddings/Header.ts +9 -7
- package/source/directives/vary/embeddings/Language.ts +2 -2
- package/source/directives/vary/embeddings/Parameter.ts +14 -0
- package/source/directives/vary/embeddings/index.ts +3 -3
- package/source/exceptions.ts +22 -11
- package/source/io.ts +2 -2
- package/source/root.ts +5 -0
- package/transpiled/Annotation.d.ts +1 -0
- package/transpiled/Context.d.ts +6 -4
- package/transpiled/Directive.d.ts +8 -21
- package/transpiled/Directive.js +11 -14
- package/transpiled/Directive.js.map +1 -1
- package/transpiled/Endpoint.d.ts +7 -5
- package/transpiled/Endpoint.js +58 -2
- package/transpiled/Endpoint.js.map +1 -1
- package/transpiled/Factory.js +8 -2
- package/transpiled/Factory.js.map +1 -1
- package/transpiled/Gateway.d.ts +4 -8
- package/transpiled/Gateway.js +23 -33
- package/transpiled/Gateway.js.map +1 -1
- package/transpiled/HTTP/Context.d.ts +24 -0
- package/transpiled/HTTP/Context.js +47 -0
- package/transpiled/HTTP/Context.js.map +1 -0
- package/transpiled/HTTP/Server.d.ts +8 -7
- package/transpiled/HTTP/Server.js +69 -77
- package/transpiled/HTTP/Server.js.map +1 -1
- package/transpiled/HTTP/Timing.d.ts +10 -0
- package/transpiled/HTTP/Timing.js +29 -0
- package/transpiled/HTTP/Timing.js.map +1 -0
- package/transpiled/HTTP/exceptions.d.ts +1 -1
- package/transpiled/HTTP/exceptions.js.map +1 -1
- package/transpiled/HTTP/index.d.ts +1 -0
- package/transpiled/HTTP/index.js +1 -0
- package/transpiled/HTTP/index.js.map +1 -1
- package/transpiled/HTTP/messages.d.ts +7 -21
- package/transpiled/HTTP/messages.js +24 -26
- package/transpiled/HTTP/messages.js.map +1 -1
- package/transpiled/Mapping.js +7 -7
- package/transpiled/Mapping.js.map +1 -1
- package/transpiled/RTD/Context.d.ts +7 -6
- package/transpiled/RTD/Directives.d.ts +19 -4
- package/transpiled/RTD/Endpoint.d.ts +6 -4
- package/transpiled/RTD/Match.d.ts +2 -4
- package/transpiled/RTD/Method.d.ts +7 -7
- package/transpiled/RTD/Method.js.map +1 -1
- package/transpiled/RTD/Node.d.ts +4 -6
- package/transpiled/RTD/Node.js +2 -1
- package/transpiled/RTD/Node.js.map +1 -1
- package/transpiled/RTD/Tree.d.ts +6 -6
- package/transpiled/RTD/Tree.js +4 -1
- package/transpiled/RTD/Tree.js.map +1 -1
- package/transpiled/RTD/factory.d.ts +2 -4
- package/transpiled/RTD/factory.js +1 -1
- package/transpiled/RTD/factory.js.map +1 -1
- package/transpiled/Tenant.d.ts +0 -1
- package/transpiled/Tenant.js +0 -6
- package/transpiled/Tenant.js.map +1 -1
- package/transpiled/deployment.js +5 -0
- package/transpiled/deployment.js.map +1 -1
- package/transpiled/directives/auth/Anonymous.js +3 -4
- package/transpiled/directives/auth/Anonymous.js.map +1 -1
- package/transpiled/directives/auth/Authorization.d.ts +2 -3
- package/transpiled/directives/auth/Authorization.js +10 -8
- package/transpiled/directives/auth/Authorization.js.map +1 -1
- package/transpiled/directives/auth/Delegate.d.ts +8 -0
- package/transpiled/directives/auth/Delegate.js +29 -0
- package/transpiled/directives/auth/Delegate.js.map +1 -0
- package/transpiled/directives/auth/Incept.d.ts +1 -1
- package/transpiled/directives/auth/Incept.js +11 -6
- package/transpiled/directives/auth/Incept.js.map +1 -1
- package/transpiled/directives/auth/Role.d.ts +4 -1
- package/transpiled/directives/auth/Role.js +25 -17
- package/transpiled/directives/auth/Role.js.map +1 -1
- package/transpiled/directives/auth/Scheme.js +2 -2
- package/transpiled/directives/auth/Scheme.js.map +1 -1
- package/transpiled/directives/cache/Cache.d.ts +3 -3
- package/transpiled/directives/cache/Cache.js +3 -3
- package/transpiled/directives/cache/Cache.js.map +1 -1
- package/transpiled/directives/cache/Control.d.ts +5 -4
- package/transpiled/directives/cache/Control.js +32 -15
- package/transpiled/directives/cache/Control.js.map +1 -1
- package/transpiled/directives/cache/types.d.ts +1 -1
- package/transpiled/directives/cors/CORS.d.ts +2 -3
- package/transpiled/directives/cors/CORS.js +17 -10
- package/transpiled/directives/cors/CORS.js.map +1 -1
- package/transpiled/directives/dev/Development.d.ts +3 -3
- package/transpiled/directives/dev/Development.js +1 -1
- package/transpiled/directives/dev/Development.js.map +1 -1
- package/transpiled/directives/index.d.ts +2 -2
- package/transpiled/directives/index.js +5 -3
- package/transpiled/directives/index.js.map +1 -1
- package/transpiled/directives/io/Directive.d.ts +8 -0
- package/transpiled/directives/io/Directive.js +3 -0
- package/transpiled/directives/io/Directive.js.map +1 -0
- package/transpiled/directives/io/IO.d.ts +9 -0
- package/transpiled/directives/io/IO.js +33 -0
- package/transpiled/directives/io/IO.js.map +1 -0
- package/transpiled/directives/io/Input.d.ts +11 -0
- package/transpiled/directives/io/Input.js +63 -0
- package/transpiled/directives/io/Input.js.map +1 -0
- package/transpiled/directives/io/Message.d.ts +1 -0
- package/transpiled/directives/io/Message.js +3 -0
- package/transpiled/directives/io/Message.js.map +1 -0
- package/transpiled/directives/io/Output.d.ts +13 -0
- package/transpiled/directives/io/Output.js +76 -0
- package/transpiled/directives/io/Output.js.map +1 -0
- package/transpiled/directives/io/index.d.ts +2 -0
- package/transpiled/directives/io/index.js +6 -0
- package/transpiled/directives/io/index.js.map +1 -0
- package/transpiled/directives/io/schemas.d.ts +7 -0
- package/transpiled/directives/io/schemas.js +14 -0
- package/transpiled/directives/io/schemas.js.map +1 -0
- package/transpiled/directives/octets/Context.d.ts +4 -4
- package/transpiled/directives/octets/Context.js +4 -2
- package/transpiled/directives/octets/Context.js.map +1 -1
- package/transpiled/directives/octets/Delete.d.ts +5 -4
- package/transpiled/directives/octets/Delete.js +24 -12
- package/transpiled/directives/octets/Delete.js.map +1 -1
- package/transpiled/directives/octets/Directive.d.ts +8 -0
- package/transpiled/directives/octets/Directive.js +8 -0
- package/transpiled/directives/octets/Directive.js.map +1 -0
- package/transpiled/directives/octets/Fetch.d.ts +4 -3
- package/transpiled/directives/octets/Fetch.js +31 -15
- package/transpiled/directives/octets/Fetch.js.map +1 -1
- package/transpiled/directives/octets/List.d.ts +4 -3
- package/transpiled/directives/octets/List.js +16 -7
- package/transpiled/directives/octets/List.js.map +1 -1
- package/transpiled/directives/octets/Octets.d.ts +4 -4
- package/transpiled/directives/octets/Octets.js +8 -4
- package/transpiled/directives/octets/Octets.js.map +1 -1
- package/transpiled/directives/octets/Permute.d.ts +4 -3
- package/transpiled/directives/octets/Permute.js +14 -7
- package/transpiled/directives/octets/Permute.js.map +1 -1
- package/transpiled/directives/octets/Store.d.ts +6 -4
- package/transpiled/directives/octets/Store.js +28 -13
- package/transpiled/directives/octets/Store.js.map +1 -1
- package/transpiled/directives/octets/Workflow.d.ts +15 -0
- package/transpiled/directives/octets/Workflow.js +59 -0
- package/transpiled/directives/octets/Workflow.js.map +1 -0
- package/transpiled/directives/octets/schemas.d.ts +2 -0
- package/transpiled/directives/octets/schemas.js +2 -1
- package/transpiled/directives/octets/schemas.js.map +1 -1
- package/transpiled/directives/octets/types.d.ts +0 -5
- package/transpiled/directives/octets/{workflow → workflows}/Execution.js +0 -1
- package/transpiled/directives/octets/workflows/Execution.js.map +1 -0
- package/transpiled/directives/octets/{workflow → workflows}/Workflow.d.ts +1 -1
- package/transpiled/directives/octets/{workflow → workflows}/Workflow.js +2 -2
- package/transpiled/directives/octets/workflows/Workflow.js.map +1 -0
- package/transpiled/directives/octets/workflows/index.js.map +1 -0
- package/transpiled/directives/require/Directive.d.ts +4 -0
- package/transpiled/directives/require/Directive.js +3 -0
- package/transpiled/directives/require/Directive.js.map +1 -0
- package/transpiled/directives/require/Headers.d.ts +7 -0
- package/transpiled/directives/require/Headers.js +19 -0
- package/transpiled/directives/require/Headers.js.map +1 -0
- package/transpiled/directives/require/Require.d.ts +9 -0
- package/transpiled/directives/require/Require.js +27 -0
- package/transpiled/directives/require/Require.js.map +1 -0
- package/transpiled/directives/require/index.d.ts +2 -0
- package/transpiled/directives/require/index.js +6 -0
- package/transpiled/directives/require/index.js.map +1 -0
- package/transpiled/directives/vary/Directive.d.ts +2 -1
- package/transpiled/directives/vary/Embed.d.ts +2 -1
- package/transpiled/directives/vary/Embed.js +8 -6
- package/transpiled/directives/vary/Embed.js.map +1 -1
- package/transpiled/directives/vary/Vary.d.ts +3 -3
- package/transpiled/directives/vary/Vary.js +4 -4
- package/transpiled/directives/vary/Vary.js.map +1 -1
- package/transpiled/directives/vary/embeddings/Embedding.d.ts +2 -1
- package/transpiled/directives/vary/embeddings/Header.js +9 -7
- package/transpiled/directives/vary/embeddings/Header.js.map +1 -1
- package/transpiled/directives/vary/embeddings/Language.js +2 -2
- package/transpiled/directives/vary/embeddings/Language.js.map +1 -1
- package/transpiled/directives/vary/embeddings/Parameter.d.ts +7 -0
- package/transpiled/directives/vary/embeddings/Parameter.js +14 -0
- package/transpiled/directives/vary/embeddings/Parameter.js.map +1 -0
- package/transpiled/directives/vary/embeddings/index.d.ts +2 -2
- package/transpiled/directives/vary/embeddings/index.js +5 -3
- package/transpiled/directives/vary/embeddings/index.js.map +1 -1
- package/transpiled/exceptions.d.ts +3 -2
- package/transpiled/exceptions.js +13 -7
- package/transpiled/exceptions.js.map +1 -1
- package/transpiled/io.d.ts +2 -2
- package/transpiled/root.js +5 -0
- package/transpiled/root.js.map +1 -1
- package/transpiled/tsconfig.tsbuildinfo +1 -1
- package/components/identity.federation/operations/assertions-as-values.cjs.map +0 -1
- package/components/identity.federation/operations/jwt.cjs.map +0 -1
- package/source/HTTP/Server.fixtures.ts +0 -40
- package/transpiled/HTTP/Server.fixtures.d.ts +0 -10
- package/transpiled/HTTP/Server.fixtures.js +0 -31
- package/transpiled/HTTP/Server.fixtures.js.map +0 -1
- package/transpiled/directives/octets/workflow/Execution.js.map +0 -1
- package/transpiled/directives/octets/workflow/Workflow.js.map +0 -1
- package/transpiled/directives/octets/workflow/index.js.map +0 -1
- /package/components/identity.federation/operations/{assertions-as-values.d.cts → lib/assertions-as-values.d.ts} +0 -0
- /package/source/directives/octets/{workflow → workflows}/index.ts +0 -0
- /package/transpiled/directives/octets/{workflow → workflows}/Execution.d.ts +0 -0
- /package/transpiled/directives/octets/{workflow → workflows}/index.d.ts +0 -0
- /package/transpiled/directives/octets/{workflow → workflows}/index.js +0 -0
package/source/HTTP/messages.ts
CHANGED
|
@@ -1,27 +1,26 @@
|
|
|
1
|
-
import { type IncomingHttpHeaders } from 'node:http'
|
|
2
1
|
import { Readable } from 'node:stream'
|
|
3
|
-
import {
|
|
4
|
-
import { buffer } from '@toa.io/streams'
|
|
2
|
+
import { buffer } from 'node:stream/consumers'
|
|
5
3
|
import { formats } from './formats'
|
|
6
4
|
import { BadRequest, NotAcceptable, UnsupportedMediaType } from './exceptions'
|
|
7
|
-
import type {
|
|
8
|
-
import type
|
|
5
|
+
import type { Context } from './Context'
|
|
6
|
+
import type * as http from 'node:http'
|
|
9
7
|
|
|
10
8
|
export function write
|
|
11
|
-
(
|
|
12
|
-
for (const transform of
|
|
9
|
+
(context: Context, response: http.ServerResponse, message: OutgoingMessage): void {
|
|
10
|
+
for (const transform of context.pipelines.response)
|
|
13
11
|
transform(message)
|
|
14
12
|
|
|
15
|
-
message.headers?.forEach((value, key) => response.
|
|
13
|
+
message.headers?.forEach((value, key) => response.setHeader(key, value))
|
|
14
|
+
context.timing.append(response)
|
|
16
15
|
|
|
17
16
|
if (message.body instanceof Readable)
|
|
18
|
-
stream(message,
|
|
17
|
+
stream(message, context, response)
|
|
19
18
|
else
|
|
20
|
-
send(message,
|
|
19
|
+
send(message, context, response)
|
|
21
20
|
}
|
|
22
21
|
|
|
23
|
-
export async function read (
|
|
24
|
-
const type = request.headers['content-type']
|
|
22
|
+
export async function read (context: Context): Promise<any> {
|
|
23
|
+
const type = context.request.headers['content-type']
|
|
25
24
|
|
|
26
25
|
if (type === undefined)
|
|
27
26
|
return undefined
|
|
@@ -30,8 +29,7 @@ export async function read (request: Request): Promise<any> {
|
|
|
30
29
|
throw new UnsupportedMediaType()
|
|
31
30
|
|
|
32
31
|
const format = formats[type]
|
|
33
|
-
|
|
34
|
-
const buf = await buffer(request)
|
|
32
|
+
const buf = await context.timing.capture('buffer', buffer(context.request))
|
|
35
33
|
|
|
36
34
|
try {
|
|
37
35
|
return format.decode(buf)
|
|
@@ -40,32 +38,33 @@ export async function read (request: Request): Promise<any> {
|
|
|
40
38
|
}
|
|
41
39
|
}
|
|
42
40
|
|
|
43
|
-
function send
|
|
41
|
+
function send
|
|
42
|
+
(message: OutgoingMessage, context: Context, response: http.ServerResponse): void {
|
|
44
43
|
if (message.body === undefined || message.body === null) {
|
|
45
44
|
response.end()
|
|
46
45
|
|
|
47
46
|
return
|
|
48
47
|
}
|
|
49
48
|
|
|
50
|
-
if (
|
|
49
|
+
if (context.encoder === null)
|
|
51
50
|
throw new NotAcceptable()
|
|
52
51
|
|
|
53
|
-
const buf =
|
|
52
|
+
const buf = context.encoder.encode(message.body)
|
|
54
53
|
|
|
55
54
|
response
|
|
56
|
-
.
|
|
57
|
-
.
|
|
55
|
+
.setHeader('content-type', context.encoder.type)
|
|
56
|
+
.appendHeader('vary', 'accept')
|
|
58
57
|
.end(buf)
|
|
59
58
|
}
|
|
60
59
|
|
|
61
60
|
function stream
|
|
62
|
-
(message: OutgoingMessage,
|
|
61
|
+
(message: OutgoingMessage, context: Context, response: http.ServerResponse): void {
|
|
63
62
|
const encoded = message.headers !== undefined && message.headers.has('content-type')
|
|
64
63
|
|
|
65
64
|
if (encoded)
|
|
66
|
-
pipe(
|
|
65
|
+
message.body.pipe(response)
|
|
67
66
|
else
|
|
68
|
-
multipart(message,
|
|
67
|
+
multipart(message, context, response)
|
|
69
68
|
|
|
70
69
|
message.body.on('error', (e: Error) => {
|
|
71
70
|
console.error(e)
|
|
@@ -73,54 +72,39 @@ function stream
|
|
|
73
72
|
})
|
|
74
73
|
}
|
|
75
74
|
|
|
76
|
-
function
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function multipart (message: OutgoingMessage, request: IncomingMessage, response: Response): void {
|
|
82
|
-
if (request.encoder === null)
|
|
75
|
+
function multipart
|
|
76
|
+
(message: OutgoingMessage, context: Context, response: http.ServerResponse): void {
|
|
77
|
+
if (context.encoder === null)
|
|
83
78
|
throw new NotAcceptable()
|
|
84
79
|
|
|
85
|
-
const encoder =
|
|
80
|
+
const encoder = context.encoder
|
|
86
81
|
|
|
87
|
-
response.
|
|
82
|
+
response.setHeader('content-type', `${encoder.multipart}; boundary=${BOUNDARY}`)
|
|
88
83
|
|
|
89
84
|
message.body
|
|
90
|
-
.map((part: unknown) => Buffer.concat([CUT, encoder.encode(part)]))
|
|
85
|
+
.map((part: unknown) => Buffer.concat([CUT, encoder.encode(part), CRLF]))
|
|
91
86
|
.on('end', () => response.end(FINALCUT))
|
|
92
87
|
.pipe(response)
|
|
93
88
|
}
|
|
94
89
|
|
|
95
90
|
const BOUNDARY = 'cut'
|
|
96
91
|
const CUT = Buffer.from(`--${BOUNDARY}\r\n`)
|
|
92
|
+
const CRLF = Buffer.from('\r\n')
|
|
97
93
|
const FINALCUT = Buffer.from(`--${BOUNDARY}--`)
|
|
98
94
|
|
|
99
|
-
export interface IncomingMessage extends Request {
|
|
100
|
-
method: string
|
|
101
|
-
path: string
|
|
102
|
-
url: string
|
|
103
|
-
headers: IncomingHttpHeaders
|
|
104
|
-
query: Query
|
|
105
|
-
parse: <T> () => Promise<T>
|
|
106
|
-
encoder: Format | null
|
|
107
|
-
subtype: string | null
|
|
108
|
-
pipelines: {
|
|
109
|
-
body: Array<(input: unknown) => unknown>
|
|
110
|
-
response: Array<(output: OutgoingMessage) => void>
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
95
|
export interface OutgoingMessage {
|
|
115
96
|
status?: number
|
|
116
97
|
headers?: Headers
|
|
117
98
|
body?: any
|
|
118
99
|
}
|
|
119
100
|
|
|
120
|
-
export interface Query
|
|
101
|
+
export interface Query {
|
|
102
|
+
[key: string]: string | number | undefined
|
|
103
|
+
|
|
121
104
|
id?: string
|
|
122
105
|
criteria?: string
|
|
123
106
|
sort?: string
|
|
124
107
|
omit?: string
|
|
125
108
|
limit?: string
|
|
109
|
+
version?: number
|
|
126
110
|
}
|
package/source/Mapping.ts
CHANGED
|
@@ -29,7 +29,10 @@ class QueryableMapping extends Mapping {
|
|
|
29
29
|
public fit (input: any, qs: http.Query, parameters: Parameter[]): core.Request {
|
|
30
30
|
const query = this.query.fit(qs, parameters)
|
|
31
31
|
|
|
32
|
-
return {
|
|
32
|
+
return {
|
|
33
|
+
input,
|
|
34
|
+
query
|
|
35
|
+
}
|
|
33
36
|
}
|
|
34
37
|
}
|
|
35
38
|
|
|
@@ -38,14 +41,10 @@ class InputMapping extends Mapping {
|
|
|
38
41
|
if (input === undefined && parameters.length > 0)
|
|
39
42
|
input = {}
|
|
40
43
|
|
|
41
|
-
if (typeof input === 'object')
|
|
42
|
-
|
|
44
|
+
if (typeof input === 'object' && input !== null)
|
|
45
|
+
for (const parameter of parameters)
|
|
46
|
+
input[parameter.name] = parameter.value
|
|
43
47
|
|
|
44
48
|
return { input }
|
|
45
49
|
}
|
|
46
|
-
|
|
47
|
-
private assign (input: Record<string, any>, parameters: Parameter[]): void {
|
|
48
|
-
for (const parameter of parameters)
|
|
49
|
-
input[parameter.name] = parameter.value
|
|
50
|
-
}
|
|
51
50
|
}
|
package/source/RTD/Context.ts
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import { type
|
|
1
|
+
import { type DirectiveFactory } from './Directives'
|
|
2
|
+
import { type EndpointsFactory } from './Endpoint'
|
|
3
|
+
import type { Directive } from './syntax'
|
|
3
4
|
|
|
4
|
-
export interface Context<
|
|
5
|
-
TEndpoint extends Endpoint = any,
|
|
6
|
-
TDirectives extends Directives<TDirectives> = any,
|
|
7
|
-
TExtension = any
|
|
8
|
-
> {
|
|
5
|
+
export interface Context<TExtension = any> {
|
|
9
6
|
readonly protected: boolean
|
|
10
|
-
readonly endpoints: EndpointsFactory
|
|
7
|
+
readonly endpoints: EndpointsFactory
|
|
11
8
|
readonly directives: {
|
|
12
|
-
readonly factory:
|
|
13
|
-
stack:
|
|
9
|
+
readonly factory: DirectiveFactory
|
|
10
|
+
stack: Directive[]
|
|
14
11
|
}
|
|
15
12
|
readonly extension?: TExtension
|
|
16
13
|
}
|
package/source/RTD/Directives.ts
CHANGED
|
@@ -1,9 +1,33 @@
|
|
|
1
|
+
import type { Parameter } from './Match'
|
|
1
2
|
import type * as syntax from './syntax'
|
|
3
|
+
import type { Context, OutgoingMessage } from '../HTTP'
|
|
4
|
+
import type { Output } from '../io'
|
|
2
5
|
|
|
3
|
-
export interface Directives
|
|
4
|
-
|
|
6
|
+
export interface Directives {
|
|
7
|
+
preflight: (context: Context, parameters: Parameter[]) => Promise<Output>
|
|
8
|
+
settle: (context: Context, response: OutgoingMessage) => Promise<void>
|
|
5
9
|
}
|
|
6
10
|
|
|
7
|
-
export interface
|
|
8
|
-
create: (directives: syntax.Directive[]) =>
|
|
11
|
+
export interface DirectiveFactory {
|
|
12
|
+
create: (directives: syntax.Directive[]) => Directives
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface DirectiveSet {
|
|
16
|
+
family: DirectiveFamily
|
|
17
|
+
directives: any[]
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface DirectiveFamily<TDirective = any, TExtension = any> {
|
|
21
|
+
readonly name: string
|
|
22
|
+
readonly mandatory: boolean
|
|
23
|
+
|
|
24
|
+
create: (name: string, ...rest: any[]) => TDirective
|
|
25
|
+
|
|
26
|
+
preflight?: (directives: TDirective[],
|
|
27
|
+
request: Context & TExtension,
|
|
28
|
+
parameters: Parameter[]) => Output | Promise<Output>
|
|
29
|
+
|
|
30
|
+
settle?: (directives: TDirective[],
|
|
31
|
+
request: Context & TExtension,
|
|
32
|
+
response: OutgoingMessage) => void | Promise<void>
|
|
9
33
|
}
|
package/source/RTD/Endpoint.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { type Context } from './Context'
|
|
2
|
+
import type * as http from '../HTTP'
|
|
2
3
|
import type * as syntax from './syntax'
|
|
4
|
+
import type * as RTD from './index'
|
|
3
5
|
|
|
4
|
-
export interface Endpoint
|
|
5
|
-
call:
|
|
6
|
+
export interface Endpoint {
|
|
7
|
+
call: (context: http.Context, parameters: RTD.Parameter[]) => Promise<http.OutgoingMessage>
|
|
6
8
|
close: () => Promise<void>
|
|
7
9
|
}
|
|
8
10
|
|
|
9
|
-
export interface EndpointsFactory
|
|
10
|
-
create: (method: syntax.Method, context: Context) =>
|
|
11
|
+
export interface EndpointsFactory {
|
|
12
|
+
create: (method: syntax.Method, context: Context) => Endpoint
|
|
11
13
|
}
|
package/source/RTD/Match.ts
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import { type Node } from './Node'
|
|
2
|
-
import { type Directives } from './Directives'
|
|
3
|
-
import { type Endpoint } from './Endpoint'
|
|
4
2
|
|
|
5
|
-
export interface Match
|
|
6
|
-
|
|
7
|
-
TDirectives extends Directives<TDirectives> = any
|
|
8
|
-
> {
|
|
9
|
-
node: Node<TEndpoint, TDirectives>
|
|
3
|
+
export interface Match {
|
|
4
|
+
node: Node
|
|
10
5
|
parameters: Parameter[]
|
|
11
6
|
}
|
|
12
7
|
|
package/source/RTD/Method.ts
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { Endpoint } from './Endpoint'
|
|
2
|
+
import type { Directives } from './Directives'
|
|
3
3
|
|
|
4
|
-
export class Method
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
> {
|
|
8
|
-
public readonly endpoint: TEndpoint | null
|
|
9
|
-
public readonly directives: TDirectives
|
|
4
|
+
export class Method {
|
|
5
|
+
public readonly endpoint: Endpoint | null
|
|
6
|
+
public readonly directives: Directives
|
|
10
7
|
|
|
11
|
-
public constructor (endpoint:
|
|
8
|
+
public constructor (endpoint: Endpoint | null, directives: Directives) {
|
|
12
9
|
this.endpoint = endpoint
|
|
13
10
|
this.directives = directives
|
|
14
11
|
}
|
|
@@ -18,7 +15,4 @@ export class Method<
|
|
|
18
15
|
}
|
|
19
16
|
}
|
|
20
17
|
|
|
21
|
-
export type Methods<
|
|
22
|
-
TEndpoint extends Endpoint<TEndpoint> = any,
|
|
23
|
-
TDirectives extends Directives<TDirectives> = any
|
|
24
|
-
> = Record<string, Method<TEndpoint, TDirectives>>
|
|
18
|
+
export type Methods = Record<string, Method>
|
package/source/RTD/Node.ts
CHANGED
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
import { type Route } from './Route'
|
|
2
2
|
import { type Methods } from './Method'
|
|
3
3
|
import { type Match, type Parameter } from './Match'
|
|
4
|
-
import { type Directives } from './Directives'
|
|
5
|
-
import { type Endpoint } from './Endpoint'
|
|
6
4
|
|
|
7
|
-
export class Node
|
|
8
|
-
TEndpoint extends Endpoint<TEndpoint> = any,
|
|
9
|
-
TDirectives extends Directives<TDirectives> = any
|
|
10
|
-
> {
|
|
5
|
+
export class Node {
|
|
11
6
|
public intermediate: boolean
|
|
12
|
-
public methods: Methods
|
|
7
|
+
public methods: Methods
|
|
13
8
|
private readonly protected: boolean
|
|
14
9
|
private routes: Route[]
|
|
15
10
|
|
|
16
11
|
public constructor
|
|
17
|
-
(routes: Route[], methods: Methods
|
|
12
|
+
(routes: Route[], methods: Methods, properties: Properties) {
|
|
18
13
|
this.routes = routes
|
|
19
14
|
this.methods = methods
|
|
20
15
|
this.protected = properties.protected
|
|
@@ -34,26 +29,30 @@ export class Node<
|
|
|
34
29
|
return null
|
|
35
30
|
}
|
|
36
31
|
|
|
37
|
-
public merge (node: Node
|
|
32
|
+
public merge (node: Node): void {
|
|
38
33
|
this.intermediate = node.intermediate
|
|
39
34
|
|
|
40
|
-
if (!this.protected)
|
|
41
|
-
|
|
35
|
+
if (!this.protected)
|
|
36
|
+
this.replace(node)
|
|
37
|
+
else
|
|
38
|
+
this.append(node)
|
|
42
39
|
|
|
43
40
|
this.sort()
|
|
44
41
|
}
|
|
45
42
|
|
|
46
|
-
private replace (node: Node
|
|
43
|
+
private replace (node: Node): void {
|
|
47
44
|
const methods = Object.values(this.methods)
|
|
48
45
|
|
|
49
46
|
this.routes = node.routes
|
|
50
47
|
this.methods = node.methods
|
|
51
48
|
|
|
52
49
|
for (const method of methods)
|
|
53
|
-
void method.close()
|
|
50
|
+
void method.close()
|
|
51
|
+
|
|
52
|
+
// race condition is really unlikely
|
|
54
53
|
}
|
|
55
54
|
|
|
56
|
-
private append (node: Node
|
|
55
|
+
private append (node: Node): void {
|
|
57
56
|
for (const route of node.routes)
|
|
58
57
|
this.mergeRoute(route)
|
|
59
58
|
|
package/source/RTD/Tree.ts
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import { type Node } from './Node'
|
|
2
1
|
import { createNode } from './factory'
|
|
3
2
|
import { fragment } from './segment'
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import
|
|
3
|
+
import type { Node } from './Node'
|
|
4
|
+
import type { Match } from './Match'
|
|
5
|
+
import type { Context } from './Context'
|
|
6
|
+
import type { DirectiveFactory } from './Directives'
|
|
7
|
+
import type { EndpointsFactory } from './Endpoint'
|
|
8
8
|
import type * as syntax from './syntax'
|
|
9
9
|
|
|
10
|
-
export class Tree
|
|
11
|
-
TEndpoint extends Endpoint<TEndpoint> = any,
|
|
12
|
-
TDirectives extends Directives<TDirectives> = any
|
|
13
|
-
> {
|
|
10
|
+
export class Tree {
|
|
14
11
|
private readonly root: syntax.Node
|
|
15
|
-
private readonly trunk: Node
|
|
16
|
-
private readonly endpoints: EndpointsFactory
|
|
17
|
-
private readonly directives:
|
|
12
|
+
private readonly trunk: Node
|
|
13
|
+
private readonly endpoints: EndpointsFactory
|
|
14
|
+
private readonly directives: DirectiveFactory
|
|
18
15
|
|
|
19
16
|
public constructor
|
|
20
|
-
(node: syntax.Node, endpoints: EndpointsFactory, directives:
|
|
17
|
+
(node: syntax.Node, endpoints: EndpointsFactory, directives: DirectiveFactory) {
|
|
21
18
|
this.endpoints = endpoints
|
|
22
19
|
this.directives = directives
|
|
23
20
|
this.trunk = this.createNode(node, PROTECTED)
|
|
24
21
|
this.root = node
|
|
25
22
|
}
|
|
26
23
|
|
|
27
|
-
public match (path: string): Match
|
|
24
|
+
public match (path: string): Match | null {
|
|
28
25
|
if (path === '/')
|
|
29
|
-
return {
|
|
26
|
+
return {
|
|
27
|
+
node: this.trunk,
|
|
28
|
+
parameters: []
|
|
29
|
+
}
|
|
30
30
|
|
|
31
31
|
const fragments = fragment(path)
|
|
32
32
|
|
|
@@ -39,7 +39,8 @@ export class Tree<
|
|
|
39
39
|
this.trunk.merge(branch)
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
private createNode
|
|
42
|
+
private createNode
|
|
43
|
+
(node: syntax.Node, protect: boolean, extension?: any): Node {
|
|
43
44
|
const context: Context = {
|
|
44
45
|
protected: protect,
|
|
45
46
|
endpoints: this.endpoints,
|
package/source/RTD/factory.ts
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import { Node, type Properties } from './Node'
|
|
2
2
|
import { Route } from './Route'
|
|
3
|
-
import { type Context } from './Context'
|
|
4
3
|
import { segment } from './segment'
|
|
5
4
|
import { Method, type Methods } from './Method'
|
|
6
|
-
import {
|
|
7
|
-
import { type Directives } from './Directives'
|
|
5
|
+
import type { Context } from './Context'
|
|
8
6
|
import type * as syntax from './syntax'
|
|
9
7
|
|
|
10
|
-
export function createNode
|
|
11
|
-
(node: syntax.Node, context: Context): Node<TEndpoint, TDirectives> {
|
|
8
|
+
export function createNode (node: syntax.Node, context: Context): Node {
|
|
12
9
|
if (node.isolated === true)
|
|
13
10
|
context.directives.stack = node.directives
|
|
14
11
|
else
|
|
@@ -36,7 +33,7 @@ function createRoute (route: syntax.Route, context: Context): Route {
|
|
|
36
33
|
}
|
|
37
34
|
|
|
38
35
|
function createMethod (method: syntax.Method, context: Context): Method {
|
|
39
|
-
const stack =
|
|
36
|
+
const stack = method.directives.concat(context.directives.stack)
|
|
40
37
|
const directives = context.directives.factory.create(stack)
|
|
41
38
|
|
|
42
39
|
const endpoint = method.mapping?.endpoint === undefined
|
package/source/Tenant.ts
CHANGED
|
@@ -25,14 +25,6 @@ export class Tenant extends Connector {
|
|
|
25
25
|
public override async open (): Promise<void> {
|
|
26
26
|
await this.expose()
|
|
27
27
|
await this.broadcast.receive('ping', this.expose.bind(this))
|
|
28
|
-
|
|
29
|
-
console.info('Exposition Tenant for ' +
|
|
30
|
-
`'${this.branch.namespace}.${this.branch.component}' has started.`)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
public override async dispose (): Promise<void> {
|
|
34
|
-
console.info('Exposition Tenant for ' +
|
|
35
|
-
`'${this.branch.namespace}.${this.branch.component}' has been stopped.`)
|
|
36
28
|
}
|
|
37
29
|
|
|
38
30
|
private async expose (): Promise<void> {
|
package/source/deployment.ts
CHANGED
|
@@ -41,6 +41,12 @@ export function deployment (_: unknown, annotation: Annotation | undefined): Dep
|
|
|
41
41
|
value: '1'
|
|
42
42
|
})
|
|
43
43
|
|
|
44
|
+
if (annotation?.trace === true)
|
|
45
|
+
service.variables.push({
|
|
46
|
+
name: 'TOA_EXPOSITION_TRACE',
|
|
47
|
+
value: '1'
|
|
48
|
+
})
|
|
49
|
+
|
|
44
50
|
if (annotation !== undefined)
|
|
45
51
|
schemas.annotaion.validate(annotation)
|
|
46
52
|
|
|
@@ -8,7 +8,8 @@ export class Anonymous implements Directive {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
public authorize (_: any, input: Input): boolean {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
return 'authorization' in input.request.headers
|
|
12
|
+
? false
|
|
13
|
+
: this.allow
|
|
13
14
|
}
|
|
14
15
|
}
|
|
@@ -7,14 +7,14 @@ import { Role } from './Role'
|
|
|
7
7
|
import { Rule } from './Rule'
|
|
8
8
|
import { Incept } from './Incept'
|
|
9
9
|
import { Echo } from './Echo'
|
|
10
|
-
import { split } from './split'
|
|
11
10
|
import { Scheme } from './Scheme'
|
|
11
|
+
import { Delegate } from './Delegate'
|
|
12
|
+
import { split } from './split'
|
|
12
13
|
import { PRIMARY, PROVIDERS } from './schemes'
|
|
13
14
|
import type { Output } from '../../io'
|
|
14
15
|
import type { Component } from '@toa.io/core'
|
|
15
16
|
import type { Remotes } from '../../Remotes'
|
|
16
|
-
import type {
|
|
17
|
-
import type { Parameter } from '../../RTD'
|
|
17
|
+
import type { Parameter, DirectiveFamily } from '../../RTD'
|
|
18
18
|
import type {
|
|
19
19
|
AuthenticationResult,
|
|
20
20
|
Ban,
|
|
@@ -27,7 +27,7 @@ import type {
|
|
|
27
27
|
Schemes
|
|
28
28
|
} from './types'
|
|
29
29
|
|
|
30
|
-
export class Authorization implements
|
|
30
|
+
export class Authorization implements DirectiveFamily<Directive, Extension> {
|
|
31
31
|
public readonly depends: string[] = ['Vary']
|
|
32
32
|
public readonly name: string = 'auth'
|
|
33
33
|
public readonly mandatory: boolean = true
|
|
@@ -38,10 +38,10 @@ export class Authorization implements Family<Directive, Extension> {
|
|
|
38
38
|
private bans: Component | null = null
|
|
39
39
|
|
|
40
40
|
public create (name: string, value: any, remotes: Remotes): Directive {
|
|
41
|
-
assert.ok(name in
|
|
42
|
-
`Directive '
|
|
41
|
+
assert.ok(name in constructors,
|
|
42
|
+
`Directive 'auth:${name}' is not implemented.`)
|
|
43
43
|
|
|
44
|
-
const Class =
|
|
44
|
+
const Class = constructors[name]
|
|
45
45
|
|
|
46
46
|
for (const name of REMOTES)
|
|
47
47
|
this.discovery[name] ??= remotes.discover('identity', name)
|
|
@@ -56,7 +56,7 @@ export class Authorization implements Family<Directive, Extension> {
|
|
|
56
56
|
public async preflight (directives: Directive[],
|
|
57
57
|
input: Input,
|
|
58
58
|
parameters: Parameter[]): Promise<Output> {
|
|
59
|
-
const identity = await this.resolve(input.headers.authorization)
|
|
59
|
+
const identity = await this.resolve(input.request.headers.authorization)
|
|
60
60
|
|
|
61
61
|
input.identity = identity
|
|
62
62
|
|
|
@@ -67,8 +67,10 @@ export class Authorization implements Family<Directive, Extension> {
|
|
|
67
67
|
return directive.reply?.(identity) ?? null
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
if (identity === null)
|
|
71
|
-
|
|
70
|
+
if (identity === null)
|
|
71
|
+
throw new http.Unauthorized()
|
|
72
|
+
else
|
|
73
|
+
throw new http.Forbidden()
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
public async settle (directives: Directive[],
|
|
@@ -90,9 +92,9 @@ export class Authorization implements Family<Directive, Extension> {
|
|
|
90
92
|
const token = await this.tokens.invoke<string>('encrypt', { input: { identity } })
|
|
91
93
|
const authorization = `Token ${token}`
|
|
92
94
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
+
response.headers ??= new Headers()
|
|
95
96
|
response.headers.set('authorization', authorization)
|
|
97
|
+
response.headers.append('cache-control', 'no-store')
|
|
96
98
|
}
|
|
97
99
|
|
|
98
100
|
private async resolve (authorization: string | undefined): Promise<Identity | null> {
|
|
@@ -131,14 +133,15 @@ export class Authorization implements Family<Directive, Extension> {
|
|
|
131
133
|
}
|
|
132
134
|
}
|
|
133
135
|
|
|
134
|
-
const
|
|
136
|
+
const constructors: Record<string, new (value: any, argument?: any) => Directive> = {
|
|
135
137
|
anonymous: Anonymous,
|
|
136
138
|
id: Id,
|
|
137
139
|
role: Role,
|
|
138
140
|
rule: Rule,
|
|
139
141
|
incept: Incept,
|
|
140
142
|
scheme: Scheme,
|
|
141
|
-
echo: Echo
|
|
143
|
+
echo: Echo,
|
|
144
|
+
delegate: Delegate
|
|
142
145
|
}
|
|
143
146
|
|
|
144
147
|
const REMOTES: Remote[] = ['basic', 'federation', 'tokens', 'roles', 'bans']
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { BadRequest } from '../../HTTP'
|
|
2
|
+
import { type Directive, type Identity } from './types'
|
|
3
|
+
import type { Input } from '../../io'
|
|
4
|
+
|
|
5
|
+
export class Delegate implements Directive {
|
|
6
|
+
private readonly property: string
|
|
7
|
+
|
|
8
|
+
public constructor (property: string) {
|
|
9
|
+
this.property = property
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
public authorize (identity: Identity | null, context: Input): boolean {
|
|
13
|
+
if (identity === null)
|
|
14
|
+
return false
|
|
15
|
+
|
|
16
|
+
context.pipelines.body.push((body) => this.embed(body, identity))
|
|
17
|
+
|
|
18
|
+
return true
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
private embed (body: unknown, identity: Identity): Record<string, unknown> {
|
|
22
|
+
if (body === undefined)
|
|
23
|
+
body = {}
|
|
24
|
+
|
|
25
|
+
check(body)
|
|
26
|
+
body[this.property] = identity
|
|
27
|
+
|
|
28
|
+
return body
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function check (body: unknown): asserts body is Record<string, unknown> {
|
|
33
|
+
if (typeof body !== 'object' || body === null)
|
|
34
|
+
throw new BadRequest('Invalid request body')
|
|
35
|
+
}
|
|
@@ -15,28 +15,33 @@ export class Incept implements Directive {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
public authorize (identity: Identity | null, input: Input): boolean {
|
|
18
|
-
return identity === null && 'authorization' in input.headers
|
|
18
|
+
return identity === null && 'authorization' in input.request.headers
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
public async settle (
|
|
21
|
+
public async settle (input: Input, response: http.OutgoingMessage): Promise<void> {
|
|
22
22
|
const id = response.body?.[this.property]
|
|
23
23
|
|
|
24
24
|
if (id === undefined)
|
|
25
25
|
throw new http.Conflict('Identity inception has failed as the response body ' +
|
|
26
26
|
` does not contain the '${this.property}' property.`)
|
|
27
27
|
|
|
28
|
-
const [scheme, credentials] = split(request.headers.authorization!)
|
|
28
|
+
const [scheme, credentials] = split(input.request.headers.authorization!)
|
|
29
29
|
const provider = PROVIDERS[scheme]
|
|
30
30
|
|
|
31
31
|
this.schemes[scheme] ??= await this.discovery[provider]
|
|
32
32
|
|
|
33
33
|
const identity = await this.schemes[scheme]
|
|
34
|
-
.invoke<Maybe<Identity>>('create', {
|
|
34
|
+
.invoke<Maybe<Identity>>('create', {
|
|
35
|
+
input: {
|
|
36
|
+
id,
|
|
37
|
+
credentials
|
|
38
|
+
}
|
|
39
|
+
})
|
|
35
40
|
|
|
36
41
|
if (identity instanceof Error)
|
|
37
42
|
throw new http.Conflict(identity)
|
|
38
43
|
|
|
39
|
-
|
|
40
|
-
|
|
44
|
+
input.identity = identity
|
|
45
|
+
input.identity.scheme = scheme
|
|
41
46
|
}
|
|
42
47
|
}
|