@toa.io/extensions.exposition 1.0.0-alpha.11 → 1.0.0-alpha.111

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 (601) 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 +9 -7
  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 +10 -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 +132 -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/flow.md +44 -0
  129. package/documentation/identity.md +29 -22
  130. package/documentation/introspection.md +82 -0
  131. package/documentation/map.md +73 -0
  132. package/documentation/octets.md +100 -68
  133. package/documentation/protocol.md +14 -4
  134. package/documentation/query.md +29 -4
  135. package/documentation/require.md +15 -0
  136. package/documentation/tree.md +13 -0
  137. package/features/access.feature +129 -48
  138. package/features/annotation.feature +1 -0
  139. package/features/auth.claims.feature +171 -0
  140. package/features/auth.incept.feature +89 -0
  141. package/features/auth.input.feature +59 -0
  142. package/features/authorities.basic.feature +141 -0
  143. package/features/authorities.feature +32 -0
  144. package/features/authorities.federation.feature +100 -0
  145. package/features/authorities.tokens.feature +117 -0
  146. package/features/body.feature +2 -0
  147. package/features/cache.feature +109 -5
  148. package/features/cors.feature +8 -2
  149. package/features/debug.feature +34 -0
  150. package/features/directives.feature +3 -0
  151. package/features/dynamic.feature +48 -0
  152. package/features/errors.feature +32 -7
  153. package/features/etag.feature +109 -1
  154. package/features/flow.feature +96 -0
  155. package/features/identity.bans.feature +137 -0
  156. package/features/identity.basic.feature +85 -28
  157. package/features/identity.feature +18 -6
  158. package/features/identity.federation.feature +89 -18
  159. package/features/identity.roles.feature +112 -19
  160. package/features/identity.tokens.feature +13 -4
  161. package/features/identtiy.tokens.custom.feature +247 -0
  162. package/features/introspection.feature +153 -0
  163. package/features/io.feature +38 -1
  164. package/features/map.feature +305 -0
  165. package/features/methods.feature +47 -0
  166. package/features/octets.cloudinary.feature +68 -0
  167. package/features/octets.download.feature +189 -0
  168. package/features/octets.entries.feature +13 -55
  169. package/features/octets.feature +84 -108
  170. package/features/octets.head.feature +40 -0
  171. package/features/octets.meta.feature +65 -15
  172. package/features/octets.workflows.feature +242 -58
  173. package/features/probes.feature +14 -0
  174. package/features/{queries.feature → query.feature} +77 -2
  175. package/features/realtime.feature +34 -0
  176. package/features/require.feature +67 -0
  177. package/features/response.feature +38 -3
  178. package/features/routes.feature +93 -2
  179. package/features/server.feature +21 -0
  180. package/features/steps/.env.example +3 -0
  181. package/features/steps/Database.ts +16 -9
  182. package/features/steps/Gateway.ts +26 -7
  183. package/features/steps/IdP.ts +63 -25
  184. package/features/steps/Parameters.ts +44 -1
  185. package/features/steps/Realtime.ts +151 -0
  186. package/features/steps/components/echo/manifest.toa.yaml +14 -1
  187. package/features/steps/components/echo/operations/identity.js +7 -0
  188. package/features/steps/components/echo/operations/parameters.js +7 -0
  189. package/features/steps/components/echo.beacon/manifest.toa.yaml +2 -0
  190. package/features/steps/components/echo.beacon/operations/hello.js +5 -0
  191. package/features/steps/components/greeter/manifest.toa.yaml +0 -1
  192. package/features/steps/components/octets.tester/manifest.toa.yaml +22 -3
  193. package/features/steps/components/octets.tester/operations/authority.js +7 -0
  194. package/features/steps/components/octets.tester/operations/bar.js +0 -1
  195. package/features/steps/components/octets.tester/operations/baz.js +0 -2
  196. package/features/steps/components/octets.tester/operations/foo.js +1 -2
  197. package/features/steps/components/octets.tester/operations/redirect.js +12 -0
  198. package/features/steps/components/octets.tester/operations/yex.js +16 -0
  199. package/features/steps/components/octets.tester/operations/yield.js +13 -0
  200. package/features/steps/components/pots/manifest.toa.yaml +12 -4
  201. package/features/steps/components/sequences/manifest.toa.yaml +0 -1
  202. package/features/steps/components/users/manifest.toa.yaml +4 -3
  203. package/features/steps/components/users/operations/create.js +15 -0
  204. package/features/steps/components/users.properties/manifest.toa.yaml +1 -2
  205. package/features/streams.feature +5 -0
  206. package/features/timestamps.feature +41 -0
  207. package/features/timing.feature +4 -1
  208. package/package.json +25 -13
  209. package/readme.md +19 -14
  210. package/schemas/annotation.cos.yaml +1 -1
  211. package/schemas/method.cos.yaml +1 -1
  212. package/schemas/node.cos.yaml +2 -0
  213. package/schemas/octets/put.cos.yaml +25 -0
  214. package/schemas/query.cos.yaml +4 -10
  215. package/source/Annotation.ts +3 -3
  216. package/source/Branch.ts +1 -0
  217. package/source/Composition.ts +0 -6
  218. package/source/Context.ts +1 -0
  219. package/source/Directive.test.ts +1 -1
  220. package/source/Directive.ts +7 -6
  221. package/source/Endpoint.ts +69 -17
  222. package/source/Factory.ts +22 -13
  223. package/source/Gateway.ts +73 -19
  224. package/source/HTTP/Context.ts +31 -7
  225. package/source/HTTP/Server.ts +61 -47
  226. package/source/HTTP/exceptions.ts +13 -1
  227. package/source/HTTP/formats/index.ts +3 -3
  228. package/source/HTTP/messages.test.ts +45 -2
  229. package/source/HTTP/messages.ts +34 -8
  230. package/source/Introspection.ts +11 -0
  231. package/source/Mapping.ts +68 -21
  232. package/source/Query.test.ts +3 -3
  233. package/source/Query.ts +123 -33
  234. package/source/RTD/Context.ts +1 -1
  235. package/source/RTD/Endpoint.ts +3 -0
  236. package/source/RTD/Method.ts +16 -0
  237. package/source/RTD/Node.ts +29 -13
  238. package/source/RTD/Route.ts +5 -4
  239. package/source/RTD/Tree.ts +2 -2
  240. package/source/RTD/factory.ts +5 -2
  241. package/source/RTD/syntax/parse.test.ts +1 -1
  242. package/source/RTD/syntax/parse.ts +37 -24
  243. package/source/RTD/syntax/types.ts +6 -4
  244. package/source/Remotes.ts +7 -6
  245. package/source/Tenant.ts +6 -20
  246. package/source/deployment.ts +33 -23
  247. package/source/directives/auth/Anonymous.ts +3 -3
  248. package/source/directives/auth/Anyone.ts +13 -0
  249. package/source/directives/auth/Authorization.ts +65 -25
  250. package/source/directives/auth/Delegate.ts +13 -6
  251. package/source/directives/auth/Echo.ts +16 -6
  252. package/source/directives/auth/Federation.ts +84 -0
  253. package/source/directives/auth/Id.ts +1 -1
  254. package/source/directives/auth/Incept.ts +27 -12
  255. package/source/directives/auth/Input.ts +72 -0
  256. package/source/directives/auth/Role.test.ts +53 -6
  257. package/source/directives/auth/Role.ts +23 -19
  258. package/source/directives/auth/Rule.ts +3 -5
  259. package/source/directives/auth/Scheme.ts +5 -5
  260. package/source/directives/auth/create.ts +10 -0
  261. package/source/directives/auth/split.ts +1 -1
  262. package/source/directives/auth/types.ts +11 -6
  263. package/source/directives/cache/Cache.ts +13 -6
  264. package/source/directives/cache/Control.ts +42 -16
  265. package/source/directives/cors/CORS.ts +3 -2
  266. package/source/directives/dev/Development.ts +1 -1
  267. package/source/directives/flow/Compose.ts +68 -0
  268. package/source/directives/flow/Fetch.ts +86 -0
  269. package/source/directives/flow/Flow.ts +42 -0
  270. package/source/directives/flow/index.ts +3 -0
  271. package/source/directives/flow/types.ts +7 -0
  272. package/source/directives/index.ts +4 -2
  273. package/source/directives/io/IO.ts +1 -1
  274. package/source/directives/io/Input.ts +8 -5
  275. package/source/directives/io/Output.ts +5 -4
  276. package/source/directives/map/Authority.ts +15 -0
  277. package/source/directives/map/Claims.ts +58 -0
  278. package/source/directives/map/Directive.ts +4 -0
  279. package/source/directives/map/Headers.ts +38 -0
  280. package/source/directives/map/Language.ts +42 -0
  281. package/source/directives/map/Languages.ts +11 -0
  282. package/source/directives/map/Map.ts +61 -0
  283. package/source/directives/map/Mapping.ts +19 -0
  284. package/source/directives/{vary → map}/Properties.ts +2 -4
  285. package/source/directives/map/Segments.ts +26 -0
  286. package/source/directives/map/index.ts +3 -0
  287. package/source/directives/octets/Context.ts +3 -2
  288. package/source/directives/octets/Delete.ts +11 -11
  289. package/source/directives/octets/Get.ts +86 -0
  290. package/source/directives/octets/Octets.ts +9 -12
  291. package/source/directives/octets/{Store.ts → Put.ts} +36 -36
  292. package/source/directives/octets/Workflow.ts +1 -1
  293. package/source/directives/octets/bytes.test.ts +30 -0
  294. package/source/directives/octets/bytes.ts +18 -0
  295. package/source/directives/octets/schemas.ts +4 -8
  296. package/source/directives/octets/workflows/Execution.ts +60 -8
  297. package/source/directives/octets/workflows/Workflow.ts +4 -4
  298. package/source/directives/require/Directive.ts +5 -0
  299. package/source/directives/require/Headers.ts +20 -0
  300. package/source/directives/require/Require.ts +28 -0
  301. package/source/directives/require/index.ts +3 -0
  302. package/source/exceptions.ts +14 -6
  303. package/source/manifest.ts +10 -11
  304. package/source/root.ts +16 -1
  305. package/source/schemas.ts +1 -1
  306. package/transpiled/Annotation.d.ts +3 -3
  307. package/transpiled/Branch.d.ts +1 -0
  308. package/transpiled/Composition.d.ts +0 -1
  309. package/transpiled/Composition.js +0 -4
  310. package/transpiled/Composition.js.map +1 -1
  311. package/transpiled/Context.d.ts +1 -0
  312. package/transpiled/Directive.js +7 -5
  313. package/transpiled/Directive.js.map +1 -1
  314. package/transpiled/Endpoint.d.ts +6 -4
  315. package/transpiled/Endpoint.js +47 -9
  316. package/transpiled/Endpoint.js.map +1 -1
  317. package/transpiled/Factory.d.ts +3 -2
  318. package/transpiled/Factory.js +18 -10
  319. package/transpiled/Factory.js.map +1 -1
  320. package/transpiled/Gateway.d.ts +3 -0
  321. package/transpiled/Gateway.js +55 -12
  322. package/transpiled/Gateway.js.map +1 -1
  323. package/transpiled/HTTP/Context.d.ts +9 -2
  324. package/transpiled/HTTP/Context.js +20 -6
  325. package/transpiled/HTTP/Context.js.map +1 -1
  326. package/transpiled/HTTP/Server.d.ts +13 -2
  327. package/transpiled/HTTP/Server.js +47 -40
  328. package/transpiled/HTTP/Server.js.map +1 -1
  329. package/transpiled/HTTP/exceptions.d.ts +7 -1
  330. package/transpiled/HTTP/exceptions.js +13 -1
  331. package/transpiled/HTTP/exceptions.js.map +1 -1
  332. package/transpiled/HTTP/formats/index.js +3 -3
  333. package/transpiled/HTTP/formats/index.js.map +1 -1
  334. package/transpiled/HTTP/messages.d.ts +2 -1
  335. package/transpiled/HTTP/messages.js +32 -7
  336. package/transpiled/HTTP/messages.js.map +1 -1
  337. package/transpiled/Introspection.d.ts +9 -0
  338. package/transpiled/Introspection.js +3 -0
  339. package/transpiled/Introspection.js.map +1 -0
  340. package/transpiled/Mapping.d.ts +11 -2
  341. package/transpiled/Mapping.js +50 -19
  342. package/transpiled/Mapping.js.map +1 -1
  343. package/transpiled/Query.d.ts +10 -1
  344. package/transpiled/Query.js +87 -30
  345. package/transpiled/Query.js.map +1 -1
  346. package/transpiled/RTD/Context.d.ts +1 -1
  347. package/transpiled/RTD/Endpoint.d.ts +1 -0
  348. package/transpiled/RTD/Method.d.ts +4 -0
  349. package/transpiled/RTD/Method.js +11 -0
  350. package/transpiled/RTD/Method.js.map +1 -1
  351. package/transpiled/RTD/Node.d.ts +4 -1
  352. package/transpiled/RTD/Node.js +23 -12
  353. package/transpiled/RTD/Node.js.map +1 -1
  354. package/transpiled/RTD/Route.d.ts +1 -1
  355. package/transpiled/RTD/Route.js +0 -1
  356. package/transpiled/RTD/Route.js.map +1 -1
  357. package/transpiled/RTD/Tree.d.ts +1 -1
  358. package/transpiled/RTD/Tree.js.map +1 -1
  359. package/transpiled/RTD/factory.js +5 -2
  360. package/transpiled/RTD/factory.js.map +1 -1
  361. package/transpiled/RTD/syntax/parse.js +34 -22
  362. package/transpiled/RTD/syntax/parse.js.map +1 -1
  363. package/transpiled/RTD/syntax/types.d.ts +5 -3
  364. package/transpiled/RTD/syntax/types.js +1 -1
  365. package/transpiled/RTD/syntax/types.js.map +1 -1
  366. package/transpiled/Remotes.d.ts +4 -4
  367. package/transpiled/Remotes.js +6 -5
  368. package/transpiled/Remotes.js.map +1 -1
  369. package/transpiled/Tenant.d.ts +5 -5
  370. package/transpiled/Tenant.js +2 -13
  371. package/transpiled/Tenant.js.map +1 -1
  372. package/transpiled/deployment.d.ts +1 -1
  373. package/transpiled/deployment.js +28 -20
  374. package/transpiled/deployment.js.map +1 -1
  375. package/transpiled/directives/auth/Anonymous.d.ts +2 -2
  376. package/transpiled/directives/auth/Anonymous.js +2 -2
  377. package/transpiled/directives/auth/Anonymous.js.map +1 -1
  378. package/transpiled/directives/auth/Anyone.d.ts +6 -0
  379. package/transpiled/directives/auth/Anyone.js +14 -0
  380. package/transpiled/directives/auth/Anyone.js.map +1 -0
  381. package/transpiled/directives/auth/Authorization.d.ts +4 -3
  382. package/transpiled/directives/auth/Authorization.js +49 -22
  383. package/transpiled/directives/auth/Authorization.js.map +1 -1
  384. package/transpiled/directives/auth/Delegate.d.ts +5 -4
  385. package/transpiled/directives/auth/Delegate.js +10 -4
  386. package/transpiled/directives/auth/Delegate.js.map +1 -1
  387. package/transpiled/directives/auth/Echo.d.ts +4 -4
  388. package/transpiled/directives/auth/Echo.js +11 -4
  389. package/transpiled/directives/auth/Echo.js.map +1 -1
  390. package/transpiled/directives/auth/Federation.d.ts +16 -0
  391. package/transpiled/directives/auth/Federation.js +57 -0
  392. package/transpiled/directives/auth/Federation.js.map +1 -0
  393. package/transpiled/directives/auth/Id.d.ts +1 -1
  394. package/transpiled/directives/auth/Id.js.map +1 -1
  395. package/transpiled/directives/auth/Incept.d.ts +4 -3
  396. package/transpiled/directives/auth/Incept.js +23 -10
  397. package/transpiled/directives/auth/Incept.js.map +1 -1
  398. package/transpiled/directives/auth/Input.d.ts +14 -0
  399. package/transpiled/directives/auth/Input.js +49 -0
  400. package/transpiled/directives/auth/Input.js.map +1 -0
  401. package/transpiled/directives/auth/Role.d.ts +5 -2
  402. package/transpiled/directives/auth/Role.js +22 -18
  403. package/transpiled/directives/auth/Role.js.map +1 -1
  404. package/transpiled/directives/auth/Rule.d.ts +2 -4
  405. package/transpiled/directives/auth/Rule.js +2 -2
  406. package/transpiled/directives/auth/Rule.js.map +1 -1
  407. package/transpiled/directives/auth/Scheme.d.ts +2 -2
  408. package/transpiled/directives/auth/Scheme.js +4 -4
  409. package/transpiled/directives/auth/Scheme.js.map +1 -1
  410. package/transpiled/directives/auth/create.d.ts +2 -0
  411. package/transpiled/directives/auth/create.js +12 -0
  412. package/transpiled/directives/auth/create.js.map +1 -0
  413. package/transpiled/directives/auth/split.js +1 -1
  414. package/transpiled/directives/auth/split.js.map +1 -1
  415. package/transpiled/directives/auth/types.d.ts +8 -5
  416. package/transpiled/directives/cache/Cache.d.ts +3 -3
  417. package/transpiled/directives/cache/Cache.js +10 -4
  418. package/transpiled/directives/cache/Cache.js.map +1 -1
  419. package/transpiled/directives/cache/Control.d.ts +2 -1
  420. package/transpiled/directives/cache/Control.js +29 -12
  421. package/transpiled/directives/cache/Control.js.map +1 -1
  422. package/transpiled/directives/cors/CORS.js +3 -2
  423. package/transpiled/directives/cors/CORS.js.map +1 -1
  424. package/transpiled/directives/dev/Development.js +1 -1
  425. package/transpiled/directives/dev/Development.js.map +1 -1
  426. package/transpiled/directives/flow/Compose.d.ts +8 -0
  427. package/transpiled/directives/flow/Compose.js +74 -0
  428. package/transpiled/directives/flow/Compose.js.map +1 -0
  429. package/transpiled/directives/flow/Fetch.d.ts +12 -0
  430. package/transpiled/directives/flow/Fetch.js +58 -0
  431. package/transpiled/directives/flow/Fetch.js.map +1 -0
  432. package/transpiled/directives/flow/Flow.d.ts +10 -0
  433. package/transpiled/directives/flow/Flow.js +33 -0
  434. package/transpiled/directives/flow/Flow.js.map +1 -0
  435. package/transpiled/directives/flow/index.d.ts +2 -0
  436. package/transpiled/directives/flow/index.js +6 -0
  437. package/transpiled/directives/flow/index.js.map +1 -0
  438. package/transpiled/directives/flow/types.d.ts +6 -0
  439. package/transpiled/directives/flow/types.js.map +1 -0
  440. package/transpiled/directives/index.js +4 -2
  441. package/transpiled/directives/index.js.map +1 -1
  442. package/transpiled/directives/io/IO.js +1 -1
  443. package/transpiled/directives/io/IO.js.map +1 -1
  444. package/transpiled/directives/io/Input.js +4 -2
  445. package/transpiled/directives/io/Input.js.map +1 -1
  446. package/transpiled/directives/io/Output.js +2 -2
  447. package/transpiled/directives/io/Output.js.map +1 -1
  448. package/transpiled/directives/map/Authority.d.ts +6 -0
  449. package/transpiled/directives/map/Authority.js +19 -0
  450. package/transpiled/directives/map/Authority.js.map +1 -0
  451. package/transpiled/directives/map/Claims.d.ts +10 -0
  452. package/transpiled/directives/map/Claims.js +44 -0
  453. package/transpiled/directives/map/Claims.js.map +1 -0
  454. package/transpiled/directives/map/Directive.d.ts +3 -0
  455. package/transpiled/directives/map/Directive.js.map +1 -0
  456. package/transpiled/directives/map/Headers.d.ts +7 -0
  457. package/transpiled/directives/map/Headers.js +34 -0
  458. package/transpiled/directives/map/Headers.js.map +1 -0
  459. package/transpiled/directives/map/Language.d.ts +10 -0
  460. package/transpiled/directives/map/Language.js +38 -0
  461. package/transpiled/directives/map/Language.js.map +1 -0
  462. package/transpiled/directives/map/Languages.d.ts +4 -0
  463. package/transpiled/directives/map/Languages.js +17 -0
  464. package/transpiled/directives/map/Languages.js.map +1 -0
  465. package/transpiled/directives/map/Map.d.ts +13 -0
  466. package/transpiled/directives/map/Map.js +46 -0
  467. package/transpiled/directives/map/Map.js.map +1 -0
  468. package/transpiled/directives/map/Mapping.d.ts +13 -0
  469. package/transpiled/directives/map/Mapping.js +13 -0
  470. package/transpiled/directives/map/Mapping.js.map +1 -0
  471. package/transpiled/directives/{vary → map}/Properties.d.ts +2 -2
  472. package/transpiled/directives/{vary → map}/Properties.js +1 -3
  473. package/transpiled/directives/map/Properties.js.map +1 -0
  474. package/transpiled/directives/map/Segments.d.ts +6 -0
  475. package/transpiled/directives/map/Segments.js +25 -0
  476. package/transpiled/directives/map/Segments.js.map +1 -0
  477. package/transpiled/directives/map/index.d.ts +2 -0
  478. package/transpiled/directives/map/index.js +6 -0
  479. package/transpiled/directives/map/index.js.map +1 -0
  480. package/transpiled/directives/octets/Context.js +4 -24
  481. package/transpiled/directives/octets/Context.js.map +1 -1
  482. package/transpiled/directives/octets/Delete.js +8 -8
  483. package/transpiled/directives/octets/Delete.js.map +1 -1
  484. package/transpiled/directives/octets/{Fetch.d.ts → Get.d.ts} +5 -6
  485. package/transpiled/directives/octets/{Fetch.js → Get.js} +25 -29
  486. package/transpiled/directives/octets/Get.js.map +1 -0
  487. package/transpiled/directives/octets/Octets.js +9 -12
  488. package/transpiled/directives/octets/Octets.js.map +1 -1
  489. package/transpiled/directives/octets/{Store.d.ts → Put.d.ts} +6 -2
  490. package/transpiled/directives/octets/{Store.js → Put.js} +22 -26
  491. package/transpiled/directives/octets/Put.js.map +1 -0
  492. package/transpiled/directives/octets/Workflow.js +1 -1
  493. package/transpiled/directives/octets/Workflow.js.map +1 -1
  494. package/transpiled/directives/octets/bytes.d.ts +1 -0
  495. package/transpiled/directives/octets/bytes.js +21 -0
  496. package/transpiled/directives/octets/bytes.js.map +1 -0
  497. package/transpiled/directives/octets/schemas.d.ts +4 -8
  498. package/transpiled/directives/octets/schemas.js +3 -6
  499. package/transpiled/directives/octets/schemas.js.map +1 -1
  500. package/transpiled/directives/octets/workflows/Execution.d.ts +5 -1
  501. package/transpiled/directives/octets/workflows/Execution.js +44 -9
  502. package/transpiled/directives/octets/workflows/Execution.js.map +1 -1
  503. package/transpiled/directives/octets/workflows/Workflow.d.ts +1 -1
  504. package/transpiled/directives/octets/workflows/Workflow.js +2 -1
  505. package/transpiled/directives/octets/workflows/Workflow.js.map +1 -1
  506. package/transpiled/directives/require/Directive.d.ts +4 -0
  507. package/transpiled/directives/require/Directive.js +3 -0
  508. package/transpiled/directives/require/Directive.js.map +1 -0
  509. package/transpiled/directives/require/Headers.d.ts +7 -0
  510. package/transpiled/directives/require/Headers.js +19 -0
  511. package/transpiled/directives/require/Headers.js.map +1 -0
  512. package/transpiled/directives/require/Require.d.ts +9 -0
  513. package/transpiled/directives/require/Require.js +27 -0
  514. package/transpiled/directives/require/Require.js.map +1 -0
  515. package/transpiled/directives/require/index.d.ts +2 -0
  516. package/transpiled/directives/require/index.js +6 -0
  517. package/transpiled/directives/require/index.js.map +1 -0
  518. package/transpiled/exceptions.d.ts +3 -2
  519. package/transpiled/exceptions.js +8 -1
  520. package/transpiled/exceptions.js.map +1 -1
  521. package/transpiled/manifest.js +10 -11
  522. package/transpiled/manifest.js.map +1 -1
  523. package/transpiled/root.js +16 -1
  524. package/transpiled/root.js.map +1 -1
  525. package/transpiled/schemas.d.ts +1 -1
  526. package/transpiled/schemas.js +2 -2
  527. package/transpiled/schemas.js.map +1 -1
  528. package/transpiled/tsconfig.tsbuildinfo +1 -1
  529. package/components/identity.basic/operations/create.d.ts +0 -10
  530. package/components/identity.basic/operations/create.js +0 -10
  531. package/components/identity.basic/operations/create.js.map +0 -1
  532. package/components/identity.basic/source/create.ts +0 -18
  533. package/components/identity.federation/operations/create.d.ts +0 -10
  534. package/components/identity.federation/operations/create.js +0 -15
  535. package/components/identity.federation/operations/create.js.map +0 -1
  536. package/components/identity.federation/operations/schemas.d.ts +0 -59
  537. package/components/identity.federation/operations/schemas.js +0 -9
  538. package/components/identity.federation/operations/schemas.js.map +0 -1
  539. package/components/identity.federation/operations/types.js.map +0 -1
  540. package/components/identity.federation/source/create.ts +0 -26
  541. package/components/identity.federation/source/schemas.ts +0 -61
  542. package/components/identity.tokens/operations/types.d.ts +0 -40
  543. package/components/identity.tokens/operations/types.js.map +0 -1
  544. package/components/identity.tokens/source/types.ts +0 -48
  545. package/components/octets.storage/operations/fetch.js +0 -46
  546. package/components/octets.storage/operations/list.js +0 -7
  547. package/components/octets.storage/operations/permute.js +0 -7
  548. package/components/octets.storage/operations/store.js +0 -11
  549. package/documentation/vary.md +0 -69
  550. package/features/steps/components/octets.tester/operations/diversify.js +0 -14
  551. package/features/vary.feature +0 -180
  552. package/schemas/octets/context.cos.yaml +0 -1
  553. package/schemas/octets/fetch.cos.yaml +0 -3
  554. package/schemas/octets/permute.cos.yaml +0 -1
  555. package/schemas/octets/store.cos.yaml +0 -3
  556. package/source/HTTP/Server.test.ts +0 -126
  557. package/source/directives/octets/Fetch.ts +0 -100
  558. package/source/directives/octets/List.ts +0 -72
  559. package/source/directives/octets/Permute.ts +0 -44
  560. package/source/directives/vary/Directive.ts +0 -6
  561. package/source/directives/vary/Embed.ts +0 -62
  562. package/source/directives/vary/Vary.ts +0 -48
  563. package/source/directives/vary/embeddings/Embedding.ts +0 -6
  564. package/source/directives/vary/embeddings/Header.ts +0 -32
  565. package/source/directives/vary/embeddings/Language.ts +0 -31
  566. package/source/directives/vary/embeddings/index.ts +0 -11
  567. package/source/directives/vary/index.ts +0 -3
  568. package/transpiled/directives/octets/Fetch.js.map +0 -1
  569. package/transpiled/directives/octets/List.d.ts +0 -16
  570. package/transpiled/directives/octets/List.js +0 -74
  571. package/transpiled/directives/octets/List.js.map +0 -1
  572. package/transpiled/directives/octets/Permute.d.ts +0 -11
  573. package/transpiled/directives/octets/Permute.js.map +0 -1
  574. package/transpiled/directives/octets/Store.js.map +0 -1
  575. package/transpiled/directives/vary/Directive.d.ts +0 -5
  576. package/transpiled/directives/vary/Directive.js.map +0 -1
  577. package/transpiled/directives/vary/Embed.d.ts +0 -10
  578. package/transpiled/directives/vary/Embed.js +0 -49
  579. package/transpiled/directives/vary/Embed.js.map +0 -1
  580. package/transpiled/directives/vary/Properties.js.map +0 -1
  581. package/transpiled/directives/vary/Vary.d.ts +0 -10
  582. package/transpiled/directives/vary/Vary.js +0 -36
  583. package/transpiled/directives/vary/Vary.js.map +0 -1
  584. package/transpiled/directives/vary/embeddings/Embedding.d.ts +0 -5
  585. package/transpiled/directives/vary/embeddings/Embedding.js.map +0 -1
  586. package/transpiled/directives/vary/embeddings/Header.d.ts +0 -7
  587. package/transpiled/directives/vary/embeddings/Header.js +0 -28
  588. package/transpiled/directives/vary/embeddings/Header.js.map +0 -1
  589. package/transpiled/directives/vary/embeddings/Language.d.ts +0 -7
  590. package/transpiled/directives/vary/embeddings/Language.js +0 -28
  591. package/transpiled/directives/vary/embeddings/Language.js.map +0 -1
  592. package/transpiled/directives/vary/embeddings/index.d.ts +0 -5
  593. package/transpiled/directives/vary/embeddings/index.js +0 -10
  594. package/transpiled/directives/vary/embeddings/index.js.map +0 -1
  595. package/transpiled/directives/vary/index.d.ts +0 -2
  596. package/transpiled/directives/vary/index.js +0 -6
  597. package/transpiled/directives/vary/index.js.map +0 -1
  598. /package/components/{identity.federation/operations → identity.tokens/operations/lib}/types.js +0 -0
  599. /package/schemas/octets/{list.cos.yaml → get.cos.yaml} +0 -0
  600. /package/{components/identity.tokens/operations → transpiled/directives/flow}/types.js +0 -0
  601. /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,23 @@ 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
