@toa.io/extensions.exposition 1.0.0-alpha.12 → 1.0.0-alpha.121

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 (623) hide show
  1. package/components/context.toa.yaml +2 -2
  2. package/components/identity.bans/manifest.toa.yaml +14 -6
  3. package/components/identity.bans/operations/transit.d.ts +14 -0
  4. package/components/identity.bans/operations/transit.js +11 -0
  5. package/components/identity.bans/operations/transit.js.map +1 -0
  6. package/components/identity.bans/operations/tsconfig.tsbuildinfo +1 -0
  7. package/components/identity.bans/source/transit.ts +21 -0
  8. package/components/identity.bans/tsconfig.json +9 -0
  9. package/components/identity.basic/manifest.toa.yaml +28 -10
  10. package/components/identity.basic/operations/authenticate.d.ts +5 -1
  11. package/components/identity.basic/operations/authenticate.js +7 -4
  12. package/components/identity.basic/operations/authenticate.js.map +1 -1
  13. package/components/identity.basic/operations/incept.d.ts +12 -0
  14. package/components/identity.basic/operations/incept.js +26 -0
  15. package/components/identity.basic/operations/incept.js.map +1 -0
  16. package/components/identity.basic/operations/transit.d.ts +4 -4
  17. package/components/identity.basic/operations/transit.js +8 -6
  18. package/components/identity.basic/operations/transit.js.map +1 -1
  19. package/components/identity.basic/operations/tsconfig.tsbuildinfo +1 -1
  20. package/components/identity.basic/operations/types.d.ts +8 -4
  21. package/components/identity.basic/source/authenticate.ts +18 -7
  22. package/components/identity.basic/source/incept.ts +38 -0
  23. package/components/identity.basic/source/transit.ts +11 -9
  24. package/components/identity.basic/source/types.ts +8 -4
  25. package/components/identity.federation/manifest.toa.yaml +61 -19
  26. package/components/identity.federation/operations/authenticate.d.ts +13 -2
  27. package/components/identity.federation/operations/authenticate.js +10 -11
  28. package/components/identity.federation/operations/authenticate.js.map +1 -1
  29. package/components/identity.federation/operations/decode.d.ts +2 -0
  30. package/{transpiled/directives/octets/Permute.js → components/identity.federation/operations/decode.js} +7 -32
  31. package/components/identity.federation/operations/decode.js.map +1 -0
  32. package/components/identity.federation/operations/incept.d.ts +11 -0
  33. package/components/identity.federation/operations/incept.js +14 -0
  34. package/components/identity.federation/operations/incept.js.map +1 -0
  35. package/components/identity.federation/operations/lib/assertions-as-values.js +4 -2
  36. package/components/identity.federation/operations/lib/assertions-as-values.js.map +1 -1
  37. package/components/identity.federation/operations/lib/get.d.ts +1 -0
  38. package/components/identity.federation/operations/lib/get.js +64 -0
  39. package/components/identity.federation/operations/lib/get.js.map +1 -0
  40. package/components/identity.federation/operations/lib/jwt.d.ts +4 -5
  41. package/components/identity.federation/operations/lib/jwt.js +20 -16
  42. package/components/identity.federation/operations/lib/jwt.js.map +1 -1
  43. package/components/identity.federation/operations/tsconfig.tsbuildinfo +1 -1
  44. package/components/identity.federation/operations/types/configuration.d.ts +15 -0
  45. package/components/identity.federation/operations/types/configuration.js +3 -0
  46. package/components/identity.federation/operations/types/configuration.js.map +1 -0
  47. package/components/identity.federation/operations/{types.d.ts → types/context.d.ts} +11 -12
  48. package/{transpiled/directives/vary/embeddings/Embedding.js → components/identity.federation/operations/types/context.js} +1 -1
  49. package/components/identity.federation/operations/types/context.js.map +1 -0
  50. package/components/identity.federation/operations/types/entity.d.ts +6 -0
  51. package/components/identity.federation/operations/types/entity.js +3 -0
  52. package/components/identity.federation/operations/types/entity.js.map +1 -0
  53. package/components/identity.federation/operations/types/index.d.ts +3 -0
  54. package/components/identity.federation/operations/types/index.js +20 -0
  55. package/components/identity.federation/operations/types/index.js.map +1 -0
  56. package/components/identity.federation/source/authenticate.ts +24 -17
  57. package/components/identity.federation/source/decode.ts +9 -0
  58. package/components/identity.federation/source/incept.ts +26 -0
  59. package/components/identity.federation/source/lib/assertions-as-values.ts +5 -2
  60. package/components/identity.federation/source/lib/get.ts +82 -0
  61. package/components/identity.federation/source/lib/jwt.test.ts +127 -4
  62. package/components/identity.federation/source/lib/jwt.ts +26 -19
  63. package/components/identity.federation/source/types/configuration.ts +16 -0
  64. package/components/identity.federation/source/{types.ts → types/context.ts} +12 -12
  65. package/components/identity.federation/source/types/entity.ts +6 -0
  66. package/components/identity.federation/source/types/index.ts +3 -0
  67. package/components/identity.federation/tsconfig.json +5 -4
  68. package/components/identity.keys/manifest.toa.yaml +54 -0
  69. package/components/identity.keys/operations/create.d.ts +22 -0
  70. package/components/identity.keys/operations/create.js +16 -0
  71. package/components/identity.keys/operations/create.js.map +1 -0
  72. package/components/identity.keys/operations/tsconfig.tsbuildinfo +1 -0
  73. package/components/identity.keys/source/create.ts +35 -0
  74. package/components/identity.keys/tsconfig.json +9 -0
  75. package/components/identity.roles/manifest.toa.yaml +7 -5
  76. package/components/identity.roles/operations/grant.d.ts +1 -1
  77. package/components/identity.roles/operations/grant.js +8 -7
  78. package/components/identity.roles/operations/grant.js.map +1 -1
  79. package/components/identity.roles/operations/lib/Entity.d.ts +1 -1
  80. package/components/identity.roles/operations/tsconfig.tsbuildinfo +1 -1
  81. package/components/identity.roles/source/grant.ts +9 -8
  82. package/components/identity.roles/source/lib/Entity.ts +1 -1
  83. package/components/identity.tokens/manifest.toa.yaml +103 -9
  84. package/components/identity.tokens/operations/authenticate.d.ts +3 -3
  85. package/components/identity.tokens/operations/authenticate.js +20 -13
  86. package/components/identity.tokens/operations/authenticate.js.map +1 -1
  87. package/components/identity.tokens/operations/decrypt.d.ts +12 -3
  88. package/components/identity.tokens/operations/decrypt.js +62 -17
  89. package/components/identity.tokens/operations/decrypt.js.map +1 -1
  90. package/components/identity.tokens/operations/encrypt.d.ts +3 -3
  91. package/components/identity.tokens/operations/encrypt.js +26 -6
  92. package/components/identity.tokens/operations/encrypt.js.map +1 -1
  93. package/components/identity.tokens/operations/issue.d.ts +24 -0
  94. package/components/identity.tokens/operations/issue.js +58 -0
  95. package/components/identity.tokens/operations/issue.js.map +1 -0
  96. package/components/identity.tokens/operations/lib/index.d.ts +2 -0
  97. package/components/identity.tokens/operations/lib/index.js +19 -0
  98. package/components/identity.tokens/operations/lib/index.js.map +1 -0
  99. package/components/identity.tokens/operations/lib/pad.d.ts +1 -0
  100. package/components/identity.tokens/operations/lib/pad.js +5 -0
  101. package/components/identity.tokens/operations/lib/pad.js.map +1 -0
  102. package/components/identity.tokens/operations/lib/types.d.ts +74 -0
  103. package/components/identity.tokens/operations/lib/types.js.map +1 -0
  104. package/components/identity.tokens/operations/revoke.d.ts +2 -2
  105. package/components/identity.tokens/operations/revoke.js.map +1 -1
  106. package/components/identity.tokens/operations/tsconfig.tsbuildinfo +1 -1
  107. package/components/identity.tokens/receivers/identity.bans.created.js +3 -0
  108. package/components/identity.tokens/source/authenticate.test.ts +22 -9
  109. package/components/identity.tokens/source/authenticate.ts +23 -15
  110. package/components/identity.tokens/source/decrypt.test.ts +33 -18
  111. package/components/identity.tokens/source/decrypt.ts +91 -20
  112. package/components/identity.tokens/source/encrypt.test.ts +67 -12
  113. package/components/identity.tokens/source/encrypt.ts +37 -9
  114. package/components/identity.tokens/source/issue.ts +80 -0
  115. package/components/identity.tokens/source/lib/index.ts +2 -0
  116. package/components/identity.tokens/source/lib/pad.ts +1 -0
  117. package/components/identity.tokens/source/lib/paseto.test.ts +16 -0
  118. package/components/identity.tokens/source/lib/types.ts +85 -0
  119. package/components/identity.tokens/source/revoke.ts +2 -2
  120. package/components/octets.storage/manifest.toa.yaml +11 -11
  121. package/components/octets.storage/operations/get.js +3 -3
  122. package/components/octets.storage/operations/head.js +7 -0
  123. package/components/octets.storage/operations/put.js +135 -0
  124. package/documentation/access.md +91 -29
  125. package/documentation/authorities.md +48 -0
  126. package/documentation/cache.md +8 -1
  127. package/documentation/components.md +125 -54
  128. package/documentation/dev.md +30 -0
  129. package/documentation/flow.md +44 -0
  130. package/documentation/identity.md +29 -22
  131. package/documentation/introspection.md +82 -0
  132. package/documentation/map.md +73 -0
  133. package/documentation/octets.md +122 -69
  134. package/documentation/protocol.md +11 -4
  135. package/documentation/query.md +29 -4
  136. package/documentation/require.md +15 -0
  137. package/documentation/tree.md +13 -0
  138. package/features/access.feature +129 -48
  139. package/features/annotation.feature +1 -0
  140. package/features/auth.claims.feature +171 -0
  141. package/features/auth.incept.feature +89 -0
  142. package/features/auth.input.feature +59 -0
  143. package/features/authorities.basic.feature +141 -0
  144. package/features/authorities.feature +32 -0
  145. package/features/authorities.federation.feature +100 -0
  146. package/features/authorities.tokens.feature +117 -0
  147. package/features/body.feature +2 -0
  148. package/features/cache.feature +109 -5
  149. package/features/cors.feature +8 -2
  150. package/features/debug.feature +34 -0
  151. package/features/dev.feature +56 -0
  152. package/features/directives.feature +3 -0
  153. package/features/dynamic.feature +48 -0
  154. package/features/errors.feature +32 -7
  155. package/features/etag.feature +109 -1
  156. package/features/flow.feature +148 -0
  157. package/features/identity.bans.feature +137 -0
  158. package/features/identity.basic.feature +85 -28
  159. package/features/identity.feature +18 -6
  160. package/features/identity.federation.feature +89 -18
  161. package/features/identity.roles.feature +112 -19
  162. package/features/identity.tokens.feature +13 -4
  163. package/features/identtiy.tokens.custom.feature +247 -0
  164. package/features/interruptions.feature +19 -0
  165. package/features/introspection.feature +153 -0
  166. package/features/io.feature +38 -1
  167. package/features/map.feature +305 -0
  168. package/features/methods.feature +47 -0
  169. package/features/octets.cloudinary.feature +71 -0
  170. package/features/octets.download.feature +189 -0
  171. package/features/octets.entries.feature +13 -55
  172. package/features/octets.feature +90 -114
  173. package/features/octets.head.feature +40 -0
  174. package/features/octets.location.feature +83 -0
  175. package/features/octets.meta.feature +65 -15
  176. package/features/octets.workflows.feature +339 -66
  177. package/features/probes.feature +14 -0
  178. package/features/{queries.feature → query.feature} +77 -2
  179. package/features/realtime.feature +34 -0
  180. package/features/require.feature +67 -0
  181. package/features/response.feature +38 -3
  182. package/features/routes.feature +93 -2
  183. package/features/server.feature +21 -0
  184. package/features/steps/.env.example +3 -0
  185. package/features/steps/Common.ts +4 -0
  186. package/features/steps/Database.ts +16 -9
  187. package/features/steps/Gateway.ts +26 -7
  188. package/features/steps/HTTP.ts +25 -2
  189. package/features/steps/IdP.ts +63 -25
  190. package/features/steps/Identity.ts +51 -0
  191. package/features/steps/Parameters.ts +44 -1
  192. package/features/steps/Realtime.ts +151 -0
  193. package/features/steps/components/echo/manifest.toa.yaml +14 -1
  194. package/features/steps/components/echo/operations/identity.js +7 -0
  195. package/features/steps/components/echo/operations/parameters.js +7 -0
  196. package/features/steps/components/echo.beacon/manifest.toa.yaml +2 -0
  197. package/features/steps/components/echo.beacon/operations/hello.js +5 -0
  198. package/features/steps/components/greeter/manifest.toa.yaml +0 -1
  199. package/features/steps/components/octets.tester/manifest.toa.yaml +25 -3
  200. package/features/steps/components/octets.tester/operations/authority.js +7 -0
  201. package/features/steps/components/octets.tester/operations/bar.js +0 -1
  202. package/features/steps/components/octets.tester/operations/baz.js +0 -2
  203. package/features/steps/components/octets.tester/operations/echo.js +1 -1
  204. package/features/steps/components/octets.tester/operations/foo.js +1 -2
  205. package/features/steps/components/octets.tester/operations/id.js +7 -0
  206. package/features/steps/components/octets.tester/operations/identity.js +7 -0
  207. package/features/steps/components/octets.tester/operations/redirect.js +12 -0
  208. package/features/steps/components/octets.tester/operations/yex.js +16 -0
  209. package/features/steps/components/octets.tester/operations/yield.js +13 -0
  210. package/features/steps/components/pots/manifest.toa.yaml +12 -4
  211. package/features/steps/components/sequences/manifest.toa.yaml +0 -1
  212. package/features/steps/components/users/manifest.toa.yaml +4 -3
  213. package/features/steps/components/users/operations/create.js +15 -0
  214. package/features/steps/components/users.properties/manifest.toa.yaml +1 -2
  215. package/features/streams.feature +5 -0
  216. package/features/timestamps.feature +41 -0
  217. package/features/timing.feature +4 -1
  218. package/package.json +25 -13
  219. package/readme.md +19 -14
  220. package/schemas/annotation.cos.yaml +1 -1
  221. package/schemas/method.cos.yaml +1 -1
  222. package/schemas/node.cos.yaml +2 -0
  223. package/schemas/octets/put.cos.yaml +28 -0
  224. package/schemas/query.cos.yaml +4 -10
  225. package/source/Annotation.ts +3 -3
  226. package/source/Branch.ts +1 -0
  227. package/source/Composition.ts +0 -6
  228. package/source/Context.ts +1 -0
  229. package/source/Directive.test.ts +1 -1
  230. package/source/Directive.ts +16 -8
  231. package/source/Endpoint.ts +69 -17
  232. package/source/Factory.ts +22 -13
  233. package/source/Gateway.ts +73 -19
  234. package/source/HTTP/Context.ts +31 -7
  235. package/source/HTTP/Server.ts +116 -48
  236. package/source/HTTP/exceptions.ts +13 -1
  237. package/source/HTTP/formats/index.ts +3 -3
  238. package/source/HTTP/messages.test.ts +45 -2
  239. package/source/HTTP/messages.ts +39 -8
  240. package/source/Introspection.ts +11 -0
  241. package/source/Mapping.ts +68 -21
  242. package/source/Query.test.ts +3 -3
  243. package/source/Query.ts +123 -33
  244. package/source/RTD/Context.ts +1 -1
  245. package/source/RTD/Endpoint.ts +3 -0
  246. package/source/RTD/Method.ts +16 -0
  247. package/source/RTD/Node.ts +29 -13
  248. package/source/RTD/Route.ts +5 -4
  249. package/source/RTD/Tree.ts +2 -2
  250. package/source/RTD/factory.ts +5 -2
  251. package/source/RTD/syntax/parse.test.ts +1 -1
  252. package/source/RTD/syntax/parse.ts +37 -24
  253. package/source/RTD/syntax/types.ts +6 -4
  254. package/source/Remotes.ts +7 -6
  255. package/source/Tenant.ts +6 -20
  256. package/source/deployment.ts +33 -23
  257. package/source/directives/auth/Anonymous.ts +3 -3
  258. package/source/directives/auth/Anyone.ts +13 -0
  259. package/source/directives/auth/Authorization.ts +65 -25
  260. package/source/directives/auth/Delegate.ts +13 -6
  261. package/source/directives/auth/Echo.ts +16 -6
  262. package/source/directives/auth/Federation.ts +84 -0
  263. package/source/directives/auth/Id.ts +1 -1
  264. package/source/directives/auth/Incept.ts +27 -12
  265. package/source/directives/auth/Input.ts +72 -0
  266. package/source/directives/auth/Role.test.ts +53 -6
  267. package/source/directives/auth/Role.ts +23 -19
  268. package/source/directives/auth/Rule.ts +3 -5
  269. package/source/directives/auth/Scheme.ts +5 -5
  270. package/source/directives/auth/create.ts +10 -0
  271. package/source/directives/auth/split.ts +1 -1
  272. package/source/directives/auth/types.ts +11 -6
  273. package/source/directives/cache/Cache.ts +13 -6
  274. package/source/directives/cache/Control.ts +42 -16
  275. package/source/directives/cors/CORS.ts +3 -2
  276. package/source/directives/dev/Development.ts +12 -7
  277. package/source/directives/dev/Sleep.ts +40 -0
  278. package/source/directives/dev/types.ts +1 -1
  279. package/source/directives/flow/Compose.ts +92 -0
  280. package/source/directives/flow/Fetch.ts +86 -0
  281. package/source/directives/flow/Flow.ts +42 -0
  282. package/source/directives/flow/index.ts +3 -0
  283. package/source/directives/flow/types.ts +7 -0
  284. package/source/directives/index.ts +4 -2
  285. package/source/directives/io/IO.ts +1 -1
  286. package/source/directives/io/Input.ts +8 -5
  287. package/source/directives/io/Output.ts +5 -4
  288. package/source/directives/map/Authority.ts +15 -0
  289. package/source/directives/map/Claims.ts +58 -0
  290. package/source/directives/map/Directive.ts +4 -0
  291. package/source/directives/map/Headers.ts +38 -0
  292. package/source/directives/map/Language.ts +42 -0
  293. package/source/directives/map/Languages.ts +11 -0
  294. package/source/directives/map/Map.ts +61 -0
  295. package/source/directives/map/Mapping.ts +19 -0
  296. package/source/directives/{vary → map}/Properties.ts +2 -4
  297. package/source/directives/map/Segments.ts +26 -0
  298. package/source/directives/map/index.ts +3 -0
  299. package/source/directives/octets/Context.ts +3 -2
  300. package/source/directives/octets/Delete.ts +21 -17
  301. package/source/directives/octets/Get.ts +86 -0
  302. package/source/directives/octets/Octets.ts +9 -12
  303. package/source/directives/octets/{Store.ts → Put.ts} +52 -38
  304. package/source/directives/octets/Workflow.ts +9 -3
  305. package/source/directives/octets/bytes.test.ts +30 -0
  306. package/source/directives/octets/bytes.ts +18 -0
  307. package/source/directives/octets/schemas.ts +4 -8
  308. package/source/directives/octets/types.ts +2 -0
  309. package/source/directives/octets/workflows/Execution.ts +61 -8
  310. package/source/directives/octets/workflows/Workflow.ts +17 -7
  311. package/source/directives/octets/workflows/index.ts +1 -1
  312. package/source/directives/require/Directive.ts +5 -0
  313. package/source/directives/require/Headers.ts +20 -0
  314. package/source/directives/require/Require.ts +28 -0
  315. package/source/directives/require/index.ts +3 -0
  316. package/source/exceptions.ts +14 -6
  317. package/source/manifest.ts +10 -11
  318. package/source/root.ts +16 -1
  319. package/source/schemas.ts +1 -1
  320. package/transpiled/Annotation.d.ts +3 -3
  321. package/transpiled/Branch.d.ts +1 -0
  322. package/transpiled/Composition.d.ts +0 -1
  323. package/transpiled/Composition.js +0 -4
  324. package/transpiled/Composition.js.map +1 -1
  325. package/transpiled/Context.d.ts +1 -0
  326. package/transpiled/Directive.js +15 -8
  327. package/transpiled/Directive.js.map +1 -1
  328. package/transpiled/Endpoint.d.ts +6 -4
  329. package/transpiled/Endpoint.js +47 -9
  330. package/transpiled/Endpoint.js.map +1 -1
  331. package/transpiled/Factory.d.ts +3 -2
  332. package/transpiled/Factory.js +18 -10
  333. package/transpiled/Factory.js.map +1 -1
  334. package/transpiled/Gateway.d.ts +3 -0
  335. package/transpiled/Gateway.js +55 -12
  336. package/transpiled/Gateway.js.map +1 -1
  337. package/transpiled/HTTP/Context.d.ts +9 -2
  338. package/transpiled/HTTP/Context.js +20 -6
  339. package/transpiled/HTTP/Context.js.map +1 -1
  340. package/transpiled/HTTP/Server.d.ts +15 -4
  341. package/transpiled/HTTP/Server.js +83 -41
  342. package/transpiled/HTTP/Server.js.map +1 -1
  343. package/transpiled/HTTP/exceptions.d.ts +7 -1
  344. package/transpiled/HTTP/exceptions.js +13 -1
  345. package/transpiled/HTTP/exceptions.js.map +1 -1
  346. package/transpiled/HTTP/formats/index.js +3 -3
  347. package/transpiled/HTTP/formats/index.js.map +1 -1
  348. package/transpiled/HTTP/messages.d.ts +2 -1
  349. package/transpiled/HTTP/messages.js +36 -7
  350. package/transpiled/HTTP/messages.js.map +1 -1
  351. package/transpiled/Introspection.d.ts +9 -0
  352. package/transpiled/Introspection.js +3 -0
  353. package/transpiled/Introspection.js.map +1 -0
  354. package/transpiled/Mapping.d.ts +11 -2
  355. package/transpiled/Mapping.js +50 -19
  356. package/transpiled/Mapping.js.map +1 -1
  357. package/transpiled/Query.d.ts +10 -1
  358. package/transpiled/Query.js +87 -30
  359. package/transpiled/Query.js.map +1 -1
  360. package/transpiled/RTD/Context.d.ts +1 -1
  361. package/transpiled/RTD/Endpoint.d.ts +1 -0
  362. package/transpiled/RTD/Method.d.ts +4 -0
  363. package/transpiled/RTD/Method.js +11 -0
  364. package/transpiled/RTD/Method.js.map +1 -1
  365. package/transpiled/RTD/Node.d.ts +4 -1
  366. package/transpiled/RTD/Node.js +23 -12
  367. package/transpiled/RTD/Node.js.map +1 -1
  368. package/transpiled/RTD/Route.d.ts +1 -1
  369. package/transpiled/RTD/Route.js +0 -1
  370. package/transpiled/RTD/Route.js.map +1 -1
  371. package/transpiled/RTD/Tree.d.ts +1 -1
  372. package/transpiled/RTD/Tree.js.map +1 -1
  373. package/transpiled/RTD/factory.js +5 -2
  374. package/transpiled/RTD/factory.js.map +1 -1
  375. package/transpiled/RTD/syntax/parse.js +34 -22
  376. package/transpiled/RTD/syntax/parse.js.map +1 -1
  377. package/transpiled/RTD/syntax/types.d.ts +5 -3
  378. package/transpiled/RTD/syntax/types.js +1 -1
  379. package/transpiled/RTD/syntax/types.js.map +1 -1
  380. package/transpiled/Remotes.d.ts +4 -4
  381. package/transpiled/Remotes.js +6 -5
  382. package/transpiled/Remotes.js.map +1 -1
  383. package/transpiled/Tenant.d.ts +5 -5
  384. package/transpiled/Tenant.js +2 -13
  385. package/transpiled/Tenant.js.map +1 -1
  386. package/transpiled/deployment.d.ts +1 -1
  387. package/transpiled/deployment.js +28 -20
  388. package/transpiled/deployment.js.map +1 -1
  389. package/transpiled/directives/auth/Anonymous.d.ts +2 -2
  390. package/transpiled/directives/auth/Anonymous.js +2 -2
  391. package/transpiled/directives/auth/Anonymous.js.map +1 -1
  392. package/transpiled/directives/auth/Anyone.d.ts +6 -0
  393. package/transpiled/directives/auth/Anyone.js +14 -0
  394. package/transpiled/directives/auth/Anyone.js.map +1 -0
  395. package/transpiled/directives/auth/Authorization.d.ts +4 -3
  396. package/transpiled/directives/auth/Authorization.js +49 -22
  397. package/transpiled/directives/auth/Authorization.js.map +1 -1
  398. package/transpiled/directives/auth/Delegate.d.ts +5 -4
  399. package/transpiled/directives/auth/Delegate.js +10 -4
  400. package/transpiled/directives/auth/Delegate.js.map +1 -1
  401. package/transpiled/directives/auth/Echo.d.ts +4 -4
  402. package/transpiled/directives/auth/Echo.js +11 -4
  403. package/transpiled/directives/auth/Echo.js.map +1 -1
  404. package/transpiled/directives/auth/Federation.d.ts +16 -0
  405. package/transpiled/directives/auth/Federation.js +57 -0
  406. package/transpiled/directives/auth/Federation.js.map +1 -0
  407. package/transpiled/directives/auth/Id.d.ts +1 -1
  408. package/transpiled/directives/auth/Id.js.map +1 -1
  409. package/transpiled/directives/auth/Incept.d.ts +4 -3
  410. package/transpiled/directives/auth/Incept.js +23 -10
  411. package/transpiled/directives/auth/Incept.js.map +1 -1
  412. package/transpiled/directives/auth/Input.d.ts +13 -0
  413. package/transpiled/directives/auth/Input.js +49 -0
  414. package/transpiled/directives/auth/Input.js.map +1 -0
  415. package/transpiled/directives/auth/Role.d.ts +5 -2
  416. package/transpiled/directives/auth/Role.js +22 -18
  417. package/transpiled/directives/auth/Role.js.map +1 -1
  418. package/transpiled/directives/auth/Rule.d.ts +2 -4
  419. package/transpiled/directives/auth/Rule.js +2 -2
  420. package/transpiled/directives/auth/Rule.js.map +1 -1
  421. package/transpiled/directives/auth/Scheme.d.ts +2 -2
  422. package/transpiled/directives/auth/Scheme.js +4 -4
  423. package/transpiled/directives/auth/Scheme.js.map +1 -1
  424. package/transpiled/directives/auth/create.d.ts +2 -0
  425. package/transpiled/directives/auth/create.js +12 -0
  426. package/transpiled/directives/auth/create.js.map +1 -0
  427. package/transpiled/directives/auth/split.js +1 -1
  428. package/transpiled/directives/auth/split.js.map +1 -1
  429. package/transpiled/directives/auth/types.d.ts +8 -5
  430. package/transpiled/directives/cache/Cache.d.ts +3 -3
  431. package/transpiled/directives/cache/Cache.js +10 -4
  432. package/transpiled/directives/cache/Cache.js.map +1 -1
  433. package/transpiled/directives/cache/Control.d.ts +2 -1
  434. package/transpiled/directives/cache/Control.js +29 -12
  435. package/transpiled/directives/cache/Control.js.map +1 -1
  436. package/transpiled/directives/cors/CORS.js +3 -2
  437. package/transpiled/directives/cors/CORS.js.map +1 -1
  438. package/transpiled/directives/dev/Development.d.ts +1 -1
  439. package/transpiled/directives/dev/Development.js +13 -7
  440. package/transpiled/directives/dev/Development.js.map +1 -1
  441. package/transpiled/directives/dev/Sleep.d.ts +8 -0
  442. package/transpiled/directives/dev/Sleep.js +36 -0
  443. package/transpiled/directives/dev/Sleep.js.map +1 -0
  444. package/transpiled/directives/dev/types.d.ts +1 -1
  445. package/transpiled/directives/flow/Compose.d.ts +9 -0
  446. package/transpiled/directives/flow/Compose.js +94 -0
  447. package/transpiled/directives/flow/Compose.js.map +1 -0
  448. package/transpiled/directives/flow/Fetch.d.ts +12 -0
  449. package/transpiled/directives/flow/Fetch.js +58 -0
  450. package/transpiled/directives/flow/Fetch.js.map +1 -0
  451. package/transpiled/directives/flow/Flow.d.ts +10 -0
  452. package/transpiled/directives/flow/Flow.js +33 -0
  453. package/transpiled/directives/flow/Flow.js.map +1 -0
  454. package/transpiled/directives/flow/index.d.ts +2 -0
  455. package/transpiled/directives/flow/index.js +6 -0
  456. package/transpiled/directives/flow/index.js.map +1 -0
  457. package/transpiled/directives/flow/types.d.ts +6 -0
  458. package/transpiled/directives/flow/types.js.map +1 -0
  459. package/transpiled/directives/index.js +4 -2
  460. package/transpiled/directives/index.js.map +1 -1
  461. package/transpiled/directives/io/IO.js +1 -1
  462. package/transpiled/directives/io/IO.js.map +1 -1
  463. package/transpiled/directives/io/Input.js +4 -2
  464. package/transpiled/directives/io/Input.js.map +1 -1
  465. package/transpiled/directives/io/Output.js +2 -2
  466. package/transpiled/directives/io/Output.js.map +1 -1
  467. package/transpiled/directives/map/Authority.d.ts +6 -0
  468. package/transpiled/directives/map/Authority.js +19 -0
  469. package/transpiled/directives/map/Authority.js.map +1 -0
  470. package/transpiled/directives/map/Claims.d.ts +10 -0
  471. package/transpiled/directives/map/Claims.js +44 -0
  472. package/transpiled/directives/map/Claims.js.map +1 -0
  473. package/transpiled/directives/map/Directive.d.ts +3 -0
  474. package/transpiled/directives/map/Directive.js.map +1 -0
  475. package/transpiled/directives/map/Headers.d.ts +7 -0
  476. package/transpiled/directives/map/Headers.js +34 -0
  477. package/transpiled/directives/map/Headers.js.map +1 -0
  478. package/transpiled/directives/map/Language.d.ts +10 -0
  479. package/transpiled/directives/map/Language.js +38 -0
  480. package/transpiled/directives/map/Language.js.map +1 -0
  481. package/transpiled/directives/map/Languages.d.ts +4 -0
  482. package/transpiled/directives/map/Languages.js +17 -0
  483. package/transpiled/directives/map/Languages.js.map +1 -0
  484. package/transpiled/directives/map/Map.d.ts +13 -0
  485. package/transpiled/directives/map/Map.js +46 -0
  486. package/transpiled/directives/map/Map.js.map +1 -0
  487. package/transpiled/directives/map/Mapping.d.ts +13 -0
  488. package/transpiled/directives/map/Mapping.js +13 -0
  489. package/transpiled/directives/map/Mapping.js.map +1 -0
  490. package/transpiled/directives/{vary → map}/Properties.d.ts +2 -2
  491. package/transpiled/directives/{vary → map}/Properties.js +1 -3
  492. package/transpiled/directives/map/Properties.js.map +1 -0
  493. package/transpiled/directives/map/Segments.d.ts +6 -0
  494. package/transpiled/directives/map/Segments.js +25 -0
  495. package/transpiled/directives/map/Segments.js.map +1 -0
  496. package/transpiled/directives/map/index.d.ts +2 -0
  497. package/transpiled/directives/map/index.js +6 -0
  498. package/transpiled/directives/map/index.js.map +1 -0
  499. package/transpiled/directives/octets/Context.js +4 -24
  500. package/transpiled/directives/octets/Context.js.map +1 -1
  501. package/transpiled/directives/octets/Delete.js +15 -12
  502. package/transpiled/directives/octets/Delete.js.map +1 -1
  503. package/transpiled/directives/octets/{Fetch.d.ts → Get.d.ts} +5 -6
  504. package/transpiled/directives/octets/{Fetch.js → Get.js} +25 -29
  505. package/transpiled/directives/octets/Get.js.map +1 -0
  506. package/transpiled/directives/octets/Octets.js +9 -12
  507. package/transpiled/directives/octets/Octets.js.map +1 -1
  508. package/transpiled/directives/octets/{Store.d.ts → Put.d.ts} +8 -2
  509. package/transpiled/directives/octets/{Store.js → Put.js} +33 -27
  510. package/transpiled/directives/octets/Put.js.map +1 -0
  511. package/transpiled/directives/octets/Workflow.js +7 -2
  512. package/transpiled/directives/octets/Workflow.js.map +1 -1
  513. package/transpiled/directives/octets/bytes.d.ts +1 -0
  514. package/transpiled/directives/octets/bytes.js +21 -0
  515. package/transpiled/directives/octets/bytes.js.map +1 -0
  516. package/transpiled/directives/octets/schemas.d.ts +4 -8
  517. package/transpiled/directives/octets/schemas.js +3 -6
  518. package/transpiled/directives/octets/schemas.js.map +1 -1
  519. package/transpiled/directives/octets/types.d.ts +2 -0
  520. package/transpiled/directives/octets/workflows/Execution.d.ts +6 -1
  521. package/transpiled/directives/octets/workflows/Execution.js +44 -9
  522. package/transpiled/directives/octets/workflows/Execution.js.map +1 -1
  523. package/transpiled/directives/octets/workflows/Workflow.d.ts +8 -3
  524. package/transpiled/directives/octets/workflows/Workflow.js +9 -4
  525. package/transpiled/directives/octets/workflows/Workflow.js.map +1 -1
  526. package/transpiled/directives/octets/workflows/index.d.ts +1 -1
  527. package/transpiled/directives/octets/workflows/index.js.map +1 -1
  528. package/transpiled/directives/require/Directive.d.ts +4 -0
  529. package/transpiled/directives/require/Directive.js +3 -0
  530. package/transpiled/directives/require/Directive.js.map +1 -0
  531. package/transpiled/directives/require/Headers.d.ts +7 -0
  532. package/transpiled/directives/require/Headers.js +19 -0
  533. package/transpiled/directives/require/Headers.js.map +1 -0
  534. package/transpiled/directives/require/Require.d.ts +9 -0
  535. package/transpiled/directives/require/Require.js +27 -0
  536. package/transpiled/directives/require/Require.js.map +1 -0
  537. package/transpiled/directives/require/index.d.ts +2 -0
  538. package/transpiled/directives/require/index.js +6 -0
  539. package/transpiled/directives/require/index.js.map +1 -0
  540. package/transpiled/exceptions.d.ts +3 -2
  541. package/transpiled/exceptions.js +8 -1
  542. package/transpiled/exceptions.js.map +1 -1
  543. package/transpiled/manifest.js +10 -11
  544. package/transpiled/manifest.js.map +1 -1
  545. package/transpiled/root.js +16 -1
  546. package/transpiled/root.js.map +1 -1
  547. package/transpiled/schemas.d.ts +1 -1
  548. package/transpiled/schemas.js +2 -2
  549. package/transpiled/schemas.js.map +1 -1
  550. package/transpiled/tsconfig.tsbuildinfo +1 -1
  551. package/components/identity.basic/operations/create.d.ts +0 -10
  552. package/components/identity.basic/operations/create.js +0 -10
  553. package/components/identity.basic/operations/create.js.map +0 -1
  554. package/components/identity.basic/source/create.ts +0 -18
  555. package/components/identity.federation/operations/create.d.ts +0 -10
  556. package/components/identity.federation/operations/create.js +0 -15
  557. package/components/identity.federation/operations/create.js.map +0 -1
  558. package/components/identity.federation/operations/schemas.d.ts +0 -59
  559. package/components/identity.federation/operations/schemas.js +0 -9
  560. package/components/identity.federation/operations/schemas.js.map +0 -1
  561. package/components/identity.federation/operations/types.js.map +0 -1
  562. package/components/identity.federation/source/create.ts +0 -26
  563. package/components/identity.federation/source/schemas.ts +0 -61
  564. package/components/identity.tokens/operations/types.d.ts +0 -40
  565. package/components/identity.tokens/operations/types.js.map +0 -1
  566. package/components/identity.tokens/source/types.ts +0 -48
  567. package/components/octets.storage/operations/fetch.js +0 -46
  568. package/components/octets.storage/operations/list.js +0 -7
  569. package/components/octets.storage/operations/permute.js +0 -7
  570. package/components/octets.storage/operations/store.js +0 -11
  571. package/documentation/vary.md +0 -69
  572. package/features/steps/components/octets.tester/operations/diversify.js +0 -14
  573. package/features/vary.feature +0 -180
  574. package/schemas/octets/context.cos.yaml +0 -1
  575. package/schemas/octets/fetch.cos.yaml +0 -3
  576. package/schemas/octets/permute.cos.yaml +0 -1
  577. package/schemas/octets/store.cos.yaml +0 -3
  578. package/source/HTTP/Server.test.ts +0 -126
  579. package/source/directives/octets/Fetch.ts +0 -100
  580. package/source/directives/octets/List.ts +0 -72
  581. package/source/directives/octets/Permute.ts +0 -44
  582. package/source/directives/vary/Directive.ts +0 -6
  583. package/source/directives/vary/Embed.ts +0 -62
  584. package/source/directives/vary/Vary.ts +0 -48
  585. package/source/directives/vary/embeddings/Embedding.ts +0 -6
  586. package/source/directives/vary/embeddings/Header.ts +0 -32
  587. package/source/directives/vary/embeddings/Language.ts +0 -31
  588. package/source/directives/vary/embeddings/index.ts +0 -11
  589. package/source/directives/vary/index.ts +0 -3
  590. package/transpiled/directives/octets/Fetch.js.map +0 -1
  591. package/transpiled/directives/octets/List.d.ts +0 -16
  592. package/transpiled/directives/octets/List.js +0 -74
  593. package/transpiled/directives/octets/List.js.map +0 -1
  594. package/transpiled/directives/octets/Permute.d.ts +0 -11
  595. package/transpiled/directives/octets/Permute.js.map +0 -1
  596. package/transpiled/directives/octets/Store.js.map +0 -1
  597. package/transpiled/directives/vary/Directive.d.ts +0 -5
  598. package/transpiled/directives/vary/Directive.js.map +0 -1
  599. package/transpiled/directives/vary/Embed.d.ts +0 -10
  600. package/transpiled/directives/vary/Embed.js +0 -49
  601. package/transpiled/directives/vary/Embed.js.map +0 -1
  602. package/transpiled/directives/vary/Properties.js.map +0 -1
  603. package/transpiled/directives/vary/Vary.d.ts +0 -10
  604. package/transpiled/directives/vary/Vary.js +0 -36
  605. package/transpiled/directives/vary/Vary.js.map +0 -1
  606. package/transpiled/directives/vary/embeddings/Embedding.d.ts +0 -5
  607. package/transpiled/directives/vary/embeddings/Embedding.js.map +0 -1
  608. package/transpiled/directives/vary/embeddings/Header.d.ts +0 -7
  609. package/transpiled/directives/vary/embeddings/Header.js +0 -28
  610. package/transpiled/directives/vary/embeddings/Header.js.map +0 -1
  611. package/transpiled/directives/vary/embeddings/Language.d.ts +0 -7
  612. package/transpiled/directives/vary/embeddings/Language.js +0 -28
  613. package/transpiled/directives/vary/embeddings/Language.js.map +0 -1
  614. package/transpiled/directives/vary/embeddings/index.d.ts +0 -5
  615. package/transpiled/directives/vary/embeddings/index.js +0 -10
  616. package/transpiled/directives/vary/embeddings/index.js.map +0 -1
  617. package/transpiled/directives/vary/index.d.ts +0 -2
  618. package/transpiled/directives/vary/index.js +0 -6
  619. package/transpiled/directives/vary/index.js.map +0 -1
  620. /package/components/{identity.federation/operations → identity.tokens/operations/lib}/types.js +0 -0
  621. /package/schemas/octets/{list.cos.yaml → get.cos.yaml} +0 -0
  622. /package/{components/identity.tokens/operations → transpiled/directives/flow}/types.js +0 -0
  623. /package/transpiled/directives/{vary → map}/Directive.js +0 -0
