@toa.io/extensions.exposition 1.0.0-alpha.282 → 1.0.0-alpha.283

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.
Files changed (312) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/components/exposition.octets/manifest.toa.yaml +11 -0
  3. package/components/exposition.octets/types/index.d.ts +3 -0
  4. package/components/exposition.octets/types/toa.d.ts +41 -0
  5. package/components/identity.bans/types/index.d.ts +3 -0
  6. package/components/identity.bans/types/toa.d.ts +34 -0
  7. package/components/identity.basic/manifest.toa.yaml +13 -2
  8. package/components/identity.basic/operations/add.d.ts +3 -3
  9. package/components/identity.basic/operations/authenticate.d.ts +2 -2
  10. package/components/identity.basic/operations/check.d.ts +1 -1
  11. package/components/identity.basic/operations/delete.d.ts +2 -2
  12. package/components/identity.basic/operations/incept.d.ts +2 -2
  13. package/components/identity.basic/operations/info.d.ts +1 -1
  14. package/components/identity.basic/operations/transit.d.ts +4 -3
  15. package/components/identity.basic/operations/transit.js +2 -1
  16. package/components/identity.basic/operations/transit.js.map +1 -1
  17. package/components/identity.basic/source/add.ts +3 -3
  18. package/components/identity.basic/source/authenticate.ts +2 -2
  19. package/components/identity.basic/source/check.ts +1 -1
  20. package/components/identity.basic/source/delete.ts +2 -2
  21. package/components/identity.basic/source/incept.ts +2 -2
  22. package/components/identity.basic/source/info.ts +1 -1
  23. package/components/identity.basic/source/transit.ts +6 -4
  24. package/components/identity.basic/tsconfig.tsbuildinfo +1 -1
  25. package/components/identity.basic/types/index.d.ts +21 -0
  26. package/components/identity.basic/types/toa.d.ts +121 -0
  27. package/components/identity.clients/manifest.toa.yaml +243 -0
  28. package/components/identity.clients/operations/describe.d.ts +27 -0
  29. package/components/identity.clients/operations/describe.js +44 -0
  30. package/components/identity.clients/operations/describe.js.map +1 -0
  31. package/components/identity.clients/operations/lib/Context.d.ts +29 -0
  32. package/components/identity.clients/operations/lib/Context.js +2 -0
  33. package/components/identity.clients/operations/lib/Context.js.map +1 -0
  34. package/components/identity.clients/operations/lib/Entity.d.ts +29 -0
  35. package/components/identity.clients/operations/lib/Entity.js +2 -0
  36. package/components/identity.clients/operations/lib/Entity.js.map +1 -0
  37. package/components/identity.clients/operations/lib/canonical.d.ts +11 -0
  38. package/components/identity.clients/operations/lib/canonical.js +24 -0
  39. package/components/identity.clients/operations/lib/canonical.js.map +1 -0
  40. package/components/identity.clients/operations/lib/cimd.d.ts +8 -0
  41. package/components/identity.clients/operations/lib/cimd.js +86 -0
  42. package/components/identity.clients/operations/lib/cimd.js.map +1 -0
  43. package/components/identity.clients/operations/lib/errors.d.ts +7 -0
  44. package/components/identity.clients/operations/lib/errors.js +5 -0
  45. package/components/identity.clients/operations/lib/errors.js.map +1 -0
  46. package/components/identity.clients/operations/lib/index.d.ts +6 -0
  47. package/components/identity.clients/operations/lib/index.js +7 -0
  48. package/components/identity.clients/operations/lib/index.js.map +1 -0
  49. package/components/identity.clients/operations/lib/redirect.d.ts +10 -0
  50. package/components/identity.clients/operations/lib/redirect.js +32 -0
  51. package/components/identity.clients/operations/lib/redirect.js.map +1 -0
  52. package/components/identity.clients/operations/register.d.ts +37 -0
  53. package/components/identity.clients/operations/register.js +84 -0
  54. package/components/identity.clients/operations/register.js.map +1 -0
  55. package/components/identity.clients/source/describe.ts +65 -0
  56. package/components/identity.clients/source/lib/Context.ts +38 -0
  57. package/components/identity.clients/source/lib/Entity.ts +31 -0
  58. package/components/identity.clients/source/lib/canonical.test.ts +43 -0
  59. package/components/identity.clients/source/lib/canonical.ts +27 -0
  60. package/components/identity.clients/source/lib/cimd.test.ts +120 -0
  61. package/components/identity.clients/source/lib/cimd.ts +107 -0
  62. package/components/identity.clients/source/lib/errors.ts +4 -0
  63. package/components/identity.clients/source/lib/index.ts +6 -0
  64. package/components/identity.clients/source/lib/redirect.test.ts +41 -0
  65. package/components/identity.clients/source/lib/redirect.ts +35 -0
  66. package/components/identity.clients/source/register.ts +125 -0
  67. package/components/identity.clients/tsconfig.json +10 -0
  68. package/components/identity.clients/tsconfig.tsbuildinfo +1 -0
  69. package/components/identity.clients/types/index.d.ts +3 -0
  70. package/components/identity.clients/types/toa.d.ts +109 -0
  71. package/components/identity.credentials/operations/list.d.ts +2 -1
  72. package/components/identity.credentials/operations/list.js.map +1 -1
  73. package/components/identity.credentials/source/list.ts +2 -1
  74. package/components/identity.credentials/tsconfig.tsbuildinfo +1 -1
  75. package/components/identity.credentials/types/index.d.ts +3 -0
  76. package/components/identity.credentials/types/toa.d.ts +30 -0
  77. package/components/identity.federation/manifest.toa.yaml +37 -1
  78. package/components/identity.federation/operations/authenticate.d.ts +1 -1
  79. package/components/identity.federation/operations/lib/Ctx.d.ts +2 -2
  80. package/components/identity.federation/operations/lib/decode.js +22 -8
  81. package/components/identity.federation/operations/lib/decode.js.map +1 -1
  82. package/components/identity.federation/operations/lib/errors.d.ts +7 -0
  83. package/components/identity.federation/operations/lib/errors.js +4 -0
  84. package/components/identity.federation/operations/lib/errors.js.map +1 -1
  85. package/components/identity.federation/operations/lib/exchange.js +11 -6
  86. package/components/identity.federation/operations/lib/exchange.js.map +1 -1
  87. package/components/identity.federation/operations/types/configuration.d.ts +1 -1
  88. package/components/identity.federation/operations/types/context.d.ts +3 -2
  89. package/components/identity.federation/source/authenticate.ts +1 -1
  90. package/components/identity.federation/source/lib/Ctx.ts +2 -2
  91. package/components/identity.federation/source/lib/decode.ts +25 -9
  92. package/components/identity.federation/source/lib/errors.ts +5 -0
  93. package/components/identity.federation/source/lib/exchange.ts +11 -7
  94. package/components/identity.federation/source/types/configuration.ts +1 -1
  95. package/components/identity.federation/source/types/context.ts +3 -2
  96. package/components/identity.federation/tsconfig.tsbuildinfo +1 -1
  97. package/components/identity.federation/types/index.d.ts +3 -0
  98. package/components/identity.federation/types/toa.d.ts +127 -0
  99. package/components/identity.grants/manifest.toa.yaml +245 -0
  100. package/components/identity.grants/operations/authorize.d.ts +35 -0
  101. package/components/identity.grants/operations/authorize.js +54 -0
  102. package/components/identity.grants/operations/authorize.js.map +1 -0
  103. package/components/identity.grants/operations/exchange.d.ts +37 -0
  104. package/components/identity.grants/operations/exchange.js +89 -0
  105. package/components/identity.grants/operations/exchange.js.map +1 -0
  106. package/components/identity.grants/operations/lib/code.d.ts +15 -0
  107. package/components/identity.grants/operations/lib/code.js +30 -0
  108. package/components/identity.grants/operations/lib/code.js.map +1 -0
  109. package/components/identity.grants/operations/lib/identify.d.ts +6 -0
  110. package/components/identity.grants/operations/lib/identify.js +15 -0
  111. package/components/identity.grants/operations/lib/identify.js.map +1 -0
  112. package/components/identity.grants/operations/lib/index.d.ts +3 -0
  113. package/components/identity.grants/operations/lib/index.js +3 -0
  114. package/components/identity.grants/operations/lib/index.js.map +1 -0
  115. package/components/identity.grants/operations/list.d.ts +13 -0
  116. package/components/identity.grants/operations/list.js +18 -0
  117. package/components/identity.grants/operations/list.js.map +1 -0
  118. package/components/identity.grants/operations/revoke.d.ts +18 -0
  119. package/components/identity.grants/operations/revoke.js +25 -0
  120. package/components/identity.grants/operations/revoke.js.map +1 -0
  121. package/components/identity.grants/source/authorize.ts +90 -0
  122. package/components/identity.grants/source/exchange.ts +130 -0
  123. package/components/identity.grants/source/lib/code.ts +39 -0
  124. package/components/identity.grants/source/lib/identify.ts +16 -0
  125. package/components/identity.grants/source/lib/index.ts +3 -0
  126. package/components/identity.grants/source/list.ts +28 -0
  127. package/components/identity.grants/source/revoke.ts +38 -0
  128. package/components/identity.grants/tsconfig.json +10 -0
  129. package/components/identity.grants/tsconfig.tsbuildinfo +1 -0
  130. package/components/identity.grants/types/index.d.ts +60 -0
  131. package/components/identity.grants/types/toa.d.ts +108 -0
  132. package/components/identity.keys/manifest.toa.yaml +1 -0
  133. package/components/identity.keys/operations/create.d.ts +1 -1
  134. package/components/identity.keys/operations/revoke.d.ts +1 -1
  135. package/components/identity.keys/source/create.ts +1 -1
  136. package/components/identity.keys/source/revoke.ts +1 -1
  137. package/components/identity.keys/tsconfig.tsbuildinfo +1 -1
  138. package/components/identity.keys/types/index.d.ts +3 -0
  139. package/components/identity.keys/types/toa.d.ts +47 -0
  140. package/components/identity.otp/operations/lib/Context.d.ts +4 -2
  141. package/components/identity.otp/source/lib/Context.ts +4 -2
  142. package/components/identity.otp/tsconfig.tsbuildinfo +1 -1
  143. package/components/identity.otp/types/index.d.ts +3 -0
  144. package/components/identity.otp/types/toa.d.ts +56 -0
  145. package/components/identity.passkeys/manifest.toa.yaml +3 -0
  146. package/components/identity.passkeys/operations/authenticate.d.ts +1 -1
  147. package/components/identity.passkeys/operations/challenge.d.ts +1 -1
  148. package/components/identity.passkeys/operations/create.d.ts +1 -1
  149. package/components/identity.passkeys/operations/types/Context.d.ts +2 -1
  150. package/components/identity.passkeys/operations/use.d.ts +1 -1
  151. package/components/identity.passkeys/source/authenticate.ts +1 -1
  152. package/components/identity.passkeys/source/challenge.ts +1 -1
  153. package/components/identity.passkeys/source/create.ts +1 -1
  154. package/components/identity.passkeys/source/types/Context.ts +2 -1
  155. package/components/identity.passkeys/source/use.ts +1 -1
  156. package/components/identity.passkeys/tsconfig.tsbuildinfo +1 -1
  157. package/components/identity.passkeys/types/index.d.ts +3 -0
  158. package/components/identity.passkeys/types/toa.d.ts +120 -0
  159. package/components/identity.roles/operations/principal.d.ts +1 -1
  160. package/components/identity.roles/source/principal.ts +1 -1
  161. package/components/identity.roles/tsconfig.tsbuildinfo +1 -1
  162. package/components/identity.roles/types/index.d.ts +3 -0
  163. package/components/identity.roles/types/toa.d.ts +43 -0
  164. package/components/identity.tokens/manifest.toa.yaml +34 -3
  165. package/components/identity.tokens/operations/authenticate.d.ts +2 -1
  166. package/components/identity.tokens/operations/authenticate.js +8 -0
  167. package/components/identity.tokens/operations/authenticate.js.map +1 -1
  168. package/components/identity.tokens/operations/decrypt.d.ts +2 -1
  169. package/components/identity.tokens/operations/decrypt.js +2 -2
  170. package/components/identity.tokens/operations/decrypt.js.map +1 -1
  171. package/components/identity.tokens/operations/encrypt.d.ts +2 -1
  172. package/components/identity.tokens/operations/encrypt.js.map +1 -1
  173. package/components/identity.tokens/operations/issue.d.ts +2 -1
  174. package/components/identity.tokens/operations/issue.js +2 -1
  175. package/components/identity.tokens/operations/issue.js.map +1 -1
  176. package/components/identity.tokens/operations/lib/form.d.ts +8 -0
  177. package/components/identity.tokens/operations/lib/form.js +24 -0
  178. package/components/identity.tokens/operations/lib/form.js.map +1 -0
  179. package/components/identity.tokens/operations/lib/index.d.ts +2 -1
  180. package/components/identity.tokens/operations/lib/index.js +1 -1
  181. package/components/identity.tokens/operations/lib/index.js.map +1 -1
  182. package/components/identity.tokens/source/authenticate.test.ts +8 -5
  183. package/components/identity.tokens/source/authenticate.ts +12 -1
  184. package/components/identity.tokens/source/decrypt.test.ts +1 -1
  185. package/components/identity.tokens/source/decrypt.ts +4 -3
  186. package/components/identity.tokens/source/encrypt.test.ts +1 -1
  187. package/components/identity.tokens/source/encrypt.ts +2 -1
  188. package/components/identity.tokens/source/issue.test.ts +71 -0
  189. package/components/identity.tokens/source/issue.ts +4 -2
  190. package/components/identity.tokens/source/lib/form.test.ts +25 -0
  191. package/components/identity.tokens/source/lib/form.ts +31 -0
  192. package/components/identity.tokens/source/lib/index.ts +2 -1
  193. package/components/identity.tokens/tsconfig.tsbuildinfo +1 -1
  194. package/components/identity.tokens/types/index.d.ts +61 -0
  195. package/components/identity.tokens/types/toa.d.ts +113 -0
  196. package/documentation/cache.md +10 -1
  197. package/documentation/consent.md +101 -0
  198. package/documentation/identity.md +3 -1
  199. package/documentation/io.md +36 -2
  200. package/documentation/oauth.md +179 -0
  201. package/documentation/protocol.md +4 -0
  202. package/features/auth.bearer.feature +120 -0
  203. package/features/cache.feature +46 -0
  204. package/features/oauth.clients.feature +195 -0
  205. package/features/oauth.discovery.feature +165 -0
  206. package/features/oauth.grants.feature +286 -0
  207. package/features/steps/Gateway.ts +6 -1
  208. package/features/steps/Parameters.ts +4 -0
  209. package/features/steps/components/echo/manifest.toa.yaml +2 -0
  210. package/features/steps/components/octets.tester/manifest.toa.yaml +2 -0
  211. package/features/steps/components/octets.tester/operations/redirect.js +6 -1
  212. package/features/steps/components/users/manifest.toa.yaml +1 -0
  213. package/package.json +8 -6
  214. package/readme.md +3 -0
  215. package/schemas/annotation.cos.yaml +30 -0
  216. package/source/Annotation.ts +23 -0
  217. package/source/Factory.ts +1 -1
  218. package/source/HTTP/Server.ts +9 -5
  219. package/source/HTTP/formats/form.ts +21 -0
  220. package/source/HTTP/formats/index.ts +17 -2
  221. package/source/HTTP/messages.test.ts +25 -1
  222. package/source/HTTP/messages.ts +10 -3
  223. package/source/Interception.ts +8 -2
  224. package/source/deployment.ts +4 -1
  225. package/source/directives/auth/Authorization.ts +46 -19
  226. package/source/directives/auth/Incept.ts +14 -9
  227. package/source/directives/auth/schemes.test.ts +8 -4
  228. package/source/directives/auth/schemes.ts +22 -9
  229. package/source/directives/auth/types.ts +5 -2
  230. package/source/directives/cache/Cache.ts +13 -4
  231. package/source/directives/cache/Control.ts +0 -3
  232. package/source/directives/flow/Fetch.ts +1 -1
  233. package/source/directives/index.ts +2 -1
  234. package/source/directives/io/IO.ts +2 -0
  235. package/source/directives/io/Output.ts +4 -1
  236. package/source/directives/io/Status.test.ts +84 -0
  237. package/source/directives/io/Status.ts +46 -0
  238. package/source/directives/oauth/Discovery.ts +76 -0
  239. package/source/directives/oauth/documents.ts +113 -0
  240. package/source/directives/oauth/index.ts +3 -0
  241. package/source/directives/octets/Delete.ts +1 -1
  242. package/source/directives/octets/Get.ts +1 -1
  243. package/source/directives/octets/Workflow.ts +1 -1
  244. package/source/directives/octets/workflows/Execution.ts +1 -1
  245. package/source/index.ts +6 -0
  246. package/source/octets.d.ts +17 -0
  247. package/source/userland.ts +47 -0
  248. package/transpiled/Annotation.d.ts +17 -0
  249. package/transpiled/Factory.js +1 -1
  250. package/transpiled/Factory.js.map +1 -1
  251. package/transpiled/HTTP/Server.d.ts +4 -1
  252. package/transpiled/HTTP/Server.js +4 -3
  253. package/transpiled/HTTP/Server.js.map +1 -1
  254. package/transpiled/HTTP/formats/form.d.ts +9 -0
  255. package/transpiled/HTTP/formats/form.js +18 -0
  256. package/transpiled/HTTP/formats/form.js.map +1 -0
  257. package/transpiled/HTTP/formats/index.d.ts +10 -2
  258. package/transpiled/HTTP/formats/index.js +10 -0
  259. package/transpiled/HTTP/formats/index.js.map +1 -1
  260. package/transpiled/HTTP/messages.d.ts +6 -0
  261. package/transpiled/HTTP/messages.js +3 -3
  262. package/transpiled/HTTP/messages.js.map +1 -1
  263. package/transpiled/Interception.d.ts +4 -1
  264. package/transpiled/Interception.js +4 -2
  265. package/transpiled/Interception.js.map +1 -1
  266. package/transpiled/deployment.js +2 -0
  267. package/transpiled/deployment.js.map +1 -1
  268. package/transpiled/directives/auth/Authorization.d.ts +1 -1
  269. package/transpiled/directives/auth/Authorization.js +38 -18
  270. package/transpiled/directives/auth/Authorization.js.map +1 -1
  271. package/transpiled/directives/auth/Incept.d.ts +1 -1
  272. package/transpiled/directives/auth/Incept.js +11 -7
  273. package/transpiled/directives/auth/Incept.js.map +1 -1
  274. package/transpiled/directives/auth/schemes.d.ts +16 -4
  275. package/transpiled/directives/auth/schemes.js +20 -8
  276. package/transpiled/directives/auth/schemes.js.map +1 -1
  277. package/transpiled/directives/auth/types.d.ts +4 -2
  278. package/transpiled/directives/cache/Cache.js +9 -2
  279. package/transpiled/directives/cache/Cache.js.map +1 -1
  280. package/transpiled/directives/cache/Control.js +0 -2
  281. package/transpiled/directives/cache/Control.js.map +1 -1
  282. package/transpiled/directives/index.js +2 -1
  283. package/transpiled/directives/index.js.map +1 -1
  284. package/transpiled/directives/io/IO.js +2 -0
  285. package/transpiled/directives/io/IO.js.map +1 -1
  286. package/transpiled/directives/io/Output.js +4 -1
  287. package/transpiled/directives/io/Output.js.map +1 -1
  288. package/transpiled/directives/io/Status.d.ts +19 -0
  289. package/transpiled/directives/io/Status.js +34 -0
  290. package/transpiled/directives/io/Status.js.map +1 -0
  291. package/transpiled/directives/oauth/Discovery.d.ts +23 -0
  292. package/transpiled/directives/oauth/Discovery.js +58 -0
  293. package/transpiled/directives/oauth/Discovery.js.map +1 -0
  294. package/transpiled/directives/oauth/documents.d.ts +9 -0
  295. package/transpiled/directives/oauth/documents.js +82 -0
  296. package/transpiled/directives/oauth/documents.js.map +1 -0
  297. package/transpiled/directives/oauth/index.d.ts +2 -0
  298. package/transpiled/directives/oauth/index.js +3 -0
  299. package/transpiled/directives/oauth/index.js.map +1 -0
  300. package/transpiled/index.d.ts +2 -0
  301. package/transpiled/userland.d.ts +39 -0
  302. package/transpiled/userland.js +7 -0
  303. package/transpiled/userland.js.map +1 -0
  304. package/tsconfig.tsbuildinfo +1 -1
  305. package/components/identity.basic/operations/types.d.ts +0 -61
  306. package/components/identity.basic/operations/types.js +0 -2
  307. package/components/identity.basic/operations/types.js.map +0 -1
  308. package/components/identity.basic/source/types.ts +0 -69
  309. package/components/identity.tokens/operations/lib/types.d.ts +0 -88
  310. package/components/identity.tokens/operations/lib/types.js +0 -2
  311. package/components/identity.tokens/operations/lib/types.js.map +0 -1
  312. package/components/identity.tokens/source/lib/types.ts +0 -102
