@greenpandastudios/aug-cli 0.19.0

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 (414) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +13 -0
  3. package/THIRD_PARTY_NOTICES.md +18 -0
  4. package/bin/aug.mjs +3 -0
  5. package/docs/api/crypto.md +351 -0
  6. package/docs/api/io.md +207 -0
  7. package/docs/api/json.md +21 -0
  8. package/docs/api/memory.md +109 -0
  9. package/docs/api/time.md +54 -0
  10. package/docs/api/web.md +184 -0
  11. package/docs/assets/benchmarks/execution.svg +2978 -0
  12. package/docs/assets/benchmarks/http.svg +1674 -0
  13. package/docs/assets/benchmarks/improvements.svg +2315 -0
  14. package/docs/assets/benchmarks/memory.svg +1891 -0
  15. package/docs/benchmark-baseline.json +1087 -0
  16. package/docs/benchmark-results.json +91123 -0
  17. package/docs/benchmarks.json +38 -0
  18. package/docs/compatibility.md +42 -0
  19. package/docs/concurrency-implementation.md +18 -0
  20. package/docs/diagnostics.md +97 -0
  21. package/docs/docker.md +35 -0
  22. package/docs/example-projects.json +26 -0
  23. package/docs/examples/approved-design/counters.md +253 -0
  24. package/docs/examples/approved-design/dependencies/august/0.19.0/io/contracts.md +395 -0
  25. package/docs/examples/approved-design/domain/app.md +165 -0
  26. package/docs/examples/approved-design/domain/export.md +83 -0
  27. package/docs/examples/approved-design/domain/models.md +80 -0
  28. package/docs/examples/approved-design/domain/numbers.md +248 -0
  29. package/docs/examples/approved-design/index.md +39 -0
  30. package/docs/examples/approved-design/main-yaml.md +24 -0
  31. package/docs/examples/approved-design/main.md +215 -0
  32. package/docs/examples/benchmark/index.md +33 -0
  33. package/docs/examples/benchmark/main-yaml.md +17 -0
  34. package/docs/examples/benchmark/main.md +117 -0
  35. package/docs/examples/cli-args/index.md +32 -0
  36. package/docs/examples/cli-args/main.md +107 -0
  37. package/docs/examples/collections/index.md +32 -0
  38. package/docs/examples/collections/main.md +118 -0
  39. package/docs/examples/collections-benchmark/index.md +34 -0
  40. package/docs/examples/collections-benchmark/main.md +115 -0
  41. package/docs/examples/cpu-benchmark/index.md +34 -0
  42. package/docs/examples/cpu-benchmark/main.md +90 -0
  43. package/docs/examples/developer-workflow/calculator.md +357 -0
  44. package/docs/examples/developer-workflow/dependencies/august/0.19.0/io/contracts.md +395 -0
  45. package/docs/examples/developer-workflow/index.md +37 -0
  46. package/docs/examples/developer-workflow/logging/console.md +124 -0
  47. package/docs/examples/developer-workflow/logging/export.md +70 -0
  48. package/docs/examples/developer-workflow/logging/logger.md +111 -0
  49. package/docs/examples/developer-workflow/main.md +172 -0
  50. package/docs/examples/drop/index.md +33 -0
  51. package/docs/examples/drop/main.md +85 -0
  52. package/docs/examples/drop/resource.md +95 -0
  53. package/docs/examples/errors/errors.md +85 -0
  54. package/docs/examples/errors/index.md +33 -0
  55. package/docs/examples/errors/main.md +92 -0
  56. package/docs/examples/ffi/index.md +33 -0
  57. package/docs/examples/ffi/main.md +75 -0
  58. package/docs/examples/ffi/native.md +93 -0
  59. package/docs/examples/generic-di/dependencies/august/0.19.0/io/contracts.md +395 -0
  60. package/docs/examples/generic-di/index.md +33 -0
  61. package/docs/examples/generic-di/main.md +111 -0
  62. package/docs/examples/generic-di/types.md +180 -0
  63. package/docs/examples/generics/index.md +33 -0
  64. package/docs/examples/generics/main.md +120 -0
  65. package/docs/examples/generics/types.md +189 -0
  66. package/docs/examples/hello/app/export.md +67 -0
  67. package/docs/examples/hello/app/greeter.md +190 -0
  68. package/docs/examples/hello/dependencies/august/0.19.0/io/contracts.md +395 -0
  69. package/docs/examples/hello/index.md +37 -0
  70. package/docs/examples/hello/logging/console.md +121 -0
  71. package/docs/examples/hello/logging/export.md +71 -0
  72. package/docs/examples/hello/logging/logger.md +120 -0
  73. package/docs/examples/hello/main.md +115 -0
  74. package/docs/examples/http-benchmark/index.md +35 -0
  75. package/docs/examples/http-benchmark/main.md +79 -0
  76. package/docs/examples/http-benchmark/routes.md +88 -0
  77. package/docs/examples/index.md +60 -0
  78. package/docs/examples/interceptors/app.md +250 -0
  79. package/docs/examples/interceptors/dependencies/august/0.19.0/io/contracts.md +395 -0
  80. package/docs/examples/interceptors/index.md +35 -0
  81. package/docs/examples/interceptors/interceptors.md +284 -0
  82. package/docs/examples/interceptors/logging.md +155 -0
  83. package/docs/examples/interceptors/main.md +162 -0
  84. package/docs/examples/json-benchmark/data.md +71 -0
  85. package/docs/examples/json-benchmark/dependencies/august/0.19.0/json/contracts.md +103 -0
  86. package/docs/examples/json-benchmark/index.md +35 -0
  87. package/docs/examples/json-benchmark/main.md +131 -0
  88. package/docs/examples/new-syntax/console.md +118 -0
  89. package/docs/examples/new-syntax/dependencies/august/0.19.0/io/contracts.md +395 -0
  90. package/docs/examples/new-syntax/greeter.md +145 -0
  91. package/docs/examples/new-syntax/index.md +36 -0
  92. package/docs/examples/new-syntax/logger.md +111 -0
  93. package/docs/examples/new-syntax/main.md +135 -0
  94. package/docs/examples/new-syntax/math.md +79 -0
  95. package/docs/examples/oidc-login/client/contracts.md +151 -0
  96. package/docs/examples/oidc-login/client/endpoints.md +263 -0
  97. package/docs/examples/oidc-login/client/export.md +107 -0
  98. package/docs/examples/oidc-login/client/login.md +515 -0
  99. package/docs/examples/oidc-login/client/logout.md +249 -0
  100. package/docs/examples/oidc-login/client/protocol.md +595 -0
  101. package/docs/examples/oidc-login/client/session.md +297 -0
  102. package/docs/examples/oidc-login/client/views.md +144 -0
  103. package/docs/examples/oidc-login/common/export.md +115 -0
  104. package/docs/examples/oidc-login/common/headers.md +162 -0
  105. package/docs/examples/oidc-login/common/keys.md +336 -0
  106. package/docs/examples/oidc-login/common/settings.md +116 -0
  107. package/docs/examples/oidc-login/common/views.md +103 -0
  108. package/docs/examples/oidc-login/dependencies/august/0.19.0/crypto/contracts.md +925 -0
  109. package/docs/examples/oidc-login/dependencies/august/0.19.0/crypto/jose.md +434 -0
  110. package/docs/examples/oidc-login/dependencies/august/0.19.0/json/contracts.md +103 -0
  111. package/docs/examples/oidc-login/dependencies/august/0.19.0/memory/store.md +374 -0
  112. package/docs/examples/oidc-login/dependencies/august/0.19.0/time/contracts.md +150 -0
  113. package/docs/examples/oidc-login/dependencies/august/0.19.0/web/contracts.md +532 -0
  114. package/docs/examples/oidc-login/index.md +57 -0
  115. package/docs/examples/oidc-login/main-yaml.md +28 -0
  116. package/docs/examples/oidc-login/main.md +283 -0
  117. package/docs/examples/oidc-login/provider/authorization.md +457 -0
  118. package/docs/examples/oidc-login/provider/contracts.md +267 -0
  119. package/docs/examples/oidc-login/provider/credentials.md +148 -0
  120. package/docs/examples/oidc-login/provider/discovery.md +215 -0
  121. package/docs/examples/oidc-login/provider/export.md +131 -0
  122. package/docs/examples/oidc-login/provider/token.md +364 -0
  123. package/docs/examples/oidc-login/provider/userinfo.md +228 -0
  124. package/docs/examples/oidc-login/provider/views.md +137 -0
  125. package/docs/examples/ownership/counter.md +140 -0
  126. package/docs/examples/ownership/index.md +33 -0
  127. package/docs/examples/ownership/main.md +90 -0
  128. package/docs/examples/ownership-transfer/dependencies/august/0.19.0/io/contracts.md +395 -0
  129. package/docs/examples/ownership-transfer/index.md +33 -0
  130. package/docs/examples/ownership-transfer/main.md +125 -0
  131. package/docs/examples/ownership-transfer/resource.md +150 -0
  132. package/docs/examples/packages-app/dependencies/packages/@example/aug-math/0.1.0/arithmetic.md +117 -0
  133. package/docs/examples/packages-app/index.md +34 -0
  134. package/docs/examples/packages-app/main-yaml.md +18 -0
  135. package/docs/examples/packages-app/main.md +80 -0
  136. package/docs/examples/packages-math/aug-package-json.md +24 -0
  137. package/docs/examples/packages-math/index.md +36 -0
  138. package/docs/examples/packages-math/package-json.md +25 -0
  139. package/docs/examples/packages-math/src/arithmetic.md +121 -0
  140. package/docs/examples/packages-math/src/export.md +63 -0
  141. package/docs/examples/startup-benchmark/index.md +34 -0
  142. package/docs/examples/startup-benchmark/main.md +68 -0
  143. package/docs/examples/visibility/counter.md +142 -0
  144. package/docs/examples/visibility/index.md +33 -0
  145. package/docs/examples/visibility/main.md +96 -0
  146. package/docs/examples.json +47 -0
  147. package/docs/getting-started.md +5 -0
  148. package/docs/grammar.md +136 -0
  149. package/docs/implementation-map.md +106 -0
  150. package/docs/index.md +46 -0
  151. package/docs/language-conformance.md +30 -0
  152. package/docs/language-constructs.md +1461 -0
  153. package/docs/language-design-audit.md +147 -0
  154. package/docs/maintaining-docs.md +43 -0
  155. package/docs/packages.md +184 -0
  156. package/docs/performance.md +535 -0
  157. package/docs/production-readiness.md +39 -0
  158. package/docs/reference.md +361 -0
  159. package/docs/release-review.md +23 -0
  160. package/docs/releasing.md +79 -0
  161. package/docs/roadmap.md +13 -0
  162. package/docs/specifications.md +86 -0
  163. package/docs/testing.md +120 -0
  164. package/docs/tooling.md +197 -0
  165. package/docs/web-implementation-plan.md +39 -0
  166. package/docs/web-library-gaps.md +27 -0
  167. package/docs/web.md +197 -0
  168. package/examples/approved-design/.aug-spec/august/0.19.0/io/contracts.aug +36 -0
  169. package/examples/approved-design/.aug-spec/august/0.19.0/io/contracts.aug.md +316 -0
  170. package/examples/approved-design/.aug-spec/manifest.json +14 -0
  171. package/examples/approved-design/counters.aug +22 -0
  172. package/examples/approved-design/counters.aug.md +177 -0
  173. package/examples/approved-design/domain/app.aug +12 -0
  174. package/examples/approved-design/domain/app.aug.md +97 -0
  175. package/examples/approved-design/domain/export.aug +5 -0
  176. package/examples/approved-design/domain/export.aug.md +25 -0
  177. package/examples/approved-design/domain/models.aug +2 -0
  178. package/examples/approved-design/domain/models.aug.md +30 -0
  179. package/examples/approved-design/domain/numbers.aug +29 -0
  180. package/examples/approved-design/domain/numbers.aug.md +141 -0
  181. package/examples/approved-design/main.aug +26 -0
  182. package/examples/approved-design/main.aug.md +108 -0
  183. package/examples/approved-design/main.yaml +8 -0
  184. package/examples/benchmark/.aug-spec/manifest.json +7 -0
  185. package/examples/benchmark/main.aug +17 -0
  186. package/examples/benchmark/main.aug.md +43 -0
  187. package/examples/benchmark/main.yaml +1 -0
  188. package/examples/cli-args/.aug-spec/manifest.json +7 -0
  189. package/examples/cli-args/main.aug +15 -0
  190. package/examples/cli-args/main.aug.md +38 -0
  191. package/examples/collections/.aug-spec/manifest.json +7 -0
  192. package/examples/collections/main.aug +18 -0
  193. package/examples/collections/main.aug.md +43 -0
  194. package/examples/developer-workflow/.aug-spec/august/0.19.0/io/contracts.aug +36 -0
  195. package/examples/developer-workflow/.aug-spec/august/0.19.0/io/contracts.aug.md +316 -0
  196. package/examples/developer-workflow/.aug-spec/manifest.json +13 -0
  197. package/examples/developer-workflow/calculator.aug +55 -0
  198. package/examples/developer-workflow/calculator.aug.md +228 -0
  199. package/examples/developer-workflow/logging/console.aug +8 -0
  200. package/examples/developer-workflow/logging/console.aug.md +67 -0
  201. package/examples/developer-workflow/logging/export.aug +2 -0
  202. package/examples/developer-workflow/logging/export.aug.md +19 -0
  203. package/examples/developer-workflow/logging/logger.aug +6 -0
  204. package/examples/developer-workflow/logging/logger.aug.md +57 -0
  205. package/examples/developer-workflow/main.aug +25 -0
  206. package/examples/developer-workflow/main.aug.md +79 -0
  207. package/examples/drop/.aug-spec/manifest.json +8 -0
  208. package/examples/drop/main.aug +3 -0
  209. package/examples/drop/main.aug.md +35 -0
  210. package/examples/drop/resource.aug +8 -0
  211. package/examples/drop/resource.aug.md +44 -0
  212. package/examples/errors/.aug-spec/manifest.json +8 -0
  213. package/examples/errors/errors.aug +6 -0
  214. package/examples/errors/errors.aug.md +33 -0
  215. package/examples/errors/main.aug +7 -0
  216. package/examples/errors/main.aug.md +36 -0
  217. package/examples/ffi/.aug-spec/manifest.json +8 -0
  218. package/examples/ffi/main.aug +2 -0
  219. package/examples/ffi/main.aug.md +27 -0
  220. package/examples/ffi/native.aug +6 -0
  221. package/examples/ffi/native.aug.md +43 -0
  222. package/examples/generic-di/.aug-spec/august/0.19.0/io/contracts.aug +36 -0
  223. package/examples/generic-di/.aug-spec/august/0.19.0/io/contracts.aug.md +316 -0
  224. package/examples/generic-di/.aug-spec/manifest.json +10 -0
  225. package/examples/generic-di/main.aug +9 -0
  226. package/examples/generic-di/main.aug.md +49 -0
  227. package/examples/generic-di/types.aug +17 -0
  228. package/examples/generic-di/types.aug.md +124 -0
  229. package/examples/generics/.aug-spec/manifest.json +8 -0
  230. package/examples/generics/main.aug +9 -0
  231. package/examples/generics/main.aug.md +58 -0
  232. package/examples/generics/types.aug +19 -0
  233. package/examples/generics/types.aug.md +132 -0
  234. package/examples/hello/.aug-spec/august/0.19.0/io/contracts.aug +36 -0
  235. package/examples/hello/.aug-spec/august/0.19.0/io/contracts.aug.md +316 -0
  236. package/examples/hello/.aug-spec/manifest.json +14 -0
  237. package/examples/hello/app/export.aug +1 -0
  238. package/examples/hello/app/export.aug.md +17 -0
  239. package/examples/hello/app/greeter.aug +22 -0
  240. package/examples/hello/app/greeter.aug.md +109 -0
  241. package/examples/hello/logging/console.aug +7 -0
  242. package/examples/hello/logging/console.aug.md +65 -0
  243. package/examples/hello/logging/export.aug +2 -0
  244. package/examples/hello/logging/export.aug.md +19 -0
  245. package/examples/hello/logging/logger.aug +9 -0
  246. package/examples/hello/logging/logger.aug.md +59 -0
  247. package/examples/hello/main.aug +9 -0
  248. package/examples/hello/main.aug.md +49 -0
  249. package/examples/interceptors/.aug-spec/august/0.19.0/io/contracts.aug +36 -0
  250. package/examples/interceptors/.aug-spec/august/0.19.0/io/contracts.aug.md +316 -0
  251. package/examples/interceptors/.aug-spec/manifest.json +12 -0
  252. package/examples/interceptors/app.aug +28 -0
  253. package/examples/interceptors/app.aug.md +162 -0
  254. package/examples/interceptors/interceptors.aug +40 -0
  255. package/examples/interceptors/interceptors.aug.md +180 -0
  256. package/examples/interceptors/logging.aug +12 -0
  257. package/examples/interceptors/logging.aug.md +96 -0
  258. package/examples/interceptors/main.aug +22 -0
  259. package/examples/interceptors/main.aug.md +76 -0
  260. package/examples/new-syntax/.aug-spec/august/0.19.0/io/contracts.aug +36 -0
  261. package/examples/new-syntax/.aug-spec/august/0.19.0/io/contracts.aug.md +316 -0
  262. package/examples/new-syntax/.aug-spec/manifest.json +13 -0
  263. package/examples/new-syntax/console.aug +7 -0
  264. package/examples/new-syntax/console.aug.md +63 -0
  265. package/examples/new-syntax/greeter.aug +10 -0
  266. package/examples/new-syntax/greeter.aug.md +89 -0
  267. package/examples/new-syntax/logger.aug +6 -0
  268. package/examples/new-syntax/logger.aug.md +57 -0
  269. package/examples/new-syntax/main.aug +12 -0
  270. package/examples/new-syntax/main.aug.md +64 -0
  271. package/examples/new-syntax/math.aug +3 -0
  272. package/examples/new-syntax/math.aug.md +29 -0
  273. package/examples/oidc-login/.aug-spec/august/0.19.0/crypto/contracts.aug +73 -0
  274. package/examples/oidc-login/.aug-spec/august/0.19.0/crypto/contracts.aug.md +791 -0
  275. package/examples/oidc-login/.aug-spec/august/0.19.0/crypto/jose.aug +68 -0
  276. package/examples/oidc-login/.aug-spec/august/0.19.0/crypto/jose.aug.md +266 -0
  277. package/examples/oidc-login/.aug-spec/august/0.19.0/json/contracts.aug +6 -0
  278. package/examples/oidc-login/.aug-spec/august/0.19.0/json/contracts.aug.md +55 -0
  279. package/examples/oidc-login/.aug-spec/august/0.19.0/memory/store.aug +45 -0
  280. package/examples/oidc-login/.aug-spec/august/0.19.0/memory/store.aug.md +250 -0
  281. package/examples/oidc-login/.aug-spec/august/0.19.0/time/contracts.aug +11 -0
  282. package/examples/oidc-login/.aug-spec/august/0.19.0/time/contracts.aug.md +96 -0
  283. package/examples/oidc-login/.aug-spec/august/0.19.0/web/contracts.aug +58 -0
  284. package/examples/oidc-login/.aug-spec/august/0.19.0/web/contracts.aug.md +420 -0
  285. package/examples/oidc-login/.aug-spec/manifest.json +40 -0
  286. package/examples/oidc-login/README.md +29 -0
  287. package/examples/oidc-login/client/contracts.aug +7 -0
  288. package/examples/oidc-login/client/contracts.aug.md +80 -0
  289. package/examples/oidc-login/client/endpoints.aug +21 -0
  290. package/examples/oidc-login/client/endpoints.aug.md +161 -0
  291. package/examples/oidc-login/client/export.aug +7 -0
  292. package/examples/oidc-login/client/export.aug.md +29 -0
  293. package/examples/oidc-login/client/login.aug +58 -0
  294. package/examples/oidc-login/client/login.aug.md +331 -0
  295. package/examples/oidc-login/client/logout.aug +18 -0
  296. package/examples/oidc-login/client/logout.aug.md +150 -0
  297. package/examples/oidc-login/client/protocol.aug +106 -0
  298. package/examples/oidc-login/client/protocol.aug.md +326 -0
  299. package/examples/oidc-login/client/session.aug +34 -0
  300. package/examples/oidc-login/client/session.aug.md +155 -0
  301. package/examples/oidc-login/client/views.aug +21 -0
  302. package/examples/oidc-login/client/views.aug.md +68 -0
  303. package/examples/oidc-login/common/export.aug +9 -0
  304. package/examples/oidc-login/common/export.aug.md +33 -0
  305. package/examples/oidc-login/common/headers.aug +11 -0
  306. package/examples/oidc-login/common/headers.aug.md +79 -0
  307. package/examples/oidc-login/common/keys.aug +37 -0
  308. package/examples/oidc-login/common/keys.aug.md +207 -0
  309. package/examples/oidc-login/common/settings.aug +4 -0
  310. package/examples/oidc-login/common/settings.aug.md +47 -0
  311. package/examples/oidc-login/common/views.aug +16 -0
  312. package/examples/oidc-login/common/views.aug.md +34 -0
  313. package/examples/oidc-login/main.aug +39 -0
  314. package/examples/oidc-login/main.aug.md +166 -0
  315. package/examples/oidc-login/main.yaml +12 -0
  316. package/examples/oidc-login/provider/authorization.aug +59 -0
  317. package/examples/oidc-login/provider/authorization.aug.md +264 -0
  318. package/examples/oidc-login/provider/contracts.aug +15 -0
  319. package/examples/oidc-login/provider/contracts.aug.md +193 -0
  320. package/examples/oidc-login/provider/credentials.aug +10 -0
  321. package/examples/oidc-login/provider/credentials.aug.md +64 -0
  322. package/examples/oidc-login/provider/discovery.aug +13 -0
  323. package/examples/oidc-login/provider/discovery.aug.md +133 -0
  324. package/examples/oidc-login/provider/export.aug +13 -0
  325. package/examples/oidc-login/provider/export.aug.md +41 -0
  326. package/examples/oidc-login/provider/token.aug +37 -0
  327. package/examples/oidc-login/provider/token.aug.md +223 -0
  328. package/examples/oidc-login/provider/userinfo.aug +26 -0
  329. package/examples/oidc-login/provider/userinfo.aug.md +104 -0
  330. package/examples/oidc-login/provider/views.aug +18 -0
  331. package/examples/oidc-login/provider/views.aug.md +63 -0
  332. package/examples/ownership/.aug-spec/manifest.json +8 -0
  333. package/examples/ownership/counter.aug +14 -0
  334. package/examples/ownership/counter.aug.md +85 -0
  335. package/examples/ownership/main.aug +4 -0
  336. package/examples/ownership/main.aug.md +38 -0
  337. package/examples/ownership-transfer/.aug-spec/august/0.19.0/io/contracts.aug +36 -0
  338. package/examples/ownership-transfer/.aug-spec/august/0.19.0/io/contracts.aug.md +316 -0
  339. package/examples/ownership-transfer/.aug-spec/manifest.json +10 -0
  340. package/examples/ownership-transfer/main.aug +9 -0
  341. package/examples/ownership-transfer/main.aug.md +63 -0
  342. package/examples/ownership-transfer/resource.aug +16 -0
  343. package/examples/ownership-transfer/resource.aug.md +89 -0
  344. package/examples/packages/README.md +15 -0
  345. package/examples/packages/app/.aug-spec/manifest.json +9 -0
  346. package/examples/packages/app/.aug-spec/packages/@example/aug-math/0.1.0/arithmetic.aug +9 -0
  347. package/examples/packages/app/.aug-spec/packages/@example/aug-math/0.1.0/arithmetic.aug.md +63 -0
  348. package/examples/packages/app/main.aug +2 -0
  349. package/examples/packages/app/main.aug.md +33 -0
  350. package/examples/packages/app/main.yaml +2 -0
  351. package/examples/packages/math/.aug-spec/manifest.json +8 -0
  352. package/examples/packages/math/README.md +3 -0
  353. package/examples/packages/math/aug-package.json +8 -0
  354. package/examples/packages/math/package.json +9 -0
  355. package/examples/packages/math/src/arithmetic.aug +8 -0
  356. package/examples/packages/math/src/arithmetic.aug.md +63 -0
  357. package/examples/packages/math/src/export.aug +1 -0
  358. package/examples/packages/math/src/export.aug.md +17 -0
  359. package/examples/visibility/.aug-spec/manifest.json +8 -0
  360. package/examples/visibility/counter.aug +14 -0
  361. package/examples/visibility/counter.aug.md +87 -0
  362. package/examples/visibility/main.aug +7 -0
  363. package/examples/visibility/main.aug.md +39 -0
  364. package/package.json +50 -0
  365. package/runtime/aug_crypto.c +121 -0
  366. package/runtime/aug_html.c +93 -0
  367. package/runtime/aug_http.c +829 -0
  368. package/runtime/aug_json.c +165 -0
  369. package/runtime/aug_runtime.c +792 -0
  370. package/runtime/aug_runtime.h +245 -0
  371. package/runtime/aug_tasks.c +172 -0
  372. package/runtime/aug_time.c +5 -0
  373. package/runtime/aug_values.c +80 -0
  374. package/scripts/bootstrap-native.mjs +121 -0
  375. package/scripts/native-dependencies.lock.json +65 -0
  376. package/scripts/native-home.mjs +11 -0
  377. package/src/actions.js +109 -0
  378. package/src/ast.js +19 -0
  379. package/src/builtins.js +93 -0
  380. package/src/checker.js +2896 -0
  381. package/src/cli.js +344 -0
  382. package/src/codegen.js +1159 -0
  383. package/src/config.js +149 -0
  384. package/src/continuation.js +110 -0
  385. package/src/di.js +24 -0
  386. package/src/documentation.js +27 -0
  387. package/src/editor.js +782 -0
  388. package/src/effects.js +29 -0
  389. package/src/fixes.js +222 -0
  390. package/src/formatter.js +296 -0
  391. package/src/freshness.js +154 -0
  392. package/src/help.js +212 -0
  393. package/src/html.js +27 -0
  394. package/src/http-policies.js +90 -0
  395. package/src/inference.js +16 -0
  396. package/src/interceptors.js +70 -0
  397. package/src/javadoc.js +67 -0
  398. package/src/lexer.js +199 -0
  399. package/src/libraries.js +31 -0
  400. package/src/lsp.js +180 -0
  401. package/src/native.js +144 -0
  402. package/src/navigation.js +162 -0
  403. package/src/openapi.js +220 -0
  404. package/src/ownership.js +232 -0
  405. package/src/package-manager.js +299 -0
  406. package/src/parser.js +1155 -0
  407. package/src/policies.js +130 -0
  408. package/src/project-init.js +19 -0
  409. package/src/project.js +292 -0
  410. package/src/schemas.js +62 -0
  411. package/src/semantic.js +255 -0
  412. package/src/spec.js +738 -0
  413. package/src/testing.js +186 -0
  414. package/src/types.js +10 -0
