@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,133 @@
|
|
|
1
|
+
<!-- Generated by aug spec. Edit the August source, then regenerate. -->
|
|
2
|
+
|
|
3
|
+
# `discovery.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
|
+
- [`Discovery`](discovery.aug.md#symbol-Discovery) is an immutable record.
|
|
10
|
+
- [`discovery`](discovery.aug.md#symbol-discovery) handles `GET` `/provider/.well-known/openid-configuration` returning `Discovery`.
|
|
11
|
+
- [`jwks`](discovery.aug.md#symbol-jwks) handles `GET` `/provider/jwks` returning `RsaJwks`.
|
|
12
|
+
|
|
13
|
+
<a id="symbol-Discovery"></a>
|
|
14
|
+
|
|
15
|
+
## `Discovery`
|
|
16
|
+
|
|
17
|
+
[source](discovery.aug#L5)
|
|
18
|
+
|
|
19
|
+
Immutable record.
|
|
20
|
+
|
|
21
|
+
**Author documentation**
|
|
22
|
+
|
|
23
|
+
Discovery advertises exactly this provider's supported authorization-code profile.
|
|
24
|
+
|
|
25
|
+
**Inputs**
|
|
26
|
+
|
|
27
|
+
- `issuer` (`string`) — required labeled input — stored as `issuer` and read-only after initialization.
|
|
28
|
+
- `authorization_endpoint` (`string`) — required labeled input — stored as `authorization_endpoint` and read-only after initialization.
|
|
29
|
+
- `token_endpoint` (`string`) — required labeled input — stored as `token_endpoint` and read-only after initialization.
|
|
30
|
+
- `userinfo_endpoint` (`string`) — required labeled input — stored as `userinfo_endpoint` and read-only after initialization.
|
|
31
|
+
- `jwks_uri` (`string`) — required labeled input — stored as `jwks_uri` and read-only after initialization.
|
|
32
|
+
- `response_types_supported` (`List<string>`) — required labeled input — stored as `response_types_supported` and read-only after initialization.
|
|
33
|
+
- `grant_types_supported` (`List<string>`) — required labeled input — stored as `grant_types_supported` and read-only after initialization.
|
|
34
|
+
- `subject_types_supported` (`List<string>`) — required labeled input — stored as `subject_types_supported` and read-only after initialization.
|
|
35
|
+
- `id_token_signing_alg_values_supported` (`List<string>`) — required labeled input — stored as `id_token_signing_alg_values_supported` and read-only after initialization.
|
|
36
|
+
- `token_endpoint_auth_methods_supported` (`List<string>`) — required labeled input — stored as `token_endpoint_auth_methods_supported` and read-only after initialization.
|
|
37
|
+
- `scopes_supported` (`List<string>`) — required labeled input — stored as `scopes_supported` and read-only after initialization.
|
|
38
|
+
- `claims_supported` (`List<string>`) — required labeled input — stored as `claims_supported` and read-only after initialization.
|
|
39
|
+
- `code_challenge_methods_supported` (`List<string>`) — required labeled input — stored as `code_challenge_methods_supported` and read-only after initialization.
|
|
40
|
+
|
|
41
|
+
<a id="symbol-discovery"></a>
|
|
42
|
+
|
|
43
|
+
## `discovery`
|
|
44
|
+
|
|
45
|
+
[source](discovery.aug#L6)
|
|
46
|
+
|
|
47
|
+
Returns: [`Discovery`](discovery.aug.md#symbol-Discovery).
|
|
48
|
+
|
|
49
|
+
HTTP route: `GET` `/provider/.well-known/openid-configuration`. 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.
|
|
50
|
+
|
|
51
|
+
**What it does**
|
|
52
|
+
|
|
53
|
+
- Set `config` to call [`settings`](../common/settings.aug.md#symbol-settings).
|
|
54
|
+
- Return call [`Discovery`](discovery.aug.md#symbol-Discovery) with `issuer` = `issuer` of `config`; `authorization_endpoint` = (`issuer` of `config` plus `"/authorize"`); `token_endpoint` = (`issuer` of `config` plus `"/token"`); `userinfo_endpoint` = (`issuer` of `config` plus `"/userinfo"`); `jwks_uri` = (`issuer` of `config` plus `"/jwks"`); `response_types_supported` = a list containing `"code"`; `grant_types_supported` = a list containing `"authorization_code"`; `subject_types_supported` = a list containing `"public"`; `id_token_signing_alg_values_supported` = a list containing `"RS256"`; `token_endpoint_auth_methods_supported` = a list containing `"none"`; `scopes_supported` = a list containing `"openid"`, `"profile"`; `claims_supported` = a list containing `"iss"`, `"sub"`, `"aud"`, `"exp"`, `"iat"`, `"nonce"`, `"name"`; `code_challenge_methods_supported` = a list containing `"S256"`.
|
|
55
|
+
|
|
56
|
+
<a id="symbol-jwks"></a>
|
|
57
|
+
|
|
58
|
+
## `jwks`
|
|
59
|
+
|
|
60
|
+
[source](discovery.aug#L11)
|
|
61
|
+
|
|
62
|
+
**Inputs**
|
|
63
|
+
|
|
64
|
+
- `crypto` ([`Crypto`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto)) — injected; callers omit it.
|
|
65
|
+
- `keys` ([`SigningKeys`](../common/keys.aug.md#symbol-SigningKeys)) — injected; callers omit it.
|
|
66
|
+
|
|
67
|
+
Returns: [`RsaJwks`](../.aug-spec/august/0.19.0/crypto/jose.aug.md#symbol-RsaJwks).
|
|
68
|
+
|
|
69
|
+
Capabilities: [`keys.provider`](../common/keys.aug.md#symbol-SigningKeys.provider), [`crypto.publicRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.publicRsa), [`crypto.exportRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.exportRsa).
|
|
70
|
+
|
|
71
|
+
Can fail with `KeyError`, `CryptoError`. Callers must catch or propagate these errors.
|
|
72
|
+
|
|
73
|
+
HTTP route: `GET` `/provider/jwks`. 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.
|
|
74
|
+
|
|
75
|
+
**What it does**
|
|
76
|
+
|
|
77
|
+
- Set `publicKey` to call [`Crypto.publicRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.publicRsa) on `crypto` with `key` = call [`SigningKeys.provider`](../common/keys.aug.md#symbol-SigningKeys.provider) on `keys`.
|
|
78
|
+
- Return call [`RsaJwks`](../.aug-spec/august/0.19.0/crypto/jose.aug.md#symbol-RsaJwks) with `keys` = a list containing call [`rsaJwk`](../.aug-spec/august/0.19.0/crypto/jose.aug.md#symbol-rsaJwk) with `publicKey` = `publicKey`; `kid` = `"provider-1"`; inject `crypto` from `crypto`.
|
|
79
|
+
|
|
80
|
+
**Author documentation**
|
|
81
|
+
|
|
82
|
+
Only the provider's public signing key is published. Session keys never enter this JWKS.
|
|
83
|
+
|
|
84
|
+
## Dependencies used by this file
|
|
85
|
+
|
|
86
|
+
Only referenced types and operations appear here. Each name links to its complete specification.
|
|
87
|
+
|
|
88
|
+
### [`Crypto`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto)
|
|
89
|
+
|
|
90
|
+
Capability interface from `august.crypto`.
|
|
91
|
+
|
|
92
|
+
- [`Crypto.exportRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.exportRsa) (`publicKey`: `RsaPublicKey`) → `Tuple<Bytes,Bytes>`; can fail with `CryptoError`.
|
|
93
|
+
- [`Crypto.publicRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.publicRsa) (`key`: `RsaPrivateKey`) → `RsaPublicKey`; can fail with `CryptoError`.
|
|
94
|
+
|
|
95
|
+
### [`RsaJwks`](../.aug-spec/august/0.19.0/crypto/jose.aug.md#symbol-RsaJwks)
|
|
96
|
+
|
|
97
|
+
Record from `august.crypto`.
|
|
98
|
+
|
|
99
|
+
- Construct with `keys`: `List<RsaJwk>` → [`RsaJwks`](../.aug-spec/august/0.19.0/crypto/jose.aug.md#symbol-RsaJwks).
|
|
100
|
+
|
|
101
|
+
### [`rsaJwk`](../.aug-spec/august/0.19.0/crypto/jose.aug.md#symbol-rsaJwk)
|
|
102
|
+
|
|
103
|
+
Function from `august.crypto`.
|
|
104
|
+
|
|
105
|
+
- [`rsaJwk`](../.aug-spec/august/0.19.0/crypto/jose.aug.md#symbol-rsaJwk) (`publicKey`: `RsaPublicKey`, `kid`: `string`) → [`RsaJwk`](../.aug-spec/august/0.19.0/crypto/jose.aug.md#symbol-RsaJwk); inject `crypto`: [`Crypto`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto); uses [`crypto.exportRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.exportRsa); can fail with `CryptoError`.
|
|
106
|
+
|
|
107
|
+
### [`KeyError`](../common/keys.aug.md#symbol-KeyError)
|
|
108
|
+
|
|
109
|
+
Class from `common`.
|
|
110
|
+
|
|
111
|
+
Used as a type or provider.
|
|
112
|
+
|
|
113
|
+
### [`SigningKeys`](../common/keys.aug.md#symbol-SigningKeys)
|
|
114
|
+
|
|
115
|
+
Capability interface from `common`.
|
|
116
|
+
|
|
117
|
+
- [`SigningKeys.provider`](../common/keys.aug.md#symbol-SigningKeys.provider) (no caller inputs) → `RsaPrivateKey`; can fail with `KeyError`.
|
|
118
|
+
|
|
119
|
+
### [`Settings`](../common/settings.aug.md#symbol-Settings)
|
|
120
|
+
|
|
121
|
+
Record.
|
|
122
|
+
|
|
123
|
+
- Read `issuer` (`string`).
|
|
124
|
+
|
|
125
|
+
### [`settings`](../common/settings.aug.md#symbol-settings)
|
|
126
|
+
|
|
127
|
+
Function from `common`.
|
|
128
|
+
|
|
129
|
+
- [`settings`](../common/settings.aug.md#symbol-settings) (no caller inputs) → [`Settings`](../common/settings.aug.md#symbol-Settings).
|
|
130
|
+
|
|
131
|
+
## Shared language rules
|
|
132
|
+
|
|
133
|
+
See the [language reference](https://greenpandastudios.github.io/augscript/reference) for numeric, equality, ownership, and task rules.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export AuthorizationRequest from contracts
|
|
2
|
+
export AuthorizationCode from contracts
|
|
3
|
+
export AccessGrant from contracts
|
|
4
|
+
export IdClaims from contracts
|
|
5
|
+
export TokenResponse from contracts
|
|
6
|
+
export UserInfo from contracts
|
|
7
|
+
export Discovery from discovery
|
|
8
|
+
export discovery from discovery
|
|
9
|
+
export jwks from discovery
|
|
10
|
+
export authorize from authorization
|
|
11
|
+
export providerLogin from authorization
|
|
12
|
+
export token from token
|
|
13
|
+
export userinfo from userinfo
|
|
@@ -0,0 +1,41 @@
|
|
|
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 `AuthorizationRequest` from this folder.
|
|
10
|
+
- Export `AuthorizationCode` from this folder.
|
|
11
|
+
- Export `AccessGrant` from this folder.
|
|
12
|
+
- Export `IdClaims` from this folder.
|
|
13
|
+
- Export `TokenResponse` from this folder.
|
|
14
|
+
- Export `UserInfo` from this folder.
|
|
15
|
+
- Export `Discovery` from this folder.
|
|
16
|
+
- Export `discovery` from this folder.
|
|
17
|
+
- Export `jwks` from this folder.
|
|
18
|
+
- Export `authorize` from this folder.
|
|
19
|
+
- Export `providerLogin` from this folder.
|
|
20
|
+
- Export `token` from this folder.
|
|
21
|
+
- Export `userinfo` from this folder.
|
|
22
|
+
|
|
23
|
+
## Folder exports
|
|
24
|
+
|
|
25
|
+
- Export the declaration `AuthorizationRequest` from [`contracts.aug`](contracts.aug.md#symbol-AuthorizationRequest).
|
|
26
|
+
- Export the declaration `AuthorizationCode` from [`contracts.aug`](contracts.aug.md#symbol-AuthorizationCode).
|
|
27
|
+
- Export the declaration `AccessGrant` from [`contracts.aug`](contracts.aug.md#symbol-AccessGrant).
|
|
28
|
+
- Export the declaration `IdClaims` from [`contracts.aug`](contracts.aug.md#symbol-IdClaims).
|
|
29
|
+
- Export the declaration `TokenResponse` from [`contracts.aug`](contracts.aug.md#symbol-TokenResponse).
|
|
30
|
+
- Export the declaration `UserInfo` from [`contracts.aug`](contracts.aug.md#symbol-UserInfo).
|
|
31
|
+
- Export the declaration `Discovery` from [`discovery.aug`](discovery.aug.md#symbol-Discovery).
|
|
32
|
+
- Export the declaration `discovery` from [`discovery.aug`](discovery.aug.md#symbol-discovery).
|
|
33
|
+
- Export the declaration `jwks` from [`discovery.aug`](discovery.aug.md#symbol-jwks).
|
|
34
|
+
- Export the declaration `authorize` from [`authorization.aug`](authorization.aug.md#symbol-authorize).
|
|
35
|
+
- Export the declaration `providerLogin` from [`authorization.aug`](authorization.aug.md#symbol-providerLogin).
|
|
36
|
+
- Export the declaration `token` from [`token.aug`](token.aug.md#symbol-token).
|
|
37
|
+
- Export the declaration `userinfo` from [`userinfo.aug`](userinfo.aug.md#symbol-userinfo).
|
|
38
|
+
|
|
39
|
+
## Shared language rules
|
|
40
|
+
|
|
41
|
+
See the [language reference](https://greenpandastudios.github.io/augscript/reference) for numeric, equality, ownership, and task rules.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import AuthorizationCode and AccessGrant and TokenForm and TokenResponse and OAuthError and IdClaims from contracts
|
|
2
|
+
import settings and SigningKeys and KeyError and securityHeaders from common
|
|
3
|
+
import Crypto and signJwt and JwtError from august.crypto
|
|
4
|
+
import Clock from august.time
|
|
5
|
+
import ExpiringStore and StoreFull from august.memory
|
|
6
|
+
|
|
7
|
+
_oauthError(string code, string description) returns HttpResponse<Json> unless HttpError:
|
|
8
|
+
return HttpResponse(body=Json(value=OAuthError(error=code, error_description=description)), status=400, headers=securityHeaders())
|
|
9
|
+
|
|
10
|
+
/** A real OAuth token endpoint. Exact client/redirect binding, S256 PKCE, expiry and one-use codes are enforced. Errors use OAuth JSON. */
|
|
11
|
+
endpoint POST "/provider/token" as token(HttpRequest http from request, resolve Crypto crypto, resolve Clock clock, resolve SigningKeys keys, resolve ExpiringStore<AuthorizationCode> codes, resolve ExpiringStore<AccessGrant> access) returns HttpResponse<Json> uses crypto.sha256 and crypto.equal and crypto.random and crypto.signRsa and clock.now and keys.provider and codes.take and access.put unless CryptoError with status 503 and TimeError with status 503 and KeyError and JwtError and StoreFull with status 503 and HttpError:
|
|
12
|
+
config = settings()
|
|
13
|
+
try:
|
|
14
|
+
form = http.form<TokenForm>()
|
|
15
|
+
if form.grant_type != "authorization_code":
|
|
16
|
+
return _oauthError(code="unsupported_grant_type", description="Only authorization_code is supported.")
|
|
17
|
+
if form.client_id != config.clientId:
|
|
18
|
+
return _oauthError(code="invalid_client", description="The registered client is required.")
|
|
19
|
+
if (not form.code.isToken(min=43, max=43)) or (not form.code_verifier.isToken(min=43, max=128)):
|
|
20
|
+
return _oauthError(code="invalid_grant", description="The authorization grant is invalid.")
|
|
21
|
+
now = clock.now()
|
|
22
|
+
match codes.take(key=form.code, now=now):
|
|
23
|
+
when null:
|
|
24
|
+
return _oauthError(code="invalid_grant", description="The authorization grant is invalid.")
|
|
25
|
+
when some grant:
|
|
26
|
+
challenge = crypto.sha256(input=form.code_verifier.bytes()).base64url()
|
|
27
|
+
if grant.clientId != form.client_id or grant.redirectUri != form.redirect_uri or (not crypto.equal(left=challenge.bytes(), right=grant.challenge.bytes())):
|
|
28
|
+
return _oauthError(code="invalid_grant", description="The authorization grant is invalid.")
|
|
29
|
+
claims = IdClaims(iss=config.issuer, sub=grant.subject, aud=grant.clientId, exp=now + 300, iat=now, nonce=grant.nonce, name=grant.name)
|
|
30
|
+
idToken = signJwt(key=keys.provider(), claims=Json(value=claims), kid="provider-1", tokenType="JWT")
|
|
31
|
+
accessToken = crypto.random(size=32).base64url()
|
|
32
|
+
value = AccessGrant(subject=grant.subject, name=grant.name, expires=now + 300)
|
|
33
|
+
access.put(key=accessToken, value=value, expires=value.expires, now=now)
|
|
34
|
+
body = TokenResponse(token_type="Bearer", access_token=accessToken, id_token=idToken, expires_in=300, scope="openid profile")
|
|
35
|
+
return HttpResponse(body=Json(value=body), headers=securityHeaders())
|
|
36
|
+
catch HttpError error:
|
|
37
|
+
return _oauthError(code="invalid_request", description="Submit the required URL-encoded token fields once each.")
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
<!-- Generated by aug spec. Edit the August source, then regenerate. -->
|
|
2
|
+
|
|
3
|
+
# `token.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
|
+
- [`_oauthError`](token.aug.md#symbol-_oauthError) is a function returning `HttpResponse<Json>`.
|
|
10
|
+
- [`token`](token.aug.md#symbol-token) handles `POST` `/provider/token` returning `HttpResponse<Json>`.
|
|
11
|
+
|
|
12
|
+
<a id="symbol-token"></a>
|
|
13
|
+
|
|
14
|
+
## `token`
|
|
15
|
+
|
|
16
|
+
[source](token.aug#L11)
|
|
17
|
+
|
|
18
|
+
**Inputs**
|
|
19
|
+
|
|
20
|
+
- `http` (`HttpRequest`) — read from the HTTP request.
|
|
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
|
+
- `codes` ([`ExpiringStore<AuthorizationCode>`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore)) — injected; callers omit it.
|
|
25
|
+
- `access` ([`ExpiringStore<AccessGrant>`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore)) — injected; callers omit it.
|
|
26
|
+
|
|
27
|
+
Returns: `HttpResponse<Json>`.
|
|
28
|
+
|
|
29
|
+
Capabilities: [`crypto.sha256`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.sha256), [`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), [`clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now), [`keys.provider`](../common/keys.aug.md#symbol-SigningKeys.provider), [`codes.take`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.take), [`access.put`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.put).
|
|
30
|
+
|
|
31
|
+
Can fail with `CryptoError`, `TimeError`, `KeyError`, `JwtError`, `StoreFull`, `HttpError`. Callers must catch or propagate these errors.
|
|
32
|
+
|
|
33
|
+
HTTP route: `POST` `/provider/token`. 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.
|
|
34
|
+
|
|
35
|
+
Declared HTTP failures: `CryptoError` returns status 503; `TimeError` returns status 503; [`StoreFull`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-StoreFull) returns status 503.
|
|
36
|
+
|
|
37
|
+
**What it does**
|
|
38
|
+
|
|
39
|
+
- Set `config` to call [`settings`](../common/settings.aug.md#symbol-settings).
|
|
40
|
+
- Try these operations:
|
|
41
|
+
- Set `form` to call `form` on `http` with type arguments [`TokenForm`](contracts.aug.md#symbol-TokenForm).
|
|
42
|
+
- If `grant_type` of `form` does not equal `"authorization_code"`:
|
|
43
|
+
- Return call [`_oauthError`](token.aug.md#symbol-_oauthError) with `code` = `"unsupported_grant_type"`; `description` = `"Only authorization_code is supported."`.
|
|
44
|
+
- If `client_id` of `form` does not equal `clientId` of `config`:
|
|
45
|
+
- Return call [`_oauthError`](token.aug.md#symbol-_oauthError) with `code` = `"invalid_client"`; `description` = `"The registered client is required."`.
|
|
46
|
+
- If not (call `isToken` on `code` of `form` with `min` = `43`; `max` = `43`) or not (call `isToken` on `code_verifier` of `form` with `min` = `43`; `max` = `128`):
|
|
47
|
+
- Return call [`_oauthError`](token.aug.md#symbol-_oauthError) with `code` = `"invalid_grant"`; `description` = `"The authorization grant is invalid."`.
|
|
48
|
+
- Set `now` to call [`Clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now) on `clock`.
|
|
49
|
+
- Select the matching case for call [`ExpiringStore.take`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.take) on `codes` with `key` = `code` of `form`; `now` = `now`:
|
|
50
|
+
- A null value, including omitted optional input:
|
|
51
|
+
- Return call [`_oauthError`](token.aug.md#symbol-_oauthError) with `code` = `"invalid_grant"`; `description` = `"The authorization grant is invalid."`.
|
|
52
|
+
- A present, non-null value, named `grant`:
|
|
53
|
+
- 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 `code_verifier` of `form`.
|
|
54
|
+
- If ((`clientId` of `grant` does not equal `client_id` of `form`) or (`redirectUri` of `grant` does not equal `redirect_uri` of `form`)) or not (call [`Crypto.equal`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.equal) on `crypto` with `left` = call `bytes` on `challenge`; `right` = call `bytes` on `challenge` of `grant`):
|
|
55
|
+
- Return call [`_oauthError`](token.aug.md#symbol-_oauthError) with `code` = `"invalid_grant"`; `description` = `"The authorization grant is invalid."`.
|
|
56
|
+
- Set `claims` to call [`IdClaims`](contracts.aug.md#symbol-IdClaims) with `iss` = `issuer` of `config`; `sub` = `subject` of `grant`; `aud` = `clientId` of `grant`; `exp` = (`now` plus `300`); `iat` = `now`; `nonce` = `nonce` of `grant`; `name` = `name` of `grant`.
|
|
57
|
+
- Set `idToken` to call [`signJwt`](../.aug-spec/august/0.19.0/crypto/jose.aug.md#symbol-signJwt) with `key` = call [`SigningKeys.provider`](../common/keys.aug.md#symbol-SigningKeys.provider) on `keys`; `claims` = call `Json` with `value` = `claims`; `kid` = `"provider-1"`; `tokenType` = `"JWT"`; inject `crypto` from `crypto`.
|
|
58
|
+
- Set `accessToken` 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`.
|
|
59
|
+
- Set `value` to call [`AccessGrant`](contracts.aug.md#symbol-AccessGrant) with `subject` = `subject` of `grant`; `name` = `name` of `grant`; `expires` = (`now` plus `300`).
|
|
60
|
+
- Call [`ExpiringStore.put`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.put) on `access` with `key` = `accessToken`; `value` = `value`; `expires` = `expires` of `value`; `now` = `now`.
|
|
61
|
+
- Set `body` to call [`TokenResponse`](contracts.aug.md#symbol-TokenResponse) with `token_type` = `"Bearer"`; `access_token` = `accessToken`; `id_token` = `idToken`; `expires_in` = `300`; `scope` = `"openid profile"`.
|
|
62
|
+
- Return call `HttpResponse` with `body` = call `Json` with `value` = `body`; `headers` = call [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders).
|
|
63
|
+
- If they fail with `HttpError`, name the failure `error` and recover:
|
|
64
|
+
- Return call [`_oauthError`](token.aug.md#symbol-_oauthError) with `code` = `"invalid_request"`; `description` = `"Submit the required URL-encoded token fields once each."`.
|
|
65
|
+
|
|
66
|
+
**Author documentation**
|
|
67
|
+
|
|
68
|
+
A real OAuth token endpoint. Exact client/redirect binding, S256 PKCE, expiry and one-use codes are enforced. Errors use OAuth JSON.
|
|
69
|
+
|
|
70
|
+
<a id="symbol-_oauthError"></a>
|
|
71
|
+
|
|
72
|
+
## `_oauthError`
|
|
73
|
+
|
|
74
|
+
[source](token.aug#L7)
|
|
75
|
+
|
|
76
|
+
Private to its defining scope.
|
|
77
|
+
|
|
78
|
+
**Inputs**
|
|
79
|
+
|
|
80
|
+
- `code` (`string`) — required labeled input.
|
|
81
|
+
- `description` (`string`) — required labeled input.
|
|
82
|
+
|
|
83
|
+
Returns: `HttpResponse<Json>`.
|
|
84
|
+
|
|
85
|
+
Can fail with `HttpError`. Callers must catch or propagate these errors.
|
|
86
|
+
|
|
87
|
+
**What it does**
|
|
88
|
+
|
|
89
|
+
- Return call `HttpResponse` with `body` = call `Json` with `value` = call [`OAuthError`](contracts.aug.md#symbol-OAuthError) with `error` = `code`; `error_description` = `description`; `status` = `400`; `headers` = call [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders).
|
|
90
|
+
|
|
91
|
+
## Dependencies used by this file
|
|
92
|
+
|
|
93
|
+
Only referenced types and operations appear here. Each name links to its complete specification.
|
|
94
|
+
|
|
95
|
+
### [`Crypto`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto)
|
|
96
|
+
|
|
97
|
+
Capability interface from `august.crypto`.
|
|
98
|
+
|
|
99
|
+
- [`Crypto.equal`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.equal) (`left`: `Bytes`, `right`: `Bytes`) → `bool`.
|
|
100
|
+
- [`Crypto.random`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.random) (`size`: `int`) → `Bytes`; can fail with `CryptoError`.
|
|
101
|
+
- [`Crypto.sha256`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.sha256) (`input`: `Bytes`) → `Bytes`; can fail with `CryptoError`.
|
|
102
|
+
- [`Crypto.signRsa`](../.aug-spec/august/0.19.0/crypto/contracts.aug.md#symbol-Crypto.signRsa) (`key`: `RsaPrivateKey`, `input`: `Bytes`) → `Bytes`; can fail with `CryptoError`.
|
|
103
|
+
|
|
104
|
+
### [`JwtError`](../.aug-spec/august/0.19.0/crypto/jose.aug.md#symbol-JwtError)
|
|
105
|
+
|
|
106
|
+
Class from `august.crypto`.
|
|
107
|
+
|
|
108
|
+
Used as a type or provider.
|
|
109
|
+
|
|
110
|
+
### [`signJwt`](../.aug-spec/august/0.19.0/crypto/jose.aug.md#symbol-signJwt)
|
|
111
|
+
|
|
112
|
+
Function from `august.crypto`.
|
|
113
|
+
|
|
114
|
+
- [`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`.
|
|
115
|
+
|
|
116
|
+
### [`ExpiringStore`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore)
|
|
117
|
+
|
|
118
|
+
Capability interface from `august.memory`.
|
|
119
|
+
|
|
120
|
+
- [`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`.
|
|
121
|
+
- [`ExpiringStore.take`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.take) (`key`: `string`, `now`: `int`) → `optional T`.
|
|
122
|
+
|
|
123
|
+
### [`StoreFull`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-StoreFull)
|
|
124
|
+
|
|
125
|
+
Class from `august.memory`.
|
|
126
|
+
|
|
127
|
+
Used as a type or provider.
|
|
128
|
+
|
|
129
|
+
### [`Clock`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock)
|
|
130
|
+
|
|
131
|
+
Capability interface from `august.time`.
|
|
132
|
+
|
|
133
|
+
- [`Clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now) (no caller inputs) → `int`; can fail with `TimeError`.
|
|
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.provider`](../common/keys.aug.md#symbol-SigningKeys.provider) (no caller inputs) → `RsaPrivateKey`; can fail with `KeyError`.
|
|
152
|
+
|
|
153
|
+
### [`Settings`](../common/settings.aug.md#symbol-Settings)
|
|
154
|
+
|
|
155
|
+
Record.
|
|
156
|
+
|
|
157
|
+
- Read `clientId` (`string`).
|
|
158
|
+
- Read `issuer` (`string`).
|
|
159
|
+
|
|
160
|
+
### [`settings`](../common/settings.aug.md#symbol-settings)
|
|
161
|
+
|
|
162
|
+
Function from `common`.
|
|
163
|
+
|
|
164
|
+
- [`settings`](../common/settings.aug.md#symbol-settings) (no caller inputs) → [`Settings`](../common/settings.aug.md#symbol-Settings).
|
|
165
|
+
|
|
166
|
+
### [`AccessGrant`](contracts.aug.md#symbol-AccessGrant)
|
|
167
|
+
|
|
168
|
+
Record from `contracts`.
|
|
169
|
+
|
|
170
|
+
- Construct with `subject`: `string`, `name`: `string`, `expires`: `int` → [`AccessGrant`](contracts.aug.md#symbol-AccessGrant).
|
|
171
|
+
- Read `expires` (`int`).
|
|
172
|
+
|
|
173
|
+
### [`AuthorizationCode`](contracts.aug.md#symbol-AuthorizationCode)
|
|
174
|
+
|
|
175
|
+
Record from `contracts`.
|
|
176
|
+
|
|
177
|
+
- Read `challenge` (`string`).
|
|
178
|
+
- Read `clientId` (`string`).
|
|
179
|
+
- Read `name` (`string`).
|
|
180
|
+
- Read `nonce` (`string`).
|
|
181
|
+
- Read `redirectUri` (`string`).
|
|
182
|
+
- Read `subject` (`string`).
|
|
183
|
+
|
|
184
|
+
### [`IdClaims`](contracts.aug.md#symbol-IdClaims)
|
|
185
|
+
|
|
186
|
+
Record from `contracts`.
|
|
187
|
+
|
|
188
|
+
- Construct with `iss`: `string`, `sub`: `string`, `aud`: `string`, `exp`: `int`, `iat`: `int`, `nonce`: `string`, `name`: `string` → [`IdClaims`](contracts.aug.md#symbol-IdClaims).
|
|
189
|
+
|
|
190
|
+
### [`OAuthError`](contracts.aug.md#symbol-OAuthError)
|
|
191
|
+
|
|
192
|
+
Record from `contracts`.
|
|
193
|
+
|
|
194
|
+
- Construct with `error`: `string`, `error_description`: `string` → [`OAuthError`](contracts.aug.md#symbol-OAuthError).
|
|
195
|
+
|
|
196
|
+
### [`TokenForm`](contracts.aug.md#symbol-TokenForm)
|
|
197
|
+
|
|
198
|
+
Record from `contracts`.
|
|
199
|
+
|
|
200
|
+
- Read `client_id` (`string`).
|
|
201
|
+
- Read `code` (`string`).
|
|
202
|
+
- Read `code_verifier` (`string`).
|
|
203
|
+
- Read `grant_type` (`string`).
|
|
204
|
+
- Read `redirect_uri` (`string`).
|
|
205
|
+
|
|
206
|
+
### [`TokenResponse`](contracts.aug.md#symbol-TokenResponse)
|
|
207
|
+
|
|
208
|
+
Record from `contracts`.
|
|
209
|
+
|
|
210
|
+
- Construct with `token_type`: `string`, `access_token`: `string`, `id_token`: `string`, `expires_in`: `int`, `scope`: `string` → [`TokenResponse`](contracts.aug.md#symbol-TokenResponse).
|
|
211
|
+
|
|
212
|
+
## Built-in operations used by this file
|
|
213
|
+
|
|
214
|
+
- `Bytes.base64url` (no inputs) → `string`: Encode immutable bytes as unpadded RFC 4648 URL-safe base64.
|
|
215
|
+
- `HttpRequest.form` (no inputs) → `TokenForm`: Decode a form record inside a handler so protocol-specific error responses can be returned. Can fail with `HttpError`.
|
|
216
|
+
- `string.bytes` (no inputs) → `Bytes`: Encode this string as immutable UTF-8 bytes.
|
|
217
|
+
- `string.isToken` (`min`: `int`, `max`: `int`) → `bool`: Require an ASCII RFC 3986 unreserved token with a bounded length.
|
|
218
|
+
|
|
219
|
+
[Full built-in reference](https://greenpandastudios.github.io/augscript/language-constructs).
|
|
220
|
+
|
|
221
|
+
## Shared language rules
|
|
222
|
+
|
|
223
|
+
See the [language reference](https://greenpandastudios.github.io/augscript/reference) for numeric, equality, ownership, and task rules.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import UserInfo and AccessGrant from contracts
|
|
2
|
+
import securityHeaders from common
|
|
3
|
+
import Clock from august.time
|
|
4
|
+
import ExpiringStore from august.memory
|
|
5
|
+
|
|
6
|
+
/** The opaque access token is valid only at this provider. Missing, expired and malformed credentials receive the same response. */
|
|
7
|
+
endpoint GET "/provider/userinfo" as userinfo(optional string authorization from header, resolve Clock clock, resolve ExpiringStore<AccessGrant> access) returns HttpResponse<Json> uses clock.now and access.get unless TimeError and HttpError:
|
|
8
|
+
match authorization:
|
|
9
|
+
when null:
|
|
10
|
+
pass
|
|
11
|
+
when some header:
|
|
12
|
+
parts = header.split(separator=" ")
|
|
13
|
+
if parts.length() == 2:
|
|
14
|
+
try:
|
|
15
|
+
if parts.get(index=0) == "Bearer":
|
|
16
|
+
token = parts.get(index=1)
|
|
17
|
+
if token.isToken(min=43, max=43):
|
|
18
|
+
match access.get(key=token, now=clock.now()):
|
|
19
|
+
when null:
|
|
20
|
+
pass
|
|
21
|
+
when some grant:
|
|
22
|
+
return HttpResponse(body=Json(value=UserInfo(sub=grant.subject, name=grant.name)), headers=securityHeaders())
|
|
23
|
+
catch IndexError error:
|
|
24
|
+
pass
|
|
25
|
+
headers = securityHeaders().with(name="www-authenticate", value="Bearer error=\"invalid_token\"")
|
|
26
|
+
return HttpResponse(body=Json(value={"error": "invalid_token"}), status=401, headers=headers)
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<!-- Generated by aug spec. Edit the August source, then regenerate. -->
|
|
2
|
+
|
|
3
|
+
# `userinfo.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
|
+
- [`userinfo`](userinfo.aug.md#symbol-userinfo) handles `GET` `/provider/userinfo` returning `HttpResponse<Json>`.
|
|
10
|
+
|
|
11
|
+
<a id="symbol-userinfo"></a>
|
|
12
|
+
|
|
13
|
+
## `userinfo`
|
|
14
|
+
|
|
15
|
+
[source](userinfo.aug#L7)
|
|
16
|
+
|
|
17
|
+
**Inputs**
|
|
18
|
+
|
|
19
|
+
- `authorization` (`optional string`) — read from the HTTP header; absent value becomes null.
|
|
20
|
+
- `clock` ([`Clock`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock)) — injected; callers omit it.
|
|
21
|
+
- `access` ([`ExpiringStore<AccessGrant>`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore)) — injected; callers omit it.
|
|
22
|
+
|
|
23
|
+
Returns: `HttpResponse<Json>`.
|
|
24
|
+
|
|
25
|
+
Capabilities: [`clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now), [`access.get`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.get).
|
|
26
|
+
|
|
27
|
+
Can fail with `TimeError`, `HttpError`. Callers must catch or propagate these errors.
|
|
28
|
+
|
|
29
|
+
HTTP route: `GET` `/provider/userinfo`. 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.
|
|
30
|
+
|
|
31
|
+
**What it does**
|
|
32
|
+
|
|
33
|
+
- Select the matching case for `authorization`:
|
|
34
|
+
- A null value, including omitted optional input:
|
|
35
|
+
- Continue without another operation.
|
|
36
|
+
- A present, non-null value, named `header`:
|
|
37
|
+
- Set `parts` to call `split` on `header` with `separator` = `" "`.
|
|
38
|
+
- If call `length` on `parts` equals `2`:
|
|
39
|
+
- Try these operations:
|
|
40
|
+
- If call `get` on `parts` with `index` = `0` equals `"Bearer"`:
|
|
41
|
+
- Set `token` to call `get` on `parts` with `index` = `1`.
|
|
42
|
+
- If call `isToken` on `token` with `min` = `43`; `max` = `43` is true:
|
|
43
|
+
- Select the matching case for call [`ExpiringStore.get`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.get) on `access` with `key` = `token`; `now` = call [`Clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now) on `clock`:
|
|
44
|
+
- A null value, including omitted optional input:
|
|
45
|
+
- Continue without another operation.
|
|
46
|
+
- A present, non-null value, named `grant`:
|
|
47
|
+
- Return call `HttpResponse` with `body` = call `Json` with `value` = call [`UserInfo`](contracts.aug.md#symbol-UserInfo) with `sub` = `subject` of `grant`; `name` = `name` of `grant`; `headers` = call [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders).
|
|
48
|
+
- If they fail with `IndexError`, name the failure `error` and recover:
|
|
49
|
+
- Continue without another operation.
|
|
50
|
+
- Set `headers` to call `with` on call [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders) with `name` = `"www-authenticate"`; `value` = `"Bearer error=\"invalid_token\""`.
|
|
51
|
+
- Return call `HttpResponse` with `body` = call `Json` with `value` = a map with `"error"` mapped to `"invalid_token"`; `status` = `401`; `headers` = `headers`.
|
|
52
|
+
|
|
53
|
+
**Author documentation**
|
|
54
|
+
|
|
55
|
+
The opaque access token is valid only at this provider. Missing, expired and malformed credentials receive the same response.
|
|
56
|
+
|
|
57
|
+
## Dependencies used by this file
|
|
58
|
+
|
|
59
|
+
Only referenced types and operations appear here. Each name links to its complete specification.
|
|
60
|
+
|
|
61
|
+
### [`ExpiringStore`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore)
|
|
62
|
+
|
|
63
|
+
Capability interface from `august.memory`.
|
|
64
|
+
|
|
65
|
+
- [`ExpiringStore.get`](../.aug-spec/august/0.19.0/memory/store.aug.md#symbol-ExpiringStore.get) (`key`: `string`, `now`: `int`) → `optional T`.
|
|
66
|
+
|
|
67
|
+
### [`Clock`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock)
|
|
68
|
+
|
|
69
|
+
Capability interface from `august.time`.
|
|
70
|
+
|
|
71
|
+
- [`Clock.now`](../.aug-spec/august/0.19.0/time/contracts.aug.md#symbol-Clock.now) (no caller inputs) → `int`; can fail with `TimeError`.
|
|
72
|
+
|
|
73
|
+
### [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders)
|
|
74
|
+
|
|
75
|
+
Function from `common`.
|
|
76
|
+
|
|
77
|
+
- [`securityHeaders`](../common/headers.aug.md#symbol-securityHeaders) (no caller inputs) → `Headers`; can fail with `HttpError`.
|
|
78
|
+
|
|
79
|
+
### [`AccessGrant`](contracts.aug.md#symbol-AccessGrant)
|
|
80
|
+
|
|
81
|
+
Record from `contracts`.
|
|
82
|
+
|
|
83
|
+
- Read `name` (`string`).
|
|
84
|
+
- Read `subject` (`string`).
|
|
85
|
+
|
|
86
|
+
### [`UserInfo`](contracts.aug.md#symbol-UserInfo)
|
|
87
|
+
|
|
88
|
+
Record from `contracts`.
|
|
89
|
+
|
|
90
|
+
- Construct with `sub`: `string`, `name`: `string` → [`UserInfo`](contracts.aug.md#symbol-UserInfo).
|
|
91
|
+
|
|
92
|
+
## Built-in operations used by this file
|
|
93
|
+
|
|
94
|
+
- `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`.
|
|
95
|
+
- `List<string>.get` (`index`: `int`) → `string`: Read a zero-based position. An invalid index raises checked IndexError. Reference results grant reading. Can fail with `IndexError`.
|
|
96
|
+
- `List<string>.length` (no inputs) → `int`: Read the number of elements.
|
|
97
|
+
- `string.isToken` (`min`: `int`, `max`: `int`) → `bool`: Require an ASCII RFC 3986 unreserved token with a bounded length.
|
|
98
|
+
- `string.split` (`separator`: `string`) → `List<string>`: Split at an exact separator, preserving empty parts.
|
|
99
|
+
|
|
100
|
+
[Full built-in reference](https://greenpandastudios.github.io/augscript/language-constructs).
|
|
101
|
+
|
|
102
|
+
## Shared language rules
|
|
103
|
+
|
|
104
|
+
See the [language reference](https://greenpandastudios.github.io/augscript/reference) for numeric, equality, ownership, and task rules.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import Page from common
|
|
2
|
+
/** A server form with a checked HTTP action. The browser submits to the provider endpoint. */
|
|
3
|
+
ProviderLogin(string requestId, string csrf, string message, HttpAction submit) returns Html:
|
|
4
|
+
return <Page title="Sign in with the August provider">
|
|
5
|
+
<p>{message}</p>
|
|
6
|
+
<p style="background:#f3f5f9;padding:12px;border-radius:8px">Demo account: <strong>ada</strong> · password <strong>august-demo</strong></p>
|
|
7
|
+
<form method="post" action="/provider/login" onSubmit={submit}>
|
|
8
|
+
<input type="hidden" name="request_id" value={requestId} />
|
|
9
|
+
<input type="hidden" name="csrf" value={csrf} />
|
|
10
|
+
<p><label for="username">Username</label><br /><input id="username" name="username" autocomplete="username" value="ada" maxlength="64" required style="padding:10px;width:90%" /></p>
|
|
11
|
+
<p><label for="password">Password</label><br /><input id="password" type="password" name="password" autocomplete="current-password" maxlength="256" required style="padding:10px;width:90%" /></p>
|
|
12
|
+
<button type="submit" style="padding:12px 20px;border:0;border-radius:9px;background:#4852d7;color:white;font:inherit">Sign in and return to the app</button>
|
|
13
|
+
</form>
|
|
14
|
+
<p style="font-size:14px;color:#677189">The provider and app run in the same executable. Authorization codes still travel through the OpenID Connect protocol.</p>
|
|
15
|
+
</Page>
|
|
16
|
+
|
|
17
|
+
ProviderFailure(string message) returns Html:
|
|
18
|
+
return <Page title="Sign-in could not continue"><p>{message}</p><a href="/login/start">Start a new sign-in</a></Page>
|