@toa.io/extensions.exposition 1.0.0-alpha.0 → 1.0.0-alpha.3

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 (449) hide show
  1. package/components/context.toa.yaml +12 -0
  2. package/components/identity.bans/manifest.toa.yaml +1 -1
  3. package/components/identity.basic/manifest.toa.yaml +2 -2
  4. package/components/identity.basic/operations/authenticate.d.ts +9 -0
  5. package/components/identity.basic/operations/authenticate.js +24 -0
  6. package/components/identity.basic/operations/authenticate.js.map +1 -0
  7. package/components/identity.basic/operations/create.d.ts +10 -0
  8. package/components/identity.basic/operations/create.js +10 -0
  9. package/components/identity.basic/operations/create.js.map +1 -0
  10. package/components/identity.basic/operations/transit.d.ts +12 -0
  11. package/components/identity.basic/operations/transit.js +53 -0
  12. package/components/identity.basic/operations/transit.js.map +1 -0
  13. package/components/identity.basic/operations/tsconfig.tsbuildinfo +1 -0
  14. package/components/identity.basic/operations/types.d.ts +38 -0
  15. package/components/identity.basic/operations/types.js +3 -0
  16. package/components/identity.basic/operations/types.js.map +1 -0
  17. package/components/identity.basic/source/authenticate.ts +0 -1
  18. package/components/identity.federation/events/principal.js +22 -0
  19. package/components/identity.federation/manifest.toa.yaml +100 -0
  20. package/components/identity.federation/operations/authenticate.d.ts +3 -0
  21. package/components/identity.federation/operations/authenticate.js +20 -0
  22. package/components/identity.federation/operations/authenticate.js.map +1 -0
  23. package/components/identity.federation/operations/create.d.ts +10 -0
  24. package/components/identity.federation/operations/create.js +15 -0
  25. package/components/identity.federation/operations/create.js.map +1 -0
  26. package/components/identity.federation/operations/lib/assertions-as-values.d.ts +4 -0
  27. package/components/identity.federation/operations/lib/assertions-as-values.js +45 -0
  28. package/components/identity.federation/operations/lib/assertions-as-values.js.map +1 -0
  29. package/components/identity.federation/operations/lib/jwt.d.ts +20 -0
  30. package/components/identity.federation/operations/lib/jwt.js +136 -0
  31. package/components/identity.federation/operations/lib/jwt.js.map +1 -0
  32. package/components/identity.federation/operations/schemas.d.ts +59 -0
  33. package/components/identity.federation/operations/schemas.js +9 -0
  34. package/components/identity.federation/operations/schemas.js.map +1 -0
  35. package/components/identity.federation/operations/tsconfig.tsbuildinfo +1 -0
  36. package/components/identity.federation/operations/types.d.ts +51 -0
  37. package/components/identity.federation/operations/types.js +3 -0
  38. package/components/identity.federation/operations/types.js.map +1 -0
  39. package/components/identity.federation/source/authenticate.ts +28 -0
  40. package/components/identity.federation/source/create.ts +26 -0
  41. package/components/identity.federation/source/lib/assertions-as-values.ts +19 -0
  42. package/components/identity.federation/source/lib/jwt.test.ts +56 -0
  43. package/components/identity.federation/source/lib/jwt.ts +171 -0
  44. package/components/identity.federation/source/schemas.ts +61 -0
  45. package/components/identity.federation/source/types.ts +56 -0
  46. package/components/identity.federation/tsconfig.json +9 -0
  47. package/components/identity.roles/operations/list.d.ts +5 -0
  48. package/components/identity.roles/operations/list.js +8 -0
  49. package/components/identity.roles/operations/list.js.map +1 -0
  50. package/components/identity.roles/operations/principal.d.ts +15 -0
  51. package/components/identity.roles/operations/principal.js +8 -0
  52. package/components/identity.roles/operations/principal.js.map +1 -0
  53. package/components/identity.roles/operations/tsconfig.tsbuildinfo +1 -0
  54. package/components/identity.tokens/manifest.toa.yaml +1 -1
  55. package/components/identity.tokens/operations/authenticate.d.ts +9 -0
  56. package/components/identity.tokens/operations/authenticate.js +32 -0
  57. package/components/identity.tokens/operations/authenticate.js.map +1 -0
  58. package/components/identity.tokens/operations/decrypt.d.ts +3 -0
  59. package/components/identity.tokens/operations/decrypt.js +32 -0
  60. package/components/identity.tokens/operations/decrypt.js.map +1 -0
  61. package/components/identity.tokens/operations/encrypt.d.ts +8 -0
  62. package/components/identity.tokens/operations/encrypt.js +22 -0
  63. package/components/identity.tokens/operations/encrypt.js.map +1 -0
  64. package/components/identity.tokens/operations/revoke.d.ts +2 -0
  65. package/components/identity.tokens/operations/revoke.js +8 -0
  66. package/components/identity.tokens/operations/revoke.js.map +1 -0
  67. package/components/identity.tokens/operations/tsconfig.tsbuildinfo +1 -0
  68. package/components/identity.tokens/operations/types.d.ts +40 -0
  69. package/components/identity.tokens/operations/types.js +3 -0
  70. package/components/identity.tokens/operations/types.js.map +1 -0
  71. package/components/octets.storage/manifest.toa.yaml +1 -0
  72. package/components/octets.storage/operations/store.js +2 -2
  73. package/cucumber.js +0 -1
  74. package/documentation/components.md +32 -2
  75. package/documentation/identity.md +14 -7
  76. package/documentation/octets.md +105 -40
  77. package/documentation/protocol.md +21 -1
  78. package/documentation/query.md +1 -1
  79. package/documentation/vary.md +69 -0
  80. package/features/cors.feature +72 -0
  81. package/features/identity.feature +19 -3
  82. package/features/identity.federation.feature +155 -0
  83. package/features/octets.entries.feature +121 -0
  84. package/features/octets.feature +2 -28
  85. package/features/octets.meta.feature +65 -0
  86. package/features/octets.workflows.feature +176 -4
  87. package/features/response.feature +65 -0
  88. package/features/routes.feature +37 -0
  89. package/features/steps/Captures.ts +6 -0
  90. package/features/steps/Components.ts +18 -6
  91. package/features/steps/Gateway.ts +1 -2
  92. package/features/steps/HTTP.ts +40 -87
  93. package/features/steps/IdP.ts +149 -0
  94. package/features/steps/Parameters.ts +8 -2
  95. package/features/steps/Workspace.ts +5 -7
  96. package/features/steps/components/echo/operations/error.js +11 -0
  97. package/features/steps/components/octets.tester/manifest.toa.yaml +3 -0
  98. package/features/steps/components/octets.tester/operations/concat.js +7 -0
  99. package/features/steps/components/octets.tester/operations/echo.js +7 -0
  100. package/features/steps/components/users/manifest.toa.yaml +3 -0
  101. package/features/steps/components/users.properties/manifest.toa.yaml +13 -0
  102. package/features/steps/tsconfig.json +1 -1
  103. package/features/vary.feature +150 -0
  104. package/package.json +17 -18
  105. package/schemas/octets/delete.cos.yaml +2 -1
  106. package/schemas/octets/list.cos.yaml +2 -1
  107. package/schemas/octets/workflow.cos.yaml +12 -0
  108. package/source/Directive.test.ts +8 -2
  109. package/source/Directive.ts +19 -16
  110. package/source/Factory.ts +8 -7
  111. package/source/Gateway.ts +22 -8
  112. package/source/HTTP/Server.fixtures.ts +0 -1
  113. package/source/HTTP/Server.test.ts +61 -134
  114. package/source/HTTP/Server.ts +91 -47
  115. package/source/HTTP/formats/msgpack.ts +9 -6
  116. package/source/HTTP/formats/text.ts +1 -1
  117. package/source/HTTP/formats/yaml.ts +1 -1
  118. package/source/HTTP/messages.ts +15 -3
  119. package/source/Interception.ts +24 -0
  120. package/source/RTD/Directives.ts +2 -2
  121. package/source/RTD/Tree.ts +3 -0
  122. package/source/RTD/syntax/parse.ts +6 -6
  123. package/source/RTD/syntax/types.ts +1 -1
  124. package/source/deployment.ts +1 -2
  125. package/source/directives/auth/{Family.ts → Authorization.ts} +29 -33
  126. package/source/directives/auth/Incept.ts +1 -1
  127. package/source/directives/auth/Rule.ts +2 -2
  128. package/source/directives/auth/index.ts +2 -2
  129. package/source/directives/auth/schemes.ts +2 -1
  130. package/source/directives/auth/types.ts +9 -6
  131. package/source/directives/cache/{Family.ts → Cache.ts} +4 -5
  132. package/source/directives/cache/index.ts +2 -2
  133. package/source/directives/cache/types.ts +1 -1
  134. package/source/directives/cors/CORS.ts +54 -0
  135. package/source/directives/cors/index.ts +3 -0
  136. package/source/directives/dev/{Family.ts → Development.ts} +3 -4
  137. package/source/directives/dev/Stub.ts +4 -4
  138. package/source/directives/dev/Throw.ts +4 -4
  139. package/source/directives/dev/index.ts +2 -2
  140. package/source/directives/dev/types.ts +1 -1
  141. package/source/directives/index.ts +10 -6
  142. package/source/directives/octets/Context.ts +1 -1
  143. package/source/directives/octets/Delete.ts +50 -9
  144. package/source/directives/octets/Fetch.ts +18 -19
  145. package/source/directives/octets/List.ts +37 -7
  146. package/source/directives/octets/{Family.ts → Octets.ts} +10 -7
  147. package/source/directives/octets/Permute.ts +3 -3
  148. package/source/directives/octets/Store.ts +57 -99
  149. package/source/directives/octets/Workflow.ts +41 -0
  150. package/source/directives/octets/index.ts +2 -2
  151. package/source/directives/octets/schemas.test.ts +21 -0
  152. package/source/directives/octets/schemas.ts +13 -6
  153. package/source/directives/octets/types.ts +4 -3
  154. package/source/directives/octets/workflows/Execution.ts +76 -0
  155. package/source/directives/octets/workflows/Workflow.ts +37 -0
  156. package/source/directives/octets/workflows/index.ts +1 -0
  157. package/source/directives/vary/Directive.ts +6 -0
  158. package/source/directives/vary/Embed.ts +62 -0
  159. package/source/directives/vary/Properties.ts +17 -0
  160. package/source/directives/vary/Vary.ts +48 -0
  161. package/source/directives/vary/embeddings/Embedding.ts +6 -0
  162. package/source/directives/vary/embeddings/Header.ts +30 -0
  163. package/source/directives/vary/embeddings/Language.ts +31 -0
  164. package/source/directives/vary/embeddings/index.ts +11 -0
  165. package/source/directives/vary/index.ts +3 -0
  166. package/source/io.ts +4 -0
  167. package/source/manifest.test.ts +6 -14
  168. package/source/manifest.ts +9 -6
  169. package/source/schemas.ts +7 -3
  170. package/transpiled/Annotation.d.ts +7 -0
  171. package/transpiled/Annotation.js +3 -0
  172. package/transpiled/Annotation.js.map +1 -0
  173. package/transpiled/Branch.d.ts +7 -0
  174. package/transpiled/Branch.js +3 -0
  175. package/transpiled/Branch.js.map +1 -0
  176. package/transpiled/Composition.d.ts +14 -0
  177. package/transpiled/Composition.js +43 -0
  178. package/transpiled/Composition.js.map +1 -0
  179. package/transpiled/Context.d.ts +5 -0
  180. package/transpiled/Context.js +3 -0
  181. package/transpiled/Context.js.map +1 -0
  182. package/transpiled/Directive.d.ts +31 -0
  183. package/transpiled/Directive.js +78 -0
  184. package/transpiled/Directive.js.map +1 -0
  185. package/transpiled/Endpoint.d.ts +20 -0
  186. package/transpiled/Endpoint.js +45 -0
  187. package/transpiled/Endpoint.js.map +1 -0
  188. package/transpiled/Factory.d.ts +9 -0
  189. package/transpiled/Factory.js +67 -0
  190. package/transpiled/Factory.js.map +1 -0
  191. package/transpiled/Gateway.d.ts +22 -0
  192. package/transpiled/Gateway.js +102 -0
  193. package/transpiled/Gateway.js.map +1 -0
  194. package/transpiled/HTTP/Server.d.ts +24 -0
  195. package/transpiled/HTTP/Server.fixtures.d.ts +10 -0
  196. package/transpiled/HTTP/Server.fixtures.js +31 -0
  197. package/transpiled/HTTP/Server.fixtures.js.map +1 -0
  198. package/transpiled/HTTP/Server.js +149 -0
  199. package/transpiled/HTTP/Server.js.map +1 -0
  200. package/transpiled/HTTP/exceptions.d.ts +34 -0
  201. package/transpiled/HTTP/exceptions.js +71 -0
  202. package/transpiled/HTTP/exceptions.js.map +1 -0
  203. package/transpiled/HTTP/formats/index.d.ts +10 -0
  204. package/transpiled/HTTP/formats/index.js +38 -0
  205. package/transpiled/HTTP/formats/index.js.map +1 -0
  206. package/transpiled/HTTP/formats/json.d.ts +6 -0
  207. package/transpiled/HTTP/formats/json.js +17 -0
  208. package/transpiled/HTTP/formats/json.js.map +1 -0
  209. package/transpiled/HTTP/formats/msgpack.d.ts +6 -0
  210. package/transpiled/HTTP/formats/msgpack.js +17 -0
  211. package/transpiled/HTTP/formats/msgpack.js.map +1 -0
  212. package/transpiled/HTTP/formats/text.d.ts +8 -0
  213. package/transpiled/HTTP/formats/text.js +15 -0
  214. package/transpiled/HTTP/formats/text.js.map +1 -0
  215. package/transpiled/HTTP/formats/yaml.d.ts +6 -0
  216. package/transpiled/HTTP/formats/yaml.js +41 -0
  217. package/transpiled/HTTP/formats/yaml.js.map +1 -0
  218. package/transpiled/HTTP/index.d.ts +3 -0
  219. package/transpiled/HTTP/index.js +20 -0
  220. package/transpiled/HTTP/index.js.map +1 -0
  221. package/transpiled/HTTP/messages.d.ts +33 -0
  222. package/transpiled/HTTP/messages.js +75 -0
  223. package/transpiled/HTTP/messages.js.map +1 -0
  224. package/transpiled/Interception.d.ts +9 -0
  225. package/transpiled/Interception.js +19 -0
  226. package/transpiled/Interception.js.map +1 -0
  227. package/transpiled/Mapping.d.ts +8 -0
  228. package/transpiled/Mapping.js +38 -0
  229. package/transpiled/Mapping.js.map +1 -0
  230. package/transpiled/Query.d.ts +13 -0
  231. package/transpiled/Query.js +107 -0
  232. package/transpiled/Query.js.map +1 -0
  233. package/transpiled/RTD/Context.d.ts +11 -0
  234. package/transpiled/RTD/Context.js +3 -0
  235. package/transpiled/RTD/Context.js.map +1 -0
  236. package/transpiled/RTD/Directives.d.ts +7 -0
  237. package/transpiled/RTD/Directives.js +3 -0
  238. package/transpiled/RTD/Directives.js.map +1 -0
  239. package/transpiled/RTD/Endpoint.d.ts +9 -0
  240. package/transpiled/RTD/Endpoint.js +3 -0
  241. package/transpiled/RTD/Endpoint.js.map +1 -0
  242. package/transpiled/RTD/Match.d.ts +11 -0
  243. package/transpiled/RTD/Match.js +3 -0
  244. package/transpiled/RTD/Match.js.map +1 -0
  245. package/transpiled/RTD/Method.d.ts +9 -0
  246. package/transpiled/RTD/Method.js +16 -0
  247. package/transpiled/RTD/Method.js.map +1 -0
  248. package/transpiled/RTD/Node.d.ts +21 -0
  249. package/transpiled/RTD/Node.js +61 -0
  250. package/transpiled/RTD/Node.js.map +1 -0
  251. package/transpiled/RTD/Route.d.ts +14 -0
  252. package/transpiled/RTD/Route.js +49 -0
  253. package/transpiled/RTD/Route.js.map +1 -0
  254. package/transpiled/RTD/Tree.d.ts +14 -0
  255. package/transpiled/RTD/Tree.js +42 -0
  256. package/transpiled/RTD/Tree.js.map +1 -0
  257. package/transpiled/RTD/factory.d.ts +6 -0
  258. package/transpiled/RTD/factory.js +36 -0
  259. package/transpiled/RTD/factory.js.map +1 -0
  260. package/transpiled/RTD/index.d.ts +8 -0
  261. package/transpiled/RTD/index.js +38 -0
  262. package/transpiled/RTD/index.js.map +1 -0
  263. package/transpiled/RTD/segment.d.ts +8 -0
  264. package/transpiled/RTD/segment.js +25 -0
  265. package/transpiled/RTD/segment.js.map +1 -0
  266. package/transpiled/RTD/syntax/index.d.ts +2 -0
  267. package/transpiled/RTD/syntax/index.js +19 -0
  268. package/transpiled/RTD/syntax/index.js.map +1 -0
  269. package/transpiled/RTD/syntax/parse.d.ts +4 -0
  270. package/transpiled/RTD/syntax/parse.js +128 -0
  271. package/transpiled/RTD/syntax/parse.js.map +1 -0
  272. package/transpiled/RTD/syntax/types.d.ts +41 -0
  273. package/transpiled/RTD/syntax/types.js +5 -0
  274. package/transpiled/RTD/syntax/types.js.map +1 -0
  275. package/transpiled/Remotes.d.ts +9 -0
  276. package/transpiled/Remotes.js +25 -0
  277. package/transpiled/Remotes.js.map +1 -0
  278. package/transpiled/Tenant.d.ts +13 -0
  279. package/transpiled/Tenant.js +34 -0
  280. package/transpiled/Tenant.js.map +1 -0
  281. package/transpiled/deployment.d.ts +3 -0
  282. package/transpiled/deployment.js +66 -0
  283. package/transpiled/deployment.js.map +1 -0
  284. package/transpiled/directives/auth/Anonymous.d.ts +6 -0
  285. package/transpiled/directives/auth/Anonymous.js +17 -0
  286. package/transpiled/directives/auth/Anonymous.js.map +1 -0
  287. package/transpiled/directives/auth/Authorization.d.ts +20 -0
  288. package/transpiled/directives/auth/Authorization.js +125 -0
  289. package/transpiled/directives/auth/Authorization.js.map +1 -0
  290. package/transpiled/directives/auth/Echo.d.ts +6 -0
  291. package/transpiled/directives/auth/Echo.js +13 -0
  292. package/transpiled/directives/auth/Echo.js.map +1 -0
  293. package/transpiled/directives/auth/Id.d.ts +7 -0
  294. package/transpiled/directives/auth/Id.js +17 -0
  295. package/transpiled/directives/auth/Id.js.map +1 -0
  296. package/transpiled/directives/auth/Incept.d.ts +10 -0
  297. package/transpiled/directives/auth/Incept.js +58 -0
  298. package/transpiled/directives/auth/Incept.js.map +1 -0
  299. package/transpiled/directives/auth/Role.d.ts +11 -0
  300. package/transpiled/directives/auth/Role.js +44 -0
  301. package/transpiled/directives/auth/Role.js.map +1 -0
  302. package/transpiled/directives/auth/Rule.d.ts +9 -0
  303. package/transpiled/directives/auth/Rule.js +22 -0
  304. package/transpiled/directives/auth/Rule.js.map +1 -0
  305. package/transpiled/directives/auth/Scheme.d.ts +7 -0
  306. package/transpiled/directives/auth/Scheme.js +47 -0
  307. package/transpiled/directives/auth/Scheme.js.map +1 -0
  308. package/transpiled/directives/auth/index.d.ts +2 -0
  309. package/transpiled/directives/auth/index.js +6 -0
  310. package/transpiled/directives/auth/index.js.map +1 -0
  311. package/transpiled/directives/auth/schemes.d.ts +3 -0
  312. package/transpiled/directives/auth/schemes.js +10 -0
  313. package/transpiled/directives/auth/schemes.js.map +1 -0
  314. package/transpiled/directives/auth/split.d.ts +2 -0
  315. package/transpiled/directives/auth/split.js +38 -0
  316. package/transpiled/directives/auth/split.js.map +1 -0
  317. package/transpiled/directives/auth/types.d.ts +31 -0
  318. package/transpiled/directives/auth/types.js +3 -0
  319. package/transpiled/directives/auth/types.js.map +1 -0
  320. package/transpiled/directives/cache/Cache.d.ts +11 -0
  321. package/transpiled/directives/cache/Cache.js +28 -0
  322. package/transpiled/directives/cache/Cache.js.map +1 -0
  323. package/transpiled/directives/cache/Control.d.ts +9 -0
  324. package/transpiled/directives/cache/Control.js +42 -0
  325. package/transpiled/directives/cache/Control.js.map +1 -0
  326. package/transpiled/directives/cache/Exact.d.ts +4 -0
  327. package/transpiled/directives/cache/Exact.js +11 -0
  328. package/transpiled/directives/cache/Exact.js.map +1 -0
  329. package/transpiled/directives/cache/index.d.ts +2 -0
  330. package/transpiled/directives/cache/index.js +6 -0
  331. package/transpiled/directives/cache/index.js.map +1 -0
  332. package/transpiled/directives/cache/types.d.ts +7 -0
  333. package/transpiled/directives/cache/types.js +3 -0
  334. package/transpiled/directives/cache/types.js.map +1 -0
  335. package/transpiled/directives/cors/CORS.d.ts +11 -0
  336. package/transpiled/directives/cors/CORS.js +44 -0
  337. package/transpiled/directives/cors/CORS.js.map +1 -0
  338. package/transpiled/directives/cors/index.d.ts +2 -0
  339. package/transpiled/directives/cors/index.js +6 -0
  340. package/transpiled/directives/cors/index.js.map +1 -0
  341. package/transpiled/directives/dev/Development.d.ts +9 -0
  342. package/transpiled/directives/dev/Development.js +29 -0
  343. package/transpiled/directives/dev/Development.js.map +1 -0
  344. package/transpiled/directives/dev/Stub.d.ts +7 -0
  345. package/transpiled/directives/dev/Stub.js +14 -0
  346. package/transpiled/directives/dev/Stub.js.map +1 -0
  347. package/transpiled/directives/dev/Throw.d.ts +7 -0
  348. package/transpiled/directives/dev/Throw.js +14 -0
  349. package/transpiled/directives/dev/Throw.js.map +1 -0
  350. package/transpiled/directives/dev/index.d.ts +2 -0
  351. package/transpiled/directives/dev/index.js +6 -0
  352. package/transpiled/directives/dev/index.js.map +1 -0
  353. package/transpiled/directives/dev/types.d.ts +4 -0
  354. package/transpiled/directives/dev/types.js +3 -0
  355. package/transpiled/directives/dev/types.js.map +1 -0
  356. package/transpiled/directives/index.d.ts +4 -0
  357. package/transpiled/directives/index.js +12 -0
  358. package/transpiled/directives/index.js.map +1 -0
  359. package/transpiled/directives/octets/Context.d.ts +8 -0
  360. package/transpiled/directives/octets/Context.js +40 -0
  361. package/transpiled/directives/octets/Context.js.map +1 -0
  362. package/transpiled/directives/octets/Delete.d.ts +19 -0
  363. package/transpiled/directives/octets/Delete.js +72 -0
  364. package/transpiled/directives/octets/Delete.js.map +1 -0
  365. package/transpiled/directives/octets/Fetch.d.ts +17 -0
  366. package/transpiled/directives/octets/Fetch.js +76 -0
  367. package/transpiled/directives/octets/Fetch.js.map +1 -0
  368. package/transpiled/directives/octets/List.d.ts +15 -0
  369. package/transpiled/directives/octets/List.js +65 -0
  370. package/transpiled/directives/octets/List.js.map +1 -0
  371. package/transpiled/directives/octets/Octets.d.ts +12 -0
  372. package/transpiled/directives/octets/Octets.js +53 -0
  373. package/transpiled/directives/octets/Octets.js.map +1 -0
  374. package/transpiled/directives/octets/Permute.d.ts +10 -0
  375. package/transpiled/directives/octets/Permute.js +51 -0
  376. package/transpiled/directives/octets/Permute.js.map +1 -0
  377. package/transpiled/directives/octets/Store.d.ts +23 -0
  378. package/transpiled/directives/octets/Store.js +88 -0
  379. package/transpiled/directives/octets/Store.js.map +1 -0
  380. package/transpiled/directives/octets/Workflow.d.ts +14 -0
  381. package/transpiled/directives/octets/Workflow.js +52 -0
  382. package/transpiled/directives/octets/Workflow.js.map +1 -0
  383. package/transpiled/directives/octets/index.d.ts +2 -0
  384. package/transpiled/directives/octets/index.js +6 -0
  385. package/transpiled/directives/octets/index.js.map +1 -0
  386. package/transpiled/directives/octets/schemas.d.ts +13 -0
  387. package/transpiled/directives/octets/schemas.js +18 -0
  388. package/transpiled/directives/octets/schemas.js.map +1 -0
  389. package/transpiled/directives/octets/types.d.ts +10 -0
  390. package/transpiled/directives/octets/types.js +3 -0
  391. package/transpiled/directives/octets/types.js.map +1 -0
  392. package/transpiled/directives/octets/workflows/Execution.d.ts +25 -0
  393. package/transpiled/directives/octets/workflows/Execution.js +54 -0
  394. package/transpiled/directives/octets/workflows/Execution.js.map +1 -0
  395. package/transpiled/directives/octets/workflows/Workflow.d.ts +12 -0
  396. package/transpiled/directives/octets/workflows/Workflow.js +25 -0
  397. package/transpiled/directives/octets/workflows/Workflow.js.map +1 -0
  398. package/transpiled/directives/octets/workflows/index.d.ts +1 -0
  399. package/transpiled/directives/octets/workflows/index.js +6 -0
  400. package/transpiled/directives/octets/workflows/index.js.map +1 -0
  401. package/transpiled/directives/vary/Directive.d.ts +5 -0
  402. package/transpiled/directives/vary/Directive.js +3 -0
  403. package/transpiled/directives/vary/Directive.js.map +1 -0
  404. package/transpiled/directives/vary/Embed.d.ts +10 -0
  405. package/transpiled/directives/vary/Embed.js +49 -0
  406. package/transpiled/directives/vary/Embed.js.map +1 -0
  407. package/transpiled/directives/vary/Properties.d.ts +9 -0
  408. package/transpiled/directives/vary/Properties.js +16 -0
  409. package/transpiled/directives/vary/Properties.js.map +1 -0
  410. package/transpiled/directives/vary/Vary.d.ts +10 -0
  411. package/transpiled/directives/vary/Vary.js +36 -0
  412. package/transpiled/directives/vary/Vary.js.map +1 -0
  413. package/transpiled/directives/vary/embeddings/Embedding.d.ts +5 -0
  414. package/transpiled/directives/vary/embeddings/Embedding.js +3 -0
  415. package/transpiled/directives/vary/embeddings/Embedding.js.map +1 -0
  416. package/transpiled/directives/vary/embeddings/Header.d.ts +7 -0
  417. package/transpiled/directives/vary/embeddings/Header.js +26 -0
  418. package/transpiled/directives/vary/embeddings/Header.js.map +1 -0
  419. package/transpiled/directives/vary/embeddings/Language.d.ts +7 -0
  420. package/transpiled/directives/vary/embeddings/Language.js +28 -0
  421. package/transpiled/directives/vary/embeddings/Language.js.map +1 -0
  422. package/transpiled/directives/vary/embeddings/index.d.ts +5 -0
  423. package/transpiled/directives/vary/embeddings/index.js +10 -0
  424. package/transpiled/directives/vary/embeddings/index.js.map +1 -0
  425. package/transpiled/directives/vary/index.d.ts +2 -0
  426. package/transpiled/directives/vary/index.js +6 -0
  427. package/transpiled/directives/vary/index.js.map +1 -0
  428. package/transpiled/discovery.d.ts +1 -0
  429. package/transpiled/discovery.js +3 -0
  430. package/transpiled/discovery.js.map +1 -0
  431. package/transpiled/exceptions.d.ts +2 -0
  432. package/transpiled/exceptions.js +39 -0
  433. package/transpiled/exceptions.js.map +1 -0
  434. package/transpiled/index.d.ts +5 -0
  435. package/transpiled/index.js +12 -0
  436. package/transpiled/index.js.map +1 -0
  437. package/transpiled/io.d.ts +3 -0
  438. package/transpiled/io.js +3 -0
  439. package/transpiled/io.js.map +1 -0
  440. package/transpiled/manifest.d.ts +3 -0
  441. package/transpiled/manifest.js +66 -0
  442. package/transpiled/manifest.js.map +1 -0
  443. package/transpiled/root.d.ts +2 -0
  444. package/transpiled/root.js +39 -0
  445. package/transpiled/root.js.map +1 -0
  446. package/transpiled/schemas.d.ts +7 -0
  447. package/transpiled/schemas.js +14 -0
  448. package/transpiled/schemas.js.map +1 -0
  449. package/transpiled/tsconfig.tsbuildinfo +1 -0
