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