@@ -0,0 +1,161 @@
1
+ <!-- Generated by aug spec. Edit the August source, then regenerate. -->
2
+
3
+ # `endpoints.aug` specification
4
+
5
+ August 0.19.0. This document is compiled from checked code with deterministic wording guided by Simplified Technical English.
6
+
7
+ ## In this file
8
+
9
+ - [`home`](endpoints.aug.md#symbol-home) handles `GET` `/` returning `HttpResponse<Html>`.
10
+ - [`me`](endpoints.aug.md#symbol-me) handles `GET` `/me` returning `HttpResponse<UserInfo>`.
11
+
12
+ <a id="symbol-home"></a>
13
+
14
+ ## `home`
15
+
16
+ [source](endpoints.aug#L11)
17
+
18
+ **Inputs**
19
+
20
+ - `token` (`optional string`) — read from the HTTP cookie named `aug_session`; absent value becomes null.
21
+ - `crypto` ([`Crypto`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto)) — injected; callers omit it.
22
+ - `clock` ([`Clock`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock)) — injected; callers omit it.
23
+ - `keys` ([`SigningKeys`](../common/keys.aug.md#symbol-SigningKeys)) — injected; callers omit it.
24
+ - `sessions` ([`ExpiringStore<SessionClaims>`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore)) — injected; callers omit it.
25
+
26
+ Returns: `HttpResponse<Html>`.
27
+
28
+ Capabilities: [`crypto.publicRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.publicRsa), [`crypto.decodeBase64url`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.decodeBase64url), [`crypto.verifyRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.verifyRsa), [`crypto.equal`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.equal), [`clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now), [`keys.session`](../common/keys.aug.md#symbol-SigningKeys.session), [`sessions.get`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.get).
29
+
30
+ Can fail with `KeyError`, `TimeError`, `HttpError`. Callers must catch or propagate these errors.
31
+
32
+ HTTP route: `GET` `/`. Use status 200 when the handler returns a body; a returned HttpResponse can set its own status. An unhandled request failure returns status 500 and cancels its request tasks.
33
+
34
+ **What it does**
35
+
36
+ - Try these operations:
37
+ - Set `session` to call [`authenticate`](session.aug.md#symbol-authenticate) with `token` = `token`; inject `crypto` from `crypto`, `clock` from `clock`, `keys` from `keys`, `sessions` from `sessions`.
38
+ - Return call `HttpResponse` with `body` = call [`Welcome`](views.aug.md#symbol-Welcome) with `session` = `session`; `headers` = call [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders).
39
+ - If they fail with [`SessionError`](contracts.aug.md#symbol-SessionError), name the failure `error` and recover:
40
+ - Return call `HttpResponse` with `body` = call [`LoginPage`](views.aug.md#symbol-LoginPage); `headers` = call [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders).
41
+
42
+ **Author documentation**
43
+
44
+ The app renders a verified session or offers its OIDC login flow. No token claims are displayed before verification.
45
+
46
+ <a id="symbol-me"></a>
47
+
48
+ ## `me`
49
+
50
+ [source](endpoints.aug#L19)
51
+
52
+ **Inputs**
53
+
54
+ - `token` (`optional string`) — read from the HTTP cookie named `aug_session`; absent value becomes null.
55
+ - `crypto` ([`Crypto`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto)) — injected; callers omit it.
56
+ - `clock` ([`Clock`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock)) — injected; callers omit it.
57
+ - `keys` ([`SigningKeys`](../common/keys.aug.md#symbol-SigningKeys)) — injected; callers omit it.
58
+ - `sessions` ([`ExpiringStore<SessionClaims>`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore)) — injected; callers omit it.
59
+
60
+ Returns: `HttpResponse<UserInfo>`.
61
+
62
+ Capabilities: [`crypto.publicRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.publicRsa), [`crypto.decodeBase64url`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.decodeBase64url), [`crypto.verifyRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.verifyRsa), [`crypto.equal`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.equal), [`clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now), [`keys.session`](../common/keys.aug.md#symbol-SigningKeys.session), [`sessions.get`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.get).
63
+
64
+ Can fail with `SessionError`, `KeyError`, `TimeError`, `HttpError`. Callers must catch or propagate these errors.
65
+
66
+ HTTP route: `GET` `/me`. Use status 200 when the handler returns a body; a returned HttpResponse can set its own status. An unhandled request failure returns status 500 and cancels its request tasks.
67
+
68
+ Declared HTTP failures: [`SessionError`](contracts.aug.md#symbol-SessionError) returns status 401.
69
+
70
+ **What it does**
71
+
72
+ - Set `session` to call [`authenticate`](session.aug.md#symbol-authenticate) with `token` = `token`; inject `crypto` from `crypto`, `clock` from `clock`, `keys` from `keys`, `sessions` from `sessions`.
73
+ - Return call `HttpResponse` with `body` = call [`UserInfo`](../provider/contracts.aug.md#symbol-UserInfo) with `sub` = `sub` of `session`; `name` = `name` of `session`; `headers` = call [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders).
74
+
75
+ **Author documentation**
76
+
77
+ A protected JSON resource accepts only a live, verified application session.
78
+
79
+ ## Dependencies used by this file
80
+
81
+ Only referenced types and operations appear here. Each name links to its complete specification.
82
+
83
+ ### [`Crypto`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto)
84
+
85
+ Capability interface from `august.crypto`.
86
+
87
+ - [`Crypto.decodeBase64url`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.decodeBase64url) (`input`: `string`) → `Bytes`; can fail with `CryptoError`.
88
+ - [`Crypto.equal`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.equal) (`left`: `Bytes`, `right`: `Bytes`) → `bool`.
89
+ - [`Crypto.publicRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.publicRsa) (`key`: `RsaPrivateKey`) → `RsaPublicKey`; can fail with `CryptoError`.
90
+ - [`Crypto.verifyRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.verifyRsa) (`publicKey`: `RsaPublicKey`, `input`: `Bytes`, `signature`: `Bytes`) → `bool`; can fail with `CryptoError`.
91
+
92
+ ### [`ExpiringStore`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore)
93
+
94
+ Capability interface from `august.memory`.
95
+
96
+ - [`ExpiringStore.get`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.get) (`key`: `string`, `now`: `int`) → `optional T`.
97
+
98
+ ### [`Clock`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock)
99
+
100
+ Capability interface from `august.time`.
101
+
102
+ - [`Clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now) (no caller inputs) → `int`; can fail with `TimeError`.
103
+
104
+ ### [`SessionClaims`](contracts.aug.md#symbol-SessionClaims)
105
+
106
+ Record from `contracts`.
107
+
108
+ - Read `name` (`string`).
109
+ - Read `sub` (`string`).
110
+
111
+ ### [`SessionError`](contracts.aug.md#symbol-SessionError)
112
+
113
+ Class from `contracts`.
114
+
115
+ Used as a type or provider.
116
+
117
+ ### [`authenticate`](session.aug.md#symbol-authenticate)
118
+
119
+ Function from `session`.
120
+
121
+ - [`authenticate`](session.aug.md#symbol-authenticate) (`token`: `optional string`) → [`SessionClaims`](contracts.aug.md#symbol-SessionClaims); inject `crypto`: [`Crypto`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto), `clock`: [`Clock`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock), `keys`: [`SigningKeys`](../common/keys.aug.md#symbol-SigningKeys), `sessions`: [`ExpiringStore<SessionClaims>`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore); uses [`crypto.publicRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.publicRsa), [`crypto.decodeBase64url`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.decodeBase64url), [`crypto.verifyRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.verifyRsa), [`crypto.equal`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.equal), [`clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now), [`keys.session`](../common/keys.aug.md#symbol-SigningKeys.session), [`sessions.get`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.get); can fail with `SessionError`, `KeyError`, `TimeError`.
122
+
123
+ ### [`LoginPage`](views.aug.md#symbol-LoginPage)
124
+
125
+ Function from `views`.
126
+
127
+ - [`LoginPage`](views.aug.md#symbol-LoginPage) (no caller inputs) → `Html`.
128
+
129
+ ### [`Welcome`](views.aug.md#symbol-Welcome)
130
+
131
+ Function from `views`.
132
+
133
+ - [`Welcome`](views.aug.md#symbol-Welcome) (`session`: [`SessionClaims`](contracts.aug.md#symbol-SessionClaims)) → `Html`; can fail with `HttpError`.
134
+
135
+ ### [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders)
136
+
137
+ Function from `common`.
138
+
139
+ - [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders) (no caller inputs) → `Headers`; can fail with `HttpError`.
140
+
141
+ ### [`KeyError`](../common/keys.aug.md#symbol-KeyError)
142
+
143
+ Class from `common`.
144
+
145
+ Used as a type or provider.
146
+
147
+ ### [`SigningKeys`](../common/keys.aug.md#symbol-SigningKeys)
148
+
149
+ Capability interface from `common`.
150
+
151
+ - [`SigningKeys.session`](../common/keys.aug.md#symbol-SigningKeys.session) (no caller inputs) → `RsaPrivateKey`; can fail with `KeyError`.
152
+
153
+ ### [`UserInfo`](../provider/contracts.aug.md#symbol-UserInfo)
154
+
155
+ Record from `provider`.
156
+
157
+ - Construct with `sub`: `string`, `name`: `string` → [`UserInfo`](../provider/contracts.aug.md#symbol-UserInfo).
158
+
159
+ ## Shared language rules
160
+
161
+ See the [language reference](https://greenpandastudios.github.io/augscript/reference) for numeric, equality, ownership, and task rules.
@@ -0,0 +1,7 @@
1
+ export LoginTransaction from contracts
2
+ export SessionClaims from contracts
3
+ export home from endpoints
4
+ export me from endpoints
5
+ export logout from logout
6
+ export startLogin from login
7
+ export loginCallback from login
@@ -0,0 +1,29 @@
1
+ <!-- Generated by aug spec. Edit the August source, then regenerate. -->
2
+
3
+ # `export.aug` specification
4
+
5
+ August 0.19.0. This document is compiled from checked code with deterministic wording guided by Simplified Technical English.
6
+
7
+ ## In this file
8
+
9
+ - Export `LoginTransaction` from this folder.
10
+ - Export `SessionClaims` from this folder.
11
+ - Export `home` from this folder.
12
+ - Export `me` from this folder.
13
+ - Export `logout` from this folder.
14
+ - Export `startLogin` from this folder.
15
+ - Export `loginCallback` from this folder.
16
+
17
+ ## Folder exports
18
+
19
+ - Export the declaration `LoginTransaction` from [`contracts.aug`](contracts.aug.md#symbol-LoginTransaction).
20
+ - Export the declaration `SessionClaims` from [`contracts.aug`](contracts.aug.md#symbol-SessionClaims).
21
+ - Export the declaration `home` from [`endpoints.aug`](endpoints.aug.md#symbol-home).
22
+ - Export the declaration `me` from [`endpoints.aug`](endpoints.aug.md#symbol-me).
23
+ - Export the declaration `logout` from [`logout.aug`](logout.aug.md#symbol-logout).
24
+ - Export the declaration `startLogin` from [`login.aug`](login.aug.md#symbol-startLogin).
25
+ - Export the declaration `loginCallback` from [`login.aug`](login.aug.md#symbol-loginCallback).
26
+
27
+ ## Shared language rules
28
+
29
+ See the [language reference](https://greenpandastudios.github.io/augscript/reference) for numeric, equality, ownership, and task rules.
@@ -0,0 +1,58 @@
1
+ import LoginTransaction and SessionClaims and SessionError from contracts
2
+ import discover and responseJson and validateIdentity from protocol
3
+ import TokenResponse and UserInfo from provider
4
+ import settings and SigningKeys and KeyError and securityHeaders and withCookie from common
5
+ import Crypto and RsaJwks and signJwt and JwtError from august.crypto
6
+ import Clock from august.time
7
+ import HttpClient and urlEncode from august.web
8
+ import ExpiringStore and StoreFull from august.memory
9
+
10
+ /** Start a browser-bound, short-lived transaction. The PKCE verifier stays on the server. */
11
+ endpoint GET "/login/start" as startLogin(resolve Crypto crypto, resolve Clock clock, resolve HttpClient client, resolve ExpiringStore<LoginTransaction> transactions) returns HttpResponse<Html> uses crypto.random and crypto.sha256 and clock.now and client.request and transactions.put unless SessionError with status 502 and CryptoError with status 503 and TimeError with status 503 and StoreFull with status 503 and HttpError:
12
+ config = settings()
13
+ document = discover()
14
+ browser = crypto.random(size=32).base64url()
15
+ state = crypto.random(size=32).base64url()
16
+ nonce = crypto.random(size=32).base64url()
17
+ verifier = crypto.random(size=32).base64url()
18
+ transaction = LoginTransaction(state, nonce, verifier, expires=clock.now() + 300)
19
+ transactions.put(key=browser, value=transaction, expires=transaction.expires, now=clock.now())
20
+ challenge = crypto.sha256(input=verifier.bytes()).base64url()
21
+ location = document.authorization_endpoint + "?response_type=code&client_id=" + urlEncode(input=config.clientId) + "&redirect_uri=" + urlEncode(input=config.callback) + "&scope=openid%20profile&state=" + urlEncode(input=state) + "&nonce=" + urlEncode(input=nonce) + "&code_challenge=" + urlEncode(input=challenge) + "&code_challenge_method=S256"
22
+ headers = withCookie(headers=securityHeaders().with(name="location", value=location), name="aug_login", value=browser, path="/login", maxAge=300, secure=config.secureCookies)
23
+ return HttpResponse(body=<p>Opening the identity provider.</p>, status=303, headers=headers)
24
+
25
+ /** Exchange a one-use code over HTTP, verify the provider JWT/JWKS and UserInfo subject, then issue a distinct app-session JWT. */
26
+ endpoint GET "/login/callback" as loginCallback(string code from query, string state from query, optional string browser from cookie "aug_login", resolve Crypto crypto, resolve Clock clock, resolve HttpClient client, resolve SigningKeys keys, resolve ExpiringStore<LoginTransaction> transactions, resolve ExpiringStore<SessionClaims> sessions) returns HttpResponse<Html> uses crypto.equal and crypto.random and crypto.signRsa and crypto.decodeBase64url and crypto.importRsa and crypto.verifyRsa and clock.now and client.request and keys.session and transactions.take and sessions.put unless SessionError with status 400 and CryptoError with status 503 and TimeError with status 503 and KeyError and StoreFull with status 503 and JwtError and JsonError and HttpError:
27
+ if (not code.isToken(min=43, max=43)) or (not state.isToken(min=43, max=43)):
28
+ throw SessionError()
29
+ match browser:
30
+ when null:
31
+ throw SessionError()
32
+ when some secret:
33
+ match transactions.take(key=secret, now=clock.now()):
34
+ when null:
35
+ throw SessionError()
36
+ when some transaction:
37
+ if (not crypto.equal(left=transaction.state.bytes(), right=state.bytes())):
38
+ throw SessionError()
39
+ config = settings()
40
+ document = discover()
41
+ body = "grant_type=authorization_code&code=" + urlEncode(input=code) + "&redirect_uri=" + urlEncode(input=config.callback) + "&client_id=" + urlEncode(input=config.clientId) + "&code_verifier=" + urlEncode(input=transaction.verifier)
42
+ headers = Headers().with(name="content-type", value="application/x-www-form-urlencoded")
43
+ tokens = responseJson(response=client.request(method="POST", url=document.token_endpoint, headers, body=body.bytes())).decode<TokenResponse>()
44
+ if tokens.token_type != "Bearer" or (not tokens.access_token.isToken(min=43, max=43)) or tokens.expires_in <= 0:
45
+ throw SessionError()
46
+ jwks = responseJson(response=client.request(method="GET", url=document.jwks_uri)).decode<RsaJwks>()
47
+ identity = validateIdentity(token=tokens.id_token, nonce=transaction.nonce, now=clock.now(), jwks)
48
+ authHeaders = Headers().with(name="authorization", value="Bearer " + tokens.access_token)
49
+ user = responseJson(response=client.request(method="GET", url=document.userinfo_endpoint, headers=authHeaders)).decode<UserInfo>()
50
+ if user.sub != identity.sub:
51
+ throw SessionError()
52
+ now = clock.now()
53
+ session = SessionClaims(iss=config.baseUrl + "/app", sub=identity.sub, aud="august-app", exp=now + config.sessionSeconds, iat=now, jti=crypto.random(size=32).base64url(), csrf=crypto.random(size=32).base64url(), name=user.name)
54
+ jwt = signJwt(key=keys.session(), claims=Json(value=session), kid="session-1", tokenType="august-session+jwt")
55
+ sessions.put(key=session.jti, value=session, expires=session.exp, now=now)
56
+ responseHeaders = withCookie(headers=securityHeaders().with(name="location", value="/"), name="aug_session", value=jwt, path="/", maxAge=config.sessionSeconds, secure=config.secureCookies)
57
+ responseHeaders = withCookie(headers=responseHeaders, name="aug_login", value="", path="/login", maxAge=0, secure=config.secureCookies)
58
+ return HttpResponse(body=<p>Signed in.</p>, status=303, headers=responseHeaders)
@@ -0,0 +1,331 @@
1
+ <!-- Generated by aug spec. Edit the August source, then regenerate. -->
2
+
3
+ # `login.aug` specification
4
+
5
+ August 0.19.0. This document is compiled from checked code with deterministic wording guided by Simplified Technical English.
6
+
7
+ ## In this file
8
+
9
+ - [`startLogin`](login.aug.md#symbol-startLogin) handles `GET` `/login/start` returning `HttpResponse<Html>`.
10
+ - [`loginCallback`](login.aug.md#symbol-loginCallback) handles `GET` `/login/callback` returning `HttpResponse<Html>`.
11
+
12
+ <a id="symbol-startLogin"></a>
13
+
14
+ ## `startLogin`
15
+
16
+ [source](login.aug#L11)
17
+
18
+ **Inputs**
19
+
20
+ - `crypto` ([`Crypto`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto)) — injected; callers omit it.
21
+ - `clock` ([`Clock`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock)) — injected; callers omit it.
22
+ - `client` ([`HttpClient`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-HttpClient)) — injected; callers omit it.
23
+ - `transactions` ([`ExpiringStore<LoginTransaction>`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore)) — injected; callers omit it.
24
+
25
+ Returns: `HttpResponse<Html>`.
26
+
27
+ Capabilities: [`crypto.random`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.random), [`crypto.sha256`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.sha256), [`clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now), [`client.request`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-HttpClient.request), [`transactions.put`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.put).
28
+
29
+ Can fail with `SessionError`, `CryptoError`, `TimeError`, `StoreFull`, `HttpError`. Callers must catch or propagate these errors.
30
+
31
+ HTTP route: `GET` `/login/start`. Use status 200 when the handler returns a body; a returned HttpResponse can set its own status. An unhandled request failure returns status 500 and cancels its request tasks.
32
+
33
+ Declared HTTP failures: [`SessionError`](contracts.aug.md#symbol-SessionError) returns status 502; `CryptoError` returns status 503; `TimeError` returns status 503; [`StoreFull`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-StoreFull) returns status 503.
34
+
35
+ **What it does**
36
+
37
+ - Set `config` to call [`settings`](../common/settings.aug.md#symbol-settings).
38
+ - Set `document` to call [`discover`](protocol.aug.md#symbol-discover); inject `client` from `client`.
39
+ - Set `browser` to call `base64url` on call [`Crypto.random`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.random) on `crypto` with `size` = `32`.
40
+ - Set `state` to call `base64url` on call [`Crypto.random`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.random) on `crypto` with `size` = `32`.
41
+ - Set `nonce` to call `base64url` on call [`Crypto.random`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.random) on `crypto` with `size` = `32`.
42
+ - Set `verifier` to call `base64url` on call [`Crypto.random`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.random) on `crypto` with `size` = `32`.
43
+ - Set `transaction` to call [`LoginTransaction`](contracts.aug.md#symbol-LoginTransaction) with `state` = `state`; `nonce` = `nonce`; `verifier` = `verifier`; `expires` = (call [`Clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now) on `clock` plus `300`).
44
+ - Call [`ExpiringStore.put`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.put) on `transactions` with `key` = `browser`; `value` = `transaction`; `expires` = `expires` of `transaction`; `now` = call [`Clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now) on `clock`.
45
+ - Set `challenge` to call `base64url` on call [`Crypto.sha256`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.sha256) on `crypto` with `input` = call `bytes` on `verifier`.
46
+ - Build `location` by joining these text parts without separators, in order:
47
+ 1. `authorization_endpoint` of `document`
48
+ 2. `"?response_type=code&client_id="`
49
+ 3. call [`urlEncode`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-urlEncode) with `input` = `clientId` of `config`
50
+ 4. `"&redirect_uri="`
51
+ 5. call [`urlEncode`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-urlEncode) with `input` = `callback` of `config`
52
+ 6. `"&scope=openid%20profile&state="`
53
+ 7. call [`urlEncode`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-urlEncode) with `input` = `state`
54
+ 8. `"&nonce="`
55
+ 9. call [`urlEncode`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-urlEncode) with `input` = `nonce`
56
+ 10. `"&code_challenge="`
57
+ 11. call [`urlEncode`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-urlEncode) with `input` = `challenge`
58
+ 12. `"&code_challenge_method=S256"`
59
+ - Set `headers` to call [`withCookie`](../common/headers.aug.md#symbol-withCookie) with `headers` = call `with` on call [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders) with `name` = `"location"`; `value` = `location`; `name` = `"aug_login"`; `value` = `browser`; `path` = `"/login"`; `maxAge` = `300`; `secure` = `secureCookies` of `config`.
60
+ - Return call `HttpResponse` with `body` = the HTML element `p` containing `Opening the identity provider.` (rendered on the server with embedded text escaped); `status` = `303`; `headers` = `headers`.
61
+
62
+ **Author documentation**
63
+
64
+ Start a browser-bound, short-lived transaction. The PKCE verifier stays on the server.
65
+
66
+ <a id="symbol-loginCallback"></a>
67
+
68
+ ## `loginCallback`
69
+
70
+ [source](login.aug#L26)
71
+
72
+ **Inputs**
73
+
74
+ - `code` (`string`) — read from the HTTP query.
75
+ - `state` (`string`) — read from the HTTP query.
76
+ - `browser` (`optional string`) — read from the HTTP cookie named `aug_login`; absent value becomes null.
77
+ - `crypto` ([`Crypto`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto)) — injected; callers omit it.
78
+ - `clock` ([`Clock`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock)) — injected; callers omit it.
79
+ - `client` ([`HttpClient`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-HttpClient)) — injected; callers omit it.
80
+ - `keys` ([`SigningKeys`](../common/keys.aug.md#symbol-SigningKeys)) — injected; callers omit it.
81
+ - `transactions` ([`ExpiringStore<LoginTransaction>`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore)) — injected; callers omit it.
82
+ - `sessions` ([`ExpiringStore<SessionClaims>`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore)) — injected; callers omit it.
83
+
84
+ Returns: `HttpResponse<Html>`.
85
+
86
+ Capabilities: [`crypto.equal`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.equal), [`crypto.random`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.random), [`crypto.signRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.signRsa), [`crypto.decodeBase64url`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.decodeBase64url), [`crypto.importRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.importRsa), [`crypto.verifyRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.verifyRsa), [`clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now), [`client.request`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-HttpClient.request), [`keys.session`](../common/keys.aug.md#symbol-SigningKeys.session), [`transactions.take`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.take), [`sessions.put`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.put).
87
+
88
+ Can fail with `SessionError`, `CryptoError`, `TimeError`, `KeyError`, `StoreFull`, `JwtError`, `JsonError`, `HttpError`. Callers must catch or propagate these errors.
89
+
90
+ HTTP route: `GET` `/login/callback`. Use status 200 when the handler returns a body; a returned HttpResponse can set its own status. An unhandled request failure returns status 500 and cancels its request tasks.
91
+
92
+ Declared HTTP failures: [`SessionError`](contracts.aug.md#symbol-SessionError) returns status 400; `CryptoError` returns status 503; `TimeError` returns status 503; [`StoreFull`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-StoreFull) returns status 503.
93
+
94
+ **What it does**
95
+
96
+ - If not (call `isToken` on `code` with `min` = `43`; `max` = `43`) or not (call `isToken` on `state` with `min` = `43`; `max` = `43`):
97
+ - Fail with call [`SessionError`](contracts.aug.md#symbol-SessionError). Transfer control to a matching catch or propagate the failure.
98
+ - Select the matching case for `browser`:
99
+ - A null value, including omitted optional input:
100
+ - Fail with call [`SessionError`](contracts.aug.md#symbol-SessionError). Transfer control to a matching catch or propagate the failure.
101
+ - A present, non-null value, named `secret`:
102
+ - Select the matching case for call [`ExpiringStore.take`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.take) on `transactions` with `key` = `secret`; `now` = call [`Clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now) on `clock`:
103
+ - A null value, including omitted optional input:
104
+ - Fail with call [`SessionError`](contracts.aug.md#symbol-SessionError). Transfer control to a matching catch or propagate the failure.
105
+ - A present, non-null value, named `transaction`:
106
+ - If not (call [`Crypto.equal`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.equal) on `crypto` with `left` = call `bytes` on `state` of `transaction`; `right` = call `bytes` on `state`):
107
+ - Fail with call [`SessionError`](contracts.aug.md#symbol-SessionError). Transfer control to a matching catch or propagate the failure.
108
+ - Set `config` to call [`settings`](../common/settings.aug.md#symbol-settings).
109
+ - Set `document` to call [`discover`](protocol.aug.md#symbol-discover); inject `client` from `client`.
110
+ - Build `body` by joining these text parts without separators, in order:
111
+ 1. `"grant_type=authorization_code&code="`
112
+ 2. call [`urlEncode`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-urlEncode) with `input` = `code`
113
+ 3. `"&redirect_uri="`
114
+ 4. call [`urlEncode`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-urlEncode) with `input` = `callback` of `config`
115
+ 5. `"&client_id="`
116
+ 6. call [`urlEncode`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-urlEncode) with `input` = `clientId` of `config`
117
+ 7. `"&code_verifier="`
118
+ 8. call [`urlEncode`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-urlEncode) with `input` = `verifier` of `transaction`
119
+ - Set `headers` to call `with` on call `Headers` with `name` = `"content-type"`; `value` = `"application/x-www-form-urlencoded"`.
120
+ - Set `tokens` to call `decode` on call [`responseJson`](protocol.aug.md#symbol-responseJson) with `response` = call [`HttpClient.request`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-HttpClient.request) on `client` with `method` = `"POST"`; `url` = `token_endpoint` of `document`; `headers` = `headers`; `body` = call `bytes` on `body` with type arguments [`TokenResponse`](../provider/contracts.aug.md#symbol-TokenResponse).
121
+ - If ((`token_type` of `tokens` does not equal `"Bearer"`) or not (call `isToken` on `access_token` of `tokens` with `min` = `43`; `max` = `43`)) or (`expires_in` of `tokens` is at most `0`):
122
+ - Fail with call [`SessionError`](contracts.aug.md#symbol-SessionError). Transfer control to a matching catch or propagate the failure.
123
+ - Set `jwks` to call `decode` on call [`responseJson`](protocol.aug.md#symbol-responseJson) with `response` = call [`HttpClient.request`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-HttpClient.request) on `client` with `method` = `"GET"`; `url` = `jwks_uri` of `document` with type arguments [`RsaJwks`](../.aug-spec/august/0.19.0/crypto/jose.aug.md#symbol-RsaJwks).
124
+ - Set `identity` to call [`validateIdentity`](protocol.aug.md#symbol-validateIdentity) with `token` = `id_token` of `tokens`; `nonce` = `nonce` of `transaction`; `now` = call [`Clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now) on `clock`; `jwks` = `jwks`; inject `crypto` from `crypto`.
125
+ - Set `authHeaders` to call `with` on call `Headers` with `name` = `"authorization"`; `value` = (`"Bearer "` plus `access_token` of `tokens`).
126
+ - Set `user` to call `decode` on call [`responseJson`](protocol.aug.md#symbol-responseJson) with `response` = call [`HttpClient.request`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-HttpClient.request) on `client` with `method` = `"GET"`; `url` = `userinfo_endpoint` of `document`; `headers` = `authHeaders` with type arguments [`UserInfo`](../provider/contracts.aug.md#symbol-UserInfo).
127
+ - If `sub` of `user` does not equal `sub` of `identity`:
128
+ - Fail with call [`SessionError`](contracts.aug.md#symbol-SessionError). Transfer control to a matching catch or propagate the failure.
129
+ - Set `now` to call [`Clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now) on `clock`.
130
+ - Set `session` to call [`SessionClaims`](contracts.aug.md#symbol-SessionClaims) with `iss` = (`baseUrl` of `config` plus `"/app"`); `sub` = `sub` of `identity`; `aud` = `"august-app"`; `exp` = (`now` plus `sessionSeconds` of `config`); `iat` = `now`; `jti` = call `base64url` on call [`Crypto.random`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.random) on `crypto` with `size` = `32`; `csrf` = call `base64url` on call [`Crypto.random`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.random) on `crypto` with `size` = `32`; `name` = `name` of `user`.
131
+ - Set `jwt` to call [`signJwt`](../.aug-spec/august/0.19.0/crypto/jose.aug.md#symbol-signJwt) with `key` = call [`SigningKeys.session`](../common/keys.aug.md#symbol-SigningKeys.session) on `keys`; `claims` = call `Json` with `value` = `session`; `kid` = `"session-1"`; `tokenType` = `"august-session+jwt"`; inject `crypto` from `crypto`.
132
+ - Call [`ExpiringStore.put`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.put) on `sessions` with `key` = `jti` of `session`; `value` = `session`; `expires` = `exp` of `session`; `now` = `now`.
133
+ - Set `responseHeaders` to call [`withCookie`](../common/headers.aug.md#symbol-withCookie) with `headers` = call `with` on call [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders) with `name` = `"location"`; `value` = `"/"`; `name` = `"aug_session"`; `value` = `jwt`; `path` = `"/"`; `maxAge` = `sessionSeconds` of `config`; `secure` = `secureCookies` of `config`.
134
+ - Set `responseHeaders` to call [`withCookie`](../common/headers.aug.md#symbol-withCookie) with `headers` = `responseHeaders`; `name` = `"aug_login"`; `value` = `""`; `path` = `"/login"`; `maxAge` = `0`; `secure` = `secureCookies` of `config`.
135
+ - Return call `HttpResponse` with `body` = the HTML element `p` containing `Signed in.` (rendered on the server with embedded text escaped); `status` = `303`; `headers` = `responseHeaders`.
136
+
137
+ **Author documentation**
138
+
139
+ Exchange a one-use code over HTTP, verify the provider JWT/JWKS and UserInfo subject, then issue a distinct app-session JWT.
140
+
141
+ ## Dependencies used by this file
142
+
143
+ Only referenced types and operations appear here. Each name links to its complete specification.
144
+
145
+ ### [`Crypto`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto)
146
+
147
+ Capability interface from `august.crypto`.
148
+
149
+ - [`Crypto.decodeBase64url`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.decodeBase64url) (`input`: `string`) → `Bytes`; can fail with `CryptoError`.
150
+ - [`Crypto.equal`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.equal) (`left`: `Bytes`, `right`: `Bytes`) → `bool`.
151
+ - [`Crypto.importRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.importRsa) (`modulus`: `Bytes`, `exponent`: `Bytes`) → `RsaPublicKey`; can fail with `CryptoError`.
152
+ - [`Crypto.random`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.random) (`size`: `int`) → `Bytes`; can fail with `CryptoError`.
153
+ - [`Crypto.sha256`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.sha256) (`input`: `Bytes`) → `Bytes`; can fail with `CryptoError`.
154
+ - [`Crypto.signRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.signRsa) (`key`: `RsaPrivateKey`, `input`: `Bytes`) → `Bytes`; can fail with `CryptoError`.
155
+ - [`Crypto.verifyRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.verifyRsa) (`publicKey`: `RsaPublicKey`, `input`: `Bytes`, `signature`: `Bytes`) → `bool`; can fail with `CryptoError`.
156
+
157
+ ### [`JwtError`](../.aug-spec/august/0.19.0/crypto/jose.aug.md#symbol-JwtError)
158
+
159
+ Class from `august.crypto`.
160
+
161
+ Used as a type or provider.
162
+
163
+ ### [`RsaJwks`](../.aug-spec/august/0.19.0/crypto/jose.aug.md#symbol-RsaJwks)
164
+
165
+ Record from `august.crypto`.
166
+
167
+ Used as a type or provider.
168
+
169
+ ### [`signJwt`](../.aug-spec/august/0.19.0/crypto/jose.aug.md#symbol-signJwt)
170
+
171
+ Function from `august.crypto`.
172
+
173
+ - [`signJwt`](../.aug-spec/august/0.19.0/crypto/jose.aug.md#symbol-signJwt) (`key`: `RsaPrivateKey`, `claims`: `Json`, `kid`: `string`, `tokenType`: `string`) → `string`; inject `crypto`: [`Crypto`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto); uses [`crypto.signRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.signRsa); can fail with `JwtError`.
174
+
175
+ ### [`ExpiringStore`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore)
176
+
177
+ Capability interface from `august.memory`.
178
+
179
+ - [`ExpiringStore.put`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.put) (`key`: `string`, `value`: `T`, `expires`: `int`, `now`: `int`) → `void`; can fail with `StoreFull`.
180
+ - [`ExpiringStore.take`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.take) (`key`: `string`, `now`: `int`) → `optional T`.
181
+
182
+ ### [`StoreFull`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-StoreFull)
183
+
184
+ Class from `august.memory`.
185
+
186
+ Used as a type or provider.
187
+
188
+ ### [`Clock`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock)
189
+
190
+ Capability interface from `august.time`.
191
+
192
+ - [`Clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now) (no caller inputs) → `int`; can fail with `TimeError`.
193
+
194
+ ### [`HttpClient`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-HttpClient)
195
+
196
+ Capability interface from `august.web`.
197
+
198
+ - [`HttpClient.request`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-HttpClient.request) (`method`: `string`, `url`: `string`, `headers`: `optional Headers`, `body`: `optional Bytes`) → `HttpResponse<Bytes>`; can fail with `HttpError`.
199
+
200
+ ### [`urlEncode`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-urlEncode)
201
+
202
+ Function from `august.web`.
203
+
204
+ - [`urlEncode`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-urlEncode) (`input`: `string`) → `string`; can fail with `HttpError`.
205
+
206
+ ### [`LoginTransaction`](contracts.aug.md#symbol-LoginTransaction)
207
+
208
+ Record from `contracts`.
209
+
210
+ - Construct with `state`: `string`, `nonce`: `string`, `verifier`: `string`, `expires`: `int` → [`LoginTransaction`](contracts.aug.md#symbol-LoginTransaction).
211
+ - Read `expires` (`int`).
212
+ - Read `nonce` (`string`).
213
+ - Read `state` (`string`).
214
+ - Read `verifier` (`string`).
215
+
216
+ ### [`SessionClaims`](contracts.aug.md#symbol-SessionClaims)
217
+
218
+ Record from `contracts`.
219
+
220
+ - Construct with `iss`: `string`, `sub`: `string`, `aud`: `string`, `exp`: `int`, `iat`: `int`, `jti`: `string`, `csrf`: `string`, `name`: `string` → [`SessionClaims`](contracts.aug.md#symbol-SessionClaims).
221
+ - Read `exp` (`int`).
222
+ - Read `jti` (`string`).
223
+
224
+ ### [`SessionError`](contracts.aug.md#symbol-SessionError)
225
+
226
+ Class from `contracts`.
227
+
228
+ - Construct with no caller inputs → [`SessionError`](contracts.aug.md#symbol-SessionError).
229
+
230
+ ### [`discover`](protocol.aug.md#symbol-discover)
231
+
232
+ Function from `protocol`.
233
+
234
+ - [`discover`](protocol.aug.md#symbol-discover) (no caller inputs) → [`Discovery`](../provider/discovery.aug.md#symbol-Discovery); inject `client`: [`HttpClient`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-HttpClient); uses [`client.request`](../.aug-spec/august/0.19.0/web/contracts.aug.md#symbol-HttpClient.request); can fail with `SessionError`, `HttpError`.
235
+
236
+ ### [`responseJson`](protocol.aug.md#symbol-responseJson)
237
+
238
+ Function from `protocol`.
239
+
240
+ - [`responseJson`](protocol.aug.md#symbol-responseJson) (`response`: `HttpResponse<Bytes>`) → `Json`; can fail with `SessionError`.
241
+
242
+ ### [`validateIdentity`](protocol.aug.md#symbol-validateIdentity)
243
+
244
+ Function from `protocol`.
245
+
246
+ - [`validateIdentity`](protocol.aug.md#symbol-validateIdentity) (`token`: `string`, `nonce`: `string`, `now`: `int`, `jwks`: [`RsaJwks`](../.aug-spec/august/0.19.0/crypto/jose.aug.md#symbol-RsaJwks)) → [`IdClaims`](../provider/contracts.aug.md#symbol-IdClaims); inject `crypto`: [`Crypto`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto); uses [`crypto.decodeBase64url`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.decodeBase64url), [`crypto.importRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.importRsa), [`crypto.verifyRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.verifyRsa), [`crypto.equal`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.equal); can fail with `SessionError`.
247
+
248
+ ### [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders)
249
+
250
+ Function from `common`.
251
+
252
+ - [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders) (no caller inputs) → `Headers`; can fail with `HttpError`.
253
+
254
+ ### [`withCookie`](../common/headers.aug.md#symbol-withCookie)
255
+
256
+ Function from `common`.
257
+
258
+ - [`withCookie`](../common/headers.aug.md#symbol-withCookie) (`headers`: `Headers`, `name`: `string`, `value`: `string`, `path`: `string`, `maxAge`: `int`, `secure`: `bool`) → `Headers`; can fail with `HttpError`.
259
+
260
+ ### [`KeyError`](../common/keys.aug.md#symbol-KeyError)
261
+
262
+ Class from `common`.
263
+
264
+ Used as a type or provider.
265
+
266
+ ### [`SigningKeys`](../common/keys.aug.md#symbol-SigningKeys)
267
+
268
+ Capability interface from `common`.
269
+
270
+ - [`SigningKeys.session`](../common/keys.aug.md#symbol-SigningKeys.session) (no caller inputs) → `RsaPrivateKey`; can fail with `KeyError`.
271
+
272
+ ### [`Settings`](../common/settings.aug.md#symbol-Settings)
273
+
274
+ Record.
275
+
276
+ - Read `baseUrl` (`string`).
277
+ - Read `callback` (`string`).
278
+ - Read `clientId` (`string`).
279
+ - Read `secureCookies` (`bool`).
280
+ - Read `sessionSeconds` (`int`).
281
+
282
+ ### [`settings`](../common/settings.aug.md#symbol-settings)
283
+
284
+ Function from `common`.
285
+
286
+ - [`settings`](../common/settings.aug.md#symbol-settings) (no caller inputs) → [`Settings`](../common/settings.aug.md#symbol-Settings).
287
+
288
+ ### [`IdClaims`](../provider/contracts.aug.md#symbol-IdClaims)
289
+
290
+ Record.
291
+
292
+ - Read `sub` (`string`).
293
+
294
+ ### [`TokenResponse`](../provider/contracts.aug.md#symbol-TokenResponse)
295
+
296
+ Record from `provider`.
297
+
298
+ - Read `access_token` (`string`).
299
+ - Read `expires_in` (`int`).
300
+ - Read `id_token` (`string`).
301
+ - Read `token_type` (`string`).
302
+
303
+ ### [`UserInfo`](../provider/contracts.aug.md#symbol-UserInfo)
304
+
305
+ Record from `provider`.
306
+
307
+ - Read `name` (`string`).
308
+ - Read `sub` (`string`).
309
+
310
+ ### [`Discovery`](../provider/discovery.aug.md#symbol-Discovery)
311
+
312
+ Record.
313
+
314
+ - Read `authorization_endpoint` (`string`).
315
+ - Read `jwks_uri` (`string`).
316
+ - Read `token_endpoint` (`string`).
317
+ - Read `userinfo_endpoint` (`string`).
318
+
319
+ ## Built-in operations used by this file
320
+
321
+ - `Bytes.base64url` (no inputs) → `string`: Encode immutable bytes as unpadded RFC 4648 URL-safe base64.
322
+ - `Headers.with` (`name`: `string`, `value`: `string`) → `Headers`: Return new headers with one additional validated field. Header names ignore case; duplicate values remain separate. Can fail with `HttpError`.
323
+ - `Json.decode` (no inputs) → `UserInfo`: Decode a checked record or data type: json.decode<Profile>(). Unknown fields, type mismatches, and validation errors are rejected. Can fail with `JsonError`.
324
+ - `string.bytes` (no inputs) → `Bytes`: Encode this string as immutable UTF-8 bytes.
325
+ - `string.isToken` (`min`: `int`, `max`: `int`) → `bool`: Require an ASCII RFC 3986 unreserved token with a bounded length.
326
+
327
+ [Full built-in reference](https://greenpandastudios.github.io/augscript/language-constructs).
328
+
329
+ ## Shared language rules
330
+
331
+ See the [language reference](https://greenpandastudios.github.io/augscript/reference) for numeric, equality, ownership, and task rules.
@@ -0,0 +1,18 @@
1
+ import SessionClaims and SessionError and LogoutForm from contracts
2
+ import authenticate from session
3
+ import settings and SigningKeys and KeyError and securityHeaders and withCookie from common
4
+ import Crypto from august.crypto
5
+ import Clock from august.time
6
+ import ExpiringStore from august.memory
7
+
8
+ /** POST logout checks the origin and session-bound CSRF value, then removes the live registry entry before clearing the cookie. */
9
+ endpoint POST "/logout" as logout(LogoutForm input from form, optional string token from cookie "aug_session", optional string origin from header, resolve Crypto crypto, resolve Clock clock, resolve SigningKeys keys, resolve ExpiringStore<SessionClaims> sessions) returns HttpResponse<Html> uses crypto.publicRsa and crypto.decodeBase64url and crypto.verifyRsa and crypto.equal and clock.now and keys.session and sessions.get and sessions.take unless SessionError with status 403 and KeyError and TimeError and CryptoError and HttpError:
10
+ config = settings()
11
+ if origin != config.baseUrl:
12
+ throw SessionError()
13
+ session = authenticate(token)
14
+ if (not crypto.equal(left=input.csrf.bytes(), right=session.csrf.bytes())):
15
+ throw SessionError()
16
+ sessions.take(key=session.jti, now=clock.now())
17
+ headers = withCookie(headers=securityHeaders().with(name="location", value="/"), name="aug_session", value="", path="/", maxAge=0, secure=config.secureCookies)
18
+ return HttpResponse(body=<p>Signed out.</p>, status=303, headers=headers)