@@ -2,7 +2,7 @@ Feature: Octets storage workflows
2
2
 
3
3
  Scenario: Running a workflow
4
4
  Given the `octets.tester` is running
5
- Given the annotation:
5
+ And the annotation:
6
6
  """yaml
7
7
  /:
8
8
  auth:anonymous: true
@@ -47,8 +47,8 @@ Feature: Octets storage workflows
47
47
  """
48
48
  When the following request is received:
49
49
  """
50
- GET /10cf16b458f759e0d617f2f3d83599ff:meta HTTP/1.1
51
- accept: application/yaml
50
+ GET /10cf16b458f759e0d617f2f3d83599ff HTTP/1.1
51
+ accept: application/vnd.toa.octets.entry+yaml
52
52
  """
53
53
  Then the following reply is sent:
54
54
  """
@@ -74,7 +74,7 @@ Feature: Octets storage workflows
74
74
  content-length: 473831
75
75
  """
76
76
 
77
- Scenario: Getting error when adding metadata to a file
77
+ Scenario: Getting error when running workflow on `store`
78
78
  Given the `octets.tester` is running
79
79
  Given the annotation:
80
80
  """yaml
@@ -112,3 +112,175 @@ Feature: Octets storage workflows
112
112
  message: Something went wrong
113
113
  --cut--
114
114
  """