12
  accept: string
13
- meta: <string>
14
- fetch: &simple
13
+ limit: number
14
+ trust: ~ # array of strings or regular expressions
15
+ errors:
16
+ - LOCATION_UNTRUSTED
17
+ - LOCATION_LENGTH
18
+ - LOCATION_UNAVAILABLE
19
+ - INVALID_ID
20
+ get: &simple
15
21
  bindings: ~
16
22
  input:
17
23
  storage*: string
18
24
  path*: string
19
- get: *simple
20
- list: *simple
25
+ head: *simple
21
26
  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,132 @@
1
+ 'use strict'
2
+
3
+ const { Readable } = require('node:stream')
4
+ const { Err } = require('error-value')
5
+ const { match } = require('matchacho')
6
+
7
+ async function put (input, context) {
8
+ const { storage, request, accept, limit, trust } = input
9
+ const path = request.url
10
+ const id = request.headers['content-id']
11
+ const claim = request.headers['content-type']
12
+ const attributes = parseAttributes(request.headers['content-attributes'])
13
+ const location = request.headers['content-location']
14
+
15
+ /** @type {Readable} */
16
+ let body = request
17
+
18
+ const options = { claim, accept, attributes }
19
+
20
+ if (id !== undefined) {
21
+ if (!ID_RX.test(id))
22
+ return ERR_INVALID_ID
23
+
24
+ options.id = id
25
+ }
26
+
27
+ if (location !== undefined) {
28
+ const length = Number.parseInt(request.headers['content-length'])
29
+
30
+ if (length !== 0)
31
+ return ERR_LENGTH
32
+
33
+ if (!trusted(location, trust))
34
+ return ERR_UNTRUSTED
35
+
36
+ body = await download(location)
37
+
38
+ if (body instanceof Error)
39
+ return body
40
+
41
+ options.origin = location
42
+ }
43
+
44
+ if (limit !== undefined)
45
+ options.limit = limit
46
+
47
+ return context.storages[storage].put(path, body, options)
48
+ }
49
+
50
+ /**
51
+ * @param {string | string[] | undefined} values
52
+ * @returns {Record<string, string>}
53
+ */
54
+ function parseAttributes (values) {
55
+ const attributes = {}
56
+
57
+ if (values === undefined)
58
+ return attributes
59
+
60
+ if (typeof values === 'string')
61
+ values = values.split(',')
62
+
63
+ for (const pair of values) {
64
+ const eq = pair.indexOf('=')
65
+ const key = (eq === -1 ? pair : pair.slice(0, eq)).trim()
66
+
67
+ attributes[key] = eq === -1 ? 'true' : pair.slice(eq + 1).trim()
68
+ }
69
+
70
+ return attributes
71
+ }
72
+
73
+ /**
74
+ * @param {string} location
75
+ * @return {Readable | Error}
76
+ */
77
+ async function download (location) {
78
+ const response = await fetch(location)
79
+
80
+ if (!response.ok)
81
+ return ERR_UNAVAILABLE
82
+
83
+ return response.body === null ? ERR_UNAVAILABLE : Readable.fromWeb(
84
+ /** @type {import('node:stream/web').ReadableStream} **/ response.body)
85
+
86
+ }
87
+
88
+ /**
89
+ * @param {string} location
90
+ * @param {Trust | undefined} trust
91
+ * @return {boolean}
92
+ */
93
+ function trusted (location, trust) {
94
+ if (trust === undefined)
95
+ return false
96
+
97
+ const url = toURL(location)
98
+
99
+ if (url === null)
100
+ return false
101
+
102
+ for (const permission of trust) {
103
+ const ok = match(permission,
104
+ String, (origin) => url.origin === origin,
105
+ RegExp, (pattern) => pattern.test(url.origin))
106
+
107
+ if (ok)
108
+ return true
109
+ }
110
+
111
+ return false
112
+ }
113
+
114
+ function toURL (location) {
115
+ try {
116
+ return new URL(location)
117
+ } catch (error) {
118
+ return null
119
+ }
120
+ }
121
+
122
+ const ERR_UNTRUSTED = new Err('LOCATION_UNTRUSTED', 'Location is not trusted')
123
+ const ERR_LENGTH = new Err('LOCATION_LENGTH', 'Content-Length must be 0 when Content-Location is used')
124
+ const ERR_UNAVAILABLE = new Err('LOCATION_UNAVAILABLE', 'Location is not available')
125
+ const ERR_INVALID_ID = new Err('INVALID_ID', 'Invalid Content-ID')
126
+
127
+ const ID_RX = /^[a-zA-Z0-9-_]{1,32}$/
128
+
129
+ exports.effect = put
130
+
131
+ /** @typedef {Array<string | RegExp>} Trust */
132
+ /** @typedef {import('node:stream').Readable} Readable */