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

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 +112 -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 +35 -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 +78 -40
  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 +7 -0
  442. package/transpiled/directives/dev/Sleep.js +32 -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,33 +1,104 @@
1
1
  import { V3 } from 'paseto'
2
- import { type Maybe } from '@toa.io/types'
3
- import { type Context, type Claim, type DecryptOutput } from './types'
2
+ import { Err } from 'error-value'
3
+ import { LRUCache } from 'lru-cache'
4
+ import type { Maybe, Operation } from '@toa.io/types'
5
+ import type { Context, Claims, DecryptOutput } from './lib'
4
6
 
5
- export async function computation (token: string, context: Context):
6
- Promise<Maybe<DecryptOutput>> {
7
- let refresh = false
8
- let claim = await decrypt(token, context.configuration.key0)
7
+ export class Computation implements Operation {
8
+ private keys: Record<string, Key> = {}
9
+ private cache!: LRUCache<string, KeyEntry>
10
+ private latest!: string
11
+ private remote!: Context['remote']['identity']['keys']
9
12
 
10
- if (claim === null && context.configuration.key1 !== undefined) {
11
- refresh = true
12
- claim = await decrypt(token, context.configuration.key1)
13
+ public mount (context: Context): void {
14
+ this.latest = Object.keys(context.configuration.keys)[0]
15
+ this.remote = context.remote.identity.keys
16
+ this.cache = new LRUCache<string, KeyEntry>(context.configuration.cache)
17
+
18
+ for (const [kid, key] of Object.entries(context.configuration.keys))
19
+ this.keys[kid] = { key }
13
20
  }
14
21
 
15
- if (claim === null)
16
- return ERR_INVALID_TOKEN
17
- else return {
18
- identity: claim.identity,
19
- iat: claim.iat,
20
- exp: claim.exp,
21
- refresh
22
+ public async execute (token: string): Promise<Maybe<DecryptOutput>> {
23
+ const kid = this.kid(token)
24
+
25
+ if (kid instanceof Error)
26
+ return kid
27
+
28
+ const key = await this.key(kid)
29
+
30
+ if (key instanceof Error)
31
+ return key
32
+
33
+ const claims = await decrypt(token, key.key)
34
+
35
+ if (claims instanceof Error)
36
+ return claims
37
+
38
+ if (key.identity !== undefined && claims.identity.id !== key.identity)
39
+ return ERR_FORGED_KEY
40
+
41
+ return {
42
+ iss: claims.iss,
43
+ iat: claims.iat,
44
+ exp: claims.exp,
45
+ identity: claims.identity,
46
+ refresh: kid !== this.latest && key.identity === undefined
47
+ }
48
+ }
49
+
50
+ private kid (token: string): Maybe<string> {
51
+ const [, , , footer] = token.split('.')
52
+
53
+ if (footer === undefined)
54
+ return ERR_INVALID_TOKEN
55
+
56
+ try {
57
+ const json = Buffer.from(footer, 'base64url').toString('utf-8')
58
+ const { kid } = JSON.parse(json)
59
+
60
+ if (typeof kid !== 'string')
61
+ return ERR_INVALID_TOKEN
62
+
63
+ return kid
64
+ } catch {
65
+ return ERR_INVALID_TOKEN
66
+ }
67
+ }
68
+
69
+ private async key (kid: string): Promise<Maybe<Key>> {
70
+ if (kid in this.keys)
71
+ return this.keys[kid]
72
+
73
+ if (!this.cache.has(kid)) {
74
+ const value = await this.remote.observe({ query: { id: kid } })
75
+
76
+ this.cache.set(kid, { value })
77
+ }
78
+
79
+ const entry = this.cache.get(kid)
80
+
81
+ return entry?.value ?? ERR_INVALID_KEY
22
82
  }
23
83
  }
24
84
 
25
- async function decrypt (token: string, key: string): Promise<Claim | null> {
85
+ async function decrypt (token: string, key: string): Promise<Maybe<Claims>> {
26
86
  try {
27
- return await V3.decrypt<Claim>(token, key)
87
+ return await V3.decrypt<Claims>(token, key)
28
88
  } catch {
29
- return null
89
+ return ERR_INVALID_TOKEN
30
90
  }
31
91
  }
32
92
 
33
- const ERR_INVALID_TOKEN = new Error('INVALID_TOKEN')
93
+ interface Key {
94
+ key: string
95
+ identity?: string
96
+ }
97
+
98
+ interface KeyEntry {
99
+ value: Key | null
100
+ }
101
+
102
+ const ERR_INVALID_TOKEN = new Err('INVALID_TOKEN')
103
+ const ERR_INVALID_KEY = new Err('INVALID_KEY')
104
+ const ERR_FORGED_KEY = new Err('FORGED_KEY')
@@ -1,35 +1,90 @@
1
+ import assert from 'node:assert'
1
2
  import { generate } from 'randomstring'
2
3
  import { timeout } from '@toa.io/generic'
3
4
  import { Effect as Encrypt } from './encrypt'
4
- import { computation as decrypt } from './decrypt'
5
- import { type Context, type Identity } from './types'
5
+ import { Computation as Decrypt } from './decrypt'
6
+ import { type Context, type Identity } from './lib'
6
7
 
7
8
  let encrypt: Encrypt
9
+ let decrypt: Decrypt
8
10
 
9
- const context: Context = {} as unknown as Context
11
+ const context: Context = { remote: { identity: { keys: null } } } as unknown as Context
12
+ const authority = generate()
10
13
 
11
14
  beforeEach(() => {
12
15
  context.configuration = {
13
- key0: 'k3.local.m28p8SrbS467t-2IUjQuSOqmjvi24TbXhyjAW_dOrog',
14
- lifetime: 1000,
15
- refresh: 2
16
+ keys: {
17
+ key0: 'k3.local.m28p8SrbS467t-2IUjQuSOqmjvi24TbXhyjAW_dOrog'
18
+ },
19
+ lifetime: 1,
20
+ refresh: 2,
21
+ cache: {
22
+ max: 1024,
23
+ ttl: 3
24
+ }
16
25
  }
17
26
 
18
27
  encrypt = new Encrypt()
19
28
  encrypt.mount(context)
29
+
30
+ decrypt = new Decrypt()
31
+ decrypt.mount(context)
32
+ })
33
+
34
+ it('should encrypt with configured lifetime by default', async () => {
35
+ const identity: Identity = { id: generate(), roles: [] }
36
+
37
+ const encrypted = await encrypt.execute({
38
+ authority,
39
+ identity
40
+ })
41
+
42
+ if (encrypted instanceof Error)
43
+ throw encrypted
44
+
45
+ await expect(decrypt.execute(encrypted)).resolves.toMatchObject({ iss: authority, identity })
46
+
47
+ await timeout(context.configuration.lifetime * 1000)
48
+
49
+ await expect(decrypt.execute(encrypted)).resolves.toMatchObject({ code: 'INVALID_TOKEN' })
20
50
  })
21
51
 
22
52
  it('should encrypt with given lifetime', async () => {
23
- const identity: Identity = { id: generate() }
53
+ const identity: Identity = { id: generate(), roles: [] }
24
54
  const lifetime = 0.1
25
- const encrypted = await encrypt.execute({ identity, lifetime })
26
55
 
27
- if (encrypted === undefined)
28
- throw new Error('?')
56
+ const encrypted = await encrypt.execute({
57
+ authority,
58
+ identity,
59
+ lifetime
60
+ })
29
61
 
30
- await expect(decrypt(encrypted, context)).resolves.toMatchObject({ identity })
62
+ if (encrypted instanceof Error)
63
+ throw encrypted
64
+
65
+ await expect(decrypt.execute(encrypted)).resolves.toMatchObject({ iss: authority, identity })
31
66
 
32
67
  await timeout(lifetime * 1000)
33
68
 
34
- await expect(decrypt(encrypted, context)).resolves.toMatchObject({ message: 'INVALID_TOKEN' })
69
+ await expect(decrypt.execute(encrypted)).resolves.toMatchObject({ code: 'INVALID_TOKEN' })
70
+ })
71
+
72
+ it('should encrypt without lifetime INSECURE', async () => {
73
+ const identity: Identity = { id: generate(), roles: [] }
74
+ const lifetime = 0
75
+
76
+ const encrypted = await encrypt.execute({
77
+ authority,
78
+ identity,
79
+ lifetime
80
+ })
81
+
82
+ if (encrypted instanceof Error)
83
+ throw encrypted
84
+
85
+ const decrypted = await decrypt.execute(encrypted)
86
+
87
+ assert.ok(!(decrypted instanceof Error))
88
+
89
+ expect(decrypted.identity).toMatchObject(identity)
35
90
  })
@@ -1,25 +1,53 @@
1
1
  import { V3 } from 'paseto'
2
- import { type Operation } from '@toa.io/types'
3
- import { type Claim, type Context, type EncryptInput } from './types'
2
+ import { Err } from 'error-value'
3
+ import type { Operation, Maybe } from '@toa.io/types'
4
+ import type { Identity, Claims, Context, EncryptInput, Key } from './lib'
4
5
 
5
6
  export class Effect implements Operation {
6
- private key: string = ''
7
- private lifetime: number = 0
7
+ private key!: Pick<Key, 'id' | 'key'>
8
+ private lifetime!: number
8
9
 
9
10
  public mount (context: Context): void {
10
- this.key = context.configuration.key0
11
+ const [id, secret] = Object.entries(context.configuration.keys)[0]
12
+
13
+ this.key = { id, key: secret }
11
14
  this.lifetime = context.configuration.lifetime * 1000
12
15
  }
13
16
 
14
- public async execute (input: EncryptInput): Promise<string> {
15
- const lifetime = input.lifetime === undefined ? this.lifetime : input.lifetime * 1000
17
+ public async execute (input: EncryptInput): Promise<Maybe<string>> {
18
+ if (input.scopes?.some((scope) => !within(scope, input.identity.roles)) === true)
19
+ return ERR_INACCESSIBLE_SCOPE
20
+
21
+ const lifetime = input.lifetime === undefined ? this.lifetime : (input.lifetime * 1000)
16
22
 
17
23
  const exp = lifetime === 0
18
24
  ? undefined
19
25
  : new Date(Date.now() + lifetime).toISOString()
20
26
 
21
- const payload: Partial<Claim> = { identity: input.identity, exp }
27
+ const identity: Identity = {
28
+ id: input.identity.id,
29
+ roles: input.scopes ?? input.identity.roles
30
+ }
31
+
32
+ if (input.permissions !== undefined)
33
+ identity.permissions = input.permissions
34
+
35
+ const payload: Partial<Claims> = {
36
+ identity,
37
+ iss: input.authority
38
+ }
39
+
40
+ if (exp !== undefined)
41
+ payload.exp = exp
22
42
 
23
- return await V3.encrypt(payload, this.key)
43
+ const key = input.key ?? this.key
44
+
45
+ return await V3.encrypt(payload, key.key, { footer: { kid: key.id } })
24
46
  }
25
47
  }
48
+
49
+ function within (scope: string, roles: string[]): boolean {
50
+ return roles.some((role) => role === scope || scope.startsWith(role + ':'))
51
+ }
52
+
53
+ const ERR_INACCESSIBLE_SCOPE = new Err('INACCESSIBLE_SCOPE')
@@ -0,0 +1,80 @@
1
+ import type { Maybe, Operation } from '@toa.io/types'
2
+ import type { Context, Identity } from './lib'
3
+
4
+ export class Effect implements Operation {
5
+ private keys!: Context['remote']['identity']['keys']
6
+ private roles!: Context['remote']['identity']['roles']
7
+ private encrypt!: Context['local']['encrypt']
8
+ private lifetime!: number
9
+
10
+ public mount (context: Context): void {
11
+ this.keys = context.remote.identity.keys
12
+ this.roles = context.remote.identity.roles
13
+ this.encrypt = context.local.encrypt
14
+ this.lifetime = context.configuration.lifetime * 1000
15
+ }
16
+
17
+ public async execute (input: Input): Promise<Maybe<Output>> {
18
+ const expires = input.lifetime === 0
19
+ ? undefined
20
+ : new Date(Date.now() + input.lifetime * 1000).getTime()
21
+
22
+ const key = await this.keys.create({
23
+ input: {
24
+ identity: input.identity,
25
+ label: input.label,
26
+ expires
27
+ }
28
+ })
29
+
30
+ const roles = await this.roles.list({
31
+ query: {
32
+ criteria: `identity==${input.identity}`,
33
+ limit: 1024
34
+ }
35
+ })
36
+
37
+ const identity: Identity = {
38
+ id: input.identity,
39
+ roles
40
+ }
41
+
42
+ const { authority, lifetime, scopes, permissions } = input
43
+
44
+ const token = await this.encrypt({
45
+ input: {
46
+ authority,
47
+ identity,
48
+ lifetime,
49
+ scopes,
50
+ permissions,
51
+ key
52
+ }
53
+ })
54
+
55
+ if (token instanceof Error)
56
+ return token
57
+
58
+ return {
59
+ kid: key.id,
60
+ // technically, the token expires some time later
61
+ ...(expires !== undefined && { exp: expires }),
62
+ token
63
+ }
64
+ }
65
+ }
66
+
67
+ interface Input {
68
+ authority: string
69
+ identity: string
70
+ lifetime: number
71
+ label: string
72
+ scopes?: string[]
73
+ permissions?: Record<string, string[]>
74
+ }
75
+
76
+ interface Output {
77
+ kid: string
78
+ exp?: number
79
+ token: string
80
+ }
@@ -0,0 +1,2 @@
1
+ export * from './pad'
2
+ export * from './types'
@@ -0,0 +1 @@
1
+ export const PAD = 'v3.local.'
@@ -0,0 +1,16 @@
1
+ import { V3 } from 'paseto'
2
+
3
+ it('should be ok', async () => {
4
+ const payload = { iss: 'test', sub: 'me' }
5
+ const key = await V3.generateKey('local', { format: 'paserk' })
6
+ const token = await V3.encrypt(payload, key, { footer: 'key0' })
7
+ const [, , , footer] = token.split('.')
8
+ const kid = Buffer.from(footer, 'base64url').toString('utf-8')
9
+
10
+ console.log(footer, kid)
11
+ console.log(key)
12
+
13
+ const decrypted = await V3.decrypt(token, key)
14
+
15
+ console.log(decrypted)
16
+ })
@@ -0,0 +1,85 @@
1
+ import type { Call, Maybe, Observation } from '@toa.io/types'
2
+
3
+ export interface Context {
4
+ local: {
5
+ observe: Observation<Entity>
6
+ encrypt: Call<Maybe<string>, EncryptInput>
7
+ decrypt: Call<Maybe<DecryptOutput>, string>
8
+ }
9
+ remote: {
10
+ identity: {
11
+ keys: {
12
+ observe: Observation<CustomKey>
13
+ create: Call<Key>
14
+ }
15
+ roles: {
16
+ list: Call<string[]>
17
+ }
18
+ }
19
+ }
20
+ configuration: Configuration
21
+ }
22
+
23
+ export interface Configuration {
24
+ readonly keys: Record<string, string>
25
+ readonly lifetime: number
26
+ readonly refresh: number
27
+ readonly cache: {
28
+ max: number
29
+ ttl: number
30
+ }
31
+ }
32
+
33
+ export interface Entity {
34
+ revokedAt?: number
35
+ }
36
+
37
+ export interface Identity extends Record<string, any> {
38
+ id: string
39
+ roles: string[]
40
+ permissions?: Record<string, string[]>
41
+ }
42
+
43
+ export interface AuthenticateInput {
44
+ authority: string
45
+ credentials: string
46
+ }
47
+
48
+ export interface AuthenticateOutput {
49
+ identity: Identity
50
+ refresh: boolean
51
+ }
52
+
53
+ export interface EncryptInput {
54
+ authority: string
55
+ identity: Identity
56
+ lifetime?: number
57
+ scopes?: string[]
58
+ permissions?: Record<string, string[]>
59
+ key?: Key
60
+ }
61
+
62
+ export interface DecryptOutput {
63
+ iss: string
64
+ iat: string
65
+ exp?: string
66
+ identity: Identity
67
+ refresh: boolean
68
+ }
69
+
70
+ export interface Claims {
71
+ identity: Identity
72
+ iss: string
73
+ iat: string
74
+ exp?: string
75
+ }
76
+
77
+ export interface Key {
78
+ id: string
79
+ key: string
80
+ label: string
81
+ }
82
+
83
+ export interface CustomKey extends Key {
84
+ identity: string
85
+ }
@@ -1,5 +1,5 @@
1
- import { type Entity } from './types'
1
+ import type { Entity } from './lib'
2
2
 
3
- export function transition (_: never, object: Entity): void {
3
+ export function transition (_: unknown, object: Entity): void {
4
4
  object.revokedAt = Date.now()
5
5
  }
@@ -4,24 +4,24 @@ name: storage
4
4
  storages: ~
5
5
 
6
6
  operations:
7
- store:
7
+ put:
8
8
  bindings: ~
9
9
  input:
10
10
  storage*: string
11
11
  request*: ~
12
+ location: string
12
13
  accept: string
13
- meta: <string>
14
- fetch: &simple
14
+ limit: number
15
+ trust: ~ # array of strings or regular expressions
16
+ errors:
17
+ - LOCATION_UNTRUSTED
18
+ - LOCATION_LENGTH
19
+ - LOCATION_UNAVAILABLE
20
+ - INVALID_ID
21
+ get: &simple
15
22
  bindings: ~
16
23
  input:
17
24
  storage*: string
18
25
  path*: string
19
- get: *simple
20
- list: *simple
26
+ head: *simple
21
27
  delete: *simple
22
- permute:
23
- bindings: ~
24
- input:
25
- storage*: string
26
- path*: string
27
- list*: [string]
@@ -1,7 +1,7 @@
1
1
  'use strict'
2
2
 
3
- function get (input, context) {
4
- return context.storages[input.storage].get(input.path)
3
+ async function get (input, context) {
4
+ return await context.storages[input.storage].get(input.path)
5
5
  }
6
6
 
7
- exports.computation = get
7
+ exports.effect = get
@@ -0,0 +1,7 @@
1
+ 'use strict'
2
+
3
+ async function head (input, context) {
4
+ return await context.storages[input.storage].head(input.path)
5
+ }
6
+
7
+ exports.computation = head
@@ -0,0 +1,135 @@
1
+ 'use strict'
2
+
3
+ const { Readable } = require('node:stream')
4
+ const { posix } = require('node:path')
5
+ const { Err } = require('error-value')
6
+ const { match } = require('matchacho')
7
+
8
+ async function put (input, context) {
9
+ const { storage, request, location, accept, limit, trust } = input
10
+ const url = request.url
11
+ const id = request.headers['content-id']
12
+ const claim = request.headers['content-type']
13
+ const attributes = parseAttributes(request.headers['content-attributes'])
14
+ const reference = request.headers['content-location']
15
+
16
+ /** @type {Readable} */
17
+ let body = request
18
+
19
+ const options = { claim, accept, attributes }
20
+
21
+ if (id !== undefined) {
22
+ if (!ID_RX.test(id))
23
+ return ERR_INVALID_ID
24
+
25
+ options.id = id
26
+ }
27
+
28
+ if (reference !== undefined) {
29
+ const length = Number.parseInt(request.headers['content-length'])
30
+
31
+ if (length !== 0)
32
+ return ERR_LENGTH
33
+
34
+ if (!trusted(reference, trust))
35
+ return ERR_UNTRUSTED
36
+
37
+ body = await download(reference)
38
+
39
+ if (body instanceof Error)
40
+ return body
41
+
42
+ options.origin = reference
43
+ }
44
+
45
+ if (limit !== undefined)
46
+ options.limit = limit
47
+
48
+ const path = posix.resolve(url, location ?? '.')
49
+
50
+ return context.storages[storage].put(path, body, options)
51
+ }
52
+
53
+ /**
54
+ * @param {string | string[] | undefined} values
55
+ * @returns {Record<string, string>}
56
+ */
57
+ function parseAttributes (values) {
58
+ const attributes = {}
59
+
60
+ if (values === undefined)
61
+ return attributes
62
+
63
+ if (typeof values === 'string')
64
+ values = values.split(',')
65
+
66
+ for (const pair of values) {
67
+ const eq = pair.indexOf('=')
68
+ const key = (eq === -1 ? pair : pair.slice(0, eq)).trim()
69
+
70
+ attributes[key] = eq === -1 ? 'true' : pair.slice(eq + 1).trim()
71
+ }
72
+
73
+ return attributes
74
+ }
75
+
76
+ /**
77
+ * @param {string} location
78
+ * @return {Readable | Error}
79
+ */
80
+ async function download (location) {
81
+ const response = await fetch(location)
82
+
83
+ if (!response.ok)
84
+ return ERR_UNAVAILABLE
85
+
86
+ return response.body === null ? ERR_UNAVAILABLE : Readable.fromWeb(
87
+ /** @type {import('node:stream/web').ReadableStream} **/ response.body)
88
+
89
+ }
90
+
91
+ /**
92
+ * @param {string} location
93
+ * @param {Trust | undefined} trust
94
+ * @return {boolean}
95
+ */
96
+ function trusted (location, trust) {
97
+ if (trust === undefined)
98
+ return false
99
+
100
+ const url = toURL(location)
101
+
102
+ if (url === null)
103
+ return false
104
+
105
+ for (const permission of trust) {
106
+ const ok = match(permission,
107
+ String, (origin) => url.origin === origin,
108
+ RegExp, (pattern) => pattern.test(url.origin))
109
+
110
+ if (ok)
111
+ return true
112
+ }
113
+
114
+ return false
115
+ }
116
+
117
+ function toURL (location) {
118
+ try {
119
+ return new URL(location)
120
+ } catch (error) {
121
+ return null
122
+ }
123
+ }
124
+
125
+ const ERR_UNTRUSTED = new Err('LOCATION_UNTRUSTED', 'Location is not trusted')
126
+ const ERR_LENGTH = new Err('LOCATION_LENGTH', 'Content-Length must be 0 when Content-Location is used')
127
+ const ERR_UNAVAILABLE = new Err('LOCATION_UNAVAILABLE', 'Location is not available')
128
+ const ERR_INVALID_ID = new Err('INVALID_ID', 'Invalid Content-ID')
129
+
130
+ const ID_RX = /^[a-zA-Z0-9-_]{1,32}$/
131
+
132
+ exports.effect = put
133
+
134
+ /** @typedef {Array<string | RegExp>} Trust */
135
+ /** @typedef {import('node:stream').Readable} Readable */