115
+
116
+ Scenario: Running a workflow on `delete`
117
+ Given the `octets.tester` is running
118
+ And the annotation:
119
+ """yaml
120
+ /:
121
+ auth:anonymous: true
122
+ octets:context: octets
123
+ POST:
124
+ octets:store: ~
125
+ /*:
126
+ GET:
127
+ octets:fetch: ~
128
+ DELETE:
129
+ octets:delete:
130
+ workflow:
131
+ echo: octets.tester.echo
132
+ """
133
+ When the stream of `lenna.ascii` is received with the following headers:
134
+ """
135
+ POST / HTTP/1.1
136
+ content-type: application/octet-stream
137
+ """
138
+ Then the following reply is sent:
139
+ """
140
+ 201 Created
141
+ """
142
+ When the following request is received:
143
+ """
144
+ DELETE /10cf16b458f759e0d617f2f3d83599ff HTTP/1.1
145
+ accept: application/yaml
146
+ """
147
+ Then the following reply is sent:
148
+ """
149
+ 202 Accepted
150
+ content-type: multipart/yaml; boundary=cut
151
+
152
+ --cut
153
+ echo: 10cf16b458f759e0d617f2f3d83599ff
154
+ --cut--
155
+ """
156
+ When the following request is received:
157
+ """
158
+ GET /10cf16b458f759e0d617f2f3d83599ff HTTP/1.1
159
+ """
160
+ Then the following reply is sent:
161
+ """
162
+ 404 Not Found
163
+ """
164
+
165
+ Scenario: Error in the workflow on `delete`
166
+ Given the `octets.tester` is running
167
+ And the annotation:
168
+ """yaml
169
+ /:
170
+ auth:anonymous: true
171
+ octets:context: octets
172
+ POST:
173
+ octets:store: ~
174
+ /*:
175
+ GET:
176
+ octets:fetch: ~
177
+ DELETE:
178
+ octets:delete:
179
+ workflow:
180
+ err: octets.tester.err
181
+ """
182
+ When the stream of `lenna.ascii` is received with the following headers:
183
+ """
184
+ POST / HTTP/1.1
185
+ content-type: application/octet-stream
186
+ """
187
+ Then the following reply is sent:
188
+ """
189
+ 201 Created
190
+ """
191
+ When the following request is received:
192
+ """
193
+ DELETE /10cf16b458f759e0d617f2f3d83599ff HTTP/1.1
194
+ accept: application/yaml
195
+ """
196
+ Then the following reply is sent:
197
+ """
198
+ 202 Accepted
199
+ content-type: multipart/yaml; boundary=cut
200
+
201
+ --cut
202
+ error:
203
+ step: err
204
+ code: ERROR
205
+ message: Something went wrong
206
+ --cut--
207
+ """
208
+ When the following request is received:
209
+ """
210
+ GET /10cf16b458f759e0d617f2f3d83599ff HTTP/1.1
211
+ """
212
+ Then the following reply is sent:
213
+ """
214
+ 200 OK
215
+ """
216
+
217
+ Scenario: Passing parameters to the workflow
218
+ Given the `octets.tester` is running
219
+ And the annotation:
220
+ """yaml
221
+ /:
222
+ /:a/:b:
223
+ auth:anonymous: true
224
+ octets:context: octets
225
+ POST:
226
+ octets:store:
227
+ workflow:
228
+ concat: octets.tester.concat
229
+ """
230
+ When the stream of `lenna.ascii` is received with the following headers:
231
+ """
232
+ POST /hello/world/ HTTP/1.1
233
+ accept: application/yaml
234
+ content-type: application/octet-stream
235
+ """
236
+ Then the following reply is sent:
237
+ """
238
+ 201 Created
239
+ content-type: multipart/yaml; boundary=cut
240
+
241
+ --cut
242
+ id: 10cf16b458f759e0d617f2f3d83599ff
243
+ type: application/octet-stream
244
+ size: 8169
245
+ --cut
246
+ concat: hello world
247
+ --cut--
248
+ """
249
+
250
+ Scenario: Executing a workflow with `octets:workflow`
251
+ Given the `octets.tester` is running
252
+ And the annotation:
253
+ """yaml
254
+ /:
255
+ auth:anonymous: true
256
+ octets:context: octets
257
+ POST:
258
+ octets:store: ~
259
+ /*:
260
+ DELETE:
261
+ octets:workflow:
262
+ echo: octets.tester.echo
263
+ """
264
+ When the stream of `lenna.ascii` is received with the following headers:
265
+ """
266
+ POST / HTTP/1.1
267
+ content-type: application/octet-stream
268
+ """
269
+ Then the following reply is sent:
270
+ """
271
+ 201 Created
272
+ """
273
+ When the following request is received:
274
+ """
275
+ DELETE /10cf16b458f759e0d617f2f3d83599ff HTTP/1.1
276
+ accept: application/yaml
277
+ """
278
+ Then the following reply is sent:
279
+ """
280
+ 202 Accepted
281
+ content-type: multipart/yaml; boundary=cut
282
+
283
+ --cut
284
+ echo: 10cf16b458f759e0d617f2f3d83599ff
285
+ --cut--
286
+ """
@@ -0,0 +1,65 @@
1
+ Feature: Response
2
+
3
+ Scenario: Content negotiation
4
+ Given the annotation:
5
+ """yaml
6
+ /:
7
+ GET:
8
+ anonymous: true
9
+ dev:stub: hello
10
+ """
11
+ When the following request is received:
12
+ """
13
+ GET / HTTP/1.1
14
+ accept: application/json
15
+ """
16
+ Then the following reply is sent:
17
+ """
18
+ 200 OK
19
+ content-type: application/json
20
+ vary: accept
21
+ """
22
+
23
+ Scenario: Error as YAML
24
+ Given the `echo` is running with the following manifest:
25
+ """yaml
26
+ exposition:
27
+ /:
28
+ GET: error
29
+ """
30
+ When the following request is received:
31
+ """
32
+ GET /echo/ HTTP/1.1
33
+ accept: application/yaml
34
+ """
35
+ Then the following reply is sent:
36
+ """
37
+ 409 Conflict
38
+ content-type: application/yaml
39
+
40
+ code: CODE
41
+ message: message
42
+ """
43
+
44
+ Scenario: Error as MessagePack
45
+ Given the `echo` is running with the following manifest:
46
+ """yaml
47
+ exposition:
48
+ /:
49
+ GET: error
50
+ """
51
+ When the following request is received:
52
+ """
53
+ GET /echo/ HTTP/1.1
54
+ accept: application/msgpack
55
+ """
56
+ Then the following reply is sent:
57
+ """
58
+ 409 Conflict
59
+ content-type: application/msgpack
60
+ """
61
+ And response body contains MessagePack-encoded value:
62
+ """yaml
63
+ code: CODE
64
+ message: message
65
+ """
@@ -87,3 +87,40 @@ Feature: Routes
87
87
 