@@ -1,5 +1,5 @@
1
1
  import { type Component } from '@toa.io/core'
2
- import { type Maybe } from '@toa.io/types'
2
+ import { type Maybe } from '@toa.io/core'
3
3
  import { type Parameter } from '../../RTD/index.js'
4
4
  import type * as http from '../../HTTP/index.js'
5
5
  import type * as io from '../../io.js'
@@ -23,6 +23,9 @@ export interface Identity {
23
23
  roles?: string[]
24
24
  permissions?: Record<string, string[]>
25
25
  scheme: string | null // null for transient identities
26
+
27
+ /** The component that verified the credentials; none for a transient identity. */
28
+ provider?: Remote
26
29
  refresh: boolean
27
30
  }
28
31
 
@@ -43,6 +46,6 @@ export type AuthenticationResult = Maybe<{ identity: Identity, refresh: boolean
43
46
  export type Scheme = 'basic' | 'token' | 'bearer' | 'code' | 'otp'
44
47
  export type Remote = 'basic' | 'federation' | 'tokens' | 'roles' | 'bans' | 'otp'
45
48
  export type Discovery = Record<Remote, Promise<Component>>
46
- export type Schemes = Record<Scheme, Component>
49
+ export type Components = Partial<Record<Remote, Component>>
47
50
 
48
51
  export type Create = (name: string, value: any, ...args: any[]) => Directive
@@ -23,14 +23,23 @@ export class Cache implements DirectiveFamily<Directive> {
23
23
  }
24
24
 
25
25
  public async settle (directives: Directive[], context: AuthenticatedContext, response: http.OutgoingMessage): Promise<void> {
26
- const method = context.request.method
26
+ const directive = directives[0]
27
+
28
+ response.headers ??= new Headers()
29
+
30
+ // `cache:exact` sets what it is given, whatever the method: whether a reply may be
31
+ // stored at all is not a question about the method's cacheability, and a token
32
+ // endpoint answers a POST it must not have kept
33
+ if (directive instanceof Exact) {
34
+ directive.set(context, response.headers)
27
35
 
28
- if (method !== 'GET' && method !== 'HEAD')
29
36
  return
37
+ }
30
38
 
31
- const directive = directives[0]
39
+ const method = context.request.method
32
40
 
33
- response.headers ??= new Headers()
41
+ if (method !== 'GET' && method !== 'HEAD')
42
+ return
34
43
 
35
44
  if (directive === undefined) {
36
45
  if (context.identity !== null && !Control.disabled(response.headers)) {
@@ -22,9 +22,6 @@ export class Control implements Directive {
22
22
  }
23
23
 
24
24
  public set (context: AuthenticatedContext, headers: Headers): void {
25
- if (!['GET', 'HEAD', 'OPTIONS'].includes(context.request.method))
26
- return
27
-
28
25
  this.control ??= this.resolve(context)
29
26
 
30
27
  if (Control.disabled(headers))
@@ -5,7 +5,7 @@ import { NotFound } from '../../HTTP/index.js'
5
5
  import type { Directive } from './types.js'
6
6
  import type { ReadableStream } from 'node:stream/web'
7
7
  import type { Remotes } from '../../Remotes.js'
8
- import type { Maybe } from '@toa.io/types'
8
+ import type { Maybe } from '@toa.io/core'
9
9
  import type { Component } from '@toa.io/core'
10
10
  import type { Output } from '../../io.js'
11
11
  import type { Input } from '../octets/types.js'
@@ -7,8 +7,9 @@ import { io } from './io/index.js'
7
7
  import { map } from './map/index.js'
8
8
  import { req } from './require/index.js'
9
9
  import { flow } from './flow/index.js'
10
+ import { discovery } from './oauth/index.js'
10
11
  import type { DirectiveFamily } from '../RTD/index.js'
11
12
  import type { Interceptor } from '../Interception.js'
12
13
 
13
14
  export const families: DirectiveFamily[] = [authorization, io, cache, map, req, flow, octets, dev]
14
- export const interceptors: Interceptor[] = [cors]
15
+ export const interceptors: Interceptor[] = [cors, discovery]
@@ -1,6 +1,7 @@
1
1
  import { Output } from './Output.js'
2
2
  import { Input } from './Input.js'
3
3
  import { Throttle } from './Throttle.js'
4
+ import { Status } from './Status.js'
4
5
  import { Sync } from './lib/throttle/index.js'
5
6
  import type * as http from '../../HTTP/index.js'
6
7
  import type { Parameter, DirectiveFamily } from '../../RTD/index.js'
@@ -72,6 +73,7 @@ export class IO implements DirectiveFamily<Directive> {
72
73
  const constructors: Record<string, Constructor> = {
73
74
  input: Input,
74
75
  output: Output,
76
+ status: Status,
75
77
  throttle: Throttle
76
78
  }
77
79
 
@@ -35,7 +35,10 @@ export class Output implements Directive {
35
35
 
36
36
  private restriction (context: Context) {
37
37
  return (message: OutgoingMessage): void => {
38
- const error = message.status !== undefined && message.status >= 300
38
+ // what the gateway built is its own — a code and a message — and a restriction has
39
+ // nothing to say about it; everything else is a reply the operation returned, and is
40
+ // restricted whatever status it carries
41
+ const error = message.authentic === true
39
42
  const stream = message.body instanceof Stream
40
43
  const none = message.body === undefined || message.body === null
41
44
 
@@ -0,0 +1,84 @@
1
+ import { it } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+
4
+ import { Status } from './Status.js'
5
+ import { Output } from './Output.js'
6
+ import type { Input as Context } from '../../io.js'
7
+ import type { OutgoingMessage } from '../../HTTP/index.js'
8
+
9
+ const status = new Status('status')
10
+
11
+ function context (): Context {
12
+ return { pipelines: { body: [], response: [] }, url: { pathname: '/' } } as unknown as Context
13
+ }
14
+
15
+ it('should take the status from the property and remove it', () => {
16
+ const response: OutgoingMessage = { body: { status: 400, error: 'invalid_request' } }
17
+
18
+ status.settle(context(), response)
19
+
20
+ assert.equal(response.status, 400)
21
+ assert.deepEqual(response.body, { error: 'invalid_request' })
22
+ })
23
+
24
+ it('should leave a reply that states no status alone', () => {
25
+ const response: OutgoingMessage = { body: { id: 'x' } }
26
+
27
+ status.settle(context(), response)
28
+
29
+ assert.equal(response.status, undefined)
30
+ assert.deepEqual(response.body, { id: 'x' })
31
+ })
32
+
33
+ it('should refuse a status that is not one', () => {
34
+ for (const value of ['400', null, {}, true])
35
+ assert.throws(() => {
36
+ status.settle(context(), { body: { status: value } } as OutgoingMessage)
37
+ }, /`io:status` expects 'status' to be a number/)
38
+ })
39
+
40
+ it('should refuse a declaration that is not a property name', () => {
41
+ for (const value of [1, null, {}, ['status']])
42
+ assert.throws(() => Status.validate(value), /`io:status` must be a string/)
43
+ })
44
+
45
+ it('should have a reply it named the status of restricted, whatever that status is', () => {
46
+ for (const stated of [200, 400]) {
47
+ const ctx = context()
48
+ const output = new Output(['code', 'error'])
49
+
50
+ output.preflight(ctx, [])
51
+
52
+ const response: OutgoingMessage = {
53
+ body: { status: stated, code: 'SplxlO', error: 'invalid_grant', secret: 'x' }
54
+ }
55
+
56
+ status.settle(ctx, response)
57
+
58
+ for (const transform of ctx.pipelines.response)
59
+ transform(response)
60
+
61
+ assert.equal(response.status, stated)
62
+ assert.deepEqual(response.body, { code: 'SplxlO', error: 'invalid_grant' })
63
+ }
64
+ })
65
+
66
+ it('should leave a failure the gateway built alone, on such a route too', () => {
67
+ const ctx = context()
68
+ const output = new Output(['code'])
69
+
70
+ output.preflight(ctx, [])
71
+
72
+ // what `Server.fail` builds out of an exception, on a route that also declares `io:status`
73
+ const response: OutgoingMessage = {
74
+ status: 422,
75
+ authentic: true,
76
+ body: { code: 'NOT_FOUND', message: 'nope' }
77
+ }
78
+
79
+ for (const transform of ctx.pipelines.response)
80
+ transform(response)
81
+
82
+ assert.deepEqual(response.body, { code: 'NOT_FOUND', message: 'nope' },
83
+ 'a code and a message are not what a restriction has anything to say about')
84
+ })
@@ -0,0 +1,46 @@
1
+ import assert from 'node:assert'
2
+ import type { Directive } from './Directive.js'
3
+ import type * as http from '../../HTTP/index.js'
4
+
5
+ /**
6
+ * The status of the reply, taken from a property of what the operation returned and removed
7
+ * from it — an outcome the operation knows and the transport does not, like a protocol that
8
+ * states its error as a body rather than as a status of its own.
9
+ *
10
+ * Settled rather than transformed, so the status is set before anything reads it. A reply of
11
+ * 300 or above is left as the operation built it, which `io:output` does not restrict: a
12
+ * failure and a success are different shapes, and one list of permitted properties does not
13
+ * describe both.
14
+ */
15
+ export class Status implements Directive {
16
+ private readonly property: string
17
+
18
+ public constructor (property: unknown) {
19
+ this.property = property as string
20
+ }
21
+
22
+ public static validate (value: unknown): asserts value is string {
23
+ assert.ok(typeof value === 'string', '`io:status` must be a string')
24
+ }
25
+
26
+ public preflight (): void {
27
+ // nothing to do until the operation has answered
28
+ }
29
+
30
+ public settle (_: unknown, response: http.OutgoingMessage): void {
31
+ const body: unknown = response.body
32
+
33
+ if (body === null || typeof body !== 'object' || !(this.property in body))
34
+ return
35
+
36
+ const value: unknown = (body as Record<string, unknown>)[this.property]
37
+
38
+ assert.ok(typeof value === 'number',
39
+ `\`io:status\` expects '${this.property}' to be a number`)
40
+
41
+ response.status = value
42
+
43
+ // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
44
+ delete (body as Record<string, unknown>)[this.property]
45
+ }
46
+ }
@@ -0,0 +1,76 @@
1
+ import { documents, type Documents } from './documents.js'
2
+ import type * as http from '../../HTTP/index.js'
3
+ import type { Input, Output } from '../../io.js'
4
+ import type { Interceptor } from '../../Interception.js'
5
+
6
+ /**
7
+ * What a client reads before it can authenticate: where the authorization server is, and
8
+ * what this resource expects. Both are fixed paths a specification names, both must be
9
+ * answered to anyone, and both are a function of the annotation alone — nothing is read to
10
+ * build them, so they are built once per authority and served as they are.
11
+ *
12
+ * An interceptor rather than a route because `auth` runs before any directive: a client
13
+ * re-reading discovery while holding a stale token would have it verified, and then be
14
+ * refused a document that has to be public.
15
+ */
16
+ export class Discovery implements Interceptor {
17
+ /**
18
+ * A map, because the key is the request's authority and an unconfigured host is passed
19
+ * through as itself: `Host: constructor` names something a plain object answers on its own.
20
+ */
21
+ private readonly authorities = new Map<string, Documents>()
22
+
23
+ public mount (options: http.Options): void {
24
+ this.authorities.clear()
25
+
26
+ if (options.oauth === undefined)
27
+ return
28
+
29
+ for (const [authority, host] of Object.entries(options.authorities))
30
+ this.authorities.set(authority, documents(origin(host), options.oauth))
31
+ }
32
+
33
+ public reset (): void {
34
+ this.authorities.clear()
35
+ }
36
+
37
+ public intercept (input: Input): Output {
38
+ const known = this.authorities.get(input.authority)
39
+
40
+ if (known === undefined)
41
+ return null
42
+
43
+ // every reply, not just a document's: the challenge is what points a client here
44
+ input.pipelines.response.push((response) => {
45
+ if (response.status !== UNAUTHORIZED)
46
+ return
47
+
48
+ response.headers ??= new Headers()
49
+ response.headers.set('www-authenticate', known.challenge(input.url.pathname))
50
+ })
51
+
52
+ const body = known.read(input.url.pathname)
53
+
54
+ if (body === undefined)
55
+ return null
56
+
57
+ return { body, headers: new Headers({ 'cache-control': 'public, max-age=3600' }) }
58
+ }
59
+ }
60
+
61
+ /**
62
+ * The absolute URL an authority is reached at. Loopback is served over http and everything
63
+ * else over https: the gateway may sit behind a terminating proxy, so the connection does
64
+ * not say which, and the configured host does. Taken from the configuration rather than
65
+ * from the request's `host`, which is the client's to write.
66
+ */
67
+ function origin (host: string): string {
68
+ const name = host.split(':')[0]
69
+
70
+ const loopback = name === 'localhost' || name === '127.0.0.1' || name === '[::1]' ||
71
+ name.endsWith('.localhost')
72
+
73
+ return `${loopback ? 'http' : 'https'}://${host}`
74
+ }
75
+
76
+ const UNAUTHORIZED = 401
@@ -0,0 +1,113 @@
1
+ import type { OAuth } from '../../Annotation.js'
2
+
3
+ /** The discovery documents of one authority, and the challenge that points at them. */
4
+ export interface Documents {
5
+ /** The document a path names, or nothing when it names none. */
6
+ read: (pathname: string) => object | undefined
7
+
8
+ /** `WWW-Authenticate` for a request to this path, which names the resource it failed at. */
9
+ challenge: (pathname: string) => string
10
+ }
11
+
12
+ export function documents (issuer: string, oauth: OAuth): Documents {
13
+ const server = authorizationServer(issuer, oauth)
14
+ const resources = protectedResources(issuer, oauth)
15
+ const scope = oauth.scopes === undefined ? '' : `, scope="${oauth.scopes.join(' ')}"`
16
+
17
+ function read (pathname: string): object | undefined {
18
+ if (pathname === AUTHORIZATION_SERVER || pathname === OPENID_CONFIGURATION)
19
+ return server
20
+
21
+ if (pathname.startsWith(PROTECTED_RESOURCE))
22
+ return resources.get(pathname.slice(PROTECTED_RESOURCE.length))
23
+
24
+ return undefined
25
+ }
26
+
27
+ function challenge (pathname: string): string {
28
+ return `Bearer resource_metadata="${issuer}${PROTECTED_RESOURCE}${suffix(oauth, pathname)}"${scope}`
29
+ }
30
+
31
+ return { read, challenge }
32
+ }
33
+
34
+ /**
35
+ * RFC 8414. `authorization_endpoint` is the application's own page and may be anywhere;
36
+ * everything else this extension serves. Both flags are load-bearing for a client that
37
+ * prefers Client ID Metadata Documents: without either it falls back to registration.
38
+ */
39
+ function authorizationServer (issuer: string, oauth: OAuth): object {
40
+ const metadata: Record<string, unknown> = {
41
+ issuer,
42
+ authorization_endpoint: oauth.authorize,
43
+ token_endpoint: `${issuer}${TOKEN}`,
44
+ response_types_supported: ['code'],
45
+ grant_types_supported: ['authorization_code'],
46
+ code_challenge_methods_supported: ['S256'],
47
+ token_endpoint_auth_methods_supported: ['none'],
48
+ client_id_metadata_document_supported: true,
49
+ authorization_response_iss_parameter_supported: true
50
+ }
51
+
52
+ if (oauth.registration === 'open')
53
+ metadata.registration_endpoint = `${issuer}${REGISTRATION}`
54
+
55
+ if (oauth.scopes !== undefined)
56
+ metadata.scopes_supported = oauth.scopes
57
+
58
+ return metadata
59
+ }
60
+
61
+ /**
62
+ * RFC 9728, keyed by the path the well-known segment is followed by: a client resolving
63
+ * `https://host/mcp` reads `/.well-known/oauth-protected-resource/mcp`, and one that names
64
+ * no path reads the document at the origin.
65
+ */
66
+ function protectedResources (issuer: string, oauth: OAuth): Map<string, object> {
67
+ const map = new Map<string, object>()
68
+
69
+ for (const path of oauth.resources ?? [])
70
+ map.set(canonical(path), resource(issuer, canonical(path), oauth))
71
+
72
+ map.set('', resource(issuer, '', oauth))
73
+
74
+ return map
75
+ }
76
+
77
+ function resource (issuer: string, path: string, oauth: OAuth): object {
78
+ const metadata: Record<string, unknown> = {
79
+ resource: issuer + path,
80
+ authorization_servers: [issuer],
81
+ bearer_methods_supported: ['header']
82
+ }
83
+
84
+ if (oauth.scopes !== undefined)
85
+ metadata.scopes_supported = oauth.scopes
86
+
87
+ return metadata
88
+ }
89
+
90
+ /** The document a request to this path was refused against: the longest resource holding it. */
91
+ function suffix (oauth: OAuth, pathname: string): string {
92
+ let longest = ''
93
+
94
+ for (const path of oauth.resources ?? [])
95
+ if (pathname.startsWith(path) && path.length > longest.length)
96
+ longest = path
97
+
98
+ return canonical(longest)
99
+ }
100
+
101
+ /**
102
+ * A resource is identified without its trailing slash — the form MCP asks for — while a
103
+ * route is declared with one, so `/mcp/` identifies `…/mcp`.
104
+ */
105
+ function canonical (path: string): string {
106
+ return path.endsWith('/') ? path.slice(0, -1) : path
107
+ }
108
+
109
+ const AUTHORIZATION_SERVER = '/.well-known/oauth-authorization-server'
110
+ const PROTECTED_RESOURCE = '/.well-known/oauth-protected-resource'
111
+ const OPENID_CONFIGURATION = '/.well-known/openid-configuration'
112
+ const TOKEN = '/identity/grants/'
113
+ const REGISTRATION = '/identity/clients/'
@@ -0,0 +1,3 @@
1
+ import { Discovery } from './Discovery.js'
2
+
3
+ export const discovery = new Discovery()
@@ -5,7 +5,7 @@ import { Workflow } from './workflows/index.js'
5
5
  import { Directive } from './Directive.js'
6
6
  import type { Parameter } from '../../RTD/index.js'
7
7
  import type { Unit, Location } from './workflows/index.js'
8
- import type { Maybe } from '@toa.io/types'
8
+ import type { Maybe } from '@toa.io/core'
9
9
  import type { Component } from '@toa.io/core'
10
10
  import type { Output } from '../../io.js'
11
11
  import type { Input } from './types.js'
@@ -1,7 +1,7 @@
1
1
  import { Forbidden, NotFound } from '../../HTTP/index.js'
2
2
  import * as schemas from './schemas.js'
3
3
  import { Directive } from './Directive.js'
4
- import type { Maybe } from '@toa.io/types'
4
+ import type { Maybe } from '@toa.io/core'
5
5
  import type { Entry, Stream } from '@toa.io/extensions.storages'
6
6
  import type { Component } from '@toa.io/core'
7
7
  import type { Output } from '../../io.js'
@@ -7,7 +7,7 @@ import type { Input } from './types.js'
7
7
  import type { Component } from '@toa.io/core'
8
8
  import type { Output } from '../../io.js'
9
9
  import type { Remotes } from '../../Remotes.js'
10
- import type { Maybe } from '@toa.io/types'
10
+ import type { Maybe } from '@toa.io/core'
11
11
  import type { Entry } from '@toa.io/extensions.storages'
12
12
  import type { Parameter } from '../../RTD/index.js'
13
13
 
@@ -3,7 +3,7 @@ import { console } from 'openspan'
3
3
  import type { Unit } from './Workflow.js'
4
4
  import type { Remotes } from '../../../Remotes.js'
5
5
  import type { Component } from '@toa.io/core'
6
- import type { Maybe } from '@toa.io/types'
6
+ import type { Maybe } from '@toa.io/core'
7
7
  import type { Entry } from '@toa.io/extensions.storages'
8
8
 
9
9
  export class Execution extends Readable {
package/source/index.ts CHANGED
@@ -4,3 +4,9 @@ export { components } from './Composition.js'
4
4
  export { Factory } from './Factory.js'
5
5
 
6
6
  export type { Remotes } from './Remotes.js'
7
+
8
+ // what an operation is written against, rather than the gateway's own
9
+ export type { Claims, Identity } from './userland.js'
10
+
11
+ // what an octets workflow is given
12
+ export type * as octets from './octets.js'
@@ -0,0 +1,17 @@
1
+ export interface WorkflowInput<
2
+ TParameters extends Record<string, string> = Record<string, string>,
3
+ TSteps extends Record<string, unknown> = Record<string, unknown>,
4
+ > {
5
+ authority: string
6
+ identity?: string
7
+ storage: string
8
+ path: string
9
+ entry: {
10
+ id: string
11
+ type: string
12
+ size: number
13
+ meta: Record<string, unknown>
14
+ }
15
+ parameters: TParameters
16
+ steps: TSteps
17
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * What Exposition puts into an operation's input, for the operation to be written against.
3
+ *
4
+ * The gateway's own types are its business; these are the application's.
5
+ */
6
+
7
+ /**
8
+ * The identity behind the call, as `auth:delegate` embeds it:
9
+ *
10
+ * ```yaml
11
+ * /echo:
12
+ * GET:
13
+ * auth:assert: true
14
+ * auth:delegate: identity
15
+ * endpoint: echo
16
+ * ```
17
+ *
18
+ * ```javascript
19
+ * export async function computation ({ identity }, context) { }
20
+ * ```
21
+ */
22
+ export interface Identity {
23
+ readonly id: string
24
+
25
+ /** What the identity holds. Delegation resolves them, so they are always here. */
26
+ roles: string[]
27
+
28
+ permissions?: Record<string, string[]>
29
+
30
+ /** How the identity was authenticated; `null` for a transient one. */
31
+ scheme: string | null
32
+
33
+ /** Whether the credentials presented are due to be exchanged. */
34
+ refresh: boolean
35
+
36
+ /** The token's claims, where the identity was federated. */
37
+ claims?: Claims
38
+ }
39
+
40
+ /** A federated token's payload: what it must carry, and whatever else the issuer put there. */
41
+ export interface Claims {
42
+ iss: string
43
+ sub: string
44
+ aud?: string | string[]
45
+
46
+ [claim: string]: unknown
47
+ }
@@ -19,8 +19,25 @@ export interface Annotation {
19
19
  ip?: string;
20
20
  /** Failed authentications an address may make; none are metered unless set. See `identity.md`. */
21
21
  bouncer?: Bouncer;
22
+ /** The authorization server this context exposes; none is exposed without it. */
23
+ oauth?: OAuth;
22
24
  '/'?: object;
23
25
  }
26
+ export interface OAuth {
27
+ /**
28
+ * Where a client sends the user to consent. The one endpoint of the flow that needs a
29
+ * person, and so the one this extension does not serve: an application builds it.
30
+ */
31
+ authorize: string;
32
+ /** Paths a token may be restricted to, each advertised as a protected resource. */
33
+ resources?: string[];
34
+ /** What a client may ask for. Each is a role, or a scope within one. */
35
+ scopes?: string[];
36
+ /** Origins whose Client ID Metadata Documents may be read. None are without it. */
37
+ trust?: string[];
38
+ /** Dynamic Client Registration, off unless opened. */
39
+ registration?: 'open' | 'closed';
40
+ }
24
41
  export interface Bouncer {
25
42
  /** what an address may fail at once, 20 by default */
26
43
  attempts?: number;
@@ -41,7 +41,7 @@ export class Factory {
41
41
  const node = root.resolve();
42
42
  const methods = new EndpointsFactory(remotes);
43
43
  const directives = new DirectivesFactory(families, remotes, this.host, options);
44
- const interception = new Interception(interceptors);
44
+ const interception = new Interception(interceptors, options);
45
45
  const tree = new Tree(node, methods, directives);
46
46
  const composition = new Composition(this.host);
47
47
  const gateway = new Gateway(broadcast, tree, interception);
@@ -1 +1 @@
1
- {"version":3,"file":"Factory.js","sourceRoot":"","sources":["../source/Factory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Factory.js","sourceRoot":"","sources":["../source/Factory.ts"],"names":[],"mappings":"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"}
@@ -2,10 +2,11 @@ import { Connector } from '@toa.io/core';
2
2
  import { type OutgoingMessage } from './messages.js';
3
3
  import { Context } from './Context.js';
4
4
  import type { Protocol } from './types.js';
5
- import type { Bouncer } from '../Annotation.js';
5
+ import type { Bouncer, OAuth } from '../Annotation.js';
6
6
  export declare class Server extends Connector {
7
7
  private readonly server;
8
8
  private readonly properties;
9
+ /** Host to authority. A map: a `Host` of `constructor` names what a plain object answers. */
9
10
  private readonly authorities;
10
11
  /** Tracked for the drain: `Http2Server` has no `closeIdleConnections`. */
11
12
  private readonly sessions;
@@ -40,6 +41,8 @@ interface Properties {
40
41
  ip?: string;
41
42
  /** Failed authentications an address may make; none are metered unless set. */
42
43
  bouncer?: Bouncer;
44
+ /** The authorization server this context exposes; none is exposed without it. */
45
+ oauth?: OAuth;
43
46
  }
44
47
  export type Options = {
45
48
  authorities: Properties['authorities'];