@@ -1,47 +1,62 @@
1
+ import assert from 'node:assert'
1
2
  import { type Maybe } from '@toa.io/types'
2
3
  import * as http from '../../HTTP'
3
- import { type Directive, type Discovery, type Identity, type Input, type Schemes } from './types'
4
+ import { type Directive, type Discovery, type Identity, type Context, type Schemes } from './types'
4
5
  import { split } from './split'
6
+ import { create } from './create'
5
7
  import { PROVIDERS } from './schemes'
6
8
 
7
9
  export class Incept implements Directive {
8
- private readonly property: string
10
+ private readonly property: string | null
9
11
  private readonly discovery: Discovery
10
12
  private readonly schemes: Schemes = {} as unknown as Schemes
11
13
 
12
14
  public constructor (property: string, discovery: Discovery) {
15
+ assert.ok(property === null || typeof property === 'string',
16
+ '`auth:incept` value must be a string or null')
17
+
13
18
  this.property = property
14
19
  this.discovery = discovery
15
20
  }
16
21
 
17
- public authorize (identity: Identity | null, input: Input): boolean {
18
- return identity === null && 'authorization' in input.request.headers
22
+ public authorize (identity: Identity | null, context: Context): boolean {
23
+ return identity === null && 'authorization' in context.request.headers
24
+ }
25
+
26
+ public reply (context: Context): http.OutgoingMessage | null {
27
+ if (this.property !== null)
28
+ return null
29
+
30
+ const body = create(context.request.headers.authorization)
31
+
32
+ return { body }
19
33
  }
20
34
 
21
- public async settle (input: Input, response: http.OutgoingMessage): Promise<void> {
22
- const id = response.body?.[this.property]
35
+ public async settle (context: Context, response: http.OutgoingMessage): Promise<void> {
36
+ const id = response.body?.[this.property ?? 'id']
23
37
 
24
38
  if (id === undefined)
25
39
  throw new http.Conflict('Identity inception has failed as the response body ' +
26
- ` does not contain the '${this.property}' property.`)
40
+ `does not contain the '${this.property}' property`)
27
41
 
28
- const [scheme, credentials] = split(input.request.headers.authorization!)
42
+ const [scheme, credentials] = split(context.request.headers.authorization!)
29
43
  const provider = PROVIDERS[scheme]
30
44
 
31
45
  this.schemes[scheme] ??= await this.discovery[provider]
32
46
 
33
47
  const identity = await this.schemes[scheme]
34
- .invoke<Maybe<Identity>>('create', {
48
+ .invoke<Maybe<Identity>>('incept', {
35
49
  input: {
50
+ authority: context.authority,
36
51
  id,
37
52
  credentials
38
53
  }
39
54
  })
40
55
 
41
56
  if (identity instanceof Error)
42
- throw new http.Conflict(identity)
57
+ throw new http.UnprocessableEntity(identity)
43
58
 
44
- input.identity = identity
45
- input.identity.scheme = scheme
59
+ context.identity = identity
60
+ context.identity.scheme = scheme
46
61
  }
47
62
  }
@@ -0,0 +1,72 @@
1
+ import { Forbidden } from '../../HTTP'
2
+ import type { Parameter } from '../../RTD'
3
+ import type { Context, Directive, Identity, Create } from './types'
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((declaration) => new Statement(declaration, create))
11
+ }
12
+
13
+ public async authorize
14
+ (identity: Identity | null, context: Context, parameters: Parameter[]): Promise<boolean> {
15
+ context.pipelines.body.push(async (body) => this.check(identity, context, parameters, body))
16
+
17
+ return false
18
+ }
19
+
20
+ // eslint-disable-next-line max-params
21
+ private async check (identity: Identity | null, context: Context, parameters: Parameter[], body: unknown): Promise<unknown> {
22
+ if (body === undefined || body === null || body.constructor !== Object)
23
+ return body
24
+
25
+ const settled = await Promise.allSettled(this.statements.map(async (statement) =>
26
+ statement.check(identity, context, parameters, body as Body)))
27
+
28
+ for (const result of settled)
29
+ if (result.status === 'rejected')
30
+ throw result.reason
31
+
32
+ return body
33
+ }
34
+ }
35
+
36
+ class Statement {
37
+ private readonly properties: string[]
38
+ private readonly directives: Directive[] = []
39
+
40
+ public constructor ({ prop, ...directives }: Declaration, create: Create) {
41
+ this.properties = typeof prop === 'string' ? [prop] : prop
42
+
43
+ for (const [name, value] of Object.entries(directives)) {
44
+ const directive = create(name, value)
45
+
46
+ this.directives.push(directive)
47
+ }
48
+ }
49
+
50
+ // eslint-disable-next-line max-params
51
+ public async check (identity: Identity | null, context: Context, parameters: Parameter[], body: Body): Promise<void> {
52
+ const match = this.properties.some((property) => property in body)
53
+
54
+ if (!match)
55
+ return
56
+
57
+ for (const directive of this.directives) {
58
+ const authorized = await directive.authorize(identity, context, parameters)
59
+
60
+ if (!authorized)
61
+ throw new Forbidden('Input property is not authorized')
62
+ }
63
+ }
64
+ }
65
+
66
+ export interface Declaration {
67
+ [key: Exclude<string, 'prop'>]: unknown
68
+
69
+ prop: string | string[]
70
+ }
71
+
72
+ type Body = Record<string, unknown>
@@ -2,6 +2,7 @@ import { type Component } from '@toa.io/core'
2
2
  import { generate } from 'randomstring'
3
3
  import { Role } from './Role'
4
4
  import { type Identity } from './types'
5
+ import type { Parameter } from '../../RTD'
5
6
 
6
7
  const remote = {
7
8
  invoke: jest.fn()
@@ -16,16 +17,26 @@ beforeEach(() => {
16
17
  it('should return false if not matched', async () => {
17
18
  const roles = ['admin', 'user']
18
19
  const directive = new Role(roles, discovery)
19
- const identity: Identity = { id: generate(), scheme: '', refresh: false }
20
+
21
+ const identity: Identity = {
22
+ id: generate(),
23
+ scheme: '',
24
+ refresh: false
25
+ }
20
26
 
21
27
  remote.invoke.mockResolvedValueOnce(['guest'])
22
28
 
23
- const result = await directive.authorize(identity)
29
+ const result = await directive.authorize(identity, undefined, [])
24
30
 
25
31
  expect(result).toBe(false)
26
32
 
27
33
  expect(remote.invoke)
28
- .toBeCalledWith('list', { query: { criteria: `identity==${identity.id}`, limit: 1024 } })
34
+ .toBeCalledWith('list', {
35
+ query: {
36
+ criteria: `identity==${identity.id}`,
37
+ limit: 1024
38
+ }
39
+ })
29
40
  })
30
41
 
31
42
  it('should return true on exact match', async () => {
@@ -52,11 +63,47 @@ it('should return false on non-scope substring match', async () => {
52
63
  expect(result).toBe(false)
53
64
  })
54
65
 
55
- async function match (expected: string[], actual: string[]): Promise<boolean> {
66
+ it('should return true on match with parameters', async () => {
67
+ const result = await match(['app:{org}:reviews'],
68
+ ['app:29e54ae1:reviews'], [{
69
+ name: 'org',
70
+ value: '29e54ae1'
71
+ }])
72
+
73
+ expect(result).toBe(true)
74
+ })
75
+
76
+ it('should return true on match with parameters', async () => {
77
+ const result = await match(['app:{org}:reviews'],
78
+ ['app:29e54ae1:reviews'], [{
79
+ name: 'org',
80
+ value: '29e54ae1'
81
+ }])
82
+
83
+ expect(result).toBe(true)
84
+ })
85
+
86
+ it('should return false on mismatch with parameters', async () => {
87
+ const result = await match(['app:{org}:reviews'],
88
+ ['app:29e54ae1:reviews'], [{
89
+ name: 'org',
90
+ value: '88584c9b'
91
+ }])
92
+
93
+ expect(result).toBe(false)
94
+ })
95
+
96
+ async function match
97
+ (expected: string[], actual: string[], parameters: Parameter[] = []): Promise<boolean> {
56
98
  const directive = new Role(expected, discovery)
57
- const identity: Identity = { id: generate(), scheme: '', refresh: false }
99
+
100
+ const identity: Identity = {
101
+ id: generate(),
102
+ scheme: '',
103
+ refresh: false
104
+ }
58
105
 
59
106
  remote.invoke.mockResolvedValueOnce(actual)
60
107
 
61
- return await directive.authorize(identity)
108
+ return await directive.authorize(identity, undefined, parameters)
62
109
  }
@@ -1,17 +1,21 @@
1
+ import assert from 'node:assert'
1
2
  import { type Component, type Query } from '@toa.io/core'
2
3
  import { type Directive, type Identity } from './types'
4
+ import type { Parameter } from '../../RTD'
3
5
 
4
6
  export class Role implements Directive {
5
7
  public static remote: Component | null = null
6
8
  private readonly roles: string[]
7
9
  private readonly discovery: Promise<Component>
10
+ private readonly dynamic: boolean
8
11
 
9
12
  public constructor (roles: string | string[], discovery: Promise<Component>) {
10
13
  this.roles = typeof roles === 'string' ? [roles] : roles
11
14
  this.discovery = discovery
15
+ this.dynamic = this.roles.some((role) => role.includes('{'))
12
16
  }
13
17
 
14
- public static async set (identity: Identity, discovery: Promise<Component>): Promise<void> {
18
+ public static async get (identity: Identity, discovery: Promise<Component>): Promise<string[]> {
15
19
  this.remote ??= await discovery
16
20
 
17
21
  const query: Query = {
@@ -19,40 +23,40 @@ export class Role implements Directive {
19
23
  limit: 1024
20
24
  }
21
25
 
22
- identity.roles = await this.remote.invoke('list', { query })
26
+ return await this.remote.invoke('list', { query })
23
27
  }
24
28
 
25
- public async authorize (identity: Identity | null): Promise<boolean> {
29
+ public async authorize
30
+ (identity: Identity | null, _: unknown, parameters: Parameter[]): Promise<boolean> {
26
31
  if (identity === null)
27
32
  return false
28
33
 
29
- await Role.set(identity, this.discovery)
34
+ identity.roles ??= await Role.get(identity, this.discovery)
30
35
 
31
- if (identity.roles === undefined)
32
- return false
33
-
34
- return this.match(identity.roles)
36
+ return this.match(identity.roles, parameters)
35
37
  }
36
38
 
37
- private match (roles: string[]): boolean {
39
+ private match (roles: string[], parameters: Parameter[]): boolean {
40
+ const required = this.dynamic ? this.substitute(parameters) : this.roles
41
+
38
42
  for (const role of roles) {
39
- const index = this.roles.findIndex((expected) => compare(expected, role))
43
+ const ok = required.some((expected) => expected === role || expected.startsWith(role + ':'))
40
44
 
41
- if (index !== -1)
45
+ if (ok)
42
46
  return true
43
47
  }
44
48
 
45
49
  return false
46
50
  }
47
- }
48
51
 
49
- function compare (expected: string, actual: string): boolean {
50
- const exp = expected.split(':')
51
- const act = actual.split(':')
52
+ private substitute (parameters: Parameter[]): string[] {
53
+ return this.roles.map((role) => role.replaceAll(/{(\w+)}/g, (_, key) => {
54
+ const value = parameters.find((parameter) => parameter.name === key)?.value
52
55
 
53
- for (let i = 0; i < act.length; i++)
54
- if (exp[i] !== act[i])
55
- return false
56
+ assert.ok(value !== undefined,
57
+ `Role '${role}' requires '${key}' route parameter`)
56
58
 
57
- return true
59
+ return value
60
+ }))
61
+ }
58
62
  }
@@ -1,5 +1,5 @@
1
1
  import { type Parameter } from '../../RTD'
2
- import type { Input, Directive, Identity } from './types'
2
+ import type { Context, Directive, Identity, Create } from './types'
3
3
 
4
4
  export class Rule implements Directive {
5
5
  private readonly directives: Directive[] = []
@@ -13,9 +13,9 @@ export class Rule implements Directive {
13
13
  }
14
14
 
15
15
  public async authorize
16
- (identity: Identity | null, input: Input, parameters: Parameter[]): Promise<boolean> {
16
+ (identity: Identity | null, context: Context, parameters: Parameter[]): Promise<boolean> {
17
17
  for (const directive of this.directives) {
18
- const authorized = await directive.authorize(identity, input, parameters)
18
+ const authorized = await directive.authorize(identity, context, parameters)
19
19
 
20
20
  if (!authorized)
21
21
  return false
@@ -24,5 +24,3 @@ export class Rule implements Directive {
24
24
  return true
25
25
  }
26
26
  }
27
-
28
- type Create = (name: string, value: any, ...args: any[]) => Directive
@@ -1,5 +1,5 @@
1
1
  import * as http from '../../HTTP'
2
- import { type Directive, type Identity, type Input } from './types'
2
+ import { type Directive, type Identity, type Context } from './types'
3
3
  import { split } from './split'
4
4
 
5
5
  export class Scheme implements Directive {
@@ -11,15 +11,15 @@ export class Scheme implements Directive {
11
11
  this.Scheme = scheme[0].toUpperCase() + scheme.substring(1)
12
12
  }
13
13
 
14
- public authorize (_: Identity | null, input: Input): boolean {
15
- if (input.request.headers.authorization === undefined)
14
+ public authorize (_: Identity | null, context: Context): boolean {
15
+ if (context.request.headers.authorization === undefined)
16
16
  return false
17
17
 
18
- const [scheme] = split(input.request.headers.authorization)
18
+ const [scheme] = split(context.request.headers.authorization)
19
19
 
20
20
  if (scheme !== this.scheme)
21
21
  throw new http.Forbidden(this.Scheme +
22
- ' authentication scheme is required to access this resource.')
22
+ ' authentication scheme is required to access this resource')
23
23
 
24
24
  return false
25
25
  }
@@ -0,0 +1,10 @@
1
+ import { newid } from '@toa.io/generic'
2
+ import type { Identity } from './types'
3
+
4
+ export function create (credentials?: string): Identity {
5
+ const scheme = credentials === undefined
6
+ ? null
7
+ : credentials.split(' ')[0]
8
+
9
+ return { id: newid(), scheme, refresh: false, roles: [] }
10
+ }
@@ -5,7 +5,7 @@ export function split (authorization: string): [Scheme, string] {
5
5
  const space = authorization.indexOf(' ')
6
6
 
7
7
  if (space === -1)
8
- throw new http.Unauthorized('Malformed authorization header.')
8
+ throw new http.Unauthorized('Malformed authorization header')
9
9
 
10
10
  const Scheme = authorization.slice(0, space)
11
11
  const scheme = Scheme.toLowerCase() as Scheme
@@ -5,21 +5,24 @@ import type * as http from '../../HTTP'
5
5
  import type * as io from '../../io'
6
6
 
7
7
  export interface Directive {
8
+ priority?: number
9
+
8
10
  authorize: (
9
11
  identity: Identity | null,
10
- input: Input,
11
- parameters: Parameter[],
12
+ context: Context,
13
+ parameters: Parameter[]
12
14
  ) => boolean | Promise<boolean>
13
15
 
14
- reply?: (identity: Identity | null) => http.OutgoingMessage
16
+ reply?: (context: Context) => http.OutgoingMessage | null
15
17
 
16
- settle?: (request: Input, response: http.OutgoingMessage) => Promise<void>
18
+ settle?: (context: Context, response: http.OutgoingMessage) => Promise<void>
17
19
  }
18
20
 
19
21
  export interface Identity {
20
22
  readonly id: string
21
- scheme: string
22
23
  roles?: string[]
24
+ permissions?: Record<string, string[]>
25
+ scheme: string | null // null for transient identities
23
26
  refresh: boolean
24
27
  }
25
28
 
@@ -31,10 +34,12 @@ export interface Ban {
31
34
  banned: boolean
32
35
  }
33
36
 
34
- export type Input = io.Input & Extension
37
+ export type Context = io.Input & Extension
35
38
  export type AuthenticationResult = Maybe<{ identity: Identity, refresh: boolean }>
36
39
 
37
40
  export type Scheme = 'basic' | 'token' | 'bearer'
38
41
  export type Remote = 'basic' | 'federation' | 'tokens' | 'roles' | 'bans'
39
42
  export type Discovery = Record<Remote, Promise<Component>>
40
43
  export type Schemes = Record<Scheme, Component>
44
+
45
+ export type Create = (name: string, value: any, ...args: any[]) => Directive
@@ -1,19 +1,19 @@
1
1
  import { Control } from './Control'
2
2
  import { Exact } from './Exact'
3
- import type { Input, Output } from '../../io'
4
- import type { Directive } from './types'
3
+ import type { Output } from '../../io'
4
+ import type { AuthenticatedContext, Directive } from './types'
5
5
  import type { DirectiveFamily } from '../../RTD'
6
6
  import type * as http from '../../HTTP'
7
7
 
8
8
  export class Cache implements DirectiveFamily<Directive> {
9
9
  public readonly name: string = 'cache'
10
- public readonly mandatory: boolean = false
10
+ public readonly mandatory: boolean = true
11
11
 
12
12
  public create (name: string, value: any): Directive {
13
13
  const Class = constructors[name]
14
14
 
15
15
  if (Class === undefined)
16
- throw new Error(`Directive '${name}' is not provided by the '${this.name}' family.`)
16
+ throw new Error(`Directive 'cache:${name}' is not implemented`)
17
17
 
18
18
  return new Class(value)
19
19
  }
@@ -23,9 +23,16 @@ export class Cache implements DirectiveFamily<Directive> {
23
23
  }
24
24
 
25
25
  public async settle
26
- (directives: Directive[], input: Input, response: http.OutgoingMessage): Promise<void> {
26
+ (directives: Directive[], context: AuthenticatedContext, response: http.OutgoingMessage): Promise<void> {
27
+ const directive = directives[0]
28
+
27
29
  response.headers ??= new Headers()
28
- directives[0]?.set(input, response.headers)
30
+
31
+ if (directive === undefined) {
32
+ if (context.identity !== null && !Control.disabled(response.headers))
33
+ response.headers.set('cache-control', 'private')
34
+ } else
35
+ directive.set(context, response.headers)
29
36
  }
30
37
  }
31
38
 
@@ -4,56 +4,82 @@ import type { AuthenticatedContext, Directive } from './types'
4
4
  export class Control implements Directive {
5
5
  protected readonly value: string
6
6
  private cache: string | null = null
7
+ private vary: boolean = false
7
8
 
8
9
  public constructor (value: string) {
9
10
  this.value = value
10
11
  }
11
12
 
13
+ public static disabled (headers: Headers): boolean {
14
+ const value = headers.get('cache-control')
15
+
16
+ if (value === null)
17
+ return false
18
+
19
+ const directives = mask(value)
20
+
21
+ return (directives & NO_STORE) === NO_STORE
22
+ }
23
+
12
24
  public set (context: AuthenticatedContext, headers: Headers): void {
13
25
  if (!['GET', 'HEAD', 'OPTIONS'].includes(context.request.method))
14
26
  return
15
27
 
16
28
  this.cache ??= this.resolve(context)
17
29
 
30
+ if (Control.disabled(headers))
31
+ return
32
+
18
33
  headers.set('cache-control', this.cache)
34
+
35
+ if (this.vary !== null)
36
+ headers.append('vary', 'authorization')
19
37
  }
20
38
 
21
39
  protected resolve (request: AuthenticatedContext): string {
22
40
  if (request.identity === null)
23
41
  return this.value
24
42
 
25
- const directives = this.mask()
43
+ const directives = mask(this.value)
44
+
45
+ if ((directives & PRIVATE) === PRIVATE)
46
+ this.vary = true
26
47
 
27
48
  if ((directives & (PUBLIC | NO_CACHE)) === PUBLIC)
28
49
  return 'no-cache, ' + this.value
29
50
 
30
- if ((directives & (PUBLIC | PRIVATE)) === 0)
51
+ if ((directives & (PUBLIC | PRIVATE)) === 0) {
52
+ this.vary = true
53
+
31
54
  return 'private, ' + this.value
55
+ }
32
56
 
33
57
  return this.value
34
58
  }
59
+ }
35
60
 
36
- private mask (): number {
37
- const directives = this.value.match(DIRECTIVES_RX)
61
+ function mask (value: string): number {
62
+ const directives = value.match(DIRECTIVES_RX)
38
63
 
39
- if (directives === null)
40
- return 0
64
+ if (directives === null)
65
+ return 0
41
66
 
42
- let mask = 0
67
+ let mask = 0
43
68
 
44
- for (const directive of directives)
45
- mask |= match<number>(directive,
46
- 'private', PRIVATE,
47
- 'public', PUBLIC,
48
- 'no-cache', NO_CACHE,
49
- 0)
69
+ for (const directive of directives)
70
+ mask |= match<number>(directive,
71
+ 'private', PRIVATE,
72
+ 'public', PUBLIC,
73
+ 'no-cache', NO_CACHE,
74
+ 'no-store', NO_STORE,
75
+ 0)
50
76
 
51
- return mask
52
- }
77
+ return mask
53
78
  }
54
79
 
55
- const DIRECTIVES_RX = /\b(private|public|no-cache)\b/ig
80
+ const DIRECTIVES_RX = /\b(private|public|no-cache|no-store)\b/ig
56
81
 
57
82
  const PUBLIC = 1
58
83
  const PRIVATE = 2
59
84
  const NO_CACHE = 4
85
+ const NO_STORE = 8
@@ -14,7 +14,7 @@ export class CORS implements Interceptor {
14
14
  ])
15
15
 
16
16
  private readonly headers = new Headers({
17
- 'access-control-allow-methods': 'GET, POST, PUT, PATCH, DELETE',
17
+ 'access-control-allow-methods': 'GET, POST, PUT, PATCH, DELETE, LOCK, UNLOCK',
18
18
  'access-control-allow-credentials': 'true',
19
19
  'access-control-allow-headers': Array.from(this.requestHeaders).join(', '),
20
20
  'access-control-max-age': '3600',
@@ -34,8 +34,9 @@ export class CORS implements Interceptor {
34
34
  input.pipelines.response.push((output) => {
35
35
  output.headers ??= new Headers()
36
36
  output.headers.set('access-control-allow-origin', origin)
37
+ output.headers.set('access-control-allow-credentials', 'true')
37
38
  output.headers.set('access-control-expose-headers',
38
- 'authorization, content-type, content-length, etag')
39
+ 'authorization, content-type, content-length, etag, last-modified')
39
40
 
40
41
  const method = input.request.method
41
42
 
@@ -1,5 +1,6 @@
1
1
  import { Stub } from './Stub'
2
2
  import { Throw } from './Throw'
3
+ import { Sleep } from './Sleep'
3
4
  import { type Directive } from './types'
4
5
  import type { Input, Output } from '../../io'
5
6
  import type { DirectiveFamily } from '../../RTD'
@@ -12,24 +13,28 @@ export class Development implements DirectiveFamily<Directive> {
12
13
  const Class = constructors[name]
13
14
 
14
15
  if (Class === undefined)
15
- throw new Error(`Directive '${name}' is not provided by the '${this.name}' family.`)
16
+ throw new Error(`Directive 'dev:${name}' is not implemented`)
16
17
 
17
18
  return new Class(value)
18
19
  }
19
20
 
20
- public preflight (directives: Directive[], input: Input): Output {
21
+ public async preflight (directives: Directive[], input: Input): Promise<Output> {
22
+ let output = null
23
+
21
24
  for (const directive of directives) {
22
- const output = directive.apply(input)
25
+ const out = await directive.apply(input)
23
26
 
24
- if (output !== null)
25
- return output
27
+ if (out !== null)
28
+ if (output !== null) throw new Error('`dev` directives ambiguous output')
29
+ else output = out
26
30
  }
27
31
 
28
- return null
32
+ return output
29
33
  }
30
34
  }
31
35
 
32
36
  const constructors: Record<string, new (value: any) => Directive> = {
33
37
  stub: Stub,
34
- throw: Throw
38
+ throw: Throw,
39
+ sleep: Sleep
35
40
  }