88
88
  Hello
89
89
  """
90
+
91
+ Scenario: Routes with naming conflicts
92
+ Given the Gateway is running
93
+ And the `users` is running with the following manifest:
94
+ """yaml
95
+ exposition:
96
+ /:
97
+ POST: create
98
+ """
99
+ And the `users.properties` is running with the following manifest:
100
+ """yaml
101
+ exposition:
102
+ /:id:
103
+ GET: observe
104
+ """
105
+ When the following request is received:
106
+ """
107
+ GET /users/properties/b5534021e30042259badffbd1831e472/ HTTP/1.1
108
+ accept: application/yaml
109
+ """
110
+ Then the following reply is sent:
111
+ """
112
+ 200 OK
113
+
114
+ newbie: false
115
+ """
116
+ When the following request is received:
117
+ """
118
+ POST /users/ HTTP/1.1
119
+ content-type: application/yaml
120
+
121
+ name: Alice
122
+ """
123
+ Then the following reply is sent:
124
+ """
125
+ 201 Created
126
+ """
@@ -0,0 +1,6 @@
1
+ import * as http from '@toa.io/agent'
2
+ import { binding } from 'cucumber-tsflow'
3
+
4
+ @binding()
5
+ export class Captures extends http.Captures {
6
+ }
@@ -1,3 +1,4 @@
1
+ import * as assert from 'node:assert'
1
2
  import { after, binding, given } from 'cucumber-tsflow'
2
3
  import * as boot from '@toa.io/boot'
3
4
  import { timeout } from '@toa.io/generic'
@@ -8,7 +9,7 @@ import { Workspace } from './Workspace'
8
9
  @binding([Workspace])
9
10
  export class Components {
10
11
  private readonly workspace: Workspace
11
- private composition: Connector | null = null
12
+ private compositions: Record<string, Connector> = {}
12
13
 
13
14
  public constructor (workspace: Workspace) {
14
15
  this.workspace = workspace
@@ -26,18 +27,29 @@ export class Components {
26
27
  await this.runComponent(name, manifest)
27
28
  }
28
29
 
29
- @after()
30
30
  @given('the `{word}` is stopped')
31
- public async stop (_?: string): Promise<void> {
32
- await this.composition?.disconnect()
31
+ public async stop (name: string): Promise<void> {
32
+ assert.ok(name in this.compositions, `Composition '${name}' is not running`)
33
+
34
+ await this.compositions[name].disconnect()
35
+ delete this.compositions[name]
36
+ }
37
+
38
+ @after()
39
+ public async shutdown (): Promise<void> {
40
+ const promises = Object.values(this.compositions).map((composition) => composition.disconnect())
41
+
42
+ await Promise.all(promises)
33
43
  }
34
44
 
35
45
  private async runComponent (name: string, manifest?: object): Promise<void> {
46
+ assert.ok(!(name in this.compositions), `Composition '${name}' is already running`)
47
+
36
48
  const path = await this.workspace.addComponent(name, manifest)
37
49
 
38
- this.composition = await boot.composition([path])
50
+ this.compositions[name] = await boot.composition([path])
39
51
 
40
- await this.composition.connect()
52
+ await this.compositions[name].connect()
41
53
  await timeout(50) // discovery
42
54
  }
43
55
  }
@@ -18,8 +18,7 @@ export class Gateway {
18
18
  const annotation = parse(yaml)
19
19
 
20
20
  if ('/' in annotation) {
21
- const node = { '/': annotation['/'] }
22
- const tree = syntax.parse(node, shortcuts)
21
+ const tree = syntax.parse(annotation['/'], shortcuts)
23
22
 
24
23
  process.env.TOA_EXPOSITION = encode(tree)
25
24
  }
@@ -1,121 +1,74 @@
1
- import { AssertionError } from 'node:assert'
1
+ import * as assert from 'node:assert'
2
+ import * as fs from 'node:fs'
3
+ import * as path from 'node:path'
2
4
  import { binding, then, when } from 'cucumber-tsflow'
3
- import * as http from '@toa.io/http'
4
- import { trim } from '@toa.io/generic'
5
- import { buffer } from '@toa.io/streams'
6
- import { open } from '../../../storages/source/test/util'
5
+ import * as http from '@toa.io/agent'
6
+ import * as msgpack from 'msgpackr'
7
+ import * as YAML from 'js-yaml'
8
+ import { Captures } from './Captures'
7
9
  import { Parameters } from './Parameters'
8
10
  import { Gateway } from './Gateway'
11
+ import type { Readable } from 'node:stream'
9
12
 
10
- @binding([Gateway, Parameters])
11
- export class HTTP {
13
+ @binding([Gateway, Parameters, Captures])
14
+ export class HTTP extends http.Agent {
12
15
  private readonly gateway: Gateway
13
- private readonly origin: string
14
- private response: string = ''
15
- private readonly variables: Record<string, string> = {}
16
+ private fetched: Response | null = null
16
17
 
17
- public constructor (gateway: Gateway, parameters: Parameters) {
18
+ public constructor (gateway: Gateway, parameters: Parameters, captures: Captures) {
19
+ super(parameters.origin, captures)
18
20
  this.gateway = gateway
19
- this.origin = parameters.origin
20
21
  }
21
22
 
22
23
  @when('the following request is received:')
23
- public async request (input: string): Promise<any> {
24
- let [headers, body] = trim(input).split('\n\n')
25
-
26
- if (body !== undefined)
27
- headers += '\ncontent-length: ' + body?.length
28
-
29
- const text = headers + '\n\n' + (body ?? '')
30
- const request = text.replaceAll(SUBSTITUTE, (_, name) => this.variables[name])
31
-
24
+ public override async request (input: string): Promise<any> {
32
25
  await this.gateway.start()
33
-
34
- this.response = await http.request(request, this.origin)
26
+ this.fetched = await super.request(input)
35
27
  }
36
28
 
37
29
  @then('the following reply is sent:')
38
- public responseIncludes (expected: string): void {
39
- const lines = trim(expected).split('\n')
40
-
41
- for (const line of lines) {
42
- const escaped = line.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
43
-
44
- const expression = escaped.replace(CAPTURE,
45
- (_, name) => `(?<${name}>\\S{1,2048})`)
30
+ public override responseIncludes (expected: string): void {
31
+ super.responseIncludes(expected)
32
+ }
46
33
 
47
- const rx = new RegExp(expression, 'i')
48
- const match = this.response.match(rx)
34
+ @then('response body contains {word}-encoded value:')
35
+ public async bodyIs (format: string, yaml: string): Promise<void> {
36
+ assert.ok(this.fetched !== null, 'Response is null')
49
37
 
50
- if (match === null)
51
- throw new AssertionError({
52
- message: `Response is missing '${line}'`,
53
- expected: line,
54
- actual: this.response
55
- })
38
+ const buf = await this.fetched.arrayBuffer()
39
+ const value = encoders[format]?.(buf as Buffer)
40
+ const expected = YAML.load(yaml)
56
41
 
57
- Object.assign(this.variables, match.groups)
58
- }
42
+ assert.deepEqual(value, expected, 'Values are not equal')
59
43
  }
60
44
 
61
45
  @then('the reply does not contain:')
62
- public responseExcludes (expected: string): void {
63
- const lines = trim(expected).split('\n')
64
-
65
- for (const line of lines) {
66
- line.replace(SUBSTITUTE, (_, name) => this.variables[name])
67
-
68
- const includes = this.response.includes(line)
69
-
70
- if (includes)
71
- throw new AssertionError({
72
- message: `Response contains '${line}'`,
73
- expected: line,
74
- actual: this.response
75
- })
76
- }
46
+ public override responseExcludes (expected: string): void {
47
+ super.responseExcludes(expected)
77
48
  }
78
49
 
79
50
  @when('the stream of `{word}` is received with the following headers:')
80
51
  public async streamRequest (filename: string, head: string): Promise<any> {
81
- head = trim(head) + '\n\n'
52
+ const stream = open(filename)
82
53
 
83
54
  await this.gateway.start()
84
-
85
- const { url, method, headers } = http.parse.request(head)
86
- const href = new URL(url, this.origin).href
87
- const body = open(filename)
88
-
89
- headers.connection = 'close' // required for interrupted streams
90
-
91
- const request = {
92
- method,
93
- headers,
94
- body: body as unknown as ReadableStream,
95
- duplex: 'half'
96
- }
97
-
98
- try {
99
- const response = await fetch(href, request)
100
-
101
- this.response = await http.parse.response(response)
102
- } catch (e: any) {
103
- console.error(e)
104
- console.error(e.cause)
105
-
106
- throw e
107
- }
55
+ await super.stream(head, stream)
108
56
  }
109
57
 
110
58
  @then('the stream equals to `{word}` is sent with the following headers:')
111
59
  public async responseStreamMatch (filename: string, head: string): Promise<any> {
112
- const buf = await buffer(open(filename))
113
- const text = buf.toString('utf8')
114
- const expected = head + '\n\n' + text
60
+ const stream = open(filename)
115
61
 
116
- this.responseIncludes(expected)
62
+ await super.streamMatch(head, stream)
117
63
  }
118
64
  }
119
65
 
120
- const CAPTURE = /\\\$\\{\\{ (?<name>[A-Za-z_]{0,32}) \\}\\}/g
121
- const SUBSTITUTE = /\${{ (?<name>[A-Za-z_]{0,32}) }}/g
66
+ const FILEDIR = path.resolve(__dirname, '../../../storages/source/test')
67
+
68
+ function open (filename: string): Readable {
69
+ return fs.createReadStream(path.join(FILEDIR, filename))
70
+ }
71
+
72
+ const encoders: Record<string, (buf: Buffer | Uint8Array) => any> = {
73
+ MessagePack: msgpack.decode
74
+ }
@@ -0,0 +1,149 @@
1
+ import { once } from 'node:events'
2
+ import * as crypto from 'node:crypto'
3
+ import * as http from 'node:http'
4
+ import * as assert from 'node:assert'
5
+ import * as util from 'node:util'
6
+ import { binding, given, afterAll } from 'cucumber-tsflow'
7
+ import { Captures } from './Captures'
8
+
9
+ import type { AddressInfo } from 'node:net'
10
+
11
+ @binding([Captures])
12
+ export class IdP {
13
+ private static server?: http.Server
14
+ private static privateKey?: crypto.KeyObject
15
+ private static issuer?: string
16
+
17
+ public constructor (private readonly captures: Captures) {}
18
+
19
+ @afterAll()
20
+ public static async stop (): Promise<void> {
21
+ if (this.server instanceof http.Server) {
22
+ this.server.close()
23
+ await once(this.server, 'close')
24
+ }
25
+ }
26
+
27
+ @given(/local IDP is running/i)
28
+ public async start (): Promise<void> {
29
+ if (IdP.server instanceof http.Server) return
30
+
31
+ // creating the key
32
+ const { publicKey, privateKey } = await util.promisify(crypto.generateKeyPair)('rsa', {
33
+ modulusLength: 2048
34
+ })
35
+
36
+ IdP.privateKey = privateKey
37
+
38
+ const jwk = JSON.stringify({
39
+ keys: [{ use: 'sig', alg: 'RS256', ...publicKey.export({ format: 'jwk' }) }]
40
+ })
41
+
42
+ const JWK_URL = '/.well-known/jwks'
43
+
44
+ const server = http.createServer((request, response) => {
45
+ switch (request.url) {
46
+ case JWK_URL:
47
+ response.writeHead(200, {
48
+ 'Content-Type': 'application/json',
49
+ 'Content-Length': jwk.length,
50
+ 'Cache-Control': 'no-cache, no-store, must-revalidate',
51
+ Pragma: 'no-cache',
52
+ Expires: '0'
53
+ })
54
+ response.end(jwk)
55
+ break
56
+
57
+ case '/.well-known/openid-configuration':
58
+ {
59
+ const openIdConfiguration = JSON.stringify({
60
+ issuer: IdP.issuer,
61
+ jwks_uri: IdP.issuer + JWK_URL,
62
+ response_types_supported: ['id_token'],
63
+ subject_types_supported: ['public'],
64
+ id_token_signing_alg_values_supported: ['RS256'],
65
+ scopes_supported: ['openid']
66
+ })
67
+
68
+ response.writeHead(200, {
69
+ 'Content-Type': 'application/json',
70
+ 'Cache-Control': 'public, max-age=3600',
71
+ 'Content-Length': openIdConfiguration.length
72
+ })
73
+ response.end(openIdConfiguration)
74
+ }
75
+
76
+ break
77
+
78
+ default:
79
+ response.writeHead(404, 'Not found')
80
+ response.end()
81
+ }
82
+ })
83
+
84
+ server.listen(44444, 'localhost')
85
+ await once(server, 'listening')
86
+
87
+ const address = server.address() as AddressInfo
88
+
89
+ console.log('IdP is listening on %s:%s', address.address, address.port)
90
+ IdP.server = server
91
+ IdP.issuer = `http://localhost:${address.port}`
92
+ }
93
+
94
+ @given('the IDP token for {word} is issued')
95
+ public async issueToken (user: string): Promise<void> {
96
+ assert.ok(IdP.privateKey, 'IdP private key is not available')
97
+
98
+ const jwt = [
99
+ {
100
+ typ: 'JWT',
101
+ alg: 'RS256'
102
+ },
103
+ {
104
+ iss: IdP.issuer,
105
+ sub: `${user}-mock-id`,
106
+ aud: 'test',
107
+ iat: Math.floor(Date.now() / 1000),
108
+ exp: Math.floor((Date.now() + 1000 * 60 * 5) / 1000)
109
+ }
110
+ ]
111
+ .map((v) => Buffer.from(JSON.stringify(v)).toString('base64url'))
112
+ .join('.')
113
+
114
+ const signature = crypto.createSign('RSA-SHA256').end(jwt).sign(IdP.privateKey, 'base64url')
115
+
116
+ const idToken = `${jwt}.${signature}`
117
+
118
+ this.captures.set(`${user}.id_token`, idToken)
119
+ }
120
+
121
+ @given('the IDP {word} token for {word} is issued with following secret:')
122
+ public async issueSymmetricToken (alg: string, user: string, secret: string): Promise<void> {
123
+ console.log('Sym token for %s with secret "%s"', user, secret)
124
+
125
+ const jwt = [
126
+ {
127
+ typ: 'JWT',
128
+ alg
129
+ },
130
+ {
131
+ iss: IdP.issuer,
132
+ sub: `${user}-mock-id`,
133
+ aud: 'test',
134
+ iat: Math.floor(Date.now() / 1000),
135
+ exp: Math.floor((Date.now() + 1000 * 60 * 5) / 1000)
136
+ }
137
+ ]
138
+ .map((v) => Buffer.from(JSON.stringify(v)).toString('base64url'))
139
+ .join('.')
140
+
141
+ const signature = crypto.createHmac(alg.replace(/^HS(\d{3})$/, 'sha$1'), secret)
142
+ .update(jwt)
143
+ .digest('base64url')
144
+
145
+ const idToken = `${jwt}.${signature}`
146
+
147
+ this.captures.set(`${user}.id_token`, idToken)
148
+ }
149
+ }